1(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ 2/*! 3FullCalendar Bootstrap Plugin v4.3.0 4Docs & License: https://fullcalendar.io/ 5(c) 2019 Adam Shaw 6*/ 7 8(function (global, factory) { 9 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core')) : 10 typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core'], factory) : 11 (global = global || self, factory(global.FullCalendarBootstrap = {}, global.FullCalendar)); 12}(this, function (exports, core) { 'use strict'; 13 14 /*! ***************************************************************************** 15 Copyright (c) Microsoft Corporation. All rights reserved. 16 Licensed under the Apache License, Version 2.0 (the "License"); you may not use 17 this file except in compliance with the License. You may obtain a copy of the 18 License at http://www.apache.org/licenses/LICENSE-2.0 19 20 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 21 KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 22 WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 23 MERCHANTABLITY OR NON-INFRINGEMENT. 24 25 See the Apache Version 2.0 License for specific language governing permissions 26 and limitations under the License. 27 ***************************************************************************** */ 28 /* global Reflect, Promise */ 29 30 var extendStatics = function(d, b) { 31 extendStatics = Object.setPrototypeOf || 32 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 33 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; 34 return extendStatics(d, b); 35 }; 36 37 function __extends(d, b) { 38 extendStatics(d, b); 39 function __() { this.constructor = d; } 40 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 41 } 42 43 var BootstrapTheme = /** @class */ (function (_super) { 44 __extends(BootstrapTheme, _super); 45 function BootstrapTheme() { 46 return _super !== null && _super.apply(this, arguments) || this; 47 } 48 return BootstrapTheme; 49 }(core.Theme)); 50 BootstrapTheme.prototype.classes = { 51 widget: 'fc-bootstrap', 52 tableGrid: 'table-bordered', 53 tableList: 'table', 54 tableListHeading: 'table-active', 55 buttonGroup: 'btn-group', 56 button: 'btn btn-primary', 57 buttonActive: 'active', 58 today: 'alert alert-info', 59 popover: 'card card-primary', 60 popoverHeader: 'card-header', 61 popoverContent: 'card-body', 62 // day grid 63 // for left/right border color when border is inset from edges (all-day in timeGrid view) 64 // avoid `table` class b/c don't want margins/padding/structure. only border color. 65 headerRow: 'table-bordered', 66 dayRow: 'table-bordered', 67 // list view 68 listView: 'card card-primary' 69 }; 70 BootstrapTheme.prototype.baseIconClass = 'fa'; 71 BootstrapTheme.prototype.iconClasses = { 72 close: 'fa-times', 73 prev: 'fa-chevron-left', 74 next: 'fa-chevron-right', 75 prevYear: 'fa-angle-double-left', 76 nextYear: 'fa-angle-double-right' 77 }; 78 BootstrapTheme.prototype.iconOverrideOption = 'bootstrapFontAwesome'; 79 BootstrapTheme.prototype.iconOverrideCustomButtonOption = 'bootstrapFontAwesome'; 80 BootstrapTheme.prototype.iconOverridePrefix = 'fa-'; 81 var main = core.createPlugin({ 82 themeClasses: { 83 bootstrap: BootstrapTheme 84 } 85 }); 86 87 exports.BootstrapTheme = BootstrapTheme; 88 exports.default = main; 89 90 Object.defineProperty(exports, '__esModule', { value: true }); 91 92})); 93 94},{"@fullcalendar/core":2}],2:[function(require,module,exports){ 95/*!
96FullCalendar Core Package v4.3.1 97Docs & License: https://fullcalendar.io/ 98(c) 2019 Adam Shaw 99*/ 100 101(function (global, factory) { 102 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 103 typeof define === 'function' && define.amd ? define(['exports'], factory) : 104 (global = global || self, factory(global.FullCalendar = {})); 105}(this, function (exports) { 'use strict'; 106 107 // Creating 108 // ---------------------------------------------------------------------------------------------------------------- 109 var elementPropHash = { 110 className: true, 111 colSpan: true, 112 rowSpan: true 113 }; 114 var containerTagHash = { 115 '<tr': 'tbody', 116 '<td': 'tr' 117 }; 118 function createElement(tagName, attrs, content) { 119 var el = document.createElement(tagName); 120 if (attrs) { 121 for (var attrName in attrs) { 122 if (attrName === 'style') { 123 applyStyle(el, attrs[attrName]); 124 } 125 else if (elementPropHash[attrName]) { 126 el[attrName] = attrs[attrName]; 127 } 128 else { 129 el.setAttribute(attrName, attrs[attrName]); 130 } 131 } 132 } 133 if (typeof content === 'string') { 134 el.innerHTML = content; // shortcut. no need to process HTML in any way 135 } 136 else if (content != null) { 137 appendToElement(el, content); 138 } 139 return el; 140 } 141 function htmlToElement(html) { 142 html = html.trim(); 143 var container = document.createElement(computeContainerTag(html)); 144 container.innerHTML = html; 145 return container.firstChild; 146 } 147 function htmlToElements(html) { 148 return Array.prototype.slice.call(htmlToNodeList(html)); 149 } 150 function htmlToNodeList(html) { 151 html = html.trim(); 152 var container = document.createElement(computeContainerTag(html)); 153 container.innerHTML = html; 154 return container.childNodes; 155 } 156 // assumes html already trimmed and tag names are lowercase 157 function computeContainerTag(html) { 158 return containerTagHash[html.substr(0, 3) // faster than using regex 159 ] || 'div'; 160 } 161 function appendToElement(el, content) { 162 var childNodes = normalizeContent(content); 163 for (var i = 0; i < childNodes.length; i++) { 164 el.appendChild(childNodes[i]); 165 } 166 } 167 function prependToElement(parent, content) { 168 var newEls = normalizeContent(content); 169 var afterEl = parent.firstChild || null; // if no firstChild, will append to end, but that's okay, b/c there were no children 170 for (var i = 0; i < newEls.length; i++) { 171 parent.insertBefore(newEls[i], afterEl); 172 } 173 } 174 function insertAfterElement(refEl, content) { 175 var newEls = normalizeContent(content); 176 var afterEl = refEl.nextSibling || null; 177 for (var i = 0; i < newEls.length; i++) { 178 refEl.parentNode.insertBefore(newEls[i], afterEl); 179 } 180 } 181 function normalizeContent(content) { 182 var els; 183 if (typeof content === 'string') { 184 els = htmlToElements(content); 185 } 186 else if (content instanceof Node) { 187 els = [content]; 188 } 189 else { // Node[] or NodeList 190 els = Array.prototype.slice.call(content); 191 } 192 return els; 193 } 194 function removeElement(el) { 195 if (el.parentNode) { 196 el.parentNode.removeChild(el); 197 } 198 } 199 // Querying 200 // ---------------------------------------------------------------------------------------------------------------- 201 // from https://developer.mozilla.org/en-US/docs/Web/API/Element/closest 202 var matchesMethod = Element.prototype.matches || 203 Element.prototype.matchesSelector || 204 Element.prototype.msMatchesSelector; 205 var closestMethod = Element.prototype.closest || function (selector) { 206 // polyfill 207 var el = this; 208 if (!document.documentElement.contains(el)) { 209 return null; 210 } 211 do { 212 if (elementMatches(el, selector)) { 213 return el; 214 } 215 el = el.parentElement || el.parentNode; 216 } while (el !== null && el.nodeType === 1); 217 return null; 218 }; 219 function elementClosest(el, selector) { 220 return closestMethod.call(el, selector); 221 } 222 function elementMatches(el, selector) { 223 return matchesMethod.call(el, selector); 224 } 225 // accepts multiple subject els 226 // returns a real array. good for methods like forEach 227 function findElements(container, selector) { 228 var containers = container instanceof HTMLElement ? [container] : container; 229 var allMatches = []; 230 for (var i = 0; i < containers.length; i++) { 231 var matches = containers[i].querySelectorAll(selector); 232 for (var j = 0; j < matches.length; j++) { 233 allMatches.push(matches[j]); 234 } 235 } 236 return allMatches; 237 } 238 // accepts multiple subject els 239 // only queries direct child elements 240 function findChildren(parent, selector) { 241 var parents = parent instanceof HTMLElement ? [parent] : parent; 242 var allMatches = []; 243 for (var i = 0; i < parents.length; i++) { 244 var childNodes = parents[i].children; // only ever elements 245 for (var j = 0; j < childNodes.length; j++) { 246 var childNode = childNodes[j]; 247 if (!selector || elementMatches(childNode, selector)) { 248 allMatches.push(childNode); 249 } 250 } 251 } 252 return allMatches; 253 } 254 // Attributes 255 // ---------------------------------------------------------------------------------------------------------------- 256 function forceClassName(el, className, bool) { 257 if (bool) { 258 el.classList.add(className); 259 } 260 else { 261 el.classList.remove(className); 262 } 263 } 264 // Style 265 // ---------------------------------------------------------------------------------------------------------------- 266 var PIXEL_PROP_RE = /(top|left|right|bottom|width|height)$/i; 267 function applyStyle(el, props) { 268 for (var propName in props) { 269 applyStyleProp(el, propName, props[propName]); 270 } 271 } 272 function applyStyleProp(el, name, val) { 273 if (val == null) { 274 el.style[name] = ''; 275 } 276 else if (typeof val === 'number' && PIXEL_PROP_RE.test(name)) { 277 el.style[name] = val + 'px'; 278 } 279 else { 280 el.style[name] = val; 281 } 282 } 283 284 function pointInsideRect(point, rect) { 285 return point.left >= rect.left && 286 point.left < rect.right && 287 point.top >
287= rect.top && 288 point.top < rect.bottom; 289 } 290 // Returns a new rectangle that is the intersection of the two rectangles. If they don't intersect, returns false 291 function intersectRects(rect1, rect2) { 292 var res = { 293 left: Math.max(rect1.left, rect2.left), 294 right: Math.min(rect1.right, rect2.right), 295 top: Math.max(rect1.top, rect2.top), 296 bottom: Math.min(rect1.bottom, rect2.bottom) 297 }; 298 if (res.left < res.right && res.top < res.bottom) { 299 return res; 300 } 301 return false; 302 } 303 function translateRect(rect, deltaX, deltaY) { 304 return { 305 left: rect.left + deltaX, 306 right: rect.right + deltaX, 307 top: rect.top + deltaY, 308 bottom: rect.bottom + deltaY 309 }; 310 } 311 // Returns a new point that will have been moved to reside within the given rectangle 312 function constrainPoint(point, rect) { 313 return { 314 left: Math.min(Math.max(point.left, rect.left), rect.right), 315 top: Math.min(Math.max(point.top, rect.top), rect.bottom) 316 }; 317 } 318 // Returns a point that is the center of the given rectangle 319 function getRectCenter(rect) { 320 return { 321 left: (rect.left + rect.right) / 2, 322 top: (rect.top + rect.bottom) / 2 323 }; 324 } 325 // Subtracts point2's coordinates from point1's coordinates, returning a delta 326 function diffPoints(point1, point2) { 327 return { 328 left: point1.left - point2.left, 329 top: point1.top - point2.top 330 }; 331 } 332 333 // Logic for determining if, when the element is right-to-left, the scrollbar appears on the left side 334 var isRtlScrollbarOnLeft = null; 335 function getIsRtlScrollbarOnLeft() { 336 if (isRtlScrollbarOnLeft === null) { 337 isRtlScrollbarOnLeft = computeIsRtlScrollbarOnLeft(); 338 } 339 return isRtlScrollbarOnLeft; 340 } 341 function computeIsRtlScrollbarOnLeft() { 342 var outerEl = createElement('div', { 343 style: { 344 position: 'absolute', 345 top: -1000, 346 left: 0, 347 border: 0, 348 padding: 0, 349 overflow: 'scroll', 350 direction: 'rtl' 351 } 352 }, '<div></div>'); 353 document.body.appendChild(outerEl); 354 var innerEl = outerEl.firstChild; 355 var res = innerEl.getBoundingClientRect().left > outerEl.getBoundingClientRect().left; 356 removeElement(outerEl); 357 return res; 358 } 359 // The scrollbar width computations in computeEdges are sometimes flawed when it comes to 360 // retina displays, rounding, and IE11. Massage them into a usable value. 361 function sanitizeScrollbarWidth(width) { 362 width = Math.max(0, width); // no negatives 363 width = Math.round(width); 364 return width; 365 } 366 367 function computeEdges(el, getPadding) { 368 if (getPadding === void 0) { getPadding = false; } 369 var computedStyle = window.getComputedStyle(el); 370 var borderLeft = parseInt(computedStyle.borderLeftWidth, 10) || 0; 371 var borderRight = parseInt(computedStyle.borderRightWidth, 10) || 0; 372 var borderTop = parseInt(computedStyle.borderTopWidth, 10) || 0; 373 var borderBottom = parseInt(computedStyle.borderBottomWidth, 10) || 0; 374 // must use offset(Width|Height) because compatible with client(Width|Height) 375 var scrollbarLeftRight = sanitizeScrollbarWidth(el.offsetWidth - el.clientWidth - borderLeft - borderRight); 376 var scrollbarBottom = sanitizeScrollbarWidth(el.offsetHeight - el.clientHeight - borderTop - borderBottom); 377 var res = { 378 borderLeft: borderLeft, 379 borderRight: borderRight, 380 borderTop: borderTop, 381 borderBottom: borderBottom, 382 scrollbarBottom: scrollbarBottom, 383 scrollbarLeft: 0, 384 scrollbarRight: 0 385 }; 386 if (getIsRtlScrollbarOnLeft() && computedStyle.direction === 'rtl') { // is the scrollbar on the left side? 387 res.scrollbarLeft = scrollbarLeftRight; 388 } 389 else { 390 res.scrollbarRight = scrollbarLeftRight; 391 } 392 if (getPadding) { 393 res.paddingLeft = parseInt(computedStyle.paddingLeft, 10) || 0; 394 res.paddingRight = parseInt(computedStyle.paddingRight, 10) || 0; 395 res.paddingTop = parseInt(computedStyle.paddingTop, 10) || 0; 396 res.paddingBottom = parseInt(computedStyle.paddingBottom, 10) || 0; 397 } 398 return res; 399 } 400 function computeInnerRect(el, goWithinPadding) { 401 if (goWithinPadding === void 0) { goWithinPadding = false; } 402 var outerRect = computeRect(el); 403 var edges = computeEdges(el, goWithinPadding); 404 var res = { 405 left: outerRect.left + edges.borderLeft + edges.scrollbarLeft, 406 right: outerRect.right - edges.borderRight - edges.scrollbarRight, 407 top: outerRect.top + edges.borderTop, 408 bottom: outerRect.bottom - edges.borderBottom - edges.scrollbarBottom 409 }; 410 if (goWithinPadding) { 411 res.left += edges.paddingLeft; 412 res.right -= edges.paddingRight; 413 res.top += edges.paddingTop; 414 res.bottom -= edges.paddingBottom; 415 } 416 return res; 417 } 418 function computeRect(el) { 419 var rect = el.getBoundingClientRect(); 420 return { 421 left: rect.left + window.pageXOffset, 422 top: rect.top + window.pageYOffset, 423 right: rect.right + window.pageXOffset, 424 bottom: rect.bottom + window.pageYOffset 425 }; 426 } 427 function computeViewportRect() { 428 return { 429 left: window.pageXOffset, 430 right: window.pageXOffset + document.documentElement.clientWidth, 431 top: window.pageYOffset, 432 bottom: window.pageYOffset + document.documentElement.clientHeight 433 }; 434 } 435 function computeHeightAndMargins(el) { 436 return el.getBoundingClientRect().height + computeVMargins(el); 437 } 438 function computeVMargins(el) { 439 var computed = window.getComputedStyle(el); 440 return parseInt(computed.marginTop, 10) + 441 parseInt(computed.marginBottom, 10); 442 } 443 // does not return window 444 function getClippingParents(el) { 445 var parents = []; 446 while (el instanceof HTMLElement) { // will stop when gets to document or null 447 var computedStyle = window.getComputedStyle(el); 448 if (computedStyle.position === 'fixed') { 449 break; 450 } 451 if ((/(auto|scroll)/).test(computedStyle.overflow + computedStyle.overflowY + computedStyle.overflowX)) { 452 parents.push(el); 453 } 454 el = el.parentNode; 455 } 456 return parents; 457 }
458 function computeClippingRect(el) { 459 return getClippingParents(el) 460 .map(function (el) { 461 return computeInnerRect(el); 462 }) 463 .concat(computeViewportRect()) 464 .reduce(function (rect0, rect1) { 465 return intersectRects(rect0, rect1) || rect1; // should always intersect 466 }); 467 } 468 469 // Stops a mouse/touch event from doing it's native browser action 470 function preventDefault(ev) { 471 ev.preventDefault(); 472 } 473 // Event Delegation 474 // ---------------------------------------------------------------------------------------------------------------- 475 function listenBySelector(container, eventType, selector, handler) { 476 function realHandler(ev) { 477 var matchedChild = elementClosest(ev.target, selector); 478 if (matchedChild) { 479 handler.call(matchedChild, ev, matchedChild); 480 } 481 } 482 container.addEventListener(eventType, realHandler); 483 return function () { 484 container.removeEventListener(eventType, realHandler); 485 }; 486 } 487 function listenToHoverBySelector(container, selector, onMouseEnter, onMouseLeave) { 488 var currentMatchedChild; 489 return listenBySelector(container, 'mouseover', selector, function (ev, matchedChild) { 490 if (matchedChild !== currentMatchedChild) { 491 currentMatchedChild = matchedChild; 492 onMouseEnter(ev, matchedChild); 493 var realOnMouseLeave_1 = function (ev) { 494 currentMatchedChild = null; 495 onMouseLeave(ev, matchedChild); 496 matchedChild.removeEventListener('mouseleave', realOnMouseLeave_1); 497 }; 498 // listen to the next mouseleave, and then unattach 499 matchedChild.addEventListener('mouseleave', realOnMouseLeave_1); 500 } 501 }); 502 } 503 // Animation 504 // ---------------------------------------------------------------------------------------------------------------- 505 var transitionEventNames = [ 506 'webkitTransitionEnd', 507 'otransitionend', 508 'oTransitionEnd', 509 'msTransitionEnd', 510 'transitionend' 511 ]; 512 // triggered only when the next single subsequent transition finishes 513 function whenTransitionDone(el, callback) { 514 var realCallback = function (ev) { 515 callback(ev); 516 transitionEventNames.forEach(function (eventName) { 517 el.removeEventListener(eventName, realCallback); 518 }); 519 }; 520 transitionEventNames.forEach(function (eventName) { 521 el.addEventListener(eventName, realCallback); // cross-browser way to determine when the transition finishes 522 }); 523 } 524 525 var DAY_IDS = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']; 526 // Adding 527 function addWeeks(m, n) { 528 var a = dateToUtcArray(m); 529 a[2] += n * 7; 530 return arrayToUtcDate(a); 531 } 532 function addDays(m, n) { 533 var a = dateToUtcArray(m); 534 a[2] += n; 535 return arrayToUtcDate(a); 536 } 537 function addMs(m, n) { 538 var a = dateToUtcArray(m); 539 a[6] += n; 540 return arrayToUtcDate(a); 541 } 542 // Diffing (all return floats) 543 function diffWeeks(m0, m1) { 544 return diffDays(m0, m1) / 7; 545 } 546 function diffDays(m0, m1) { 547 return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60 * 24); 548 } 549 function diffHours(m0, m1) { 550 return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60); 551 } 552 function diffMinutes(m0, m1) { 553 return (m1.valueOf() - m0.valueOf()) / (1000 * 60); 554 } 555 function diffSeconds(m0, m1) { 556 return (m1.valueOf() - m0.valueOf()) / 1000; 557 } 558 function diffDayAndTime(m0, m1) { 559 var m0day = startOfDay(m0); 560 var m1day = startOfDay(m1); 561 return { 562 years: 0, 563 months: 0, 564 days: Math.round(diffDays(m0day, m1day)), 565 milliseconds: (m1.valueOf() - m1day.valueOf()) - (m0.valueOf() - m0day.valueOf()) 566 }; 567 } 568 // Diffing Whole Units 569 function diffWholeWeeks(m0, m1) { 570 var d = diffWholeDays(m0, m1); 571 if (d !== null && d % 7 === 0) { 572 return d / 7; 573 } 574 return null; 575 } 576 function diffWholeDays(m0, m1) { 577 if (timeAsMs(m0) === timeAsMs(m1)) { 578 return Math.round(diffDays(m0, m1)); 579 } 580 return null; 581 } 582 // Start-Of 583 function startOfDay(m) { 584 return arrayToUtcDate([ 585 m.getUTCFullYear(), 586 m.getUTCMonth(), 587 m.getUTCDate() 588 ]); 589 } 590 function startOfHour(m) { 591 return arrayToUtcDate([ 592 m.getUTCFullYear(), 593 m.getUTCMonth(), 594 m.getUTCDate(), 595 m.getUTCHours() 596 ]); 597 } 598 function startOfMinute(m) { 599 return arrayToUtcDate([ 600 m.getUTCFullYear(), 601 m.getUTCMonth(), 602 m.getUTCDate(), 603 m.getUTCHours(), 604 m.getUTCMinutes() 605 ]); 606 } 607 function startOfSecond(m) { 608 return arrayToUtcDate([ 609 m.getUTCFullYear(), 610 m.getUTCMonth(), 611 m.getUTCDate(), 612 m.getUTCHours(), 613 m.getUTCMinutes(), 614 m.getUTCSeconds() 615 ]); 616 } 617 // Week Computation 618 function weekOfYear(marker, dow, doy) { 619 var y = marker.getUTCFullYear(); 620 var w = weekOfGivenYear(marker, y, dow, doy); 621 if (w < 1) { 622 return weekOfGivenYear(marker, y - 1, dow, doy); 623 } 624 var nextW = weekOfGivenYear(marker, y + 1, dow, doy); 625 if (nextW >= 1) { 626 return Math.min(w, nextW); 627 } 628 return w; 629 } 630 function weekOfGivenYear(marker, year, dow, doy) { 631 var firstWeekStart = arrayToUtcDate([year, 0, 1 + firstWeekOffset(year, dow, doy)]); 632 var dayStart = startOfDay(marker); 633 var days = Math.round(diffDays(firstWeekStart, dayStart)); 634 return Math.floor(days / 7) + 1; // zero-indexed 635 } 636 // start-of-first-week - start-of-year 637 function firstWeekOffset(year, dow, doy) { 638 // first-week day -- which january is always in the first week (4 for iso, 1 for other) 639 var fwd = 7 + dow - doy; 640 // first-week day local weekday -- which local weekday is fwd 641 var fwdlw = (7 + arrayToUtcDate([year, 0, fwd]).getUTCDay() - dow) % 7; 642 return -fwdlw + fwd - 1; 643 } 644 // Array Conversion 645 function dateToLocalArray(date) { 646 return [ 647 date.getFullYear(), 648 date.getMonth(), 649 date.getDate(), 650 date.getHours(), 651 date.getMinutes(), 652 date.getSeconds(), 653 date.getMilliseconds() 654 ]; 655 } 656 function arrayToLocalDate(a) { 657 return new Date(a[0], a[1] || 0, a[2] == null ? 1 : a[2], // day of month 658 a[3] || 0, a[4] || 0, a[5] || 0); 659 } 660 function dateToUtcArray(date) { 661 return [ 662 date.getUTCFullYear(), 663 date.getUTCMonth(), 664 date.getUTCDate(), 665 date.getUTCHours(), 666 date.getUTCMinutes(), 667 date.getUTCSeconds(), 668 date.getUTCMilliseconds() 669 ]; 670 } 671 function arrayToUtcDate(a) { 672 // according to web standards (and Safari), a month index is required. 673 // massage if only given a year. 674 if (a.length === 1) { 675 a = a.concat([0]); 676 } 677 return new Date(Date.UTC.apply(Date, a)); 678 } 679 // Other Utils 680 function isValidDate(m) { 681 return !isNaN(m.valueOf()); 682 } 683 function timeAsMs(m) { 684 return m.getUTCHours() * 1000 * 60 * 60 + 685 m.getUTCMinutes() * 1000 * 60 + 686 m.getUTCSeconds() * 1000 + 687 m.getUTCMilliseconds(); 688 } 689 690 var INTERNAL_UNITS = ['years', 'months', 'days', 'milliseconds'];
691 var PARSE_RE = /^(-?)(?:(\d+)\.)?(\d+):(\d\d)(?::(\d\d)(?:\.(\d\d\d))?)?/; 692 // Parsing and Creation 693 function createDuration(input, unit) { 694 var _a; 695 if (typeof input === 'string') { 696 return parseString(input); 697 } 698 else if (typeof input === 'object' && input) { // non-null object 699 return normalizeObject(input); 700 } 701 else if (typeof input === 'number') { 702 return normalizeObject((_a = {}, _a[unit || 'milliseconds'] = input, _a)); 703 } 704 else { 705 return null; 706 } 707 } 708 function parseString(s) { 709 var m = PARSE_RE.exec(s); 710 if (m) { 711 var sign = m[1] ? -1 : 1; 712 return { 713 years: 0, 714 months: 0, 715 days: sign * (m[2] ? parseInt(m[2], 10) : 0), 716 milliseconds: sign * ((m[3] ? parseInt(m[3], 10) : 0) * 60 * 60 * 1000 + // hours 717 (m[4] ? parseInt(m[4], 10) : 0) * 60 * 1000 + // minutes 718 (m[5] ? parseInt(m[5], 10) : 0) * 1000 + // seconds 719 (m[6] ? parseInt(m[6], 10) : 0) // ms 720 ) 721 }; 722 } 723 return null; 724 } 725 function normalizeObject(obj) { 726 return { 727 years: obj.years || obj.year || 0, 728 months: obj.months || obj.month || 0, 729 days: (obj.days || obj.day || 0) + 730 getWeeksFromInput(obj) * 7, 731 milliseconds: (obj.hours || obj.hour || 0) * 60 * 60 * 1000 + // hours 732 (obj.minutes || obj.minute || 0) * 60 * 1000 + // minutes 733 (obj.seconds || obj.second || 0) * 1000 + // seconds 734 (obj.milliseconds || obj.millisecond || obj.ms || 0) // ms 735 }; 736 } 737 function getWeeksFromInput(obj) { 738 return obj.weeks || obj.week || 0; 739 } 740 // Equality 741 function durationsEqual(d0, d1) { 742 return d0.years === d1.years && 743 d0.months === d1.months && 744 d0.days === d1.days && 745 d0.milliseconds === d1.milliseconds; 746 } 747 function isSingleDay(dur) { 748 return dur.years === 0 && dur.months === 0 && dur.days === 1 && dur.milliseconds === 0; 749 } 750 // Simple Math 751 function addDurations(d0, d1) { 752 return { 753 years: d0.years + d1.years, 754 months: d0.months + d1.months, 755 days: d0.days + d1.days, 756 milliseconds: d0.milliseconds + d1.milliseconds 757 }; 758 } 759 function subtractDurations(d1, d0) { 760 return { 761 years: d1.years - d0.years, 762 months: d1.months - d0.months, 763 days: d1.days - d0.days, 764 milliseconds: d1.milliseconds - d0.milliseconds 765 }; 766 } 767 function multiplyDuration(d, n) { 768 return { 769 years: d.years * n, 770 months: d.months * n, 771 days: d.days * n, 772 milliseconds: d.milliseconds * n 773 }; 774 } 775 // Conversions 776 // "Rough" because they are based on average-case Gregorian months/years 777 function asRoughYears(dur) { 778 return asRoughDays(dur) / 365; 779 } 780 function asRoughMonths(dur) { 781 return asRoughDays(dur) / 30; 782 } 783 function asRoughDays(dur) { 784 return asRoughMs(dur) / 864e5; 785 } 786 function asRoughMinutes(dur) { 787 return asRoughMs(dur) / (1000 * 60); 788 } 789 function asRoughSeconds(dur) { 790 return asRoughMs(dur) / 1000; 791 } 792 function asRoughMs(dur) { 793 return dur.years * (365 * 864e5) + 794 dur.months * (30 * 864e5) + 795 dur.days * 864e5 + 796 dur.milliseconds; 797 } 798 // Advanced Math 799 function wholeDivideDurations(numerator, denominator) { 800 var res = null; 801 for (var i = 0; i < INTERNAL_UNITS.length; i++) { 802 var unit = INTERNAL_UNITS[i]; 803 if (denominator[unit]) { 804 var localRes = numerator[unit] / denominator[unit]; 805 if (!isInt(localRes) || (res !== null && res !== localRes)) { 806 return null; 807 } 808 res = localRes; 809 } 810 else if (numerator[unit]) { 811 // needs to divide by something but can't! 812 return null; 813 } 814 } 815 return res; 816 } 817 function greatestDurationDenominator(dur, dontReturnWeeks) { 818 var ms = dur.milliseconds; 819 if (ms) { 820 if (ms % 1000 !== 0) { 821 return { unit: 'millisecond', value: ms }; 822 } 823 if (ms % (1000 * 60) !== 0) { 824 return { unit: 'second', value: ms / 1000 }; 825 } 826 if (ms % (1000 * 60 * 60) !== 0) { 827 return { unit: 'minute', value: ms / (1000 * 60) }; 828 } 829 if (ms) { 830 return { unit: 'hour', value: ms / (1000 * 60 * 60) }; 831 } 832 } 833 if (dur.days) { 834 if (!dontReturnWeeks && dur.days % 7 === 0) { 835 return { unit: 'week', value: dur.days / 7 }; 836 } 837 return { unit: 'day', value: dur.days }; 838 } 839 if (dur.months) { 840 return { unit: 'month', value: dur.months }; 841 } 842 if (dur.years) { 843 return { unit: 'year', value: dur.years }; 844 } 845 return { unit: 'millisecond', value: 0 }; 846 } 847 848 /* FullCalendar-specific DOM Utilities 849 ----------------------------------------------------------------------------------------------------------------------*/ 850 // Given the scrollbar widths of some other container, create borders/margins on rowEls in order to match the left 851 // and right space that was offset by the scrollbars. A 1-pixel border first, then margin beyond that. 852 function compensateScroll(rowEl, scrollbarWidths) { 853 if (scrollbarWidths.left) { 854 applyStyle(rowEl, { 855 borderLeftWidth: 1, 856 marginLeft: scrollbarWidths.left - 1 857 }); 858 } 859 if (scrollbarWidths.right) { 860 applyStyle(rowEl, { 861 borderRightWidth: 1, 862 marginRight: scrollbarWidths.right - 1 863 }); 864 } 865 } 866 // Undoes compensateScroll and restores all borders/margins 867 function uncompensateScroll(rowEl) { 868 applyStyle(rowEl, { 869 marginLeft: '', 870 marginRight: '', 871 borderLeftWidth: '', 872 borderRightWidth: '' 873 }); 874 }
875 // Make the mouse cursor express that an event is not allowed in the current area 876 function disableCursor() { 877 document.body.classList.add('fc-not-allowed'); 878 } 879 // Returns the mouse cursor to its original look 880 function enableCursor() { 881 document.body.classList.remove('fc-not-allowed'); 882 } 883 // Given a total available height to fill, have `els` (essentially child rows) expand to accomodate. 884 // By default, all elements that are shorter than the recommended height are expanded uniformly, not considering 885 // any other els that are already too tall. if `shouldRedistribute` is on, it considers these tall rows and 886 // reduces the available height. 887 function distributeHeight(els, availableHeight, shouldRedistribute) { 888 // *FLOORING NOTE*: we floor in certain places because zoom can give inaccurate floating-point dimensions, 889 // and it is better to be shorter than taller, to avoid creating unnecessary scrollbars. 890 var minOffset1 = Math.floor(availableHeight / els.length); // for non-last element 891 var minOffset2 = Math.floor(availableHeight - minOffset1 * (els.length - 1)); // for last element *FLOORING NOTE* 892 var flexEls = []; // elements that are allowed to expand. array of DOM nodes 893 var flexOffsets = []; // amount of vertical space it takes up 894 var flexHeights = []; // actual css height 895 var usedHeight = 0; 896 undistributeHeight(els); // give all elements their natural height 897 // find elements that are below the recommended height (expandable). 898 // important to query for heights in a single first pass (to avoid reflow oscillation). 899 els.forEach(function (el, i) { 900 var minOffset = i === els.length - 1 ? minOffset2 : minOffset1; 901 var naturalHeight = el.getBoundingClientRect().height; 902 var naturalOffset = naturalHeight + computeVMargins(el); 903 if (naturalOffset < minOffset) { 904 flexEls.push(el); 905 flexOffsets.push(naturalOffset); 906 flexHeights.push(naturalHeight); 907 } 908 else { 909 // this element stretches past recommended height (non-expandable). mark the space as occupied. 910 usedHeight += naturalOffset; 911 } 912 }); 913 // readjust the recommended height to only consider the height available to non-maxed-out rows. 914 if (shouldRedistribute) { 915 availableHeight -= usedHeight; 916 minOffset1 = Math.floor(availableHeight / flexEls.length); 917 minOffset2 = Math.floor(availableHeight - minOffset1 * (flexEls.length - 1)); // *FLOORING NOTE* 918 } 919 // assign heights to all expandable elements 920 flexEls.forEach(function (el, i) { 921 var minOffset = i === flexEls.length - 1 ? minOffset2 : minOffset1; 922 var naturalOffset = flexOffsets[i]; 923 var naturalHeight = flexHeights[i]; 924 var newHeight = minOffset - (naturalOffset - naturalHeight); // subtract the margin/padding 925 if (naturalOffset < minOffset) { // we check this again because redistribution might have changed things 926 el.style.height = newHeight + 'px'; 927 } 928 }); 929 } 930 // Undoes distrubuteHeight, restoring all els to their natural height 931 function undistributeHeight(els) { 932 els.forEach(function (el) { 933 el.style.height = ''; 934 }); 935 } 936 // Given `els`, a set of <td> cells, find the cell with the largest natural width and set the widths of all the 937 // cells to be that width. 938 // PREREQUISITE: if you want a cell to take up width, it needs to have a single inner element w/ display:inline 939 function matchCellWidths(els) { 940 var maxInnerWidth = 0; 941 els.forEach(function (el) { 942 var innerEl = el.firstChild; // hopefully an element 943 if (innerEl instanceof HTMLElement) { 944 var innerWidth_1 = innerEl.getBoundingClientRect().width; 945 if (innerWidth_1 > maxInnerWidth) { 946 maxInnerWidth = innerWidth_1; 947 } 948 } 949 }); 950 maxInnerWidth++; // sometimes not accurate of width the text needs to stay on one line. insurance
951 els.forEach(function (el) { 952 el.style.width = maxInnerWidth + 'px'; 953 }); 954 return maxInnerWidth; 955 } 956 // Given one element that resides inside another, 957 // Subtracts the height of the inner element from the outer element. 958 function subtractInnerElHeight(outerEl, innerEl) { 959 // effin' IE8/9/10/11 sometimes returns 0 for dimensions. this weird hack was the only thing that worked 960 var reflowStyleProps = { 961 position: 'relative', 962 left: -1 // ensure reflow in case the el was already relative. negative is less likely to cause new scroll 963 }; 964 applyStyle(outerEl, reflowStyleProps); 965 applyStyle(innerEl, reflowStyleProps); 966 var diff = // grab the dimensions 967 outerEl.getBoundingClientRect().height - 968 innerEl.getBoundingClientRect().height; 969 // undo hack 970 var resetStyleProps = { position: '', left: '' }; 971 applyStyle(outerEl, resetStyleProps); 972 applyStyle(innerEl, resetStyleProps); 973 return diff; 974 } 975 /* Selection 976 ----------------------------------------------------------------------------------------------------------------------*/ 977 function preventSelection(el) { 978 el.classList.add('fc-unselectable'); 979 el.addEventListener('selectstart', preventDefault); 980 } 981 function allowSelection(el) { 982 el.classList.remove('fc-unselectable'); 983 el.removeEventListener('selectstart', preventDefault); 984 } 985 /* Context Menu 986 ----------------------------------------------------------------------------------------------------------------------*/ 987 function preventContextMenu(el) { 988 el.addEventListener('contextmenu', preventDefault); 989 } 990 function allowContextMenu(el) { 991 el.removeEventListener('contextmenu', preventDefault); 992 } 993 /* Object Ordering by Field 994 ----------------------------------------------------------------------------------------------------------------------*/ 995 function parseFieldSpecs(input) { 996 var specs = []; 997 var tokens = []; 998 var i; 999 var token; 1000 if (typeof input === 'string') { 1001 tokens = input.split(/\s*,\s*/); 1002 } 1003 else if (typeof input === 'function') { 1004 tokens = [input]; 1005 } 1006 else if (Array.isArray(input)) { 1007 tokens = input; 1008 } 1009 for (i = 0; i < tokens.length; i++) { 1010 token = tokens[i]; 1011 if (typeof token === 'string') { 1012 specs.push(token.charAt(0) === '-' ? 1013 { field: token.substring(1), order: -1 } : 1014 { field: token, order: 1 }); 1015 } 1016 else if (typeof token === 'function') { 1017 specs.push({ func: token }); 1018 } 1019 } 1020 return specs; 1021 } 1022 function compareByFieldSpecs(obj0, obj1, fieldSpecs) { 1023 var i; 1024 var cmp; 1025 for (i = 0; i < fieldSpecs.length; i++) { 1026 cmp = compareByFieldSpec(obj0, obj1, fieldSpecs[i]); 1027 if (cmp) { 1028 return cmp; 1029 } 1030 } 1031 return 0; 1032 } 1033 function compareByFieldSpec(obj0, obj1, fieldSpec) { 1034 if (fieldSpec.func) { 1035 return fieldSpec.func(obj0, obj1); 1036 } 1037 return flexibleCompare(obj0[fieldSpec.field], obj1[fieldSpec.field]) 1038 * (fieldSpec.order || 1); 1039 } 1040 function flexibleCompare(a, b) { 1041 if (!a && !b) { 1042 return 0; 1043 } 1044 if (b == null) { 1045 return -1; 1046 } 1047 if (a == null) { 1048 return 1; 1049 } 1050 if (typeof a === 'string' || typeof b === 'string') { 1051 return String(a).localeCompare(String(b)); 1052 } 1053 return a - b; 1054 } 1055 /* String Utilities 1056 ----------------------------------------------------------------------------------------------------------------------*/ 1057 function capitaliseFirstLetter(str) { 1058 return str.charAt(0).toUpperCase() + str.slice(1); 1059 } 1060 function padStart(val, len) { 1061 var s = String(val); 1062 return '000'.substr(0, len - s.length) + s; 1063 } 1064 /* Number Utilities 1065 ----------------------------------------------------------------------------------------------------------------------*/ 1066 function compareNumbers(a, b) { 1067 return a - b; 1068 } 1069 function isInt(n) { 1070 return n % 1 === 0; 1071 } 1072 /* Weird Utilities 1073 ----------------------------------------------------------------------------------------------------------------------*/ 1074 function applyAll(functions, thisObj, args) { 1075 if (typeof functions === 'function') { // supplied a single function 1076 functions = [functions]; 1077 } 1078 if (functions) { 1079 var i = void 0; 1080 var ret = void 0; 1081 for (i = 0; i < functions.length; i++) { 1082 ret = functions[i].apply(thisObj, args) || ret; 1083 } 1084 return ret; 1085 } 1086 } 1087 function firstDefined() { 1088 var args = []; 1089 for (var _i = 0; _i < arguments.length; _i++) { 1090 args[_i] = arguments[_i]; 1091 } 1092 for (var i = 0; i < args.length; i++) { 1093 if (args[i] !== undefined) { 1094 return args[i]; 1095 } 1096 } 1097 } 1098 // Returns a function, that, as long as it continues to be invoked, will not 1099 // be triggered. The function will be called after it stops being called for 1100 // N milliseconds. If `immediate` is passed, trigger the function on the 1101 // leading edge, instead of the trailing. 1102 // https://github.com/jashkenas/underscore/blob/1.6.0/underscore.js#L714 1103 function debounce(func, wait) { 1104 var timeout; 1105 var args; 1106 var context; 1107 var timestamp; 1108 var result; 1109 var later = function () { 1110 var last = new Date().valueOf() - timestamp; 1111 if (last < wait) { 1112 timeout = setTimeout(later, wait - last); 1113 } 1114 else { 1115 timeout = null;
1116 result = func.apply(context, args); 1117 context = args = null; 1118 } 1119 }; 1120 return function () { 1121 context = this; 1122 args = arguments; 1123 timestamp = new Date().valueOf(); 1124 if (!timeout) { 1125 timeout = setTimeout(later, wait); 1126 } 1127 return result; 1128 }; 1129 } 1130 // Number and Boolean are only types that defaults or not computed for 1131 // TODO: write more comments 1132 function refineProps(rawProps, processors, defaults, leftoverProps) { 1133 if (defaults === void 0) { defaults = {}; } 1134 var refined = {}; 1135 for (var key in processors) { 1136 var processor = processors[key]; 1137 if (rawProps[key] !== undefined) { 1138 // found 1139 if (processor === Function) { 1140 refined[key] = typeof rawProps[key] === 'function' ? rawProps[key] : null; 1141 } 1142 else if (processor) { // a refining function? 1143 refined[key] = processor(rawProps[key]); 1144 } 1145 else { 1146 refined[key] = rawProps[key]; 1147 } 1148 } 1149 else if (defaults[key] !== undefined) { 1150 // there's an explicit default 1151 refined[key] = defaults[key]; 1152 } 1153 else { 1154 // must compute a default 1155 if (processor === String) { 1156 refined[key] = ''; // empty string is default for String 1157 } 1158 else if (!processor || processor === Number || processor === Boolean || processor === Function) { 1159 refined[key] = null; // assign null for other non-custom processor funcs 1160 } 1161 else { 1162 refined[key] = processor(null); // run the custom processor func 1163 } 1164 } 1165 } 1166 if (leftoverProps) { 1167 for (var key in rawProps) { 1168 if (processors[key] === undefined) { 1169 leftoverProps[key] = rawProps[key]; 1170 } 1171 } 1172 } 1173 return refined; 1174 } 1175 /* Date stuff that doesn't belong in datelib core 1176 ----------------------------------------------------------------------------------------------------------------------*/ 1177 // given a timed range, computes an all-day range that has the same exact duration, 1178 // but whose start time is aligned with the start of the day. 1179 function computeAlignedDayRange(timedRange) { 1180 var dayCnt = Math.floor(diffDays(timedRange.start, timedRange.end)) || 1; 1181 var start = startOfDay(timedRange.start); 1182 var end = addDays(start, dayCnt); 1183 return { start: start, end: end }; 1184 } 1185 // given a timed range, computes an all-day range based on how for the end date bleeds into the next day 1186 // TODO: give nextDayThreshold a default arg 1187 function computeVisibleDayRange(timedRange, nextDayThreshold) { 1188 if (nextDayThreshold === void 0) { nextDayThreshold = createDuration(0); } 1189 var startDay = null; 1190 var endDay = null; 1191 if (timedRange.end) { 1192 endDay = startOfDay(timedRange.end); 1193 var endTimeMS = timedRange.end.valueOf() - endDay.valueOf(); // # of milliseconds into `endDay` 1194 // If the end time is actually inclusively part of the next day and is equal to or 1195 // beyond the next day threshold, adjust the end to be the exclusive end of `endDay`. 1196 // Otherwise, leaving it as inclusive will cause it to exclude `endDay`. 1197 if (endTimeMS && endTimeMS >= asRoughMs(nextDayThreshold)) { 1198 endDay = addDays(endDay, 1); 1199 } 1200 } 1201 if (timedRange.start) { 1202 startDay = startOfDay(timedRange.start); // the beginning of the day the range starts 1203 // If end is within `startDay` but not past nextDayThreshold, assign the default duration of one day. 1204 if (endDay && endDay <= startDay) { 1205 endDay = addDays(startDay, 1); 1206 } 1207 } 1208 return { start: startDay, end: endDay }; 1209 } 1210 // spans from one day into another? 1211 function isMultiDayRange(range) { 1212 var visibleRange = computeVisibleDayRange(range); 1213 return diffDays(visibleRange.start, visibleRange.end) > 1; 1214 } 1215 function diffDates(date0, date1, dateEnv, largeUnit) { 1216 if (largeUnit === 'year') { 1217 return createDuration(dateEnv.diffWholeYears(date0, date1), 'year'); 1218 } 1219 else if (largeUnit === 'month') { 1220 return createDuration(dateEnv.diffWholeMonths(date0, date1), 'month'); 1221 } 1222 else { 1223 return diffDayAndTime(date0, date1); // returns a duration 1224 } 1225 } 1226 1227 /*! ***************************************************************************** 1228 Copyright (c) Microsoft Corporation. All rights reserved. 1229 Licensed under the Apache License, Version 2.0 (the "License");
1229 you may not use 1230 this file except in compliance with the License. You may obtain a copy of the 1231 License at http://www.apache.org/licenses/LICENSE-2.0 1232 1233 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 1234 KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 1235 WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 1236 MERCHANTABLITY OR NON-INFRINGEMENT. 1237 1238 See the Apache Version 2.0 License for specific language governing permissions 1239 and limitations under the License. 1240 ***************************************************************************** */ 1241 /* global Reflect, Promise */ 1242 1243 var extendStatics = function(d, b) { 1244 extendStatics = Object.setPrototypeOf || 1245 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 1246 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; 1247 return extendStatics(d, b); 1248 }; 1249 1250 function __extends(d, b) { 1251 extendStatics(d, b); 1252 function __() { this.constructor = d; } 1253 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 1254 } 1255 1256 var __assign = function() { 1257 __assign = Object.assign || function __assign(t) { 1258 for (var s, i = 1, n = arguments.length; i < n; i++) { 1259 s = arguments[i]; 1260 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 1261 } 1262 return t; 1263 }; 1264 return __assign.apply(this, arguments); 1265 }; 1266 1267 function parseRecurring(eventInput, allDayDefault, dateEnv, recurringTypes, leftovers) { 1268 for (var i = 0; i < recurringTypes.length; i++) { 1269 var localLeftovers = {}; 1270 var parsed = recurringTypes[i].parse(eventInput, localLeftovers, dateEnv); 1271 if (parsed) { 1272 var allDay = localLeftovers.allDay; 1273 delete localLeftovers.allDay; // remove from leftovers 1274 if (allDay == null) { 1275 allDay = allDayDefault; 1276 if (allDay == null) { 1277 allDay = parsed.allDayGuess; 1278 if (allDay == null) { 1279 allDay = false; 1280 } 1281 } 1282 } 1283 __assign(leftovers, localLeftovers); 1284 return { 1285 allDay: allDay, 1286 duration: parsed.duration, 1287 typeData: parsed.typeData, 1288 typeId: i 1289 }; 1290 } 1291 } 1292 return null; 1293 } 1294 /* 1295 Event MUST have a recurringDef 1296 */ 1297 function expandRecurringRanges(eventDef, duration, framingRange, dateEnv, recurringTypes) { 1298 var typeDef = recurringTypes[eventDef.recurringDef.typeId]; 1299 var markers = typeDef.expand(eventDef.recurringDef.typeData, { 1300 start: dateEnv.subtract(framingRange.start, duration), 1301 end: framingRange.end 1302 }, dateEnv); 1303 // the recurrence plugins don't guarantee that all-day events are start-of-day, so we have to 1304 if (eventDef.allDay) { 1305 markers = markers.map(startOfDay); 1306 } 1307 return markers; 1308 } 1309 1310 var hasOwnProperty = Object.prototype.hasOwnProperty; 1311 // Merges an array of objects into a single object. 1312 // The second argument allows for an array of property names who's object values will be merged together. 1313 function mergeProps(propObjs, complexProps) { 1314 var dest = {}; 1315 var i; 1316 var name; 1317 var complexObjs; 1318 var j; 1319 var val; 1320 var props; 1321 if (complexProps) { 1322 for (i = 0; i < complexProps.length; i++) { 1323 name = complexProps[i]; 1324 complexObjs = []; 1325 // collect the trailing object values, stopping when a non-object is discovered 1326 for (j = propObjs.length - 1; j >= 0; j--) { 1327 val = propObjs[j][name]; 1328 if (typeof val === 'object' && val) { // non-null object 1329 complexObjs.unshift(val); 1330 } 1331 else if (val !== undefined) { 1332 dest[name] = val; // if there were no objects, this value will be used 1333 break; 1334 } 1335 } 1336 // if the trailing values were objects, use the merged value 1337 if (complexObjs.length) { 1338 dest[name] = mergeProps(complexObjs); 1339 } 1340 } 1341 } 1342 // copy values into the destination, going from last to first 1343 for (i = propObjs.length - 1; i >= 0; i--) { 1344 props = propObjs[i]; 1345 for (name in props) { 1346 if (!(name in dest)) { // if already assigned by previous props or complex props, don't reassign 1347 dest[name] = props[name]; 1348 } 1349 } 1350 } 1351 return dest; 1352 } 1353 function filterHash(hash, func) { 1354 var filtered = {}; 1355 for (var key in hash) { 1356 if (func(hash[key], key)) { 1357 filtered[key] = hash[key]; 1358 } 1359 } 1360 return filtered; 1361 } 1362 function mapHash(hash, func) { 1363 var newHash = {}; 1364 for (var key in hash) { 1365 newHash[key] = func(hash[key], key); 1366 } 1367 return newHash; 1368 } 1369 function arrayToHash(a) { 1370 var hash = {}; 1371 for (var _i = 0, a_1 = a; _i < a_1.length; _i++) { 1372 var item = a_1[_i]; 1373 hash[item] = true; 1374 } 1375 return hash; 1376 } 1377 function hashValuesToArray(obj) { 1378 var a = []; 1379 for (var key in obj) { 1380 a.push(obj[key]); 1381 } 1382 return a; 1383 } 1384 function isPropsEqual(obj0, obj1) { 1385 for (var key in obj0) { 1386 if (hasOwnProperty.call(obj0, key)) { 1387 if (!(key in obj1)) { 1388 return false;
1389 } 1390 } 1391 } 1392 for (var key in obj1) { 1393 if (hasOwnProperty.call(obj1, key)) { 1394 if (obj0[key] !== obj1[key]) { 1395 return false; 1396 } 1397 } 1398 } 1399 return true; 1400 } 1401 1402 function parseEvents(rawEvents, sourceId, calendar, allowOpenRange) { 1403 var eventStore = createEmptyEventStore(); 1404 for (var _i = 0, rawEvents_1 = rawEvents; _i < rawEvents_1.length; _i++) { 1405 var rawEvent = rawEvents_1[_i]; 1406 var tuple = parseEvent(rawEvent, sourceId, calendar, allowOpenRange); 1407 if (tuple) { 1408 eventTupleToStore(tuple, eventStore); 1409 } 1410 } 1411 return eventStore; 1412 } 1413 function eventTupleToStore(tuple, eventStore) { 1414 if (eventStore === void 0) { eventStore = createEmptyEventStore(); } 1415 eventStore.defs[tuple.def.defId] = tuple.def; 1416 if (tuple.instance) { 1417 eventStore.instances[tuple.instance.instanceId] = tuple.instance; 1418 } 1419 return eventStore; 1420 } 1421 function expandRecurring(eventStore, framingRange, calendar) { 1422 var dateEnv = calendar.dateEnv; 1423 var defs = eventStore.defs, instances = eventStore.instances; 1424 // remove existing recurring instances 1425 instances = filterHash(instances, function (instance) { 1426 return !defs[instance.defId].recurringDef; 1427 }); 1428 for (var defId in defs) { 1429 var def = defs[defId]; 1430 if (def.recurringDef) { 1431 var duration = def.recurringDef.duration; 1432 if (!duration) { 1433 duration = def.allDay ? 1434 calendar.defaultAllDayEventDuration : 1435 calendar.defaultTimedEventDuration; 1436 } 1437 var starts = expandRecurringRanges(def, duration, framingRange, calendar.dateEnv, calendar.pluginSystem.hooks.recurringTypes); 1438 for (var _i = 0, starts_1 = starts; _i < starts_1.length; _i++) { 1439 var start = starts_1[_i]; 1440 var instance = createEventInstance(defId, { 1441 start: start, 1442 end: dateEnv.add(start, duration) 1443 }); 1444 instances[instance.instanceId] = instance; 1445 } 1446 } 1447 } 1448 return { defs: defs, instances: instances }; 1449 } 1450 // retrieves events that have the same groupId as the instance specified by `instanceId` 1451 // or they are the same as the instance. 1452 // why might instanceId not be in the store? an event from another calendar? 1453 function getRelevantEvents(eventStore, instanceId) { 1454 var instance = eventStore.instances[instanceId]; 1455 if (instance) { 1456 var def_1 = eventStore.defs[instance.defId]; 1457 // get events/instances with same group 1458 var newStore = filterEventStoreDefs(eventStore, function (lookDef) { 1459 return isEventDefsGrouped(def_1, lookDef); 1460 }); 1461 // add the original 1462 // TODO: wish we could use eventTupleToStore or something like it 1463 newStore.defs[def_1.defId] = def_1; 1464 newStore.instances[instance.instanceId] = instance; 1465 return newStore; 1466 } 1467 return createEmptyEventStore(); 1468 } 1469 function isEventDefsGrouped(def0, def1) { 1470 return Boolean(def0.groupId && def0.groupId === def1.groupId); 1471 } 1472 function transformRawEvents(rawEvents, eventSource, calendar) { 1473 var calEachTransform = calendar.opt('eventDataTransform'); 1474 var sourceEachTransform = eventSource ? eventSource.eventDataTransform : null; 1475 if (sourceEachTransform) { 1476 rawEvents = transformEachRawEvent(rawEvents, sourceEachTransform); 1477 } 1478 if (calEachTransform) { 1479 rawEvents = transformEachRawEvent(rawEvents, calEachTransform); 1480 } 1481 return rawEvents; 1482 } 1483 function transformEachRawEvent(rawEvents, func) { 1484 var refinedEvents; 1485 if (!func) { 1486 refinedEvents = rawEvents; 1487 } 1488 else { 1489 refinedEvents = []; 1490 for (var _i = 0, rawEvents_2 = rawEvents; _i < rawEvents_2.length; _i++) { 1491 var rawEvent = rawEvents_2[_i]; 1492 var refinedEvent = func(rawEvent); 1493 if (refinedEvent) { 1494 refinedEvents.push(refinedEvent); 1495 } 1496 else if (refinedEvent == null) { 1497 refinedEvents.push(rawEvent); 1498 } // if a different falsy value, do nothing 1499 } 1500 } 1501 return refinedEvents; 1502 } 1503 function createEmptyEventStore() { 1504 return { defs: {}, instances: {} }; 1505 } 1506 function mergeEventStores(store0, store1) { 1507 return { 1508 defs: __assign({}, store0.defs, store1.defs), 1509 instances: __assign({}, store0.instances, store1.instances) 1510 }; 1511 } 1512 function filterEventStoreDefs(eventStore, filterFunc) { 1513 var defs = filterHash(eventStore.defs, filterFunc); 1514 var instances = filterHash(eventStore.instances, function (instance) { 1515 return defs[instance.defId]; // still exists? 1516 }); 1517 return { defs: defs, instances: instances }; 1518 } 1519 1520 function parseRange(input, dateEnv) { 1521 var start = null; 1522 var end = null; 1523 if (input.start) { 1524 start = dateEnv.createMarker(input.start); 1525 } 1526 if (input.end) { 1527 end = dateEnv.createMarker(input.end); 1528 } 1529 if (!start && !end) { 1530 return null; 1531 } 1532 if (start && end && end < start) { 1533 return null; 1534 } 1535 return { start: start, end: end }; 1536 } 1537 // SIDE-EFFECT: will mutate ranges. 1538 // Will return a new array result. 1539 function invertRanges(ranges, constraintRange) { 1540 var invertedRanges = []; 1541 var start = constraintRange.start; // the end of the previous range. the start of the new range 1542 var i; 1543 var dateRange; 1544 // ranges need to be in order. required for our date-walking algorithm 1545 ranges.sort(compareRanges); 1546 for (i = 0; i < ranges.length; i++) { 1547 dateRange = ranges[i]; 1548 // add the span of time before the event (if there is any) 1549 if (dateRange.start > start) { // compare millisecond time (skip any ambig logic) 1550 invertedRanges.push({ start: start, end: dateRange.start }); 1551 } 1552 if (dateRange.end > start) { 1553 start = dateRange.end; 1554 } 1555 } 1556 // add the span of time after the last event (if there is any) 1557 if (start < constraintRange.end) { // compare millisecond time (skip any ambig logic) 1558 invertedRanges.push({ start: start, end: constraintRange.end }); 1559 } 1560 return invertedRanges; 1561 } 1562 function compareRanges(range0, range1) { 1563 return range0.start.valueOf() - range1.start.valueOf(); // earlier ranges go first 1564 } 1565 function intersectRanges(range0, range1) { 1566 var start = range0.start; 1567 var end = range0.end; 1568 var newRange = null; 1569 if (range1.start !== null) { 1570 if (start === null) { 1571 start = range1.start; 1572 } 1573 else { 1574 start = new Date(Math.max(start.valueOf(), range1.start.valueOf())); 1575 } 1576 } 1577 if (range1.end != null) { 1578 if (end === null) { 1579 end = range1.end; 1580 } 1581 else { 1582 end = new Date(Math.min(end.valueOf(), range1.end.valueOf())); 1583 } 1584 } 1585 if (start === null || end === null || start < end) { 1586 newRange = { start: start, end: end }; 1587 } 1588 return newRange; 1589 } 1590 function rangesEqual(range0, range1) { 1591 return (range0.start === null ? null : range0.start.valueOf()) === (range1.start === null ? null : range1.start.valueOf()) && 1592 (range0.end === null ? null : range0.end.valueOf()) === (range1.end === null ? null : range1.end.valueOf()); 1593 } 1594 function rangesIntersect(range0, range1) { 1595 return (range0.end === null || range1.start === null || range0.end > range1.start) && 1596 (range0.start === null || range1.end === null || range0.start < range1.end); 1597 } 1598 function rangeContainsRange(outerRange, innerRange) { 1599 return (outerRange.start === null || (innerRange.start !== null && innerRange.start >= outerRange.start)) && 1600 (outerRange.end === null || (innerRange.end !== null && innerRange.end <= outerRange.end)); 1601 } 1602 function rangeContainsMarker(range, date) { 1603 return (range.start === null || date >= range.start) && 1604 (range.end === null || date < range.end); 1605 } 1606 // If the given date is not within the given range, move it inside. 1607 // (If it's past the end, make it one millisecond before the end). 1608 function constrainMarkerToRange(date, range) { 1609 if (range.start != null && date < range.start) { 1610 return range.start; 1611 } 1612 if (range.end != null && date >= range.end) { 1613 return new Date(range.end.valueOf() - 1); 1614 } 1615 return date; 1616 } 1617 1618 function removeExact(array, exactVal) { 1619 var removeCnt = 0; 1620 var i = 0; 1621 while (i < array.length) { 1622 if (array[i] === exactVal) { 1623 array.splice(i, 1); 1624 removeCnt++; 1625 } 1626 else { 1627 i++; 1628 } 1629 } 1630 return removeCnt; 1631 } 1632 function isArraysEqual(a0, a1) { 1633 var len = a0.length; 1634 var i; 1635 if (len !== a1.length) { // not array? or not same length? 1636 return false;
1637 } 1638 for (i = 0; i < len; i++) { 1639 if (a0[i] !== a1[i]) { 1640 return false; 1641 } 1642 } 1643 return true; 1644 } 1645 1646 function memoize(workerFunc) { 1647 var args; 1648 var res; 1649 return function () { 1650 if (!args || !isArraysEqual(args, arguments)) { 1651 args = arguments; 1652 res = workerFunc.apply(this, arguments); 1653 } 1654 return res; 1655 }; 1656 } 1657 /* 1658 always executes the workerFunc, but if the result is equal to the previous result, 1659 return the previous result instead. 1660 */ 1661 function memoizeOutput(workerFunc, equalityFunc) { 1662 var cachedRes = null; 1663 return function () { 1664 var newRes = workerFunc.apply(this, arguments); 1665 if (cachedRes === null || !(cachedRes === newRes || equalityFunc(cachedRes, newRes))) { 1666 cachedRes = newRes; 1667 } 1668 return cachedRes; 1669 }; 1670 } 1671 1672 var EXTENDED_SETTINGS_AND_SEVERITIES = { 1673 week: 3, 1674 separator: 0, 1675 omitZeroMinute: 0, 1676 meridiem: 0, 1677 omitCommas: 0 1678 }; 1679 var STANDARD_DATE_PROP_SEVERITIES = { 1680 timeZoneName: 7, 1681 era: 6, 1682 year: 5, 1683 month: 4, 1684 day: 2, 1685 weekday: 2, 1686 hour: 1, 1687 minute: 1, 1688 second: 1 1689 }; 1690 var MERIDIEM_RE = /\s*([ap])\.?m\.?/i; // eats up leading spaces too 1691 var COMMA_RE = /,/g; // we need re for globalness 1692 var MULTI_SPACE_RE = /\s+/g; 1693 var LTR_RE = /\u200e/g; // control character 1694 var UTC_RE = /UTC|GMT/; 1695 var NativeFormatter = /** @class */ (function () { 1696 function NativeFormatter(formatSettings) { 1697 var standardDateProps = {}; 1698 var extendedSettings = {}; 1699 var severity = 0; 1700 for (var name_1 in formatSettings) { 1701 if (name_1 in EXTENDED_SETTINGS_AND_SEVERITIES) { 1702 extendedSettings[name_1] = formatSettings[name_1]; 1703 severity = Math.max(EXTENDED_SETTINGS_AND_SEVERITIES[name_1], severity); 1704 } 1705 else { 1706 standardDateProps[name_1] = formatSettings[name_1]; 1707 if (name_1 in STANDARD_DATE_PROP_SEVERITIES) { 1708 severity = Math.max(STANDARD_DATE_PROP_SEVERITIES[name_1], severity); 1709 } 1710 } 1711 } 1712 this.standardDateProps = standardDateProps; 1713 this.extendedSettings = extendedSettings; 1714 this.severity = severity; 1715 this.buildFormattingFunc = memoize(buildFormattingFunc); 1716 } 1717 NativeFormatter.prototype.format = function (date, context) { 1718 return this.buildFormattingFunc(this.standardDateProps, this.extendedSettings, context)(date); 1719 }; 1720 NativeFormatter.prototype.formatRange = function (start, end, context) { 1721 var _a = this, standardDateProps = _a.standardDateProps, extendedSettings = _a.extendedSettings; 1722 var diffSeverity = computeMarkerDiffSeverity(start.marker, end.marker, context.calendarSystem); 1723 if (!diffSeverity) { 1724 return this.format(start, context); 1725 } 1726 var biggestUnitForPartial = diffSeverity; 1727 if (biggestUnitForPartial > 1 && // the two dates are different in a way that's larger scale than time 1728 (standardDateProps.year === 'numeric' || standardDateProps.year === '2-digit') && 1729 (standardDateProps.month === 'numeric' || standardDateProps.month === '2-digit') && 1730 (standardDateProps.day === 'numeric' || standardDateProps.day === '2-digit')) { 1731 biggestUnitForPartial = 1; // make it look like the dates are only different in terms of time 1732 } 1733 var full0 = this.format(start, context); 1734 var full1 = this.format(end, context); 1735 if (full0 === full1) { 1736 return full0; 1737 } 1738 var partialDateProps = computePartialFormattingOptions(standardDateProps, biggestUnitForParti
1738al); 1739 var partialFormattingFunc = buildFormattingFunc(partialDateProps, extendedSettings, context); 1740 var partial0 = partialFormattingFunc(start); 1741 var partial1 = partialFormattingFunc(end); 1742 var insertion = findCommonInsertion(full0, partial0, full1, partial1); 1743 var separator = extendedSettings.separator || ''; 1744 if (insertion) { 1745 return insertion.before + partial0 + separator + partial1 + insertion.after; 1746 } 1747 return full0 + separator + full1; 1748 }; 1749 NativeFormatter.prototype.getLargestUnit = function () { 1750 switch (this.severity) { 1751 case 7: 1752 case 6: 1753 case 5: 1754 return 'year'; 1755 case 4: 1756 return 'month'; 1757 case 3: 1758 return 'week'; 1759 default: 1760 return 'day'; 1761 } 1762 }; 1763 return NativeFormatter; 1764 }()); 1765 function buildFormattingFunc(standardDateProps, extendedSettings, context) { 1766 var standardDatePropCnt = Object.keys(standardDateProps).length; 1767 if (standardDatePropCnt === 1 && standardDateProps.timeZoneName === 'short') { 1768 return function (date) { 1769 return formatTimeZoneOffset(date.timeZoneOffset); 1770 }; 1771 } 1772 if (standardDatePropCnt === 0 && extendedSettings.week) { 1773 return function (date) { 1774 return formatWeekNumber(context.computeWeekNumber(date.marker), context.weekLabel, context.locale, extendedSettings.week); 1775 }; 1776 } 1777 return buildNativeFormattingFunc(standardDateProps, extendedSettings, context); 1778 } 1779 function buildNativeFormattingFunc(standardDateProps, extendedSettings, context) { 1780 standardDateProps = __assign({}, standardDateProps); // copy 1781 extendedSettings = __assign({}, extendedSettings); // copy 1782 sanitizeSettings(standardDateProps, extendedSettings); 1783 standardDateProps.timeZone = 'UTC'; // we leverage the only guaranteed timeZone for our UTC markers 1784 var normalFormat = new Intl.DateTimeFormat(context.locale.codes, standardDateProps); 1785 var zeroFormat; // needed? 1786 if (extendedSettings.omitZeroMinute) { 1787 var zeroProps = __assign({}, standardDateProps); 1788 delete zeroProps.minute; // seconds and ms were already considered in sanitizeSettings 1789 zeroFormat = new Intl.DateTimeFormat(context.locale.codes, zeroProps); 1790 } 1791 return function (date) { 1792 var marker = date.marker; 1793 var format; 1794 if (zeroFormat && !marker.getUTCMinutes()) { 1795 format = zeroFormat; 1796 } 1797 else { 1798 format = normalFormat; 1799 } 1800 var s = format.format(marker); 1801 return postProcess(s, date, standardDateProps, extendedSettings, context); 1802 }; 1803 } 1804 function sanitizeSettings(standardDateProps, extendedSettings) { 1805 // deal with a browser inconsistency where formatting the timezone 1806 // requires that the hour/minute be present. 1807 if (standardDateProps.timeZoneName) { 1808 if (!standardDateProps.hour) { 1809 standardDateProps.hour = '2-digit'; 1810 } 1811 if (!standardDateProps.minute) { 1812 standardDateProps.minute = '2-digit'; 1813 } 1814 } 1815 // only support short timezone names 1816 if (standardDateProps.timeZoneName === 'long') { 1817 standardDateProps.timeZoneName = 'short'; 1818 } 1819 // if requesting to display seconds, MUST display minutes 1820 if (extendedSettings.omitZeroMinute && (standardDateProps.second || standardDateProps.millisecond)) { 1821 delete extendedSettings.omitZeroMinute; 1822 } 1823 } 1824 function postProcess(s, date, standardDateProps, extendedSettings, context) { 1825 s = s.replace(LTR_RE, ''); // remove left-to-right control chars. do first. good for other regexes 1826 if (standardDateProps.timeZoneName === 'short') { 1827 s = injectTzoStr(s, (context.timeZone === 'UTC' || date.timeZoneOffset == null) ? 1828 'UTC' : // important to normalize for IE, which does "GMT" 1829 formatTimeZoneOffset(date.timeZoneOffset)); 1830 } 1831 if (extendedSettings.omitCommas) { 1832 s = s.replace(COMMA_RE, '').trim(); 1833 } 1834 if (extendedSettings.omitZeroMinute) { 1835 s = s.replace(':00', ''); // zeroFormat doesn't always achieve this 1836 } 1837 // ^ do anything that might create adjacent spaces before this point,
1838 // because MERIDIEM_RE likes to eat up loading spaces 1839 if (extendedSettings.meridiem === false) { 1840 s = s.replace(MERIDIEM_RE, '').trim(); 1841 } 1842 else if (extendedSettings.meridiem === 'narrow') { // a/p 1843 s = s.replace(MERIDIEM_RE, function (m0, m1) { 1844 return m1.toLocaleLowerCase(); 1845 }); 1846 } 1847 else if (extendedSettings.meridiem === 'short') { // am/pm 1848 s = s.replace(MERIDIEM_RE, function (m0, m1) { 1849 return m1.toLocaleLowerCase() + 'm'; 1850 }); 1851 } 1852 else if (extendedSettings.meridiem === 'lowercase') { // other meridiem transformers already converted to lowercase 1853 s = s.replace(MERIDIEM_RE, function (m0) { 1854 return m0.toLocaleLowerCase(); 1855 }); 1856 } 1857 s = s.replace(MULTI_SPACE_RE, ' '); 1858 s = s.trim(); 1859 return s; 1860 } 1861 function injectTzoStr(s, tzoStr) { 1862 var replaced = false; 1863 s = s.replace(UTC_RE, function () { 1864 replaced = true; 1865 return tzoStr; 1866 }); 1867 // IE11 doesn't include UTC/GMT in the original string, so append to end 1868 if (!replaced) { 1869 s += ' ' + tzoStr; 1870 } 1871 return s; 1872 } 1873 function formatWeekNumber(num, weekLabel, locale, display) { 1874 var parts = []; 1875 if (display === 'narrow') { 1876 parts.push(weekLabel); 1877 } 1878 else if (display === 'short') { 1879 parts.push(weekLabel, ' '); 1880 } 1881 // otherwise, considered 'numeric' 1882 parts.push(locale.simpleNumberFormat.format(num)); 1883 if (locale.options.isRtl) { // TODO: use control characters instead? 1884 parts.reverse(); 1885 } 1886 return parts.join(''); 1887 } 1888 // Range Formatting Utils 1889 // 0 = exactly the same 1890 // 1 = different by time 1891 // and bigger 1892 function computeMarkerDiffSeverity(d0, d1, ca) { 1893 if (ca.getMarkerYear(d0) !== ca.getMarkerYear(d1)) { 1894 return 5; 1895 } 1896 if (ca.getMarkerMonth(d0) !== ca.getMarkerMonth(d1)) { 1897 return 4; 1898 } 1899 if (ca.getMarkerDay(d0) !== ca.getMarkerDay(d1)) { 1900 return 2; 1901 } 1902 if (timeAsMs(d0) !== timeAsMs(d1)) { 1903 return 1; 1904 } 1905 return 0; 1906 } 1907 function computePartialFormattingOptions(options, biggestUnit) { 1908 var partialOptions = {}; 1909 for (var name_2 in options) { 1910 if (!(name_2 in STANDARD_DATE_PROP_SEVERITIES) || // not a date part prop (like timeZone) 1911 STANDARD_DATE_PROP_SEVERITIES[name_2] <= biggestUnit) { 1912 partialOptions[name_2] = options[name_2]; 1913 } 1914 } 1915 return partialOptions; 1916 } 1917 function findCommonInsertion(full0, partial0, full1, partial1) { 1918 var i0 = 0; 1919 while (i0 < full0.length) { 1920 var found0 = full0.indexOf(partial0, i0); 1921 if (found0 === -1) { 1922 break; 1923 } 1924 var before0 = full0.substr(0, found0); 1925 i0 = found0 + partial0.length; 1926 var after0 = full0.substr(i0); 1927 var i1 = 0; 1928 while (i1 < full1.length) { 1929 var found1 = full1.indexOf(partial1, i1); 1930 if (found1 === -1) { 1931 break; 1932 } 1933 var before1 = full1.substr(0, found1); 1934 i1 = found1 + partial1.length; 1935 var after1 = full1.substr(i1); 1936 if (before0 === before1 && after0 === after1) { 1937 return { 1938 before: before0, 1939 after: after0 1940 }; 1941 } 1942 } 1943 } 1944 return null; 1945 } 1946 1947 /* 1948 TODO: fix the terminology of "formatter" vs "formatting func" 1949 */ 1950 /* 1951 At the time of instantiation, this object does not know which cmd-formatting system it will use. 1952 It receives this at the time of formatting, as a setting. 1953 */ 1954 var CmdFormatter = /** @class */ (function () { 1955 function CmdFormatter(cmdStr, separator) { 1956 this.cmdStr = cmdStr; 1957 this.separator = separator; 1958 } 1959 CmdFormatter.prototype.format = function (date, context) { 1960 return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(date, null, context, this.separator)); 1961 }; 1962 CmdFormatter.prototype.formatRange = function (start, end, context) { 1963 return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(start, end, context, this.separator)); 1964 }; 1965 return CmdFormatter; 1966 }()); 1967 1968 var FuncFormatter = /** @class */ (function () { 1969 function FuncFormatter(func) { 1970 this.func = func; 1971 } 1972 FuncFormatter.prototype.format = function (date, context) { 1973 return this.func(createVerboseFormattingArg(date, null, context)); 1974 }; 1975 FuncFormatter.prototype.formatRange = function (start, end, context) { 1976 return this.func(createVerboseFormattingArg(start, end, context)); 1977 }; 1978 return FuncFormatter; 1979 }()); 1980 1981 // Formatter Object Creation 1982 function createFormatter(input, defaultSeparator) { 1983 if (typeof input === 'object' && input) { // non-null object 1984 if (typeof defaultSeparator === 'string') { 1985 input = __assign({ separator: defaultSeparator }, input); 1986 } 1987 return new NativeFormatter(input); 1988 } 1989 else if (typeof input === 'string') { 1990 return new CmdFormatter(input, defaultSeparator); 1991 } 1992 else if (typeof input === 'function') { 1993 return new FuncFormatter(input); 1994 } 1995 } 1996 // String Utils 1997 // timeZoneOffset is in minutes 1998 function buildIsoString(marker, timeZoneOffset, stripZeroTime) { 1999 if (stripZeroTime === void 0) { stripZeroTime = false; } 2000 var s = marker.toISOString(); 2001 s = s.replace('.000', ''); 2002 if (stripZeroTime) { 2003 s = s.replace('T00:00:00Z', ''); 2004 } 2005 if (s.length > 10) { // time part wasn't stripped, can add timezone info 2006 if (timeZoneOffset == null) { 2007 s = s.replace('Z', ''); 2008 } 2009 else if (timeZoneOffset !== 0) { 2010 s = s.replace('Z', formatTimeZoneOffset(timeZoneOffset, true)); 2011 } 2012 // otherwise, its UTC-0 and we want to keep the Z 2013 } 2014 return s; 2015 } 2016 function formatIsoTimeString(marker) { 2017 return padStart(marker.getUTCHours(), 2) + ':' + 2018 padStart(marker.getUTCMinutes(), 2) + ':' + 2019 padStart(marker.getUTCSeconds(), 2); 2020 } 2021 function formatTimeZoneOffset(minutes, doIso) { 2022 if (doIso === void 0) { doIso = false; } 2023 var sign = minutes < 0 ? '-' : '+'; 2024 var abs = Math.abs(minutes); 2025 var hours = Math.floor(abs / 60); 2026 var mins = Math.round(abs % 60); 2027 if (doIso) { 2028 return sign + padStart(hours, 2) + ':' + padStart(mins, 2); 2029 } 2030 else { 2031 return 'GMT' + sign + hours + (mins ? ':' + padStart(mins, 2) : ''); 2032 } 2033 } 2034 // Arg Utils 2035 function createVerboseFormattingArg(start, end, context, separator) { 2036 var startInfo = expandZonedMarker(start, context.calendarSystem); 2037 var endInfo = end ? expandZonedMarker(end, context.calendarSystem) : null; 2038 return { 2039 date: startInfo, 2040 start: startInfo, 2041 end: endInfo, 2042 timeZone: context.timeZone, 2043 localeCodes: context.locale.codes, 2044 separator: separator 2045 }; 2046 } 2047 function expandZonedMarker(dateInfo, calendarSystem) { 2048 var a = calendarSystem.markerToArray(dateInfo.marker); 2049 return { 2050 marker: dateInfo.marker, 2051 timeZoneOffset: dateInfo.timeZoneOffset, 2052 array: a, 2053 year: a[0], 2054 month: a[1], 2055 day: a[2], 2056 hour: a[3], 2057 minute: a[4], 2058 second: a[5], 2059 millisecond: a[6] 2060 }; 2061 } 2062 2063 var EventSourceApi = /** @class */ (function () { 2064 function EventSourceApi(calendar, internalEventSource) { 2065 this.calendar = calendar; 2066 this.internalEventSource = internalEventSource; 2067 } 2068 EventSourceApi.prototype.remove = function () { 2069 this.calendar.dispatch({
2070 type: 'REMOVE_EVENT_SOURCE', 2071 sourceId: this.internalEventSource.sourceId 2072 }); 2073 }; 2074 EventSourceApi.prototype.refetch = function () { 2075 this.calendar.dispatch({ 2076 type: 'FETCH_EVENT_SOURCES', 2077 sourceIds: [this.internalEventSource.sourceId] 2078 }); 2079 }; 2080 Object.defineProperty(EventSourceApi.prototype, "id", { 2081 get: function () { 2082 return this.internalEventSource.publicId; 2083 }, 2084 enumerable: true, 2085 configurable: true 2086 }); 2087 Object.defineProperty(EventSourceApi.prototype, "url", { 2088 // only relevant to json-feed event sources 2089 get: function () { 2090 return this.internalEventSource.meta.url; 2091 }, 2092 enumerable: true, 2093 configurable: true 2094 }); 2095 return EventSourceApi; 2096 }()); 2097 2098 var EventApi = /** @class */ (function () { 2099 function EventApi(calendar, def, instance) { 2100 this._calendar = calendar; 2101 this._def = def; 2102 this._instance = instance || null; 2103 } 2104 /* 2105 TODO: make event struct more responsible for this 2106 */ 2107 EventApi.prototype.setProp = function (name, val) { 2108 var _a, _b; 2109 if (name in DATE_PROPS) ; 2110 else if (name in NON_DATE_PROPS) { 2111 if (typeof NON_DATE_PROPS[name] === 'function') { 2112 val = NON_DATE_PROPS[name](val); 2113 } 2114 this.mutate({ 2115 standardProps: (_a = {}, _a[name] = val, _a) 2116 }); 2117 } 2118 else if (name in UNSCOPED_EVENT_UI_PROPS) { 2119 var ui = void 0; 2120 if (typeof UNSCOPED_EVENT_UI_PROPS[name] === 'function') { 2121 val = UNSCOPED_EVENT_UI_PROPS[name](val); 2122 } 2123 if (name === 'color') { 2124 ui = { backgroundColor: val, borderColor: val }; 2125 } 2126 else if (name === 'editable') { 2127 ui = { startEditable: val, durationEditable: val }; 2128 } 2129 else { 2130 ui = (_b = {}, _b[name] = val, _b); 2131 } 2132 this.mutate({ 2133 standardProps: { ui: ui } 2134 }); 2135 } 2136 }; 2137 EventApi.prototype.setExtendedProp = function (name, val) { 2138 var _a; 2139 this.mutate({ 2140 extendedProps: (_a = {}, _a[name] = val, _a) 2141 }); 2142 }; 2143 EventApi.prototype.setStart = function (startInput, options) { 2144 if (options === void 0) { options = {}; } 2145 var dateEnv = this._calendar.dateEnv; 2146 var start = dateEnv.createMarker(startInput); 2147 if (start && this._instance) { // TODO: warning if parsed bad 2148 var instanceRange = this._instance.range; 2149 var startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity); // what if parsed bad!? 2150 if (options.maintainDuration) { 2151 this.mutate({ datesDelta: startDelta }); 2152 } 2153 else { 2154 this.mutate({ startDelta: startDelta }); 2155 } 2156 } 2157 }; 2158 EventApi.prototype.setEnd = function (endInput, options) { 2159 if (options === void 0) { options = {}; } 2160 var dateEnv = this._calendar.dateEnv; 2161 var end; 2162 if (endInput != null) { 2163 end = dateEnv.createMarker(endInput); 2164 if (!end) { 2165 return; // TODO: warning if parsed bad 2166 } 2167 } 2168 if (this._instance) { 2169 if (end) { 2170 var endDelta = diffDates(this._instance.range.end, end, dateEnv, options.granularity); 2171 this.mutate({ endDelta: endDelta }); 2172 } 2173 else { 2174 this.mutate({ standardProps: { hasEnd: false } }); 2175 } 2176 } 2177 }; 2178 EventApi.prototype.setDates = function (startInput, endInput, options) { 2179 if (options === void 0) { options = {}; } 2180 var dateEnv = this._calendar.dateEnv; 2181 var standardProps = { allDay: options.allDay }; 2182 var start = dateEnv.createMarker(startInput); 2183 var end; 2184 if (!start) { 2185 return; // TODO: warning if parsed bad 2186 } 2187 if (endInput != null) { 2188 end = dateEnv.createMarker(endInput); 2189 if (!end) { // TODO: warning if parsed bad 2190 return; 2191 } 2192 } 2193 if (this._instance) { 2194 var instanceRange = this._instance.range; 2195 // when computing the diff for an event being converted to all-day, 2196 // compute diff off of the all-day values the way event-mutation does. 2197 if (options.allDay === true) { 2198 instanceRange = computeAlignedDayRange(instanceRange); 2199 } 2200 var startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity); 2201 if (end) { 2202 var endDelta = diffDates(instanceRange.end, end, dateEnv, options.granularity); 2203 if (durationsEqual(startDelta, endDelta)) { 2204 this.mutate({ datesDelta: startDelta, standardProps: standardProps }); 2205 } 2206 else { 2207 this.mutate({ startDelta: startDelta, endDelta: endDelta, standardProps: standardProps }); 2208 } 2209 } 2210 else { // means "clear the end" 2211 standardProps.hasEnd = false;
2212 this.mutate({ datesDelta: startDelta, standardProps: standardProps }); 2213 } 2214 } 2215 }; 2216 EventApi.prototype.moveStart = function (deltaInput) { 2217 var delta = createDuration(deltaInput); 2218 if (delta) { // TODO: warning if parsed bad 2219 this.mutate({ startDelta: delta }); 2220 } 2221 }; 2222 EventApi.prototype.moveEnd = function (deltaInput) { 2223 var delta = createDuration(deltaInput); 2224 if (delta) { // TODO: warning if parsed bad 2225 this.mutate({ endDelta: delta }); 2226 } 2227 }; 2228 EventApi.prototype.moveDates = function (deltaInput) { 2229 var delta = createDuration(deltaInput); 2230 if (delta) { // TODO: warning if parsed bad 2231 this.mutate({ datesDelta: delta }); 2232 } 2233 }; 2234 EventApi.prototype.setAllDay = function (allDay, options) { 2235 if (options === void 0) { options = {}; } 2236 var standardProps = { allDay: allDay }; 2237 var maintainDuration = options.maintainDuration; 2238 if (maintainDuration == null) { 2239 maintainDuration = this._calendar.opt('allDayMaintainDuration'); 2240 } 2241 if (this._def.allDay !== allDay) { 2242 standardProps.hasEnd = maintainDuration; 2243 } 2244 this.mutate({ standardProps: standardProps }); 2245 }; 2246 EventApi.prototype.formatRange = function (formatInput) { 2247 var dateEnv = this._calendar.dateEnv; 2248 var instance = this._instance; 2249 var formatter = createFormatter(formatInput, this._calendar.opt('defaultRangeSeparator')); 2250 if (this._def.hasEnd) { 2251 return dateEnv.formatRange(instance.range.start, instance.range.end, formatter, { 2252 forcedStartTzo: instance.forcedStartTzo, 2253 forcedEndTzo: instance.forcedEndTzo 2254 }); 2255 } 2256 else { 2257 return dateEnv.format(instance.range.start, formatter, { 2258 forcedTzo: instance.forcedStartTzo 2259 }); 2260 } 2261 }; 2262 EventApi.prototype.mutate = function (mutation) { 2263 var def = this._def; 2264 var instance = this._instance; 2265 if (instance) { 2266 this._calendar.dispatch({ 2267 type: 'MUTATE_EVENTS', 2268 instanceId: instance.instanceId, 2269 mutation: mutation, 2270 fromApi: true 2271 }); 2272 var eventStore = this._calendar.state.eventStore; 2273 this._def = eventStore.defs[def.defId]; 2274 this._instance = eventStore.instances[instance.instanceId]; 2275 } 2276 }; 2277 EventApi.prototype.remove = function () { 2278 this._calendar.dispatch({ 2279 type: 'REMOVE_EVENT_DEF', 2280 defId: this._def.defId 2281 }); 2282 }; 2283 Object.defineProperty(EventApi.prototype, "source", { 2284 get: function () { 2285 var sourceId = this._def.sourceId; 2286 if (sourceId) { 2287 return new EventSourceApi(this._calendar, this._calendar.state.eventSources[sourceId]); 2288 } 2289 return null; 2290 }, 2291 enumerable: true, 2292 configurable: true 2293 }); 2294 Object.defineProperty(EventApi.prototype, "start", { 2295 get: function () { 2296 return this._instance ? 2297 this._calendar.dateEnv.toDate(this._instance.range.start) : 2298 null; 2299 }, 2300 enumerable: true, 2301 configurable: true 2302 }); 2303 Object.defineProperty(EventApi.prototype, "end", { 2304 get: function () { 2305 return (this._instance && this._def.hasEnd) ? 2306 this._calendar.dateEnv.toDate(this._instance.range.end) : 2307 null; 2308 }, 2309 enumerable: true, 2310 configurable: true 2311 }); 2312 Object.defineProperty(EventApi.prototype, "id", { 2313 // computable props that all access the def
2314 // TODO: find a TypeScript-compatible way to do this at scale 2315 get: function () { return this._def.publicId; }, 2316 enumerable: true, 2317 configurable: true 2318 }); 2319 Object.defineProperty(EventApi.prototype, "groupId", { 2320 get: function () { return this._def.groupId; }, 2321 enumerable: true, 2322 configurable: true 2323 }); 2324 Object.defineProperty(EventApi.prototype, "allDay", { 2325 get: function () { return this._def.allDay; }, 2326 enumerable: true, 2327 configurable: true 2328 }); 2329 Object.defineProperty(EventApi.prototype, "title", { 2330 get: function () { return this._def.title; }, 2331 enumerable: true, 2332 configurable: true 2333 }); 2334 Object.defineProperty(EventApi.prototype, "url", { 2335 get: function () { return this._def.url; }, 2336 enumerable: true, 2337 configurable: true 2338 }); 2339 Object.defineProperty(EventApi.prototype, "rendering", { 2340 get: function () { return this._def.rendering; }, 2341 enumerable: true, 2342 configurable: true 2343 }); 2344 Object.defineProperty(EventApi.prototype, "startEditable", { 2345 get: function () { return this._def.ui.startEditable; }, 2346 enumerable: true, 2347 configurable: true 2348 }); 2349 Object.defineProperty(EventApi.prototype, "durationEditable", { 2350 get: function () { return this._def.ui.durationEditable; }, 2351 enumerable: true, 2352 configurable: true 2353 }); 2354 Object.defineProperty(EventApi.prototype, "constraint", { 2355 get: function () { return this._def.ui.constraints[0] || null; }, 2356 enumerable: true, 2357 configurable: true 2358 }); 2359 Object.defineProperty(EventApi.prototype, "overlap", { 2360 get: function () { return this._def.ui.overlap; }, 2361 enumerable: true, 2362 configurable: true 2363 }); 2364 Object.defineProperty(EventApi.prototype, "allow", { 2365 get: function () { return this._def.ui.allows[0] || null; }, 2366 enumerable: true, 2367 configurable: true 2368 }); 2369 Object.defineProperty(EventApi.prototype, "backgroundColor", { 2370 get: function () { return this._def.ui.backgroundColor; }, 2371 enumerable: true, 2372 configurable: true 2373 }); 2374 Object.defineProperty(EventApi.prototype, "borderColor", { 2375 get: function () { return this._def.ui.borderColor; }, 2376 enumerable: true, 2377 configurable: true 2378 }); 2379 Object.defineProperty(EventApi.prototype, "textColor", { 2380 get: function () { return this._def.ui.textColor; }, 2381 enumerable: true, 2382 configurable: true 2383 }); 2384 Object.defineProperty(EventApi.prototype, "classNames", { 2385 // NOTE: user can't modify these because Object.freeze was called in event-def parsing 2386 get: function () { return this._def.ui.classNames; }, 2387 enumerable: true, 2388 configurable: true 2389 }); 2390 Object.defineProperty(EventApi.prototype, "extendedProps", { 2391 get: function () { return this._def.extendedProps; }, 2392 enumerable: true, 2393 configurable: true 2394 }); 2395 return EventApi; 2396 }()); 2397 2398 /* 2399 Specifying nextDayThreshold signals that all-day ranges should be sliced. 2400 */ 2401 function sliceEventStore(eventStore, eventUiBases, framingRange, nextDayThreshold) { 2402 var inverseBgByGroupId = {}; 2403 var inverseBgByDefId = {}; 2404 var defByGroupId = {}; 2405 var bgRanges = []; 2406 var fgRanges = []; 2407 var eventUis = compileEventUis(eventStore.defs, eventUiBases); 2408 for (var defId in eventStore.defs) { 2409 var def = eventStore.defs[defId]; 2410 if (def.rendering === 'inverse-background') { 2411 if (def.groupId) { 2412 inverseBgByGroupId[def.groupId] = []; 2413 if (!defByGroupId[def.groupId]) { 2414 defByGroupId[def.groupId] = def; 2415 } 2416 } 2417 else { 2418 inverseBgByDefId[defId] = []; 2419 } 2420 } 2421 } 2422 for (var instanceId in eventStore.instances) { 2423 var instance = eventStore.instances[instanceId]; 2424 var def = eventStore.defs[instance.defId]; 2425 var ui = eventUis[def.defId]; 2426 var origRange = instance.range; 2427 var normalRange = (!def.allDay && nextDayThreshold) ? 2428 computeVisibleDayRange(origRange, nextDayThreshold) : 2429 origRange; 2430 var slicedRange = intersectRanges(normalRange, framingRange); 2431 if (slicedRange) { 2432 if (def.rendering === 'inverse-background') { 2433 if (def.groupId) { 2434 inverseBgByGroupId[def.groupId].push(slicedRange); 2435 } 2436 else { 2437 inverseBgByDefId[instance.defId].push(slicedRange); 2438 } 2439 } 2440 else { 2441 (def.rendering === 'background' ? bgRanges : fgRanges).push({ 2442 def: def, 2443 ui: ui, 2444 instance: instance, 2445 range: slicedRange, 2446 isStart: normalRange.start && normalRange.start.valueOf() === slicedRange.start.valueOf(), 2447 isEnd: normalRange.end && normalRange.end.valueOf() === slicedRange.end.valueOf() 2448 }); 2449 } 2450 } 2451 } 2452 for (var groupId in inverseBgByGroupId) { // BY GROUP 2453 var ranges = inverseBgByGroupId[groupId]; 2454 var invertedRanges = invertRanges(ranges, framingRange); 2455 for (var _i = 0, invertedRanges_1 = invertedRanges; _i < invertedRanges_1.length; _i++) { 2456 var invertedRange = invertedRanges_1[_i]; 2457 var def = defByGroupId[groupId]; 2458 var ui = eventUis[def.defId]; 2459 bgRanges.push({ 2460 def: def, 2461 ui: ui, 2462 instance: null, 2463 range: invertedRange, 2464 isStart: false, 2465 isEnd: false 2466 }); 2467 } 2468 } 2469 for (var defId in inverseBgByDefId) { 2470 var ranges = inverseBgByDefId[defId]; 2471 var invertedRanges = invertRanges(ranges, framingRange); 2472 for (var _a = 0, invertedRanges_2 = invertedRanges; _a < invertedRanges_2.length; _a++) { 2473 var invertedRange = invertedRanges_2[_a]; 2474 bgRanges.push({ 2475 def: eventStore.defs[defId], 2476 ui: eventUis[defId], 2477 instance: null, 2478 range: invertedRange, 2479 isStart: false, 2480 isEnd: false 2481 }); 2482 } 2483 } 2484 return { bg: bgRanges, fg: fgRanges }; 2485 } 2486 function hasBgRendering(def) { 2487 return def.rendering === 'background' || def.rendering === 'inverse-background'; 2488 } 2489 function filterSegsViaEls(view, segs, isMirror) { 2490 if (view.hasPublicHandlers('eventRender')) { 2491 segs = segs.filter(function (seg) { 2492 var custom = view.publiclyTrigger('eventRender', [ 2493 { 2494 event: new EventApi(view.calendar, seg.eventRange.def, seg.eventRange.instance), 2495 isMirror: isMirror, 2496 isStart: seg.isStart, 2497 isEnd: seg.isEnd, 2498 // TODO: include seg.range once all components consistently generate it 2499 el: seg.el, 2500 view: view 2501 } 2502 ]); 2503 if (custom === false) { // means don't render at all 2504 return false;
2505 } 2506 else if (custom && custom !== true) { 2507 seg.el = custom; 2508 } 2509 return true; 2510 }); 2511 } 2512 for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) { 2513 var seg = segs_1[_i]; 2514 setElSeg(seg.el, seg); 2515 } 2516 return segs; 2517 } 2518 function setElSeg(el, seg) { 2519 el.fcSeg = seg; 2520 } 2521 function getElSeg(el) { 2522 return el.fcSeg || null; 2523 } 2524 // event ui computation 2525 function compileEventUis(eventDefs, eventUiBases) { 2526 return mapHash(eventDefs, function (eventDef) { 2527 return compileEventUi(eventDef, eventUiBases); 2528 }); 2529 } 2530 function compileEventUi(eventDef, eventUiBases) { 2531 var uis = []; 2532 if (eventUiBases['']) { 2533 uis.push(eventUiBases['']); 2534 } 2535 if (eventUiBases[eventDef.defId]) { 2536 uis.push(eventUiBases[eventDef.defId]); 2537 } 2538 uis.push(eventDef.ui); 2539 return combineEventUis(uis); 2540 } 2541 2542 // applies the mutation to ALL defs/instances within the event store 2543 function applyMutationToEventStore(eventStore, eventConfigBase, mutation, calendar) { 2544 var eventConfigs = compileEventUis(eventStore.defs, eventConfigBase); 2545 var dest = createEmptyEventStore(); 2546 for (var defId in eventStore.defs) { 2547 var def = eventStore.defs[defId]; 2548 dest.defs[defId] = applyMutationToEventDef(def, eventConfigs[defId], mutation, calendar.pluginSystem.hooks.eventDefMutationAppliers, calendar); 2549 } 2550 for (var instanceId in eventStore.instances) { 2551 var instance = eventStore.instances[instanceId]; 2552 var def = dest.defs[instance.defId]; // important to grab the newly modified def 2553 dest.instances[instanceId] = applyMutationToEventInstance(instance, def, eventConfigs[instance.defId], mutation, calendar); 2554 } 2555 return dest; 2556 } 2557 function applyMutationToEventDef(eventDef, eventConfig, mutation, appliers, calendar) { 2558 var standardProps = mutation.standardProps || {}; 2559 // if hasEnd has not been specified, guess a good value based on deltas. 2560 // if duration will change, there's no way the default duration will persist, 2561 // and thus, we need to mark the event as having a real end 2562 if (standardProps.hasEnd == null && 2563 eventConfig.durationEditable && 2564 (mutation.startDelta || mutation.endDelta)) { 2565 standardProps.hasEnd = true; // TODO: is this mutation okay? 2566 } 2567 var copy = __assign({}, eventDef, standardProps, { ui: __assign({}, eventDef.ui, standardProps.ui) }); 2568 if (mutation.extendedProps) { 2569 copy.extendedProps = __assign({}, copy.extendedProps, mutation.extendedProps); 2570 } 2571 for (var _i = 0, appliers_1 = appliers; _i < appliers_1.length; _i++) { 2572 var applier = appliers_1[_i]; 2573 applier(copy, mutation, calendar); 2574 } 2575 if (!copy.hasEnd && calendar.opt('forceEventDuration')) { 2576 copy.hasEnd = true; 2577 } 2578 return copy; 2579 } 2580 function applyMutationToEventInstance(eventInstance, eventDef, // must first be modified by applyMutationToEventDef 2581 eventConfig, mutation, calendar) { 2582 var dateEnv = calendar.dateEnv; 2583 var forceAllDay = mutation.standardProps && mutation.standardProps.allDay === true; 2584 var clearEnd = mutation.standardProps && mutation.standardProps.hasEnd === false; 2585 var copy = __assign({}, eventInstance); 2586 if (forceAllDay) { 2587 copy.range = computeAlignedDayRange(copy.range); 2588 } 2589 if (mutation.datesDelta && eventConfig.startEditable) { 2590 copy.range = { 2591 start: dateEnv.add(copy.range.start, mutation.datesDelta), 2592 end: dateEnv.add(copy.range.end, mutation.datesDelta) 2593 }; 2594 } 2595 if (mutation.startDelta && eventConfig.durationEditable) { 2596 copy.range = { 2597 start: dateEnv.add(copy.range.start, mutation.startDelta), 2598 end: copy.range.end 2599 }; 2600 } 2601 if (mutation.endDelta && eventConfig.durationEditable) { 2602 copy.range = { 2603 start: copy.range.start, 2604 end: dateEnv.add(copy.range.end, mutation.endDelta) 2605 }; 2606 } 2607 if (clearEnd) { 2608 copy.range = { 2609 start: copy.range.start, 2610 end: calendar.getDefaultEventEnd(eventDef.allDay, copy.range.start) 2611 }; 2612 } 2613 // in case event was all-day but the supplied deltas were not 2614 // better util for this? 2615 if (eventDef.allDay) { 2616 copy.range = { 2617 start: startOfDay(copy.range.start), 2618 end: startOfDay(copy.range.end) 2619 }; 2620 } 2621 // handle invalid durations 2622 if (copy.range.end < copy.range.start) { 2623 copy.range.end = calendar.getDefaultEventEnd(eventDef.allDay, copy.range.start); 2624 } 2625 return copy; 2626 } 2627 2628 function reduceEventStore (eventStore, action, eventSources, dateProfile, calendar) { 2629 switch (action.type) { 2630 case 'RECEIVE_EVENTS': // raw 2631 return receiveRawEvents(eventStore, eventSources[action.sourceId], action.fetchId, action.fetchRange, action.rawEvents, calendar); 2632 case 'ADD_EVENTS': // already parsed, but not expanded 2633 return addEvent(eventStore, action.eventStore, // new ones 2634 dateProfile ? dateProfile.activeRange : null, calendar); 2635 case 'MERGE_EVENTS': // already parsed and expanded 2636 return mergeEventStores(eventStore, action.eventStore); 2637 case 'PREV': // TODO: how do we track all actions that affect dateProfile :( 2638 case 'NEXT': 2639 case 'SET_DATE': 2640 case 'SET_VIEW_TYPE': 2641 if (dateProfile) { 2642 return expandRecurring(eventStore, dateProfile.activeRange, calendar); 2643 } 2644 else { 2645 return eventStore; 2646 } 2647 case 'CHANGE_TIMEZONE': 2648 return rezoneDates(eventStore, action.oldDateEnv, calendar.dateEnv); 2649 case 'MUTATE_EVENTS': 2650 return applyMutationToRelated(eventStore, action.instanceId, action.mutation, action.fromApi, calendar);
2651 case 'REMOVE_EVENT_INSTANCES': 2652 return excludeInstances(eventStore, action.instances); 2653 case 'REMOVE_EVENT_DEF': 2654 return filterEventStoreDefs(eventStore, function (eventDef) { 2655 return eventDef.defId !== action.defId; 2656 }); 2657 case 'REMOVE_EVENT_SOURCE': 2658 return excludeEventsBySourceId(eventStore, action.sourceId); 2659 case 'REMOVE_ALL_EVENT_SOURCES': 2660 return filterEventStoreDefs(eventStore, function (eventDef) { 2661 return !eventDef.sourceId; // only keep events with no source id 2662 }); 2663 case 'REMOVE_ALL_EVENTS': 2664 return createEmptyEventStore(); 2665 case 'RESET_EVENTS': 2666 return { 2667 defs: eventStore.defs, 2668 instances: eventStore.instances 2669 }; 2670 default: 2671 return eventStore; 2672 } 2673 } 2674 function receiveRawEvents(eventStore, eventSource, fetchId, fetchRange, rawEvents, calendar) { 2675 if (eventSource && // not already removed 2676 fetchId === eventSource.latestFetchId // TODO: wish this logic was always in event-sources 2677 ) { 2678 var subset = parseEvents(transformRawEvents(rawEvents, eventSource, calendar), eventSource.sourceId, calendar); 2679 if (fetchRange) { 2680 subset = expandRecurring(subset, fetchRange, calendar); 2681 } 2682 return mergeEventStores(excludeEventsBySourceId(eventStore, eventSource.sourceId), subset); 2683 } 2684 return eventStore; 2685 } 2686 function addEvent(eventStore, subset, expandRange, calendar) { 2687 if (expandRange) { 2688 subset = expandRecurring(subset, expandRange, calendar); 2689 } 2690 return mergeEventStores(eventStore, subset); 2691 } 2692 function rezoneDates(eventStore, oldDateEnv, newDateEnv) { 2693 var defs = eventStore.defs; 2694 var instances = mapHash(eventStore.instances, function (instance) { 2695 var def = defs[instance.defId]; 2696 if (def.allDay || def.recurringDef) { 2697 return instance; // isn't dependent on timezone 2698 } 2699 else { 2700 return __assign({}, instance, { range: { 2701 start: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.start, instance.forcedStartTzo)), 2702 end: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.end, instance.forcedEndTzo)) 2703 }, forcedStartTzo: newDateEnv.canComputeOffset ? null : instance.forcedStartTzo, forcedEndTzo: newDateEnv.canComputeOffset ? null : instance.forcedEndTzo }); 2704 } 2705 }); 2706 return { defs: defs, instances: instances }; 2707 } 2708 function applyMutationToRelated(eventStore, instanceId, mutation, fromApi, calendar) { 2709 var relevant = getRelevantEvents(eventStore, instanceId); 2710 var eventConfigBase = fromApi ? 2711 { '': { 2712 startEditable: true, 2713 durationEditable: true, 2714 constraints: [], 2715 overlap: null, 2716 allows: [], 2717 backgroundColor: '', 2718 borderColor: '', 2719 textColor: '', 2720 classNames: [] 2721 } } : 2722 calendar.eventUiBases; 2723 relevant = applyMutationToEventStore(relevant, eventConfigBase, mutation, calendar); 2724 return mergeEventStores(eventStore, relevant); 2725 } 2726 function excludeEventsBySourceId(eventStore, sourceId) { 2727 return filterEventStoreDefs(eventStore, function (eventDef) { 2728 return eventDef.sourceId !== sourceId; 2729 }); 2730 } 2731 // QUESTION: why not just return instances? do a general object-property-exclusion util 2732 function excludeInstances(eventStore, removals) { 2733 return { 2734 defs: eventStore.defs, 2735 instances: filterHash(eventStore.instances, function (instance) { 2736 return !removals[instance.instanceId]; 2737 }) 2738 }; 2739 } 2740 2741 // high-level segmenting-aware tester functions 2742 // ------------------------------------------------------------------------------------------------------------------------ 2743 function isInteractionValid(interaction, calendar) { 2744 return isNewPropsValid({ eventDrag: interaction }, calendar); // HACK: the eventDrag props is used for ALL interactions 2745 } 2746 function isDateSelectionValid(dateSelection, calendar) { 2747 return isNewPropsValid({ dateSelection: dateSelection }, calendar); 2748 } 2749 function isNewPropsValid(newProps, calendar) { 2750 var view = calendar.view; 2751 var props = __assign({ businessHours: view ? view.props.businessHours : createEmptyEventStore(), dateSelection: '', eventStore: calendar.state.eventStore, eventUiBases: calendar.eventUiBases, eventSelection: '', eventDrag: null, eventResize: null }, newProps); 2752 return (calendar.pluginSystem.hooks.isPropsValid || isPropsValid)(props, calendar); 2753 } 2754 function isPropsValid(state, calendar, dateSpanMeta, filterConfig) {
2755 if (dateSpanMeta === void 0) { dateSpanMeta = {}; } 2756 if (state.eventDrag && !isInteractionPropsValid(state, calendar, dateSpanMeta, filterConfig)) { 2757 return false; 2758 } 2759 if (state.dateSelection && !isDateSelectionPropsValid(state, calendar, dateSpanMeta, filterConfig)) { 2760 return false; 2761 } 2762 return true; 2763 } 2764 // Moving Event Validation 2765 // ------------------------------------------------------------------------------------------------------------------------ 2766 function isInteractionPropsValid(state, calendar, dateSpanMeta, filterConfig) { 2767 var interaction = state.eventDrag; // HACK: the eventDrag props is used for ALL interactions 2768 var subjectEventStore = interaction.mutatedEvents; 2769 var subjectDefs = subjectEventStore.defs; 2770 var subjectInstances = subjectEventStore.instances; 2771 var subjectConfigs = compileEventUis(subjectDefs, interaction.isEvent ? 2772 state.eventUiBases : 2773 { '': calendar.selectionConfig } // if not a real event, validate as a selection 2774 ); 2775 if (filterConfig) { 2776 subjectConfigs = mapHash(subjectConfigs, filterConfig); 2777 } 2778 var otherEventStore = excludeInstances(state.eventStore, interaction.affectedEvents.instances); // exclude the subject events. TODO: exclude defs too? 2779 var otherDefs = otherEventStore.defs; 2780 var otherInstances = otherEventStore.instances; 2781 var otherConfigs = compileEventUis(otherDefs, state.eventUiBases); 2782 for (var subjectInstanceId in subjectInstances) { 2783 var subjectInstance = subjectInstances[subjectInstanceId]; 2784 var subjectRange = subjectInstance.range; 2785 var subjectConfig = subjectConfigs[subjectInstance.defId]; 2786 var subjectDef = subjectDefs[subjectInstance.defId]; 2787 // constraint 2788 if (!allConstraintsPass(subjectConfig.constraints, subjectRange, otherEventStore, state.businessHours, calendar)) { 2789 return false; 2790 } 2791 // overlap 2792 var overlapFunc = calendar.opt('eventOverlap'); 2793 if (typeof overlapFunc !== 'function') { 2794 overlapFunc = null; 2795 } 2796 for (var otherInstanceId in otherInstances) { 2797 var otherInstance = otherInstances[otherInstanceId]; 2798 // intersect! evaluate 2799 if (rangesIntersect(subjectRange, otherInstance.range)) { 2800 var otherOverlap = otherConfigs[otherInstance.defId].overlap; 2801 // consider the other event's overlap. only do this if the subject event is a "real" event 2802 if (otherOverlap === false && interaction.isEvent) { 2803 return false; 2804 } 2805 if (subjectConfig.overlap === false) { 2806 return false; 2807 } 2808 if (overlapFunc && !overlapFunc(new EventApi(calendar, otherDefs[otherInstance.defId], otherInstance), // still event 2809 new EventApi(calendar, subjectDef, subjectInstance) // moving event 2810 )) { 2811 return false; 2812 } 2813 } 2814 } 2815 // allow (a function) 2816 var calendarEventStore = calendar.state.eventStore; // need global-to-calendar, not local to component (splittable)state 2817 for (var _i = 0, _a = subjectConfig.allows; _i < _a.length; _i++) { 2818 var subjectAllow = _a[_i]; 2819 var subjectDateSpan = __assign({}, dateSpanMeta, { range: subjectInstance.range, allDay: subjectDef.allDay }); 2820 var origDef = calendarEventStore.defs[subjectDef.defId]; 2821 var origInstance = calendarEventStore.instances[subjectInstanceId]; 2822 var eventApi = void 0; 2823 if (origDef) { // was previously in the calendar 2824 eventApi = new EventApi(calendar, origDef, origInstance); 2825 } 2826 else { // was an external event 2827 eventApi = new EventApi(calendar, subjectDef); // no instance, because had no dates 2828 } 2829 if (!subjectAllow(calendar.buildDateSpanApi(subjectDateSpan), eventApi)) { 2830 return false;
2831 } 2832 } 2833 } 2834 return true; 2835 } 2836 // Date Selection Validation 2837 // ------------------------------------------------------------------------------------------------------------------------ 2838 function isDateSelectionPropsValid(state, calendar, dateSpanMeta, filterConfig) { 2839 var relevantEventStore = state.eventStore; 2840 var relevantDefs = relevantEventStore.defs; 2841 var relevantInstances = relevantEventStore.instances; 2842 var selection = state.dateSelection; 2843 var selectionRange = selection.range; 2844 var selectionConfig = calendar.selectionConfig; 2845 if (filterConfig) { 2846 selectionConfig = filterConfig(selectionConfig); 2847 } 2848 // constraint 2849 if (!allConstraintsPass(selectionConfig.constraints, selectionRange, relevantEventStore, state.businessHours, calendar)) { 2850 return false; 2851 } 2852 // overlap 2853 var overlapFunc = calendar.opt('selectOverlap'); 2854 if (typeof overlapFunc !== 'function') { 2855 overlapFunc = null; 2856 } 2857 for (var relevantInstanceId in relevantInstances) { 2858 var relevantInstance = relevantInstances[relevantInstanceId]; 2859 // intersect! evaluate 2860 if (rangesIntersect(selectionRange, relevantInstance.range)) { 2861 if (selectionConfig.overlap === false) { 2862 return false; 2863 } 2864 if (overlapFunc && !overlapFunc(new EventApi(calendar, relevantDefs[relevantInstance.defId], relevantInstance))) { 2865 return false; 2866 } 2867 } 2868 } 2869 // allow (a function) 2870 for (var _i = 0, _a = selectionConfig.allows; _i < _a.length; _i++) { 2871 var selectionAllow = _a[_i]; 2872 var fullDateSpan = __assign({}, dateSpanMeta, selection); 2873 if (!selectionAllow(calendar.buildDateSpanApi(fullDateSpan), null)) { 2874 return false; 2875 } 2876 } 2877 return true; 2878 } 2879 // Constraint Utils 2880 // ------------------------------------------------------------------------------------------------------------------------ 2881 function allConstraintsPass(constraints, subjectRange, otherEventStore, businessHoursUnexpanded, calendar) { 2882 for (var _i = 0, constraints_1 = constraints; _i < constraints_1.length; _i++) { 2883 var constraint = constraints_1[_i]; 2884 if (!anyRangesContainRange(constraintToRanges(constraint, subjectRange, otherEventStore, businessHoursUnexpanded, calendar), subjectRange)) { 2885 return false; 2886 } 2887 } 2888 return true; 2889 } 2890 function constraintToRanges(constraint, subjectRange, // for expanding a recurring constraint, or expanding business hours 2891 otherEventStore, // for if constraint is an even group ID 2892 businessHoursUnexpanded, // for if constraint is 'businessHours' 2893 calendar // for expanding businesshours 2894 ) { 2895 if (constraint === 'businessHours') { 2896 return eventStoreToRanges(expandRecurring(businessHoursUnexpanded, subjectRange, calendar)); 2897 } 2898 else if (typeof constraint === 'string') { // an group ID 2899 return eventStoreToRanges(filterEventStoreDefs(otherEventStore, function (eventDef) { 2900 return eventDef.groupId === constraint; 2901 })); 2902 } 2903 else if (typeof constraint === 'object' && constraint) { // non-null object 2904 return eventStoreToRanges(expandRecurring(constraint, subjectRange, calendar)); 2905 } 2906 return []; // if it's false 2907 } 2908 // TODO: move to event-store file? 2909 function eventStoreToRanges(eventStore) { 2910 var instances = eventStore.instances; 2911 var ranges = []; 2912 for (var instanceId in instances) { 2913 ranges.push(instances[instanceId].range); 2914 } 2915 return ranges; 2916 } 2917 // TODO: move to geom file? 2918 function anyRangesContainRange(outerRanges, innerRange) { 2919 for (var _i = 0, outerRanges_1 = outerRanges; _i < outerRanges_1.length; _i++) { 2920 var outerRange = outerRanges_1[_i]; 2921 if (rangeContainsRange(outerRange, innerRange)) { 2922 return true; 2923 } 2924 } 2925 return false;
2926 } 2927 // Parsing 2928 // ------------------------------------------------------------------------------------------------------------------------ 2929 function normalizeConstraint(input, calendar) { 2930 if (Array.isArray(input)) { 2931 return parseEvents(input, '', calendar, true); // allowOpenRange=true 2932 } 2933 else if (typeof input === 'object' && input) { // non-null object 2934 return parseEvents([input], '', calendar, true); // allowOpenRange=true 2935 } 2936 else if (input != null) { 2937 return String(input); 2938 } 2939 else { 2940 return null; 2941 } 2942 } 2943 2944 function htmlEscape(s) { 2945 return (s + '').replace(/&/g, '&') 2946 .replace(/</g, '<') 2947 .replace(/>/g, '>') 2948 .replace(/'/g, ''') 2949 .replace(/"/g, '"') 2950 .replace(/\n/g, '<br />'); 2951 } 2952 // Given a hash of CSS properties, returns a string of CSS. 2953 // Uses property names as-is (no camel-case conversion). Will not make statements for null/undefined values. 2954 function cssToStr(cssProps) { 2955 var statements = []; 2956 for (var name_1 in cssProps) { 2957 var val = cssProps[name_1]; 2958 if (val != null && val !== '') { 2959 statements.push(name_1 + ':' + val); 2960 } 2961 } 2962 return statements.join(';'); 2963 } 2964 // Given an object hash of HTML attribute names to values, 2965 // generates a string that can be injected between < > in HTML 2966 function attrsToStr(attrs) { 2967 var parts = []; 2968 for (var name_2 in attrs) { 2969 var val = attrs[name_2]; 2970 if (val != null) { 2971 parts.push(name_2 + '="' + htmlEscape(val) + '"'); 2972 } 2973 } 2974 return parts.join(' '); 2975 } 2976 function parseClassName(raw) { 2977 if (Array.isArray(raw)) { 2978 return raw; 2979 } 2980 else if (typeof raw === 'string') { 2981 return raw.split(/\s+/); 2982 } 2983 else { 2984 return []; 2985 } 2986 } 2987 2988 var UNSCOPED_EVENT_UI_PROPS = { 2989 editable: Boolean, 2990 startEditable: Boolean, 2991 durationEditable: Boolean, 2992 constraint: null, 2993 overlap: null, 2994 allow: null, 2995 className: parseClassName, 2996 classNames: parseClassName, 2997 color: String, 2998 backgroundColor: String, 2999 borderColor: String, 3000 textColor: String 3001 }; 3002 function processUnscopedUiProps(rawProps, calendar, leftovers) { 3003 var props = refineProps(rawProps, UNSCOPED_EVENT_UI_PROPS, {}, leftovers); 3004 var constraint = normalizeConstraint(props.constraint, calendar); 3005 return { 3006 startEditable: props.startEditable != null ? props.startEditable : props.editable, 3007 durationEditable: props.durationEditable != null ? props.durationEditable : props.editable, 3008 constraints: constraint != null ? [constraint] : [], 3009 overlap: props.overlap, 3010 allows: props.allow != null ? [props.allow] : [], 3011 backgroundColor: props.backgroundColor || props.color, 3012 borderColor: props.borderColor || props.color, 3013 textColor: props.textColor, 3014 classNames: props.classNames.concat(props.className) 3015 }; 3016 } 3017 function processScopedUiProps(prefix, rawScoped, calendar, leftovers) { 3018 var rawUnscoped = {}; 3019 var wasFound = {}; 3020 for (var key in UNSCOPED_EVENT_UI_PROPS) { 3021 var scopedKey = prefix + capitaliseFirstLetter(key); 3022 rawUnscoped[key] = rawScoped[scopedKey]; 3023 wasFound[scopedKey] = true; 3024 } 3025 if (prefix === 'event') { 3026 rawUnscoped.editable = rawScoped.editable; // special case. there is no 'eventEditable', just 'editable' 3027 } 3028 if (leftovers) { 3029 for (var key in rawScoped) { 3030 if (!wasFound[key]) { 3031 leftovers[key] = rawScoped[key]; 3032 } 3033 } 3034 } 3035 return processUnscopedUiProps(rawUnscoped, calendar); 3036 } 3037 var EMPTY_EVENT_UI = { 3038 startEditable: null, 3039 durationEditable: null, 3040 constraints: [], 3041 overlap: null, 3042 allows: [], 3043 backgroundColor: '', 3044 borderColor: '', 3045 textColor: '', 3046 classNames: [] 3047 }; 3048 // prevent against problems with <2 args! 3049 function combineEventUis(uis) { 3050 return uis.reduce(combineTwoEventUis, EMPTY_EVENT_UI); 3051 } 3052 function combineTwoEventUis(item0, item1) { 3053 return { 3054 startEditable: item1.startEditable != null ? item1.startEditable : item0.startEditable, 3055 durationEditable: item1.durationEditable != null ? item1.durationEditable : item0.durationEditable, 3056 constraints: item0.constraints.concat(item1.constraints), 3057 overlap: typeof item1.overlap === 'boolean' ? item1.overlap : item0.overlap, 3058 allows: item0.allows.concat(item1.allows), 3059 backgroundColor: item1.backgroundColor || item0.backgroundColor, 3060 borderColor: item1.borderColor || item0.borderColor, 3061 textColor: item1.textColor || item0.textColor,
3062 classNames: item0.classNames.concat(item1.classNames) 3063 }; 3064 } 3065 3066 var NON_DATE_PROPS = { 3067 id: String, 3068 groupId: String, 3069 title: String, 3070 url: String, 3071 rendering: String, 3072 extendedProps: null 3073 }; 3074 var DATE_PROPS = { 3075 start: null, 3076 date: null, 3077 end: null, 3078 allDay: null 3079 }; 3080 var uid = 0; 3081 function parseEvent(raw, sourceId, calendar, allowOpenRange) { 3082 var allDayDefault = computeIsAllDayDefault(sourceId, calendar); 3083 var leftovers0 = {}; 3084 var recurringRes = parseRecurring(raw, // raw, but with single-event stuff stripped out 3085 allDayDefault, calendar.dateEnv, calendar.pluginSystem.hooks.recurringTypes, leftovers0 // will populate with non-recurring props 3086 ); 3087 if (recurringRes) { 3088 var def = parseEventDef(leftovers0, sourceId, recurringRes.allDay, Boolean(recurringRes.duration), calendar); 3089 def.recurringDef = { 3090 typeId: recurringRes.typeId, 3091 typeData: recurringRes.typeData, 3092 duration: recurringRes.duration 3093 }; 3094 return { def: def, instance: null }; 3095 } 3096 else { 3097 var leftovers1 = {}; 3098 var singleRes = parseSingle(raw, allDayDefault, calendar, leftovers1, allowOpenRange); 3099 if (singleRes) { 3100 var def = parseEventDef(leftovers1, sourceId, singleRes.allDay, singleRes.hasEnd, calendar); 3101 var instance = createEventInstance(def.defId, singleRes.range, singleRes.forcedStartTzo, singleRes.forcedEndTzo); 3102 return { def: def, instance: instance }; 3103 } 3104 } 3105 return null; 3106 } 3107 /* 3108 Will NOT populate extendedProps with the leftover properties. 3109 Will NOT populate date-related props. 3110 The EventNonDateInput has been normalized (id => publicId, etc). 3111 */ 3112 function parseEventDef(raw, sourceId, allDay, hasEnd, calendar) { 3113 var leftovers = {}; 3114 var def = pluckNonDateProps(raw, calendar, leftovers); 3115 def.defId = String(uid++); 3116 def.sourceId = sourceId; 3117 def.allDay = allDay; 3118 def.hasEnd = hasEnd; 3119 for (var _i = 0, _a = calendar.pluginSystem.hooks.eventDefParsers; _i < _a.length; _i++) { 3120 var eventDefParser = _a[_i]; 3121 var newLeftovers = {}; 3122 eventDefParser(def, leftovers, newLeftovers); 3123 leftovers = newLeftovers; 3124 } 3125 def.extendedProps = __assign(leftovers, def.extendedProps || {}); 3126 // help out EventApi from having user modify props 3127 Object.freeze(def.ui.classNames); 3128 Object.freeze(def.extendedProps); 3129 return def; 3130 } 3131 function createEventInstance(defId, range, forcedStartTzo, forcedEndTzo) { 3132 return { 3133 instanceId: String(uid++), 3134 defId: defId, 3135 range: range, 3136 forcedStartTzo: forcedStartTzo == null ? null : forcedStartTzo, 3137 forcedEndTzo: forcedEndTzo == null ? null : forcedEndTzo 3138 }; 3139 } 3140 function parseSingle(raw, allDayDefault, calendar, leftovers, allowOpenRange) { 3141 var props = pluckDateProps(raw, leftovers); 3142 var allDay = props.allDay; 3143 var startMeta; 3144 var startMarker = null; 3145 var hasEnd = false; 3146 var endMeta; 3147 var endMarker = null; 3148 startMeta = calendar.dateEnv.createMarkerMeta(props.start); 3149 if (startMeta) { 3150 startMarker = startMeta.marker; 3151 } 3152 else if (!allowOpenRange) { 3153 return null; 3154 } 3155 if (props.end != null) { 3156 endMeta = calendar.dateEnv.createMarkerMeta(props.end); 3157 } 3158 if (allDay == null) { 3159 if (allDayDefault != null) { 3160 allDay = allDayDefault; 3161 } 3162 else { 3163 // fall back to the date props LAST 3164 allDay = (!startMeta || startMeta.isTimeUnspecified) && 3165 (!endMeta || endMeta.isTimeUnspecified); 3166 } 3167 } 3168 if (allDay && startMarker) { 3169 startMarker = startOfDay(startMarker); 3170 } 3171 if (endMeta) { 3172 endMarker = endMeta.marker; 3173 if (allDay) { 3174 endMarker = startOfDay(endMarker); 3175 } 3176 if (startMarker && endMarker <= startMarker) { 3177 endMarker = null; 3178 } 3179 } 3180 if (endMarker) { 3181 hasEnd = true; 3182 } 3183 else if (!allowOpenRange) { 3184 hasEnd = calendar.opt('forceEventDuration') || false; 3185 endMarker = calendar.dateEnv.add(startMarker, allDay ? 3186 calendar.defaultAllDayEventDuration : 3187 calendar.defaultTimedEventDuration); 3188 } 3189 return { 3190 allDay: allDay, 3191 hasEnd: hasEnd, 3192 range: { start: startMarker, end: endMarker }, 3193 forcedStartTzo: startMeta ? startMeta.forcedTzo : null, 3194 forcedEndTzo: endMeta ? endMeta.forcedTzo : null 3195 }; 3196 } 3197 function pluckDateProps(raw, leftovers) { 3198 var props = refineProps(raw, DATE_PROPS, {}, leftovers); 3199 props.start = (props.start !== null) ? props.start : props.date; 3200 delete props.date; 3201 return props; 3202 } 3203 function pluckNonDateProps(raw, calendar, leftovers) { 3204 var preLeftovers = {}; 3205 var props = refineProps(raw, NON_DATE_PROPS, {}, preLeftovers); 3206 var ui = processUnscopedUiProps(preLeftovers, calendar, leftovers); 3207 props.publicId = props.id; 3208 delete props.id; 3209 props.ui = ui; 3210 return props; 3211 } 3212 function computeIsAllDayDefault(sourceId, calendar) { 3213 var res = null; 3214 if (sourceId) { 3215 var source = calendar.state.eventSources[sourceId]; 3216 res = source.allDayDefault; 3217 } 3218 if (res == null) { 3219 res = calendar.opt('allDayDefault'); 3220 } 3221 return res; 3222 } 3223 3224 var DEF_DEFAULTS = { 3225 startTime: '09:00', 3226 endTime: '17:00', 3227 daysOfWeek: [1, 2, 3, 4, 5], 3228 rendering: 'inverse-background', 3229 classNames: 'fc-nonbusiness', 3230 groupId: '_businessHours' // so multiple defs get grouped 3231 }; 3232 /* 3233 TODO: pass around as EventDefHash!!! 3234 */ 3235 function parseBusinessHours(input, calendar) { 3236 return parseEvents(refineInputs(input), '', calendar); 3237 } 3238 function refineInputs(input) { 3239 var rawDefs; 3240 if (input === true) { 3241 rawDefs = [{}]; // will get DEF_DEFAULTS verbatim 3242 } 3243 else if (Array.isArray(input)) { 3244 // if specifying an array, every sub-definition NEEDS a day-of-week 3245 rawDefs = input.filter(function (rawDef) { 3246 return rawDef.daysOfWeek; 3247 }); 3248 } 3249 else if (typeof input === 'object' && input) { // non-null object 3250 rawDefs = [input]; 3251 } 3252 else { // is probably false 3253 rawDefs = []; 3254 } 3255 rawDefs = rawDefs.map(function (rawDef) { 3256 return __assign({}, DEF_DEFAULTS, rawDef); 3257 }); 3258 return rawDefs; 3259 } 3260 3261 function memoizeRendering(renderFunc, unrenderFunc, dependencies) { 3262 if (dependencies === void 0) { dependencies = []; } 3263 var dependents = []; 3264 var thisContext; 3265 var prevArgs; 3266 function unrender() { 3267 if (prevArgs) {
3268 for (var _i = 0, dependents_1 = dependents; _i < dependents_1.length; _i++) { 3269 var dependent = dependents_1[_i]; 3270 dependent.unrender(); 3271 } 3272 if (unrenderFunc) { 3273 unrenderFunc.apply(thisContext, prevArgs); 3274 } 3275 prevArgs = null; 3276 } 3277 } 3278 function res() { 3279 if (!prevArgs || !isArraysEqual(prevArgs, arguments)) { 3280 unrender(); 3281 thisContext = this; 3282 prevArgs = arguments; 3283 renderFunc.apply(this, arguments); 3284 } 3285 } 3286 res.dependents = dependents; 3287 res.unrender = unrender; 3288 for (var _i = 0, dependencies_1 = dependencies; _i < dependencies_1.length; _i++) { 3289 var dependency = dependencies_1[_i]; 3290 dependency.dependents.push(res); 3291 } 3292 return res; 3293 } 3294 3295 var EMPTY_EVENT_STORE = createEmptyEventStore(); // for purecomponents. TODO: keep elsewhere 3296 var Splitter = /** @class */ (function () { 3297 function Splitter() { 3298 this.getKeysForEventDefs = memoize(this._getKeysForEventDefs); 3299 this.splitDateSelection = memoize(this._splitDateSpan); 3300 this.splitEventStore = memoize(this._splitEventStore); 3301 this.splitIndividualUi = memoize(this._splitIndividualUi); 3302 this.splitEventDrag = memoize(this._splitInteraction); 3303 this.splitEventResize = memoize(this._splitInteraction); 3304 this.eventUiBuilders = {}; // TODO: typescript protection 3305 } 3306 Splitter.prototype.splitProps = function (props) { 3307 var _this = this; 3308 var keyInfos = this.getKeyInfo(props); 3309 var defKeys = this.getKeysForEventDefs(props.eventStore); 3310 var dateSelections = this.splitDateSelection(props.dateSelection); 3311 var individualUi = this.splitIndividualUi(props.eventUiBases, defKeys); // the individual *bases* 3312 var eventStores = this.splitEventStore(props.eventStore, defKeys); 3313 var eventDrags = this.splitEventDrag(props.eventDrag); 3314 var eventResizes = this.splitEventResize(props.eventResize); 3315 var splitProps = {}; 3316 this.eventUiBuilders = mapHash(keyInfos, function (info, key) { 3317 return _this.eventUiBuilders[key] || memoize(buildEventUiForKey); 3318 }); 3319 for (var key in keyInfos) { 3320 var keyInfo = keyInfos[key]; 3321 var eventStore = eventStores[key] || EMPTY_EVENT_STORE; 3322 var buildEventUi = this.eventUiBuilders[key]; 3323 splitProps[key] = { 3324 businessHours: keyInfo.businessHours || props.businessHours, 3325 dateSelection: dateSelections[key] || null, 3326 eventStore: eventStore, 3327 eventUiBases: buildEventUi(props.eventUiBases[''], keyInfo.ui, individualUi[key]), 3328 eventSelection: eventStore.instances[props.eventSelection] ? props.eventSelection : '', 3329 eventDrag: eventDrags[key] || null, 3330 eventResize: eventResizes[key] || null 3331 }; 3332 } 3333 return splitProps; 3334 }; 3335 Splitter.prototype._splitDateSpan = function (dateSpan) { 3336 var dateSpans = {}; 3337 if (dateSpan) { 3338 var keys = this.getKeysForDateSpan(dateSpan); 3339 for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) { 3340 var key = keys_1[_i]; 3341 dateSpans[key] = dateSpan; 3342 } 3343 } 3344 return dateSpans; 3345 }; 3346 Splitter.prototype._getKeysForEventDefs = function (eventStore) { 3347 var _this = this; 3348 return mapHash(eventStore.defs, function (eventDef) { 3349 return _this.getKeysForEventDef(eventDef); 3350 }); 3351 }; 3352 Splitter.prototype._splitEventStore = function (eventStore, defKeys) { 3353 var defs = eventStore.defs, instances = eventStore.instances; 3354 var splitStores = {}; 3355 for (var defId in defs) { 3356 for (var _i = 0, _a = defKeys[defId]; _i < _a.length; _i++) { 3357 var key = _a[_i]; 3358 if (!splitStores[key]) { 3359 splitStores[key] = createEmptyEventStore(); 3360 }
3361 splitStores[key].defs[defId] = defs[defId]; 3362 } 3363 } 3364 for (var instanceId in instances) { 3365 var instance = instances[instanceId]; 3366 for (var _b = 0, _c = defKeys[instance.defId]; _b < _c.length; _b++) { 3367 var key = _c[_b]; 3368 if (splitStores[key]) { // must have already been created 3369 splitStores[key].instances[instanceId] = instance; 3370 } 3371 } 3372 } 3373 return splitStores; 3374 }; 3375 Splitter.prototype._splitIndividualUi = function (eventUiBases, defKeys) { 3376 var splitHashes = {}; 3377 for (var defId in eventUiBases) { 3378 if (defId) { // not the '' key 3379 for (var _i = 0, _a = defKeys[defId]; _i < _a.length; _i++) { 3380 var key = _a[_i]; 3381 if (!splitHashes[key]) { 3382 splitHashes[key] = {}; 3383 } 3384 splitHashes[key][defId] = eventUiBases[defId]; 3385 } 3386 } 3387 } 3388 return splitHashes; 3389 }; 3390 Splitter.prototype._splitInteraction = function (interaction) { 3391 var splitStates = {}; 3392 if (interaction) { 3393 var affectedStores_1 = this._splitEventStore(interaction.affectedEvents, this._getKeysForEventDefs(interaction.affectedEvents) // can't use cached. might be events from other calendar 3394 ); 3395 // can't rely on defKeys because event data is mutated 3396 var mutatedKeysByDefId = this._getKeysForEventDefs(interaction.mutatedEvents); 3397 var mutatedStores_1 = this._splitEventStore(interaction.mutatedEvents, mutatedKeysByDefId); 3398 var populate = function (key) { 3399 if (!splitStates[key]) { 3400 splitStates[key] = { 3401 affectedEvents: affectedStores_1[key] || EMPTY_EVENT_STORE, 3402 mutatedEvents: mutatedStores_1[key] || EMPTY_EVENT_STORE, 3403 isEvent: interaction.isEvent, 3404 origSeg: interaction.origSeg 3405 }; 3406 } 3407 }; 3408 for (var key in affectedStores_1) { 3409 populate(key); 3410 } 3411 for (var key in mutatedStores_1) { 3412 populate(key); 3413 } 3414 } 3415 return splitStates; 3416 }; 3417 return Splitter; 3418 }()); 3419 function buildEventUiForKey(allUi, eventUiForKey, individualUi) { 3420 var baseParts = []; 3421 if (allUi) { 3422 baseParts.push(allUi); 3423 } 3424 if (eventUiForKey) { 3425 baseParts.push(eventUiForKey); 3426 } 3427 var stuff = { 3428 '': combineEventUis(baseParts) 3429 }; 3430 if (individualUi) { 3431 __assign(stuff, individualUi); 3432 } 3433 return stuff; 3434 } 3435 3436 // Generates HTML for an anchor to another view into the calendar. 3437 // Will either generate an <a> tag or a non-clickable <span> tag, depending on enabled settings. 3438 // `gotoOptions` can either be a DateMarker, or an object with the form: 3439 // { date, type, forceOff } 3440 // `type` is a view-type like "day" or "week". default value is "day". 3441 // `attrs` and `innerHtml` are use to generate the rest of the HTML tag. 3442 function buildGotoAnchorHtml(component, gotoOptions, attrs, innerHtml) { 3443 var dateEnv = component.dateEnv; 3444 var date; 3445 var type; 3446 var forceOff; 3447 var finalOptions; 3448 if (gotoOptions instanceof Date) { 3449 date = gotoOptions; // a single date-like input 3450 } 3451 else { 3452 date = gotoOptions.date; 3453 type = gotoOptions.type; 3454 forceOff = gotoOptions.forceOff; 3455 } 3456 finalOptions = { 3457 date: dateEnv.formatIso(date, { omitTime: true }), 3458 type: type || 'day' 3459 }; 3460 if (typeof attrs === 'string') { 3461 innerHtml = attrs; 3462 attrs = null; 3463 } 3464 attrs = attrs ? ' ' + attrsToStr(attrs) : ''; // will have a leading space 3465 innerHtml = innerHtml || ''; 3466 if (!forceOff && component.opt('navLinks')) { 3467 return '<a' + attrs + 3468 ' data-goto="' + htmlEscape(JSON.stringify(finalOptions)) + '">' + 3469 innerHtml + 3470 '</a>'; 3471 } 3472 else { 3473 return '<span' + attrs + '>' + 3474 innerHtml + 3475 '</span>'; 3476 } 3477 } 3478 function getAllDayHtml(component) { 3479 return component.opt('allDayHtml') || htmlEscape(component.opt('allDayText')); 3480 } 3481 // Computes HTML classNames for a single-day element 3482 function getDayClasses(date, dateProfile, context, noThemeHighlight) { 3483 var calendar = context.calendar, view = context.view, theme = context.theme, dateEnv = context.dateEnv; 3484 var classes = []; 3485 var todayStart; 3486 var todayEnd; 3487 if (!rangeContainsMarker(dateProfile.activeRange, date)) { 3488 classes.push('fc-disabled-day'); 3489 } 3490 else { 3491 classes.push('fc-' + DAY_IDS[date.getUTCDay()]); 3492 if (view.opt('monthMode') && 3493 dateEnv.getMonth(date) !== dateEnv.getMonth(dateProfile.currentRange.start)) { 3494 classes.push('fc-other-month'); 3495 } 3496 todayStart = startOfDay(calendar.getNow()); 3497 todayEnd = addDays(todayStart, 1); 3498 if (date < todayStart) { 3499 classes.push('fc-past'); 3500 } 3501 else if (date >= todayEnd) { 3502 classes.push('fc-future'); 3503 } 3504 else { 3505 classes.push('fc-today'); 3506 if (noThemeHighlight !== true) { 3507 classes.push(theme.getClass('today')); 3508 } 3509 } 3510 } 3511 return classes; 3512 } 3513 3514 // given a function that resolves a result asynchronously. 3515 // the function can either call passed-in success and failure callbacks, 3516 // or it can return a promise. 3517 // if you need to pass additional params to func, bind them first. 3518 function unpromisify(func, success, failure) { 3519 // guard against success/failure callbacks being called more than once 3520 // and guard against a promise AND callback being used together. 3521 var isResolved = false;
3522 var wrappedSuccess = function () { 3523 if (!isResolved) { 3524 isResolved = true; 3525 success.apply(this, arguments); 3526 } 3527 }; 3528 var wrappedFailure = function () { 3529 if (!isResolved) { 3530 isResolved = true; 3531 if (failure) { 3532 failure.apply(this, arguments); 3533 } 3534 } 3535 }; 3536 var res = func(wrappedSuccess, wrappedFailure); 3537 if (res && typeof res.then === 'function') { 3538 res.then(wrappedSuccess, wrappedFailure); 3539 } 3540 } 3541 3542 var Mixin = /** @class */ (function () { 3543 function Mixin() { 3544 } 3545 // mix into a CLASS 3546 Mixin.mixInto = function (destClass) { 3547 this.mixIntoObj(destClass.prototype); 3548 }; 3549 // mix into ANY object 3550 Mixin.mixIntoObj = function (destObj) { 3551 var _this = this; 3552 Object.getOwnPropertyNames(this.prototype).forEach(function (name) { 3553 if (!destObj[name]) { // if destination doesn't already define it 3554 destObj[name] = _this.prototype[name]; 3555 } 3556 }); 3557 }; 3558 /* 3559 will override existing methods 3560 TODO: remove! not used anymore 3561 */ 3562 Mixin.mixOver = function (destClass) { 3563 var _this = this; 3564 Object.getOwnPropertyNames(this.prototype).forEach(function (name) { 3565 destClass.prototype[name] = _this.prototype[name]; 3566 }); 3567 }; 3568 return Mixin; 3569 }()); 3570 3571 /* 3572 USAGE: 3573 import { default as EmitterMixin, EmitterInterface } from './EmitterMixin' 3574 in class: 3575 on: EmitterInterface['on'] 3576 one: EmitterInterface['one'] 3577 off: EmitterInterface['off'] 3578 trigger: EmitterInterface['trigger'] 3579 triggerWith: EmitterInterface['triggerWith'] 3580 hasHandlers: EmitterInterface['hasHandlers'] 3581 after class: 3582 EmitterMixin.mixInto(TheClass) 3583 */ 3584 var EmitterMixin = /** @class */ (function (_super) { 3585 __extends(EmitterMixin, _super); 3586 function EmitterMixin() { 3587 return _super !== null && _super.apply(this, arguments) || this; 3588 } 3589 EmitterMixin.prototype.on = function (type, handler) { 3590 addToHash(this._handlers || (this._handlers = {}), type, handler); 3591 return this; // for chaining 3592 }; 3593 // todo: add comments 3594 EmitterMixin.prototype.one = function (type, handler) { 3595 addToHash(this._oneHandlers || (this._oneHandlers = {}), type, handler); 3596 return this; // for chaining 3597 }; 3598 EmitterMixin.prototype.off = function (type, handler) { 3599 if (this._handlers) { 3600 removeFromHash(this._handlers, type, handler); 3601 } 3602 if (this._oneHandlers) { 3603 removeFromHash(this._oneHandlers, type, handler); 3604 } 3605 return this; // for chaining 3606 }; 3607 EmitterMixin.prototype.trigger = function (type) { 3608 var args = []; 3609 for (var _i = 1; _i < arguments.length; _i++) { 3610 args[_i - 1] = arguments[_i]; 3611 } 3612 this.triggerWith(type, this, args); 3613 return this; // for chaining 3614 }; 3615 EmitterMixin.prototype.triggerWith = function (type, context, args) { 3616 if (this._handlers) { 3617 applyAll(this._handlers[type], context, args); 3618 } 3619 if (this._oneHandlers) { 3620 applyAll(this._oneHandlers[type], context, args); 3621 delete this._oneHandlers[type]; // will never fire again 3622 } 3623 return this; // for chaining 3624 }; 3625 EmitterMixin.prototype.hasHandlers = function (type) { 3626 return (this._handlers && this._handlers[type] && this._handlers[type].length) || 3627 (this._oneHandlers && this._oneHandlers[type] && this._oneHandlers[type].length); 3628 }; 3629 return EmitterMixin; 3630 }(Mixin)); 3631 function addToHash(hash, type, handler) { 3632 (hash[type] || (hash[type] = [])) 3633 .push(handler); 3634 } 3635 function removeFromHash(hash, type, handler) { 3636 if (handler) { 3637 if (hash[type]) { 3638 hash[type] = hash[type].filter(function (func) { 3639 return func !== handler; 3640 }); 3641 } 3642 } 3643 else { 3644 delete hash[type]; // remove all handler funcs for this type 3645 } 3646 } 3647 3648 /* 3649 Records offset information for a set of elements, relative to an origin element. 3650 Can record the left/right OR the top/bottom OR both. 3651 Provides methods for querying the cache by position. 3652 */ 3653 var PositionCache = /** @class */ (function () { 3654 function PositionCache(originEl, els, isHorizontal, isVertical) { 3655 this.originEl = originEl; 3656 this.els = els; 3657 this.isHorizontal = isHorizontal; 3658 this.isVertical = isVertical; 3659 } 3660 // Queries the els for coordinates and stores them. 3661 // Call this method before using and of the get* methods below. 3662 PositionCache.prototype.build = function () { 3663 var originEl = this.originEl; 3664 var originClientRect = this.originClientRect = 3665 originEl.getBoundingClientRect(); // relative to viewport top-left 3666 if (this.isHorizontal) { 3667 this.buildElHorizontals(originClientRect.left); 3668 } 3669 if (this.isVertical) { 3670 this.buildElVerticals(originClientRect.top); 3671 } 3672 };
3673 // Populates the left/right internal coordinate arrays 3674 PositionCache.prototype.buildElHorizontals = function (originClientLeft) { 3675 var lefts = []; 3676 var rights = []; 3677 for (var _i = 0, _a = this.els; _i < _a.length; _i++) { 3678 var el = _a[_i]; 3679 var rect = el.getBoundingClientRect(); 3680 lefts.push(rect.left - originClientLeft); 3681 rights.push(rect.right - originClientLeft); 3682 } 3683 this.lefts = lefts; 3684 this.rights = rights; 3685 }; 3686 // Populates the top/bottom internal coordinate arrays 3687 PositionCache.prototype.buildElVerticals = function (originClientTop) { 3688 var tops = []; 3689 var bottoms = []; 3690 for (var _i = 0, _a = this.els; _i < _a.length; _i++) { 3691 var el = _a[_i]; 3692 var rect = el.getBoundingClientRect(); 3693 tops.push(rect.top - originClientTop); 3694 bottoms.push(rect.bottom - originClientTop); 3695 } 3696 this.tops = tops; 3697 this.bottoms = bottoms; 3698 }; 3699 // Given a left offset (from document left), returns the index of the el that it horizontally intersects. 3700 // If no intersection is made, returns undefined. 3701 PositionCache.prototype.leftToIndex = function (leftPosition) { 3702 var lefts = this.lefts; 3703 var rights = this.rights; 3704 var len = lefts.length; 3705 var i; 3706 for (i = 0; i < len; i++) { 3707 if (leftPosition >= lefts[i] && leftPosition < rights[i]) { 3708 return i; 3709 } 3710 } 3711 }; 3712 // Given a top offset (from document top), returns the index of the el that it vertically intersects. 3713 // If no intersection is made, returns undefined. 3714 PositionCache.prototype.topToIndex = function (topPosition) { 3715 var tops = this.tops; 3716 var bottoms = this.bottoms; 3717 var len = tops.length; 3718 var i; 3719 for (i = 0; i < len; i++) { 3720 if (topPosition >= tops[i] && topPosition < bottoms[i]) { 3721 return i; 3722 } 3723 } 3724 }; 3725 // Gets the width of the element at the given index 3726 PositionCache.prototype.getWidth = function (leftIndex) { 3727 return this.rights[leftIndex] - this.lefts[leftIndex]; 3728 }; 3729 // Gets the height of the element at the given index 3730 PositionCache.prototype.getHeight = function (topIndex) { 3731 return this.bottoms[topIndex] - this.tops[topIndex]; 3732 }; 3733 return PositionCache; 3734 }()); 3735 3736 /* 3737 An object for getting/setting scroll-related information for an element. 3738 Internally, this is done very differently for window versus DOM element, 3739 so this object serves as a common interface. 3740 */ 3741 var ScrollController = /** @class */ (function () { 3742 function ScrollController() { 3743 } 3744 ScrollController.prototype.getMaxScrollTop = function () { 3745 return this.getScrollHeight() - this.getClientHeight(); 3746 }; 3747 ScrollController.prototype.getMaxScrollLeft = function () { 3748 return this.getScrollWidth() - this.getClientWidth(); 3749 }; 3750 ScrollController.prototype.canScrollVertically = function () { 3751 return this.getMaxScrollTop() > 0; 3752 }; 3753 ScrollController.prototype.canScrollHorizontally = function () { 3754 return this.getMaxScrollLeft() > 0; 3755 }; 3756 ScrollController.prototype.canScrollUp = function () { 3757 return this.getScrollTop() > 0; 3758 }; 3759 ScrollController.prototype.canScrollDown = function () { 3760 return this.getScrollTop() < this.getMaxScrollTop(); 3761 }; 3762 ScrollController.prototype.canScrollLeft = function () { 3763 return this.getScrollLeft() > 0; 3764 }; 3765 ScrollController.prototype.canScrollRight = function () { 3766 return this.getScrollLeft() < this.getMaxScrollLeft(); 3767 };
3768 return ScrollController; 3769 }()); 3770 var ElementScrollController = /** @class */ (function (_super) { 3771 __extends(ElementScrollController, _super); 3772 function ElementScrollController(el) { 3773 var _this = _super.call(this) || this; 3774 _this.el = el; 3775 return _this; 3776 } 3777 ElementScrollController.prototype.getScrollTop = function () { 3778 return this.el.scrollTop; 3779 }; 3780 ElementScrollController.prototype.getScrollLeft = function () { 3781 return this.el.scrollLeft; 3782 }; 3783 ElementScrollController.prototype.setScrollTop = function (top) { 3784 this.el.scrollTop = top; 3785 }; 3786 ElementScrollController.prototype.setScrollLeft = function (left) { 3787 this.el.scrollLeft = left; 3788 }; 3789 ElementScrollController.prototype.getScrollWidth = function () { 3790 return this.el.scrollWidth; 3791 }; 3792 ElementScrollController.prototype.getScrollHeight = function () { 3793 return this.el.scrollHeight; 3794 }; 3795 ElementScrollController.prototype.getClientHeight = function () { 3796 return this.el.clientHeight; 3797 }; 3798 ElementScrollController.prototype.getClientWidth = function () { 3799 return this.el.clientWidth; 3800 }; 3801 return ElementScrollController; 3802 }(ScrollController)); 3803 var WindowScrollController = /** @class */ (function (_super) { 3804 __extends(WindowScrollController, _super); 3805 function WindowScrollController() { 3806 return _super !== null && _super.apply(this, arguments) || this; 3807 } 3808 WindowScrollController.prototype.getScrollTop = function () { 3809 return window.pageYOffset; 3810 }; 3811 WindowScrollController.prototype.getScrollLeft = function () { 3812 return window.pageXOffset; 3813 }; 3814 WindowScrollController.prototype.setScrollTop = function (n) { 3815 window.scroll(window.pageXOffset, n); 3816 }; 3817 WindowScrollController.prototype.setScrollLeft = function (n) { 3818 window.scroll(n, window.pageYOffset); 3819 }; 3820 WindowScrollController.prototype.getScrollWidth = function () { 3821 return document.documentElement.scrollWidth; 3822 }; 3823 WindowScrollController.prototype.getScrollHeight = function () { 3824 return document.documentElement.scrollHeight; 3825 }; 3826 WindowScrollController.prototype.getClientHeight = function () { 3827 return document.documentElement.clientHeight; 3828 }; 3829 WindowScrollController.prototype.getClientWidth = function () { 3830 return document.documentElement.clientWidth; 3831 }; 3832 return WindowScrollController; 3833 }(ScrollController)); 3834 3835 /* 3836 Embodies a div that has potential scrollbars 3837 */ 3838 var ScrollComponent = /** @class */ (function (_super) { 3839 __extends(ScrollComponent, _super); 3840 function ScrollComponent(overflowX, overflowY) { 3841 var _this = _super.call(this, createElement('div', { 3842 className: 'fc-scroller' 3843 })) || this; 3844 _this.overflowX = overflowX; 3845 _this.overflowY = overflowY; 3846 _this.applyOverflow(); 3847 return _this; 3848 } 3849 // sets to natural height, unlocks overflow 3850 ScrollComponent.prototype.clear = function () { 3851 this.setHeight('auto'); 3852 this.applyOverflow(); 3853 }; 3854 ScrollComponent.prototype.destroy = function () { 3855 removeElement(this.el); 3856 }; 3857 // Overflow 3858 // ----------------------------------------------------------------------------------------------------------------- 3859 ScrollComponent.prototype.applyOverflow = function () { 3860 applyStyle(this.el, { 3861 overflowX: this.overflowX, 3862 overflowY: this.overflowY 3863 }); 3864 }; 3865 // Causes any 'auto' overflow values to resolves to 'scroll' or 'hidden'. 3866 // Useful for preserving scrollbar widths regardless of future resizes. 3867 // Can pass in scrollbarWidths for optimization. 3868 ScrollComponent.prototype.lockOverflow = function (scrollbarWidths) { 3869 var overflowX = this.overflowX; 3870 var overflowY = this.overflowY;
3871 scrollbarWidths = scrollbarWidths || this.getScrollbarWidths(); 3872 if (overflowX === 'auto') { 3873 overflowX = (scrollbarWidths.bottom || // horizontal scrollbars? 3874 this.canScrollHorizontally() // OR scrolling pane with massless scrollbars? 3875 ) ? 'scroll' : 'hidden'; 3876 } 3877 if (overflowY === 'auto') { 3878 overflowY = (scrollbarWidths.left || scrollbarWidths.right || // horizontal scrollbars? 3879 this.canScrollVertically() // OR scrolling pane with massless scrollbars? 3880 ) ? 'scroll' : 'hidden'; 3881 } 3882 applyStyle(this.el, { overflowX: overflowX, overflowY: overflowY }); 3883 }; 3884 ScrollComponent.prototype.setHeight = function (height) { 3885 applyStyleProp(this.el, 'height', height); 3886 }; 3887 ScrollComponent.prototype.getScrollbarWidths = function () { 3888 var edges = computeEdges(this.el); 3889 return { 3890 left: edges.scrollbarLeft, 3891 right: edges.scrollbarRight, 3892 bottom: edges.scrollbarBottom 3893 }; 3894 }; 3895 return ScrollComponent; 3896 }(ElementScrollController)); 3897 3898 var Theme = /** @class */ (function () { 3899 function Theme(calendarOptions) { 3900 this.calendarOptions = calendarOptions; 3901 this.processIconOverride(); 3902 } 3903 Theme.prototype.processIconOverride = function () { 3904 if (this.iconOverrideOption) { 3905 this.setIconOverride(this.calendarOptions[this.iconOverrideOption]); 3906 } 3907 }; 3908 Theme.prototype.setIconOverride = function (iconOverrideHash) { 3909 var iconClassesCopy; 3910 var buttonName; 3911 if (typeof iconOverrideHash === 'object' && iconOverrideHash) { // non-null object 3912 iconClassesCopy = __assign({}, this.iconClasses); 3913 for (buttonName in iconOverrideHash) { 3914 iconClassesCopy[buttonName] = this.applyIconOverridePrefix(iconOverrideHash[buttonName]); 3915 } 3916 this.iconClasses = iconClassesCopy; 3917 } 3918 else if (iconOverrideHash === false) { 3919 this.iconClasses = {}; 3920 } 3921 }; 3922 Theme.prototype.applyIconOverridePrefix = function (className) { 3923 var prefix = this.iconOverridePrefix; 3924 if (prefix && className.indexOf(prefix) !== 0) { // if not already present 3925 className = prefix + className; 3926 } 3927 return className; 3928 }; 3929 Theme.prototype.getClass = function (key) { 3930 return this.classes[key] || ''; 3931 }; 3932 Theme.prototype.getIconClass = function (buttonName) { 3933 var className = this.iconClasses[buttonName]; 3934 if (className) { 3935 return this.baseIconClass + ' ' + className; 3936 } 3937 return ''; 3938 }; 3939 Theme.prototype.getCustomButtonIconClass = function (customButtonProps) { 3940 var className; 3941 if (this.iconOverrideCustomButtonOption) { 3942 className = customButtonProps[this.iconOverrideCustomButtonOption]; 3943 if (className) { 3944 return this.baseIconClass + ' ' + this.applyIconOverridePrefix(className); 3945 } 3946 } 3947 return ''; 3948 }; 3949 return Theme; 3950 }()); 3951 Theme.prototype.classes = {}; 3952 Theme.prototype.iconClasses = {}; 3953 Theme.prototype.baseIconClass = ''; 3954 Theme.prototype.iconOverridePrefix = ''; 3955 3956 var guid = 0; 3957 var Component = /** @class */ (function () { 3958 function Component(context, isView) { 3959 // HACK to populate view at top of component instantiation call chain 3960 if (isView) { 3961 context.view = this; 3962 } 3963 this.uid = String(guid++); 3964 this.context = context; 3965 this.dateEnv = context.dateEnv; 3966 this.theme = context.theme; 3967 this.view = context.view; 3968 this.calendar = context.calendar; 3969 this.isRtl = this.opt('dir') === 'rtl'; 3970 } 3971 Component.addEqualityFuncs = function (newFuncs) { 3972 this.prototype.equalityFuncs = __assign({}, this.prototype.equalityFuncs, newFuncs); 3973 }; 3974 Component.prototype.opt = function (name) { 3975 return this.context.options[name]; 3976 }; 3977 Component.prototype.receiveProps = function (props) { 3978 var _a = recycleProps(this.props || {}, props, this.equalityFuncs), anyChanges = _a.anyChanges, comboProps = _a.comboProps; 3979 this.props = comboProps;
3980 if (anyChanges) { 3981 this.render(comboProps); 3982 } 3983 }; 3984 Component.prototype.render = function (props) { 3985 }; 3986 // after destroy is called, this component won't ever be used again 3987 Component.prototype.destroy = function () { 3988 }; 3989 return Component; 3990 }()); 3991 Component.prototype.equalityFuncs = {}; 3992 /* 3993 Reuses old values when equal. If anything is unequal, returns newProps as-is. 3994 Great for PureComponent, but won't be feasible with React, so just eliminate and use React's DOM diffing. 3995 */ 3996 function recycleProps(oldProps, newProps, equalityFuncs) { 3997 var comboProps = {}; // some old, some new 3998 var anyChanges = false; 3999 for (var key in newProps) { 4000 if (key in oldProps && (oldProps[key] === newProps[key] || 4001 (equalityFuncs[key] && equalityFuncs[key](oldProps[key], newProps[key])))) { 4002 // equal to old? use old prop 4003 comboProps[key] = oldProps[key]; 4004 } 4005 else { 4006 comboProps[key] = newProps[key]; 4007 anyChanges = true; 4008 } 4009 } 4010 for (var key in oldProps) { 4011 if (!(key in newProps)) { 4012 anyChanges = true; 4013 break; 4014 } 4015 } 4016 return { anyChanges: anyChanges, comboProps: comboProps }; 4017 } 4018 4019 /* 4020 PURPOSES: 4021 - hook up to fg, fill, and mirror renderers 4022 - interface for dragging and hits 4023 */ 4024 var DateComponent = /** @class */ (function (_super) { 4025 __extends(DateComponent, _super); 4026 function DateComponent(context, el, isView) { 4027 var _this = _super.call(this, context, isView) || this; 4028 _this.el = el; 4029 return _this; 4030 } 4031 DateComponent.prototype.destroy = function () { 4032 _super.prototype.destroy.call(this); 4033 removeElement(this.el); 4034 }; 4035 // TODO: WHAT ABOUT (sourceSeg && sourceSeg.component.doesDragMirror) 4036 // 4037 // Event Drag-n-Drop Rendering (for both events and external elements) 4038 // --------------------------------------------------------------------------------------------------------------- 4039 /* 4040 renderEventDragSegs(state: EventSegUiInteractionState) { 4041 if (state) { 4042 let { isEvent, segs, sourceSeg } = state 4043 4044 if (this.eventRenderer) { 4045 this.eventRenderer.hideByHash(state.affectedInstances) 4046 } 4047 4048 // if the user is dragging something that is considered an event with real event data, 4049 // and this component likes to do drag mirrors OR the component where the seg came from 4050 // likes to do drag mirrors, then render a drag mirror. 4051 if (isEvent && (this.doesDragMirror || sourceSeg && sourceSeg.component.doesDragMirror)) { 4052 if (this.mirrorRenderer) { 4053 this.mirrorRenderer.renderSegs(segs, { isDragging: true, sourceSeg }) 4054 } 4055 } 4056 4057 // if it would be impossible to render a drag mirror OR this component likes to render 4058 // highlights, then render a highlight. 4059 if (!isEvent || this.doesDragHighlight) { 4060 if (this.fillRenderer) { 4061 this.fillRenderer.renderSegs('highlight', segs) 4062 } 4063 } 4064 } 4065 } 4066 */ 4067 // Hit System 4068 // ----------------------------------------------------------------------------------------------------------------- 4069 DateComponent.prototype.buildPositionCaches = function () { 4070 }; 4071 DateComponent.prototype.queryHit = function (positionLeft, positionTop, elWidth, elHeight) { 4072 return null; // this should be abstract 4073 }; 4074 // Validation 4075 // ----------------------------------------------------------------------------------------------------------------- 4076 DateComponent.prototype.isInteractionValid = function (interaction) { 4077 var calendar = this.calendar; 4078 var dateProfile = this.props.dateProfile; // HACK 4079 var instances = interaction.mutatedEvents.instances; 4080 if (dateProfile) { // HACK for DayTile 4081 for (var instanceId in instances) { 4082 if (!rangeContainsRange(dateProfile.validRange, instances[instanceId].range)) { 4083 return false;
4084 } 4085 } 4086 } 4087 return isInteractionValid(interaction, calendar); 4088 }; 4089 DateComponent.prototype.isDateSelectionValid = function (selection) { 4090 var dateProfile = this.props.dateProfile; // HACK 4091 if (dateProfile && // HACK for DayTile 4092 !rangeContainsRange(dateProfile.validRange, selection.range)) { 4093 return false; 4094 } 4095 return isDateSelectionValid(selection, this.calendar); 4096 }; 4097 // Triggering 4098 // ----------------------------------------------------------------------------------------------------------------- 4099 // TODO: move to Calendar 4100 DateComponent.prototype.publiclyTrigger = function (name, args) { 4101 var calendar = this.calendar; 4102 return calendar.publiclyTrigger(name, args); 4103 }; 4104 DateComponent.prototype.publiclyTriggerAfterSizing = function (name, args) { 4105 var calendar = this.calendar; 4106 return calendar.publiclyTriggerAfterSizing(name, args); 4107 }; 4108 DateComponent.prototype.hasPublicHandlers = function (name) { 4109 var calendar = this.calendar; 4110 return calendar.hasPublicHandlers(name); 4111 }; 4112 DateComponent.prototype.triggerRenderedSegs = function (segs, isMirrors) { 4113 var calendar = this.calendar; 4114 if (this.hasPublicHandlers('eventPositioned')) { 4115 for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) { 4116 var seg = segs_1[_i]; 4117 this.publiclyTriggerAfterSizing('eventPositioned', [ 4118 { 4119 event: new EventApi(calendar, seg.eventRange.def, seg.eventRange.instance), 4120 isMirror: isMirrors, 4121 isStart: seg.isStart, 4122 isEnd: seg.isEnd, 4123 el: seg.el, 4124 view: this // safe to cast because this method is only called on context.view 4125 } 4126 ]); 4127 } 4128 } 4129 if (!calendar.state.loadingLevel) { // avoid initial empty state while pending 4130 calendar.afterSizingTriggers._eventsPositioned = [null]; // fire once 4131 } 4132 }; 4133 DateComponent.prototype.triggerWillRemoveSegs = function (segs, isMirrors) { 4134 var calendar = this.calendar; 4135 for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) { 4136 var seg = segs_2[_i]; 4137 calendar.trigger('eventElRemove', seg.el); 4138 } 4139 if (this.hasPublicHandlers('eventDestroy')) { 4140 for (var _a = 0, segs_3 = segs; _a < segs_3.length; _a++) { 4141 var seg = segs_3[_a]; 4142 this.publiclyTrigger('eventDestroy', [ 4143 { 4144 event: new EventApi(calendar, seg.eventRange.def, seg.eventRange.instance), 4145 isMirror: isMirrors, 4146 el: seg.el, 4147 view: this // safe to cast because this method is only called on context.view 4148 } 4149 ]); 4150 } 4151 } 4152 }; 4153 // Pointer Interaction Utils 4154 // ----------------------------------------------------------------------------------------------------------------- 4155 DateComponent.prototype.isValidSegDownEl = function (el) { 4156 return !this.props.eventDrag && // HACK 4157 !this.props.eventResize && // HACK 4158 !elementClosest(el, '.fc-mirror') && 4159 (this.isPopover() || !this.isInPopover(el)); 4160 // ^above line ensures we don't detect a seg interaction within a nested component. 4161 // it's a HACK because it only supports a popover as the nested component. 4162 }; 4163 DateComponent.prototype.isValidDateDownEl = function (el) { 4164 var segEl = elementClosest(el, this.fgSegSelector); 4165 return (!segEl || segEl.classList.contains('fc-mirror')) && 4166 !elementClosest(el, '.fc-more') && // a "more.." link 4167 !elementClosest(el, 'a[data-goto]') && // a clickable nav link 4168 !this.isInPopover(el); 4169 }; 4170 DateComponent.prototype.isPopover = function () { 4171 return this.el.classList.contains('fc-popover'); 4172 }; 4173 DateComponent.prototype.isInPopover = function (el) { 4174 return Boolean(elementClosest(el, '.fc-popover')); 4175 }; 4176 return DateComponent; 4177 }(Component)); 4178 DateComponent.prototype.fgSegSelector = '.fc-event-container > *'; 4179 DateComponent.prototype.bgSegSelector = '.fc-bgevent:not(.fc-nonbusiness)'; 4180 4181 var uid$1 = 0; 4182 function createPlugin(input) { 4183 return { 4184 id: String(uid$1++), 4185 deps: input.deps || [], 4186 reducers: input.reducers || [], 4187 eventDefParsers: input.eventDefParsers || [], 4188 isDraggableTransformers: input.isDraggableTransformers || [], 4189 eventDragMutationMassagers: input.eventDragMutationMassagers || [], 4190 eventDefMutationAppliers: input.eventDefMutationAppliers || [], 4191 dateSelectionTransformers: input.dateSelectionTransformers || [], 4192 datePointTransforms: input.datePointTransforms || [], 4193 dateSpanTransforms: input.dateSpanTransforms || [], 4194 views: input.views || {}, 4195 viewPropsTransformers: input.viewPropsTransformers || [], 4196 isPropsValid: input.isPropsValid || null, 4197 externalDefTransforms: input.externalDefTransforms || [], 4198 eventResizeJoinTransforms: input.eventResizeJoinTransforms || [], 4199 viewContainerModifiers: input.viewContainerModifiers || [], 4200 eventDropTransformers: input.eventDropTransformers || [], 4201 componentInteractions: input.componentInteractions || [], 4202 calendarInteractions: input.calendarInteractions || [],
4203 themeClasses: input.themeClasses || {}, 4204 eventSourceDefs: input.eventSourceDefs || [], 4205 cmdFormatter: input.cmdFormatter, 4206 recurringTypes: input.recurringTypes || [], 4207 namedTimeZonedImpl: input.namedTimeZonedImpl, 4208 defaultView: input.defaultView || '', 4209 elementDraggingImpl: input.elementDraggingImpl, 4210 optionChangeHandlers: input.optionChangeHandlers || {} 4211 }; 4212 } 4213 var PluginSystem = /** @class */ (function () { 4214 function PluginSystem() { 4215 this.hooks = { 4216 reducers: [], 4217 eventDefParsers: [], 4218 isDraggableTransformers: [], 4219 eventDragMutationMassagers: [], 4220 eventDefMutationAppliers: [], 4221 dateSelectionTransformers: [], 4222 datePointTransforms: [], 4223 dateSpanTransforms: [], 4224 views: {}, 4225 viewPropsTransformers: [], 4226 isPropsValid: null, 4227 externalDefTransforms: [], 4228 eventResizeJoinTransforms: [], 4229 viewContainerModifiers: [], 4230 eventDropTransformers: [], 4231 componentInteractions: [], 4232 calendarInteractions: [], 4233 themeClasses: {}, 4234 eventSourceDefs: [], 4235 cmdFormatter: null, 4236 recurringTypes: [], 4237 namedTimeZonedImpl: null, 4238 defaultView: '', 4239 elementDraggingImpl: null, 4240 optionChangeHandlers: {} 4241 }; 4242 this.addedHash = {}; 4243 } 4244 PluginSystem.prototype.add = function (plugin) { 4245 if (!this.addedHash[plugin.id]) { 4246 this.addedHash[plugin.id] = true; 4247 for (var _i = 0, _a = plugin.deps; _i < _a.length; _i++) { 4248 var dep = _a[_i]; 4249 this.add(dep); 4250 } 4251 this.hooks = combineHooks(this.hooks, plugin); 4252 } 4253 }; 4254 return PluginSystem; 4255 }()); 4256 function combineHooks(hooks0, hooks1) { 4257 return { 4258 reducers: hooks0.reducers.concat(hooks1.reducers), 4259 eventDefParsers: hooks0.eventDefParsers.concat(hooks1.eventDefParsers), 4260 isDraggableTransformers: hooks0.isDraggableTransformers.concat(hooks1.isDraggableTransformers), 4261 eventDragMutationMassagers: hooks0.eventDragMutationMassagers.concat(hooks1.eventDragMutationMassagers), 4262 eventDefMutationAppliers: hooks0.eventDefMutationAppliers.concat(hooks1.eventDefMutationAppliers), 4263 dateSelectionTransformers: hooks0.dateSelectionTransformers.concat(hooks1.dateSelectionTransformers), 4264 datePointTransforms: hooks0.datePointTransforms.concat(hooks1.datePointTransforms), 4265 dateSpanTransforms: hooks0.dateSpanTransforms.concat(hooks1.dateSpanTransforms), 4266 views: __assign({}, hooks0.views, hooks1.views), 4267 viewPropsTransformers: hooks0.viewPropsTransformers.concat(hooks1.viewPropsTransformers), 4268 isPropsValid: hooks1.isPropsValid || hooks0.isPropsValid, 4269 externalDefTransforms: hooks0.externalDefTransforms.concat(hooks1.externalDefTransforms), 4270 eventResizeJoinTransforms: hooks0.eventResizeJoinTransforms.concat(hooks1.eventResizeJoinTransforms), 4271 viewContainerModifiers: hooks0.viewContainerModifiers.concat(hooks1.viewContainerModifiers), 4272 eventDropTransformers: hooks0.eventDropTransformers.concat(hooks1.eventDropTransformers), 4273 calendarInteractions: hooks0.calendarInteractions.concat(hooks1.calendarInteractions), 4274 componentInteractions: hooks0.componentInteractions.concat(hooks1.componentInteractions), 4275 themeClasses: __assign({}, hooks0.themeClasses, hooks1.themeClasses), 4276 eventSourceDefs: hooks0.eventSourceDefs.concat(hooks1.eventSourceDefs), 4277 cmdFormatter: hooks1.cmdFormatter || hooks0.cmdFormatter, 4278 recurringTypes: hooks0.recurringTypes.concat(hooks1.recurringTypes), 4279 namedTimeZonedImpl: hooks1.namedTimeZonedImpl || hooks0.namedTimeZonedImpl, 4280 defaultView: hooks0.defaultView || hooks1.defaultView, 4281 elementDraggingImpl: hooks0.elementDraggingImpl || hooks1.elementDraggingImpl, 4282 optionChangeHandlers: __assign({}, hooks0.optionChangeHandlers, hooks1.optionChangeHandlers) 4283 }; 4284 } 4285 4286 var eventSourceDef = { 4287 ignoreRange: true, 4288 parseMeta: function (raw) { 4289 if (Array.isArray(raw)) { // short form 4290 return raw; 4291 } 4292 else if (Array.isArray(raw.events)) { 4293 return raw.events; 4294 } 4295 return null; 4296 }, 4297 fetch: function (arg, success) { 4298 success({ 4299 rawEvents: arg.eventSource.meta 4300 }); 4301 } 4302 }; 4303 var ArrayEventSourcePlugin = createPlugin({ 4304 eventSourceDefs: [eventSourceDef] 4305 }); 4306 4307 var eventSourceDef$1 = { 4308 parseMeta: function (raw) { 4309 if (typeof raw === 'function') { // short form 4310 return raw; 4311 } 4312 else if (typeof raw.events === 'function') { 4313 return raw.events; 4314 } 4315 return null; 4316 }, 4317 fetch: function (arg, success, failure) { 4318 var dateEnv = arg.calendar.dateEnv; 4319 var func = arg.eventSource.meta; 4320 unpromisify(func.bind(null, { 4321 start: dateEnv.toDate(arg.range.start), 4322 end: dateEnv.toDate(arg.range.end), 4323 startStr: dateEnv.formatIso(arg.range.start), 4324 endStr: dateEnv.formatIso(arg.range.end), 4325 timeZone: dateEnv.timeZone 4326 }), function (rawEvents) { 4327 success({ rawEvents: rawEvents }); // needs an object response 4328 }, failure // send errorObj directly to failure callback 4329 ); 4330 } 4331 }; 4332 var FuncEventSourcePlugin = createPlugin({ 4333 eventSourceDefs: [eventSourceDef$1] 4334 }); 4335 4336 function requestJson(method, url, params, successCallback, failureCallback) { 4337 method = method.toUpperCase(); 4338 var body = null; 4339 if (method === 'GET') { 4340 url = injectQueryStringParams(url, params); 4341 } 4342 else { 4343 body = encodeParams(params); 4344 } 4345 var xhr = new XMLHttpRequest(); 4346 xhr.open(method, url, true); 4347 if (method !== 'GET') { 4348 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 4349 } 4350 xhr.onload = function () { 4351 if (xhr.status >= 200 && xhr.status < 400) { 4352 try { 4353 var res = JSON.parse(xhr.responseText); 4354 successCallback(res, xhr); 4355 } 4356 catch (err) { 4357 failureCallback('Failure parsing JSON', xhr); 4358 } 4359 } 4360 else { 4361 failureCallback('Request failed', xhr); 4362 } 4363 }; 4364 xhr.onerror = function () { 4365 failureCallback('Request failed', xhr); 4366 }; 4367 xhr.send(body); 4368 } 4369 function injectQueryStringParams(url, params) { 4370 return url + 4371 (url.indexOf('?') === -1 ? '?' : '&') + 4372 encodeParams(params); 4373 } 4374 function encodeParams(params) { 4375 var parts = []; 4376 for (var key in params) { 4377 parts.push(encodeURIComponent(key) + '=' + encodeURIComponent(params[key])); 4378 } 4379 return parts.join('&'); 4380 } 4381 4382 var eventSourceDef$2 = { 4383 parseMeta: function (raw) { 4384 if (typeof raw === 'string') { // short form 4385 raw = { url: raw }; 4386 } 4387 else if (!raw || typeof raw !== 'object' || !raw.url) { 4388 return null; 4389 } 4390 return { 4391 url: raw.url, 4392 method: (raw.method || 'GET').toUpperCase(), 4393 extraParams: raw.extraParams, 4394 startParam: raw.startParam, 4395 endParam: raw.endParam, 4396 timeZoneParam: raw.timeZoneParam 4397 }; 4398 }, 4399 fetch: function (arg, success, failure) { 4400 var meta = arg.eventSource.meta;
4401 var requestParams = buildRequestParams(meta, arg.range, arg.calendar); 4402 requestJson(meta.method, meta.url, requestParams, function (rawEvents, xhr) { 4403 success({ rawEvents: rawEvents, xhr: xhr }); 4404 }, function (errorMessage, xhr) { 4405 failure({ message: errorMessage, xhr: xhr }); 4406 }); 4407 } 4408 }; 4409 var JsonFeedEventSourcePlugin = createPlugin({ 4410 eventSourceDefs: [eventSourceDef$2] 4411 }); 4412 function buildRequestParams(meta, range, calendar) { 4413 var dateEnv = calendar.dateEnv; 4414 var startParam; 4415 var endParam; 4416 var timeZoneParam; 4417 var customRequestParams; 4418 var params = {}; 4419 startParam = meta.startParam; 4420 if (startParam == null) { 4421 startParam = calendar.opt('startParam'); 4422 } 4423 endParam = meta.endParam; 4424 if (endParam == null) { 4425 endParam = calendar.opt('endParam'); 4426 } 4427 timeZoneParam = meta.timeZoneParam; 4428 if (timeZoneParam == null) { 4429 timeZoneParam = calendar.opt('timeZoneParam'); 4430 } 4431 // retrieve any outbound GET/POST data from the options 4432 if (typeof meta.extraParams === 'function') { 4433 // supplied as a function that returns a key/value object
4434 customRequestParams = meta.extraParams(); 4435 } 4436 else { 4437 // probably supplied as a straight key/value object 4438 customRequestParams = meta.extraParams || {}; 4439 } 4440 __assign(params, customRequestParams); 4441 params[startParam] = dateEnv.formatIso(range.start); 4442 params[endParam] = dateEnv.formatIso(range.end); 4443 if (dateEnv.timeZone !== 'local') { 4444 params[timeZoneParam] = dateEnv.timeZone; 4445 } 4446 return params; 4447 } 4448 4449 var recurring = { 4450 parse: function (rawEvent, leftoverProps, dateEnv) { 4451 var createMarker = dateEnv.createMarker.bind(dateEnv); 4452 var processors = { 4453 daysOfWeek: null, 4454 startTime: createDuration, 4455 endTime: createDuration, 4456 startRecur: createMarker, 4457 endRecur: createMarker 4458 }; 4459 var props = refineProps(rawEvent, processors, {}, leftoverProps); 4460 var anyValid = false; 4461 for (var propName in props) { 4462 if (props[propName] != null) { 4463 anyValid = true; 4464 break; 4465 } 4466 } 4467 if (anyValid) { 4468 var duration = null; 4469 if ('duration' in leftoverProps) { 4470 duration = createDuration(leftoverProps.duration); 4471 delete leftoverProps.duration; 4472 } 4473 if (!duration && props.startTime && props.endTime) { 4474 duration = subtractDurations(props.endTime, props.startTime); 4475 } 4476 return { 4477 allDayGuess: Boolean(!props.startTime && !props.endTime), 4478 duration: duration, 4479 typeData: props // doesn't need endTime anymore but oh well 4480 }; 4481 } 4482 return null; 4483 }, 4484 expand: function (typeData, framingRange, dateEnv) { 4485 var clippedFramingRange = intersectRanges(framingRange, { start: typeData.startRecur, end: typeData.endRecur }); 4486 if (clippedFramingRange) { 4487 return expandRanges(typeData.daysOfWeek, typeData.startTime, clippedFramingRange, dateEnv); 4488 } 4489 else { 4490 return []; 4491 } 4492 } 4493 }; 4494 var SimpleRecurrencePlugin = createPlugin({ 4495 recurringTypes: [recurring] 4496 }); 4497 function expandRanges(daysOfWeek, startTime, framingRange, dateEnv) { 4498 var dowHash = daysOfWeek ? arrayToHash(daysOfWeek) : null; 4499 var dayMarker = startOfDay(framingRange.start); 4500 var endMarker = framingRange.end; 4501 var instanceStarts = []; 4502 while (dayMarker < endMarker) { 4503 var instanceStart 4504 // if everyday, or this particular day-of-week 4505 = void 0; 4506 // if everyday, or this particular day-of-week 4507 if (!dowHash || dowHash[dayMarker.getUTCDay()]) { 4508 if (startTime) { 4509 instanceStart = dateEnv.add(dayMarker, startTime); 4510 } 4511 else { 4512 instanceStart = dayMarker; 4513 } 4514 instanceStarts.push(instanceStart); 4515 } 4516 dayMarker = addDays(dayMarker, 1); 4517 } 4518 return instanceStarts; 4519 } 4520 4521 var DefaultOptionChangeHandlers = createPlugin({ 4522 optionChangeHandlers: { 4523 events: function (events, calendar, deepEqual) { 4524 handleEventSources([events], calendar, deepEqual); 4525 }, 4526 eventSources: handleEventSources, 4527 plugins: handlePlugins 4528 } 4529 }); 4530 function handleEventSources(inputs, calendar, deepEqual) { 4531 var unfoundSources = hashValuesToArray(calendar.state.eventSources);
4532 var newInputs = []; 4533 for (var _i = 0, inputs_1 = inputs; _i < inputs_1.length; _i++) { 4534 var input = inputs_1[_i]; 4535 var inputFound = false; 4536 for (var i = 0; i < unfoundSources.length; i++) { 4537 if (deepEqual(unfoundSources[i]._raw, input)) { 4538 unfoundSources.splice(i, 1); // delete 4539 inputFound = true; 4540 break; 4541 } 4542 } 4543 if (!inputFound) { 4544 newInputs.push(input); 4545 } 4546 } 4547 for (var _a = 0, unfoundSources_1 = unfoundSources; _a < unfoundSources_1.length; _a++) { 4548 var unfoundSource = unfoundSources_1[_a]; 4549 calendar.dispatch({ 4550 type: 'REMOVE_EVENT_SOURCE', 4551 sourceId: unfoundSource.sourceId 4552 }); 4553 } 4554 for (var _b = 0, newInputs_1 = newInputs; _b < newInputs_1.length; _b++) { 4555 var newInput = newInputs_1[_b]; 4556 calendar.addEventSource(newInput); 4557 } 4558 } 4559 // shortcoming: won't remove plugins 4560 function handlePlugins(inputs, calendar) { 4561 calendar.addPluginInputs(inputs); // will gracefully handle duplicates 4562 } 4563 4564 var config = {}; // TODO: make these options 4565 var globalDefaults = { 4566 defaultRangeSeparator: ' - ', 4567 titleRangeSeparator: ' \u2013 ', 4568 defaultTimedEventDuration: '01:00:00', 4569 defaultAllDayEventDuration: { day: 1 }, 4570 forceEventDuration: false, 4571 nextDayThreshold: '00:00:00', 4572 // display 4573 columnHeader: true, 4574 defaultView: '', 4575 aspectRatio: 1.35, 4576 header: { 4577 left: 'title', 4578 center: '', 4579 right: 'today prev,next' 4580 }, 4581 weekends: true, 4582 weekNumbers: false, 4583 weekNumberCalculation: 'local', 4584 editable: false, 4585 // nowIndicator: false, 4586 scrollTime: '06:00:00', 4587 minTime: '00:00:00', 4588 maxTime: '24:00:00', 4589 showNonCurrentDates: true, 4590 // event ajax 4591 lazyFetching: true, 4592 startParam: 'start', 4593 endParam: 'end', 4594 timeZoneParam: 'timeZone', 4595 timeZone: 'local', 4596 // allDayDefault: undefined, 4597 // locale 4598 locales: [], 4599 locale: '', 4600 // dir: will get this from the default locale 4601 // buttonIcons: null, 4602 // allows setting a min-height to the event segment to prevent short events overlapping each other 4603 timeGridEventMinHeight: 0, 4604 themeSystem: 'standard', 4605 // eventResizableFromStart: false, 4606 dragRevertDuration: 500, 4607 dragScroll: true, 4608 allDayMaintainDuration: false, 4609 // selectable: false, 4610 unselectAuto: true, 4611 // selectMinDistance: 0, 4612 dropAccept: '*', 4613 eventOrder: 'start,-duration,allDay,title', 4614 // ^ if start tie, longer events go before shorter. final tie-breaker is title text 4615 // rerenderDelay: null, 4616 eventLimit: false, 4617 eventLimitClick: 'popover', 4618 dayPopoverFormat: { month: 'long', day: 'numeric', year: 'numeric' }, 4619 handleWindowResize: true, 4620 windowResizeDelay: 100, 4621 longPressDelay: 1000, 4622 eventDragMinDistance: 5 // only applies to mouse 4623 }; 4624 var rtlDefaults = { 4625 header: { 4626 left: 'next,prev today', 4627 center: '', 4628 right: 'title' 4629 }, 4630 buttonIcons: { 4631 // TODO: make RTL support the responibility of the theme 4632 prev: 'fc-icon-chevron-right', 4633 next: 'fc-icon-chevron-left', 4634 prevYear: 'fc-icon-chevrons-right', 4635 nextYear: 'fc-icon-chevrons-left' 4636 } 4637 }; 4638 var complexOptions = [ 4639 'header', 4640 'footer', 4641 'buttonText', 4642 'buttonIcons' 4643 ]; 4644 // Merges an array of option objects into a single object 4645 function mergeOptions(optionObjs) { 4646 return mergeProps(optionObjs, complexOptions); 4647 } 4648 // TODO: move this stuff to a "plugin"-related file... 4649 var INTERNAL_PLUGINS = [ 4650 ArrayEventSourcePlugin, 4651 FuncEventSourcePlugin, 4652 JsonFeedEventSourcePlugin, 4653 SimpleRecurrencePlugin, 4654 DefaultOptionChangeHandlers 4655 ]; 4656 function refinePluginDefs(pluginInputs) { 4657 var plugins = []; 4658 for (var _i = 0, pluginInputs_1 = pluginInputs; _i < pluginInputs_1.length; _i++) { 4659 var pluginInput = pluginInputs_1[_i]; 4660 if (typeof pluginInput === 'string') { 4661 var globalName = 'FullCalendar' + capitaliseFirstLetter(pluginInput); 4662 if (!window[globalName]) { 4663 console.warn('Plugin file not loaded for ' + pluginInput); 4664 } 4665 else { 4666 plugins.push(window[globalName].default); // is an ES6 module 4667 } 4668 } 4669 else { 4670 plugins.push(pluginInput); 4671 } 4672 } 4673 return INTERNAL_PLUGINS.concat(plugins); 4674 } 4675 4676 var RAW_EN_LOCALE = { 4677 code: 'en', 4678 week: { 4679 dow: 0, 4680 doy: 4 // 4 days need to be within the year to be considered the first week 4681 }, 4682 dir: 'ltr', 4683 buttonText: { 4684 prev: 'prev', 4685 next: 'next', 4686 prevYear: 'prev year', 4687 nextYear: 'next year', 4688 year: 'year', 4689 today: 'today', 4690 month: 'month', 4691 week: 'week', 4692 day: 'day', 4693 list: 'list' 4694 }, 4695 weekLabel: 'W', 4696 allDayText: 'all-day', 4697 eventLimitText: 'more', 4698 noEventsMessage: 'No events to display' 4699 }; 4700 function parseRawLocales(explicitRawLocales) { 4701 var defaultCode = explicitRawLocales.length > 0 ? explicitRawLocales[0].code : 'en'; 4702 var globalArray = window['FullCalendarLocalesAll'] || []; // from locales-all.js 4703 var globalObject = window['FullCalendarLocales'] || {}; // from locales/*.js. keys are meaningless 4704 var allRawLocales = globalArray.concat(// globalArray is low prio 4705 hashValuesToArray(globalObject), // medium prio 4706 explicitRawLocales // highest prio 4707 ); 4708 var rawLocaleMap = { 4709 en: RAW_EN_LOCALE // necessary? 4710 }; 4711 for (var _i = 0, allRawLocales_1 = allRawLocales; _i < allRawLocales_1.length; _i++) { 4712 var rawLocale = allRawLocales_1[_i]; 4713 rawLocaleMap[rawLocale.code] = rawLocale; 4714 } 4715 return { 4716 map: rawLocaleMap, 4717 defaultCode: defaultCode 4718 }; 4719 } 4720 function buildLocale(inputSingular, available) { 4721 if (typeof inputSingular === 'object' && !Array.isArray(inputSingular)) { 4722 return parseLocale(inputSingular.code, [inputSingular.code], inputSingular); 4723 } 4724 else { 4725 return queryLocale(inputSingular, available); 4726 } 4727 } 4728 function queryLocale(codeArg, available) { 4729 var codes = [].concat(codeArg || []); // will convert to array 4730 var raw = queryRawLocale(codes, available) || RAW_EN_LOCALE; 4731 return parseLocale(codeArg, codes, raw); 4732 } 4733 function queryRawLocale(codes, available) { 4734 for (var i = 0; i < codes.length; i++) { 4735 var parts = codes[i].toLocaleLowerCase().split('-'); 4736 for (var j = parts.length; j > 0; j--) { 4737 var simpleId = parts.slice(0, j).join('-'); 4738 if (available[simpleId]) { 4739 return available[simpleId]; 4740 } 4741 } 4742 } 4743 return null; 4744 } 4745 function parseLocale(codeArg, codes, raw) { 4746 var merged = mergeProps([RAW_EN_LOCALE, raw], ['buttonText']); 4747 delete merged.code; // don't want this part of the options 4748 var week = merged.week; 4749 delete merged.week; 4750 return { 4751 codeArg: codeArg, 4752 codes: codes, 4753 week: week, 4754 simpleNumberFormat: new Intl.NumberFormat(codeArg), 4755 options: merged 4756 }; 4757 } 4758 4759 var OptionsManager = /** @class */ (function () { 4760 function OptionsManager(overrides) { 4761 this.overrides = __assign({}, overrides); // make a copy 4762 this.dynamicOverrides = {}; 4763 this.compute(); 4764 } 4765 OptionsManager.prototype.mutate = function (updates, removals, isDynamic) { 4766 var overrideHash = isDynamic ? this.dynamicOverrides : this.overrides; 4767 __assign(overrideHash, updates); 4768 for (var _i = 0, removals_1 = removals; _i < removals_1.length; _i++) { 4769 var propName = removals_1[_i]; 4770 delete overrideHash[propName]; 4771 } 4772 this.compute(); 4773 }; 4774 // Computes the flattened options hash for the calendar and assigns to `this.options`. 4775 // Assumes this.overrides and this.dynamicOverrides have already been initialized. 4776 OptionsManager.prototype.compute = function () {
4777 // TODO: not a very efficient system 4778 var locales = firstDefined(// explicit locale option given? 4779 this.dynamicOverrides.locales, this.overrides.locales, globalDefaults.locales); 4780 var locale = firstDefined(// explicit locales option given? 4781 this.dynamicOverrides.locale, this.overrides.locale, globalDefaults.locale); 4782 var available = parseRawLocales(locales); 4783 var localeDefaults = buildLocale(locale || available.defaultCode, available.map).options; 4784 var dir = firstDefined(// based on options computed so far, is direction RTL? 4785 this.dynamicOverrides.dir, this.overrides.dir, localeDefaults.dir); 4786 var dirDefaults = dir === 'rtl' ? rtlDefaults : {}; 4787 this.dirDefaults = dirDefaults; 4788 this.localeDefaults = localeDefaults; 4789 this.computed = mergeOptions([ 4790 globalDefaults, 4791 dirDefaults, 4792 localeDefaults, 4793 this.overrides, 4794 this.dynamicOverrides 4795 ]); 4796 }; 4797 return OptionsManager; 4798 }()); 4799 4800 var calendarSystemClassMap = {}; 4801 function registerCalendarSystem(name, theClass) { 4802 calendarSystemClassMap[name] = theClass; 4803 } 4804 function createCalendarSystem(name) { 4805 return new calendarSystemClassMap[name](); 4806 } 4807 var GregorianCalendarSystem = /** @class */ (function () { 4808 function GregorianCalendarSystem() { 4809 } 4810 GregorianCalendarSystem.prototype.getMarkerYear = function (d) { 4811 return d.getUTCFullYear(); 4812 }; 4813 GregorianCalendarSystem.prototype.getMarkerMonth = function (d) { 4814 return d.getUTCMonth(); 4815 }; 4816 GregorianCalendarSystem.prototype.getMarkerDay = function (d) { 4817 return d.getUTCDate(); 4818 }; 4819 GregorianCalendarSystem.prototype.arrayToMarker = function (arr) { 4820 return arrayToUtcDate(arr); 4821 }; 4822 GregorianCalendarSystem.prototype.markerToArray = function (marker) { 4823 return dateToUtcArray(marker); 4824 }; 4825 return GregorianCalendarSystem; 4826 }()); 4827 registerCalendarSystem('gregory', GregorianCalendarSystem); 4828 4829 var ISO_RE = /^\s*(\d{4})(-(\d{2})(-(\d{2})([T ](\d{2}):(\d{2})(:(\d{2})(\.(\d+))?)?(Z|(([-+])(\d{2})(:?(\d{2}))?))?)?)?)?$/; 4830 function parse(str) { 4831 var m = ISO_RE.exec(str); 4832 if (m) { 4833 var marker = new Date(Date.UTC(Number(m[1]), m[3] ? Number(m[3]) - 1 : 0, Number(m[5] || 1), Number(m[7] || 0), Number(m[8] || 0), Number(m[10] || 0), m[12] ? Number('0.' + m[12]) * 1000 : 0)); 4834 if (isValidDate(marker)) { 4835 var timeZoneOffset = null; 4836 if (m[13]) { 4837 timeZoneOffset = (m[15] === '-' ? -1 : 1) * (Number(m[16] || 0) * 60 + 4838 Number(m[18] || 0)); 4839 } 4840 return { 4841 marker: marker, 4842 isTimeUnspecified: !m[6], 4843 timeZoneOffset: timeZoneOffset 4844 }; 4845 } 4846 } 4847 return null; 4848 } 4849 4850 var DateEnv = /** @class */ (function () { 4851 function DateEnv(settings) { 4852 var timeZone = this.timeZone = settings.timeZone; 4853 var isNamedTimeZone = timeZone !== 'local' && timeZone !== 'UTC'; 4854 if (settings.namedTimeZoneImpl && isNamedTimeZone) { 4855 this.namedTimeZoneImpl = new settings.namedTimeZoneImpl(timeZone); 4856 } 4857 this.canComputeOffset = Boolean(!isNamedTimeZone || this.namedTimeZoneImpl); 4858 this.calendarSystem = createCalendarSystem(settings.calendarSystem); 4859 this.locale = settings.locale; 4860 this.weekDow = settings.locale.week.dow; 4861 this.weekDoy = settings.locale.week.doy; 4862 if (settings.weekNumberCalculation === 'ISO') { 4863 this.weekDow = 1; 4864 this.weekDoy = 4; 4865 } 4866 if (typeof settings.firstDay === 'number') { 4867 this.weekDow = settings.firstDay; 4868 } 4869 if (typeof settings.weekNumberCalculation === 'function') {
4870 this.weekNumberFunc = settings.weekNumberCalculation; 4871 } 4872 this.weekLabel = settings.weekLabel != null ? settings.weekLabel : settings.locale.options.weekLabel; 4873 this.cmdFormatter = settings.cmdFormatter; 4874 } 4875 // Creating / Parsing 4876 DateEnv.prototype.createMarker = function (input) { 4877 var meta = this.createMarkerMeta(input); 4878 if (meta === null) { 4879 return null; 4880 } 4881 return meta.marker; 4882 }; 4883 DateEnv.prototype.createNowMarker = function () { 4884 if (this.canComputeOffset) { 4885 return this.timestampToMarker(new Date().valueOf()); 4886 } 4887 else { 4888 // if we can't compute the current date val for a timezone, 4889 // better to give the current local date vals than UTC 4890 return arrayToUtcDate(dateToLocalArray(new Date())); 4891 } 4892 }; 4893 DateEnv.prototype.createMarkerMeta = function (input) { 4894 if (typeof input === 'string') { 4895 return this.parse(input); 4896 } 4897 var marker = null; 4898 if (typeof input === 'number') { 4899 marker = this.timestampToMarker(input); 4900 } 4901 else if (input instanceof Date) { 4902 input = input.valueOf(); 4903 if (!isNaN(input)) { 4904 marker = this.timestampToMarker(input); 4905 } 4906 } 4907 else if (Array.isArray(input)) { 4908 marker = arrayToUtcDate(input); 4909 } 4910 if (marker === null || !isValidDate(marker)) { 4911 return null; 4912 } 4913 return { marker: marker, isTimeUnspecified: false, forcedTzo: null }; 4914 }; 4915 DateEnv.prototype.parse = function (s) { 4916 var parts = parse(s); 4917 if (parts === null) { 4918 return null; 4919 } 4920 var marker = parts.marker; 4921 var forcedTzo = null; 4922 if (parts.timeZoneOffset !== null) { 4923 if (this.canComputeOffset) { 4924 marker = this.timestampToMarker(marker.valueOf() - parts.timeZoneOffset * 60 * 1000); 4925 } 4926 else { 4927 forcedTzo = parts.timeZoneOffset; 4928 } 4929 } 4930 return { marker: marker, isTimeUnspecified: parts.isTimeUnspecified, forcedTzo: forcedTzo }; 4931 }; 4932 // Accessors 4933 DateEnv.prototype.getYear = function (marker) { 4934 return this.calendarSystem.getMarkerYear(marker); 4935 }; 4936 DateEnv.prototype.getMonth = function (marker) { 4937 return this.calendarSystem.getMarkerMonth(marker); 4938 }; 4939 // Adding / Subtracting 4940 DateEnv.prototype.add = function (marker, dur) { 4941 var a = this.calendarSystem.markerToArray(marker); 4942 a[0] += dur.years; 4943 a[1] += dur.months; 4944 a[2] += dur.days; 4945 a[6] += dur.milliseconds; 4946 return this.calendarSystem.arrayToMarker(a); 4947 }; 4948 DateEnv.prototype.subtract = function (marker, dur) { 4949 var a = this.calendarSystem.markerToArray(marker); 4950 a[0] -= dur.years; 4951 a[1] -= dur.months; 4952 a[2] -= dur.days; 4953 a[6] -= dur.milliseconds; 4954 return this.calendarSystem.arrayToMarker(a); 4955 }; 4956 DateEnv.prototype.addYears = function (marker, n) { 4957 var a = this.calendarSystem.markerToArray(marker); 4958 a[0] += n; 4959 return this.calendarSystem.arrayToMarker(a); 4960 }; 4961 DateEnv.prototype.addMonths = function (marker, n) { 4962 var a = this.calendarSystem.markerToArray(marker); 4963 a[1] += n; 4964 return this.calendarSystem.arrayToMarker(a); 4965 }; 4966 // Diffing Whole Units 4967 DateEnv.prototype.diffWholeYears = function (m0, m1) { 4968 var calendarSystem = this.calendarSystem; 4969 if (timeAsMs(m0) === timeAsMs(m1) && 4970 calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1) && 4971 calendarSystem.getMarkerMonth(m0) === calendarSystem.getMarkerMonth(m1)) { 4972 return calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0); 4973 } 4974 return null; 4975 }; 4976 DateEnv.prototype.diffWholeMonths = function (m0, m1) { 4977 var calendarSystem = this.calendarSystem; 4978 if (timeAsMs(m0) === timeAsMs(m1) && 4979 calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1)) { 4980 return (calendarSystem.getMarkerMonth(m1) - calendarSystem.getMarkerMonth(m0)) + 4981 (calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0)) * 12; 4982 } 4983 return null; 4984 }; 4985 // Range / Duration 4986 DateEnv.prototype.greatestWholeUnit = function (m0, m1) { 4987 var n = this.diffWholeYears(m0, m1); 4988 if (n !== null) { 4989 return { unit: 'year', value: n }; 4990 } 4991 n = this.diffWholeMonths(m0, m1); 4992 if (n !== null) { 4993 return { unit: 'month', value: n }; 4994 } 4995 n = diffWholeWeeks(m0, m1); 4996 if (n !== null) { 4997 return { unit: 'week', value: n }; 4998 } 4999 n = diffWholeDays(m0, m1); 5000 if (n !== null) { 5001 return { unit: 'day', value: n }; 5002 } 5003 n = diffHours(m0, m1); 5004 if (isInt(n)) { 5005 return { unit: 'hour', value: n }; 5006 } 5007 n = diffMinutes(m0, m1); 5008 if (isInt(n)) { 5009 return { unit: 'minute', value: n }; 5010 } 5011 n = diffSeconds(m0, m1); 5012 if (isInt(n)) { 5013 return { unit: 'second', value: n }; 5014 } 5015 return { unit: 'millisecond', value: m1.valueOf() - m0.valueOf() }; 5016 }; 5017 DateEnv.prototype.countDurationsBetween = function (m0, m1, d) { 5018 // TODO: can use greatestWholeUnit 5019 var diff; 5020 if (d.years) { 5021 diff = this.diffWholeYears(m0, m1); 5022 if (diff !== null) { 5023 return diff / asRoughYears(d); 5024 } 5025 } 5026 if (d.months) { 5027 diff = this.diffWholeMonths(m0, m1); 5028 if (diff !== null) { 5029 return diff / asRoughMonths(d); 5030 } 5031 } 5032 if (d.days) { 5033 diff = diffWholeDays(m0, m1); 5034 if (diff !== null) { 5035 return diff / asRoughDays(d); 5036 } 5037 } 5038 return (m1.valueOf() - m0.valueOf()) / asRoughMs(d); 5039 }; 5040 // Start-Of 5041 DateEnv.prototype.startOf = function (m, unit) { 5042 if (unit === 'year') { 5043 return this.startOfYear(m); 5044 } 5045 else if (unit === 'month') { 5046 return this.startOfMonth(m); 5047 } 5048 else if (unit === 'week') { 5049 return this.startOfWeek(m); 5050 } 5051 else if (unit === 'day') { 5052 return startOfDay(m); 5053 } 5054 else if (unit === 'hour') { 5055 return startOfHour(m); 5056 } 5057 else if (unit === 'minute') { 5058 return startOfMinute(m); 5059 } 5060 else if (unit === 'second') { 5061 return startOfSecond(m); 5062 } 5063 }; 5064 DateEnv.prototype.startOfYear = function (m) { 5065 return this.calendarSystem.arrayToMarker([ 5066 this.calendarSystem.getMarkerYear(m) 5067 ]); 5068 }; 5069 DateEnv.prototype.startOfMonth = function (m) { 5070 return this.calendarSystem.arrayToMarker([ 5071 this.calendarSystem.getMarkerYear(m), 5072 this.calendarSystem.getMarkerMonth(m) 5073 ]); 5074 }; 5075 DateEnv.prototype.startOfWeek = function (m) { 5076 return this.calendarSystem.arrayToMarker([ 5077 this.calendarSystem.getMarkerYear(m), 5078 this.calendarSystem.getMarkerMonth(m), 5079 m.getUTCDate() - ((m.getUTCDay() - this.weekDow + 7) % 7) 5080 ]); 5081 }; 5082 // Week Number 5083 DateEnv.prototype.computeWeekNumber = function (marker) { 5084 if (this.weekNumberFunc) { 5085 return this.weekNumberFunc(this.toDate(marker)); 5086 } 5087 else { 5088 return weekOfYear(marker, this.weekDow, this.weekDoy); 5089 } 5090 }; 5091 // TODO: choke on timeZoneName: long 5092 DateEnv.prototype.format = function (marker, formatter, dateOptions) { 5093 if (dateOptions === void 0) { dateOptions = {}; } 5094 return formatter.format({ 5095 marker: marker, 5096 timeZoneOffset: dateOptions.forcedTzo != null ? 5097 dateOptions.forcedTzo : 5098 this.offsetForMarker(marker) 5099 }, this); 5100 }; 5101 DateEnv.prototype.formatRange = function (start, end, formatter, dateOptions) { 5102 if (dateOptions === void 0) { dateOptions = {}; } 5103 if (dateOptions.isEndExclusive) { 5104 end = addMs(end, -1); 5105 } 5106 return formatter.formatRange({ 5107 marker: start, 5108 timeZoneOffset: dateOptions.forcedStartTzo != null ? 5109 dateOptions.forcedStartTzo : 5110 this.offsetForMarker(start) 5111 }, { 5112 marker: end, 5113 timeZoneOffset: dateOptions.forcedEndTzo != null ? 5114 dateOptions.forcedEndTzo : 5115 this.offsetForMarker(end) 5116 }, this); 5117 }; 5118 DateEnv.prototype.formatIso = function (marker, extraOptions) { 5119 if (extraOptions === void 0) { extraOptions = {}; } 5120 var timeZoneOffset = null; 5121 if (!extraOptions.omitTimeZoneOffset) { 5122 if (extraOptions.forcedTzo != null) { 5123 timeZoneOffset = extraOptions.forcedTzo; 5124 } 5125 else { 5126 timeZoneOffset = this.offsetForMarker(marker); 5127 } 5128 } 5129 return buildIsoString(marker, timeZoneOffset, extraOptions.omitTime); 5130 }; 5131 // TimeZone 5132 DateEnv.prototype.timestampToMarker = function (ms) { 5133 if (this.timeZone === 'local') { 5134 return arrayToUtcDate(dateToLocalArray(new Date(ms))); 5135 } 5136 else if (this.timeZone === 'UTC' || !this.namedTimeZoneImpl) { 5137 return new Date(ms); 5138 } 5139 else { 5140 return arrayToUtcDate(this.namedTimeZoneImpl.timestampToArray(ms)); 5141 } 5142 }; 5143 DateEnv.prototype.offsetForMarker = function (m) { 5144 if (this.timeZone === 'local') { 5145 return -arrayToLocalDate(dateToUtcArray(m)).getTimezoneOffset(); // convert "inverse" offset to "normal" offset 5146 } 5147 else if (this.timeZone === 'UTC') { 5148 return 0; 5149 } 5150 else if (this.namedTimeZoneImpl) { 5151 return this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m)); 5152 } 5153 return null; 5154 }; 5155 // Conversion 5156 DateEnv.prototype.toDate = function (m, forcedTzo) { 5157 if (this.timeZone === 'local') { 5158 return arrayToLocalDate(dateToUtcArray(m)); 5159 } 5160 else if (this.timeZone === 'UTC') { 5161 return new Date(m.valueOf()); // make sure it's a copy 5162 } 5163 else if (!this.namedTimeZoneImpl) { 5164 return new Date(m.valueOf() - (forcedTzo || 0)); 5165 } 5166 else { 5167 return new Date(m.valueOf() - 5168 this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m)) * 1000 * 60 // convert minutes -> ms 5169 ); 5170 } 5171 }; 5172 return DateEnv; 5173 }()); 5174 5175 var SIMPLE_SOURCE_PROPS = { 5176 id: String, 5177 allDayDefault: Boolean, 5178 eventDataTransform: Function, 5179 success: Function, 5180 failure: Function 5181 }; 5182 var uid$2 = 0; 5183 function doesSourceNeedRange(eventSource, calendar) { 5184 var defs = calendar.pluginSystem.hooks.eventSourceDefs; 5185 return !defs[eventSource.sourceDefId].ignoreRange; 5186 } 5187 function parseEventSource(raw, calendar) { 5188 var defs = calendar.pluginSystem.hooks.eventSourceDefs;
5189 for (var i = defs.length - 1; i >= 0; i--) { // later-added plugins take precedence 5190 var def = defs[i]; 5191 var meta = def.parseMeta(raw); 5192 if (meta) { 5193 var res = parseEventSourceProps(typeof raw === 'object' ? raw : {}, meta, i, calendar); 5194 res._raw = raw; 5195 return res; 5196 } 5197 } 5198 return null; 5199 } 5200 function parseEventSourceProps(raw, meta, sourceDefId, calendar) { 5201 var leftovers0 = {}; 5202 var props = refineProps(raw, SIMPLE_SOURCE_PROPS, {}, leftovers0); 5203 var leftovers1 = {}; 5204 var ui = processUnscopedUiProps(leftovers0, calendar, leftovers1); 5205 props.isFetching = false; 5206 props.latestFetchId = ''; 5207 props.fetchRange = null; 5208 props.publicId = String(raw.id || ''); 5209 props.sourceId = String(uid$2++); 5210 props.sourceDefId = sourceDefId; 5211 props.meta = meta; 5212 props.ui = ui; 5213 props.extendedProps = leftovers1; 5214 return props; 5215 } 5216 5217 function reduceEventSources (eventSources, action, dateProfile, calendar) { 5218 switch (action.type) { 5219 case 'ADD_EVENT_SOURCES': // already parsed 5220 return addSources(eventSources, action.sources, dateProfile ? dateProfile.activeRange : null, calendar);
5221 case 'REMOVE_EVENT_SOURCE': 5222 return removeSource(eventSources, action.sourceId); 5223 case 'PREV': // TODO: how do we track all actions that affect dateProfile :( 5224 case 'NEXT': 5225 case 'SET_DATE': 5226 case 'SET_VIEW_TYPE': 5227 if (dateProfile) { 5228 return fetchDirtySources(eventSources, dateProfile.activeRange, calendar); 5229 } 5230 else { 5231 return eventSources; 5232 } 5233 case 'FETCH_EVENT_SOURCES': 5234 case 'CHANGE_TIMEZONE': 5235 return fetchSourcesByIds(eventSources, action.sourceIds ? 5236 arrayToHash(action.sourceIds) : 5237 excludeStaticSources(eventSources, calendar), dateProfile ? dateProfile.activeRange : null, calendar); 5238 case 'RECEIVE_EVENTS': 5239 case 'RECEIVE_EVENT_ERROR': 5240 return receiveResponse(eventSources, action.sourceId, action.fetchId, action.fetchRange); 5241 case 'REMOVE_ALL_EVENT_SOURCES': 5242 return {}; 5243 default: 5244 return eventSources; 5245 } 5246 } 5247 var uid$3 = 0; 5248 function addSources(eventSourceHash, sources, fetchRange, calendar) { 5249 var hash = {}; 5250 for (var _i = 0, sources_1 = sources; _i < sources_1.length; _i++) { 5251 var source = sources_1[_i]; 5252 hash[source.sourceId] = source; 5253 } 5254 if (fetchRange) { 5255 hash = fetchDirtySources(hash, fetchRange, calendar); 5256 } 5257 return __assign({}, eventSourceHash, hash); 5258 } 5259 function removeSource(eventSourceHash, sourceId) { 5260 return filterHash(eventSourceHash, function (eventSource) { 5261 return eventSource.sourceId !== sourceId; 5262 }); 5263 } 5264 function fetchDirtySources(sourceHash, fetchRange, calendar) { 5265 return fetchSourcesByIds(sourceHash, filterHash(sourceHash, function (eventSource) { 5266 return isSourceDirty(eventSource, fetchRange, calendar); 5267 }), fetchRange, calendar); 5268 } 5269 function isSourceDirty(eventSource, fetchRange, calendar) { 5270 if (!doesSourceNeedRange(eventSource, calendar)) { 5271 return !eventSource.latestFetchId; 5272 } 5273 else { 5274 return !calendar.opt('lazyFetching') || 5275 !eventSource.fetchRange || 5276 fetchRange.start < eventSource.fetchRange.start || 5277 fetchRange.end > eventSource.fetchRange.end; 5278 } 5279 } 5280 function fetchSourcesByIds(prevSources, sourceIdHash, fetchRange, calendar) { 5281 var nextSources = {}; 5282 for (var sourceId in prevSources) { 5283 var source = prevSources[sourceId]; 5284 if (sourceIdHash[sourceId]) { 5285 nextSources[sourceId] = fetchSource(source, fetchRange, calendar); 5286 } 5287 else { 5288 nextSources[sourceId] = source; 5289 } 5290 } 5291 return nextSources; 5292 } 5293 function fetchSource(eventSource, fetchRange, calendar) { 5294 var sourceDef = calendar.pluginSystem.hooks.eventSourceDefs[eventSource.sourceDefId]; 5295 var fetchId = String(uid$3++); 5296 sourceDef.fetch({ 5297 eventSource: eventSource, 5298 calendar: calendar, 5299 range: fetchRange 5300 }, function (res) { 5301 var rawEvents = res.rawEvents; 5302 var calSuccess = calendar.opt('eventSourceSuccess'); 5303 var calSuccessRes; 5304 var sourceSuccessRes; 5305 if (eventSource.success) { 5306 sourceSuccessRes = eventSource.success(rawEvents, res.xhr); 5307 } 5308 if (calSuccess) { 5309 calSuccessRes = calSuccess(rawEvents, res.xhr); 5310 } 5311 rawEvents = sourceSuccessRes || calSuccessRes || rawEvents; 5312 calendar.dispatch({ 5313 type: 'RECEIVE_EVENTS', 5314 sourceId: eventSource.sourceId, 5315 fetchId: fetchId, 5316 fetchRange: fetchRange, 5317 rawEvents: rawEvents 5318 }); 5319 }, function (error) { 5320 var callFailure = calendar.opt('eventSourceFailure'); 5321 console.warn(error.message, error); 5322 if (eventSource.failure) { 5323 eventSource.failure(error); 5324 } 5325 if (callFailure) { 5326 callFailure(error); 5327 } 5328 calendar.dispatch({ 5329 type: 'RECEIVE_EVENT_ERROR', 5330 sourceId: eventSource.sourceId, 5331 fetchId: fetchId, 5332 fetchRange: fetchRange, 5333 error: error 5334 }); 5335 }); 5336 return __assign({}, eventSource, { isFetching: true, latestFetchId: fetchId }); 5337 } 5338 function receiveResponse(sourceHash, sourceId, fetchId, fetchRange) { 5339 var _a; 5340 var eventSource = sourceHash[sourceId]; 5341 if (eventSource && // not already removed 5342 fetchId === eventSource.latestFetchId) { 5343 return __assign({}, sourceHash, (_a = {}, _a[sourceId] = __assign({}, eventSource, { isFetching: false, fetchRange: fetchRange }), _a)); 5344 } 5345 return sourceHash; 5346 } 5347 function excludeStaticSources(eventSources, calendar) { 5348 return filterHash(eventSources, function (eventSource) { 5349 return doesSourceNeedRange(eventSource, calendar); 5350 }); 5351 } 5352 5353 var DateProfileGenerator = /** @class */ (function () { 5354 function DateProfileGenerator(viewSpec, calendar) { 5355 this.viewSpec = viewSpec; 5356 this.options = viewSpec.options; 5357 this.dateEnv = calendar.dateEnv; 5358 this.calendar = calendar; 5359 this.initHiddenDays(); 5360 } 5361 /* Date Range Computation 5362 ------------------------------------------------------------------------------------------------------------------*/ 5363 // Builds a structure with info about what the dates/ranges will be for the "prev" view. 5364 DateProfileGenerator.prototype.buildPrev = function (currentDateProfile, currentDate) { 5365 var dateEnv = this.dateEnv; 5366 var prevDate = dateEnv.subtract(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month 5367 currentDateProfile.dateIncrement); 5368 return this.build(prevDate, -1); 5369 }; 5370 // Builds a structure with info about what the dates/ranges will be for the "next" view. 5371 DateProfileGenerator.prototype.buildNext = function (currentDateProfile, currentDate) { 5372 var dateEnv = this.dateEnv; 5373 var nextDate = dateEnv.add(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month 5374 currentDateProfile.dateIncrement); 5375 return this.build(nextDate, 1); 5376 }; 5377 // Builds a structure holding dates/ranges for rendering around the given date. 5378 // Optional direction param indicates whether the date is being incremented/decremented 5379 // from its previous value. decremented = -1, incremented = 1 (default). 5380 DateProfileGenerator.prototype.build = function (currentDate, direction, forceToValid) { 5381 if (forceToValid === void 0) { forceToValid = false; }
5382 var validRange; 5383 var minTime = null; 5384 var maxTime = null; 5385 var currentInfo; 5386 var isRangeAllDay; 5387 var renderRange; 5388 var activeRange; 5389 var isValid; 5390 validRange = this.buildValidRange(); 5391 validRange = this.trimHiddenDays(validRange); 5392 if (forceToValid) { 5393 currentDate = constrainMarkerToRange(currentDate, validRange); 5394 } 5395 currentInfo = this.buildCurrentRangeInfo(currentDate, direction); 5396 isRangeAllDay = /^(year|month|week|day)$/.test(currentInfo.unit); 5397 renderRange = this.buildRenderRange(this.trimHiddenDays(currentInfo.range), currentInfo.unit, isRangeAllDay); 5398 renderRange = this.trimHiddenDays(renderRange); 5399 activeRange = renderRange; 5400 if (!this.options.showNonCurrentDates) { 5401 activeRange = intersectRanges(activeRange, currentInfo.range); 5402 } 5403 minTime = createDuration(this.options.minTime); 5404 maxTime = createDuration(this.options.maxTime); 5405 activeRange = this.adjustActiveRange(activeRange, minTime, maxTime); 5406 activeRange = intersectRanges(activeRange, validRange); // might return null 5407 // it's invalid if the originally requested date is not contained, 5408 // or if the range is completely outside of the valid range. 5409 isValid = rangesIntersect(currentInfo.range, validRange); 5410 return { 5411 // constraint for where prev/next operations can go and where events can be dragged/resized to. 5412 // an object with optional start and end properties. 5413 validRange: validRange, 5414 // range the view is formally responsible for. 5415 // for example, a month view might have 1st-31st, excluding padded dates 5416 currentRange: currentInfo.range, 5417 // name of largest unit being displayed, like "month" or "week" 5418 currentRangeUnit: currentInfo.unit, 5419 isRangeAllDay: isRangeAllDay, 5420 // dates that display events and accept drag-n-drop 5421 // will be `null` if no dates accept events 5422 activeRange: activeRange, 5423 // date range with a rendered skeleton 5424 // includes not-active days that need some sort of DOM 5425 renderRange: renderRange, 5426 // Duration object that denotes the first visible time of any given day 5427 minTime: minTime, 5428 // Duration object that denotes the exclusive visible end time of any given day 5429 maxTime: maxTime, 5430 isValid: isValid, 5431 // how far the current date will move for a prev/next operation 5432 dateIncrement: this.buildDateIncrement(currentInfo.duration) 5433 // pass a fallback (might be null) ^ 5434 }; 5435 }; 5436 // Builds an object with optional start/end properties. 5437 // Indicates the minimum/maximum dates to display. 5438 // not responsible for trimming hidden days. 5439 DateProfileGenerator.prototype.buildValidRange = function () { 5440 return this.getRangeOption('validRange', this.calendar.getNow()) || 5441 { start: null, end: null }; // completely open-ended 5442 }; 5443 // Builds a structure with info about the "current" range, the range that is 5444 // highlighted as being the current month for example. 5445 // See build() for a description of `direction`. 5446 // Guaranteed to have `range` and `unit` properties. `duration` is optional. 5447 DateProfileGenerator.prototype.buildCurrentRangeInfo = function (date, direction) { 5448 var _a = this, viewSpec = _a.viewSpec, dateEnv = _a.dateEnv; 5449 var duration = null; 5450 var unit = null; 5451 var range = null; 5452 var dayCount; 5453 if (viewSpec.duration) { 5454 duration = viewSpec.duration; 5455 unit = viewSpec.durationUnit; 5456 range = this.buildRangeFromDuration(date, direction, duration, unit); 5457 } 5458 else if ((dayCount = this.options.dayCount)) { 5459 unit = 'day'; 5460 range = this.buildRangeFromDayCount(date, direction, dayCount); 5461 } 5462 else if ((range = this.buildCustomVisibleRange(date))) { 5463 unit = dateEnv.greatestWholeUnit(range.start, range.end).unit; 5464 } 5465 else { 5466 duration = this.getFallbackDuration(); 5467 unit = greatestDurationDenominator(duration).unit; 5468 range = this.buildRangeFromDuration(date, direction, duration, unit); 5469 } 5470 return { duration: duration, unit: unit, range: range }; 5471 }; 5472 DateProfileGenerator.prototype.getFallbackDuration = function () { 5473 return createDuration({ day: 1 }); 5474 }; 5475 // Returns a new activeRange to have time values (un-ambiguate) 5476 // minTime or maxTime causes the range to expand. 5477 DateProfileGenerator.prototype.adjustActiveRange = function (range, minTime, maxTime) { 5478 var dateEnv = this.dateEnv; 5479 var start = range.start; 5480 var end = range.end; 5481 if (this.viewSpec.class.prototype.usesMinMaxTime) { 5482 // expand active range if minTime is negative (why not when positive?) 5483 if (asRoughDays(minTime) < 0) { 5484 start = startOfDay(start); // necessary? 5485 start = dateEnv.add(start, minTime); 5486 } 5487 // expand active range if maxTime is beyond one day (why not when positive?) 5488 if (asRoughDays(maxTime) > 1) { 5489 end = startOfDay(end); // necessary? 5490 end = addDays(end, -1); 5491 end = dateEnv.add(end, maxTime); 5492 } 5493 } 5494 return { start: start, end: end }; 5495 }; 5496 // Builds the "current" range when it is specified as an explicit duration. 5497 // `unit` is the already-computed greatestDurationDenominator unit of duration. 5498 DateProfileGenerator.prototype.buildRangeFromDuration = function (date, direction, duration, unit) { 5499 var dateEnv = this.dateEnv; 5500 var alignment = this.options.dateAlignment; 5501 var dateIncrementInput; 5502 var dateIncrementDuration; 5503 var start; 5504 var end; 5505 var res; 5506 // compute what the alignment should be 5507 if (!alignment) { 5508 dateIncrementInput = this.options.dateIncrement; 5509 if (dateIncrementInput) { 5510 dateIncrementDuration = createDuration(dateIncrementInput); 5511 // use the smaller of the two units 5512 if (asRoughMs(dateIncrementDuration) < asRoughMs(duration)) { 5513 alignment = greatestDurationDenominator(dateIncrementDuration, !getWeeksFromInput(dateIncrementInput)).unit; 5514 } 5515 else { 5516 alignment = unit; 5517 } 5518 } 5519 else { 5520 alignment = unit; 5521 } 5522 }
5523 // if the view displays a single day or smaller 5524 if (asRoughDays(duration) <= 1) { 5525 if (this.isHiddenDay(start)) { 5526 start = this.skipHiddenDays(start, direction); 5527 start = startOfDay(start); 5528 } 5529 } 5530 function computeRes() { 5531 start = dateEnv.startOf(date, alignment); 5532 end = dateEnv.add(start, duration); 5533 res = { start: start, end: end }; 5534 } 5535 computeRes(); 5536 // if range is completely enveloped by hidden days, go past the hidden days 5537 if (!this.trimHiddenDays(res)) { 5538 date = this.skipHiddenDays(date, direction); 5539 computeRes(); 5540 } 5541 return res; 5542 }; 5543 // Builds the "current" range when a dayCount is specified. 5544 DateProfileGenerator.prototype.buildRangeFromDayCount = function (date, direction, dayCount) { 5545 var dateEnv = this.dateEnv; 5546 var customAlignment = this.options.dateAlignment; 5547 var runningCount = 0; 5548 var start = date; 5549 var end; 5550 if (customAlignment) { 5551 start = dateEnv.startOf(start, customAlignment); 5552 } 5553 start = startOfDay(start); 5554 start = this.skipHiddenDays(start, direction); 5555 end = start; 5556 do { 5557 end = addDays(end, 1); 5558 if (!this.isHiddenDay(end)) { 5559 runningCount++; 5560 } 5561 } while (runningCount < dayCount); 5562 return { start: start, end: end }; 5563 }; 5564 // Builds a normalized range object for the "visible" range, 5565 // which is a way to define the currentRange and activeRange at the same time. 5566 DateProfileGenerator.prototype.buildCustomVisibleRange = function (date) { 5567 var dateEnv = this.dateEnv; 5568 var visibleRange = this.getRangeOption('visibleRange', dateEnv.toDate(date)); 5569 if (visibleRange && (visibleRange.start == null || visibleRange.end == null)) { 5570 return null; 5571 } 5572 return visibleRange; 5573 }; 5574 // Computes the range that will represent the element/cells for *rendering*, 5575 // but which may have voided days/times. 5576 // not responsible for trimming hidden days. 5577 DateProfileGenerator.prototype.buildRenderRange = function (currentRange, currentRangeUnit, isRangeAllDay) { 5578 return currentRange; 5579 }; 5580 // Compute the duration value that should be added/substracted to the current date 5581 // when a prev/next operation happens. 5582 DateProfileGenerator.prototype.buildDateIncrement = function (fallback) { 5583 var dateIncrementInput = this.options.dateIncrement; 5584 var customAlignment; 5585 if (dateIncrementInput) { 5586 return createDuration(dateIncrementInput); 5587 } 5588 else if ((customAlignment = this.options.dateAlignment)) { 5589 return createDuration(1, customAlignment); 5590 } 5591 else if (fallback) { 5592 return fallback; 5593 } 5594 else { 5595 return createDuration({ days: 1 }); 5596 } 5597 }; 5598 // Arguments after name will be forwarded to a hypothetical function value 5599 // WARNING: passed-in arguments will be given to generator functions as-is and can cause side-effects. 5600 // Always clone your objects if you fear mutation. 5601 DateProfileGenerator.prototype.getRangeOption = function (name) { 5602 var otherArgs = []; 5603 for (var _i = 1; _i < arguments.length; _i++) { 5604 otherArgs[_i - 1] = arguments[_i]; 5605 } 5606 var val = this.options[name]; 5607 if (typeof val === 'function') { 5608 val = val.apply(null, otherArgs); 5609 } 5610 if (val) { 5611 val = parseRange(val, this.dateEnv); 5612 } 5613 if (val) { 5614 val = computeVisibleDayRange(val); 5615 } 5616 return val; 5617 }; 5618 /* Hidden Days 5619 ------------------------------------------------------------------------------------------------------------------*/ 5620 // Initializes internal variables related to calculating hidden days-of-week 5621 DateProfileGenerator.prototype.initHiddenDays = function () { 5622 var hiddenDays = this.options.hiddenDays || []; // array of day-of-week indices that are hidden
5623 var isHiddenDayHash = []; // is the day-of-week hidden? (hash with day-of-week-index -> bool) 5624 var dayCnt = 0; 5625 var i; 5626 if (this.options.weekends === false) { 5627 hiddenDays.push(0, 6); // 0=sunday, 6=saturday 5628 } 5629 for (i = 0; i < 7; i++) { 5630 if (!(isHiddenDayHash[i] = hiddenDays.indexOf(i) !== -1)) { 5631 dayCnt++; 5632 } 5633 } 5634 if (!dayCnt) { 5635 throw new Error('invalid hiddenDays'); // all days were hidden? bad. 5636 } 5637 this.isHiddenDayHash = isHiddenDayHash; 5638 }; 5639 // Remove days from the beginning and end of the range that are computed as hidden. 5640 // If the whole range is trimmed off, returns null 5641 DateProfileGenerator.prototype.trimHiddenDays = function (range) { 5642 var start = range.start; 5643 var end = range.end; 5644 if (start) { 5645 start = this.skipHiddenDays(start); 5646 } 5647 if (end) { 5648 end = this.skipHiddenDays(end, -1, true); 5649 } 5650 if (start == null || end == null || start < end) { 5651 return { start: start, end: end }; 5652 } 5653 return null; 5654 }; 5655 // Is the current day hidden? 5656 // `day` is a day-of-week index (0-6), or a Date (used for UTC) 5657 DateProfileGenerator.prototype.isHiddenDay = function (day) { 5658 if (day instanceof Date) { 5659 day = day.getUTCDay(); 5660 } 5661 return this.isHiddenDayHash[day]; 5662 }; 5663 // Incrementing the current day until it is no longer a hidden day, returning a copy. 5664 // DOES NOT CONSIDER validRange! 5665 // If the initial value of `date` is not a hidden day, don't do anything. 5666 // Pass `isExclusive` as `true` if you are dealing with an end date. 5667 // `inc` defaults to `1` (increment one day forward each time) 5668 DateProfileGenerator.prototype.skipHiddenDays = function (date, inc, isExclusive) { 5669 if (inc === void 0) { inc = 1; } 5670 if (isExclusive === void 0) { isExclusive = false; } 5671 while (this.isHiddenDayHash[(date.getUTCDay() + (isExclusive ? inc : 0) + 7) % 7]) { 5672 date = addDays(date, inc); 5673 } 5674 return date; 5675 }; 5676 return DateProfileGenerator; 5677 }());
5678 // TODO: find a way to avoid comparing DateProfiles. it's tedious 5679 function isDateProfilesEqual(p0, p1) { 5680 return rangesEqual(p0.validRange, p1.validRange) && 5681 rangesEqual(p0.activeRange, p1.activeRange) && 5682 rangesEqual(p0.renderRange, p1.renderRange) && 5683 durationsEqual(p0.minTime, p1.minTime) && 5684 durationsEqual(p0.maxTime, p1.maxTime); 5685 /* 5686 TODO: compare more? 5687 currentRange: DateRange 5688 currentRangeUnit: string 5689 isRangeAllDay: boolean 5690 isValid: boolean 5691 dateIncrement: Duration 5692 */ 5693 } 5694 5695 function reduce (state, action, calendar) { 5696 var viewType = reduceViewType(state.viewType, action); 5697 var dateProfile = reduceDateProfile(state.dateProfile, action, state.currentDate, viewType, calendar); 5698 var eventSources = reduceEventSources(state.eventSources, action, dateProfile, calendar); 5699 var nextState = __assign({}, state, { viewType: viewType, 5700 dateProfile: dateProfile, currentDate: reduceCurrentDate(state.currentDate, action, dateProfile), eventSources: eventSources, eventStore: reduceEventStore(state.eventStore, action, eventSources, dateProfile, calendar), dateSelection: reduceDateSelection(state.dateSelection, action, calendar), eventSelection: reduceSelectedEvent(state.eventSelection, action), eventDrag: reduceEventDrag(state.eventDrag, action, eventSources, calendar), eventResize: reduceEventResize(state.eventResize, action, eventSources, calendar), eventSourceLoadingLevel: computeLoadingLevel(eventSources), loadingLevel: computeLoadingLevel(eventSources) }); 5701 for (var _i = 0, _a = calendar.pluginSystem.hooks.reducers; _i < _a.length; _i++) { 5702 var reducerFunc = _a[_i]; 5703 nextState = reducerFunc(nextState, action, calendar); 5704 } 5705 // console.log(action.type, nextState) 5706 return nextState; 5707 } 5708 function reduceViewType(currentViewType, action) { 5709 switch (action.type) { 5710 case 'SET_VIEW_TYPE': 5711 return action.viewType; 5712 default: 5713 return currentViewType; 5714 } 5715 } 5716 function reduceDateProfile(currentDateProfile, action, currentDate, viewType, calendar) { 5717 var newDateProfile; 5718 switch (action.type) { 5719 case 'PREV': 5720 newDateProfile = calendar.dateProfileGenerators[viewType].buildPrev(currentDateProfile, currentDate); 5721 break; 5722 case 'NEXT': 5723 newDateProfile = calendar.dateProfileGenerators[viewType].buildNext(currentDateProfile, currentDate); 5724 break; 5725 case 'SET_DATE': 5726 if (!currentDateProfile.activeRange || 5727 !rangeContainsMarker(currentDateProfile.currentRange, action.dateMarker)) { 5728 newDateProfile = calendar.dateProfileGenerators[viewType].build(action.dateMarker, undefined, true // forceToValid 5729 ); 5730 } 5731 break; 5732 case 'SET_VIEW_TYPE': 5733 var generator = calendar.dateProfileGenerators[viewType]; 5734 if (!generator) { 5735 throw new Error(viewType ? 5736 'The FullCalendar view "' + viewType + '" does not exist. Make sure your plugins are loaded correctly.' : 5737 'No available FullCalendar view plugins.'); 5738 } 5739 newDateProfile = generator.build(action.dateMarker || currentDate, undefined, true // forceToValid 5740 ); 5741 break; 5742 } 5743 if (newDateProfile && 5744 newDateProfile.isValid && 5745 !(currentDateProfile && isDateProfilesEqual(currentDateProfile, newDateProfile))) { 5746 return newDateProfile; 5747 } 5748 else { 5749 return currentDateProfile; 5750 } 5751 } 5752 function reduceCurrentDate(currentDate, action, dateProfile) { 5753 switch (action.type) { 5754 case 'PREV': 5755 case 'NEXT': 5756 if (!rangeContainsMarker(dateProfile.currentRange, currentDate)) { 5757 return dateProfile.currentRange.start; 5758 } 5759 else { 5760 return currentDate; 5761 } 5762 case 'SET_DATE': 5763 case 'SET_VIEW_TYPE': 5764 var newDate = action.dateMarker || currentDate; 5765 if (dateProfile.activeRange && !rangeContainsMarker(dateProfile.activeRange, newD
5765ate)) { 5766 return dateProfile.currentRange.start; 5767 } 5768 else { 5769 return newDate; 5770 } 5771 default: 5772 return currentDate; 5773 } 5774 } 5775 function reduceDateSelection(currentSelection, action, calendar) { 5776 switch (action.type) { 5777 case 'SELECT_DATES': 5778 return action.selection; 5779 case 'UNSELECT_DATES': 5780 return null; 5781 default: 5782 return currentSelection; 5783 } 5784 } 5785 function reduceSelectedEvent(currentInstanceId, action) { 5786 switch (action.type) { 5787 case 'SELECT_EVENT': 5788 return action.eventInstanceId; 5789 case 'UNSELECT_EVENT': 5790 return ''; 5791 default: 5792 return currentInstanceId; 5793 } 5794 } 5795 function reduceEventDrag(currentDrag, action, sources, calendar) { 5796 switch (action.type) { 5797 case 'SET_EVENT_DRAG': 5798 var newDrag = action.state; 5799 return { 5800 affectedEvents: newDrag.affectedEvents, 5801 mutatedEvents: newDrag.mutatedEvents, 5802 isEvent: newDrag.isEvent, 5803 origSeg: newDrag.origSeg 5804 }; 5805 case 'UNSET_EVENT_DRAG': 5806 return null; 5807 default: 5808 return currentDrag; 5809 } 5810 } 5811 function reduceEventResize(currentResize, action, sources, calendar) { 5812 switch (action.type) { 5813 case 'SET_EVENT_RESIZE': 5814 var newResize = action.state; 5815 return { 5816 affectedEvents: newResize.affectedEvents, 5817 mutatedEvents: newResize.mutatedEvents, 5818 isEvent: newResize.isEvent, 5819 origSeg: newResize.origSeg 5820 }; 5821 case 'UNSET_EVENT_RESIZE': 5822 return null; 5823 default: 5824 return currentResize; 5825 } 5826 } 5827 function computeLoadingLevel(eventSources) { 5828 var cnt = 0; 5829 for (var sourceId in eventSources) { 5830 if (eventSources[sourceId].isFetching) { 5831 cnt++; 5832 } 5833 } 5834 return cnt; 5835 } 5836 5837 var STANDARD_PROPS = { 5838 start: null, 5839 end: null, 5840 allDay: Boolean 5841 }; 5842 function parseDateSpan(raw, dateEnv, defaultDuration) { 5843 var span = parseOpenDateSpan(raw, dateEnv); 5844 var range = span.range; 5845 if (!range.start) { 5846 return null; 5847 } 5848 if (!range.end) { 5849 if (defaultDuration == null) { 5850 return null; 5851 } 5852 else { 5853 range.end = dateEnv.add(range.start, defaultDuration); 5854 } 5855 } 5856 return span; 5857 } 5858 /* 5859 TODO: somehow combine with parseRange? 5860 Will return null if the start/end props were present but parsed invalidly. 5861 */ 5862 function parseOpenDateSpan(raw, dateEnv) { 5863 var leftovers = {}; 5864 var standardProps = refineProps(raw, STANDARD_PROPS, {}, leftovers); 5865 var startMeta = standardProps.start ? dateEnv.createMarkerMeta(standardProps.start) : null; 5866 var endMeta = standardProps.end ? dateEnv.createMarkerMeta(standardProps.end) : null; 5867 var allDay = standardProps.allDay; 5868 if (allDay == null) { 5869 allDay = (startMeta && startMeta.isTimeUnspecified) && 5870 (!endMeta || endMeta.isTimeUnspecified); 5871 } 5872 // use this leftover object as the selection object 5873 leftovers.range = { 5874 start: startMeta ? startMeta.marker : null, 5875 end: endMeta ? endMeta.marker : null 5876 }; 5877 leftovers.allDay = allDay; 5878 return leftovers; 5879 } 5880 function isDateSpansEqual(span0, span1) { 5881 return rangesEqual(span0.range, span1.range) && 5882 span0.allDay === span1.allDay && 5883 isSpanPropsEqual(span0, span1); 5884 } 5885 // the NON-DATE-RELATED props 5886 function isSpanPropsEqual(span0, span1) { 5887 for (var propName in span1) { 5888 if (propName !== 'range' && propName !== 'allDay') { 5889 if (span0[propName] !== span1[propName]) { 5890 return false;
5891 } 5892 } 5893 } 5894 // are there any props that span0 has that span1 DOESN'T have? 5895 // both have range/allDay, so no need to special-case. 5896 for (var propName in span0) { 5897 if (!(propName in span1)) { 5898 return false; 5899 } 5900 } 5901 return true; 5902 } 5903 function buildDateSpanApi(span, dateEnv) { 5904 return { 5905 start: dateEnv.toDate(span.range.start), 5906 end: dateEnv.toDate(span.range.end), 5907 startStr: dateEnv.formatIso(span.range.start, { omitTime: span.allDay }), 5908 endStr: dateEnv.formatIso(span.range.end, { omitTime: span.allDay }), 5909 allDay: span.allDay 5910 }; 5911 } 5912 function buildDatePointApi(span, dateEnv) { 5913 return { 5914 date: dateEnv.toDate(span.range.start), 5915 dateStr: dateEnv.formatIso(span.range.start, { omitTime: span.allDay }), 5916 allDay: span.allDay 5917 }; 5918 } 5919 function fabricateEventRange(dateSpan, eventUiBases, calendar) { 5920 var def = parseEventDef({ editable: false }, '', // sourceId 5921 dateSpan.allDay, true, // hasEnd 5922 calendar); 5923 return { 5924 def: def, 5925 ui: compileEventUi(def, eventUiBases), 5926 instance: createEventInstance(def.defId, dateSpan.range), 5927 range: dateSpan.range, 5928 isStart: true, 5929 isEnd: true 5930 }; 5931 } 5932 5933 function compileViewDefs(defaultConfigs, overrideConfigs) { 5934 var hash = {}; 5935 var viewType; 5936 for (viewType in defaultConfigs) { 5937 ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs); 5938 } 5939 for (viewType in overrideConfigs) { 5940 ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs); 5941 } 5942 return hash; 5943 } 5944 function ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs) { 5945 if (hash[viewType]) { 5946 return hash[viewType]; 5947 } 5948 var viewDef = buildViewDef(viewType, hash, defaultConfigs, overrideConfigs); 5949 if (viewDef) { 5950 hash[viewType] = viewDef; 5951 } 5952 return viewDef; 5953 } 5954 function buildViewDef(viewType, hash, defaultConfigs, overrideConfigs) { 5955 var defaultConfig = defaultConfigs[viewType]; 5956 var overrideConfig = overrideConfigs[viewType]; 5957 var queryProp = function (name) { 5958 return (defaultConfig && defaultConfig[name] !== null) ? defaultConfig[name] : 5959 ((overrideConfig && overrideConfig[name] !== null) ? overrideConfig[name] : null); 5960 }; 5961 var theClass = queryProp('class'); 5962 var superType = queryProp('superType'); 5963 if (!superType && theClass) { 5964 superType = 5965 findViewNameBySubclass(theClass, overrideConfigs) || 5966 findViewNameBySubclass(theClass, defaultConfigs); 5967 } 5968 var superDef = null; 5969 if (superType) { 5970 if (superType === viewType) { 5971 throw new Error('Can\'t have a custom view type that references itself'); 5972 } 5973 superDef = ensureViewDef(superType, hash, defaultConfigs, overrideConfigs); 5974 } 5975 if (!theClass && superDef) { 5976 theClass = superDef.class; 5977 } 5978 if (!theClass) { 5979 return null; // don't throw a warning, might be settings for a single-unit view 5980 } 5981 return { 5982 type: viewType, 5983 class: theClass, 5984 defaults: __assign({}, (superDef ? superDef.defaults : {}), (defaultConfig ? defaultConfig.options : {})), 5985 overrides: __assign({}, (superDef ? superDef.overrides : {}), (overrideConfig ? overrideConfig.options : {})) 5986 }; 5987 } 5988 function findViewNameBySubclass(viewSubclass, configs) { 5989 var superProto = Object.getPrototypeOf(viewSubclass.prototype); 5990 for (var viewType in configs) { 5991 var parsed = configs[viewType]; 5992 // need DIRECT subclass, so instanceof won't do it 5993 if (parsed.class && parsed.class.prototype === superProto) { 5994 return viewType; 5995 } 5996 } 5997 return ''; 5998 } 5999 6000 function parseViewConfigs(inputs) { 6001 return mapHash(inputs, parseViewConfig); 6002 } 6003 var VIEW_DEF_PROPS = { 6004 type: String, 6005 class: null 6006 }; 6007 function parseViewConfig(input) { 6008 if (typeof input === 'function') { 6009 input = { class: input }; 6010 } 6011 var options = {}; 6012 var props = refineProps(input, VIEW_DEF_PROPS, {}, options); 6013 return { 6014 superType: props.type, 6015 class: props.class, 6016 options: options 6017 }; 6018 } 6019 6020 function buildViewSpecs(defaultInputs, optionsManager) { 6021 var defaultConfigs = parseViewConfigs(defaultInputs); 6022 var overrideConfigs = parseViewConfigs(optionsManager.overrides.views); 6023 var viewDefs = compileViewDefs(defaultConfigs, overrideConfigs); 6024 return mapHash(viewDefs, function (viewDef) { 6025 return buildViewSpec(viewDef, overrideConfigs, optionsManager); 6026 }); 6027 } 6028 function buildViewSpec(viewDef, overrideConfigs, optionsManager) { 6029 var durationInput = viewDef.overrides.duration || 6030 viewDef.defaults.duration || 6031 optionsManager.dynamicOverrides.duration || 6032 optionsManager.overrides.duration; 6033 var duration = null; 6034 var durationUnit = ''; 6035 var singleUnit = ''; 6036 var singleUnitOverrides = {}; 6037 if (durationInput) { 6038 duration = createDuration(durationInput); 6039 if (duration) { // valid? 6040 var denom = greatestDurationDenominator(duration, !getWeeksFromInput(durationInput)); 6041 durationUnit = denom.unit; 6042 if (denom.value === 1) { 6043 singleUnit = durationUnit; 6044 singleUnitOverrides = overrideConfigs[durationUnit] ? overrideConfigs[durationUnit].options : {}; 6045 } 6046 } 6047 } 6048 var queryButtonText = function (options) { 6049 var buttonTextMap = options.buttonText || {}; 6050 var buttonTextKey = viewDef.defaults.buttonTextKey; 6051 if (buttonTextKey != null && buttonTextMap[buttonTextKey] != null) { 6052 return buttonTextMap[buttonTextKey]; 6053 } 6054 if (buttonTextMap[viewDef.type] != null) { 6055 return buttonTextMap[viewDef.type]; 6056 } 6057 if (buttonTextMap[singleUnit] != null) { 6058 return buttonTextMap[singleUnit]; 6059 } 6060 }; 6061 return { 6062 type: viewDef.type, 6063 class: viewDef.class, 6064 duration: duration, 6065 durationUnit: durationUnit, 6066 singleUnit: singleUnit, 6067 options: __assign({}, globalDefaults, viewDef.defaults, optionsManager.dirDefaults, optionsManager.localeDefaults, optionsManager.overrides, singleUnitOverrides, viewDef.overrides, optionsManager.dynamicOverrides), 6068 buttonTextOverride: queryButtonText(optionsManager.dynamicOverrides) || 6069 queryButtonText(optionsManager.overrides) || // constructor-specified buttonText lookup hash takes precedence 6070 viewDef.overrides.buttonText, 6071 buttonTextDefault: queryButtonText(optionsManager.localeDefaults) || 6072 queryButtonText(optionsManager.dirDefaults) || 6073 viewDef.defaults.buttonText || 6074 queryButtonText(globalDefaults) || 6075 viewDef.type // fall back to given view name 6076 }; 6077 } 6078 6079 var Toolbar = /** @class */ (function (_super) { 6080 __extends(Toolbar, _super); 6081 function Toolbar(context, extraClassName) { 6082 var _this = _super.call(this, context) || this; 6083 _this._renderLayout = memoizeRendering(_this.renderLayout, _this.unrenderLayout); 6084 _this._updateTitle = memoizeRendering(_this.updateTitle, null, [_this._renderLayout]); 6085 _this._updateActiveButton = memoizeRendering(_this.updateActiveButton, null, [_this._renderLayout]); 6086 _this._updateToday = memoizeRendering(_this.updateToday, null, [_this._renderLayout]); 6087 _this._updatePrev = memoizeRendering(_this.updatePrev, null, [_this._renderLayout]); 6088 _this._updateNext = memoizeRendering(_this.updateNext, null, [_this._renderLayout]); 6089 _this.el = createElement('div', { className: 'fc-toolbar ' + extraClassName }); 6090 return _this; 6091 } 6092 Toolbar.prototype.destroy = function () { 6093 _super.prototype.destroy.call(this); 6094 this._renderLayout.unrender(); // should unrender everything else 6095 removeElement(this.el); 6096 }; 6097 Toolbar.prototype.render = function (props) { 6098 this._renderLayout(props.layout); 6099 this._updateTitle(props.title); 6100 this._updateActiveButton(props.activeButton); 6101 this._updateToday(props.isTodayEnabled); 6102 this._updatePrev(props.isPrevEnabled); 6103 this._updateNext(props.isNextEnabled); 6104 }; 6105 Toolbar.prototype.renderLayout = function (layout) { 6106 var el = this.el; 6107 this.viewsWithButtons = []; 6108 appendToElement(el, this.renderSection('left', layout.left)); 6109 appendToElement(el, this.renderSection('center', layout.center)); 6110 appendToElement(el, this.renderSection('right', layout.right)); 6111 }; 6112 Toolbar.prototype.unrenderLayout = function () { 6113 this.el.innerHTML = ''; 6114 }; 6115 Toolbar.prototype.renderSection = function (position, buttonStr) { 6116 var _this = this; 6117 var _a = this, theme = _a.theme, calendar = _a.calendar; 6118 var optionsManager = calendar.optionsManager; 6119 var viewSpecs = calendar.viewSpecs; 6120 var sectionEl = createElement('div', { className: 'fc-' + position }); 6121 var calendarCustomButtons = optionsManager.computed.customButtons || {}; 6122 var calendarButtonTextOverrides = optionsManager.overrides.buttonText || {}; 6123 var calendarButtonText = optionsManager.computed.buttonText || {}; 6124 if (buttonStr) { 6125 buttonStr.split(' ').forEach(function (buttonGroupStr, i) { 6126 var groupChildren = []; 6127 var isOnlyButtons = true; 6128 var groupEl; 6129 buttonGroupStr.split(',').forEach(function (buttonName, j) { 6130 var customButtonProps; 6131 var viewSpec; 6132 var buttonClick; 6133 var buttonIcon; // only one of these will be set 6134 var buttonText; // " 6135 var buttonInnerHtml;
6136 var buttonClasses; 6137 var buttonEl; 6138 var buttonAriaAttr; 6139 if (buttonName === 'title') { 6140 groupChildren.push(htmlToElement('<h2> </h2>')); // we always want it to take up height 6141 isOnlyButtons = false; 6142 } 6143 else { 6144 if ((customButtonProps = calendarCustomButtons[buttonName])) { 6145 buttonClick = function (ev) { 6146 if (customButtonProps.click) { 6147 customButtonProps.click.call(buttonEl, ev); 6148 } 6149 }; 6150 (buttonIcon = theme.getCustomButtonIconClass(customButtonProps)) || 6151 (buttonIcon = theme.getIconClass(buttonName)) || 6152 (buttonText = customButtonProps.text); 6153 } 6154 else if ((viewSpec = viewSpecs[buttonName])) { 6155 _this.viewsWithButtons.push(buttonName); 6156 buttonClick = function () { 6157 calendar.changeView(buttonName); 6158 }; 6159 (buttonText = viewSpec.buttonTextOverride) || 6160 (buttonIcon = theme.getIconClass(buttonName)) || 6161 (buttonText = viewSpec.buttonTextDefault); 6162 } 6163 else if (calendar[buttonName]) { // a calendar method 6164 buttonClick = function () { 6165 calendar[buttonName](); 6166 }; 6167 (buttonText = calendarButtonTextOverrides[buttonName]) || 6168 (buttonIcon = theme.getIconClass(buttonName)) || 6169 (buttonText = calendarButtonText[buttonName]); 6170 // ^ everything else is considered default 6171 } 6172 if (buttonClick) { 6173 buttonClasses = [ 6174 'fc-' + buttonName + '-button', 6175 theme.getClass('button') 6176 ]; 6177 if (buttonText) { 6178 buttonInnerHtml = htmlEscape(buttonText); 6179 buttonAriaAttr = ''; 6180 } 6181 else if (buttonIcon) { 6182 buttonInnerHtml = "<span class='" + buttonIcon + "'></span>"; 6183 buttonAriaAttr = ' aria-label="' + buttonName + '"'; 6184 } 6185 buttonEl = htmlToElement(// type="button" so that it doesn't submit a form 6186 '<button type="button" class="' + buttonClasses.join(' ') + '"' + 6187 buttonAriaAttr + 6188 '>' + buttonInnerHtml + '</button>'); 6189 buttonEl.addEventListener('click', buttonClick); 6190 groupChildren.push(buttonEl); 6191 } 6192 } 6193 }); 6194 if (groupChildren.length > 1) { 6195 groupEl = document.createElement('div'); 6196 var buttonGroupClassName = theme.getClass('buttonGroup'); 6197 if (isOnlyButtons && buttonGroupClassName) { 6198 groupEl.classList.add(buttonGroupClassName); 6199 } 6200 appendToElement(groupEl, groupChildren); 6201 sectionEl.appendChild(groupEl); 6202 } 6203 else { 6204 appendToElement(sectionEl, groupChildren); // 1 or 0 children 6205 } 6206 }); 6207 } 6208 return sectionEl; 6209 }; 6210 Toolbar.prototype.updateToday = function (isTodayEnabled) { 6211 this.toggleButtonEnabled('today', isTodayEnabled); 6212 }; 6213 Toolbar.prototype.updatePrev = function (isPrevEnabled) { 6214 this.toggleButtonEnabled('prev', isPrevEnabled); 6215 }; 6216 Toolbar.prototype.updateNext = function (isNextEnabled) { 6217 this.toggleButtonEnabled('next', isNextEnabled); 6218 }; 6219 Toolbar.prototype.updateTitle = function (text) { 6220 findElements(this.el, 'h2').forEach(function (titleEl) { 6221 titleEl.innerText = text; 6222 }); 6223 }; 6224 Toolbar.prototype.updateActiveButton = function (buttonName) { 6225 var className = this.theme.getClass('buttonActive'); 6226 findElements(this.el, 'button').forEach(function (buttonEl) { 6227 if (buttonName && buttonEl.classList.contains('fc-'
6227+ buttonName + '-button')) { 6228 buttonEl.classList.add(className); 6229 } 6230 else { 6231 buttonEl.classList.remove(className); 6232 } 6233 }); 6234 }; 6235 Toolbar.prototype.toggleButtonEnabled = function (buttonName, bool) { 6236 findElements(this.el, '.fc-' + buttonName + '-button').forEach(function (buttonEl) { 6237 buttonEl.disabled = !bool; 6238 }); 6239 }; 6240 return Toolbar; 6241 }(Component)); 6242 6243 var CalendarComponent = /** @class */ (function (_super) { 6244 __extends(CalendarComponent, _super); 6245 function CalendarComponent(context, el) { 6246 var _this = _super.call(this, context) || this; 6247 _this._renderToolbars = memoizeRendering(_this.renderToolbars); 6248 _this.buildViewPropTransformers = memoize(buildViewPropTransformers); 6249 _this.el = el; 6250 prependToElement(el, _this.contentEl = createElement('div', { className: 'fc-view-container' })); 6251 var calendar = _this.calendar; 6252 for (var _i = 0, _a = calendar.pluginSystem.hooks.viewContainerModifiers; _i < _a.length; _i++) { 6253 var modifyViewContainer = _a[_i]; 6254 modifyViewContainer(_this.contentEl, calendar); 6255 } 6256 _this.toggleElClassNames(true); 6257 _this.computeTitle = memoize(computeTitle); 6258 _this.parseBusinessHours = memoize(function (input) { 6259 return parseBusinessHours(input, _this.calendar); 6260 }); 6261 return _this; 6262 } 6263 CalendarComponent.prototype.destroy = function () { 6264 if (this.header) { 6265 this.header.destroy(); 6266 } 6267 if (this.footer) { 6268 this.footer.destroy(); 6269 } 6270 if (this.view) { 6271 this.view.destroy(); 6272 } 6273 removeElement(this.contentEl); 6274 this.toggleElClassNames(false); 6275 _super.prototype.destroy.call(this); 6276 }; 6277 CalendarComponent.prototype.toggleElClassNames = function (bool) { 6278 var classList = this.el.classList; 6279 var dirClassName = 'fc-' + this.opt('dir'); 6280 var themeClassName = this.theme.getClass('widget'); 6281 if (bool) { 6282 classList.add('fc'); 6283 classList.add(dirClassName); 6284 classList.add(themeClassName); 6285 } 6286 else { 6287 classList.remove('fc'); 6288 classList.remove(dirClassName); 6289 classList.remove(themeClassName); 6290 } 6291 }; 6292 CalendarComponent.prototype.render = function (props) { 6293 this.freezeHeight(); 6294 var title = this.computeTitle(props.dateProfile, props.viewSpec.options); 6295 this._renderToolbars(props.viewSpec, props.dateProfile, props.currentDate, props.dateProfileGenerator, title); 6296 this.renderView(props, title); 6297 this.updateSize(); 6298 this.thawHeight(); 6299 }; 6300 CalendarComponent.prototype.renderToolbars = function (viewSpec, dateProfile, currentDate, dateProfileGenerator, title) { 6301 var headerLayout = this.opt('header'); 6302 var footerLayout = this.opt('footer'); 6303 var now = this.calendar.getNow(); 6304 var todayInfo = dateProfileGenerator.build(now); 6305 var prevInfo = dateProfileGenerator.buildPrev(dateProfile, currentDate); 6306 var nextInfo = dateProfileGenerator.buildNext(dateProfile, currentDate); 6307 var toolbarProps = { 6308 title: title, 6309 activeButton: viewSpec.type, 6310 isTodayEnabled: todayInfo.isValid && !rangeContainsMarker(dateProfile.currentRange, now), 6311 isPrevEnabled: prevInfo.isValid, 6312 isNextEnabled: nextInfo.isValid 6313 }; 6314 if (headerLayout) { 6315 if (!this.header) { 6316 this.header = new Toolbar(this.context, 'fc-header-toolbar'); 6317 prependToElement(this.el, this.header.el); 6318 } 6319 this.header.receiveProps(__assign({ layout: headerLayout }, toolbarProps)); 6320 } 6321 else if (this.header) { 6322 this.header.destroy(); 6323 this.header = null; 6324 }
6325 if (footerLayout) { 6326 if (!this.footer) { 6327 this.footer = new Toolbar(this.context, 'fc-footer-toolbar'); 6328 appendToElement(this.el, this.footer.el); 6329 } 6330 this.footer.receiveProps(__assign({ layout: footerLayout }, toolbarProps)); 6331 } 6332 else if (this.footer) { 6333 this.footer.destroy(); 6334 this.footer = null; 6335 } 6336 }; 6337 CalendarComponent.prototype.renderView = function (props, title) { 6338 var view = this.view; 6339 var viewSpec = props.viewSpec, dateProfileGenerator = props.dateProfileGenerator; 6340 if (!view || view.viewSpec !== viewSpec) { 6341 if (view) { 6342 view.destroy(); 6343 } 6344 view = this.view = new viewSpec['class']({ 6345 calendar: this.calendar, 6346 view: null, 6347 dateEnv: this.dateEnv, 6348 theme: this.theme, 6349 options: viewSpec.options 6350 }, viewSpec, dateProfileGenerator, this.contentEl); 6351 } 6352 else { 6353 view.addScroll(view.queryScroll()); 6354 } 6355 view.title = title; // for the API 6356 var viewProps = { 6357 dateProfile: props.dateProfile, 6358 businessHours: this.parseBusinessHours(viewSpec.options.businessHours), 6359 eventStore: props.eventStore, 6360 eventUiBases: props.eventUiBases, 6361 dateSelection: props.dateSelection, 6362 eventSelection: props.eventSelection, 6363 eventDrag: props.eventDrag, 6364 eventResize: props.eventResize 6365 }; 6366 var transformers = this.buildViewPropTransformers(this.calendar.pluginSystem.hooks.viewPropsTransformers); 6367 for (var _i = 0, transformers_1 = transformers; _i < transformers_1.length; _i++) { 6368 var transformer = transformers_1[_i]; 6369 __assign(viewProps, transformer.transform(viewProps, viewSpec, props, view)); 6370 } 6371 view.receiveProps(viewProps); 6372 }; 6373 // Sizing 6374 // ----------------------------------------------------------------------------------------------------------------- 6375 CalendarComponent.prototype.updateSize = function (isResize) { 6376 if (isResize === void 0) { isResize = false; } 6377 var view = this.view; 6378 if (isResize) { 6379 view.addScroll(view.queryScroll()); 6380 } 6381 if (isResize || this.isHeightAuto == null) { 6382 this.computeHeightVars(); 6383 } 6384 view.updateSize(isResize, this.viewHeight, this.isHeightAuto); 6385 view.updateNowIndicator(); // we need to guarantee this will run after updateSize 6386 view.popScroll(isResize); 6387 }; 6388 CalendarComponent.prototype.computeHeightVars = function () { 6389 var calendar = this.calendar; // yuck. need to handle dynamic options 6390 var heightInput = calendar.opt('height'); 6391 var contentHeightInput = calendar.opt('contentHeight'); 6392 this.isHeightAuto = heightInput === 'auto' || contentHeightInput === 'auto'; 6393 if (typeof contentHeightInput === 'number') { // exists and not 'auto' 6394 this.viewHeight = contentHeightInput; 6395 } 6396 else if (typeof contentHeightInput === 'function') { // exists and is a function 6397 this.viewHeight = contentHeightInput(); 6398 } 6399 else if (typeof heightInput === 'number') { // exists and not 'auto' 6400 this.viewHeight = heightInput - this.queryToolbarsHeight(); 6401 } 6402 else if (typeof heightInput === 'function') { // exists and is a function 6403 this.viewHeight = heightInput() - this.queryToolbarsHeight(); 6404 } 6405 else if (heightInput === 'parent') { // set to height of parent element 6406 var parentEl = this.el.parentNode; 6407 this.viewHeight = parentEl.getBoundingClientRect().height - this.queryToolbarsHeight(); 6408 } 6409 else { 6410 this.viewHeight = Math.round(this.contentEl.getBoundingClientRect().width / 6411 Math.max(calendar.opt('aspectRatio'), .5)); 6412 } 6413 }; 6414 CalendarComponent.prototype.queryToolbarsHeight = function () { 6415 var height = 0; 6416 if (this.header) { 6417 height += computeHeightAndMargins(this.header.el); 6418 } 6419 if (this.footer) { 6420 height += computeHeightAndMargins(this.footer.el); 6421 } 6422 return height; 6423 }; 6424 // Height "Freezing" 6425 // ----------------------------------------------------------------------------------------------------------------- 6426 CalendarComponent.prototype.freezeHeight = function () { 6427 applyStyle(this.el, { 6428 height: this.el.getBoundingClientRect().height, 6429 overflow: 'hidden' 6430 }); 6431 }; 6432 CalendarComponent.prototype.thawHeight = function () { 6433 applyStyle(this.el, { 6434 height: '', 6435 overflow: '' 6436 }); 6437 }; 6438 return CalendarComponent; 6439 }(Component)); 6440 // Title and Date Formatting 6441 // ----------------------------------------------------------------------------------------------------------------- 6442 // Computes what the title at the top of the calendar should be for this view 6443 function computeTitle(dateProfile, viewOptions) { 6444 var range; 6445 // for views that span a large unit of time, show the proper interval, ignoring stray days before and after 6446 if (/^(year|month)$/.test(dateProfile.currentRangeUnit)) { 6447 range = dateProfile.currentRange; 6448 } 6449 else { // for day units or smaller, use the actual day range 6450 range = dateProfile.activeRange; 6451 } 6452 return this.dateEnv.formatRange(range.start, range.end, createFormatter(viewOptions.titleFormat || computeTitleFormat(dateProfile), viewOptions.titleRangeSeparator), { isEndExclusive: dateProfile.isRangeAllDay }); 6453 }
6454 // Generates the format string that should be used to generate the title for the current date range. 6455 // Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`. 6456 function computeTitleFormat(dateProfile) { 6457 var currentRangeUnit = dateProfile.currentRangeUnit; 6458 if (currentRangeUnit === 'year') { 6459 return { year: 'numeric' }; 6460 } 6461 else if (currentRangeUnit === 'month') { 6462 return { year: 'numeric', month: 'long' }; // like "September 2014" 6463 } 6464 else { 6465 var days = diffWholeDays(dateProfile.currentRange.start, dateProfile.currentRange.end); 6466 if (days !== null && days > 1) { 6467 // multi-day range. shorter, like "Sep 9 - 10 2014" 6468 return { year: 'numeric', month: 'short', day: 'numeric' }; 6469 } 6470 else { 6471 // one day. longer, like "September 9 2014" 6472 return { year: 'numeric', month: 'long', day: 'numeric' }; 6473 } 6474 } 6475 } 6476 // Plugin 6477 // ----------------------------------------------------------------------------------------------------------------- 6478 function buildViewPropTransformers(theClasses) { 6479 return theClasses.map(function (theClass) { 6480 return new theClass(); 6481 }); 6482 } 6483 6484 var Interaction = /** @class */ (function () { 6485 function Interaction(settings) { 6486 this.component = settings.component; 6487 } 6488 Interaction.prototype.destroy = function () { 6489 }; 6490 return Interaction; 6491 }()); 6492 function parseInteractionSettings(component, input) { 6493 return { 6494 component: component, 6495 el: input.el, 6496 useEventCenter: input.useEventCenter != null ? input.useEventCenter : true 6497 }; 6498 } 6499 function interactionSettingsToStore(settings) { 6500 var _a; 6501 return _a = {}, 6502 _a[settings.component.uid] = settings, 6503 _a; 6504 } 6505 // global state 6506 var interactionSettingsStore = {}; 6507 6508 /* 6509 Detects when the user clicks on an event within a DateComponent 6510 */ 6511 var EventClicking = /** @class */ (function (_super) { 6512 __extends(EventClicking, _super); 6513 function EventClicking(settings) { 6514 var _this = _super.call(this, settings) || this; 6515 _this.handleSegClick = function (ev, segEl) { 6516 var component = _this.component; 6517 var seg = getElSeg(segEl); 6518 if (seg && // might be the <div> surrounding the more link 6519 component.isValidSegDownEl(ev.target)) { 6520 // our way to simulate a link click for elements that can't be <a> tags 6521 // grab before trigger fired in case trigger trashes DOM thru rerendering 6522 var hasUrlContainer = elementClosest(ev.target, '.fc-has-url'); 6523 var url = hasUrlContainer ? hasUrlContainer.querySelector('a[href]').href : ''; 6524 component.publiclyTrigger('eventClick', [ 6525 { 6526 el: segEl, 6527 event: new EventApi(component.calendar, seg.eventRange.def, seg.eventRange.instance), 6528 jsEvent: ev, 6529 view: component.view 6530 } 6531 ]); 6532 if (url && !ev.defaultPrevented) { 6533 window.location.href = url; 6534 } 6535 } 6536 }; 6537 var component = settings.component; 6538 _this.destroy = listenBySelector(component.el, 'click', component.fgSegSelector + ',' + component.bgSegSelector, _this.handleSegClick); 6539 return _this; 6540 } 6541 return EventClicking; 6542 }(Interaction)); 6543 6544 /* 6545 Triggers events and adds/removes core classNames when the user's pointer 6546 enters/leaves event-elements of a component. 6547 */ 6548 var EventHovering = /** @class */ (function (_super) { 6549 __extends(EventHovering, _super); 6550 function EventHovering(settings) { 6551 var _this = _super.call(this, settings) || this; 6552 // for simulating an eventMouseLeave when the event el is destroyed while mouse is over it 6553 _this.handleEventElRemove = function (el) { 6554 if (el === _this.currentSegEl) { 6555 _this.handleSegLeave(null, _this.currentSegEl); 6556 } 6557 }; 6558 _this.handleSegEnter = function (ev, segEl) { 6559 if (getElSeg(segEl)) { // TODO: better way to make sure not hovering over more+ link or its wrapper 6560 segEl.classList.add('fc-allow-mouse-resize'); 6561 _this.currentSegEl = segEl; 6562 _this.triggerEvent('eventMouseEnter', ev, segEl); 6563 } 6564 }; 6565 _this.handleSegLeave = function (ev, segEl) { 6566 if (_this.currentSegEl) { 6567 segEl.classList.remove('fc-allow-mouse-resize'); 6568 _this.currentSegEl = null; 6569 _this.triggerEvent('eventMouseLeave', ev, segEl); 6570 } 6571 }; 6572 var component = settings.component; 6573 _this.removeHoverListeners = listenToHoverBySelector(component.el, component.fgSegSelector + ',' + component.bgSegSelector, _this.handleSegEnter, _this.handleSegLeave); 6574 component.calendar.on('eventElRemove', _this.handleEventElRemove); 6575 return _this; 6576 } 6577 EventHovering.prototype.destroy = function () { 6578 this.removeHoverListeners(); 6579 this.component.calendar.off('eventElRemove', this.handleEventElRemove); 6580 }; 6581 EventHovering.prototype.triggerEvent = function (publicEvName, ev, segEl) { 6582 var component = this.component; 6583 var seg = getElSeg(segEl); 6584 if (!ev || component.isValidSegDownEl(ev.target)) { 6585 component.publiclyTrigger(publicEvName, [ 6586 { 6587 el: segEl, 6588 event: new EventApi(this.component.calendar, seg.eventRange.def, seg.eventRange.instance), 6589 jsEvent: ev, 6590 view: component.view 6591 } 6592 ]); 6593 } 6594 }; 6595 return EventHovering; 6596 }(Interaction)); 6597 6598 var StandardTheme = /** @class */ (function (_super) { 6599 __extends(StandardTheme, _super); 6600 function StandardTheme() { 6601 return _super !== null && _super.apply(this, arguments) || this; 6602 } 6603 return StandardTheme; 6604 }(Theme)); 6605 StandardTheme.prototype.classes = { 6606 widget: 'fc-unthemed', 6607 widgetHeader: 'fc-widget-header', 6608 widgetContent: 'fc-widget-content', 6609 buttonGroup: 'fc-button-group', 6610 button: 'fc-button fc-button-primary', 6611 buttonActive: 'fc-button-active', 6612 popoverHeader: 'fc-widget-header', 6613 popoverContent: 'fc-widget-content', 6614 // day grid 6615 headerRow: 'fc-widget-header', 6616 dayRow: 'fc-widget-content', 6617 // list view 6618 listView: 'fc-widget-content' 6619 }; 6620 StandardTheme.prototype.baseIconClass = 'fc-icon'; 6621 StandardTheme.prototype.iconClasses = { 6622 close: 'fc-icon-x', 6623 prev: 'fc-icon-chevron-left', 6624 next: 'fc-icon-chevron-right', 6625 prevYear: 'fc-icon-chevrons-left', 6626 nextYear: 'fc-icon-chevrons-right' 6627 }; 6628 StandardTheme.prototype.iconOverrideOption = 'buttonIcons'; 6629 StandardTheme.prototype.iconOverrideCustomButtonOption = 'icon'; 6630 StandardTheme.prototype.iconOverridePrefix = 'fc-icon-'; 6631 6632 var Calendar = /** @class */ (function () { 6633 function Calendar(el, overrides) { 6634 var _this = this; 6635 this.parseRawLocales = memoize(parseRawLocales); 6636 this.buildLocale = memoize(buildLocale); 6637 this.buildDateEnv = memoize(buildDateEnv); 6638 this.buildTheme = memoize(buildTheme); 6639 this.buildEventUiSingleBase = memoize(this._buildEventUiSingleBase); 6640 this.buildSelectionConfig = memoize(this._buildSelectionConfig); 6641 this.buildEventUiBySource = memoizeOutput(buildEventUiBySource, isPropsEqual); 6642 this.buildEventUiBases = memoize(buildEventUiBases); 6643 this.interactionsStore = {}; 6644 this.actionQueue = []; 6645 this.isReducing = false;
6646 // isDisplaying: boolean = false // installed in DOM? accepting renders? 6647 this.needsRerender = false; // needs a render? 6648 this.needsFullRerender = false; 6649 this.isRendering = false; // currently in the executeRender function? 6650 this.renderingPauseDepth = 0; 6651 this.buildDelayedRerender = memoize(buildDelayedRerender); 6652 this.afterSizingTriggers = {}; 6653 this.isViewUpdated = false; 6654 this.isDatesUpdated = false; 6655 this.isEventsUpdated = false; 6656 this.el = el; 6657 this.optionsManager = new OptionsManager(overrides || {}); 6658 this.pluginSystem = new PluginSystem(); 6659 // only do once. don't do in handleOptions. because can't remove plugins 6660 this.addPluginInputs(this.optionsManager.computed.plugins || []); 6661 this.handleOptions(this.optionsManager.computed); 6662 this.publiclyTrigger('_init'); // for tests 6663 this.hydrate(); 6664 this.calendarInteractions = this.pluginSystem.hooks.calendarInteractions 6665 .map(function (calendarInteractionClass) { 6666 return new calendarInteractionClass(_this); 6667 }); 6668 } 6669 Calendar.prototype.addPluginInputs = function (pluginInputs) { 6670 var pluginDefs = refinePluginDefs(pluginInputs); 6671 for (var _i = 0, pluginDefs_1 = pluginDefs; _i < pluginDefs_1.length; _i++) { 6672 var pluginDef = pluginDefs_1[_i]; 6673 this.pluginSystem.add(pluginDef); 6674 } 6675 }; 6676 Object.defineProperty(Calendar.prototype, "view", { 6677 // public API 6678 get: function () { 6679 return this.component ? this.component.view : null; 6680 }, 6681 enumerable: true, 6682 configurable: true 6683 }); 6684 // Public API for rendering 6685 // ----------------------------------------------------------------------------------------------------------------- 6686 Calendar.prototype.render = function () { 6687 if (!this.component) { 6688 this.renderableEventStore = createEmptyEventStore(); 6689 this.bindHandlers(); 6690 this.executeRender(); 6691 } 6692 else { 6693 this.requestRerender(true); 6694 } 6695 }; 6696 Calendar.prototype.destroy = function () { 6697 if (this.component) { 6698 this.unbindHandlers(); 6699 this.component.destroy(); // don't null-out. in case API needs access 6700 this.component = null; // umm ??? 6701 for (var _i = 0, _a = this.calendarInteractions; _i < _a.length; _i++) { 6702 var interaction = _a[_i]; 6703 interaction.destroy(); 6704 } 6705 this.publiclyTrigger('_destroyed'); 6706 } 6707 }; 6708 // Handlers 6709 // ----------------------------------------------------------------------------------------------------------------- 6710 Calendar.prototype.bindHandlers = function () { 6711 var _this = this; 6712 // event delegation for nav links 6713 this.removeNavLinkListener = listenBySelector(this.el, 'click', 'a[data-goto]', function (ev, anchorEl) { 6714 var gotoOptions = anchorEl.getAttribute('data-goto'); 6715 gotoOptions = gotoOptions ? JSON.parse(gotoOptions) : {}; 6716 var dateEnv = _this.dateEnv; 6717 var dateMarker = dateEnv.createMarker(gotoOptions.date); 6718 var viewType = gotoOptions.type; 6719 // property like "navLinkDayClick". might be a string or a function 6720 var customAction = _this.viewOpt('navLink' + capitaliseFirstLetter(viewType) + 'Click'); 6721 if (typeof customAction === 'function') { 6722 customAction(dateEnv.toDate(dateMarker), ev); 6723 } 6724 else { 6725 if (typeof customAction === 'string') { 6726 viewType = customAction; 6727 }
6728 _this.zoomTo(dateMarker, viewType); 6729 } 6730 }); 6731 if (this.opt('handleWindowResize')) { 6732 window.addEventListener('resize', this.windowResizeProxy = debounce(// prevents rapid calls 6733 this.windowResize.bind(this), this.opt('windowResizeDelay'))); 6734 } 6735 }; 6736 Calendar.prototype.unbindHandlers = function () { 6737 this.removeNavLinkListener(); 6738 if (this.windowResizeProxy) { 6739 window.removeEventListener('resize', this.windowResizeProxy); 6740 this.windowResizeProxy = null; 6741 } 6742 }; 6743 // Dispatcher 6744 // ----------------------------------------------------------------------------------------------------------------- 6745 Calendar.prototype.hydrate = function () { 6746 var _this = this; 6747 this.state = this.buildInitialState(); 6748 var rawSources = this.opt('eventSources') || []; 6749 var singleRawSource = this.opt('events'); 6750 var sources = []; // parsed 6751 if (singleRawSource) { 6752 rawSources.unshift(singleRawSource); 6753 } 6754 for (var _i = 0, rawSources_1 = rawSources; _i < rawSources_1.length; _i++) { 6755 var rawSource = rawSources_1[_i]; 6756 var source = parseEventSource(rawSource, this); 6757 if (source) { 6758 sources.push(source); 6759 } 6760 } 6761 this.batchRendering(function () { 6762 _this.dispatch({ type: 'INIT' }); // pass in sources here? 6763 _this.dispatch({ type: 'ADD_EVENT_SOURCES', sources: sources }); 6764 _this.dispatch({ 6765 type: 'SET_VIEW_TYPE', 6766 viewType: _this.opt('defaultView') || _this.pluginSystem.hooks.defaultView 6767 }); 6768 }); 6769 }; 6770 Calendar.prototype.buildInitialState = function () { 6771 return { 6772 viewType: null, 6773 loadingLevel: 0, 6774 eventSourceLoadingLevel: 0, 6775 currentDate: this.getInitialDate(), 6776 dateProfile: null, 6777 eventSources: {}, 6778 eventStore: createEmptyEventStore(), 6779 dateSelection: null, 6780 eventSelection: '', 6781 eventDrag: null, 6782 eventResize: null 6783 }; 6784 }; 6785 Calendar.prototype.dispatch = function (action) { 6786 this.actionQueue.push(action); 6787 if (!this.isReducing) { 6788 this.isReducing = true; 6789 var oldState = this.state; 6790 while (this.actionQueue.length) { 6791 this.state = this.reduce(this.state, this.actionQueue.shift(), this); 6792 } 6793 var newState = this.state; 6794 this.isReducing = false; 6795 if (!oldState.loadingLevel && newState.loadingLevel) { 6796 this.publiclyTrigger('loading', [true]); 6797 } 6798 else if (oldState.loadingLevel && !newState.loadingLevel) { 6799 this.publiclyTrigger('loading', [false]); 6800 } 6801 var view = this.component && this.component.view; 6802 if (oldState.eventStore !== newState.eventStore || this.needsFullRerender) { 6803 if (oldState.eventStore) { 6804 this.isEventsUpdated = true; 6805 } 6806 } 6807 if (oldState.dateProfile !== newState.dateProfile || this.needsFullRerender) { 6808 if (oldState.dateProfile && view) { // why would view be null!? 6809 this.publiclyTrigger('datesDestroy', [ 6810 { 6811 view: view, 6812 el: view.el 6813 } 6814 ]); 6815 } 6816 this.isDatesUpdated = true; 6817 } 6818 if (oldState.viewType !== newState.viewType || this.needsFullRerender) { 6819 if (oldState.viewType && view) { // why would view be null!? 6820 this.publiclyTrigger('viewSkeletonDestroy', [ 6821 { 6822 view: view, 6823 el: view.el 6824 } 6825 ]); 6826 } 6827 this.isViewUpdated = true; 6828 } 6829 this.requestRerender(); 6830 } 6831 }; 6832 Calendar.prototype.reduce = function (state, action, calendar) { 6833 return reduce(state, action, calendar); 6834 }; 6835 // Render Queue 6836 // ----------------------------------------------------------------------------------------------------------------- 6837 Calendar.prototype.requestRerender = function (needsFull) { 6838 if (needsFull === void 0) { needsFull = false; } 6839 this.needsRerender = true; 6840 this.needsFullRerender = this.needsFullRerender || needsFull; 6841 this.delayedRerender(); // will call a debounced-version of tryRerender 6842 }; 6843 Calendar.prototype.tryRerender = function () { 6844 if (this.component && // must be accepting renders 6845 this.needsRerender && // indicates that a rerender was requested 6846 !this.renderingPauseDepth && // not paused 6847 !this.isRendering // not currently in the render loop 6848 ) {
6849 this.executeRender(); 6850 } 6851 }; 6852 Calendar.prototype.batchRendering = function (func) { 6853 this.renderingPauseDepth++; 6854 func(); 6855 this.renderingPauseDepth--; 6856 if (this.needsRerender) { 6857 this.requestRerender(); 6858 } 6859 }; 6860 // Rendering 6861 // ----------------------------------------------------------------------------------------------------------------- 6862 Calendar.prototype.executeRender = function () { 6863 var needsFullRerender = this.needsFullRerender; // save before clearing 6864 // clear these BEFORE the render so that new values will accumulate during render 6865 this.needsRerender = false; 6866 this.needsFullRerender = false; 6867 this.isRendering = true; 6868 this.renderComponent(needsFullRerender); 6869 this.isRendering = false; 6870 // received a rerender request while rendering 6871 if (this.needsRerender) { 6872 this.delayedRerender(); 6873 } 6874 }; 6875 /* 6876 don't call this directly. use executeRender instead 6877 */ 6878 Calendar.prototype.renderComponent = function (needsFull) { 6879 var _a = this, state = _a.state, component = _a.component; 6880 var viewType = state.viewType; 6881 var viewSpec = this.viewSpecs[viewType]; 6882 var savedScroll = (needsFull && component) ? component.view.queryScroll() : null; 6883 if (!viewSpec) { 6884 throw new Error("View type \"" + viewType + "\" is not valid"); 6885 } 6886 // if event sources are still loading and progressive rendering hasn't been enabled, 6887 // keep rendering the last fully loaded set of events 6888 var renderableEventStore = this.renderableEventStore = 6889 (state.eventSourceLoadingLevel && !this.opt('progressiveEventRendering')) ? 6890 this.renderableEventStore : 6891 state.eventStore; 6892 var eventUiSingleBase = this.buildEventUiSingleBase(viewSpec.options); 6893 var eventUiBySource = this.buildEventUiBySource(state.eventSources); 6894 var eventUiBases = this.eventUiBases = this.buildEventUiBases(renderableEventStore.defs, eventUiSingleBase, eventUiBySource); 6895 if (needsFull || !component) { 6896 if (component) { 6897 component.freezeHeight(); // next component will unfreeze it 6898 component.destroy(); 6899 } 6900 component = this.component = new CalendarComponent({ 6901 calendar: this, 6902 view: null, 6903 dateEnv: this.dateEnv, 6904 theme: this.theme, 6905 options: this.optionsManager.computed 6906 }, this.el); 6907 this.isViewUpdated = true; 6908 this.isDatesUpdated = true; 6909 this.isEventsUpdated = true; 6910 } 6911 component.receiveProps(__assign({}, state, { viewSpec: viewSpec, dateProfile: state.dateProfile, dateProfileGenerator: this.dateProfileGenerators[viewType], eventStore: renderableEventStore, eventUiBases: eventUiBases, dateSelection: state.dateSelection, eventSelection: state.eventSelection, eventDrag: state.eventDrag, eventResize: state.eventResize })); 6912 if (savedScroll) { 6913 component.view.applyScroll(savedScroll, false); 6914 } 6915 if (this.isViewUpdated) { 6916 this.isViewUpdated = false; 6917 this.publiclyTrigger('viewSkeletonRender', [ 6918 { 6919 view: component.view, 6920 el: component.view.el 6921 } 6922 ]); 6923 } 6924 if (this.isDatesUpdated) { 6925 this.isDatesUpdated = false; 6926 this.publiclyTrigger('datesRender', [ 6927 { 6928 view: component.view, 6929 el: component.view.el 6930 } 6931 ]); 6932 } 6933 if (this.isEventsUpdated) { 6934 this.isEventsUpdated = false;
6935 } 6936 this.releaseAfterSizingTriggers(); 6937 }; 6938 // Options 6939 // ----------------------------------------------------------------------------------------------------------------- 6940 Calendar.prototype.setOption = function (name, val) { 6941 var _a; 6942 this.mutateOptions((_a = {}, _a[name] = val, _a), [], true); 6943 }; 6944 Calendar.prototype.getOption = function (name) { 6945 return this.optionsManager.computed[name]; 6946 }; 6947 Calendar.prototype.opt = function (name) { 6948 return this.optionsManager.computed[name]; 6949 }; 6950 Calendar.prototype.viewOpt = function (name) { 6951 return this.viewOpts()[name]; 6952 }; 6953 Calendar.prototype.viewOpts = function () { 6954 return this.viewSpecs[this.state.viewType].options; 6955 }; 6956 /* 6957 handles option changes (like a diff) 6958 */ 6959 Calendar.prototype.mutateOptions = function (updates, removals, isDynamic, deepEqual) { 6960 var _this = this; 6961 var changeHandlers = this.pluginSystem.hooks.optionChangeHandlers; 6962 var normalUpdates = {}; 6963 var specialUpdates = {}; 6964 var oldDateEnv = this.dateEnv; // do this before handleOptions 6965 var isTimeZoneDirty = false; 6966 var isSizeDirty = false; 6967 var anyDifficultOptions = Boolean(removals.length); 6968 for (var name_1 in updates) { 6969 if (changeHandlers[name_1]) { 6970 specialUpdates[name_1] = updates[name_1]; 6971 } 6972 else { 6973 normalUpdates[name_1] = updates[name_1]; 6974 } 6975 } 6976 for (var name_2 in normalUpdates) { 6977 if (/^(height|contentHeight|aspectRatio)$/.test(name_2)) { 6978 isSizeDirty = true; 6979 } 6980 else if (/^(defaultDate|defaultView)$/.test(name_2)) ; 6981 else { 6982 anyDifficultOptions = true; 6983 if (name_2 === 'timeZone') { 6984 isTimeZoneDirty = true; 6985 } 6986 } 6987 } 6988 this.optionsManager.mutate(normalUpdates, removals, isDynamic); 6989 if (anyDifficultOptions) { 6990 this.handleOptions(this.optionsManager.computed); 6991 this.needsFullRerender = true; 6992 } 6993 this.batchRendering(function () { 6994 if (anyDifficultOptions) { 6995 if (isTimeZoneDirty) { 6996 _this.dispatch({ 6997 type: 'CHANGE_TIMEZONE', 6998 oldDateEnv: oldDateEnv 6999 }); 7000 } 7001 /* HACK 7002 has the same effect as calling this.requestRerender(true) 7003 but recomputes the state's dateProfile 7004 */ 7005 _this.dispatch({ 7006 type: 'SET_VIEW_TYPE', 7007 viewType: _this.state.viewType 7008 }); 7009 } 7010 else if (isSizeDirty) { 7011 _this.updateSize(); 7012 } 7013 // special updates 7014 if (deepEqual) { 7015 for (var name_3 in specialUpdates) { 7016 changeHandlers[name_3](specialUpdates[name_3], _this, deepEqual); 7017 } 7018 } 7019 }); 7020 }; 7021 /* 7022 rebuilds things based off of a complete set of refined options 7023 */ 7024 Calendar.prototype.handleOptions = function (options) { 7025 var _this = this; 7026 var pluginHooks = this.pluginSystem.hooks; 7027 this.defaultAllDayEventDuration = createDuration(options.defaultAllDayEventDuration); 7028 this.defaultTimedEventDuration = createDuration(options.defaultTimedEventDuration); 7029 this.delayedRerender = this.buildDelayedRerender(options.rerenderDelay); 7030 this.theme = this.buildTheme(options); 7031 var available = this.parseRawLocales(options.locales); 7032 this.availableRawLocales = available.map; 7033 var locale = this.buildLocale(options.locale || available.defaultCode, available.map); 7034 this.dateEnv = this.buildDateEnv(locale, options.timeZone, pluginHooks.namedTimeZonedImpl, options.firstDay, options.weekNumberCalculation, options.weekLabel, pluginHooks.cmdFormatter); 7035 this.selectionConfig = this.buildSelectionConfig(options); // needs dateEnv. do after :( 7036 // ineffecient to do every time? 7037 this.viewSpecs = buildViewSpecs(pluginHooks.views, this.optionsManager); 7038 // ineffecient to do every time? 7039 this.dateProfileGenerators = mapHash(this.viewSpecs, function (viewSpec) { 7040 return new viewSpec.class.prototype.dateProfileGeneratorClass(viewSpec, _this); 7041 }); 7042 }; 7043 Calendar.prototype.getAvailableLocaleCodes = function () { 7044 return Object.keys(this.availableRawLocales); 7045 }; 7046 Calendar.prototype._buildSelectionConfig = function (rawOpts) { 7047 return processScopedUiProps('select', rawOpts, this); 7048 }; 7049 Calendar.prototype._buildEventUiSingleBase = function (rawOpts) { 7050 if (rawOpts.editable) { // so 'editable' affected events 7051 rawOpts = __assign({}, rawOpts, { eventEditable: true }); 7052 } 7053 return processScopedUiProps('event', rawOpts, this); 7054 }; 7055 // Trigger 7056 // ----------------------------------------------------------------------------------------------------------------- 7057 Calendar.prototype.hasPublicHandlers = function (name) { 7058 return this.hasHandlers(name) || 7059 this.opt(name); // handler specified in options 7060 }; 7061 Calendar.prototype.publiclyTrigger = function (name, args) { 7062 var optHandler = this.opt(name); 7063 this.triggerWith(name, this, args); 7064 if (optHandler) { 7065 return optHandler.apply(this, args); 7066 } 7067 }; 7068 Calendar.prototype.publiclyTriggerAfterSizing = function (name, args) { 7069 var afterSizingTriggers = this.afterSizingTriggers; 7070 (afterSizingTriggers[name] || (afterSizingTriggers[name] = [])).push(args); 7071 }; 7072 Calendar.prototype.releaseAfterSizingTriggers = function () { 7073 var afterSizingTriggers = this.afterSizingTriggers; 7074 for (var name_4 in afterSizingTriggers) { 7075 for (var _i = 0, _a = afterSizingTriggers[name_4]; _i < _a.length; _i++) { 7076 var args = _a[_i]; 7077 this.publiclyTrigger(name_4, args); 7078 } 7079 } 7080 this.afterSizingTriggers = {}; 7081 }; 7082 // View 7083 // ----------------------------------------------------------------------------------------------------------------- 7084 // Returns a boolean about whether the view is okay to instantiate at some point 7085 Calendar.prototype.isValidViewType = function (viewType) { 7086 return Boolean(this.viewSpecs[viewType]); 7087 }; 7088 Calendar.prototype.changeView = function (viewType, dateOrRange) { 7089 var dateMarker = null; 7090 if (dateOrRange) { 7091 if (dateOrRange.start && dateOrRange.end) { // a range 7092 this.optionsManager.mutate({ visibleRange: dateOrRange }, []); // will not rerender 7093 this.handleOptions(this.optionsManager.computed); // ...but yuck 7094 } 7095 else { // a date 7096 dateMarker = this.dateEnv.createMarker(dateOrRange); // just like gotoDate 7097 } 7098 } 7099 this.unselect(); 7100 this.dispatch({ 7101 type: 'SET_VIEW_TYPE', 7102 viewType: viewType, 7103 dateMarker: dateMarker 7104 }); 7105 };
7106 // Forces navigation to a view for the given date. 7107 // `viewType` can be a specific view name or a generic one like "week" or "day". 7108 // needs to change 7109 Calendar.prototype.zoomTo = function (dateMarker, viewType) { 7110 var spec; 7111 viewType = viewType || 'day'; // day is default zoom 7112 spec = this.viewSpecs[viewType] || 7113 this.getUnitViewSpec(viewType); 7114 this.unselect(); 7115 if (spec) { 7116 this.dispatch({ 7117 type: 'SET_VIEW_TYPE', 7118 viewType: spec.type, 7119 dateMarker: dateMarker 7120 }); 7121 } 7122 else { 7123 this.dispatch({ 7124 type: 'SET_DATE', 7125 dateMarker: dateMarker 7126 }); 7127 } 7128 }; 7129 // Given a duration singular unit, like "week" or "day", finds a matching view spec. 7130 // Preference is given to views that have corresponding buttons. 7131 Calendar.prototype.getUnitViewSpec = function (unit) { 7132 var component = this.component; 7133 var viewTypes = []; 7134 var i; 7135 var spec; 7136 // put views that have buttons first. there will be duplicates, but oh 7137 if (component.header) { 7138 viewTypes.push.apply(viewTypes, component.header.viewsWithButtons); 7139 } 7140 if (component.footer) { 7141 viewTypes.push.apply(viewTypes, component.footer.viewsWithButtons); 7142 } 7143 for (var viewType in this.viewSpecs) { 7144 viewTypes.push(viewType); 7145 } 7146 for (i = 0; i < viewTypes.length; i++) { 7147 spec = this.viewSpecs[viewTypes[i]]; 7148 if (spec) { 7149 if (spec.singleUnit === unit) { 7150 return spec; 7151 } 7152 } 7153 } 7154 }; 7155 // Current Date 7156 // ----------------------------------------------------------------------------------------------------------------- 7157 Calendar.prototype.getInitialDate = function () { 7158 var defaultDateInput = this.opt('defaultDate'); 7159 // compute the initial ambig-timezone date 7160 if (defaultDateInput != null) { 7161 return this.dateEnv.createMarker(defaultDateInput); 7162 } 7163 else { 7164 return this.getNow(); // getNow already returns unzoned 7165 } 7166 }; 7167 Calendar.prototype.prev = function () { 7168 this.unselect(); 7169 this.dispatch({ type: 'PREV' }); 7170 }; 7171 Calendar.prototype.next = function () { 7172 this.unselect(); 7173 this.dispatch({ type: 'NEXT' }); 7174 }; 7175 Calendar.prototype.prevYear = function () { 7176 this.unselect(); 7177 this.dispatch({ 7178 type: 'SET_DATE', 7179 dateMarker: this.dateEnv.addYears(this.state.currentDate, -1) 7180 }); 7181 }; 7182 Calendar.prototype.nextYear = function () { 7183 this.unselect(); 7184 this.dispatch({ 7185 type: 'SET_DATE', 7186 dateMarker: this.dateEnv.addYears(this.state.currentDate, 1) 7187 }); 7188 }; 7189 Calendar.prototype.today = function () { 7190 this.unselect(); 7191 this.dispatch({ 7192 type: 'SET_DATE', 7193 dateMarker: this.getNow() 7194 }); 7195 }; 7196 Calendar.prototype.gotoDate = function (zonedDateInput) { 7197 this.unselect(); 7198 this.dispatch({ 7199 type: 'SET_DATE', 7200 dateMarker: this.dateEnv.createMarker(zonedDateInput) 7201 }); 7202 }; 7203 Calendar.prototype.incrementDate = function (deltaInput) { 7204 var delta = createDuration(deltaInput); 7205 if (delta) { // else, warn about invalid input? 7206 this.unselect(); 7207 this.dispatch({ 7208 type: 'SET_DATE', 7209 dateMarker: this.dateEnv.add(this.state.currentDate, delta) 7210 }); 7211 } 7212 }; 7213 // for external API 7214 Calendar.prototype.getDate = function () { 7215 return this.dateEnv.toDate(this.state.currentDate); 7216 }; 7217 // Date Formatting Utils 7218 // ----------------------------------------------------------------------------------------------------------------- 7219 Calendar.prototype.formatDate = function (d, formatter) { 7220 var dateEnv = this.dateEnv; 7221 return dateEnv.format(dateEnv.createMarker(d), createFormatter(formatter)); 7222 }; 7223 // `settings` is for formatter AND isEndExclusive 7224 Calendar.prototype.formatRange = function (d0, d1, settings) { 7225 var dateEnv = this.dateEnv; 7226 return dateEnv.formatRange(dateEnv.createMarker(d0), dateEnv.createMarker(d1), createFormatter(settings, this.opt('defaultRangeSeparator')), settings); 7227 }; 7228 Calendar.prototype.formatIso = function (d, omitTime) { 7229 var dateEnv = this.dateEnv; 7230 return dateEnv.formatIso(dateEnv.createMarker(d), { omitTime: omitTime }); 7231 }; 7232 // Sizing 7233 // ----------------------------------------------------------------------------------------------------------------- 7234 Calendar.prototype.windowResize = function (ev) { 7235 if (!this.isHandlingWindowResize && 7236 this.component && // why? 7237 ev.target === window // not a jqui resize event 7238 ) { 7239 this.isHandlingWindowResize = true; 7240 this.updateSize(); 7241 this.publiclyTrigger('windowResize', [this.view]); 7242 this.isHandlingWindowResize = false;
7243 } 7244 }; 7245 Calendar.prototype.updateSize = function () { 7246 if (this.component) { // when? 7247 this.component.updateSize(true); 7248 } 7249 }; 7250 // Component Registration 7251 // ----------------------------------------------------------------------------------------------------------------- 7252 Calendar.prototype.registerInteractiveComponent = function (component, settingsInput) { 7253 var settings = parseInteractionSettings(component, settingsInput); 7254 var DEFAULT_INTERACTIONS = [ 7255 EventClicking, 7256 EventHovering 7257 ]; 7258 var interactionClasses = DEFAULT_INTERACTIONS.concat(this.pluginSystem.hooks.componentInteractions); 7259 var interactions = interactionClasses.map(function (interactionClass) { 7260 return new interactionClass(settings); 7261 }); 7262 this.interactionsStore[component.uid] = interactions; 7263 interactionSettingsStore[component.uid] = settings; 7264 }; 7265 Calendar.prototype.unregisterInteractiveComponent = function (component) { 7266 for (var _i = 0, _a = this.interactionsStore[component.uid]; _i < _a.length; _i++) { 7267 var listener = _a[_i]; 7268 listener.destroy(); 7269 } 7270 delete this.interactionsStore[component.uid]; 7271 delete interactionSettingsStore[component.uid]; 7272 }; 7273 // Date Selection / Event Selection / DayClick 7274 // ----------------------------------------------------------------------------------------------------------------- 7275 // this public method receives start/end dates in any format, with any timezone 7276 // NOTE: args were changed from v3 7277 Calendar.prototype.select = function (dateOrObj, endDate) { 7278 var selectionInput; 7279 if (endDate == null) { 7280 if (dateOrObj.start != null) { 7281 selectionInput = dateOrObj; 7282 } 7283 else { 7284 selectionInput = { 7285 start: dateOrObj, 7286 end: null 7287 }; 7288 } 7289 } 7290 else { 7291 selectionInput = { 7292 start: dateOrObj, 7293 end: endDate 7294 }; 7295 } 7296 var selection = parseDateSpan(selectionInput, this.dateEnv, createDuration({ days: 1 }) // TODO: cache this? 7297 ); 7298 if (selection) { // throw parse error otherwise? 7299 this.dispatch({ type: 'SELECT_DATES', selection: selection }); 7300 this.triggerDateSelect(selection); 7301 } 7302 }; 7303 // public method 7304 Calendar.prototype.unselect = function (pev) { 7305 if (this.state.dateSelection) { 7306 this.dispatch({ type: 'UNSELECT_DATES' }); 7307 this.triggerDateUnselect(pev); 7308 } 7309 }; 7310 Calendar.prototype.triggerDateSelect = function (selection, pev) { 7311 var arg = __assign({}, this.buildDateSpanApi(selection), { jsEvent: pev ? pev.origEvent : null, view: this.view }); 7312 this.publiclyTrigger('select', [arg]); 7313 }; 7314 Calendar.prototype.triggerDateUnselect = function (pev) { 7315 this.publiclyTrigger('unselect', [ 7316 { 7317 jsEvent: pev ? pev.origEvent : null, 7318 view: this.view 7319 } 7320 ]); 7321 }; 7322 // TODO: receive pev? 7323 Calendar.prototype.triggerDateClick = function (dateSpan, dayEl, view, ev) { 7324 var arg = __assign({}, this.buildDatePointApi(dateSpan), { dayEl: dayEl, jsEvent: ev, // Is this always a mouse event? See #4655 7325 view: view }); 7326 this.publiclyTrigger('dateClick', [arg]); 7327 }; 7328 Calendar.prototype.buildDatePointApi = function (dateSpan) { 7329 var props = {}; 7330 for (var _i = 0, _a = this.pluginSystem.hooks.datePointTransforms; _i < _a.length; _i++) { 7331 var transform = _a[_i]; 7332 __assign(props, transform(dateSpan, this)); 7333 } 7334 __assign(props, buildDatePointApi(dateSpan, this.dateEnv)); 7335 return props; 7336 }; 7337 Calendar.prototype.buildDateSpanApi = function (dateSpan) { 7338 var props = {}; 7339 for (var _i = 0, _a = this.pluginSystem.hooks.dateSpanTransforms; _i < _a.length; _i++) { 7340 var transform = _a[_i]; 7341 __assign(props, transform(dateSpan, this)); 7342 } 7343 __assign(props, buildDateSpanApi(dateSpan, this.dateEnv)); 7344 return props; 7345 }; 7346 // Date Utils 7347 // ----------------------------------------------------------------------------------------------------------------- 7348 // Returns a DateMarker for the current date, as defined by the client's computer or from the `now` option 7349 Calendar.prototype.getNow = function () { 7350 var now = this.opt('now'); 7351 if (typeof now === 'function') { 7352 now = now(); 7353 } 7354 if (now == null) { 7355 return this.dateEnv.createNowMarker(); 7356 } 7357 return this.dateEnv.createMarker(now); 7358 }; 7359 // Event-Date Utilities 7360 // ----------------------------------------------------------------------------------------------------------------- 7361 // Given an event's allDay status and start date, return what its fallback end date should be. 7362 // TODO: rename to computeDefaultEventEnd 7363 Calendar.prototype.getDefaultEventEnd = function (allDay, marker) { 7364 var end = marker; 7365 if (allDay) { 7366 end = startOfDay(end); 7367 end = this.dateEnv.add(end, this.defaultAllDayEventDuration); 7368 } 7369 else { 7370 end = this.dateEnv.add(end, this.defaultTimedEventDuration); 7371 } 7372 return end; 7373 }; 7374 // Public Events API 7375 // ----------------------------------------------------------------------------------------------------------------- 7376 Calendar.prototype.addEvent = function (eventInput, sourceIn
7376put) { 7377 if (eventInput instanceof EventApi) { 7378 var def = eventInput._def; 7379 var instance = eventInput._instance; 7380 // not already present? don't want to add an old snapshot 7381 if (!this.state.eventStore.defs[def.defId]) { 7382 this.dispatch({ 7383 type: 'ADD_EVENTS', 7384 eventStore: eventTupleToStore({ def: def, instance: instance }) // TODO: better util for two args? 7385 }); 7386 } 7387 return eventInput; 7388 } 7389 var sourceId; 7390 if (sourceInput instanceof EventSourceApi) { 7391 sourceId = sourceInput.internalEventSource.sourceId; 7392 } 7393 else if (sourceInput != null) { 7394 var sourceApi = this.getEventSourceById(sourceInput); // TODO: use an internal function 7395 if (!sourceApi) { 7396 console.warn('Could not find an event source with ID "' + sourceInput + '"'); // TODO: test 7397 return null; 7398 } 7399 else { 7400 sourceId = sourceApi.internalEventSource.sourceId; 7401 } 7402 } 7403 var tuple = parseEvent(eventInput, sourceId, this); 7404 if (tuple) { 7405 this.dispatch({ 7406 type: 'ADD_EVENTS', 7407 eventStore: eventTupleToStore(tuple) 7408 }); 7409 return new EventApi(this, tuple.def, tuple.def.recurringDef ? null : tuple.instance); 7410 } 7411 return null; 7412 }; 7413 // TODO: optimize 7414 Calendar.prototype.getEventById = function (id) { 7415 var _a = this.state.eventStore, defs = _a.defs, instances = _a.instances; 7416 id = String(id); 7417 for (var defId in defs) { 7418 var def = defs[defId]; 7419 if (def.publicId === id) { 7420 if (def.recurringDef) { 7421 return new EventApi(this, def, null); 7422 } 7423 else { 7424 for (var instanceId in instances) { 7425 var instance = instances[instanceId]; 7426 if (instance.defId === def.defId) { 7427 return new EventApi(this, def, instance); 7428 } 7429 } 7430 } 7431 } 7432 } 7433 return null; 7434 }; 7435 Calendar.prototype.getEvents = function () { 7436 var _a = this.state.eventStore, defs = _a.defs, instances = _a.instances; 7437 var eventApis = []; 7438 for (var id in instances) { 7439 var instance = instances[id]; 7440 var def = defs[instance.defId]; 7441 eventApis.push(new EventApi(this, def, instance)); 7442 } 7443 return eventApis; 7444 }; 7445 Calendar.prototype.removeAllEvents = function () { 7446 this.dispatch({ type: 'REMOVE_ALL_EVENTS' }); 7447 }; 7448 Calendar.prototype.rerenderEvents = function () { 7449 this.dispatch({ type: 'RESET_EVENTS' }); 7450 }; 7451 // Public Event Sources API 7452 // ----------------------------------------------------------------------------------------------------------------- 7453 Calendar.prototype.getEventSources = function () { 7454 var sourceHash = this.state.eventSources; 7455 var sourceApis = []; 7456 for (var internalId in sourceHash) { 7457 sourceApis.push(new EventSourceApi(this, sourceHash[internalId])); 7458 } 7459 return sourceApis; 7460 }; 7461 Calendar.prototype.getEventSourceById = function (id) { 7462 var sourceHash = this.state.eventSources; 7463 id = String(id); 7464 for (var sourceId in sourceHash) { 7465 if (sourceHash[sourceId].publicId === id) { 7466 return new EventSourceApi(this, sourceHash[sourceId]); 7467 } 7468 } 7469 return null; 7470 }; 7471 Calendar.prototype.addEventSource = function (sourceInput) { 7472 if (sourceInput instanceof EventSourceApi) { 7473 // not already present? don't want to add an old snapshot
7474 if (!this.state.eventSources[sourceInput.internalEventSource.sourceId]) { 7475 this.dispatch({ 7476 type: 'ADD_EVENT_SOURCES', 7477 sources: [sourceInput.internalEventSource] 7478 }); 7479 } 7480 return sourceInput; 7481 } 7482 var eventSource = parseEventSource(sourceInput, this); 7483 if (eventSource) { // TODO: error otherwise? 7484 this.dispatch({ type: 'ADD_EVENT_SOURCES', sources: [eventSource] }); 7485 return new EventSourceApi(this, eventSource); 7486 } 7487 return null; 7488 }; 7489 Calendar.prototype.removeAllEventSources = function () { 7490 this.dispatch({ type: 'REMOVE_ALL_EVENT_SOURCES' }); 7491 }; 7492 Calendar.prototype.refetchEvents = function () { 7493 this.dispatch({ type: 'FETCH_EVENT_SOURCES' }); 7494 }; 7495 // Scroll 7496 // ----------------------------------------------------------------------------------------------------------------- 7497 Calendar.prototype.scrollToTime = function (timeInput) { 7498 var duration = createDuration(timeInput); 7499 if (duration) { 7500 this.component.view.scrollToDuration(duration); 7501 } 7502 }; 7503 return Calendar; 7504 }()); 7505 EmitterMixin.mixInto(Calendar); 7506 // for memoizers 7507 // ----------------------------------------------------------------------------------------------------------------- 7508 function buildDateEnv(locale, timeZone, namedTimeZoneImpl, firstDay, weekNumberCalculation, weekLabel, cmdFormatter) { 7509 return new DateEnv({ 7510 calendarSystem: 'gregory', 7511 timeZone: timeZone, 7512 namedTimeZoneImpl: namedTimeZoneImpl, 7513 locale: locale, 7514 weekNumberCalculation: weekNumberCalculation, 7515 firstDay: firstDay, 7516 weekLabel: weekLabel, 7517 cmdFormatter: cmdFormatter 7518 }); 7519 } 7520 function buildTheme(calendarOptions) { 7521 var themeClass = this.pluginSystem.hooks.themeClasses[calendarOptions.themeSystem] || StandardTheme; 7522 return new themeClass(calendarOptions); 7523 } 7524 function buildDelayedRerender(wait) { 7525 var func = this.tryRerender.bind(this); 7526 if (wait != null) { 7527 func = debounce(func, wait); 7528 } 7529 return func; 7530 } 7531 function buildEventUiBySource(eventSources) { 7532 return mapHash(eventSources, function (eventSource) { 7533 return eventSource.ui; 7534 }); 7535 } 7536 function buildEventUiBases(eventDefs, eventUiSingleBase, eventUiBySource) { 7537 var eventUiBases = { '': eventUiSingleBase }; 7538 for (var defId in eventDefs) { 7539 var def = eventDefs[defId]; 7540 if (def.sourceId && eventUiBySource[def.sourceId]) { 7541 eventUiBases[defId] = eventUiBySource[def.sourceId]; 7542 } 7543 } 7544 return eventUiBases; 7545 } 7546 7547 var View = /** @class */ (function (_super) { 7548 __extends(View, _super); 7549 function View(context, viewSpec, dateProfileGenerator, parentEl) { 7550 var _this = _super.call(this, context, createElement('div', { className: 'fc-view fc-' + viewSpec.type + '-view' }), true // isView (HACK) 7551 ) || this; 7552 _this.renderDatesMem = memoizeRendering(_this.renderDatesWrap, _this.unrenderDatesWrap); 7553 _this.renderBusinessHoursMem = memoizeRendering(_this.renderBusinessHours, _this.unrenderBusinessHours, [_this.renderDatesMem]); 7554 _this.renderDateSelectionMem = memoizeRendering(_this.renderDateSelectionWrap, _this.unrenderDateSelectionWrap, [_this.renderDatesMem]); 7555 _this.renderEventsMem = memoizeRendering(_this.renderEvents, _this.unrenderEvents, [_this.renderDatesMem]); 7556 _this.renderEventSelectionMem = memoizeRendering(_this.renderEventSelectionWrap, _this.unrenderEventSelectionWrap, [_this.renderEventsMem]); 7557 _this.renderEventDragMem = memoizeRendering(_this.renderEventDragWrap, _this.unrenderEventDragWrap, [_this.renderDatesMem]); 7558 _this.renderEventResizeMem = memoizeRendering(_this.renderEventResizeWrap, _this.unrenderEventResizeWrap, [_this.renderDatesMem]); 7559 _this.viewSpec = viewSpec; 7560 _this.dateProfileGenerator = dateProfileGenerator; 7561 _this.type = viewSpec.type; 7562 _this.eventOrderSpecs = parseFieldSpecs(_this.opt('eventOrder')); 7563 _this.nextDayThreshold = createDuration(_this.opt('nextDayThreshold')); 7564 parentEl.appendChild(_this.el); 7565 _this.initialize(); 7566 return _this; 7567 } 7568 View.prototype.initialize = function () { 7569 }; 7570 Object.defineProperty(View.prototype, "activeStart", { 7571 // Date Setting/Unsetting 7572 // ----------------------------------------------------------------------------------------------------------------- 7573 get: function () { 7574 return this.dateEnv.toDate(this.props.dateProfile.activeRange.start); 7575 }, 7576 enumerable: true, 7577 configurable: true 7578 }); 7579 Object.defineProperty(View.prototype, "activeEnd", { 7580 get: function () { 7581 return this.dateEnv.toDate(this.props.dateProfile.activeRange.end); 7582 }, 7583 enumerable: true, 7584 configurable: true 7585 }); 7586 Object.defineProperty(View.prototype, "currentStart", { 7587 get: function () { 7588 return this.dateEnv.toDate(this.props.dateProfile.currentRange.start); 7589 }, 7590 enumerable: true, 7591 configurable: true 7592 }); 7593 Object.defineProperty(View.prototype, "currentEnd", { 7594 get: function () { 7595 return this.dateEnv.toDate(this.props.dateProfile.currentRange.end); 7596 }, 7597 enumerable: true, 7598 configurable: true 7599 }); 7600 // General Rendering 7601 // ----------------------------------------------------------------------------------------------------------------- 7602 View.prototype.render = function (props) { 7603 this.renderDatesMem(props.dateProfile); 7604 this.renderBusinessHoursMem(props.businessHours); 7605 this.renderDateSelectionMem(props.dateSelection); 7606 this.renderEventsMem(props.eventStore); 7607 this.renderEventSelectionMem(props.eventSelection); 7608 this.renderEventDragMem(props.eventDrag); 7609 this.renderEventResizeMem(props.eventResize); 7610 }; 7611 View.prototype.destroy = function () { 7612 _super.prototype.destroy.call(this); 7613 this.renderDatesMem.unrender(); // should unrender everything else 7614 }; 7615 // Sizing 7616 // ----------------------------------------------------------------------------------------------------------------- 7617 View.prototype.updateSize = function (isResize, viewHeight, isAuto) { 7618 var calendar = this.calendar; 7619 if (isResize || // HACKS... 7620 calendar.isViewUpdated || 7621 calendar.isDatesUpdated || 7622 calendar.isEventsUpdated) {
7623 // sort of the catch-all sizing 7624 // anything that might cause dimension changes 7625 this.updateBaseSize(isResize, viewHeight, isAuto); 7626 } 7627 }; 7628 View.prototype.updateBaseSize = function (isResize, viewHeight, isAuto) { 7629 }; 7630 // Date Rendering 7631 // ----------------------------------------------------------------------------------------------------------------- 7632 View.prototype.renderDatesWrap = function (dateProfile) { 7633 this.renderDates(dateProfile); 7634 this.addScroll({ 7635 duration: createDuration(this.opt('scrollTime')) 7636 }); 7637 this.startNowIndicator(dateProfile); // shouldn't render yet because updateSize will be called soon 7638 }; 7639 View.prototype.unrenderDatesWrap = function () { 7640 this.stopNowIndicator(); 7641 this.unrenderDates(); 7642 }; 7643 View.prototype.renderDates = function (dateProfile) { }; 7644 View.prototype.unrenderDates = function () { }; 7645 // Business Hours 7646 // ----------------------------------------------------------------------------------------------------------------- 7647 View.prototype.renderBusinessHours = function (businessHours) { }; 7648 View.prototype.unrenderBusinessHours = function () { }; 7649 // Date Selection 7650 // ----------------------------------------------------------------------------------------------------------------- 7651 View.prototype.renderDateSelectionWrap = function (selection) { 7652 if (selection) { 7653 this.renderDateSelection(selection); 7654 } 7655 }; 7656 View.prototype.unrenderDateSelectionWrap = function (selection) { 7657 if (selection) { 7658 this.unrenderDateSelection(selection); 7659 } 7660 }; 7661 View.prototype.renderDateSelection = function (selection) { }; 7662 View.prototype.unrenderDateSelection = function (selection) { }; 7663 // Event Rendering 7664 // ----------------------------------------------------------------------------------------------------------------- 7665 View.prototype.renderEvents = function (eventStore) { }; 7666 View.prototype.unrenderEvents = function () { }; 7667 // util for subclasses 7668 View.prototype.sliceEvents = function (eventStore, allDay) { 7669 var props = this.props; 7670 return sliceEventStore(eventStore, props.eventUiBases, props.dateProfile.activeRange, allDay ? this.nextDayThreshold : null).fg; 7671 }; 7672 View.prototype.computeEventDraggable = function (eventDef, eventUi) { 7673 var transformers = this.calendar.pluginSystem.hooks.isDraggableTransformers; 7674 var val = eventUi.startEditable; 7675 for (var _i = 0, transformers_1 = transformers; _i < transformers_1.length; _i++) { 7676 var transformer = transformers_1[_i]; 7677 val = transformer(val, eventDef, eventUi, this); 7678 } 7679 return val; 7680 }; 7681 View.prototype.computeEventStartResizable = function (eventDef, eventUi) { 7682 return eventUi.durationEditable && this.opt('eventResizableFromStart'); 7683 }; 7684 View.prototype.computeEventEndResizable = function (eventDef, eventUi) { 7685 return eventUi.durationEditable; 7686 }; 7687 // Event Selection 7688 // ----------------------------------------------------------------------------------------------------------------- 7689 View.prototype.renderEventSelectionWrap = function (instanceId) { 7690 if (instanceId) { 7691 this.renderEventSelection(instanceId); 7692 } 7693 }; 7694 View.prototype.unrenderEventSelectionWrap = function (instanceId) { 7695 if (instanceId) { 7696 this.unrenderEventSelection(instanceId); 7697 } 7698 }; 7699 View.prototype.renderEventSelection = function (instanceId) { }; 7700 View.prototype.unrenderEventSelection = function (instanceId) { }; 7701 // Event Drag 7702 // ----------------------------------------------------------------------------------------------------------------- 7703 View.prototype.renderEventDragWrap = function (state) { 7704 if (state) { 7705 this.renderEventDrag(state); 7706 } 7707 }; 7708 View.prototype.unrenderEventDragWrap = function (state) { 7709 if (state) { 7710 this.unrenderEventDrag(state); 7711 } 7712 }; 7713 View.prototype.renderEventDrag = function (state) { }; 7714 View.prototype.unrenderEventDrag = function (state) { }; 7715 // Event Resize 7716 // ----------------------------------------------------------------------------------------------------------------- 7717 View.prototype.renderEventResizeWrap = function (state) { 7718 if (state) { 7719 this.renderEventResize(state); 7720 } 7721 }; 7722 View.prototype.unrenderEventResizeWrap = function (state) { 7723 if (state) { 7724 this.unrenderEventResize(state); 7725 } 7726 }; 7727 View.prototype.renderEventResize = function (state) { }; 7728 View.prototype.unrenderEventResize = function (state) { }; 7729 /* Now Indicator 7730 ------------------------------------------------------------------------------------------------------------------*/ 7731 // Immediately render the current time indicator and begins re-rendering it at an interval, 7732 // which is defined by this.getNowIndicatorUnit(). 7733 // TODO: somehow do this for the current whole day's background too 7734 View.prototype.startNowIndicator = function (dateProfile) { 7735 var _this = this; 7736 var dateEnv = this.dateEnv; 7737 var unit; 7738 var update; 7739 var delay; // ms wait value 7740 if (this.opt('nowIndicator')) { 7741 unit = this.getNowIndicatorUnit(dateProfile); 7742 if (unit) { 7743 update = this.updateNowIndicator.bind(this); 7744 this.initialNowDate = this.calendar.getNow(); 7745 this.initialNowQueriedMs = new Date().valueOf(); 7746 // wait until the beginning of the next interval
7747 delay = dateEnv.add(dateEnv.startOf(this.initialNowDate, unit), createDuration(1, unit)).valueOf() - this.initialNowDate.valueOf(); 7748 // TODO: maybe always use setTimeout, waiting until start of next unit 7749 this.nowIndicatorTimeoutID = setTimeout(function () { 7750 _this.nowIndicatorTimeoutID = null; 7751 update(); 7752 if (unit === 'second') { 7753 delay = 1000; // every second 7754 } 7755 else { 7756 delay = 1000 * 60; // otherwise, every minute 7757 } 7758 _this.nowIndicatorIntervalID = setInterval(update, delay); // update every interval 7759 }, delay); 7760 } 7761 // rendering will be initiated in updateSize 7762 } 7763 }; 7764 // rerenders the now indicator, computing the new current time from the amount of time that has passed 7765 // since the initial getNow call. 7766 View.prototype.updateNowIndicator = function () { 7767 if (this.props.dateProfile && // a way to determine if dates were rendered yet 7768 this.initialNowDate // activated before? 7769 ) { 7770 this.unrenderNowIndicator(); // won't unrender if unnecessary 7771 this.renderNowIndicator(addMs(this.initialNowDate, new Date().valueOf() - this.initialNowQueriedMs)); 7772 this.isNowIndicatorRendered = true; 7773 } 7774 }; 7775 // Immediately unrenders the view's current time indicator and stops any re-rendering timers. 7776 // Won't cause side effects if indicator isn't rendered. 7777 View.prototype.stopNowIndicator = function () { 7778 if (this.isNowIndicatorRendered) { 7779 if (this.nowIndicatorTimeoutID) { 7780 clearTimeout(this.nowIndicatorTimeoutID); 7781 this.nowIndicatorTimeoutID = null; 7782 } 7783 if (this.nowIndicatorIntervalID) { 7784 clearInterval(this.nowIndicatorIntervalID); 7785 this.nowIndicatorIntervalID = null; 7786 } 7787 this.unrenderNowIndicator(); 7788 this.isNowIndicatorRendered = false; 7789 } 7790 }; 7791 View.prototype.getNowIndicatorUnit = function (dateProfile) { 7792 // subclasses should implement 7793 }; 7794 // Renders a current time indicator at the given datetime 7795 View.prototype.renderNowIndicator = function (date) { 7796 // SUBCLASSES MUST PASS TO CHILDREN! 7797 }; 7798 // Undoes the rendering actions from renderNowIndicator 7799 View.prototype.unrenderNowIndicator = function () { 7800 // SUBCLASSES MUST PASS TO CHILDREN! 7801 }; 7802 /* Scroller 7803 ------------------------------------------------------------------------------------------------------------------*/ 7804 View.prototype.addScroll = function (scroll) { 7805 var queuedScroll = this.queuedScroll || (this.queuedScroll = {}); 7806 __assign(queuedScroll, scroll); 7807 }; 7808 View.prototype.popScroll = function (isResize) { 7809 this.applyQueuedScroll(isResize); 7810 this.queuedScroll = null; 7811 }; 7812 View.prototype.applyQueuedScroll = function (isResize) { 7813 this.applyScroll(this.queuedScroll || {}, isResize); 7814 }; 7815 View.prototype.queryScroll = function () { 7816 var scroll = {}; 7817 if (this.props.dateProfile) { // dates rendered yet? 7818 __assign(scroll, this.queryDateScroll()); 7819 } 7820 return scroll; 7821 }; 7822 View.prototype.applyScroll = function (scroll, isResize) { 7823 var duration = scroll.duration; 7824 if (duration != null) { 7825 delete scroll.duration; 7826 if (this.props.dateProfile) { // dates rendered yet? 7827 __assign(scroll, this.computeDateScroll(duration)); 7828 } 7829 } 7830 if (this.props.dateProfile) { // dates rendered yet? 7831 this.applyDateScroll(scroll); 7832 } 7833 }; 7834 View.prototype.computeDateScroll = function (duration) { 7835 return {}; // subclasses must implement 7836 }; 7837 View.prototype.queryDateScroll = function () { 7838 return {}; // subclasses must implement 7839 }; 7840 View.prototype.applyDateScroll = function (scroll) { 7841 // subclasses must implement 7842 }; 7843 // for API 7844 View.prototype.scrollToDuration = function (duration) { 7845 this.applyScroll({ duration: duration }, false); 7846 }; 7847 return View; 7848 }(DateComponent)); 7849 EmitterMixin.mixInto(View); 7850 View.prototype.usesMinMaxTime = false;
7851 View.prototype.dateProfileGeneratorClass = DateProfileGenerator; 7852 7853 var FgEventRenderer = /** @class */ (function () { 7854 function FgEventRenderer(context) { 7855 this.segs = []; 7856 this.isSizeDirty = false; 7857 this.context = context; 7858 } 7859 FgEventRenderer.prototype.renderSegs = function (segs, mirrorInfo) { 7860 this.rangeUpdated(); // called too frequently :( 7861 // render an `.el` on each seg 7862 // returns a subset of the segs. segs that were actually rendered 7863 segs = this.renderSegEls(segs, mirrorInfo); 7864 this.segs = segs; 7865 this.attachSegs(segs, mirrorInfo); 7866 this.isSizeDirty = true; 7867 this.context.view.triggerRenderedSegs(this.segs, Boolean(mirrorInfo)); 7868 }; 7869 FgEventRenderer.prototype.unrender = function (_segs, mirrorInfo) { 7870 this.context.view.triggerWillRemoveSegs(this.segs, Boolean(mirrorInfo)); 7871 this.detachSegs(this.segs); 7872 this.segs = []; 7873 }; 7874 // Updates values that rely on options and also relate to range 7875 FgEventRenderer.prototype.rangeUpdated = function () { 7876 var options = this.context.options; 7877 var displayEventTime; 7878 var displayEventEnd; 7879 this.eventTimeFormat = createFormatter(options.eventTimeFormat || this.computeEventTimeFormat(), options.defaultRangeSeparator); 7880 displayEventTime = options.displayEventTime; 7881 if (displayEventTime == null) { 7882 displayEventTime = this.computeDisplayEventTime(); // might be based off of range 7883 } 7884 displayEventEnd = options.displayEventEnd; 7885 if (displayEventEnd == null) { 7886 displayEventEnd = this.computeDisplayEventEnd(); // might be based off of range 7887 } 7888 this.displayEventTime = displayEventTime; 7889 this.displayEventEnd = displayEventEnd; 7890 }; 7891 // Renders and assigns an `el` property for each foreground event segment. 7892 // Only returns segments that successfully rendered. 7893 FgEventRenderer.prototype.renderSegEls = function (segs, mirrorInfo) { 7894 var html = ''; 7895 var i; 7896 if (segs.length) { // don't build an empty html string 7897 // build a large concatenation of event segment HTML 7898 for (i = 0; i < segs.length; i++) { 7899 html += this.renderSegHtml(segs[i], mirrorInfo); 7900 } 7901 // Grab individual elements from the combined HTML string. Use each as the default rendering. 7902 // Then, compute the 'el' for each segment. An el might be null if the eventRender callback returned false. 7903 htmlToElements(html).forEach(function (el, i) { 7904 var seg = segs[i]; 7905 if (el) { 7906 seg.el = el; 7907 } 7908 }); 7909 segs = filterSegsViaEls(this.context.view, segs, Boolean(mirrorInfo)); 7910 } 7911 return segs; 7912 }; 7913 // Generic utility for generating the HTML classNames for an event segment's element 7914 FgEventRenderer.prototype.getSegClasses = function (seg, isDraggable, isResizable, mirrorInfo) { 7915 var classes = [ 7916 'fc-event', 7917 seg.isStart ? 'fc-start' : 'fc-not-start', 7918 seg.isEnd ? 'fc-end' : 'fc-not-end' 7919 ].concat(seg.eventRange.ui.classNames); 7920 if (isDraggable) { 7921 classes.push('fc-draggable'); 7922 } 7923 if (isResizable) { 7924 classes.push('fc-resizable'); 7925 } 7926 if (mirrorInfo) { 7927 classes.push('fc-mirror'); 7928 if (mirrorInfo.isDragging) { 7929 classes.push('fc-dragging'); 7930 } 7931 if (mirrorInfo.isResizing) { 7932 classes.push('fc-resizing'); 7933 } 7934 } 7935 return classes; 7936 }; 7937 // Compute the text that should be displayed on an event's element. 7938 // `range` can be the Event object itself, or something range-like, with at least a `start`. 7939 // If event times are disabled, or the event has no time, will return a blank string. 7940 // If not specified, formatter will default to the eventTimeFormat setting, 7941 // and displayEnd will default to the displayEventEnd setting. 7942 FgEventRenderer.prototype.getTimeText = function (eventRange, formatter, displayEnd) { 7943 var def = eventRange.def, instance = eventRange.instance; 7944 return this._getTimeText(instance.range.start, def.hasEnd ? instance.range.end : null, def.allDay, formatter, displayEnd, instance.forcedStartTzo, instance.forcedEndTzo); 7945 }; 7946 FgEventRenderer.prototype._getTimeText = function (start, end, allDay, formatter, displayEnd, forcedStartTzo, forcedEndTzo) { 7947 var dateEnv = this.context.dateEnv; 7948 if (formatter == null) { 7949 formatter = this.eventTimeFormat; 7950 } 7951 if (displayEnd == null) { 7952 displayEnd = this.displayEventEnd; 7953 } 7954 if (this.displayEventTime && !allDay) { 7955 if (displayEnd && end) { 7956 return dateEnv.formatRange(start, end, formatter, { 7957 forcedStartTzo: forcedStartTzo, 7958 forcedEndTzo: forcedEndTzo 7959 }); 7960 } 7961 else { 7962 return dateEnv.format(start, formatter, { 7963 forcedTzo: forcedStartTzo 7964 }); 7965 } 7966 } 7967 return ''; 7968 }; 7969 FgEventRenderer.prototype.computeEventTimeFormat = function () { 7970 return { 7971 hour: 'numeric', 7972 minute: '2-digit', 7973 omitZeroMinute: true 7974 }; 7975 }; 7976 FgEventRenderer.prototype.computeDisplayEventTime = function () { 7977 return true; 7978 }; 7979 FgEventRenderer.prototype.computeDisplayEventEnd = function () { 7980 return true; 7981 }; 7982 // Utility for generating event skin-related CSS properties 7983 FgEventRenderer.prototype.getSkinCss = function (ui) { 7984 return { 7985 'background-color': ui.backgroundColor, 7986 'border-color': ui.borderColor, 7987 color: ui.textColor 7988 }; 7989 }; 7990 FgEventRenderer.prototype.sortEventSegs = function (segs) { 7991 var specs = this.context.view.eventOrderSpecs; 7992 var objs = segs.map(buildSegCompareObj); 7993 objs.sort(function (obj0, obj1) { 7994 return compareByFieldSpecs(obj0, obj1, specs); 7995 }); 7996 return objs.map(function (c) { 7997 return c._seg; 7998 }); 7999 }; 8000 FgEventRenderer.prototype.computeSizes = function (force) { 8001 if (force || this.isSizeDirty) { 8002 this.computeSegSizes(this.segs); 8003 } 8004 }; 8005 FgEventRenderer.prototype.assignSizes = function (force) { 8006 if (force || this.isSizeDirty) { 8007 this.assignSegSizes(this.segs); 8008 this.isSizeDirty = false;
8009 } 8010 }; 8011 FgEventRenderer.prototype.computeSegSizes = function (segs) { 8012 }; 8013 FgEventRenderer.prototype.assignSegSizes = function (segs) { 8014 }; 8015 // Manipulation on rendered segs 8016 FgEventRenderer.prototype.hideByHash = function (hash) { 8017 if (hash) { 8018 for (var _i = 0, _a = this.segs; _i < _a.length; _i++) { 8019 var seg = _a[_i]; 8020 if (hash[seg.eventRange.instance.instanceId]) { 8021 seg.el.style.visibility = 'hidden'; 8022 } 8023 } 8024 } 8025 }; 8026 FgEventRenderer.prototype.showByHash = function (hash) { 8027 if (hash) { 8028 for (var _i = 0, _a = this.segs; _i < _a.length; _i++) { 8029 var seg = _a[_i]; 8030 if (hash[seg.eventRange.instance.instanceId]) { 8031 seg.el.style.visibility = ''; 8032 } 8033 } 8034 } 8035 }; 8036 FgEventRenderer.prototype.selectByInstanceId = function (instanceId) { 8037 if (instanceId) { 8038 for (var _i = 0, _a = this.segs; _i < _a.length; _i++) { 8039 var seg = _a[_i]; 8040 var eventInstance = seg.eventRange.instance; 8041 if (eventInstance && eventInstance.instanceId === instanceId && 8042 seg.el // necessary? 8043 ) { 8044 seg.el.classList.add('fc-selected'); 8045 } 8046 } 8047 } 8048 }; 8049 FgEventRenderer.prototype.unselectByInstanceId = function (instanceId) { 8050 if (instanceId) { 8051 for (var _i = 0, _a = this.segs; _i < _a.length; _i++) { 8052 var seg = _a[_i]; 8053 if (seg.el) { // necessary? 8054 seg.el.classList.remove('fc-selected'); 8055 } 8056 } 8057 } 8058 }; 8059 return FgEventRenderer; 8060 }()); 8061 // returns a object with all primitive props that can be compared 8062 function buildSegCompareObj(seg) { 8063 var eventDef = seg.eventRange.def; 8064 var range = seg.eventRange.instance.range; 8065 var start = range.start ? range.start.valueOf() : 0; // TODO: better support for open-range events 8066 var end = range.end ? range.end.valueOf() : 0; // " 8067 return __assign({}, eventDef.extendedProps, eventDef, { id: eventDef.publicId, start: start, 8068 end: end, duration: end - start, allDay: Number(eventDef.allDay), _seg: seg // for later retrieval 8069 }); 8070 } 8071 8072 var FillRenderer = /** @class */ (function () { 8073 function FillRenderer(context) { 8074 this.fillSegTag = 'div'; 8075 this.dirtySizeFlags = {}; 8076 this.context = context; 8077 this.containerElsByType = {}; 8078 this.segsByType = {}; 8079 } 8080 FillRenderer.prototype.getSegsByType = function (type) { 8081 return this.segsByType[type] || []; 8082 }; 8083 FillRenderer.prototype.renderSegs = function (type, segs) { 8084 var _a; 8085 var renderedSegs = this.renderSegEls(type, segs); // assignes `.el` to each seg. returns successfully rendered segs 8086 var containerEls = this.attachSegs(type, renderedSegs); 8087 if (containerEls) { 8088 (_a = (this.containerElsByType[type] || (this.containerElsByType[type] = []))).push.apply(_a, containerEls); 8089 } 8090 this.segsByType[type] = renderedSegs; 8091 if (type === 'bgEvent') { 8092 this.context.view.triggerRenderedSegs(renderedSegs, false); // isMirror=false 8093 } 8094 this.dirtySizeFlags[type] = true; 8095 }; 8096 // Unrenders a specific type of fill that is currently rendered on the grid 8097 FillRenderer.prototype.unrender = function (type) { 8098 var segs = this.segsByType[type]; 8099 if (segs) { 8100 if (type === 'bgEvent') { 8101 this.context.view.triggerWillRemoveSegs(segs, false); // isMirror=false 8102 } 8103 this.detachSegs(type, segs); 8104 } 8105 }; 8106 // Renders and assigns an `el` property for each fill segment. Generic enough to work with different types. 8107 // Only returns segments that successfully rendered.
8108 FillRenderer.prototype.renderSegEls = function (type, segs) { 8109 var _this = this; 8110 var html = ''; 8111 var i; 8112 if (segs.length) { 8113 // build a large concatenation of segment HTML 8114 for (i = 0; i < segs.length; i++) { 8115 html += this.renderSegHtml(type, segs[i]); 8116 } 8117 // Grab individual elements from the combined HTML string. Use each as the default rendering. 8118 // Then, compute the 'el' for each segment. 8119 htmlToElements(html).forEach(function (el, i) { 8120 var seg = segs[i]; 8121 if (el) { 8122 seg.el = el; 8123 } 8124 }); 8125 if (type === 'bgEvent') { 8126 segs = filterSegsViaEls(this.context.view, segs, false // isMirror. background events can never be mirror elements 8127 ); 8128 } 8129 // correct element type? (would be bad if a non-TD were inserted into a table for example) 8130 segs = segs.filter(function (seg) { 8131 return elementMatches(seg.el, _this.fillSegTag); 8132 }); 8133 } 8134 return segs; 8135 }; 8136 // Builds the HTML needed for one fill segment. Generic enough to work with different types. 8137 FillRenderer.prototype.renderSegHtml = function (type, seg) { 8138 var css = null; 8139 var classNames = []; 8140 if (type !== 'highlight' && type !== 'businessHours') { 8141 css = { 8142 'background-color': seg.eventRange.ui.backgroundColor 8143 }; 8144 } 8145 if (type !== 'highlight') { 8146 classNames = classNames.concat(seg.eventRange.ui.classNames); 8147 } 8148 if (type === 'businessHours') { 8149 classNames.push('fc-bgevent'); 8150 } 8151 else { 8152 classNames.push('fc-' + type.toLowerCase()); 8153 } 8154 return '<' + this.fillSegTag + 8155 (classNames.length ? ' class="' + classNames.join(' ') + '"' : '') + 8156 (css ? ' style="' + cssToStr(css) + '"' : '') + 8157 '></' + this.fillSegTag + '>'; 8158 }; 8159 FillRenderer.prototype.detachSegs = function (type, segs) { 8160 var containerEls = this.containerElsByType[type]; 8161 if (containerEls) { 8162 containerEls.forEach(removeElement); 8163 delete this.containerElsByType[type]; 8164 } 8165 }; 8166 FillRenderer.prototype.computeSizes = function (force) { 8167 for (var type in this.segsByType) { 8168 if (force || this.dirtySizeFlags[type]) { 8169 this.computeSegSizes(this.segsByType[type]); 8170 } 8171 } 8172 }; 8173 FillRenderer.prototype.assignSizes = function (force) { 8174 for (var type in this.segsByType) { 8175 if (force || this.dirtySizeFlags[type]) { 8176 this.assignSegSizes(this.segsByType[type]); 8177 } 8178 } 8179 this.dirtySizeFlags = {}; 8180 }; 8181 FillRenderer.prototype.computeSegSizes = function (segs) { 8182 }; 8183 FillRenderer.prototype.assignSegSizes = function (segs) { 8184 }; 8185 return FillRenderer; 8186 }()); 8187 8188 var NamedTimeZoneImpl = /** @class */ (function () { 8189 function NamedTimeZoneImpl(timeZoneName) { 8190 this.timeZoneName = timeZoneName; 8191 } 8192 return NamedTimeZoneImpl; 8193 }()); 8194 8195 /* 8196 An abstraction for a dragging interaction originating on an event. 8197 Does higher-level things than PointerDragger, such as possibly: 8198 - a "mirror" that moves with the pointer 8199 - a minimum number of pixels or other criteria for a true drag to begin 8200 8201 subclasses must emit: 8202 - pointerdown 8203 - dragstart 8204 - dragmove 8205 - pointerup 8206 - dragend 8207 */ 8208 var ElementDragging = /** @class */ (function () { 8209 function ElementDragging(el) { 8210 this.emitter = new EmitterMixin(); 8211 } 8212 ElementDragging.prototype.destroy = function () { 8213 }; 8214 ElementDragging.prototype.setMirrorIsVisible = function (bool) {
8215 // optional if subclass doesn't want to support a mirror 8216 }; 8217 ElementDragging.prototype.setMirrorNeedsRevert = function (bool) { 8218 // optional if subclass doesn't want to support a mirror 8219 }; 8220 ElementDragging.prototype.setAutoScrollEnabled = function (bool) { 8221 // optional 8222 }; 8223 return ElementDragging; 8224 }()); 8225 8226 function formatDate(dateInput, settings) { 8227 if (settings === void 0) { settings = {}; } 8228 var dateEnv = buildDateEnv$1(settings); 8229 var formatter = createFormatter(settings); 8230 var dateMeta = dateEnv.createMarkerMeta(dateInput); 8231 if (!dateMeta) { // TODO: warning? 8232 return ''; 8233 } 8234 return dateEnv.format(dateMeta.marker, formatter, { 8235 forcedTzo: dateMeta.forcedTzo 8236 }); 8237 } 8238 function formatRange(startInput, endInput, settings // mixture of env and formatter settings 8239 ) { 8240 var dateEnv = buildDateEnv$1(typeof settings === 'object' && settings ? settings : {}); // pass in if non-null object 8241 var formatter = createFormatter(settings, globalDefaults.defaultRangeSeparator); 8242 var startMeta = dateEnv.createMarkerMeta(startInput); 8243 var endMeta = dateEnv.createMarkerMeta(endInput); 8244 if (!startMeta || !endMeta) { // TODO: warning? 8245 return ''; 8246 } 8247 return dateEnv.formatRange(startMeta.marker, endMeta.marker, formatter, { 8248 forcedStartTzo: startMeta.forcedTzo, 8249 forcedEndTzo: endMeta.forcedTzo, 8250 isEndExclusive: settings.isEndExclusive 8251 }); 8252 } 8253 // TODO: more DRY and optimized 8254 function buildDateEnv$1(settings) { 8255 var locale = buildLocale(settings.locale || 'en', parseRawLocales([]).map); // TODO: don't hardcode 'en' everywhere 8256 // ensure required settings 8257 settings = __assign({ timeZone: globalDefaults.timeZone, calendarSystem: 'gregory' }, settings, { locale: locale }); 8258 return new DateEnv(settings); 8259 } 8260 8261 var DRAG_META_PROPS = { 8262 startTime: createDuration, 8263 duration: createDuration, 8264 create: Boolean, 8265 sourceId: String 8266 }; 8267 var DRAG_META_DEFAULTS = { 8268 create: true 8269 }; 8270 function parseDragMeta(raw) { 8271 var leftoverProps = {}; 8272 var refined = refineProps(raw, DRAG_META_PROPS, DRAG_META_DEFAULTS, leftoverProps); 8273 refined.leftoverProps = leftoverProps; 8274 return refined; 8275 } 8276 8277 // Computes a default column header formatting string if `colFormat` is not explicitly defined 8278 function computeFallbackHeaderFormat(datesRepDistinctDays, dayCnt) { 8279 // if more than one week row, or if there are a lot of columns with not much space, 8280 // put just the day numbers will be in each cell 8281 if (!datesRepDistinctDays || dayCnt > 10) { 8282 return { weekday: 'short' }; // "Sat" 8283 } 8284 else if (dayCnt > 1) { 8285 return { weekday: 'short', month: 'numeric', day: 'numeric', omitCommas: true }; // "Sat 11/12" 8286 } 8287 else { 8288 return { weekday: 'long' }; // "Saturday" 8289 } 8290 } 8291 function renderDateCell(dateMarker, dateProfile, datesRepDistinctDays, colCnt, colHeadFormat, context, colspan, otherAttrs) { 8292 var view = context.view, dateEnv = context.dateEnv, theme = context.theme, options = context.options; 8293 var isDateValid = rangeContainsMarker(dateProfile.activeRange, dateMarker); // TODO: called too frequently. cache somehow. 8294 var classNames = [ 8295 'fc-day-header', 8296 theme.getClass('widgetHeader') 8297 ]; 8298 var innerHtml; 8299 if (typeof options.columnHeaderHtml === 'function') { 8300 innerHtml = options.columnHeaderHtml(dateEnv.toDate(dateMarker)); 8301 } 8302 else if (typeof options.columnHeaderText === 'function') { 8303 innerHtml = htmlEscape(options.columnHeaderText(dateEnv.toDate(dateMarker))); 8304 } 8305 else { 8306 innerHtml = htmlEscape(dateEnv.format(dateMarker, colHeadFormat)); 8307 } 8308 // if only one row of days, the classNames on the header can represent the specific days beneath 8309 if (datesRepDistinctDays) {
8310 classNames = classNames.concat( 8311 // includes the day-of-week class 8312 // noThemeHighlight=true (don't highlight the header) 8313 getDayClasses(dateMarker, dateProfile, context, true)); 8314 } 8315 else { 8316 classNames.push('fc-' + DAY_IDS[dateMarker.getUTCDay()]); // only add the day-of-week class 8317 } 8318 return '' + 8319 '<th class="' + classNames.join(' ') + '"' + 8320 ((isDateValid && datesRepDistinctDays) ? 8321 ' data-date="' + dateEnv.formatIso(dateMarker, { omitTime: true }) + '"' : 8322 '') + 8323 (colspan > 1 ? 8324 ' colspan="' + colspan + '"' : 8325 '') + 8326 (otherAttrs ? 8327 ' ' + otherAttrs : 8328 '') + 8329 '>' + 8330 (isDateValid ? 8331 // don't make a link if the heading could represent multiple days, or if there's only one day (forceOff) 8332 buildGotoAnchorHtml(view, { date: dateMarker, forceOff: !datesRepDistinctDays || colCnt === 1 }, innerHtml) : 8333 // if not valid, display text, but no link 8334 innerHtml) + 8335 '</th>'; 8336 } 8337 8338 var DayHeader = /** @class */ (function (_super) { 8339 __extends(DayHeader, _super); 8340 function DayHeader(context, parentEl) { 8341 var _this = _super.call(this, context) || this; 8342 parentEl.innerHTML = ''; // because might be nbsp 8343 parentEl.appendChild(_this.el = htmlToElement('<div class="fc-row ' + _this.theme.getClass('headerRow') + '">' + 8344 '<table class="' + _this.theme.getClass('tableGrid') + '">' + 8345 '<thead></thead>' + 8346 '</table>' + 8347 '</div>')); 8348 _this.thead = _this.el.querySelector('thead'); 8349 return _this; 8350 } 8351 DayHeader.prototype.destroy = function () { 8352 removeElement(this.el); 8353 }; 8354 DayHeader.prototype.render = function (props) { 8355 var dates = props.dates, datesRepDistinctDays = props.datesRepDistinctDays; 8356 var parts = []; 8357 if (props.renderIntroHtml) { 8358 parts.push(props.renderIntroHtml()); 8359 } 8360 var colHeadFormat = createFormatter(this.opt('columnHeaderFormat') || 8361 computeFallbackHeaderFormat(datesRepDistinctDays, dates.length)); 8362 for (var _i = 0, dates_1 = dates; _i < dates_1.length; _i++) { 8363 var date = dates_1[_i]; 8364 parts.push(renderDateCell(date, props.dateProfile, datesRepDistinctDays, dates.length, colHeadFormat, this.context)); 8365 } 8366 if (this.isRtl) { 8367 parts.reverse(); 8368 } 8369 this.thead.innerHTML = '<tr>' + parts.join('') + '</tr>'; 8370 }; 8371 return DayHeader; 8372 }(Component)); 8373 8374 var DaySeries = /** @class */ (function () { 8375 function DaySeries(range, dateProfileGenerator) { 8376 var date = range.start; 8377 var end = range.end; 8378 var indices = []; 8379 var dates = []; 8380 var dayIndex = -1; 8381 while (date < end) { // loop each day from start to end 8382 if (dateProfileGenerator.isHiddenDay(date)) { 8383 indices.push(dayIndex + 0.5); // mark that it's between indices 8384 } 8385 else { 8386 dayIndex++; 8387 indices.push(dayIndex); 8388 dates.push(date); 8389 } 8390 date = addDays(date, 1); 8391 } 8392 this.dates = dates; 8393 this.indices = indices; 8394 this.cnt = dates.length; 8395 } 8396 DaySeries.prototype.sliceRange = function (range) { 8397 var firstIndex = this.getDateDayIndex(range.start); // inclusive first index 8398 var lastIndex = this.getDateDayIndex(addDays(range.end, -1)); // inclusive last index 8399 var clippedFirstIndex = Math.max(0, firstIndex); 8400 var clippedLastIndex = Math.min(this.cnt - 1, lastIndex); 8401 // deal with in-between indices 8402 clippedFirstIndex = Math.ceil(clippedFirstIndex); // in-between starts round to next cell 8403 clippedLastIndex = Math.floor(clippedLastIndex); // in-between ends round to prev cell 8404 if (clippedFirstIndex <= clippedLastIndex) { 8405 return { 8406 firstIndex: clippedFirstIndex, 8407 lastIndex: clippedLastIndex, 8408 isStart: firstIndex === clippedFirstIndex, 8409 isEnd: lastIndex === clippedLastIndex 8410 }; 8411 } 8412 else { 8413 return null; 8414 } 8415 }; 8416 // Given a date, returns its chronolocial cell-index from the first cell of the grid. 8417 // If the date lies between cells (because of hiddenDays), returns a floating-point value between offsets. 8418 // If before the first offset, returns a negative number. 8419 // If after the last offset, returns an offset past the last cell offset. 8420 // Only works for *start* dates of cells. Will not work for exclusive end dates for cells. 8421 DaySeries.prototype.getDateDayIndex = function (date) { 8422 var indices = this.indices; 8423 var dayOffset = Math.floor(diffDays(this.dates[0], date)); 8424 if (dayOffset < 0) {
8425 return indices[0] - 1; 8426 } 8427 else if (dayOffset >= indices.length) { 8428 return indices[indices.length - 1] + 1; 8429 } 8430 else { 8431 return indices[dayOffset]; 8432 } 8433 }; 8434 return DaySeries; 8435 }()); 8436 8437 var DayTable = /** @class */ (function () { 8438 function DayTable(daySeries, breakOnWeeks) { 8439 var dates = daySeries.dates; 8440 var daysPerRow; 8441 var firstDay; 8442 var rowCnt; 8443 if (breakOnWeeks) { 8444 // count columns until the day-of-week repeats 8445 firstDay = dates[0].getUTCDay(); 8446 for (daysPerRow = 1; daysPerRow < dates.length; daysPerRow++) { 8447 if (dates[daysPerRow].getUTCDay() === firstDay) { 8448 break; 8449 } 8450 } 8451 rowCnt = Math.ceil(dates.length / daysPerRow); 8452 } 8453 else { 8454 rowCnt = 1; 8455 daysPerRow = dates.length; 8456 } 8457 this.rowCnt = rowCnt; 8458 this.colCnt = daysPerRow; 8459 this.daySeries = daySeries; 8460 this.cells = this.buildCells(); 8461 this.headerDates = this.buildHeaderDates(); 8462 } 8463 DayTable.prototype.buildCells = function () { 8464 var rows = []; 8465 for (var row = 0; row < this.rowCnt; row++) { 8466 var cells = []; 8467 for (var col = 0; col < this.colCnt; col++) { 8468 cells.push(this.buildCell(row, col)); 8469 } 8470 rows.push(cells); 8471 } 8472 return rows; 8473 }; 8474 DayTable.prototype.buildCell = function (row, col) { 8475 return { 8476 date: this.daySeries.dates[row * this.colCnt + col] 8477 }; 8478 }; 8479 DayTable.prototype.buildHeaderDates = function () { 8480 var dates = []; 8481 for (var col = 0; col < this.colCnt; col++) { 8482 dates.push(this.cells[0][col].date); 8483 } 8484 return dates; 8485 }; 8486 DayTable.prototype.sliceRange = function (range) { 8487 var colCnt = this.colCnt; 8488 var seriesSeg = this.daySeries.sliceRange(range); 8489 var segs = []; 8490 if (seriesSeg) { 8491 var firstIndex = seriesSeg.firstIndex, lastIndex = seriesSeg.lastIndex; 8492 var index = firstIndex; 8493 while (index <= lastIndex) { 8494 var row = Math.floor(index / colCnt); 8495 var nextIndex = Math.min((row + 1) * colCnt, lastIndex + 1); 8496 segs.push({ 8497 row: row, 8498 firstCol: index % colCnt, 8499 lastCol: (nextIndex - 1) % colCnt, 8500 isStart: seriesSeg.isStart && index === firstIndex, 8501 isEnd: seriesSeg.isEnd && (nextIndex - 1) === lastIndex 8502 }); 8503 index = nextIndex; 8504 } 8505 } 8506 return segs; 8507 }; 8508 return DayTable; 8509 }()); 8510 8511 var Slicer = /** @class */ (function () { 8512 function Slicer() { 8513 this.sliceBusinessHours = memoize(this._sliceBusinessHours); 8514 this.sliceDateSelection = memoize(this._sliceDateSpan); 8515 this.sliceEventStore = memoize(this._sliceEventStore); 8516 this.sliceEventDrag = memoize(this._sliceInteraction); 8517 this.sliceEventResize = memoize(this._sliceInteraction); 8518 } 8519 Slicer.prototype.sliceProps = function (props, dateProfile, nextDayThreshold, component) { 8520 var extraArgs = []; 8521 for (var _i = 4; _i < arguments.length; _i++) { 8522 extraArgs[_i - 4] = arguments[_i]; 8523 } 8524 var eventUiBases = props.eventUiBases; 8525 var eventSegs = this.sliceEventStore.apply(this, [props.eventStore, eventUiBases, dateProfile, nextDayThreshold, component].concat(extraArgs)); 8526 return { 8527 dateSelectionSegs: this.sliceDateSelection.apply(this, [props.dateSelection, eventUiBases, component].concat(extraArgs)), 8528 businessHourSegs: this.sliceBusinessHours.apply(this, [props.businessHours, dateProfile, nextDayThreshold, component].concat(extraArgs)), 8529 fgEventSegs: eventSegs.fg, 8530 bgEventSegs: eventSegs.bg, 8531 eventDrag: this.sliceEventDrag.apply(this, [props.eventDrag, eventUiBases, dateProfile, nextDayThreshold, component].concat(extraArgs)), 8532 eventResize: this.sliceEventResize.apply(this, [props.eventResize, eventUiBases, dateProfile, nextDayThreshold, component].concat(extraArgs)), 8533 eventSelection: props.eventSelection 8534 }; // TODO: give interactionSegs? 8535 }; 8536 Slicer.prototype.sliceNowDate = function (// does not memoize 8537 date, component) { 8538 var extraArgs = []; 8539 for (var _i = 2; _i < arguments.length; _i++) { 8540 extraArgs[_i - 2] = arguments[_i]; 8541 } 8542 return this._sliceDateSpan.apply(this, [{ range: { start: date, end: addMs(date, 1) }, allDay: false }, 8543 {}, 8544 component].concat(extraArgs)); 8545 }; 8546 Slicer.prototype._sliceBusinessHours = function (businessHours, dateProfile, nextDayThreshold, component) { 8547 var extraArgs = []; 8548 for (var _i = 4; _i < arguments.length; _i++) { 8549 extraArgs[_i - 4] = arguments[_i]; 8550 } 8551 if (!businessHours) { 8552 return []; 8553 } 8554 return this._sliceEventStore.apply(this, [expandRecurring(businessHours, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), component.calendar), 8555 {}, 8556 dateProfile, 8557 nextDayThreshold, 8558 component].concat(extraArgs)).bg; 8559 }; 8560 Slicer.prototype._sliceEventStore = function (eventStore, eventUiBases, dateProfile, nextDayThreshold, component) { 8561 var extraArgs = []; 8562 for (var _i = 5; _i < arguments.length; _i++) { 8563 extraArgs[_i - 5] = arguments[_i]; 8564 } 8565 if (eventStore) { 8566 var rangeRes = sliceEventStore(eventStore, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold); 8567 return { 8568 bg: this.sliceEventRanges(rangeRes.bg, component, extraArgs), 8569 fg: this.sliceEventRanges(rangeRes.fg, component, extraArgs) 8570 }; 8571 } 8572 else { 8573 return { bg: [], fg: [] }; 8574 } 8575 }; 8576 Slicer.prototype._sliceInteraction = function (interaction, eventUiBases, dateProfile, nextDayThreshold, component) { 8577 var extraArgs = []; 8578 for (var _i = 5; _i < arguments.length; _i++) { 8579 extraArgs[_i - 5] = arguments[_i]; 8580 } 8581 if (!interaction) { 8582 return null; 8583 } 8584 var rangeRes = sliceEventStore(interaction.mutatedEvents, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold); 8585 return { 8586 segs: this.sliceEventRanges(rangeRes.fg, component, extraArgs), 8587 affectedInstances: interaction.affectedEvents.instances, 8588 isEvent: interaction.isEvent, 8589 sourceSeg: interaction.origSeg 8590 }; 8591 }; 8592 Slicer.prototype._sliceDateSpan = function (dateSpan, eventUiBases, component) { 8593 var extraArgs = []; 8594 for (var _i = 3; _i < arguments.length; _i++) { 8595 extraArgs[_i - 3] = arguments[_i]; 8596 } 8597 if (!dateSpan) { 8598 return []; 8599 } 8600 var eventRange = fabricateEventRange(dateSpan, eventUiBases, component.calendar); 8601 var segs = this.sliceRange.apply(this, [dateSpan.range].concat(extraArgs)); 8602 for (var _a = 0, segs_1 = segs; _a < segs_1.length; _a++) { 8603 var seg = segs_1[_a]; 8604 seg.component = component; 8605 seg.eventRange = eventRange; 8606 } 8607 return segs; 8608 }; 8609 /* 8610 "complete" seg means it has component and eventRange 8611 */ 8612 Slicer.prototype.sliceEventRanges = function (eventRanges, component, // TODO: kill 8613 extraArgs) { 8614 var segs = []; 8615 for (var _i = 0, eventRanges_1 = eventRanges; _i < eventRanges_1.length; _i++) { 8616 var eventRange = eventRanges_1[_i]; 8617 segs.push.apply(segs, this.sliceEventRange(eventRange, component, extraArgs)); 8618 } 8619 return segs; 8620 }; 8621 /* 8622 "complete" seg means it has component and eventRange 8623 */ 8624 Slicer.prototype.sliceEventRange = function (eventRange, component, // TODO: kill 8625 extraArgs) { 8626 var segs = this.sliceRange.apply(this, [eventRange.range].concat(extraArgs)); 8627 for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) { 8628 var seg = segs_2[_i]; 8629 seg.component = component; 8630 seg.eventRange = eventRange; 8631 seg.isStart = eventRange.isStart && seg.isStart; 8632 seg.isEnd = eventRange.isEnd && seg.isEnd; 8633 } 8634 return segs; 8635 }; 8636 return Slicer; 8637 }()); 8638 /* 8639 for incorporating minTime/maxTime if appropriate 8640 TODO: should be part of DateProfile! 8641 TimelineDateProfile already does this btw 8642 */ 8643 function computeActiveRange(dateProfile, isComponentAllDay) { 8644 var range = dateProfile.activeRange; 8645 if (isComponentAllDay) { 8646 return range; 8647 } 8648 return { 8649 start: addMs(range.start, dateProfile.minTime.milliseconds), 8650 end: addMs(range.end, dateProfile.maxTime.milliseconds - 864e5) // 864e5 = ms in a day 8651 }; 8652 } 8653 8654 // exports 8655 // -------------------------------------------------------------------------------------------------- 8656 var version = '4.3.1'; 8657 8658 exports.Calendar = Calendar; 8659 exports.Component = Component; 8660 exports.DateComponent = DateComponent; 8661 exports.DateEnv = DateEnv; 8662 exports.DateProfileGenerator = DateProfileGenerator; 8663 exports.DayHeader = DayHeader; 8664 exports.DaySeries = DaySeries; 8665 exports.DayTable = DayTable; 8666 exports.ElementDragging = ElementDragging; 8667 exports.ElementScrollController = ElementScrollController; 8668 exports.EmitterMixin = EmitterMixin; 8669 exports.EventApi = EventApi; 8670 exports.FgEventRenderer = FgEventRenderer;
8671 exports.FillRenderer = FillRenderer; 8672 exports.Interaction = Interaction; 8673 exports.Mixin = Mixin; 8674 exports.NamedTimeZoneImpl = NamedTimeZoneImpl; 8675 exports.PositionCache = PositionCache; 8676 exports.ScrollComponent = ScrollComponent; 8677 exports.ScrollController = ScrollController; 8678 exports.Slicer = Slicer; 8679 exports.Splitter = Splitter; 8680 exports.Theme = Theme; 8681 exports.View = View; 8682 exports.WindowScrollController = WindowScrollController; 8683 exports.addDays = addDays; 8684 exports.addDurations = addDurations; 8685 exports.addMs = addMs; 8686 exports.addWeeks = addWeeks; 8687 exports.allowContextMenu = allowContextMenu; 8688 exports.allowSelection = allowSelection; 8689 exports.appendToElement = appendToElement; 8690 exports.applyAll = applyAll; 8691 exports.applyMutationToEventStore = applyMutationToEventStore; 8692 exports.applyStyle = applyStyle; 8693 exports.applyStyleProp = applyStyleProp; 8694 exports.asRoughMinutes = asRoughMinutes; 8695 exports.asRoughMs = asRoughMs; 8696 exports.asRoughSeconds = asRoughSeconds; 8697 exports.buildGotoAnchorHtml = buildGotoAnchorHtml; 8698 exports.buildSegCompareObj = buildSegCompareObj; 8699 exports.capitaliseFirstLetter = capitaliseFirstLetter; 8700 exports.combineEventUis = combineEventUis; 8701 exports.compareByFieldSpec = compareByFieldSpec; 8702 exports.compareByFieldSpecs = compareByFieldSpecs; 8703 exports.compareNumbers = compareNumbers; 8704 exports.compensateScroll = compensateScroll; 8705 exports.computeClippingRect = computeClippingRect; 8706 exports.computeEdges = computeEdges; 8707 exports.computeFallbackHeaderFormat = computeFallbackHeaderFormat; 8708 exports.computeHeightAndMargins = computeHeightAndMargins; 8709 exports.computeInnerRect = computeInnerRect; 8710 exports.computeRect = computeRect; 8711 exports.computeVisibleDayRange = computeVisibleDayRange; 8712 exports.config = config; 8713 exports.constrainPoint = constrainPoint; 8714 exports.createDuration = createDuration; 8715 exports.createElement = createElement; 8716 exports.createEmptyEventStore = createEmptyEventStore; 8717 exports.createEventInstance = createEventInstance; 8718 exports.createFormatter = createFormatter; 8719 exports.createPlugin = createPlugin; 8720 exports.cssToStr = cssToStr; 8721 exports.debounce = debounce; 8722 exports.diffDates = diffDates; 8723 exports.diffDayAndTime = diffDayAndTime; 8724 exports.diffDays = diffDays; 8725 exports.diffPoints = diffPoints; 8726 exports.diffWeeks = diffWeeks; 8727 exports.diffWholeDays = diffWholeDays; 8728 exports.diffWholeWeeks = diffWholeWeeks; 8729 exports.disableCursor = disableCursor; 8730 exports.distributeHeight = distributeHeight; 8731 exports.elementClosest = elementClosest; 8732 exports.elementMatches = elementMatches; 8733 exports.enableCursor = enableCursor; 8734 exports.eventTupleToStore = eventTupleToStore; 8735 exports.filterEventStoreDefs = filterEventStoreDefs; 8736 exports.filterHash = filterHash; 8737 exports.findChildren = findChildren; 8738 exports.findElements = findElements; 8739 exports.flexibleCompare = flexibleCompare; 8740 exports.forceClassName = forceClassName; 8741 exports.formatDate = formatDate; 8742 exports.formatIsoTimeString = formatIsoTimeString; 8743 exports.formatRange = formatRange; 8744 exports.getAllDayHtml = getAllDayHtml; 8745 exports.getClippingParents = getClippingParents; 8746 exports.getDayClasses = getDayClasses; 8747 exports.getElSeg = getElSeg; 8748 exports.getRectCenter = getRectCenter; 8749 exports.getRelevantEvents = getRelevantEvents; 8750 exports.globalDefaults = globalDefaults; 8751 exports.greatestDurationDenominator = greatestDurationDenominator; 8752 exports.hasBgRendering = hasBgRendering; 8753 exports.htmlEscape = htmlEscape; 8754 exports.htmlToElement = htmlToElement; 8755 exports.insertAfterElement = insertAfterElement; 8756 exports.interactionSettingsStore = interactionSettingsStore; 8757 exports.interactionSettingsToStore = interactionSettingsToStore; 8758 exports.intersectRanges = intersectRanges; 8759 exports.intersectRects = intersectRects; 8760 exports.isArraysEqual = isArraysEqual; 8761 exports.isDateSpansEqual = isDateSpansEqual; 8762 exports.isInt = isInt; 8763 exports.isInteractionValid = isInteractionValid; 8764 exports.isMultiDayRange = isMultiDayRange; 8765 exports.isPropsEqual = isPropsEqual; 8766 exports.isPropsValid = isPropsValid; 8767 exports.isSingleDay = isSingleDay; 8768 exports.isValidDate = isValidDate; 8769 exports.listenBySelector = listenBySelector; 8770 exports.mapHash = mapHash;
8771 exports.matchCellWidths = matchCellWidths; 8772 exports.memoize = memoize; 8773 exports.memoizeOutput = memoizeOutput; 8774 exports.memoizeRendering = memoizeRendering; 8775 exports.mergeEventStores = mergeEventStores; 8776 exports.multiplyDuration = multiplyDuration; 8777 exports.padStart = padStart; 8778 exports.parseBusinessHours = parseBusinessHours; 8779 exports.parseDragMeta = parseDragMeta; 8780 exports.parseEventDef = parseEventDef; 8781 exports.parseFieldSpecs = parseFieldSpecs; 8782 exports.parseMarker = parse; 8783 exports.pointInsideRect = pointInsideRect; 8784 exports.prependToElement = prependToElement; 8785 exports.preventContextMenu = preventContextMenu; 8786 exports.preventDefault = preventDefault; 8787 exports.preventSelection = preventSelection; 8788 exports.processScopedUiProps = processScopedUiProps; 8789 exports.rangeContainsMarker = rangeContainsMarker; 8790 exports.rangeContainsRange = rangeContainsRange; 8791 exports.rangesEqual = rangesEqual; 8792 exports.rangesIntersect = rangesIntersect; 8793 exports.refineProps = refineProps; 8794 exports.removeElement = removeElement; 8795 exports.removeExact = removeExact; 8796 exports.renderDateCell = renderDateCell; 8797 exports.requestJson = requestJson; 8798 exports.sliceEventStore = sliceEventStore; 8799 exports.startOfDay = startOfDay; 8800 exports.subtractInnerElHeight = subtractInnerElHeight; 8801 exports.translateRect = translateRect; 8802 exports.uncompensateScroll = uncompensateScroll; 8803 exports.undistributeHeight = undistributeHeight; 8804 exports.unpromisify = unpromisify; 8805 exports.version = version; 8806 exports.whenTransitionDone = whenTransitionDone; 8807 exports.wholeDivideDurations = wholeDivideDurations; 8808 8809 Object.defineProperty(exports, '__esModule', { value: true }); 8810 8811})); 8812 8813},{}],3:[function(require,module,exports){ 8814/*! 8815FullCalendar Day Grid Plugin v4.3.0 8816Docs & License: https://fullcalendar.io/ 8817(c) 2019 Adam Shaw 8818*/ 8819 8820(function (global, factory) { 8821 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core')) : 8822 typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core'], factory) : 8823 (global = global || self, factory(global.FullCalendarDayGrid = {}, global.FullCalendar)); 8824}(this, function (exports, core) { 'use strict'; 8825 8826 /*! ***************************************************************************** 8827 Copyright (c) Microsoft Corporation. All rights reserved. 8828 Licensed under the Apache License, Version 2.0 (the "License"); you may not use 8829 this file except in compliance with the License. You may obtain a copy of the 8830 License at http://www.apache.org/licenses/LICENSE-2.0 8831 8832 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 8833 KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 8834 WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 8835 MERCHANTABLITY OR NON-INFRINGEMENT. 8836 8837 See the Apache Version 2.0 License for specific language governing permissions 8838 and limitations under the License. 8839 ***************************************************************************** */ 8840 /* global Reflect, Promise */ 8841 8842 var extendStatics = function(d, b) { 8843 extendStatics = Object.setPrototypeOf || 8844 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 8845 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; 8846 return extendStatics(d, b); 8847 }; 8848 8849 function __extends(d, b) { 8850 extendStatics(d, b); 8851 function __() { this.constructor = d; } 8852 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 8853 } 8854 8855 var __assign = function() { 8856 __assign = Object.assign || function __assign(t) { 8857 for (var s, i = 1, n = arguments.length; i < n; i++) { 8858 s = arguments[i]; 8859 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 8860 } 8861 return t; 8862 }; 8863 return __assign.apply(this, arguments); 8864 }; 8865 8866 var DayGridDateProfileGenerator = /** @class */ (function (_super) { 8867 __extends(DayGridDateProfileGenerator, _super); 8868 function DayGridDateProfileGenerator() { 8869 return _super !== null && _super.apply(this, arguments) || this; 8870 } 8871 // Computes the date range that will be rendered. 8872 DayGridDateProfileGenerator.prototype.buildRenderRange = function (currentRange, currentRangeUnit, isRangeAllDay) { 8873 var dateEnv = this.dateEnv; 8874 var renderRange = _super.prototype.buildRenderRange.call(this, currentRange, currentRangeUnit, isRangeAllDay); 8875 var start = renderRange.start; 8876 var end = renderRange.end; 8877 var endOfWeek; 8878 // year and month views should be aligned with weeks. this is already done for week 8879 if (/^(year|month)$/.test(currentRangeUnit)) { 8880 start = dateEnv.startOfWeek(start); 8881 // make end-of-week if not already 8882 endOfWeek = dateEnv.startOfWeek(end); 8883 if (endOfWeek.valueOf() !== end.valueOf()) { 8884 end = core.addWeeks(endOfWeek, 1); 8885 } 8886 } 8887 // ensure 6 weeks 8888 if (this.options.monthMode && 8889 this.options.fixedWeekCount) {
8890 var rowCnt = Math.ceil(// could be partial weeks due to hiddenDays 8891 core.diffWeeks(start, end)); 8892 end = core.addWeeks(end, 6 - rowCnt); 8893 } 8894 return { start: start, end: end }; 8895 }; 8896 return DayGridDateProfileGenerator; 8897 }(core.DateProfileGenerator)); 8898 8899 /* A rectangular panel that is absolutely positioned over other content 8900 ------------------------------------------------------------------------------------------------------------------------ 8901 Options: 8902 - className (string) 8903 - content (HTML string, element, or element array) 8904 - parentEl 8905 - top 8906 - left 8907 - right (the x coord of where the right edge should be. not a "CSS" right) 8908 - autoHide (boolean) 8909 - show (callback) 8910 - hide (callback) 8911 */ 8912 var Popover = /** @class */ (function () { 8913 function Popover(options) { 8914 var _this = this; 8915 this.isHidden = true; 8916 this.margin = 10; // the space required between the popover and the edges of the scroll container 8917 // Triggered when the user clicks *anywhere* in the document, for the autoHide feature 8918 this.documentMousedown = function (ev) { 8919 // only hide the popover if the click happened outside the popover 8920 if (_this.el && !_this.el.contains(ev.target)) { 8921 _this.hide(); 8922 } 8923 }; 8924 this.options = options; 8925 } 8926 // Shows the popover on the specified position. Renders it if not already 8927 Popover.prototype.show = function () { 8928 if (this.isHidden) { 8929 if (!this.el) { 8930 this.render(); 8931 } 8932 this.el.style.display = ''; 8933 this.position(); 8934 this.isHidden = false; 8935 this.trigger('show'); 8936 } 8937 }; 8938 // Hides the popover, through CSS, but does not remove it from the DOM 8939 Popover.prototype.hide = function () { 8940 if (!this.isHidden) { 8941 this.el.style.display = 'none'; 8942 this.isHidden = true; 8943 this.trigger('hide'); 8944 } 8945 }; 8946 // Creates `this.el` and renders content inside of it 8947 Popover.prototype.render = function () { 8948 var _this = this; 8949 var options = this.options; 8950 var el = this.el = core.createElement('div', { 8951 className: 'fc-popover ' + (options.className || ''), 8952 style: { 8953 top: '0', 8954 left: '0' 8955 } 8956 }); 8957 if (typeof options.content === 'function') { 8958 options.content(el); 8959 } 8960 options.parentEl.appendChild(el); 8961 // when a click happens on anything inside with a 'fc-close' className, hide the popover 8962 core.listenBySelector(el, 'click', '.fc-close', function (ev) { 8963 _this.hide(); 8964 }); 8965 if (options.autoHide) { 8966 document.addEventListener('mousedown', this.documentMousedown); 8967 } 8968 }; 8969 // Hides and unregisters any handlers 8970 Popover.prototype.destroy = function () { 8971 this.hide(); 8972 if (this.el) { 8973 core.removeElement(this.el); 8974 this.el = null; 8975 } 8976 document.removeEventListener('mousedown', this.documentMousedown); 8977 }; 8978 // Positions the popover optimally, using the top/left/right options 8979 Popover.prototype.position = function () { 8980 var options = this.options; 8981 var el = this.el; 8982 var elDims = el.getBoundingClientRect(); // only used for width,height 8983 var origin = core.computeRect(el.offsetParent); 8984 var clippingRect = core.computeClippingRect(options.parentEl); 8985 var top; // the "position" (not "offset") values for the popover 8986 var left; // 8987 // compute top and left 8988 top = options.top || 0; 8989 if (options.left !== undefined) { 8990 left = options.left; 8991 } 8992 else if (options.right !== undefined) { 8993 left = options.right - elDims.width; // derive the left value from the right value 8994 } 8995 else { 8996 left = 0; 8997 } 8998 // constrain to the view port. if constrained by two edges, give precedence to top/left 8999 top = Math.min(top, clippingRect.bottom - elDims.height - this.margin); 9000 top = Math.max(top, clippingRect.top + this.margin); 9001 left = Math.min(left, clippingRect.right - elDims.width - this.margin); 9002 left = Math.max(left, clippingRect.left + this.margin); 9003 core.applyStyle(el, { 9004 top: top - origin.top, 9005 left: left - origin.left 9006 }); 9007 }; 9008 // Triggers a callback. Calls a function in the option hash of the same name. 9009 // Arguments beyond the first `name` are forwarded on. 9010 // TODO: better code reuse for this. Repeat code 9011 // can kill this??? 9012 Popover.prototype.trigger = function (name) { 9013 if (this.options[name]) { 9014 this.options[name].apply(this, Array.prototype.slice.call(arguments, 1)); 9015 } 9016 }; 9017 return Popover; 9018 }()); 9019 9020 /* Event-rendering methods for the DayGrid class 9021 ----------------------------------------------------------------------------------------------------------------------*/ 9022 // "Simple" is bad a name. has nothing to do with SimpleDayGrid 9023 var SimpleDayGridEventRenderer = /** @class */ (function (_super) { 9024 __extends(SimpleDayGridEventRenderer, _super); 9025 function SimpleDayGridEventRenderer() { 9026 return _super !== null && _super.apply(this, arguments) || this; 9027 } 9028 // Builds the HTML to be used for the default element for an individual segment 9029 SimpleDayGridEventRenderer.prototype.renderSegHtml = function (seg, mirrorInfo) { 9030 var _a = this.context, view = _a.view, options = _a.options; 9031 var eventRange = seg.eventRange; 9032 var eventDef = eventRange.def; 9033 var eventUi = eventRange.ui; 9034 var allDay = eventDef.allDay; 9035 var isDraggable = view.computeEventDraggable(eventDef, eventUi); 9036 var isResizableFromStart = allDay && seg.isStart && view.computeEventStartResizable(eventDef, eventUi); 9037 var isResizableFromEnd = allDay && seg.isEnd && view.computeEventEndResizable(eventDef, eventUi);
9038 var classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd, mirrorInfo); 9039 var skinCss = core.cssToStr(this.getSkinCss(eventUi)); 9040 var timeHtml = ''; 9041 var timeText; 9042 var titleHtml; 9043 classes.unshift('fc-day-grid-event', 'fc-h-event'); 9044 // Only display a timed events time if it is the starting segment 9045 if (seg.isStart) { 9046 timeText = this.getTimeText(eventRange); 9047 if (timeText) { 9048 timeHtml = '<span class="fc-time">' + core.htmlEscape(timeText) + '</span>'; 9049 } 9050 } 9051 titleHtml = 9052 '<span class="fc-title">' + 9053 (core.htmlEscape(eventDef.title || '') || ' ') + // we always want one line of height 9054 '</span>'; 9055 return '<a class="' + classes.join(' ') + '"' + 9056 (eventDef.url ? 9057 ' href="' + core.htmlEscape(eventDef.url) + '"' : 9058 '') + 9059 (skinCss ? 9060 ' style="' + skinCss + '"' : 9061 '') + 9062 '>' + 9063 '<div class="fc-content">' + 9064 (options.dir === 'rtl' ? 9065 titleHtml + ' ' + timeHtml : // put a natural space in between 9066 timeHtml + ' ' + titleHtml // 9067 ) + 9068 '</div>' + 9069 (isResizableFromStart ? 9070 '<div class="fc-resizer fc-start-resizer"></div>' : 9071 '') + 9072 (isResizableFromEnd ? 9073 '<div class="fc-resizer fc-end-resizer"></div>' : 9074 '') + 9075 '</a>'; 9076 }; 9077 // Computes a default event time formatting string if `eventTimeFormat` is not explicitly defined 9078 SimpleDayGridEventRenderer.prototype.computeEventTimeFormat = function () { 9079 return { 9080 hour: 'numeric', 9081 minute: '2-digit', 9082 omitZeroMinute: true, 9083 meridiem: 'narrow' 9084 }; 9085 }; 9086 SimpleDayGridEventRenderer.prototype.computeDisplayEventEnd = function () { 9087 return false; // TODO: somehow consider the originating DayGrid's column count 9088 }; 9089 return SimpleDayGridEventRenderer; 9090 }(core.FgEventRenderer)); 9091 9092 /* Event-rendering methods for the DayGrid class 9093 ----------------------------------------------------------------------------------------------------------------------*/ 9094 var DayGridEventRenderer = /** @class */ (function (_super) { 9095 __extends(DayGridEventRenderer, _super); 9096 function DayGridEventRenderer(dayGrid) { 9097 var _this = _super.call(this, dayGrid.context) || this; 9098 _this.dayGrid = dayGrid; 9099 return _this; 9100 } 9101 // Renders the given foreground event segments onto the grid 9102 DayGridEventRenderer.prototype.attachSegs = function (segs, mirrorInfo) { 9103 var rowStructs = this.rowStructs = this.renderSegRows(segs); 9104 // append to each row's content skeleton 9105 this.dayGrid.rowEls.forEach(function (rowNode, i) { 9106 rowNode.querySelector('.fc-content-skeleton > table').appendChild(rowStructs[i].tbodyEl); 9107 }); 9108 // removes the "more.." events popover 9109 if (!mirrorInfo) { 9110 this.dayGrid.removeSegPopover(); 9111 } 9112 }; 9113 // Unrenders all currently rendered foreground event segments 9114 DayGridEventRenderer.prototype.detachSegs = function () { 9115 var rowStructs = this.rowStructs || []; 9116 var rowStruct; 9117 while ((rowStruct = rowStructs.pop())) { 9118 core.removeElement(rowStruct.tbodyEl); 9119 } 9120 this.rowStructs = null; 9121 }; 9122 // Uses the given events array to generate <tbody> elements that should be appended to each row's content skeleton. 9123 // Returns an array of rowStruct objects (see the bottom of `renderSegRow`). 9124 // PRECONDITION: each segment shoud already have a rendered and assigned `.el` 9125 DayGridEventRenderer.prototype.renderSegRows = function (segs) { 9126 var rowStructs = []; 9127 var segRows; 9128 var row; 9129 segRows = this.groupSegRows(segs); // group into nested arrays 9130 // iterate each row of segment groupings 9131 for (row = 0; row < segRows.length; row++) { 9132 rowStructs.push(this.renderSegRow(row, segRows[row])); 9133 } 9134 return rowStructs; 9135 }; 9136 // Given a row # and an array of segments all in the same row, render a <tbody> element, a skeleton that contains 9137 // the segments. Returns object with a bunch of internal data about how the render was calculated. 9138 // NOTE: modifies rowSegs 9139 DayGridEventRenderer.prototype.renderSegRow = function (row, rowSegs) { 9140 var dayGrid = this.dayGrid; 9141 var colCnt = dayGrid.colCnt, isRtl = dayGrid.isRtl; 9142 var segLevels = this.buildSegLevels(rowSegs); // group into sub-arrays of levels 9143 var levelCnt = Math.max(1, segLevels.length); // ensure at least one level 9144 var tbody = document.createElement('tbody'); 9145 var segMatrix = []; // lookup for which segments are rendered into which level+col cells 9146 var cellMatrix = []; // lookup for all <td> elements of the level+col matrix 9147 var loneCellMatrix = []; // lookup for <td> elements that only take up a single column 9148 var i; 9149 var levelSegs; 9150 var col; 9151 var tr; 9152 var j; 9153 var seg; 9154 var td; 9155 // populates empty cells from the current column (`col`) to `endCol` 9156 function emptyCellsUntil(endCol) { 9157 while (col < endCol) { 9158 // try to grab a cell from the level above and extend its rowspan. otherwise, create a fresh cell 9159 td = (loneCellMatrix[i - 1] || [])[col]; 9160 if (td) { 9161 td.rowSpan = (td.rowSpan || 1) + 1; 9162 } 9163 else { 9164 td = document.createElement('td'); 9165 tr.appendChild(td); 9166 } 9167 cellMatrix[i][col] = td; 9168 loneCellMatrix[i][col] = td; 9169 col++; 9170 } 9171 } 9172 for (i = 0; i < levelCnt; i++) { // iterate through all levels 9173 levelSegs = segLevels[i]; 9174 col = 0; 9175 tr = document.createElement('tr'); 9176 segMatrix.push([]); 9177 cellMatrix.push([]); 9178 loneCellMatrix.push([]); 9179 // levelCnt might be 1 even though there are no actual levels. protect against this. 9180 // this single empty row is useful for styling. 9181 if (levelSegs) { 9182 for (j = 0; j < levelSegs.length; j++) { // iterate through segments in level 9183 seg = levelSegs[j]; 9184 var leftCol = isRtl ? (colCnt - 1 - seg.lastCol) : seg.firstCol; 9185 var rightCol = isRtl ? (colCnt - 1 - seg.firstCol) : seg.lastCol; 9186 emptyCellsUntil(leftCol); 9187 // create a container that occupies or more columns. append the event element. 9188 td = core.createElement('td', { className: 'fc-event-container' }, seg.el); 9189 if (leftCol !== rightCol) { 9190 td.colSpan = rightCol - leftCol + 1; 9191 } 9192 else { // a single-column segment 9193 loneCellMatrix[i][col] = td; 9194 } 9195 while (col <= rightCol) { 9196 cellMatrix[i][col] = td; 9197 segMatrix[i][col] = seg; 9198 col++; 9199 } 9200 tr.appendChild(td); 9201 } 9202 } 9203 emptyCellsUntil(colCnt); // finish off the row 9204 var introHtml = dayGrid.renderProps.renderIntroHtml(); 9205 if (introHtml) { 9206 if (dayGrid.isRtl) { 9207 core.appendToElement(tr, introHtml); 9208 } 9209 else { 9210 core.prependToElement(tr, introHtml); 9211 } 9212 } 9213 tbody.appendChild(tr); 9214 } 9215 return { 9216 row: row, 9217 tbodyEl: tbody, 9218 cellMatrix: cellMatrix, 9219 segMatrix: segMatrix, 9220 segLevels: segLevels, 9221 segs: rowSegs 9222 }; 9223 }; 9224 // Stacks a flat array of segments, which are all assumed to be in the same row, into subarrays of vertical levels. 9225 // NOTE: modifies segs 9226 DayGridEventRenderer.prototype.buildSegLevels = function (segs) { 9227 var _a = this.dayGrid, isRtl = _a.isRtl, colCnt = _a.colCnt; 9228 var levels = []; 9229 var i; 9230 var seg; 9231 var j; 9232 // Give preference to elements with certain criteria, so they have 9233 // a chance to be closer to the top. 9234 segs = this.sortEventSegs(segs); 9235 for (i = 0; i < segs.length; i++) { 9236 seg = segs[i]; 9237 // loop through levels, starting with the topmost, until the segment doesn't collide with other segments 9238 for (j = 0; j < levels.length; j++) {
9239 if (!isDaySegCollision(seg, levels[j])) { 9240 break; 9241 } 9242 } 9243 // `j` now holds the desired subrow index 9244 seg.level = j; 9245 seg.leftCol = isRtl ? (colCnt - 1 - seg.lastCol) : seg.firstCol; // for sorting only 9246 seg.rightCol = isRtl ? (colCnt - 1 - seg.firstCol) : seg.lastCol // for sorting only 9247 ; 9248 (levels[j] || (levels[j] = [])).push(seg); 9249 } 9250 // order segments left-to-right. very important if calendar is RTL 9251 for (j = 0; j < levels.length; j++) { 9252 levels[j].sort(compareDaySegCols); 9253 } 9254 return levels; 9255 }; 9256 // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's row 9257 DayGridEventRenderer.prototype.groupSegRows = function (segs) { 9258 var segRows = []; 9259 var i; 9260 for (i = 0; i < this.dayGrid.rowCnt; i++) { 9261 segRows.push([]); 9262 } 9263 for (i = 0; i < segs.length; i++) { 9264 segRows[segs[i].row].push(segs[i]); 9265 } 9266 return segRows; 9267 }; 9268 // Computes a default `displayEventEnd` value if one is not expliclty defined 9269 DayGridEventRenderer.prototype.computeDisplayEventEnd = function () { 9270 return this.dayGrid.colCnt === 1; // we'll likely have space if there's only one day 9271 }; 9272 return DayGridEventRenderer; 9273 }(SimpleDayGridEventRenderer)); 9274 // Computes whether two segments' columns collide. They are assumed to be in the same row. 9275 function isDaySegCollision(seg, otherSegs) { 9276 var i; 9277 var otherSeg; 9278 for (i = 0; i < otherSegs.length; i++) { 9279 otherSeg = otherSegs[i]; 9280 if (otherSeg.firstCol <= seg.lastCol && 9281 otherSeg.lastCol >= seg.firstCol) { 9282 return true; 9283 } 9284 } 9285 return false; 9286 } 9287 // A cmp function for determining the leftmost event 9288 function compareDaySegCols(a, b) { 9289 return a.leftCol - b.leftCol; 9290 } 9291 9292 var DayGridMirrorRenderer = /** @class */ (function (_super) { 9293 __extends(DayGridMirrorRenderer, _super); 9294 function DayGridMirrorRenderer() { 9295 return _super !== null && _super.apply(this, arguments) || this; 9296 } 9297 DayGridMirrorRenderer.prototype.attachSegs = function (segs, mirrorInfo) { 9298 var sourceSeg = mirrorInfo.sourceSeg; 9299 var rowStructs = this.rowStructs = this.renderSegRows(segs); 9300 // inject each new event skeleton into each associated row 9301 this.dayGrid.rowEls.forEach(function (rowNode, row) { 9302 var skeletonEl = core.htmlToElement('<div class="fc-mirror-skeleton"><table></table></div>'); // will be absolutely positioned 9303 var skeletonTopEl; 9304 var skeletonTop; 9305 // If there is an original segment, match the top position. Otherwise, put it at the row's top level 9306 if (sourceSeg && sourceSeg.row === row) { 9307 skeletonTopEl = sourceSeg.el; 9308 } 9309 else { 9310 skeletonTopEl = rowNode.querySelector('.fc-content-skeleton tbody'); 9311 if (!skeletonTopEl) { // when no events 9312 skeletonTopEl = rowNode.querySelector('.fc-content-skeleton table'); 9313 } 9314 } 9315 skeletonTop = skeletonTopEl.getBoundingClientRect().top - 9316 rowNode.getBoundingClientRect().top; // the offsetParent origin 9317 skeletonEl.style.top = skeletonTop + 'px'; 9318 skeletonEl.querySelector('table').appendChild(rowStructs[row].tbodyEl); 9319 rowNode.appendChild(skeletonEl); 9320 }); 9321 }; 9322 return DayGridMirrorRenderer; 9323 }(DayGridEventRenderer)); 9324 9325 var EMPTY_CELL_HTML = '<td style="pointer-events:none"></td>'; 9326 var DayGridFillRenderer = /** @class */ (function (_super) { 9327 __extends(DayGridFillRenderer, _super); 9328 function DayGridFillRenderer(dayGrid) { 9329 var _this = _super.call(this, dayGrid.context) || this; 9330 _this.fillSegTag = 'td'; // override the default tag name 9331 _this.dayGrid = dayGrid; 9332 return _this; 9333 } 9334 DayGridFillRenderer.prototype.renderSegs = function (type, segs) { 9335 // don't render timed background events 9336 if (type === 'bgEvent') { 9337 segs = segs.filter(function (seg) { 9338 return seg.eventRange.def.allDay; 9339 }); 9340 }
9341 _super.prototype.renderSegs.call(this, type, segs); 9342 }; 9343 DayGridFillRenderer.prototype.attachSegs = function (type, segs) { 9344 var els = []; 9345 var i; 9346 var seg; 9347 var skeletonEl; 9348 for (i = 0; i < segs.length; i++) { 9349 seg = segs[i]; 9350 skeletonEl = this.renderFillRow(type, seg); 9351 this.dayGrid.rowEls[seg.row].appendChild(skeletonEl); 9352 els.push(skeletonEl); 9353 } 9354 return els; 9355 }; 9356 // Generates the HTML needed for one row of a fill. Requires the seg's el to be rendered. 9357 DayGridFillRenderer.prototype.renderFillRow = function (type, seg) { 9358 var dayGrid = this.dayGrid; 9359 var colCnt = dayGrid.colCnt, isRtl = dayGrid.isRtl; 9360 var leftCol = isRtl ? (colCnt - 1 - seg.lastCol) : seg.firstCol; 9361 var rightCol = isRtl ? (colCnt - 1 - seg.firstCol) : seg.lastCol; 9362 var startCol = leftCol; 9363 var endCol = rightCol + 1; 9364 var className; 9365 var skeletonEl; 9366 var trEl; 9367 if (type === 'businessHours') { 9368 className = 'bgevent'; 9369 } 9370 else { 9371 className = type.toLowerCase(); 9372 } 9373 skeletonEl = core.htmlToElement('<div class="fc-' + className + '-skeleton">' + 9374 '<table><tr></tr></table>' + 9375 '</div>'); 9376 trEl = skeletonEl.getElementsByTagName('tr')[0]; 9377 if (startCol > 0) { 9378 core.appendToElement(trEl, 9379 // will create (startCol + 1) td's 9380 new Array(startCol + 1).join(EMPTY_CELL_HTML)); 9381 } 9382 seg.el.colSpan = endCol - startCol; 9383 trEl.appendChild(seg.el); 9384 if (endCol < colCnt) { 9385 core.appendToElement(trEl, 9386 // will create (colCnt - endCol) td's 9387 new Array(colCnt - endCol + 1).join(EMPTY_CELL_HTML)); 9388 } 9389 var introHtml = dayGrid.renderProps.renderIntroHtml(); 9390 if (introHtml) { 9391 if (dayGrid.isRtl) { 9392 core.appendToElement(trEl, introHtml); 9393 } 9394 else { 9395 core.prependToElement(trEl, introHtml); 9396 } 9397 } 9398 return skeletonEl; 9399 }; 9400 return DayGridFillRenderer; 9401 }(core.FillRenderer)); 9402 9403 var DayTile = /** @class */ (function (_super) { 9404 __extends(DayTile, _super); 9405 function DayTile(context, el) { 9406 var _this = _super.call(this, context, el) || this; 9407 var eventRenderer = _this.eventRenderer = new DayTileEventRenderer(_this); 9408 var renderFrame = _this.renderFrame = core.memoizeRendering(_this._renderFrame); 9409 _this.renderFgEvents = core.memoizeRendering(eventRenderer.renderSegs.bind(eventRenderer), eventRenderer.unrender.bind(eventRenderer), [renderFrame]); 9410 _this.renderEventSelection = core.memoizeRendering(eventRenderer.selectByInstanceId.bind(eventRenderer), eventRenderer.unselectByInstanceId.bind(eventRenderer), [_this.renderFgEvents]); 9411 _this.renderEventDrag = core.memoizeRendering(eventRenderer.hideByHash.bind(eventRenderer), eventRenderer.showByHash.bind(eventRenderer), [renderFrame]); 9412 _this.renderEventResize = core.memoizeRendering(eventRenderer.hideByHash.bind(eventRenderer), eventRenderer.showByHash.bind(eventRenderer), [renderFrame]); 9413 context.calendar.registerInteractiveComponent(_this, { 9414 el: _this.el, 9415 useEventCenter: false 9416 }); 9417 return _this; 9418 } 9419 DayTile.prototype.render = function (props) { 9420 this.renderFrame(props.date); 9421 this.renderFgEvents(props.fgSegs); 9422 this.renderEventSelection(props.eventSelection); 9423 this.renderEventDrag(props.eventDragInstances); 9424 this.renderEventResize(props.eventResizeInstances); 9425 }; 9426 DayTile.prototype.destroy = function () { 9427 _super.prototype.destroy.call(this); 9428 this.renderFrame.unrender(); // should unrender everything else 9429 this.calendar.unregisterInteractiveComponent(this); 9430 }; 9431 DayTile.prototype._renderFrame = function (date) { 9432 var _a = this, theme = _a.theme, dateEnv = _a.dateEnv; 9433 var title = dateEnv.format(date, core.createFormatter(this.opt('dayPopoverFormat')) // TODO: cache 9434 ); 9435 this.el.innerHTML = 9436 '<div class="fc-header ' + theme.getClass('popoverHeader') + '">' + 9437 '<span class="fc-title">' + 9438 core.htmlEscape(title) + 9439 '</span>' + 9440 '<span class="fc-close ' + theme.getIconClass('close') + '"></span>' + 9441 '</div>' + 9442 '<div class="fc-body ' + theme.getClass('popoverContent') + '">' + 9443 '<div class="fc-event-container"></div>' + 9444 '</div>'; 9445 this.segContainerEl = this.el.querySelector('.fc-event-container'); 9446 }; 9447 DayTile.prototype.queryHit = function (positionLeft, positionTop, elWidth, elHeight) { 9448 var date = this.props.date; // HACK 9449 if (positionLeft < elWidth && positionTop < elHeight) { 9450 return { 9451 component: this, 9452 dateSpan: { 9453 allDay: true, 9454 range: { start: date, end: core.addDays(date, 1) } 9455 }, 9456 dayEl: this.el, 9457 rect: { 9458 left: 0, 9459 top: 0, 9460 right: elWidth, 9461 bottom: elHeight 9462 }, 9463 layer: 1 9464 }; 9465 } 9466 }; 9467 return DayTile; 9468 }(core.DateComponent)); 9469 var DayTileEventRenderer = /** @class */ (function (_super) { 9470 __extends(DayTileEventRenderer, _super); 9471 function DayTileEventRenderer(dayTile) { 9472 var _this = _super.call(this, dayTile.context) || this; 9473 _this.dayTile = dayTile; 9474 return _this; 9475 } 9476 DayTileEventRenderer.prototype.attachSegs = function (segs) { 9477 for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) { 9478 var seg = segs_1[_i]; 9479 this.dayTile.segContainerEl.appendChild(seg.el); 9480 } 9481 }; 9482 DayTileEventRenderer.prototype.detachSegs = function (segs) { 9483 for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) { 9484 var seg = segs_2[_i]; 9485 core.removeElement(seg.el); 9486 } 9487 }; 9488 return DayTileEventRenderer; 9489 }(SimpleDayGridEventRenderer)); 9490 9491 var DayBgRow = /** @class */ (function () { 9492 function DayBgRow(context) { 9493 this.context = context; 9494 } 9495 DayBgRow.prototype.renderHtml = function (props) { 9496 var parts = []; 9497 if (props.renderIntroHtml) { 9498 parts.push(props.renderIntroHtml()); 9499 } 9500 for (var _i = 0, _a = props.cells; _i < _a.length; _i++) { 9501 var cell = _a[_i]; 9502 parts.push(renderCellHtml(cell.date, props.dateProfile, this.context, cell.htmlAttrs)); 9503 } 9504 if (!props.cells.length) { 9505 parts.push('<td class="fc-day ' + this.context.theme.getClass('widgetContent') + '"></td>'); 9506 } 9507 if (this.context.options.dir === 'rtl') { 9508 parts.reverse(); 9509 } 9510 return '<tr>' + parts.join('') + '</tr>'; 9511 }; 9512 return DayBgRow; 9513 }()); 9514 function renderCellHtml(date, dateProfile, context, otherAttrs) { 9515 var dateEnv = context.dateEnv, theme = context.theme; 9516 var isDateValid = core.rangeContainsMarker(dateProfile.activeRange, date); // TODO: called too frequently. cache somehow. 9517 var classes = core.getDayClasses(date, dateProfile, context); 9518 classes.unshift('fc-day', theme.getClass('widgetContent')); 9519 return '<td class="' + classes.join(' ') + '"' + 9520 (isDateValid ? 9521 ' data-date="' + dateEnv.formatIso(date, { omitTime: true }) + '"' : 9522 '') + 9523 (otherAttrs ?
9524 ' ' + otherAttrs : 9525 '') + 9526 '></td>'; 9527 } 9528 9529 var DAY_NUM_FORMAT = core.createFormatter({ day: 'numeric' }); 9530 var WEEK_NUM_FORMAT = core.createFormatter({ week: 'numeric' }); 9531 var DayGrid = /** @class */ (function (_super) { 9532 __extends(DayGrid, _super); 9533 function DayGrid(context, el, renderProps) { 9534 var _this = _super.call(this, context, el) || this; 9535 _this.bottomCoordPadding = 0; // hack for extending the hit area for the last row of the coordinate grid 9536 _this.isCellSizesDirty = false; 9537 var eventRenderer = _this.eventRenderer = new DayGridEventRenderer(_this); 9538 var fillRenderer = _this.fillRenderer = new DayGridFillRenderer(_this); 9539 _this.mirrorRenderer = new DayGridMirrorRenderer(_this); 9540 var renderCells = _this.renderCells = core.memoizeRendering(_this._renderCells, _this._unrenderCells); 9541 _this.renderBusinessHours = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'businessHours'), fillRenderer.unrender.bind(fillRenderer, 'businessHours'), [renderCells]); 9542 _this.renderDateSelection = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'highlight'), fillRenderer.unrender.bind(fillRenderer, 'highlight'), [renderCells]); 9543 _this.renderBgEvents = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'bgEvent'), fillRenderer.unrender.bind(fillRenderer, 'bgEvent'), [renderCells]); 9544 _this.renderFgEvents = core.memoizeRendering(eventRenderer.renderSegs.bind(eventRenderer), eventRenderer.unrender.bind(eventRenderer), [renderCells]); 9545 _this.renderEventSelection = core.memoizeRendering(eventRenderer.selectByInstanceId.bind(eventRenderer), eventRenderer.unselectByInstanceId.bind(eventRenderer), [_this.renderFgEvents]); 9546 _this.renderEventDrag = core.memoizeRendering(_this._renderEventDrag, _this._unrenderEventDrag, [renderCells]); 9547 _this.renderEventResize = core.memoizeRendering(_this._renderEventResize, _this._unrenderEventResize, [renderCells]); 9548 _this.renderProps = renderProps; 9549 return _this; 9550 } 9551 DayGrid.prototype.render = function (props) { 9552 var cells = props.cells; 9553 this.rowCnt = cells.length; 9554 this.colCnt = cells[0].length; 9555 this.renderCells(cells, props.isRigid); 9556 this.renderBusinessHours(props.businessHourSegs); 9557 this.renderDateSelection(props.dateSelectionSegs); 9558 this.renderBgEvents(props.bgEventSegs); 9559 this.renderFgEvents(props.fgEventSegs); 9560 this.renderEventSelection(props.eventSelection); 9561 this.renderEventDrag(props.eventDrag); 9562 this.renderEventResize(props.eventResize); 9563 if (this.segPopoverTile) { 9564 this.updateSegPopoverTile(); 9565 } 9566 }; 9567 DayGrid.prototype.destroy = function () { 9568 _super.prototype.destroy.call(this); 9569 this.renderCells.unrender(); // will unrender everything else 9570 }; 9571 DayGrid.prototype.getCellRange = function (row, col) { 9572 var start = this.props.cells[row][col].date; 9573 var end = core.addDays(start, 1); 9574 return { start: start, end: end }; 9575 }; 9576 DayGrid.prototype.updateSegPopoverTile = function (date, segs) { 9577 var ownProps = this.props; 9578 this.segPopoverTile.receiveProps({ 9579 date: date || this.segPopoverTile.props.date, 9580 fgSegs: segs || this.segPopoverTile.props.fgSegs, 9581 eventSelection: ownProps.eventSelection, 9582 eventDragInstances: ownProps.eventDrag ? ownProps.eventDrag.affectedInstances : null, 9583 eventResizeInstances: ownProps.eventResize ? ownProps.eventResize.affectedInstances : null 9584 }); 9585 }; 9586 /* Date Rendering 9587 ------------------------------------------------------------------------------------------------------------------*/ 9588 DayGrid.prototype._renderCells = function (cells, isRigid) { 9589 var _a = this, view = _a.view, dateEnv = _a.dateEnv; 9590 var _b = this, rowCnt = _b.rowCnt, colCnt = _b.colCnt; 9591 var html = ''; 9592 var row; 9593 var col; 9594 for (row = 0; row < rowCnt; row++) { 9595 html += this.renderDayRowHtml(row, isRigid); 9596 } 9597 this.el.innerHTML = html; 9598 this.rowEls = core.findElements(this.el, '.fc-row'); 9599 this.cellEls = core.findElements(this.el, '.fc-day, .fc-disabled-day'); 9600 if (this.isRtl) { 9601 this.cellEls.reverse(); 9602 } 9603 this.rowPositions = new core.PositionCache(this.el, this.rowEls, false, true // vertical 9604 ); 9605 this.colPositions = new core.PositionCache(this.el, this.cellEls.slice(0, colCnt), // only the first row 9606 true, false // horizontal 9607 ); 9608 // trigger dayRender with each cell's element 9609 for (row = 0; row < rowCnt; row++) { 9610 for (col = 0; col < colCnt; col++) { 9611 this.publiclyTrigger('dayRender', [ 9612 { 9613 date: dateEnv.toDate(cells[row][col].date), 9614 el: this.getCellEl(row, col), 9615 view: view 9616 } 9617 ]); 9618 } 9619 } 9620 this.isCellSizesDirty = true; 9621 }; 9622 DayGrid.prototype._unrenderCells = function () { 9623 this.removeSegPopover(); 9624 }; 9625 // Generates the HTML for a single row, which is a div that wraps a table. 9626 // `row` is the row number. 9627 DayGrid.prototype.renderDayRowHtml = function (row, isRigid) { 9628 var theme = this.theme; 9629 var classes = ['fc-row', 'fc-week', theme.getClass('dayRow')]; 9630 if (isRigid) { 9631 classes.push('fc-rigid'); 9632 } 9633 var bgRow = new DayBgRow(this.context); 9634 return '' + 9635 '<div class="' + classes.join(' ') + '">' + 9636 '<div class="fc-bg">' + 9637 '<table class="' + theme.getClass('tableGrid') + '">' + 9638 bgRow.renderHtml({ 9639 cells: this.props.cells[row], 9640 dateProfile: this.props.dateProfile, 9641 renderIntroHtml: this.renderProps.renderBgIntroHtml 9642 }) + 9643 '</table>' + 9644 '</div>' + 9645 '<div class="fc-content-skeleton">' + 9646 '<table>' + 9647 (this.getIsNumbersVisible() ? 9648 '<thead>' + 9649 this.renderNumberTrHtml(row) + 9650 '</thead>' : 9651 '') + 9652 '</table>' + 9653 '</div>' + 9654 '</div>'; 9655 }; 9656 DayGrid.prototype.getIsNumbersVisible = function () { 9657 return this.getIsDayNumbersVisible() || 9658 this.renderProps.cellWeekNumbersVisible || 9659 this.renderProps.colWeekNumbersVisible; 9660 }; 9661 DayGrid.prototype.getIsDayNumbersVisible = function () { 9662 return this.rowCnt > 1; 9663 }; 9664 /* Grid Number Rendering 9665 ------------------------------------------------------------------------------------------------------------------*/ 9666 DayGrid.prototype.renderNumberTrHtml = function (row) { 9667 var intro = this.renderProps.renderNumberIntroHtml(row, this); 9668 return '' + 9669 '<tr>' + 9670 (this.isRtl ? '' : intro) + 9671 this.renderNumberCellsHtml(row) + 9672 (this.isRtl ? intro : '') + 9673 '</tr>'; 9674 }; 9675 DayGrid.prototype.renderNumberCellsHtml = function (row) { 9676 var htmls = []; 9677 var col; 9678 var date; 9679 for (col = 0; col < this.colCnt; col++) { 9680 date = this.props.cells[row][col].date; 9681 htmls.push(this.renderNumberCellHtml(date)); 9682 } 9683 if (this.isRtl) { 9684 htmls.reverse(); 9685 } 9686 return htmls.join(''); 9687 }; 9688 // Generates the HTML for the <td>s of the "number" row in the DayGrid's content skeleton. 9689 // The number row will only exist if either day numbers or week numbers are turned on. 9690 DayGrid.prototype.renderNumberCellHtml = function (date) { 9691 var _a = this, view = _a.view, dateEnv = _a.dateEnv; 9692 var html = ''; 9693 var isDateValid = core.rangeContainsMarker(this.props.dateProfile.activeRange, date); // TODO: called too frequently. cache somehow. 9694 var isDayNumberVisible = this.getIsDayNumbersVisible() && isDateValid; 9695 var classes; 9696 var weekCalcFirstDow; 9697 if (!isDayNumberVisible && !this.renderProps.cellWeekNumbersVisible) { 9698 // no numbers in day cell (week number must be along the side) 9699 return '<td></td>'; // will create an empty space above events :( 9700 } 9701 classes = core.getDayClasses(date, this.props.dateProfile, this.context); 9702 classes.unshift('fc-day-top'); 9703 if (this.renderProps.cellWeekNumbersVisible) { 9704 weekCalcFirstDow = dateEnv.weekDow; 9705 } 9706 html += '<td class="' + classes.join(' ') + '"' + 9707 (isDateValid ? 9708 ' data-date="' + dateEnv.formatIso(date, { omitTime: true }) + '"' : 9709 '') + 9710 '>'; 9711 if (this.renderProps.cellWeekNumbersVisible && (date.getUTCDay() === weekCalcFirstDow)) { 9712 html += core.buildGotoAnchorHtml(view, { date: date, type: 'week' }, { 'class': 'fc-week-number' }, dateEnv.format(date, WEEK_NUM_FORMAT) // inner HTML 9713 ); 9714 } 9715 if (isDayNumberVisible) { 9716 html += core.buildGotoAnchorHtml(view, date, { 'class': 'fc-day-number' }, dateEnv.format(date, DAY_NUM_FORMAT) // inner HTML 9717 ); 9718 } 9719 html += '</td>'; 9720 return html; 9721 }; 9722 /* Sizing 9723 ------------------------------------------------------------------------------------------------------------------*/ 9724 DayGrid.prototype.updateSize = function (isResize) { 9725 var _a = this, fillRenderer = _a.fillRenderer, eventRenderer = _a.eventRenderer, mirrorRenderer = _a.mirrorRenderer; 9726 if (isResize || 9727 this.isCellSizesDirty || 9728 this.view.calendar.isEventsUpdated // hack 9729 ) { 9730 this.buildPositionCaches(); 9731 this.isCellSizesDirty = false;
9732 } 9733 fillRenderer.computeSizes(isResize); 9734 eventRenderer.computeSizes(isResize); 9735 mirrorRenderer.computeSizes(isResize); 9736 fillRenderer.assignSizes(isResize); 9737 eventRenderer.assignSizes(isResize); 9738 mirrorRenderer.assignSizes(isResize); 9739 }; 9740 DayGrid.prototype.buildPositionCaches = function () { 9741 this.buildColPositions(); 9742 this.buildRowPositions(); 9743 }; 9744 DayGrid.prototype.buildColPositions = function () { 9745 this.colPositions.build(); 9746 }; 9747 DayGrid.prototype.buildRowPositions = function () { 9748 this.rowPositions.build(); 9749 this.rowPositions.bottoms[this.rowCnt - 1] += this.bottomCoordPadding; // hack 9750 }; 9751 /* Hit System 9752 ------------------------------------------------------------------------------------------------------------------*/ 9753 DayGrid.prototype.positionToHit = function (leftPosition, topPosition) { 9754 var _a = this, colPositions = _a.colPositions, rowPositions = _a.rowPositions; 9755 var col = colPositions.leftToIndex(leftPosition); 9756 var row = rowPositions.topToIndex(topPosition); 9757 if (row != null && col != null) { 9758 return { 9759 row: row, 9760 col: col, 9761 dateSpan: { 9762 range: this.getCellRange(row, col), 9763 allDay: true 9764 }, 9765 dayEl: this.getCellEl(row, col), 9766 relativeRect: { 9767 left: colPositions.lefts[col], 9768 right: colPositions.rights[col], 9769 top: rowPositions.tops[row], 9770 bottom: rowPositions.bottoms[row] 9771 } 9772 }; 9773 } 9774 }; 9775 /* Cell System 9776 ------------------------------------------------------------------------------------------------------------------*/ 9777 // FYI: the first column is the leftmost column, regardless of date 9778 DayGrid.prototype.getCellEl = function (row, col) { 9779 return this.cellEls[row * this.colCnt + col]; 9780 }; 9781 /* Event Drag Visualization 9782 ------------------------------------------------------------------------------------------------------------------*/ 9783 DayGrid.prototype._renderEventDrag = function (state) { 9784 if (state) { 9785 this.eventRenderer.hideByHash(state.affectedInstances); 9786 this.fillRenderer.renderSegs('highlight', state.segs); 9787 } 9788 }; 9789 DayGrid.prototype._unrenderEventDrag = function (state) { 9790 if (state) { 9791 this.eventRenderer.showByHash(state.affectedInstances); 9792 this.fillRenderer.unrender('highlight'); 9793 } 9794 }; 9795 /* Event Resize Visualization 9796 ------------------------------------------------------------------------------------------------------------------*/ 9797 DayGrid.prototype._renderEventResize = function (state) { 9798 if (state) { 9799 this.eventRenderer.hideByHash(state.affectedInstances); 9800 this.fillRenderer.renderSegs('highlight', state.segs); 9801 this.mirrorRenderer.renderSegs(state.segs, { isResizing: true, sourceSeg: state.sourceSeg }); 9802 } 9803 }; 9804 DayGrid.prototype._unrenderEventResize = function (state) { 9805 if (state) { 9806 this.eventRenderer.showByHash(state.affectedInstances); 9807 this.fillRenderer.unrender('highlight'); 9808 this.mirrorRenderer.unrender(state.segs, { isResizing: true, sourceSeg: state.sourceSeg }); 9809 } 9810 }; 9811 /* More+ Link Popover 9812 ------------------------------------------------------------------------------------------------------------------*/ 9813 DayGrid.prototype.removeSegPopover = function () { 9814 if (this.segPopover) { 9815 this.segPopover.hide(); // in handler, will call segPopover's removeElement 9816 } 9817 }; 9818 // Limits the number of "levels" (vertically stacking layers of events) for each row of the grid. 9819 // `levelLimit` can be false (don't limit), a number, or true (should be computed). 9820 DayGrid.prototype.limitRows = function (levelLimit) { 9821 var rowStructs = this.eventRenderer.rowStructs || []; 9822 var row; // row # 9823 var rowLevelLimit; 9824 for (row = 0; row < rowStructs.length; row++) { 9825 this.unlimitRow(row); 9826 if (!levelLimit) { 9827 rowLevelLimit = false;
9828 } 9829 else if (typeof levelLimit === 'number') { 9830 rowLevelLimit = levelLimit; 9831 } 9832 else { 9833 rowLevelLimit = this.computeRowLevelLimit(row); 9834 } 9835 if (rowLevelLimit !== false) { 9836 this.limitRow(row, rowLevelLimit); 9837 } 9838 } 9839 }; 9840 // Computes the number of levels a row will accomodate without going outside its bounds. 9841 // Assumes the row is "rigid" (maintains a constant height regardless of what is inside). 9842 // `row` is the row number. 9843 DayGrid.prototype.computeRowLevelLimit = function (row) { 9844 var rowEl = this.rowEls[row]; // the containing "fake" row div 9845 var rowBottom = rowEl.getBoundingClientRect().bottom; // relative to viewport! 9846 var trEls = core.findChildren(this.eventRenderer.rowStructs[row].tbodyEl); 9847 var i; 9848 var trEl; 9849 // Reveal one level <tr> at a time and stop when we find one out of bounds 9850 for (i = 0; i < trEls.length; i++) { 9851 trEl = trEls[i]; 9852 trEl.classList.remove('fc-limited'); // reset to original state (reveal) 9853 if (trEl.getBoundingClientRect().bottom > rowBottom) { 9854 return i; 9855 } 9856 } 9857 return false; // should not limit at all 9858 }; 9859 // Limits the given grid row to the maximum number of levels and injects "more" links if necessary. 9860 // `row` is the row number. 9861 // `levelLimit` is a number for the maximum (inclusive) number of levels allowed. 9862 DayGrid.prototype.limitRow = function (row, levelLimit) { 9863 var _this = this; 9864 var _a = this, colCnt = _a.colCnt, isRtl = _a.isRtl; 9865 var rowStruct = this.eventRenderer.rowStructs[row]; 9866 var moreNodes = []; // array of "more" <a> links and <td> DOM nodes 9867 var col = 0; // col #, left-to-right (not chronologically) 9868 var levelSegs; // array of segment objects in the last allowable level, ordered left-to-right 9869 var cellMatrix; // a matrix (by level, then column) of all <td> elements in the row 9870 var limitedNodes; // array of temporarily hidden level <tr> and segment <td> DOM nodes 9871 var i; 9872 var seg; 9873 var segsBelow; // array of segment objects below `seg` in the current `col` 9874 var totalSegsBelow; // total number of segments below `seg` in any of the columns `seg` occupies 9875 var colSegsBelow; // array of segment arrays, below seg, one for each column (offset from segs's first column) 9876 var td; 9877 var rowSpan; 9878 var segMoreNodes; // array of "more" <td> cells that will stand-in for the current seg's cell 9879 var j; 9880 var moreTd; 9881 var moreWrap; 9882 var moreLink; 9883 // Iterates through empty level cells and places "more" links inside if need be 9884 var emptyCellsUntil = function (endCol) { 9885 while (col < endCol) { 9886 segsBelow = _this.getCellSegs(row, col, levelLimit); 9887 if (segsBelow.length) { 9888 td = cellMatrix[levelLimit - 1][col]; 9889 moreLink = _this.renderMoreLink(row, col, segsBelow); 9890 moreWrap = core.createElement('div', null, moreLink); 9891 td.appendChild(moreWrap); 9892 moreNodes.push(moreWrap); 9893 } 9894 col++; 9895 } 9896 }; 9897 if (levelLimit && levelLimit < rowStruct.segLevels.length) { // is it actually over the limit? 9898 levelSegs = rowStruct.segLevels[levelLimit - 1]; 9899 cellMatrix = rowStruct.cellMatrix; 9900 limitedNodes = core.findChildren(rowStruct.tbodyEl).slice(levelLimit); // get level <tr> elements past the limit 9901 limitedNodes.forEach(function (node) { 9902 node.classList.add('fc-limited'); // hide elements and get a simple DOM-nodes array 9903 }); 9904 // iterate though segments in the last allowable level 9905 for (i = 0; i < levelSegs.length; i++) { 9906 seg = levelSegs[i]; 9907 var leftCol = isRtl ? (colCnt - 1 - seg.lastCol) : seg.firstCol; 9908 var rightCol = isRtl ? (colCnt - 1 - seg.firstCol) : seg.lastCol; 9909 emptyCellsUntil(leftCol); // process empty cells before the segment 9910 // determine *all* segments below `seg` that occupy the same columns 9911 colSegsBelow = []; 9912 totalSegsBelow = 0; 9913 while (col <= rightCol) { 9914 segsBelow = this.getCellSegs(row, col, levelLimit); 9915 colSegsBelow.push(segsBelow); 9916 totalSegsBelow += segsBelow.length; 9917 col++; 9918 } 9919 if (totalSegsBelow) { // do we need to replace this segment with one or many "more" links? 9920 td = cellMatrix[levelLimit - 1][leftCol]; // the segment's parent cell 9921 rowSpan = td.rowSpan || 1; 9922 segMoreNodes = []; 9923 // make a replacement <td> for each column the segment occupies. will be one for each colspan 9924 for (j = 0; j < colSegsBelow.length; j++) { 9925 moreTd = core.createElement('td', { className: 'fc-more-cell', rowSpan: rowSpan }); 9926 segsBelow = colSegsBelow[j]; 9927 moreLink = this.renderMoreLink(row, leftCol + j, [seg].concat(segsBelow) // count seg as hidden too 9928 ); 9929 moreWrap = core.createElement('div', null, moreLink); 9930 moreTd.appendChild(moreWrap); 9931 segMoreNodes.push(moreTd); 9932 moreNodes.push(moreTd); 9933 } 9934 td.classList.add('fc-limited'); 9935 core.insertAfterElement(td, segMoreNodes); 9936 limitedNodes.push(td); 9937 } 9938 } 9939 emptyCellsUntil(this.colCnt); // finish off the level 9940 rowStruct.moreEls = moreNodes; // for easy undoing later 9941 rowStruct.limitedEls = limitedNodes; // for easy undoing later 9942 } 9943 }; 9944 // Reveals all levels and removes all "more"-related elements for a grid's row. 9945 // `row` is a row number. 9946 DayGrid.prototype.unlimitRow = function (row) { 9947 var rowStruct = this.eventRenderer.rowStructs[row]; 9948 if (rowStruct.moreEls) {
9949 rowStruct.moreEls.forEach(core.removeElement); 9950 rowStruct.moreEls = null; 9951 } 9952 if (rowStruct.limitedEls) { 9953 rowStruct.limitedEls.forEach(function (limitedEl) { 9954 limitedEl.classList.remove('fc-limited'); 9955 }); 9956 rowStruct.limitedEls = null; 9957 } 9958 }; 9959 // Renders an <a> element that represents hidden event element for a cell. 9960 // Responsible for attaching click handler as well. 9961 DayGrid.prototype.renderMoreLink = function (row, col, hiddenSegs) { 9962 var _this = this; 9963 var _a = this, view = _a.view, dateEnv = _a.dateEnv; 9964 var a = core.createElement('a', { className: 'fc-more' }); 9965 a.innerText = this.getMoreLinkText(hiddenSegs.length); 9966 a.addEventListener('click', function (ev) { 9967 var clickOption = _this.opt('eventLimitClick'); 9968 var _col = _this.isRtl ? _this.colCnt - col - 1 : col; // HACK: props.cells has different dir system? 9969 var date = _this.props.cells[row][_col].date; 9970 var moreEl = ev.currentTarget; 9971 var dayEl = _this.getCellEl(row, col); 9972 var allSegs = _this.getCellSegs(row, col); 9973 // rescope the segments to be within the cell's date 9974 var reslicedAllSegs = _this.resliceDaySegs(allSegs, date); 9975 var reslicedHiddenSegs = _this.resliceDaySegs(hiddenSegs, date); 9976 if (typeof clickOption === 'function') { 9977 // the returned value can be an atomic option 9978 clickOption = _this.publiclyTrigger('eventLimitClick', [ 9979 { 9980 date: dateEnv.toDate(date), 9981 allDay: true, 9982 dayEl: dayEl, 9983 moreEl: moreEl, 9984 segs: reslicedAllSegs, 9985 hiddenSegs: reslicedHiddenSegs, 9986 jsEvent: ev, 9987 view: view 9988 } 9989 ]); 9990 } 9991 if (clickOption === 'popover') { 9992 _this.showSegPopover(row, col, moreEl, reslicedAllSegs); 9993 } 9994 else if (typeof clickOption === 'string') { // a view name 9995 view.calendar.zoomTo(date, clickOption); 9996 } 9997 }); 9998 return a; 9999 }; 10000 // Reveals the popover that displays all events within a cell 10001 DayGrid.prototype.showSegPopover = function (row, col, moreLink, segs) { 10002 var _this = this; 10003 var _a = this, calendar = _a.calendar, view = _a.view, theme = _a.theme; 10004 var _col = this.isRtl ? this.colCnt - col - 1 : col; // HACK: props.cells has different dir system? 10005 var moreWrap = moreLink.parentNode; // the <div> wrapper around the <a> 10006 var topEl; // the element we want to match the top coordinate of 10007 var options; 10008 if (this.rowCnt === 1) { 10009 topEl = view.el; // will cause the popover to cover any sort of header 10010 } 10011 else { 10012 topEl = this.rowEls[row]; // will align with top of row 10013 } 10014 options = { 10015 className: 'fc-more-popover ' + theme.getClass('popover'), 10016 parentEl: view.el, 10017 top: core.computeRect(topEl).top, 10018 autoHide: true, 10019 content: function (el) { 10020 _this.segPopoverTile = new DayTile(_this.context, el); 10021 _this.updateSegPopoverTile(_this.props.cells[row][_col].date, segs); 10022 }, 10023 hide: function () { 10024 _this.segPopoverTile.destroy(); 10025 _this.segPopoverTile = null; 10026 _this.segPopover.destroy(); 10027 _this.segPopover = null; 10028 } 10029 }; 10030 // Determine horizontal coordinate. 10031 // We use the moreWrap instead of the <td> to avoid border confusion. 10032 if (this.isRtl) { 10033 options.right = core.computeRect(moreWrap).right + 1; // +1 to be over cell border 10034 } 10035 else { 10036 options.left = core.computeRect(moreWrap).left - 1; // -1 to be over cell border 10037 } 10038 this.segPopover = new Popover(options); 10039 this.segPopover.show(); 10040 calendar.releaseAfterSizingTriggers(); // hack for eventPositioned 10041 }; 10042 // Given the events within an array of segment objects, reslice them to be in a single day
10043 DayGrid.prototype.resliceDaySegs = function (segs, dayDate) { 10044 var dayStart = dayDate; 10045 var dayEnd = core.addDays(dayStart, 1); 10046 var dayRange = { start: dayStart, end: dayEnd }; 10047 var newSegs = []; 10048 for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) { 10049 var seg = segs_1[_i]; 10050 var eventRange = seg.eventRange; 10051 var origRange = eventRange.range; 10052 var slicedRange = core.intersectRanges(origRange, dayRange); 10053 if (slicedRange) { 10054 newSegs.push(__assign({}, seg, { eventRange: { 10055 def: eventRange.def, 10056 ui: __assign({}, eventRange.ui, { durationEditable: false }), 10057 instance: eventRange.instance, 10058 range: slicedRange 10059 }, isStart: seg.isStart && slicedRange.start.valueOf() === origRange.start.valueOf(), isEnd: seg.isEnd && slicedRange.end.valueOf() === origRange.end.valueOf() })); 10060 } 10061 } 10062 return newSegs; 10063 }; 10064 // Generates the text that should be inside a "more" link, given the number of events it represents 10065 DayGrid.prototype.getMoreLinkText = function (num) { 10066 var opt = this.opt('eventLimitText'); 10067 if (typeof opt === 'function') { 10068 return opt(num); 10069 } 10070 else { 10071 return '+' + num + ' ' + opt; 10072 } 10073 }; 10074 // Returns segments within a given cell. 10075 // If `startLevel` is specified, returns only events including and below that level. Otherwise returns all segs. 10076 DayGrid.prototype.getCellSegs = function (row, col, startLevel) { 10077 var segMatrix = this.eventRenderer.rowStructs[row].segMatrix; 10078 var level = startLevel || 0; 10079 var segs = []; 10080 var seg; 10081 while (level < segMatrix.length) { 10082 seg = segMatrix[level][col]; 10083 if (seg) { 10084 segs.push(seg); 10085 } 10086 level++; 10087 } 10088 return segs; 10089 }; 10090 return DayGrid; 10091 }(core.DateComponent)); 10092 10093 var WEEK_NUM_FORMAT$1 = core.createFormatter({ week: 'numeric' }); 10094 /* An abstract class for the daygrid views, as well as month view. Renders one or more rows of day cells. 10095 ----------------------------------------------------------------------------------------------------------------------*/ 10096 // It is a manager for a DayGrid subcomponent, which does most of the heavy lifting. 10097 // It is responsible for managing width/height. 10098 var DayGridView = /** @class */ (function (_super) { 10099 __extends(DayGridView, _super); 10100 function DayGridView(context, viewSpec, dateProfileGenerator, parentEl) { 10101 var _this = _super.call(this, context, viewSpec, dateProfileGenerator, parentEl) || this; 10102 /* Header Rendering 10103 ------------------------------------------------------------------------------------------------------------------*/ 10104 // Generates the HTML that will go before the day-of week header cells 10105 _this.renderHeadIntroHtml = function () { 10106 var theme = _this.theme; 10107 if (_this.colWeekNumbersVisible) { 10108 return '' + 10109 '<th class="fc-week-number ' + theme.getClass('widgetHeader') + '" ' + _this.weekNumberStyleAttr() + '>' + 10110 '<span>' + // needed for matchCellWidths 10111 core.htmlEscape(_this.opt('weekLabel')) + 10112 '</span>' + 10113 '</th>'; 10114 } 10115 return ''; 10116 }; 10117 /* Day Grid Rendering 10118 ------------------------------------------------------------------------------------------------------------------*/ 10119 // Generates the HTML that will go before content-skeleton cells that display the day/week numbers 10120 _this.renderDayGridNumberIntroHtml = function (row, dayGrid) { 10121 var dateEnv = _this.dateEnv; 10122 var weekStart = dayGrid.props.cells[row][0].date; 10123 if (_this.colWeekNumbersVisible) { 10124 return '' + 10125 '<td class="fc-week-number" ' + _this.weekNumberStyleAttr() + '>' + 10126 core.buildGotoAnchorHtml(// aside from link, important for matchCellWidths 10127 _this, { date: weekStart, type: 'week', forceOff: dayGrid.colCnt === 1 }, dateEnv.format(weekStart, WEEK_NUM_FORMAT$1) // inner HTML 10128 ) + 10129 '</td>'; 10130 } 10131 return ''; 10132 }; 10133 // Generates the HTML that goes before the day bg cells for each day-row 10134 _this.renderDayGridBgIntroHtml = function () { 10135 var theme = _this.theme; 10136 if (_this.colWeekNumbersVisible) { 10137 return '<td class="fc-week-number ' + theme.getClass('widgetContent') + '" ' + _this.weekNumberStyleAttr() + '></td>'; 10138 } 10139 return ''; 10140 }; 10141 // Generates the HTML that goes before every other type of row generated by DayGrid. 10142 // Affects mirror-skeleton and highlight-skeleton rows. 10143 _this.renderDayGridIntroHtml = function () { 10144 if (_this.colWeekNumbersVisible) { 10145 return '<td class="fc-week-number" ' + _this.weekNumberStyleAttr() + '></td>'; 10146 } 10147 return ''; 10148 }; 10149 _this.el.classList.add('fc-dayGrid-view'); 10150 _this.el.innerHTML = _this.renderSkeletonHtml();
10151 _this.scroller = new core.ScrollComponent('hidden', // overflow x 10152 'auto' // overflow y 10153 ); 10154 var dayGridContainerEl = _this.scroller.el; 10155 _this.el.querySelector('.fc-body > tr > td').appendChild(dayGridContainerEl); 10156 dayGridContainerEl.classList.add('fc-day-grid-container'); 10157 var dayGridEl = core.createElement('div', { className: 'fc-day-grid' }); 10158 dayGridContainerEl.appendChild(dayGridEl); 10159 var cellWeekNumbersVisible; 10160 if (_this.opt('weekNumbers')) { 10161 if (_this.opt('weekNumbersWithinDays')) { 10162 cellWeekNumbersVisible = true; 10163 _this.colWeekNumbersVisible = false; 10164 } 10165 else { 10166 cellWeekNumbersVisible = false; 10167 _this.colWeekNumbersVisible = true; 10168 } 10169 } 10170 else { 10171 _this.colWeekNumbersVisible = false; 10172 cellWeekNumbersVisible = false; 10173 } 10174 _this.dayGrid = new DayGrid(_this.context, dayGridEl, { 10175 renderNumberIntroHtml: _this.renderDayGridNumberIntroHtml, 10176 renderBgIntroHtml: _this.renderDayGridBgIntroHtml, 10177 renderIntroHtml: _this.renderDayGridIntroHtml, 10178 colWeekNumbersVisible: _this.colWeekNumbersVisible, 10179 cellWeekNumbersVisible: cellWeekNumbersVisible 10180 }); 10181 return _this; 10182 } 10183 DayGridView.prototype.destroy = function () { 10184 _super.prototype.destroy.call(this); 10185 this.dayGrid.destroy(); 10186 this.scroller.destroy(); 10187 }; 10188 // Builds the HTML skeleton for the view. 10189 // The day-grid component will render inside of a container defined by this HTML. 10190 DayGridView.prototype.renderSkeletonHtml = function () { 10191 var theme = this.theme; 10192 return '' + 10193 '<table class="' + theme.getClass('tableGrid') + '">' + 10194 (this.opt('columnHeader') ? 10195 '<thead class="fc-head">' + 10196 '<tr>' + 10197 '<td class="fc-head-container ' + theme.getClass('widgetHeader') + '"> </td>' + 10198 '</tr>' + 10199 '</thead>' : 10200 '') + 10201 '<tbody class="fc-body">' + 10202 '<tr>' + 10203 '<td class="' + theme.getClass('widgetContent') + '"></td>' + 10204 '</tr>' + 10205 '</tbody>' + 10206 '</table>'; 10207 }; 10208 // Generates an HTML attribute string for setting the width of the week number column, if it is known 10209 DayGridView.prototype.weekNumberStyleAttr = function () { 10210 if (this.weekNumberWidth != null) { 10211 return 'style="width:' + this.weekNumberWidth + 'px"'; 10212 } 10213 return ''; 10214 }; 10215 // Determines whether each row should have a constant height 10216 DayGridView.prototype.hasRigidRows = function () { 10217 var eventLimit = this.opt('eventLimit'); 10218 return eventLimit && typeof eventLimit !== 'number'; 10219 }; 10220 /* Dimensions 10221 ------------------------------------------------------------------------------------------------------------------*/ 10222 DayGridView.prototype.updateSize = function (isResize, viewHeight, isAuto) { 10223 _super.prototype.updateSize.call(this, isResize, viewHeight, isAuto); // will call updateBaseSize. important that executes first 10224 this.dayGrid.updateSize(isResize); 10225 }; 10226 // Refreshes the horizontal dimensions of the view 10227 DayGridView.prototype.updateBaseSize = function (isResize, viewHeight, isAuto) { 10228 var dayGrid = this.dayGrid; 10229 var eventLimit = this.opt('eventLimit'); 10230 var headRowEl = this.header ? this.header.el : null; // HACK 10231 var scrollerHeight; 10232 var scrollbarWidths; 10233 // hack to give the view some height prior to dayGrid's columns being rendered 10234 // TODO: separate setting height from scroller VS dayGrid. 10235 if (!dayGrid.rowEls) { 10236 if (!isAuto) { 10237 scrollerHeight = this.computeScrollerHeight(viewHeight); 10238 this.scroller.setHeight(scrollerHeight); 10239 } 10240 return; 10241 } 10242 if (this.colWeekNumbersVisible) { 10243 // Make sure all week number cells running down the side have the same width. 10244 this.weekNumberWidth = core.matchCellWidths(core.findElements(this.el, '.fc-week-number')); 10245 } 10246 // reset all heights to be natural 10247 this.scroller.clear(); 10248 if (headRowEl) { 10249 core.uncompensateScroll(headRowEl); 10250 } 10251 dayGrid.removeSegPopover(); // kill the "more" popover if displayed 10252 // is the event limit a constant level number? 10253 if (eventLimit && typeof eventLimit === 'number') { 10254 dayGrid.limitRows(eventLimit); // limit the levels first so the height can redistribute after 10255 } 10256 // distribute the height to the rows 10257 // (viewHeight is a "recommended" value if isAuto) 10258 scrollerHeight = this.computeScrollerHeight(viewHeight); 10259 this.setGridHeight(scrollerHeight, isAuto); 10260 // is the event limit dynamically calculated? 10261 if (eventLimit && typeof eventLimit !== 'number') { 10262 dayGrid.limitRows(eventLimit); // limit the levels after the grid's row heights have been set 10263 } 10264 if (!isAuto) { // should we force dimensions of the scroll container? 10265 this.scroller.setHeight(scrollerHeight);
10266 scrollbarWidths = this.scroller.getScrollbarWidths(); 10267 if (scrollbarWidths.left || scrollbarWidths.right) { // using scrollbars? 10268 if (headRowEl) { 10269 core.compensateScroll(headRowEl, scrollbarWidths); 10270 } 10271 // doing the scrollbar compensation might have created text overflow which created more height. redo 10272 scrollerHeight = this.computeScrollerHeight(viewHeight); 10273 this.scroller.setHeight(scrollerHeight); 10274 } 10275 // guarantees the same scrollbar widths 10276 this.scroller.lockOverflow(scrollbarWidths); 10277 } 10278 }; 10279 // given a desired total height of the view, returns what the height of the scroller should be 10280 DayGridView.prototype.computeScrollerHeight = function (viewHeight) { 10281 return viewHeight - 10282 core.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller 10283 }; 10284 // Sets the height of just the DayGrid component in this view 10285 DayGridView.prototype.setGridHeight = function (height, isAuto) { 10286 if (this.opt('monthMode')) { 10287 // if auto, make the height of each row the height that it would be if there were 6 weeks 10288 if (isAuto) { 10289 height *= this.dayGrid.rowCnt / 6; 10290 } 10291 core.distributeHeight(this.dayGrid.rowEls, height, !isAuto); // if auto, don't compensate for height-hogging rows 10292 } 10293 else { 10294 if (isAuto) { 10295 core.undistributeHeight(this.dayGrid.rowEls); // let the rows be their natural height with no expanding 10296 } 10297 else { 10298 core.distributeHeight(this.dayGrid.rowEls, height, true); // true = compensate for height-hogging rows 10299 } 10300 } 10301 }; 10302 /* Scroll 10303 ------------------------------------------------------------------------------------------------------------------*/ 10304 DayGridView.prototype.computeDateScroll = function (duration) { 10305 return { top: 0 }; 10306 }; 10307 DayGridView.prototype.queryDateScroll = function () { 10308 return { top: this.scroller.getScrollTop() }; 10309 }; 10310 DayGridView.prototype.applyDateScroll = function (scroll) { 10311 if (scroll.top !== undefined) { 10312 this.scroller.setScrollTop(scroll.top); 10313 } 10314 }; 10315 return DayGridView; 10316 }(core.View)); 10317 DayGridView.prototype.dateProfileGeneratorClass = DayGridDateProfileGenerator; 10318 10319 var SimpleDayGrid = /** @class */ (function (_super) { 10320 __extends(SimpleDayGrid, _super); 10321 function SimpleDayGrid(context, dayGrid) { 10322 var _this = _super.call(this, context, dayGrid.el) || this; 10323 _this.slicer = new DayGridSlicer(); 10324 _this.dayGrid = dayGrid; 10325 context.calendar.registerInteractiveComponent(_this, { el: _this.dayGrid.el }); 10326 return _this; 10327 } 10328 SimpleDayGrid.prototype.destroy = function () { 10329 _super.prototype.destroy.call(this); 10330 this.calendar.unregisterInteractiveComponent(this); 10331 }; 10332 SimpleDayGrid.prototype.render = function (props) { 10333 var dayGrid = this.dayGrid; 10334 var dateProfile = props.dateProfile, dayTable = props.dayTable; 10335 dayGrid.receiveProps(__assign({}, this.slicer.sliceProps(props, dateProfile, props.nextDayThreshold, dayGrid, dayTable), { dateProfile: dateProfile, cells: dayTable.cells, isRigid: props.isRigid })); 10336 }; 10337 SimpleDayGrid.prototype.buildPositionCaches = function () { 10338 this.dayGrid.buildPositionCaches(); 10339 }; 10340 SimpleDayGrid.prototype.queryHit = function (positionLeft, positionTop) { 10341 var rawHit = this.dayGrid.positionToHit(positionLeft, positionTop); 10342 if (rawHit) { 10343 return { 10344 component: this.dayGrid, 10345 dateSpan: rawHit.dateSpan, 10346 dayEl: rawHit.dayEl, 10347 rect: { 10348 left: rawHit.relativeRect.left, 10349 right: rawHit.relativeRect.right, 10350 top: rawHit.relativeRect.top, 10351 bottom: rawHit.relativeRect.bottom 10352 }, 10353 layer: 0 10354 }; 10355 } 10356 }; 10357 return SimpleDayGrid; 10358 }(core.DateComponent));
10359 var DayGridSlicer = /** @class */ (function (_super) { 10360 __extends(DayGridSlicer, _super); 10361 function DayGridSlicer() { 10362 return _super !== null && _super.apply(this, arguments) || this; 10363 } 10364 DayGridSlicer.prototype.sliceRange = function (dateRange, dayTable) { 10365 return dayTable.sliceRange(dateRange); 10366 }; 10367 return DayGridSlicer; 10368 }(core.Slicer)); 10369 10370 var DayGridView$1 = /** @class */ (function (_super) { 10371 __extends(DayGridView, _super); 10372 function DayGridView(_context, viewSpec, dateProfileGenerator, parentEl) { 10373 var _this = _super.call(this, _context, viewSpec, dateProfileGenerator, parentEl) || this; 10374 _this.buildDayTable = core.memoize(buildDayTable); 10375 if (_this.opt('columnHeader')) { 10376 _this.header = new core.DayHeader(_this.context, _this.el.querySelector('.fc-head-container')); 10377 } 10378 _this.simpleDayGrid = new SimpleDayGrid(_this.context, _this.dayGrid); 10379 return _this; 10380 } 10381 DayGridView.prototype.destroy = function () { 10382 _super.prototype.destroy.call(this); 10383 if (this.header) { 10384 this.header.destroy(); 10385 } 10386 this.simpleDayGrid.destroy(); 10387 }; 10388 DayGridView.prototype.render = function (props) { 10389 _super.prototype.render.call(this, props); 10390 var dateProfile = this.props.dateProfile; 10391 var dayTable = this.dayTable = 10392 this.buildDayTable(dateProfile, this.dateProfileGenerator); 10393 if (this.header) { 10394 this.header.receiveProps({ 10395 dateProfile: dateProfile, 10396 dates: dayTable.headerDates, 10397 datesRepDistinctDays: dayTable.rowCnt === 1, 10398 renderIntroHtml: this.renderHeadIntroHtml 10399 }); 10400 } 10401 this.simpleDayGrid.receiveProps({ 10402 dateProfile: dateProfile, 10403 dayTable: dayTable, 10404 businessHours: props.businessHours, 10405 dateSelection: props.dateSelection, 10406 eventStore: props.eventStore, 10407 eventUiBases: props.eventUiBases, 10408 eventSelection: props.eventSelection, 10409 eventDrag: props.eventDrag, 10410 eventResize: props.eventResize, 10411 isRigid: this.hasRigidRows(), 10412 nextDayThreshold: this.nextDayThreshold 10413 }); 10414 }; 10415 return DayGridView; 10416 }(DayGridView)); 10417 function buildDayTable(dateProfile, dateProfileGenerator) { 10418 var daySeries = new core.DaySeries(dateProfile.renderRange, dateProfileGenerator); 10419 return new core.DayTable(daySeries, /year|month|week/.test(dateProfile.currentRangeUnit)); 10420 } 10421 10422 var main = core.createPlugin({ 10423 defaultView: 'dayGridMonth', 10424 views: { 10425 dayGrid: DayGridView$1, 10426 dayGridDay: { 10427 type: 'dayGrid', 10428 duration: { days: 1 } 10429 }, 10430 dayGridWeek: { 10431 type: 'dayGrid', 10432 duration: { weeks: 1 } 10433 }, 10434 dayGridMonth: { 10435 type: 'dayGrid', 10436 duration: { months: 1 }, 10437 monthMode: true, 10438 fixedWeekCount: true 10439 } 10440 } 10441 }); 10442 10443 exports.AbstractDayGridView = DayGridView; 10444 exports.DayBgRow = DayBgRow; 10445 exports.DayGrid = DayGrid; 10446 exports.DayGridSlicer = DayGridSlicer; 10447 exports.DayGridView = DayGridView$1; 10448 exports.SimpleDayGrid = SimpleDayGrid; 10449 exports.buildBasicDayTable = buildDayTable; 10450 exports.default = main; 10451 10452 Object.defineProperty(exports, '__esModule', { value: true }); 10453 10454})); 10455 10456},{"@fullcalendar/core":2}],4:[function(require,module,exports){ 10457/*! 10458FullCalendar Google Calendar Plugin v4.3.0 10459Docs & License: https://fullcalendar.io/ 10460(c) 2019 Adam Shaw 10461*/ 10462 10463(function (global, factory) { 10464 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core')) : 10465 typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core'], factory) : 10466 (global = global || self, factory(global.FullCalendarGoogleCalendar = {}, global.FullCalendar)); 10467}(this, function (exports, core) { 'use strict'; 10468 10469 /*! ***************************************************************************** 10470 Copyright (c) Microsoft Corporation. All rights reserved. 10471 Licensed under the Apache License, Version 2.0 (the "License");
10471 you may not use 10472 this file except in compliance with the License. You may obtain a copy of the 10473 License at http://www.apache.org/licenses/LICENSE-2.0 10474 10475 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 10476 KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 10477 WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 10478 MERCHANTABLITY OR NON-INFRINGEMENT. 10479 10480 See the Apache Version 2.0 License for specific language governing permissions 10481 and limitations under the License. 10482 ***************************************************************************** */ 10483 10484 var __assign = function() { 10485 __assign = Object.assign || function __assign(t) { 10486 for (var s, i = 1, n = arguments.length; i < n; i++) { 10487 s = arguments[i]; 10488 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 10489 } 10490 return t; 10491 }; 10492 return __assign.apply(this, arguments); 10493 }; 10494 10495 // TODO: expose somehow 10496 var API_BASE = 'https://www.googleapis.com/calendar/v3/calendars'; 10497 var STANDARD_PROPS = { 10498 url: String, 10499 googleCalendarApiKey: String, 10500 googleCalendarId: String, 10501 data: null 10502 }; 10503 var eventSourceDef = { 10504 parseMeta: function (raw) { 10505 if (typeof raw === 'string') { 10506 raw = { url: raw }; 10507 } 10508 if (typeof raw === 'object') { 10509 var standardProps = core.refineProps(raw, STANDARD_PROPS); 10510 if (!standardProps.googleCalendarId && standardProps.url) { 10511 standardProps.googleCalendarId = parseGoogleCalendarId(standardProps.url); 10512 } 10513 delete standardProps.url; 10514 if (standardProps.googleCalendarId) { 10515 return standardProps; 10516 } 10517 } 10518 return null; 10519 }, 10520 fetch: function (arg, onSuccess, onFailure) { 10521 var calendar = arg.calendar; 10522 var meta = arg.eventSource.meta; 10523 var apiKey = meta.googleCalendarApiKey || calendar.opt('googleCalendarApiKey'); 10524 if (!apiKey) { 10525 onFailure({ 10526 message: 'Specify a googleCalendarApiKey. See http://fullcalendar.io/docs/google_calendar/' 10527 }); 10528 } 10529 else { 10530 var url = buildUrl(meta); 10531 var requestParams_1 = buildRequestParams(arg.range, apiKey, meta.data, calendar.dateEnv); 10532 core.requestJson('GET', url, requestParams_1, function (body, xhr) { 10533 if (body.error) { 10534 onFailure({ 10535 message: 'Google Calendar API: ' + body.error.message, 10536 errors: body.error.errors, 10537 xhr: xhr 10538 }); 10539 } 10540 else { 10541 onSuccess({ 10542 rawEvents: gcalItemsToRawEventDefs(body.items, requestParams_1.timeZone), 10543 xhr: xhr 10544 }); 10545 } 10546 }, function (message, xhr) { 10547 onFailure({ message: message, xhr: xhr }); 10548 }); 10549 } 10550 } 10551 }; 10552 function parseGoogleCalendarId(url) { 10553 var match; 10554 // detect if the ID was specified as a single string. 10555 // will match calendars like "[email protected]" in addition to person email calendars. 10556 if (/^[^\/]+@([^\/\.]+\.)*(google|googlemail|gmail)\.com$/.test(url)) { 10557 return url; 10558 } 10559 else if ((match = /^https:\/\/www.googleapis.com\/calendar\/v3\/calendars\/([^\/]*)/.exec(url)) || 10560 (match = /^https?:\/\/www.google.com\/calendar\/feeds\/([^\/]*)/.exec(url))) { 10561 return decodeURIComponent(match[1]); 10562 } 10563 } 10564 function buildUrl(meta) { 10565 return API_BASE + '/' + encodeURIComponent(meta.googleCalendarId) + '/events'; 10566 }
10567 function buildRequestParams(range, apiKey, extraParams, dateEnv) { 10568 var params; 10569 var startStr; 10570 var endStr; 10571 if (dateEnv.canComputeOffset) { 10572 // strings will naturally have offsets, which GCal needs 10573 startStr = dateEnv.formatIso(range.start); 10574 endStr = dateEnv.formatIso(range.end); 10575 } 10576 else { 10577 // when timezone isn't known, we don't know what the UTC offset should be, so ask for +/- 1 day 10578 // from the UTC day-start to guarantee we're getting all the events 10579 // (start/end will be UTC-coerced dates, so toISOString is okay) 10580 startStr = core.addDays(range.start, -1).toISOString(); 10581 endStr = core.addDays(range.end, 1).toISOString(); 10582 } 10583 params = __assign({}, (extraParams || {}), { key: apiKey, timeMin: startStr, timeMax: endStr, singleEvents: true, maxResults: 9999 }); 10584 if (dateEnv.timeZone !== 'local') { 10585 params.timeZone = dateEnv.timeZone; 10586 } 10587 return params; 10588 } 10589 function gcalItemsToRawEventDefs(items, gcalTimezone) { 10590 return items.map(function (item) { 10591 return gcalItemToRawEventDef(item, gcalTimezone); 10592 }); 10593 } 10594 function gcalItemToRawEventDef(item, gcalTimezone) { 10595 var url = item.htmlLink || null; 10596 // make the URLs for each event show times in the correct timezone 10597 if (url && gcalTimezone) { 10598 url = injectQsComponent(url, 'ctz=' + gcalTimezone); 10599 } 10600 return { 10601 id: item.id, 10602 title: item.summary, 10603 start: item.start.dateTime || item.start.date, 10604 end: item.end.dateTime || item.end.date, 10605 url: url, 10606 location: item.location, 10607 description: item.description 10608 }; 10609 } 10610 // Injects a string like "arg=value" into the querystring of a URL 10611 // TODO: move to a general util file? 10612 function injectQsComponent(url, component) { 10613 // inject it after the querystring but before the fragment 10614 return url.replace(/(\?.*?)?(#|$)/, function (whole, qs, hash) { 10615 return (qs ? qs + '&' : '?') + component + hash; 10616 }); 10617 } 10618 var main = core.createPlugin({ 10619 eventSourceDefs: [eventSourceDef] 10620 }); 10621 10622 exports.default = main; 10623 10624 Object.defineProperty(exports, '__esModule', { value: true }); 10625 10626})); 10627 10628},{"@fullcalendar/core":2}],5:[function(require,module,exports){ 10629/*! 10630FullCalendar Interaction Plugin v4.3.0 10631Docs & License: https://fullcalendar.io/ 10632(c) 2019 Adam Shaw 10633*/ 10634 10635(function (global, factory) { 10636 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core')) : 10637 typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core'], factory) : 10638 (global = global || self, factory(global.FullCalendarInteraction = {}, global.FullCalendar)); 10639}(this, function (exports, core) { 'use strict'; 10640 10641 /*! ***************************************************************************** 10642 Copyright (c) Microsoft Corporation. All rights reserved. 10643 Licensed under the Apache License, Version 2.0 (the "License"); you may not use 10644 this file except in compliance with the License. You may obtain a copy of the 10645 License at http://www.apache.org/licenses/LICENSE-2.0 10646 10647 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 10648 KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 10649 WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 10650 MERCHANTABLITY OR NON-INFRINGEMENT. 10651 10652 See the Apache Version 2.0 License for specific language governing permissions 10653 and limitations under the License. 10654 ***************************************************************************** */ 10655 /* global Reflect, Promise */ 10656 10657 var extendStatics = function(d, b) { 10658 extendStatics = Object.setPrototypeOf || 10659 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 10660 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; 10661 return extendStatics(d, b); 10662 }; 10663 10664 function __extends(d, b) { 10665 extendStatics(d, b); 10666 function __() { this.constructor = d; } 10667 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 10668 } 10669 10670 var __assign = function() { 10671 __assign = Object.assign || function __assign(t) { 10672 for (var s, i = 1, n = arguments.length; i < n; i++) { 10673 s = arguments[i]; 10674 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 10675 } 10676 return t; 10677 }; 10678 return __assign.apply(this, arguments); 10679 }; 10680 10681 core.config.touchMouseIgnoreWait = 500; 10682 var ignoreMouseDepth = 0; 10683 var listenerCnt = 0; 10684 var isWindowTouchMoveCancelled = false;
10685 /* 10686 Uses a "pointer" abstraction, which monitors UI events for both mouse and touch. 10687 Tracks when the pointer "drags" on a certain element, meaning down+move+up. 10688 10689 Also, tracks if there was touch-scrolling. 10690 Also, can prevent touch-scrolling from happening. 10691 Also, can fire pointermove events when scrolling happens underneath, even when no real pointer movement. 10692 10693 emits: 10694 - pointerdown 10695 - pointermove 10696 - pointerup 10697 */ 10698 var PointerDragging = /** @class */ (function () { 10699 function PointerDragging(containerEl) { 10700 var _this = this; 10701 this.subjectEl = null; 10702 this.downEl = null; 10703 // options that can be directly assigned by caller 10704 this.selector = ''; // will cause subjectEl in all emitted events to be this element 10705 this.handleSelector = ''; 10706 this.shouldIgnoreMove = false; 10707 this.shouldWatchScroll = true; // for simulating pointermove on scroll 10708 // internal states 10709 this.isDragging = false; 10710 this.isTouchDragging = false; 10711 this.wasTouchScroll = false; 10712 // Mouse 10713 // ---------------------------------------------------------------------------------------------------- 10714 this.handleMouseDown = function (ev) { 10715 if (!_this.shouldIgnoreMouse() && 10716 isPrimaryMouseButton(ev) && 10717 _this.tryStart(ev)) { 10718 var pev = _this.createEventFromMouse(ev, true); 10719 _this.emitter.trigger('pointerdown', pev); 10720 _this.initScrollWatch(pev); 10721 if (!_this.shouldIgnoreMove) { 10722 document.addEventListener('mousemove', _this.handleMouseMove); 10723 } 10724 document.addEventListener('mouseup', _this.handleMouseUp); 10725 } 10726 }; 10727 this.handleMouseMove = function (ev) { 10728 var pev = _this.createEventFromMouse(ev); 10729 _this.recordCoords(pev); 10730 _this.emitter.trigger('pointermove', pev); 10731 }; 10732 this.handleMouseUp = function (ev) { 10733 document.removeEventListener('mousemove', _this.handleMouseMove); 10734 document.removeEventListener('mouseup', _this.handleMouseUp); 10735 _this.emitter.trigger('pointerup', _this.createEventFromMouse(ev)); 10736 _this.cleanup(); // call last so that pointerup has access to props 10737 }; 10738 // Touch 10739 // ---------------------------------------------------------------------------------------------------- 10740 this.handleTouchStart = function (ev) { 10741 if (_this.tryStart(ev)) { 10742 _this.isTouchDragging = true; 10743 var pev = _this.createEventFromTouch(ev, true); 10744 _this.emitter.trigger('pointerdown', pev); 10745 _this.initScrollWatch(pev); 10746 // unlike mouse, need to attach to target, not document 10747 // https://stackoverflow.com/a/45760014 10748 var target = ev.target; 10749 if (!_this.shouldIgnoreMove) { 10750 target.addEventListener('touchmove', _this.handleTouchMove); 10751 } 10752 target.addEventListener('touchend', _this.handleTouchEnd); 10753 target.addEventListener('touchcancel', _this.handleTouchEnd); // treat it as a touch end 10754 // attach a handler to get called when ANY scroll action happens on the page. 10755 // this was impossible to do with normal on/off because 'scroll' doesn't bubble. 10756 // http://stackoverflow.com/a/32954565/96342 10757 window.addEventListener('scroll', _this.handleTouchScroll, true // useCapture 10758 ); 10759 } 10760 }; 10761 this.handleTouchMove = function (ev) { 10762 var pev = _this.createEventFromTouch(ev); 10763 _this.recordCoords(pev); 10764 _this.emitter.trigger('pointermove', pev); 10765 }; 10766 this.handleTouchEnd = function (ev) { 10767 if (_this.isDragging) { // done to guard against touchend followed by touchcancel 10768 var target = ev.target; 10769 target.removeEventListener('touchmove', _this.handleTouchMove); 10770 target.removeEventListener('touchend', _this.handleTouchEnd); 10771 target.removeEventListener('touchcancel', _this.handleTouchEnd); 10772 window.removeEventListener('scroll', _this.handleTouchScroll, true); // useCaptured=true 10773 _this.emitter.trigger('pointerup', _this.createEventFromTouch(ev)); 10774 _this.cleanup(); // call last so that pointerup has access to props 10775 _this.isTouchDragging = false;
10776 startIgnoringMouse(); 10777 } 10778 }; 10779 this.handleTouchScroll = function () { 10780 _this.wasTouchScroll = true; 10781 }; 10782 this.handleScroll = function (ev) { 10783 if (!_this.shouldIgnoreMove) { 10784 var pageX = (window.pageXOffset - _this.prevScrollX) + _this.prevPageX; 10785 var pageY = (window.pageYOffset - _this.prevScrollY) + _this.prevPageY; 10786 _this.emitter.trigger('pointermove', { 10787 origEvent: ev, 10788 isTouch: _this.isTouchDragging, 10789 subjectEl: _this.subjectEl, 10790 pageX: pageX, 10791 pageY: pageY, 10792 deltaX: pageX - _this.origPageX, 10793 deltaY: pageY - _this.origPageY 10794 }); 10795 } 10796 }; 10797 this.containerEl = containerEl; 10798 this.emitter = new core.EmitterMixin(); 10799 containerEl.addEventListener('mousedown', this.handleMouseDown); 10800 containerEl.addEventListener('touchstart', this.handleTouchStart, { passive: true }); 10801 listenerCreated(); 10802 } 10803 PointerDragging.prototype.destroy = function () { 10804 this.containerEl.removeEventListener('mousedown', this.handleMouseDown); 10805 this.containerEl.removeEventListener('touchstart', this.handleTouchStart, { passive: true }); 10806 listenerDestroyed(); 10807 }; 10808 PointerDragging.prototype.tryStart = function (ev) { 10809 var subjectEl = this.querySubjectEl(ev); 10810 var downEl = ev.target; 10811 if (subjectEl && 10812 (!this.handleSelector || core.elementClosest(downEl, this.handleSelector))) { 10813 this.subjectEl = subjectEl; 10814 this.downEl = downEl; 10815 this.isDragging = true; // do this first so cancelTouchScroll will work 10816 this.wasTouchScroll = false; 10817 return true; 10818 } 10819 return false; 10820 }; 10821 PointerDragging.prototype.cleanup = function () { 10822 isWindowTouchMoveCancelled = false; 10823 this.isDragging = false; 10824 this.subjectEl = null; 10825 this.downEl = null; 10826 // keep wasTouchScroll around for later access 10827 this.destroyScrollWatch(); 10828 }; 10829 PointerDragging.prototype.querySubjectEl = function (ev) { 10830 if (this.selector) { 10831 return core.elementClosest(ev.target, this.selector); 10832 } 10833 else { 10834 return this.containerEl; 10835 } 10836 }; 10837 PointerDragging.prototype.shouldIgnoreMouse = function () { 10838 return ignoreMouseDepth || this.isTouchDragging; 10839 }; 10840 // can be called by user of this class, to cancel touch-based scrolling for the current drag 10841 PointerDragging.prototype.cancelTouchScroll = function () { 10842 if (this.isDragging) { 10843 isWindowTouchMoveCancelled = true; 10844 } 10845 }; 10846 // Scrolling that simulates pointermoves 10847 // ---------------------------------------------------------------------------------------------------- 10848 PointerDragging.prototype.initScrollWatch = function (ev) { 10849 if (this.shouldWatchScroll) { 10850 this.recordCoords(ev); 10851 window.addEventListener('scroll', this.handleScroll, true); // useCapture=true 10852 } 10853 }; 10854 PointerDragging.prototype.recordCoords = function (ev) { 10855 if (this.shouldWatchScroll) { 10856 this.prevPageX = ev.pageX; 10857 this.prevPageY = ev.pageY; 10858 this.prevScrollX = window.pageXOffset; 10859 this.prevScrollY = window.pageYOffset; 10860 } 10861 }; 10862 PointerDragging.prototype.destroyScrollWatch = function () { 10863 if (this.shouldWatchScroll) { 10864 window.removeEventListener('scroll', this.handleScroll, true); // useCaptured=true 10865 } 10866 }; 10867 // Event Normalization 10868 // ---------------------------------------------------------------------------------------------------- 10869 PointerDragging.prototype.createEventFromMouse = function (ev, isFirst) { 10870 var deltaX = 0; 10871 var deltaY = 0; 10872 // TODO: repeat code 10873 if (isFirst) { 10874 this.origPageX = ev.pageX; 10875 this.origPageY = ev.pageY; 10876 } 10877 else { 10878 deltaX = ev.pageX - this.origPageX; 10879 deltaY = ev.pageY - this.origPageY; 10880 } 10881 return { 10882 origEvent: ev, 10883 isTouch: false, 10884 subjectEl: this.subjectEl, 10885 pageX: ev.pageX, 10886 pageY: ev.pageY, 10887 deltaX: deltaX, 10888 deltaY: deltaY 10889 }; 10890 }; 10891 PointerDragging.prototype.createEventFromTouch = function (ev, isFirst) { 10892 var touches = ev.touches; 10893 var pageX; 10894 var pageY; 10895 var deltaX = 0; 10896 var deltaY = 0; 10897 // if touch coords available, prefer, 10898 // because FF would give bad ev.pageX ev.pageY 10899 if (touches && touches.length) { 10900 pageX = touches[0].pageX; 10901 pageY = touches[0].pageY; 10902 } 10903 else { 10904 pageX = ev.pageX; 10905 pageY = ev.pageY; 10906 } 10907 // TODO: repeat code 10908 if (isFirst) { 10909 this.origPageX = pageX; 10910 this.origPageY = pageY; 10911 } 10912 else { 10913 deltaX = pageX - this.origPageX; 10914 deltaY = pageY - this.origPageY; 10915 } 10916 return { 10917 origEvent: ev, 10918 isTouch: true, 10919 subjectEl: this.subjectEl, 10920 pageX: pageX, 10921 pageY: pageY, 10922 deltaX: deltaX, 10923 deltaY: deltaY 10924 }; 10925 }; 10926 return PointerDragging; 10927 }());
10928 // Returns a boolean whether this was a left mouse click and no ctrl key (which means right click on Mac) 10929 function isPrimaryMouseButton(ev) { 10930 return ev.button === 0 && !ev.ctrlKey; 10931 } 10932 // Ignoring fake mouse events generated by touch 10933 // ---------------------------------------------------------------------------------------------------- 10934 function startIgnoringMouse() { 10935 ignoreMouseDepth++; 10936 setTimeout(function () { 10937 ignoreMouseDepth--; 10938 }, core.config.touchMouseIgnoreWait); 10939 } 10940 // We want to attach touchmove as early as possible for Safari 10941 // ---------------------------------------------------------------------------------------------------- 10942 function listenerCreated() { 10943 if (!(listenerCnt++)) { 10944 window.addEventListener('touchmove', onWindowTouchMove, { passive: false }); 10945 } 10946 } 10947 function listenerDestroyed() { 10948 if (!(--listenerCnt)) { 10949 window.removeEventListener('touchmove', onWindowTouchMove, { passive: false }); 10950 } 10951 } 10952 function onWindowTouchMove(ev) { 10953 if (isWindowTouchMoveCancelled) { 10954 ev.preventDefault(); 10955 } 10956 } 10957 10958 /* 10959 An effect in which an element follows the movement of a pointer across the screen. 10960 The moving element is a clone of some other element. 10961 Must call start + handleMove + stop. 10962 */ 10963 var ElementMirror = /** @class */ (function () { 10964 function ElementMirror() { 10965 this.isVisible = false; // must be explicitly enabled 10966 this.sourceEl = null; 10967 this.mirrorEl = null; 10968 this.sourceElRect = null; // screen coords relative to viewport 10969 // options that can be set directly by caller 10970 this.parentNode = document.body; 10971 this.zIndex = 9999; 10972 this.revertDuration = 0; 10973 } 10974 ElementMirror.prototype.start = function (sourceEl, pageX, pageY) { 10975 this.sourceEl = sourceEl; 10976 this.sourceElRect = this.sourceEl.getBoundingClientRect(); 10977 this.origScreenX = pageX - window.pageXOffset; 10978 this.origScreenY = pageY - window.pageYOffset; 10979 this.deltaX = 0; 10980 this.deltaY = 0; 10981 this.updateElPosition(); 10982 }; 10983 ElementMirror.prototype.handleMove = function (pageX, pageY) { 10984 this.deltaX = (pageX - window.pageXOffset) - this.origScreenX; 10985 this.deltaY = (pageY - window.pageYOffset) - this.origScreenY; 10986 this.updateElPosition(); 10987 }; 10988 // can be called before start 10989 ElementMirror.prototype.setIsVisible = function (bool) { 10990 if (bool) { 10991 if (!this.isVisible) { 10992 if (this.mirrorEl) { 10993 this.mirrorEl.style.display = ''; 10994 } 10995 this.isVisible = bool; // needs to happen before updateElPosition 10996 this.updateElPosition(); // because was not updating the position while invisible 10997 } 10998 } 10999 else { 11000 if (this.isVisible) { 11001 if (this.mirrorEl) { 11002 this.mirrorEl.style.display = 'none'; 11003 } 11004 this.isVisible = bool; 11005 } 11006 } 11007 }; 11008 // always async 11009 ElementMirror.prototype.stop = function (needsRevertAnimation, callback) { 11010 var _this = this; 11011 var done = function () { 11012 _this.cleanup(); 11013 callback(); 11014 }; 11015 if (needsRevertAnimation && 11016 this.mirrorEl && 11017 this.isVisible && 11018 this.revertDuration && // if 0, transition won't work 11019 (this.deltaX || this.deltaY) // if same coords, transition won't work 11020 ) { 11021 this.doRevertAnimation(done, this.revertDuration); 11022 } 11023 else { 11024 setTimeout(done, 0); 11025 } 11026 }; 11027 ElementMirror.prototype.doRevertAnimation = function (callback, revertDuration) { 11028 var mirrorEl = this.mirrorEl; 11029 var finalSourceElRect = this.sourceEl.getBoundingClientRect(); // because autoscrolling might have happened 11030 mirrorEl.style.transition = 11031 'top ' + revertDuration + 'ms,' + 11032 'left ' + revertDuration + 'ms'; 11033 core.applyStyle(mirrorEl, { 11034 left: finalSourceElRect.left, 11035 top: finalSourceElRect.top 11036 }); 11037 core.whenTransitionDone(mirrorEl, function () { 11038 mirrorEl.style.transition = ''; 11039 callback(); 11040 }); 11041 }; 11042 ElementMirror.prototype.cleanup = function () { 11043 if (this.mirrorEl) { 11044 core.removeElement(this.mirrorEl); 11045 this.mirrorEl = null; 11046 } 11047 this.sourceEl = null; 11048 }; 11049 ElementMirror.prototype.updateElPosition = function () { 11050 if (this.sourceEl && this.isVisible) { 11051 core.applyStyle(this.getMirrorEl(), { 11052 left: this.sourceElRect.left + this.deltaX,
11053 top: this.sourceElRect.top + this.deltaY 11054 }); 11055 } 11056 }; 11057 ElementMirror.prototype.getMirrorEl = function () { 11058 var sourceElRect = this.sourceElRect; 11059 var mirrorEl = this.mirrorEl; 11060 if (!mirrorEl) { 11061 mirrorEl = this.mirrorEl = this.sourceEl.cloneNode(true); // cloneChildren=true 11062 // we don't want long taps or any mouse interaction causing selection/menus. 11063 // would use preventSelection(), but that prevents selectstart, causing problems. 11064 mirrorEl.classList.add('fc-unselectable'); 11065 mirrorEl.classList.add('fc-dragging'); 11066 core.applyStyle(mirrorEl, { 11067 position: 'fixed', 11068 zIndex: this.zIndex, 11069 visibility: '', 11070 boxSizing: 'border-box', 11071 width: sourceElRect.right - sourceElRect.left, 11072 height: sourceElRect.bottom - sourceElRect.top, 11073 right: 'auto', 11074 bottom: 'auto', 11075 margin: 0 11076 }); 11077 this.parentNode.appendChild(mirrorEl); 11078 } 11079 return mirrorEl; 11080 }; 11081 return ElementMirror; 11082 }()); 11083 11084 /* 11085 Is a cache for a given element's scroll information (all the info that ScrollController stores) 11086 in addition the "client rectangle" of the element.. the area within the scrollbars. 11087 11088 The cache can be in one of two modes: 11089 - doesListening:false - ignores when the container is scrolled by someone else 11090 - doesListening:true - watch for scrolling and update the cache 11091 */ 11092 var ScrollGeomCache = /** @class */ (function (_super) { 11093 __extends(ScrollGeomCache, _super); 11094 function ScrollGeomCache(scrollController, doesListening) { 11095 var _this = _super.call(this) || this; 11096 _this.handleScroll = function () { 11097 _this.scrollTop = _this.scrollController.getScrollTop(); 11098 _this.scrollLeft = _this.scrollController.getScrollLeft(); 11099 _this.handleScrollChange(); 11100 }; 11101 _this.scrollController = scrollController; 11102 _this.doesListening = doesListening; 11103 _this.scrollTop = _this.origScrollTop = scrollController.getScrollTop(); 11104 _this.scrollLeft = _this.origScrollLeft = scrollController.getScrollLeft();
11105 _this.scrollWidth = scrollController.getScrollWidth(); 11106 _this.scrollHeight = scrollController.getScrollHeight(); 11107 _this.clientWidth = scrollController.getClientWidth(); 11108 _this.clientHeight = scrollController.getClientHeight(); 11109 _this.clientRect = _this.computeClientRect(); // do last in case it needs cached values 11110 if (_this.doesListening) { 11111 _this.getEventTarget().addEventListener('scroll', _this.handleScroll); 11112 } 11113 return _this; 11114 } 11115 ScrollGeomCache.prototype.destroy = function () { 11116 if (this.doesListening) { 11117 this.getEventTarget().removeEventListener('scroll', this.handleScroll); 11118 } 11119 }; 11120 ScrollGeomCache.prototype.getScrollTop = function () { 11121 return this.scrollTop; 11122 }; 11123 ScrollGeomCache.prototype.getScrollLeft = function () { 11124 return this.scrollLeft; 11125 }; 11126 ScrollGeomCache.prototype.setScrollTop = function (top) { 11127 this.scrollController.setScrollTop(top); 11128 if (!this.doesListening) { 11129 // we are not relying on the element to normalize out-of-bounds scroll values 11130 // so we need to sanitize ourselves 11131 this.scrollTop = Math.max(Math.min(top, this.getMaxScrollTop()), 0); 11132 this.handleScrollChange(); 11133 } 11134 }; 11135 ScrollGeomCache.prototype.setScrollLeft = function (top) { 11136 this.scrollController.setScrollLeft(top); 11137 if (!this.doesListening) { 11138 // we are not relying on the element to normalize out-of-bounds scroll values 11139 // so we need to sanitize ourselves 11140 this.scrollLeft = Math.max(Math.min(top, this.getMaxScrollLeft()), 0); 11141 this.handleScrollChange(); 11142 } 11143 }; 11144 ScrollGeomCache.prototype.getClientWidth = function () { 11145 return this.clientWidth; 11146 }; 11147 ScrollGeomCache.prototype.getClientHeight = function () { 11148 return this.clientHeight; 11149 }; 11150 ScrollGeomCache.prototype.getScrollWidth = function () { 11151 return this.scrollWidth; 11152 }; 11153 ScrollGeomCache.prototype.getScrollHeight = function () { 11154 return this.scrollHeight; 11155 }; 11156 ScrollGeomCache.prototype.handleScrollChange = function () { 11157 }; 11158 return ScrollGeomCache; 11159 }(core.ScrollController)); 11160 var ElementScrollGeomCache = /** @class */ (function (_super) { 11161 __extends(ElementScrollGeomCache, _super); 11162 function ElementScrollGeomCache(el, doesListening) { 11163 return _super.call(this, new core.ElementScrollController(el), doesListening) || this; 11164 } 11165 ElementScrollGeomCache.prototype.getEventTarget = function () { 11166 return this.scrollController.el; 11167 }; 11168 ElementScrollGeomCache.prototype.computeClientRect = function () { 11169 return core.computeInnerRect(this.scrollController.el); 11170 }; 11171 return ElementScrollGeomCache; 11172 }(ScrollGeomCache)); 11173 var WindowScrollGeomCache = /** @class */ (function (_super) { 11174 __extends(WindowScrollGeomCache, _super); 11175 function WindowScrollGeomCache(doesListening) { 11176 return _super.call(this, new core.WindowScrollController(), doesListening) || this; 11177 } 11178 WindowScrollGeomCache.prototype.getEventTarget = function () { 11179 return window; 11180 }; 11181 WindowScrollGeomCache.prototype.computeClientRect = function () { 11182 return { 11183 left: this.scrollLeft, 11184 right: this.scrollLeft + this.clientWidth, 11185 top: this.scrollTop, 11186 bottom: this.scrollTop + this.clientHeight 11187 }; 11188 }; 11189 // the window is the only scroll object that changes it's rectangle relative 11190 // to the document's topleft as it scrolls 11191 WindowScrollGeomCache.prototype.handleScrollChange = function () { 11192 this.clientRect = this.computeClientRect(); 11193 }; 11194 return WindowScrollGeomCache; 11195 }(ScrollGeomCache)); 11196 11197 // If available we are using native "performance" API instead of "Date" 11198 // Read more about it on MDN: 11199 // https://developer.mozilla.org/en-US/docs/Web/API/Performance 11200 var getTime = typeof performance === 'function' ? performance.now : Date.now; 11201 /* 11202 For a pointer interaction, automatically scrolls certain scroll containers when the pointer 11203 approaches the edge. 11204 11205 The caller must call start + handleMove + stop. 11206 */ 11207 var AutoScroller = /** @class */ (function () { 11208 function AutoScroller() { 11209 var _this = this; 11210 // options that can be set by caller 11211 this.isEnabled = true; 11212 this.scrollQuery = [window, '.fc-scroller']; 11213 this.edgeThreshold = 50; // pixels 11214 this.maxVelocity = 300; // pixels per second 11215 // internal state 11216 this.pointerScreenX = null; 11217 this.pointerScreenY = null; 11218 this.isAnimating = false;
11219 this.scrollCaches = null; 11220 // protect against the initial pointerdown being too close to an edge and starting the scroll 11221 this.everMovedUp = false; 11222 this.everMovedDown = false; 11223 this.everMovedLeft = false; 11224 this.everMovedRight = false; 11225 this.animate = function () { 11226 if (_this.isAnimating) { // wasn't cancelled between animation calls 11227 var edge = _this.computeBestEdge(_this.pointerScreenX + window.pageXOffset, _this.pointerScreenY + window.pageYOffset); 11228 if (edge) { 11229 var now = getTime(); 11230 _this.handleSide(edge, (now - _this.msSinceRequest) / 1000); 11231 _this.requestAnimation(now); 11232 } 11233 else { 11234 _this.isAnimating = false; // will stop animation 11235 } 11236 } 11237 }; 11238 } 11239 AutoScroller.prototype.start = function (pageX, pageY) { 11240 if (this.isEnabled) { 11241 this.scrollCaches = this.buildCaches(); 11242 this.pointerScreenX = null; 11243 this.pointerScreenY = null; 11244 this.everMovedUp = false; 11245 this.everMovedDown = false; 11246 this.everMovedLeft = false; 11247 this.everMovedRight = false; 11248 this.handleMove(pageX, pageY); 11249 } 11250 }; 11251 AutoScroller.prototype.handleMove = function (pageX, pageY) { 11252 if (this.isEnabled) { 11253 var pointerScreenX = pageX - window.pageXOffset; 11254 var pointerScreenY = pageY - window.pageYOffset; 11255 var yDelta = this.pointerScreenY === null ? 0 : pointerScreenY - this.pointerScreenY; 11256 var xDelta = this.pointerScreenX === null ? 0 : pointerScreenX - this.pointerScreenX; 11257 if (yDelta < 0) { 11258 this.everMovedUp = true; 11259 } 11260 else if (yDelta > 0) { 11261 this.everMovedDown = true; 11262 } 11263 if (xDelta < 0) { 11264 this.everMovedLeft = true; 11265 } 11266 else if (xDelta > 0) { 11267 this.everMovedRight = true; 11268 } 11269 this.pointerScreenX = pointerScreenX; 11270 this.pointerScreenY = pointerScreenY; 11271 if (!this.isAnimating) { 11272 this.isAnimating = true; 11273 this.requestAnimation(getTime()); 11274 } 11275 } 11276 }; 11277 AutoScroller.prototype.stop = function () { 11278 if (this.isEnabled) { 11279 this.isAnimating = false; // will stop animation 11280 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 11281 var scrollCache = _a[_i]; 11282 scrollCache.destroy(); 11283 } 11284 this.scrollCaches = null; 11285 } 11286 }; 11287 AutoScroller.prototype.requestAnimation = function (now) { 11288 this.msSinceRequest = now; 11289 requestAnimationFrame(this.animate); 11290 }; 11291 AutoScroller.prototype.handleSide = function (edge, seconds) { 11292 var scrollCache = edge.scrollCache; 11293 var edgeThreshold = this.edgeThreshold; 11294 var invDistance = edgeThreshold - edge.distance; 11295 var velocity = // the closer to the edge, the faster we scroll 11296 (invDistance * invDistance) / (edgeThreshold * edgeThreshold) * // quadratic 11297 this.maxVelocity * seconds; 11298 var sign = 1; 11299 switch (edge.name) { 11300 case 'left': 11301 sign = -1; 11302 // falls through 11303 case 'right': 11304 scrollCache.setScrollLeft(scrollCache.getScrollLeft() + velocity * sign); 11305 break; 11306 case 'top': 11307 sign = -1; 11308 // falls through 11309 case 'bottom': 11310 scrollCache.setScrollTop(scrollCache.getScrollTop() + velocity * sign); 11311 break; 11312 } 11313 }; 11314 // left/top are relative to document topleft 11315 AutoScroller.prototype.computeBestEdge = function (left, top) { 11316 var edgeThreshold = this.edgeThreshold; 11317 var bestSide = null; 11318 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 11319 var scrollCache = _a[_i]; 11320 var rect = scrollCache.clientRect; 11321 var leftDist = left - rect.left; 11322 var rightDist = rect.right - left; 11323 var topDist = top - rect.top; 11324 var bottomDist = rect.bottom - top; 11325 // completely within the rect? 11326 if (leftDist >= 0 && rightDist >= 0 && topDist >= 0 && bottomDist >= 0) { 11327 if (topDist <= edgeThreshold && this.everMovedUp && scrollCache.canScrollUp() && 11328 (!bestSide || bestSide.distance > topDist)) { 11329 bestSide = { scrollCache: scrollCache, name: 'top', distance: topDist }; 11330 } 11331 if (bottomDist <= edgeThreshold && this.everMovedDown && scrollCache.canScrollDown() && 11332 (!bestSide || bestSide.distance > bottomDist)) { 11333 bestSide = { scrollCache: scrollCache, name: 'bottom', distance: bottomDist }; 11334 } 11335 if (leftDist <= edgeThreshold && this.everMovedLeft && scrollCache.canScrollLeft() && 11336 (!bestSide || bestSide.distance > leftDist)) { 11337 bestSide = { scrollCache: scrollCache, name: 'left', distance: leftDist }; 11338 } 11339 if (rightDist <= edgeThreshold && this.everMovedRight && scrollCache.canScrollRight() && 11340 (!bestSide || bestSide.distance > rightDist)) { 11341 bestSide = { scrollCache: scrollCache, name: 'right', distance: rightDist }; 11342 } 11343 } 11344 } 11345 return bestSide; 11346 }; 11347 AutoScroller.prototype.buildCaches = function () { 11348 return this.queryScrollEls().map(function (el) { 11349 if (el === window) { 11350 return new WindowScrollGeomCache(false); // false = don't listen to user-generated scrolls 11351 } 11352 else { 11353 return new ElementScrollGeomCache(el, false); // false = don't listen to user-generated scrolls 11354 } 11355 }); 11356 }; 11357 AutoScroller.prototype.queryScrollEls = function () { 11358 var els = []; 11359 for (var _i = 0, _a = this.scrollQuery; _i < _a.length; _i++) { 11360 var query = _a[_i]; 11361 if (typeof query === 'object') { 11362 els.push(query); 11363 } 11364 else { 11365 els.push.apply(els, Array.prototype.slice.call(document.querySelectorAll(query))); 11366 } 11367 } 11368 return els; 11369 }; 11370 return AutoScroller; 11371 }()); 11372 11373 /* 11374 Monitors dragging on an element. Has a number of high-level features: 11375 - minimum distance required before dragging 11376 - minimum wait time ("delay") before dragging 11377 - a mirror element that follows the pointer 11378 */ 11379 var FeaturefulElementDragging = /** @class */ (function (_super) { 11380 __extends(FeaturefulElementDragging, _super); 11381 function FeaturefulElementDragging(containerEl) { 11382 var _this = _super.call(this, containerEl) || this; 11383 // options that can be directly set by caller 11384 // the caller can also set the PointerDragging's options as well 11385 _this.delay = null; 11386 _this.minDistance = 0; 11387 _this.touchScrollAllowed = true; // prevents drag from starting and blocks scrolling during drag 11388 _this.mirrorNeedsRevert = false;
11389 _this.isInteracting = false; // is the user validly moving the pointer? lasts until pointerup 11390 _this.isDragging = false; // is it INTENTFULLY dragging? lasts until after revert animation 11391 _this.isDelayEnded = false; 11392 _this.isDistanceSurpassed = false; 11393 _this.delayTimeoutId = null; 11394 _this.onPointerDown = function (ev) { 11395 if (!_this.isDragging) { // so new drag doesn't happen while revert animation is going 11396 _this.isInteracting = true; 11397 _this.isDelayEnded = false; 11398 _this.isDistanceSurpassed = false; 11399 core.preventSelection(document.body); 11400 core.preventContextMenu(document.body); 11401 // prevent links from being visited if there's an eventual drag. 11402 // also prevents selection in older browsers (maybe?). 11403 // not necessary for touch, besides, browser would complain about passiveness. 11404 if (!ev.isTouch) { 11405 ev.origEvent.preventDefault(); 11406 } 11407 _this.emitter.trigger('pointerdown', ev); 11408 if (!_this.pointer.shouldIgnoreMove) { 11409 // actions related to initiating dragstart+dragmove+dragend... 11410 _this.mirror.setIsVisible(false); // reset. caller must set-visible 11411 _this.mirror.start(ev.subjectEl, ev.pageX, ev.pageY); // must happen on first pointer down 11412 _this.startDelay(ev); 11413 if (!_this.minDistance) { 11414 _this.handleDistanceSurpassed(ev); 11415 } 11416 } 11417 } 11418 }; 11419 _this.onPointerMove = function (ev) { 11420 if (_this.isInteracting) { // if false, still waiting for previous drag's revert 11421 _this.emitter.trigger('pointermove', ev); 11422 if (!_this.isDistanceSurpassed) { 11423 var minDistance = _this.minDistance; 11424 var distanceSq = void 0; // current distance from the origin, squared 11425 var deltaX = ev.deltaX, deltaY = ev.deltaY; 11426 distanceSq = deltaX * deltaX + deltaY * deltaY; 11427 if (distanceSq >= minDistance * minDistance) { // use pythagorean theorem 11428 _this.handleDistanceSurpassed(ev); 11429 } 11430 } 11431 if (_this.isDragging) { 11432 // a real pointer move? (not one simulated by scrolling) 11433 if (ev.origEvent.type !== 'scroll') { 11434 _this.mirror.handleMove(ev.pageX, ev.pageY); 11435 _this.autoScroller.handleMove(ev.pageX, ev.pageY); 11436 } 11437 _this.emitter.trigger('dragmove', ev); 11438 } 11439 } 11440 }; 11441 _this.onPointerUp = function (ev) { 11442 if (_this.isInteracting) { // if false, still waiting for previous drag's revert 11443 _this.isInteracting = false; 11444 core.allowSelection(document.body); 11445 core.allowContextMenu(document.body); 11446 _this.emitter.trigger('pointerup', ev); // can potentially set mirrorNeedsRevert 11447 if (_this.isDragging) { 11448 _this.autoScroller.stop(); 11449 _this.tryStopDrag(ev); // which will stop the mirror 11450 } 11451 if (_this.delayTimeoutId) { 11452 clearTimeout(_this.delayTimeoutId); 11453 _this.delayTimeoutId = null; 11454 } 11455 } 11456 }; 11457 var pointer = _this.pointer = new PointerDragging(containerEl); 11458 pointer.emitter.on('pointerdown', _this.onPointerDown); 11459 pointer.emitter.on('pointermove', _this.onPointerMove); 11460 pointer.emitter.on('pointerup', _this.onPointerUp); 11461 _this.mirror = new ElementMirror(); 11462 _this.autoScroller = new AutoScroller(); 11463 return _this; 11464 } 11465 FeaturefulElementDragging.prototype.destroy = function () { 11466 this.pointer.destroy(); 11467 }; 11468 FeaturefulElementDragging.prototype.startDelay = function (ev) { 11469 var _this = this; 11470 if (typeof this.delay === 'number') { 11471 this.delayTimeoutId = setTimeout(function () { 11472 _this.delayTimeoutId = null; 11473 _this.handleDelayEnd(ev); 11474 }, this.delay); // not assignable to number! 11475 } 11476 else { 11477 this.handleDelayEnd(ev); 11478 } 11479 }; 11480 FeaturefulElementDragging.prototype.handleDelayEnd = function (ev) { 11481 this.isDelayEnded = true; 11482 this.tryStartDrag(ev); 11483 }; 11484 FeaturefulElementDragging.prototype.handleDistanceSurpassed = function (ev) { 11485 this.isDistanceSurpassed = true; 11486 this.tryStartDrag(ev); 11487 }; 11488 FeaturefulElementDragging.prototype.tryStartDrag = function (ev) { 11489 if (this.isDelayEnded && this.isDistanceSurpassed) { 11490 if (!this.pointer.wasTouchScroll || this.touchScrollAllowed) { 11491 this.isDragging = true; 11492 this.mirrorNeedsRevert = false;
11493 this.autoScroller.start(ev.pageX, ev.pageY); 11494 this.emitter.trigger('dragstart', ev); 11495 if (this.touchScrollAllowed === false) { 11496 this.pointer.cancelTouchScroll(); 11497 } 11498 } 11499 } 11500 }; 11501 FeaturefulElementDragging.prototype.tryStopDrag = function (ev) { 11502 // .stop() is ALWAYS asynchronous, which we NEED because we want all pointerup events 11503 // that come from the document to fire beforehand. much more convenient this way. 11504 this.mirror.stop(this.mirrorNeedsRevert, this.stopDrag.bind(this, ev) // bound with args 11505 ); 11506 }; 11507 FeaturefulElementDragging.prototype.stopDrag = function (ev) { 11508 this.isDragging = false; 11509 this.emitter.trigger('dragend', ev); 11510 }; 11511 // fill in the implementations... 11512 FeaturefulElementDragging.prototype.setIgnoreMove = function (bool) { 11513 this.pointer.shouldIgnoreMove = bool; 11514 }; 11515 FeaturefulElementDragging.prototype.setMirrorIsVisible = function (bool) { 11516 this.mirror.setIsVisible(bool); 11517 }; 11518 FeaturefulElementDragging.prototype.setMirrorNeedsRevert = function (bool) { 11519 this.mirrorNeedsRevert = bool; 11520 }; 11521 FeaturefulElementDragging.prototype.setAutoScrollEnabled = function (bool) { 11522 this.autoScroller.isEnabled = bool; 11523 }; 11524 return FeaturefulElementDragging; 11525 }(core.ElementDragging)); 11526 11527 /* 11528 When this class is instantiated, it records the offset of an element (relative to the document topleft), 11529 and continues to monitor scrolling, updating the cached coordinates if it needs to. 11530 Does not access the DOM after instantiation, so highly performant. 11531 11532 Also keeps track of all scrolling/overflow:hidden containers that are parents of the given element 11533 and an determine if a given point is inside the combined clipping rectangle. 11534 */ 11535 var OffsetTracker = /** @class */ (function () { 11536 function OffsetTracker(el) { 11537 this.origRect = core.computeRect(el); 11538 // will work fine for divs that have overflow:hidden 11539 this.scrollCaches = core.getClippingParents(el).map(function (el) { 11540 return new ElementScrollGeomCache(el, true); // listen=true 11541 }); 11542 } 11543 OffsetTracker.prototype.destroy = function () { 11544 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 11545 var scrollCache = _a[_i]; 11546 scrollCache.destroy(); 11547 } 11548 }; 11549 OffsetTracker.prototype.computeLeft = function () { 11550 var left = this.origRect.left; 11551 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 11552 var scrollCache = _a[_i]; 11553 left += scrollCache.origScrollLeft - scrollCache.getScrollLeft(); 11554 } 11555 return left; 11556 }; 11557 OffsetTracker.prototype.computeTop = function () { 11558 var top = this.origRect.top; 11559 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 11560 var scrollCache = _a[_i]; 11561 top += scrollCache.origScrollTop - scrollCache.getScrollTop(); 11562 } 11563 return top; 11564 }; 11565 OffsetTracker.prototype.isWithinClipping = function (pageX, pageY) { 11566 var point = { left: pageX, top: pageY }; 11567 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 11568 var scrollCache = _a[_i]; 11569 if (!isIgnoredClipping(scrollCache.getEventTarget()) && 11570 !core.pointInsideRect(point, scrollCache.clientRect)) { 11571 return false; 11572 } 11573 } 11574 return true; 11575 }; 11576 return OffsetTracker; 11577 }()); 11578 // certain clipping containers should never constrain interactions, like <html> and <body> 11579 // https://github.com/fullcalendar/fullcalendar/issues/3615 11580 function isIgnoredClipping(node) { 11581 var tagName = node.tagName; 11582 return tagName === 'HTML' || tagName === 'BODY'; 11583 } 11584 11585 /* 11586 Tracks movement over multiple droppable areas (aka "hits") 11587 that exist in one or more DateComponents. 11588 Relies on an existing draggable. 11589 11590 emits: 11591 - pointerdown 11592 - dragstart 11593 - hitchange - fires initially, even if not over a hit 11594 - pointerup 11595 - (hitchange - again, to null, if ended over a hit) 11596 - dragend 11597 */ 11598 var HitDragging = /** @class */ (function () { 11599 function HitDragging(dragging, droppableStore) { 11600 var _this = this; 11601 // options that can be set by caller 11602 this.useSubjectCenter = false;
11603 this.requireInitial = true; // if doesn't start out on a hit, won't emit any events 11604 this.initialHit = null; 11605 this.movingHit = null; 11606 this.finalHit = null; // won't ever be populated if shouldIgnoreMove 11607 this.handlePointerDown = function (ev) { 11608 var dragging = _this.dragging; 11609 _this.initialHit = null; 11610 _this.movingHit = null; 11611 _this.finalHit = null; 11612 _this.prepareHits(); 11613 _this.processFirstCoord(ev); 11614 if (_this.initialHit || !_this.requireInitial) { 11615 dragging.setIgnoreMove(false); 11616 _this.emitter.trigger('pointerdown', ev); // TODO: fire this before computing processFirstCoord, so listeners can cancel. this gets fired by almost every handler :( 11617 } 11618 else { 11619 dragging.setIgnoreMove(true); 11620 } 11621 }; 11622 this.handleDragStart = function (ev) { 11623 _this.emitter.trigger('dragstart', ev); 11624 _this.handleMove(ev, true); // force = fire even if initially null 11625 }; 11626 this.handleDragMove = function (ev) { 11627 _this.emitter.trigger('dragmove', ev); 11628 _this.handleMove(ev); 11629 }; 11630 this.handlePointerUp = function (ev) { 11631 _this.releaseHits(); 11632 _this.emitter.trigger('pointerup', ev); 11633 }; 11634 this.handleDragEnd = function (ev) { 11635 if (_this.movingHit) { 11636 _this.emitter.trigger('hitupdate', null, true, ev); 11637 } 11638 _this.finalHit = _this.movingHit; 11639 _this.movingHit = null; 11640 _this.emitter.trigger('dragend', ev); 11641 }; 11642 this.droppableStore = droppableStore; 11643 dragging.emitter.on('pointerdown', this.handlePointerDown); 11644 dragging.emitter.on('dragstart', this.handleDragStart); 11645 dragging.emitter.on('dragmove', this.handleDragMove); 11646 dragging.emitter.on('pointerup', this.handlePointerUp); 11647 dragging.emitter.on('dragend', this.handleDragEnd); 11648 this.dragging = dragging; 11649 this.emitter = new core.EmitterMixin(); 11650 } 11651 // sets initialHit 11652 // sets coordAdjust 11653 HitDragging.prototype.processFirstCoord = function (ev) { 11654 var origPoint = { left: ev.pageX, top: ev.pageY }; 11655 var adjustedPoint = origPoint; 11656 var subjectEl = ev.subjectEl; 11657 var subjectRect; 11658 if (subjectEl !== document) { 11659 subjectRect = core.computeRect(subjectEl); 11660 adjustedPoint = core.constrainPoint(adjustedPoint, subjectRect); 11661 } 11662 var initialHit = this.initialHit = this.queryHitForOffset(adjustedPoint.left, adjustedPoint.top); 11663 if (initialHit) { 11664 if (this.useSubjectCenter && subjectRect) { 11665 var slicedSubjectRect = core.intersectRects(subjectRect, initialHit.rect); 11666 if (slicedSubjectRect) { 11667 adjustedPoint = core.getRectCenter(slicedSubjectRect); 11668 } 11669 } 11670 this.coordAdjust = core.diffPoints(adjustedPoint, origPoint); 11671 } 11672 else { 11673 this.coordAdjust = { left: 0, top: 0 }; 11674 } 11675 }; 11676 HitDragging.prototype.handleMove = function (ev, forceHandle) { 11677 var hit = this.queryHitForOffset(ev.pageX + this.coordAdjust.left, ev.pageY + this.coordAdjust.top); 11678 if (forceHandle || !isHitsEqual(this.movingHit, hit)) { 11679 this.movingHit = hit; 11680 this.emitter.trigger('hitupdate', hit, false, ev); 11681 } 11682 }; 11683 HitDragging.prototype.prepareHits = function () { 11684 this.offsetTrackers = core.mapHash(this.droppableStore, function (interactionSettings) { 11685 interactionSettings.component.buildPositionCaches(); 11686 return new OffsetTracker(interactionSettings.el); 11687 }); 11688 }; 11689 HitDragging.prototype.releaseHits = function () { 11690 var offsetTrackers = this.offsetTrackers; 11691 for (var id in offsetTrackers) { 11692 offsetTrackers[id].destroy(); 11693 } 11694 this.offsetTrackers = {}; 11695 }; 11696 HitDragging.prototype.queryHitForOffset = function (offsetLeft, offsetTop) { 11697 var _a = this, droppableStore = _a.droppableStore, offsetTrackers = _a.offsetTrackers; 11698 var bestHit = null; 11699 for (var id in droppableStore) { 11700 var component = droppableStore[id].component; 11701 var offsetTracker = offsetTrackers[id]; 11702 if (offsetTracker.isWithinClipping(offsetLeft, offsetTop)) { 11703 var originLeft = offsetTracker.computeLeft(); 11704 var originTop = offsetTracker.computeTop(); 11705 var positionLeft = offsetLeft - originLeft; 11706 var positionTop = offsetTop - originTop; 11707 var origRect = offsetTracker.origRect; 11708 var width = origRect.right - origRect.left; 11709 var height = origRect.bottom - origRect.top; 11710 if ( 11711 // must be within the element's bounds 11712 positionLeft >= 0 && positionLeft < width && 11713 positionTop >= 0 && positionTop < height) { 11714 var hit = component.queryHit(positionLeft, positionTop, width, height); 11715 if (hit && 11716 ( 11717 // make sure the hit is within activeRange, meaning it's not a deal cell 11718 !component.props.dateProfile || // hack for DayTile 11719 core.rangeContainsRange(component.props.dateProfile.activeRange, hit.dateSpan.range)) && 11720 (!bestHit || hit.layer > bestHit.layer)) { 11721 // TODO: better way to re-orient rectangle 11722 hit.rect.left += originLeft; 11723 hit.rect.right += originLeft; 11724 hit.rect.top += originTop; 11725 hit.rect.bottom += originTop; 11726 bestHit = hit; 11727 } 11728 } 11729 } 11730 } 11731 return bestHit; 11732 }; 11733 return HitDragging; 11734 }()); 11735 function isHitsEqual(hit0, hit1) { 11736 if (!hit0 && !hit1) { 11737 return true; 11738 } 11739 if (Boolean(hit0) !== Boolean(hit1)) { 11740 return false;
11741 } 11742 return core.isDateSpansEqual(hit0.dateSpan, hit1.dateSpan); 11743 } 11744 11745 /* 11746 Monitors when the user clicks on a specific date/time of a component. 11747 A pointerdown+pointerup on the same "hit" constitutes a click. 11748 */ 11749 var DateClicking = /** @class */ (function (_super) { 11750 __extends(DateClicking, _super); 11751 function DateClicking(settings) { 11752 var _this = _super.call(this, settings) || this; 11753 _this.handlePointerDown = function (ev) { 11754 var dragging = _this.dragging; 11755 // do this in pointerdown (not dragend) because DOM might be mutated by the time dragend is fired 11756 dragging.setIgnoreMove(!_this.component.isValidDateDownEl(dragging.pointer.downEl)); 11757 }; 11758 // won't even fire if moving was ignored 11759 _this.handleDragEnd = function (ev) { 11760 var component = _this.component; 11761 var pointer = _this.dragging.pointer; 11762 if (!pointer.wasTouchScroll) { 11763 var _a = _this.hitDragging, initialHit = _a.initialHit, finalHit = _a.finalHit; 11764 if (initialHit && finalHit && isHitsEqual(initialHit, finalHit)) { 11765 component.calendar.triggerDateClick(initialHit.dateSpan, initialHit.dayEl, component.view, ev.origEvent); 11766 } 11767 } 11768 }; 11769 var component = settings.component; 11770 // we DO want to watch pointer moves because otherwise finalHit won't get populated 11771 _this.dragging = new FeaturefulElementDragging(component.el); 11772 _this.dragging.autoScroller.isEnabled = false; 11773 var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, core.interactionSettingsToStore(settings)); 11774 hitDragging.emitter.on('pointerdown', _this.handlePointerDown); 11775 hitDragging.emitter.on('dragend', _this.handleDragEnd); 11776 return _this; 11777 } 11778 DateClicking.prototype.destroy = function () { 11779 this.dragging.destroy(); 11780 }; 11781 return DateClicking; 11782 }(core.Interaction)); 11783 11784 /* 11785 Tracks when the user selects a portion of time of a component, 11786 constituted by a drag over date cells, with a possible delay at the beginning of the drag. 11787 */ 11788 var DateSelecting = /** @class */ (function (_super) { 11789 __extends(DateSelecting, _super); 11790 function DateSelecting(settings) { 11791 var _this = _super.call(this, settings) || this; 11792 _this.dragSelection = null; 11793 _this.handlePointerDown = function (ev) { 11794 var _a = _this, component = _a.component, dragging = _a.dragging; 11795 var canSelect = component.opt('selectable') && 11796 component.isValidDateDownEl(ev.origEvent.target); 11797 // don't bother to watch expensive moves if component won't do selection 11798 dragging.setIgnoreMove(!canSelect); 11799 // if touch, require user to hold down 11800 dragging.delay = ev.isTouch ? getComponentTouchDelay(component) : null; 11801 }; 11802 _this.handleDragStart = function (ev) { 11803 _this.component.calendar.unselect(ev); // unselect previous selections 11804 }; 11805 _this.handleHitUpdate = function (hit, isFinal) { 11806 var calendar = _this.component.calendar; 11807 var dragSelection = null; 11808 var isInvalid = false; 11809 if (hit) { 11810 dragSelection = joinHitsIntoSelection(_this.hitDragging.initialHit, hit, calendar.pluginSystem.hooks.dateSelectionTransformers); 11811 if (!dragSelection || !_this.component.isDateSelectionValid(dragSelection)) { 11812 isInvalid = true; 11813 dragSelection = null; 11814 } 11815 } 11816 if (dragSelection) { 11817 calendar.dispatch({ type: 'SELECT_DATES', selection: dragSelection }); 11818 } 11819 else if (!isFinal) { // only unselect if moved away while dragging 11820 calendar.dispatch({ type: 'UNSELECT_DATES' }); 11821 } 11822 if (!isInvalid) {
11823 core.enableCursor(); 11824 } 11825 else { 11826 core.disableCursor(); 11827 } 11828 if (!isFinal) { 11829 _this.dragSelection = dragSelection; // only clear if moved away from all hits while dragging 11830 } 11831 }; 11832 _this.handlePointerUp = function (pev) { 11833 if (_this.dragSelection) { 11834 // selection is already rendered, so just need to report selection 11835 _this.component.calendar.triggerDateSelect(_this.dragSelection, pev); 11836 _this.dragSelection = null; 11837 } 11838 }; 11839 var component = settings.component; 11840 var dragging = _this.dragging = new FeaturefulElementDragging(component.el); 11841 dragging.touchScrollAllowed = false; 11842 dragging.minDistance = component.opt('selectMinDistance') || 0; 11843 dragging.autoScroller.isEnabled = component.opt('dragScroll'); 11844 var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, core.interactionSettingsToStore(settings)); 11845 hitDragging.emitter.on('pointerdown', _this.handlePointerDown); 11846 hitDragging.emitter.on('dragstart', _this.handleDragStart); 11847 hitDragging.emitter.on('hitupdate', _this.handleHitUpdate); 11848 hitDragging.emitter.on('pointerup', _this.handlePointerUp); 11849 return _this; 11850 } 11851 DateSelecting.prototype.destroy = function () { 11852 this.dragging.destroy(); 11853 }; 11854 return DateSelecting; 11855 }(core.Interaction)); 11856 function getComponentTouchDelay(component) { 11857 var delay = component.opt('selectLongPressDelay'); 11858 if (delay == null) { 11859 delay = component.opt('longPressDelay'); 11860 } 11861 return delay; 11862 } 11863 function joinHitsIntoSelection(hit0, hit1, dateSelectionTransformers) { 11864 var dateSpan0 = hit0.dateSpan; 11865 var dateSpan1 = hit1.dateSpan; 11866 var ms = [ 11867 dateSpan0.range.start, 11868 dateSpan0.range.end, 11869 dateSpan1.range.start, 11870 dateSpan1.range.end 11871 ]; 11872 ms.sort(core.compareNumbers); 11873 var props = {}; 11874 for (var _i = 0, dateSelectionTransformers_1 = dateSelectionTransformers; _i < dateSelectionTransformers_1.length; _i++) { 11875 var transformer = dateSelectionTransformers_1[_i]; 11876 var res = transformer(hit0, hit1); 11877 if (res === false) { 11878 return null; 11879 } 11880 else if (res) { 11881 __assign(props, res); 11882 } 11883 } 11884 props.range = { start: ms[0], end: ms[3] }; 11885 props.allDay = dateSpan0.allDay; 11886 return props; 11887 } 11888 11889 var EventDragging = /** @class */ (function (_super) { 11890 __extends(EventDragging, _super); 11891 function EventDragging(settings) { 11892 var _this = _super.call(this, settings) || this; 11893 // internal state 11894 _this.subjectSeg = null; // the seg being selected/dragged 11895 _this.isDragging = false; 11896 _this.eventRange = null; 11897 _this.relevantEvents = null; // the events being dragged 11898 _this.receivingCalendar = null; 11899 _this.validMutation = null; 11900 _this.mutatedRelevantEvents = null; 11901 _this.handlePointerDown = function (ev) { 11902 var origTarget = ev.origEvent.target; 11903 var _a = _this, component = _a.component, dragging = _a.dragging; 11904 var mirror = dragging.mirror; 11905 var initialCalendar = component.calendar; 11906 var subjectSeg = _this.subjectSeg = core.getElSeg(ev.subjectEl); 11907 var eventRange = _this.eventRange = subjectSeg.eventRange; 11908 var eventInstanceId = eventRange.instance.instanceId; 11909 _this.relevantEvents = core.getRelevantEvents(initialCalendar.state.eventStore, eventInstanceId); 11910 dragging.minDistance = ev.isTouch ? 0 : component.opt('eventDragMinDistance'); 11911 dragging.delay = 11912 // only do a touch delay if touch and this event hasn't been selected yet 11913 (ev.isTouch && eventInstanceId !== component.props.eventSelection) ? 11914 getComponentTouchDelay$1(component) : 11915 null; 11916 mirror.parentNode = initialCalendar.el; 11917 mirror.revertDuration = component.opt('dragRevertDuration'); 11918 var isValid = component.isValidSegDownEl(origTarget) && 11919 !core.elementClosest(origTarget, '.fc-resizer'); // NOT on a resizer 11920 dragging.setIgnoreMove(!isValid); 11921 // disable dragging for elements that are resizable (ie, selectable) 11922 // but are not draggable 11923 _this.isDragging = isValid && 11924 ev.subjectEl.classList.contains('fc-draggable'); 11925 }; 11926 _this.handleDragStart = function (ev) { 11927 var initialCalendar = _this.component.calendar; 11928 var eventRange = _this.eventRange; 11929 var eventInstanceId = eventRange.instance.instanceId; 11930 if (ev.isTouch) { 11931 // need to select a different event? 11932 if (eventInstanceId !== _this.component.props.eventSelection) { 11933 initialCalendar.dispatch({ type: 'SELECT_EVENT', eventInstanceId: eventInstanceId }); 11934 } 11935 } 11936 else { 11937 // if now using mouse, but was previous touch interaction, clear selected event 11938 initialCalendar.dispatch({ type: 'UNSELECT_EVENT' }); 11939 } 11940 if (_this.isDragging) { 11941 initialCalendar.unselect(ev); // unselect *date* selection 11942 initialCalendar.publiclyTrigger('eventDragStart', [ 11943 { 11944 el: _this.subjectSeg.el, 11945 event: new core.EventApi(initialCalendar, eventRange.def, eventRange.instance), 11946 jsEvent: ev.origEvent, 11947 view: _this.component.view 11948 } 11949 ]); 11950 } 11951 }; 11952 _this.handleHitUpdate = function (hit, isFinal) { 11953 if (!_this.isDragging) { 11954 return; 11955 } 11956 var relevantEvents = _this.relevantEvents; 11957 var initialHit = _this.hitDragging.initialHit; 11958 var initialCalendar = _this.component.calendar; 11959 // states based on new hit 11960 var receivingCalendar = null; 11961 var mutation = null; 11962 var mutatedRelevantEvents = null; 11963 var isInvalid = false;
11964 var interaction = { 11965 affectedEvents: relevantEvents, 11966 mutatedEvents: core.createEmptyEventStore(), 11967 isEvent: true, 11968 origSeg: _this.subjectSeg 11969 }; 11970 if (hit) { 11971 var receivingComponent = hit.component; 11972 receivingCalendar = receivingComponent.calendar; 11973 if (initialCalendar === receivingCalendar || 11974 receivingComponent.opt('editable') && receivingComponent.opt('droppable')) { 11975 mutation = computeEventMutation(initialHit, hit, receivingCalendar.pluginSystem.hooks.eventDragMutationMassagers); 11976 if (mutation) { 11977 mutatedRelevantEvents = core.applyMutationToEventStore(relevantEvents, receivingCalendar.eventUiBases, mutation, receivingCalendar); 11978 interaction.mutatedEvents = mutatedRelevantEvents; 11979 if (!receivingComponent.isInteractionValid(interaction)) { 11980 isInvalid = true; 11981 mutation = null; 11982 mutatedRelevantEvents = null; 11983 interaction.mutatedEvents = core.createEmptyEventStore(); 11984 } 11985 } 11986 } 11987 else { 11988 receivingCalendar = null; 11989 } 11990 } 11991 _this.displayDrag(receivingCalendar, interaction); 11992 if (!isInvalid) { 11993 core.enableCursor(); 11994 } 11995 else { 11996 core.disableCursor(); 11997 } 11998 if (!isFinal) { 11999 if (initialCalendar === receivingCalendar && // TODO: write test for this 12000 isHitsEqual(initialHit, hit)) { 12001 mutation = null; 12002 } 12003 _this.dragging.setMirrorNeedsRevert(!mutation); 12004 // render the mirror if no already-rendered mirror 12005 // TODO: wish we could somehow wait for dispatch to guarantee render 12006 _this.dragging.setMirrorIsVisible(!hit || !document.querySelector('.fc-mirror')); 12007 // assign states based on new hit 12008 _this.receivingCalendar = receivingCalendar; 12009 _this.validMutation = mutation; 12010 _this.mutatedRelevantEvents = mutatedRelevantEvents; 12011 } 12012 }; 12013 _this.handlePointerUp = function () { 12014 if (!_this.isDragging) { 12015 _this.cleanup(); // because handleDragEnd won't fire 12016 } 12017 }; 12018 _this.handleDragEnd = function (ev) { 12019 if (_this.isDragging) { 12020 var initialCalendar_1 = _this.component.calendar; 12021 var initialView = _this.component.view; 12022 var _a = _this, receivingCalendar = _a.receivingCalendar, validMutation = _a.validMutation; 12023 var eventDef = _this.eventRange.def; 12024 var eventInstance = _this.eventRange.instance; 12025 var eventApi = new core.EventApi(initialCalendar_1, eventDef, eventInstance); 12026 var relevantEvents_1 = _this.relevantEvents; 12027 var mutatedRelevantEvents = _this.mutatedRelevantEvents; 12028 var finalHit = _this.hitDragging.finalHit; 12029 _this.clearDrag(); // must happen after revert animation 12030 initialCalendar_1.publiclyTrigger('eventDragStop', [ 12031 { 12032 el: _this.subjectSeg.el, 12033 event: eventApi, 12034 jsEvent: ev.origEvent, 12035 view: initialView 12036 } 12037 ]); 12038 if (validMutation) { 12039 // dropped within same calendar 12040 if (receivingCalendar === initialCalendar_1) { 12041 initialCalendar_1.dispatch({ 12042 type: 'MERGE_EVENTS', 12043 eventStore: mutatedRelevantEvents 12044 }); 12045 var transformed = {}; 12046 for (var _i = 0, _b = initialCalendar_1.pluginSystem.hooks.eventDropTransformers; _i < _b.length; _i++) { 12047 var transformer = _b[_i]; 12048 __assign(transformed, transformer(validMutation, initialCalendar_1)); 12049 } 12050 var eventDropArg = __assign({}, transformed, { el: ev.subjectEl, delta: validMutation.datesDelta, oldEvent: eventApi, event: new core.EventApi(// the data AFT
12050ER the mutation 12051 initialCalendar_1, mutatedRelevantEvents.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents.instances[eventInstance.instanceId] : null), revert: function () { 12052 initialCalendar_1.dispatch({ 12053 type: 'MERGE_EVENTS', 12054 eventStore: relevantEvents_1 12055 }); 12056 }, jsEvent: ev.origEvent, view: initialView }); 12057 initialCalendar_1.publiclyTrigger('eventDrop', [eventDropArg]); 12058 // dropped in different calendar 12059 } 12060 else if (receivingCalendar) { 12061 initialCalendar_1.publiclyTrigger('eventLeave', [ 12062 { 12063 draggedEl: ev.subjectEl, 12064 event: eventApi, 12065 view: initialView 12066 } 12067 ]); 12068 initialCalendar_1.dispatch({ 12069 type: 'REMOVE_EVENT_INSTANCES', 12070 instances: _this.mutatedRelevantEvents.instances 12071 }); 12072 receivingCalendar.dispatch({ 12073 type: 'MERGE_EVENTS', 12074 eventStore: _this.mutatedRelevantEvents 12075 }); 12076 if (ev.isTouch) { 12077 receivingCalendar.dispatch({ 12078 type: 'SELECT_EVENT', 12079 eventInstanceId: eventInstance.instanceId 12080 }); 12081 } 12082 var dropArg = __assign({}, receivingCalendar.buildDatePointApi(finalHit.dateSpan), { draggedEl: ev.subjectEl, jsEvent: ev.origEvent, view: finalHit.component // should this be finalHit.component.view? See #4644 12083 }); 12084 receivingCalendar.publiclyTrigger('drop', [dropArg]); 12085 receivingCalendar.publiclyTrigger('eventReceive', [ 12086 { 12087 draggedEl: ev.subjectEl, 12088 event: new core.EventApi(// the data AFTER the mutation 12089 receivingCalendar, mutatedRelevantEvents.defs[eventDef.defId], mutatedRelevantEvents.instances[eventInstance.instanceId]), 12090 view: finalHit.component // should this be finalHit.component.view? See #4644 12091 } 12092 ]); 12093 } 12094 } 12095 else { 12096 initialCalendar_1.publiclyTrigger('_noEventDrop'); 12097 } 12098 } 12099 _this.cleanup(); 12100 }; 12101 var component = _this.component; 12102 var dragging = _this.dragging = new FeaturefulElementDragging(component.el); 12103 dragging.pointer.selector = EventDragging.SELECTOR; 12104 dragging.touchScrollAllowed = false; 12105 dragging.autoScroller.isEnabled = component.opt('dragScroll'); 12106 var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, core.interactionSettingsStore); 12107 hitDragging.useSubjectCenter = settings.useEventCenter; 12108 hitDragging.emitter.on('pointerdown', _this.handlePointerDown); 12109 hitDragging.emitter.on('dragstart', _this.handleDragStart); 12110 hitDragging.emitter.on('hitupdate', _this.handleHitUpdate); 12111 hitDragging.emitter.on('pointerup', _this.handlePointerUp); 12112 hitDragging.emitter.on('dragend', _this.handleDragEnd); 12113 return _this; 12114 } 12115 EventDragging.prototype.destroy = function () { 12116 this.dragging.destroy(); 12117 }; 12118 // render a drag state on the next receivingCalendar 12119 EventDragging.prototype.displayDrag = function (nextCalendar, state) { 12120 var initialCalendar = this.component.calendar; 12121 var prevCalendar = this.receivingCalendar; 12122 // does the previous calendar need to be cleared? 12123 if (prevCalendar && prevCalendar !== nextCalendar) { 12124 // does the initial calendar need to be cleared? 12125 // if so, don't clear all the way. we still need to to hide the affectedEvents 12126 if (prevCalendar === initialCalendar) { 12127 prevCalendar.dispatch({ 12128 type: 'SET_EVENT_DRAG', 12129 state: { 12130 affectedEvents: state.affectedEvents, 12131 mutatedEvents: core.createEmptyEventStore(), 12132 isEvent: true, 12133 origSeg: state.origSeg 12134 } 12135 }); 12136 // completely clear the old calendar if it wasn't the initial 12137 } 12138 else { 12139 prevCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' }); 12140 } 12141 } 12142 if (nextCalendar) { 12143 nextCalendar.dispatch({ type: 'SET_EVENT_DRAG', state: state }); 12144 } 12145 }; 12146 EventDragging.prototype.clearDrag = function () { 12147 var initialCalendar = this.component.calendar; 12148 var receivingCalendar = this.receivingCalendar; 12149 if (receivingCalendar) { 12150 receivingCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' }); 12151 } 12152 // the initial calendar might have an dummy drag state from displayDrag 12153 if (initialCalendar !== receivingCalendar) { 12154 initialCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' }); 12155 } 12156 }; 12157 EventDragging.prototype.cleanup = function () { 12158 this.subjectSeg = null; 12159 this.isDragging = false;
12160 this.eventRange = null; 12161 this.relevantEvents = null; 12162 this.receivingCalendar = null; 12163 this.validMutation = null; 12164 this.mutatedRelevantEvents = null; 12165 }; 12166 EventDragging.SELECTOR = '.fc-draggable, .fc-resizable'; // TODO: test this in IE11 12167 return EventDragging; 12168 }(core.Interaction)); 12169 function computeEventMutation(hit0, hit1, massagers) { 12170 var dateSpan0 = hit0.dateSpan; 12171 var dateSpan1 = hit1.dateSpan; 12172 var date0 = dateSpan0.range.start; 12173 var date1 = dateSpan1.range.start; 12174 var standardProps = {}; 12175 if (dateSpan0.allDay !== dateSpan1.allDay) { 12176 standardProps.allDay = dateSpan1.allDay; 12177 standardProps.hasEnd = hit1.component.opt('allDayMaintainDuration'); 12178 if (dateSpan1.allDay) { 12179 // means date1 is already start-of-day, 12180 // but date0 needs to be converted 12181 date0 = core.startOfDay(date0); 12182 } 12183 } 12184 var delta = core.diffDates(date0, date1, hit0.component.dateEnv, hit0.component === hit1.component ? 12185 hit0.component.largeUnit : 12186 null); 12187 if (delta.milliseconds) { // has hours/minutes/seconds 12188 standardProps.allDay = false; 12189 } 12190 var mutation = { 12191 datesDelta: delta, 12192 standardProps: standardProps 12193 }; 12194 for (var _i = 0, massagers_1 = massagers; _i < massagers_1.length; _i++) { 12195 var massager = massagers_1[_i]; 12196 massager(mutation, hit0, hit1); 12197 } 12198 return mutation; 12199 } 12200 function getComponentTouchDelay$1(component) { 12201 var delay = component.opt('eventLongPressDelay'); 12202 if (delay == null) { 12203 delay = component.opt('longPressDelay'); 12204 } 12205 return delay; 12206 } 12207 12208 var EventDragging$1 = /** @class */ (function (_super) { 12209 __extends(EventDragging, _super); 12210 function EventDragging(settings) { 12211 var _this = _super.call(this, settings) || this; 12212 // internal state 12213 _this.draggingSeg = null; // TODO: rename to resizingSeg? subjectSeg? 12214 _this.eventRange = null; 12215 _this.relevantEvents = null; 12216 _this.validMutation = null; 12217 _this.mutatedRelevantEvents = null; 12218 _this.handlePointerDown = function (ev) { 12219 var component = _this.component; 12220 var seg = _this.querySeg(ev); 12221 var eventRange = _this.eventRange = seg.eventRange; 12222 _this.dragging.minDistance = component.opt('eventDragMinDistance'); 12223 // if touch, need to be working with a selected event 12224 _this.dragging.setIgnoreMove(!_this.component.isValidSegDownEl(ev.origEvent.target) || 12225 (ev.isTouch && _this.component.props.eventSelection !== eventRange.instance.instanceId)); 12226 }; 12227 _this.handleDragStart = function (ev) { 12228 var calendar = _this.component.calendar; 12229 var eventRange = _this.eventRange; 12230 _this.relevantEvents = core.getRelevantEvents(calendar.state.eventStore, _this.eventRange.instance.instanceId); 12231 _this.draggingSeg = _this.querySeg(ev); 12232 calendar.unselect(); 12233 calendar.publiclyTrigger('eventResizeStart', [ 12234 { 12235 el: _this.draggingSeg.el, 12236 event: new core.EventApi(calendar, eventRange.def, eventRange.instance), 12237 jsEvent: ev.origEvent, 12238 view: _this.component.view 12239 } 12240 ]); 12241 }; 12242 _this.handleHitUpdate = function (hit, isFinal, ev) { 12243 var calendar = _this.component.calendar; 12244 var relevantEvents = _this.relevantEvents; 12245 var initialHit = _this.hitDragging.initialHit; 12246 var eventInstance = _this.eventRange.instance; 12247 var mutation = null; 12248 var mutatedRelevantEvents = null; 12249 var isInvalid = false;
12250 var interaction = { 12251 affectedEvents: relevantEvents, 12252 mutatedEvents: core.createEmptyEventStore(), 12253 isEvent: true, 12254 origSeg: _this.draggingSeg 12255 }; 12256 if (hit) { 12257 mutation = computeMutation(initialHit, hit, ev.subjectEl.classList.contains('fc-start-resizer'), eventInstance.range, calendar.pluginSystem.hooks.eventResizeJoinTransforms); 12258 } 12259 if (mutation) { 12260 mutatedRelevantEvents = core.applyMutationToEventStore(relevantEvents, calendar.eventUiBases, mutation, calendar); 12261 interaction.mutatedEvents = mutatedRelevantEvents; 12262 if (!_this.component.isInteractionValid(interaction)) { 12263 isInvalid = true; 12264 mutation = null; 12265 mutatedRelevantEvents = null; 12266 interaction.mutatedEvents = null; 12267 } 12268 } 12269 if (mutatedRelevantEvents) { 12270 calendar.dispatch({ 12271 type: 'SET_EVENT_RESIZE', 12272 state: interaction 12273 }); 12274 } 12275 else { 12276 calendar.dispatch({ type: 'UNSET_EVENT_RESIZE' }); 12277 } 12278 if (!isInvalid) { 12279 core.enableCursor(); 12280 } 12281 else { 12282 core.disableCursor(); 12283 } 12284 if (!isFinal) { 12285 if (mutation && isHitsEqual(initialHit, hit)) { 12286 mutation = null; 12287 } 12288 _this.validMutation = mutation; 12289 _this.mutatedRelevantEvents = mutatedRelevantEvents; 12290 } 12291 }; 12292 _this.handleDragEnd = function (ev) { 12293 var calendar = _this.component.calendar; 12294 var view = _this.component.view; 12295 var eventDef = _this.eventRange.def; 12296 var eventInstance = _this.eventRange.instance; 12297 var eventApi = new core.EventApi(calendar, eventDef, eventInstance); 12298 var relevantEvents = _this.relevantEvents; 12299 var mutatedRelevantEvents = _this.mutatedRelevantEvents; 12300 calendar.publiclyTrigger('eventResizeStop', [ 12301 { 12302 el: _this.draggingSeg.el, 12303 event: eventApi, 12304 jsEvent: ev.origEvent, 12305 view: view 12306 } 12307 ]); 12308 if (_this.validMutation) { 12309 calendar.dispatch({ 12310 type: 'MERGE_EVENTS', 12311 eventStore: mutatedRelevantEvents 12312 }); 12313 calendar.publiclyTrigger('eventResize', [ 12314 { 12315 el: _this.draggingSeg.el, 12316 startDelta: _this.validMutation.startDelta || core.createDuration(0), 12317 endDelta: _this.validMutation.endDelta || core.createDuration(0), 12318 prevEvent: eventApi, 12319 event: new core.EventApi(// the data AFTER the mutation 12320 calendar, mutatedRelevantEvents.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents.instances[eventInstance.instanceId] : null), 12321 revert: function () { 12322 calendar.dispatch({ 12323 type: 'MERGE_EVENTS', 12324 eventStore: relevantEvents 12325 }); 12326 }, 12327 jsEvent: ev.origEvent, 12328 view: view 12329 } 12330 ]); 12331 } 12332 else { 12333 calendar.publiclyTrigger('_noEventResize'); 12334 } 12335 // reset all internal state 12336 _this.draggingSeg = null; 12337 _this.relevantEvents = null; 12338 _this.validMutation = null; 12339 // okay to keep eventInstance around. useful to set it in handlePointerDown 12340 }; 12341 var component = settings.component; 12342 var dragging = _this.dragging = new FeaturefulElementDragging(component.el); 12343 dragging.pointer.selector = '.fc-resizer'; 12344 dragging.touchScrollAllowed = false;
12345 dragging.autoScroller.isEnabled = component.opt('dragScroll'); 12346 var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, core.interactionSettingsToStore(settings)); 12347 hitDragging.emitter.on('pointerdown', _this.handlePointerDown); 12348 hitDragging.emitter.on('dragstart', _this.handleDragStart); 12349 hitDragging.emitter.on('hitupdate', _this.handleHitUpdate); 12350 hitDragging.emitter.on('dragend', _this.handleDragEnd); 12351 return _this; 12352 } 12353 EventDragging.prototype.destroy = function () { 12354 this.dragging.destroy(); 12355 }; 12356 EventDragging.prototype.querySeg = function (ev) { 12357 return core.getElSeg(core.elementClosest(ev.subjectEl, this.component.fgSegSelector)); 12358 }; 12359 return EventDragging; 12360 }(core.Interaction)); 12361 function computeMutation(hit0, hit1, isFromStart, instanceRange, transforms) { 12362 var dateEnv = hit0.component.dateEnv; 12363 var date0 = hit0.dateSpan.range.start; 12364 var date1 = hit1.dateSpan.range.start; 12365 var delta = core.diffDates(date0, date1, dateEnv, hit0.component.largeUnit); 12366 var props = {}; 12367 for (var _i = 0, transforms_1 = transforms; _i < transforms_1.length; _i++) { 12368 var transform = transforms_1[_i]; 12369 var res = transform(hit0, hit1); 12370 if (res === false) { 12371 return null; 12372 } 12373 else if (res) { 12374 __assign(props, res); 12375 } 12376 } 12377 if (isFromStart) { 12378 if (dateEnv.add(instanceRange.start, delta) < instanceRange.end) { 12379 props.startDelta = delta; 12380 return props; 12381 } 12382 } 12383 else { 12384 if (dateEnv.add(instanceRange.end, delta) > instanceRange.start) { 12385 props.endDelta = delta; 12386 return props; 12387 } 12388 } 12389 return null; 12390 } 12391 12392 var UnselectAuto = /** @class */ (function () { 12393 function UnselectAuto(calendar) { 12394 var _this = this; 12395 this.isRecentPointerDateSelect = false; // wish we could use a selector to detect date selection, but uses hit system 12396 this.onSelect = function (selectInfo) { 12397 if (selectInfo.jsEvent) { 12398 _this.isRecentPointerDateSelect = true; 12399 } 12400 }; 12401 this.onDocumentPointerUp = function (pev) { 12402 var _a = _this, calendar = _a.calendar, documentPointer = _a.documentPointer; 12403 var state = calendar.state; 12404 // touch-scrolling should never unfocus any type of selection 12405 if (!documentPointer.wasTouchScroll) { 12406 if (state.dateSelection && // an existing date selection? 12407 !_this.isRecentPointerDateSelect // a new pointer-initiated date selection since last onDocumentPointerUp? 12408 ) { 12409 var unselectAuto = calendar.viewOpt('unselectAuto'); 12410 var unselectCancel = calendar.viewOpt('unselectCancel'); 12411 if (unselectAuto && (!unselectAuto || !core.elementClosest(documentPointer.downEl, unselectCancel))) { 12412 calendar.unselect(pev); 12413 } 12414 } 12415 if (state.eventSelection && // an existing event selected? 12416 !core.elementClosest(documentPointer.downEl, EventDragging.SELECTOR) // interaction DIDN'T start on an event 12417 ) { 12418 calendar.dispatch({ type: 'UNSELECT_EVENT' }); 12419 } 12420 } 12421 _this.isRecentPointerDateSelect = false; 12422 }; 12423 this.calendar = calendar; 12424 var documentPointer = this.documentPointer = new PointerDragging(document); 12425 documentPointer.shouldIgnoreMove = true; 12426 documentPointer.shouldWatchScroll = false; 12427 documentPointer.emitter.on('pointerup', this.onDocumentPointerUp); 12428 /* 12429 TODO: better way to know about whether there was a selection with the pointer 12430 */ 12431 calendar.on('select', this.onSelect); 12432 } 12433 UnselectAuto.prototype.destroy = function () { 12434 this.calendar.off('select', this.onSelect); 12435 this.documentPointer.destroy(); 12436 }; 12437 return UnselectAuto; 12438 }()); 12439 12440 /* 12441 Given an already instantiated draggable object for one-or-more elements, 12442 Interprets any dragging as an attempt to drag an events that lives outside 12443 of a calendar onto a calendar. 12444 */
12445 var ExternalElementDragging = /** @class */ (function () { 12446 function ExternalElementDragging(dragging, suppliedDragMeta) { 12447 var _this = this; 12448 this.receivingCalendar = null; 12449 this.droppableEvent = null; // will exist for all drags, even if create:false 12450 this.suppliedDragMeta = null; 12451 this.dragMeta = null; 12452 this.handleDragStart = function (ev) { 12453 _this.dragMeta = _this.buildDragMeta(ev.subjectEl); 12454 }; 12455 this.handleHitUpdate = function (hit, isFinal, ev) { 12456 var dragging = _this.hitDragging.dragging; 12457 var receivingCalendar = null; 12458 var droppableEvent = null; 12459 var isInvalid = false; 12460 var interaction = { 12461 affectedEvents: core.createEmptyEventStore(), 12462 mutatedEvents: core.createEmptyEventStore(), 12463 isEvent: _this.dragMeta.create, 12464 origSeg: null 12465 }; 12466 if (hit) { 12467 receivingCalendar = hit.component.calendar; 12468 if (_this.canDropElOnCalendar(ev.subjectEl, receivingCalendar)) { 12469 droppableEvent = computeEventForDateSpan(hit.dateSpan, _this.dragMeta, receivingCalendar); 12470 interaction.mutatedEvents = core.eventTupleToStore(droppableEvent); 12471 isInvalid = !core.isInteractionValid(interaction, receivingCalendar); 12472 if (isInvalid) { 12473 interaction.mutatedEvents = core.createEmptyEventStore(); 12474 droppableEvent = null; 12475 } 12476 } 12477 } 12478 _this.displayDrag(receivingCalendar, interaction); 12479 // show mirror if no already-rendered mirror element OR if we are shutting down the mirror (?) 12480 // TODO: wish we could somehow wait for dispatch to guarantee render 12481 dragging.setMirrorIsVisible(isFinal || !droppableEvent || !document.querySelector('.fc-mirror')); 12482 if (!isInvalid) { 12483 core.enableCursor(); 12484 } 12485 else { 12486 core.disableCursor(); 12487 } 12488 if (!isFinal) { 12489 dragging.setMirrorNeedsRevert(!droppableEvent); 12490 _this.receivingCalendar = receivingCalendar; 12491 _this.droppableEvent = droppableEvent; 12492 } 12493 }; 12494 this.handleDragEnd = function (pev) { 12495 var _a = _this, receivingCalendar = _a.receivingCalendar, droppableEvent = _a.droppableEvent; 12496 _this.clearDrag(); 12497 if (receivingCalendar && droppableEvent) { 12498 var finalHit = _this.hitDragging.finalHit; 12499 var finalView = finalHit.component.view; 12500 var dragMeta = _this.dragMeta; 12501 var arg = __assign({}, receivingCalendar.buildDatePointApi(finalHit.dateSpan), { draggedEl: pev.subjectEl, jsEvent: pev.origEvent, view: finalView }); 12502 receivingCalendar.publiclyTrigger('drop', [arg]); 12503 if (dragMeta.create) { 12504 receivingCalendar.dispatch({ 12505 type: 'MERGE_EVENTS', 12506 eventStore: core.eventTupleToStore(droppableEvent) 12507 }); 12508 if (pev.isTouch) { 12509 receivingCalendar.dispatch({ 12510 type: 'SELECT_EVENT', 12511 eventInstanceId: droppableEvent.instance.instanceId 12512 }); 12513 } 12514 // signal that an external event landed 12515 receivingCalendar.publiclyTrigger('eventReceive', [ 12516 { 12517 draggedEl: pev.subjectEl, 12518 event: new core.EventApi(receivingCalendar, droppableEvent.def, droppableEvent.instance), 12519 view: finalView 12520 } 12521 ]); 12522 } 12523 } 12524 _this.receivingCalendar = null; 12525 _this.droppableEvent = null; 12526 }; 12527 var hitDragging = this.hitDragging = new HitDragging(dragging, core.interactionSettingsStore); 12528 hitDragging.requireInitial = false; // will start outside of a component 12529 hitDragging.emitter.on('dragstart', this.handleDragStart); 12530 hitDragging.emitter.on('hitupdate', this.handleHitUpdate); 12531 hitDragging.emitter.on('dragend', this.handleDragEnd); 12532 this.suppliedDragMeta = suppliedDragMeta; 12533 } 12534 ExternalElementDragging.prototype.buildDragMeta = function (sub
12534jectEl) { 12535 if (typeof this.suppliedDragMeta === 'object') { 12536 return core.parseDragMeta(this.suppliedDragMeta); 12537 } 12538 else if (typeof this.suppliedDragMeta === 'function') { 12539 return core.parseDragMeta(this.suppliedDragMeta(subjectEl)); 12540 } 12541 else { 12542 return getDragMetaFromEl(subjectEl); 12543 } 12544 }; 12545 ExternalElementDragging.prototype.displayDrag = function (nextCalendar, state) { 12546 var prevCalendar = this.receivingCalendar; 12547 if (prevCalendar && prevCalendar !== nextCalendar) { 12548 prevCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' }); 12549 } 12550 if (nextCalendar) { 12551 nextCalendar.dispatch({ type: 'SET_EVENT_DRAG', state: state }); 12552 } 12553 }; 12554 ExternalElementDragging.prototype.clearDrag = function () { 12555 if (this.receivingCalendar) { 12556 this.receivingCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' }); 12557 } 12558 }; 12559 ExternalElementDragging.prototype.canDropElOnCalendar = function (el, receivingCalendar) { 12560 var dropAccept = receivingCalendar.opt('dropAccept'); 12561 if (typeof dropAccept === 'function') { 12562 return dropAccept(el); 12563 } 12564 else if (typeof dropAccept === 'string' && dropAccept) { 12565 return Boolean(core.elementMatches(el, dropAccept)); 12566 } 12567 return true; 12568 }; 12569 return ExternalElementDragging; 12570 }()); 12571 // Utils for computing event store from the DragMeta 12572 // ---------------------------------------------------------------------------------------------------- 12573 function computeEventForDateSpan(dateSpan, dragMeta, calendar) { 12574 var defProps = __assign({}, dragMeta.leftoverProps); 12575 for (var _i = 0, _a = calendar.pluginSystem.hooks.externalDefTransforms; _i < _a.length; _i++) { 12576 var transform = _a[_i]; 12577 __assign(defProps, transform(dateSpan, dragMeta)); 12578 } 12579 var def = core.parseEventDef(defProps, dragMeta.sourceId, dateSpan.allDay, calendar.opt('forceEventDuration') || Boolean(dragMeta.duration), // hasEnd 12580 calendar); 12581 var start = dateSpan.range.start; 12582 // only rely on time info if drop zone is all-day, 12583 // otherwise, we already know the time 12584 if (dateSpan.allDay && dragMeta.startTime) { 12585 start = calendar.dateEnv.add(start, dragMeta.startTime); 12586 } 12587 var end = dragMeta.duration ? 12588 calendar.dateEnv.add(start, dragMeta.duration) : 12589 calendar.getDefaultEventEnd(dateSpan.allDay, start); 12590 var instance = core.createEventInstance(def.defId, { start: start, end: end }); 12591 return { def: def, instance: instance }; 12592 } 12593 // Utils for extracting data from element 12594 // ---------------------------------------------------------------------------------------------------- 12595 function getDragMetaFromEl(el) { 12596 var str = getEmbeddedElData(el, 'event'); 12597 var obj = str ? 12598 JSON.parse(str) : 12599 { create: false }; // if no embedded data, assume no event creation 12600 return core.parseDragMeta(obj); 12601 } 12602 core.config.dataAttrPrefix = ''; 12603 function getEmbeddedElData(el, name) { 12604 var prefix = core.config.dataAttrPrefix; 12605 var prefixedName = (prefix ? prefix + '-' : '') + name; 12606 return el.getAttribute('data-' + prefixedName) || ''; 12607 } 12608 12609 /* 12610 Makes an element (that is *external* to any calendar) draggable. 12611 Can pass in data that determines how an event will be created when dropped onto a calendar. 12612 Leverages FullCalendar's internal drag-n-drop functionality WITHOUT a third-party drag system. 12613 */ 12614 var ExternalDraggable = /** @class */ (function () { 12615 function ExternalDraggable(el, settings) { 12616 var _this = this; 12617 if (settings === void 0) { settings = {}; } 12618 this.handlePointerDown = function (ev) { 12619 var dragging = _this.dragging; 12620 var _a = _this.settings, minDistance = _a.minDistance, longPressDelay = _a.longPressDelay; 12621 dragging.minDistance = 12622 minDistance != null ? 12623 minDistance : 12624 (ev.isTouch ? 0 : core.globalDefaults.eventDragMinDistance); 12625 dragging.delay = 12626 ev.isTouch ? // TODO: eventually read eventLongPressDelay instead vvv 12627 (longPressDelay != null ? longPressDelay : core.globalDefaults.longPressDelay) : 12628 0; 12629 }; 12630 this.handleDragStart = function (ev) { 12631 if (ev.isTouch && 12632 _this.dragging.delay && 12633 ev.subjectEl.classList.contains('fc-event')) { 12634 _this.dragging.mirror.getMirrorEl().classList.add('fc-selected'); 12635 } 12636 }; 12637 this.settings = settings; 12638 var dragging = this.dragging = new FeaturefulElementDragging(el); 12639 dragging.touchScrollAllowed = false;
12640 if (settings.itemSelector != null) { 12641 dragging.pointer.selector = settings.itemSelector; 12642 } 12643 if (settings.appendTo != null) { 12644 dragging.mirror.parentNode = settings.appendTo; // TODO: write tests 12645 } 12646 dragging.emitter.on('pointerdown', this.handlePointerDown); 12647 dragging.emitter.on('dragstart', this.handleDragStart); 12648 new ExternalElementDragging(dragging, settings.eventData); 12649 } 12650 ExternalDraggable.prototype.destroy = function () { 12651 this.dragging.destroy(); 12652 }; 12653 return ExternalDraggable; 12654 }()); 12655 12656 /* 12657 Detects when a *THIRD-PARTY* drag-n-drop system interacts with elements. 12658 The third-party system is responsible for drawing the visuals effects of the drag. 12659 This class simply monitors for pointer movements and fires events. 12660 It also has the ability to hide the moving element (the "mirror") during the drag. 12661 */ 12662 var InferredElementDragging = /** @class */ (function (_super) { 12663 __extends(InferredElementDragging, _super); 12664 function InferredElementDragging(containerEl) { 12665 var _this = _super.call(this, containerEl) || this; 12666 _this.shouldIgnoreMove = false; 12667 _this.mirrorSelector = ''; 12668 _this.currentMirrorEl = null; 12669 _this.handlePointerDown = function (ev) { 12670 _this.emitter.trigger('pointerdown', ev); 12671 if (!_this.shouldIgnoreMove) { 12672 // fire dragstart right away. does not support delay or min-distance 12673 _this.emitter.trigger('dragstart', ev); 12674 } 12675 }; 12676 _this.handlePointerMove = function (ev) { 12677 if (!_this.shouldIgnoreMove) { 12678 _this.emitter.trigger('dragmove', ev); 12679 } 12680 }; 12681 _this.handlePointerUp = function (ev) { 12682 _this.emitter.trigger('pointerup', ev); 12683 if (!_this.shouldIgnoreMove) { 12684 // fire dragend right away. does not support a revert animation 12685 _this.emitter.trigger('dragend', ev); 12686 } 12687 }; 12688 var pointer = _this.pointer = new PointerDragging(containerEl); 12689 pointer.emitter.on('pointerdown', _this.handlePointerDown); 12690 pointer.emitter.on('pointermove', _this.handlePointerMove); 12691 pointer.emitter.on('pointerup', _this.handlePointerUp); 12692 return _this; 12693 } 12694 InferredElementDragging.prototype.destroy = function () { 12695 this.pointer.destroy(); 12696 }; 12697 InferredElementDragging.prototype.setIgnoreMove = function (bool) { 12698 this.shouldIgnoreMove = bool; 12699 }; 12700 InferredElementDragging.prototype.setMirrorIsVisible = function (bool) { 12701 if (bool) { 12702 // restore a previously hidden element. 12703 // use the reference in case the selector class has already been removed. 12704 if (this.currentMirrorEl) { 12705 this.currentMirrorEl.style.visibility = ''; 12706 this.currentMirrorEl = null; 12707 } 12708 } 12709 else { 12710 var mirrorEl = this.mirrorSelector ? 12711 document.querySelector(this.mirrorSelector) : 12712 null; 12713 if (mirrorEl) { 12714 this.currentMirrorEl = mirrorEl; 12715 mirrorEl.style.visibility = 'hidden'; 12716 } 12717 } 12718 }; 12719 return InferredElementDragging; 12720 }(core.ElementDragging)); 12721 12722 /* 12723 Bridges third-party drag-n-drop systems with FullCalendar. 12724 Must be instantiated and destroyed by caller. 12725 */ 12726 var ThirdPartyDraggable = /** @class */ (function () { 12727 function ThirdPartyDraggable(containerOrSettings, settings) { 12728 var containerEl = document; 12729 if ( 12730 // wish we could just test instanceof EventTarget, but doesn't work in IE11 12731 containerOrSettings === document || 12732 containerOrSettings instanceof Element) { 12733 containerEl = containerOrSettings; 12734 settings = settings || {}; 12735 } 12736 else { 12737 settings = (containerOrSettings || {}); 12738 } 12739 var dragging = this.dragging = new InferredElementDragging(containerEl); 12740 if (typeof settings.itemSelector === 'string') { 12741 dragging.pointer.selector = settings.itemSelector; 12742 } 12743 else if (containerEl === document) { 12744 dragging.pointer.selector = '[data-event]'; 12745 } 12746 if (typeof settings.mirrorSelector === 'string') { 12747 dragging.mirrorSelector = settings.mirrorSelector; 12748 } 12749 new ExternalElementDragging(dragging, settings.eventData); 12750 } 12751 ThirdPartyDraggable.prototype.destroy = function () { 12752 this.dragging.destroy(); 12753 }; 12754 return ThirdPartyDraggable; 12755 }()); 12756 12757 var main = core.createPlugin({ 12758 componentInteractions: [DateClicking, DateSelecting, EventDragging, EventDragging$1], 12759 calendarInteractions: [UnselectAuto], 12760 elementDraggingImpl: FeaturefulElementDragging 12761 }); 12762 12763 exports.Draggable = ExternalDraggable; 12764 exports.FeaturefulElementDragging = FeaturefulElementDragging; 12765 exports.PointerDragging = PointerDragging; 12766 exports.ThirdPartyDraggable = ThirdPartyDraggable; 12767 exports.default = main; 12768 12769 Object.defineProperty(exports, '__esModule', { value: true }); 12770 12771})); 12772 12773},{"@fullcalendar/core":2}],6:[function(require,module,exports){ 12774/*!
12775FullCalendar List View Plugin v4.3.0 12776Docs & License: https://fullcalendar.io/ 12777(c) 2019 Adam Shaw 12778*/ 12779 12780(function (global, factory) { 12781 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core')) : 12782 typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core'], factory) : 12783 (global = global || self, factory(global.FullCalendarList = {}, global.FullCalendar)); 12784}(this, function (exports, core) { 'use strict'; 12785 12786 /*! ***************************************************************************** 12787 Copyright (c) Microsoft Corporation. All rights reserved. 12788 Licensed under the Apache License, Version 2.0 (the "License"); you may not use 12789 this file except in compliance with the License. You may obtain a copy of the 12790 License at http://www.apache.org/licenses/LICENSE-2.0 12791 12792 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 12793 KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 12794 WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 12795 MERCHANTABLITY OR NON-INFRINGEMENT. 12796 12797 See the Apache Version 2.0 License for specific language governing permissions 12798 and limitations under the License. 12799 ***************************************************************************** */ 12800 /* global Reflect, Promise */ 12801 12802 var extendStatics = function(d, b) { 12803 extendStatics = Object.setPrototypeOf || 12804 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 12805 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; 12806 return extendStatics(d, b); 12807 }; 12808 12809 function __extends(d, b) { 12810 extendStatics(d, b); 12811 function __() { this.constructor = d; } 12812 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 12813 } 12814 12815 var ListEventRenderer = /** @class */ (function (_super) { 12816 __extends(ListEventRenderer, _super); 12817 function ListEventRenderer(listView) { 12818 var _this = _super.call(this, listView.context) || this; 12819 _this.listView = listView; 12820 return _this; 12821 } 12822 ListEventRenderer.prototype.attachSegs = function (segs) { 12823 if (!segs.length) { 12824 this.listView.renderEmptyMessage(); 12825 } 12826 else { 12827 this.listView.renderSegList(segs); 12828 } 12829 }; 12830 ListEventRenderer.prototype.detachSegs = function () { 12831 }; 12832 // generates the HTML for a single event row 12833 ListEventRenderer.prototype.renderSegHtml = function (seg) { 12834 var _a = this.context, view = _a.view, theme = _a.theme; 12835 var eventRange = seg.eventRange; 12836 var eventDef = eventRange.def; 12837 var eventInstance = eventRange.instance; 12838 var eventUi = eventRange.ui; 12839 var url = eventDef.url; 12840 var classes = ['fc-list-item'].concat(eventUi.classNames); 12841 var bgColor = eventUi.backgroundColor; 12842 var timeHtml; 12843 if (eventDef.allDay) { 12844 timeHtml = core.getAllDayHtml(view); 12845 } 12846 else if (core.isMultiDayRange(eventRange.range)) { 12847 if (seg.isStart) { 12848 timeHtml = core.htmlEscape(this._getTimeText(eventInstance.range.start, seg.end, false // allDay 12849 )); 12850 } 12851 else if (seg.isEnd) { 12852 timeHtml = core.htmlEscape(this._getTimeText(seg.start, eventInstance.range.end, false // allDay 12853 )); 12854 } 12855 else { // inner segment that lasts the whole day 12856 timeHtml = core.getAllDayHtml(view); 12857 } 12858 } 12859 else { 12860 // Display the normal time text for the *event's* times 12861 timeHtml = core.htmlEscape(this.getTimeText(eventRange)); 12862 } 12863 if (url) { 12864 classes.push('fc-has-url'); 12865 } 12866 return '<tr class="' + classes.join(' ') + '">' + 12867 (this.displayEventTime ? 12868 '<td class="fc-list-item-time ' + theme.getClass('widgetContent') + '">' + 12869 (timeHtml || '') + 12870 '</td>' : 12871 '') + 12872 '<td class="fc-list-item-marker ' + theme.getClass('widgetContent') + '">' + 12873 '<span class="fc-event-dot"' + 12874 (bgColor ? 12875 ' style="background-color:' + bgColor + '"' : 12876 '') + 12877 '></span>' + 12878 '</td>' + 12879 '<td class="fc-list-item-title ' + theme.getClass('widgetContent') + '">' + 12880 '<a' + (url ? ' href="' + core.htmlEscape(url) + '"' : '') + '>
12880' + 12881 core.htmlEscape(eventDef.title || '') + 12882 '</a>' + 12883 '</td>' + 12884 '</tr>'; 12885 }; 12886 // like "4:00am" 12887 ListEventRenderer.prototype.computeEventTimeFormat = function () { 12888 return { 12889 hour: 'numeric', 12890 minute: '2-digit', 12891 meridiem: 'short' 12892 }; 12893 }; 12894 return ListEventRenderer; 12895 }(core.FgEventRenderer)); 12896 12897 /* 12898 Responsible for the scroller, and forwarding event-related actions into the "grid". 12899 */ 12900 var ListView = /** @class */ (function (_super) { 12901 __extends(ListView, _super); 12902 function ListView(context, viewSpec, dateProfileGenerator, parentEl) { 12903 var _this = _super.call(this, context, viewSpec, dateProfileGenerator, parentEl) || this; 12904 _this.computeDateVars = core.memoize(computeDateVars); 12905 _this.eventStoreToSegs = core.memoize(_this._eventStoreToSegs); 12906 var eventRenderer = _this.eventRenderer = new ListEventRenderer(_this); 12907 _this.renderContent = core.memoizeRendering(eventRenderer.renderSegs.bind(eventRenderer), eventRenderer.unrender.bind(eventRenderer)); 12908 _this.el.classList.add('fc-list-view'); 12909 var listViewClassNames = (_this.theme.getClass('listView') || '').split(' '); // wish we didn't have to do this 12910 for (var _i = 0, listViewClassNames_1 = listViewClassNames; _i < listViewClassNames_1.length; _i++) { 12911 var listViewClassName = listViewClassNames_1[_i]; 12912 if (listViewClassName) { // in case input was empty string 12913 _this.el.classList.add(listViewClassName); 12914 } 12915 } 12916 _this.scroller = new core.ScrollComponent('hidden', // overflow x 12917 'auto' // overflow y 12918 ); 12919 _this.el.appendChild(_this.scroller.el); 12920 _this.contentEl = _this.scroller.el; // shortcut 12921 context.calendar.registerInteractiveComponent(_this, { 12922 el: _this.el 12923 // TODO: make aware that it doesn't do Hits 12924 }); 12925 return _this; 12926 } 12927 ListView.prototype.render = function (props) { 12928 var _a = this.computeDateVars(props.dateProfile), dayDates = _a.dayDates, dayRanges = _a.dayRanges; 12929 this.dayDates = dayDates; 12930 this.renderContent(this.eventStoreToSegs(props.eventStore, props.eventUiBases, dayRanges)); 12931 }; 12932 ListView.prototype.destroy = function () { 12933 _super.prototype.destroy.call(this); 12934 this.renderContent.unrender(); 12935 this.scroller.destroy(); // will remove the Grid too 12936 this.calendar.unregisterInteractiveComponent(this); 12937 }; 12938 ListView.prototype.updateSize = function (isResize, viewHeight, isAuto) { 12939 _super.prototype.updateSize.call(this, isResize, viewHeight, isAuto); 12940 this.eventRenderer.computeSizes(isResize); 12941 this.eventRenderer.assignSizes(isResize); 12942 this.scroller.clear(); // sets height to 'auto' and clears overflow 12943 if (!isAuto) { 12944 this.scroller.setHeight(this.computeScrollerHeight(viewHeight)); 12945 } 12946 }; 12947 ListView.prototype.computeScrollerHeight = function (viewHeight) { 12948 return viewHeight - 12949 core.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller 12950 }; 12951 ListView.prototype._eventStoreToSegs = function (eventStore, eventUiBases, dayRanges) { 12952 return this.eventRangesToSegs(core.sliceEventStore(eventStore, eventUiBases, this.props.dateProfile.activeRange, this.nextDayThreshold).fg, dayRanges); 12953 }; 12954 ListView.prototype.eventRangesToSegs = function (eventRanges, dayRanges) { 12955 var segs = []; 12956 for (var _i = 0, eventRanges_1 = eventRanges; _i < eventRanges_1.length; _i++) { 12957 var eventRange = eventRanges_1[_i]; 12958 segs.push.apply(segs, this.eventRangeToSegs(eventRange, dayRanges)); 12959 } 12960 return segs; 12961 }; 12962 ListView.prototype.eventRangeToSegs = function (eventRange, dayRanges) { 12963 var _a = this, dateEnv = _a.dateEnv, nextDayThreshold = _a.nextDayThreshold; 12964 var range = eventRange.range; 12965 var allDay = eventRange.def.allDay; 12966 var dayIndex; 12967 var segRange; 12968 var seg; 12969 var segs = []; 12970 for (dayIndex = 0; dayIndex < dayRanges.length; dayIndex++) { 12971 segRange = core.intersectRanges(range, dayRanges[dayIndex]); 12972 if (segRange) { 12973 seg = { 12974 component: this, 12975 eventRange: eventRange, 12976 start: segRange.start, 12977 end: segRange.end, 12978 isStart: eventRange.isStart && segRange.start.valueOf() === range.start.valueOf(), 12979 isEnd: eventRange.isEnd && segRange.end.valueOf() === range.end.valueOf(), 12980 dayIndex: dayIndex 12981 }; 12982 segs.push(seg); 12983 // detect when range won't go fully into the next day, 12984 // and mutate the latest seg to the be the end. 12985 if (!seg.isEnd && !allDay && 12986 dayIndex + 1 < dayRanges.length && 12987 range.end < 12988 dateEnv.add(dayRanges[dayIndex + 1].start, nextDayThreshold)) { 12989 seg.end = range.end; 12990 seg.isEnd = true; 12991 break; 12992 } 12993 } 12994 } 12995 return segs; 12996 }; 12997 ListView.prototype.renderEmptyMessage = function () { 12998 this.contentEl.innerHTML = 12999 '<div class="fc-list-empty-wrap2">' + // TODO: try less wraps 13000 '<div class="fc-list-empty-wrap1">' + 13001 '<div class="fc-list-empty">' + 13002 core.htmlEscape(this.opt('noEventsMessage')) + 13003 '</div>' + 13004 '</div>' + 13005 '</div>'; 13006 }; 13007 // called by ListEventRenderer 13008 ListView.prototype.renderSegList = function (allSegs) { 13009 var segsByDay = this.groupSegsByDay(allSegs); // sparse array 13010 var dayIndex; 13011 var daySegs; 13012 var i; 13013 var tableEl = core.htmlToElement('<table class="fc-list-table ' + this.calendar.theme.getClass('tableList') + '"><tbody></tbody></table>'); 13014 var tbodyEl = tableEl.querySelector('tbody'); 13015 for (dayIndex = 0; dayIndex < segsByDay.length; dayIndex++) { 13016 daySegs = segsByDay[dayIndex]; 13017 if (daySegs) { // sparse array, so might be undefined 13018 // append a day header 13019 tbodyEl.appendChild(this.buildDayHeaderRow(this.dayDates[dayIndex])); 13020 daySegs = this.eventRenderer.sortEventSegs(daySegs); 13021 for (i = 0;
13021 i < daySegs.length; i++) { 13022 tbodyEl.appendChild(daySegs[i].el); // append event row 13023 } 13024 } 13025 } 13026 this.contentEl.innerHTML = ''; 13027 this.contentEl.appendChild(tableEl); 13028 }; 13029 // Returns a sparse array of arrays, segs grouped by their dayIndex 13030 ListView.prototype.groupSegsByDay = function (segs) { 13031 var segsByDay = []; // sparse array 13032 var i; 13033 var seg; 13034 for (i = 0; i < segs.length; i++) { 13035 seg = segs[i]; 13036 (segsByDay[seg.dayIndex] || (segsByDay[seg.dayIndex] = [])) 13037 .push(seg); 13038 } 13039 return segsByDay; 13040 }; 13041 // generates the HTML for the day headers that live amongst the event rows 13042 ListView.prototype.buildDayHeaderRow = function (dayDate) { 13043 var dateEnv = this.dateEnv; 13044 var mainFormat = core.createFormatter(this.opt('listDayFormat')); // TODO: cache 13045 var altFormat = core.createFormatter(this.opt('listDayAltFormat')); // TODO: cache 13046 return core.createElement('tr', { 13047 className: 'fc-list-heading', 13048 'data-date': dateEnv.formatIso(dayDate, { omitTime: true }) 13049 }, '<td class="' + (this.calendar.theme.getClass('tableListHeading') || 13050 this.calendar.theme.getClass('widgetHeader')) + '" colspan="3">' + 13051 (mainFormat ? 13052 core.buildGotoAnchorHtml(this, dayDate, { 'class': 'fc-list-heading-main' }, core.htmlEscape(dateEnv.format(dayDate, mainFormat)) // inner HTML 13053 ) : 13054 '') + 13055 (altFormat ? 13056 core.buildGotoAnchorHtml(this, dayDate, { 'class': 'fc-list-heading-alt' }, core.htmlEscape(dateEnv.format(dayDate, altFormat)) // inner HTML 13057 ) : 13058 '') + 13059 '</td>'); 13060 }; 13061 return ListView; 13062 }(core.View)); 13063 ListView.prototype.fgSegSelector = '.fc-list-item'; // which elements accept event actions 13064 function computeDateVars(dateProfile) { 13065 var dayStart = core.startOfDay(dateProfile.renderRange.start); 13066 var viewEnd = dateProfile.renderRange.end; 13067 var dayDates = []; 13068 var dayRanges = []; 13069 while (dayStart < viewEnd) { 13070 dayDates.push(dayStart); 13071 dayRanges.push({ 13072 start: dayStart, 13073 end: core.addDays(dayStart, 1) 13074 }); 13075 dayStart = core.addDays(dayStart, 1); 13076 } 13077 return { dayDates: dayDates, dayRanges: dayRanges }; 13078 } 13079 13080 var main = core.createPlugin({ 13081 views: { 13082 list: { 13083 class: ListView, 13084 buttonTextKey: 'list', 13085 listDayFormat: { month: 'long', day: 'numeric', year: 'numeric' } // like "January 1, 2016" 13086 }, 13087 listDay: { 13088 type: 'list', 13089 duration: { days: 1 }, 13090 listDayFormat: { weekday: 'long' } // day-of-week is all we need. full date is probably in header 13091 }, 13092 listWeek: { 13093 type: 'list', 13094 duration: { weeks: 1 }, 13095 listDayFormat: { weekday: 'long' }, 13096 listDayAltFormat: { month: 'long', day: 'numeric', year: 'numeric' } 13097 }, 13098 listMonth: { 13099 type: 'list', 13100 duration: { month: 1 }, 13101 listDayAltFormat: { weekday: 'long' } // day-of-week is nice-to-have 13102 }, 13103 listYear: { 13104 type: 'list', 13105 duration: { year: 1 }, 13106 listDayAltFormat: { weekday: 'long' } // day-of-week is nice-to-have 13107 } 13108 } 13109 }); 13110 13111 exports.ListView = ListView; 13112 exports.default = main; 13113 13114 Object.defineProperty(exports, '__esModule', { value: true }); 13115 13116})); 13117 13118},{"@fullcalendar/core":2}],7:[function(require,module,exports){ 13119/*! 13120FullCalendar Moment Plugin v4.3.0 13121Docs & License: https://fullcalendar.io/ 13122(c) 2019 Adam Shaw 13123*/ 13124 13125(function (global, factory) { 13126 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('moment'), require('@fullcalendar/core')) : 13127 typeof define === 'function' && define.amd ? define(['exports', 'moment', '@fullcalendar/core'], factory) : 13128 (global = global || self, factory(global.FullCalendarMoment = {}, global.moment, global.FullCalendar)); 13129}(this, function (exports, momentNs, core) { 'use strict'; 13130 13131 var moment = momentNs; // the directly callable function 13132 function toMoment(date, calendar) { 13133 if (!(calendar instanceof core.Calendar)) { 13134 throw new Error('must supply a Calendar instance'); 13135 } 13136 return convertToMoment(date, calendar.dateEnv.timeZone, null, calendar.dateEnv.locale.codes[0]); 13137 } 13138 function toDuration(fcDuration) { 13139 return moment.duration(fcDuration); // moment accepts all the props that fc.Duration already has! 13140 } 13141 function formatWithCmdStr(cmdStr, arg) { 13142 var cmd = parseCmdStr(cmdStr); 13143 if (arg.end) { 13144 var startMom = convertToMoment(arg.start.array, arg.timeZone, arg.start.timeZoneOffset, arg.localeCodes[0]); 13145 var endMom = convertToMoment(arg.end.array, arg.timeZone, arg.end.timeZoneOffset, arg.localeCodes[0]); 13146 return formatRange(cmd, createMomentFormatFunc(startMom), createMomentFormatFunc(endMom), arg.separator); 13147 } 13148 return convertToMoment(arg.date.array, arg.timeZone, arg.date.timeZoneOffset, arg.localeCodes[0]).format(cmd.whole); // TODO: test for this 13149 } 13150 var main = core.createPlugin({ 13151 cmdFormatter: formatWithCmdStr 13152 }); 13153 function createMomentFormatFunc(mom) { 13154 return function (cmdStr) { 13155 return cmdStr ? mom.format(cmdStr) : ''; // because calling with blank string results in ISO8601 :( 13156 }; 13157 } 13158 function convertToMoment(input, timeZone, timeZoneOffset, locale) { 13159 var mom; 13160 if (timeZone === 'local') { 13161 mom = moment(input); 13162 } 13163 else if (timeZone === 'UTC') { 13164 mom = moment.utc(input); 13165 } 13166 else if (moment.tz) { 13167 mom = moment.tz(input, timeZone); 13168 } 13169 else { 13170 mom = moment.utc(input); 13171 if (timeZoneOffset != null) { 13172 mom.utcOffset(timeZoneOffset); 13173 } 13174 } 13175 mom.locale(locale); 13176 return mom; 13177 } 13178 function parseCmdStr(cmdStr) { 13179 var parts = cmdStr.match(/^(.*?)\{(.*)\}(.*)$/); // TODO: lookbehinds for escape characters 13180 if (parts) { 13181 var middle = parseCmdStr(parts[2]); 13182 return { 13183 head: parts[1], 13184 middle: middle, 13185 tail: parts[3], 13186 whole: parts[1] + middle.whole + parts[3] 13187 }; 13188 } 13189 else { 13190 return { 13191 head: null, 13192 middle: null, 13193 tail: null, 13194 whole: cmdStr 13195 }; 13196 } 13197 } 13198 function formatRange(cmd, formatStart, formatEnd, separator) { 13199 if (cmd.middle) { 13200 var startHead = formatStart(cmd.head); 13201 var startMiddle = formatRange(cmd.middle, formatStart, formatEnd, separator); 13202 var startTail = formatStart(cmd.tail); 13203 var endHead = formatEnd(cmd.head); 13204 var endMiddle = formatRange(cmd.middle, formatStart, formatEnd, separator); 13205 var endTail = formatEnd(cmd.tail); 13206 if (startHead === endHead && startTail === endTail) { 13207 return startHead + 13208 (startMiddle === endMiddle ? startMiddle : startMiddle + separator + endMiddle) + 13209 startTail; 13210 } 13211 } 13212 var startWhole = formatStart(cmd.whole); 13213 var endWhole = formatEnd(cmd.whole); 13214 if (startWhole === endWhole) { 13215 return startWhole; 13216 } 13217 else { 13218 return startWhole + separator + endWhole; 13219 } 13220 } 13221 13222 exports.default = main; 13223 exports.toDuration = toDuration; 13224 exports.toMoment = toMoment; 13225 13226 Object.defineProperty(exports, '__esModule', { value: true }); 13227 13228})); 13229 13230},{"@fullcalendar/core":2,"moment":14}],8:[function(require,module,exports){ 13231/*!
13232FullCalendar Time Grid Plugin v4.3.0 13233Docs & License: https://fullcalendar.io/ 13234(c) 2019 Adam Shaw 13235*/ 13236 13237(function (global, factory) { 13238 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core'), require('@fullcalendar/daygrid')) : 13239 typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core', '@fullcalendar/daygrid'], factory) : 13240 (global = global || self, factory(global.FullCalendarTimeGrid = {}, global.FullCalendar, global.FullCalendarDayGrid)); 13241}(this, function (exports, core, daygrid) { 'use strict'; 13242 13243 /*! ***************************************************************************** 13244 Copyright (c) Microsoft Corporation. All rights reserved. 13245 Licensed under the Apache License, Version 2.0 (the "License"); you may not use 13246 this file except in compliance with the License. You may obtain a copy of the 13247 License at http://www.apache.org/licenses/LICENSE-2.0 13248 13249 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13250 KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 13251 WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 13252 MERCHANTABLITY OR NON-INFRINGEMENT. 13253 13254 See the Apache Version 2.0 License for specific language governing permissions 13255 and limitations under the License. 13256 ***************************************************************************** */ 13257 /* global Reflect, Promise */ 13258 13259 var extendStatics = function(d, b) { 13260 extendStatics = Object.setPrototypeOf || 13261 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 13262 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; 13263 return extendStatics(d, b); 13264 }; 13265 13266 function __extends(d, b) { 13267 extendStatics(d, b); 13268 function __() { this.constructor = d; } 13269 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 13270 } 13271 13272 var __assign = function() { 13273 __assign = Object.assign || function __assign(t) { 13274 for (var s, i = 1, n = arguments.length; i < n; i++) { 13275 s = arguments[i]; 13276 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 13277 } 13278 return t; 13279 }; 13280 return __assign.apply(this, arguments); 13281 }; 13282 13283 /* 13284 Only handles foreground segs. 13285 Does not own rendering. Use for low-level util methods by TimeGrid. 13286 */ 13287 var TimeGridEventRenderer = /** @class */ (function (_super) { 13288 __extends(TimeGridEventRenderer, _super); 13289 function TimeGridEventRenderer(timeGrid) { 13290 var _this = _super.call(this, timeGrid.context) || this; 13291 _this.timeGrid = timeGrid; 13292 _this.fullTimeFormat = core.createFormatter({ 13293 hour: 'numeric', 13294 minute: '2-digit', 13295 separator: _this.context.options.defaultRangeSeparator 13296 }); 13297 return _this; 13298 } 13299 // Given an array of foreground segments, render a DOM element for each, computes position, 13300 // and attaches to the column inner-container elements. 13301 TimeGridEventRenderer.prototype.attachSegs = function (segs, mirrorInfo) { 13302 var segsByCol = this.timeGrid.groupSegsByCol(segs); 13303 // order the segs within each column 13304 // TODO: have groupSegsByCol do this? 13305 for (var col = 0; col < segsByCol.length; col++) { 13306 segsByCol[col] = this.sortEventSegs(segsByCol[col]); 13307 } 13308 this.segsByCol = segsByCol; 13309 this.timeGrid.attachSegsByCol(segsByCol, this.timeGrid.fgContainerEls); 13310 }; 13311 TimeGridEventRenderer.prototype.detachSegs = function (segs) { 13312 segs.forEach(function (seg) { 13313 core.removeElement(seg.el); 13314 }); 13315 this.segsByCol = null; 13316 }; 13317 TimeGridEventRenderer.prototype.computeSegSizes = function (allSegs) { 13318 var _a = this, timeGrid = _a.timeGrid, segsByCol = _a.segsByCol; 13319 var colCnt = timeGrid.colCnt; 13320 timeGrid.computeSegVerticals(allSegs); // horizontals relies on this 13321 if (segsByCol) { 13322 for (var col = 0; col < colCnt; col++) { 13323 this.computeSegHorizontals(segsByCol[col]); // compute horizontal coordinates, z-index's, and reorder the array 13324 } 13325 } 13326 }; 13327 TimeGridEventRenderer.prototype.assignSegSizes = function (allSegs) { 13328 var _a = this, timeGrid = _a.timeGrid, segsByCol = _a.segsByCol; 13329 var colCnt = timeGrid.colCnt; 13330 timeGrid.assignSegVerticals(allSegs); // horizontals relies on this 13331 if (segsByCol) { 13332 for (var col = 0; col < colCnt; col++) { 13333 this.assignSegCss(segsByCol[col]); 13334 } 13335 } 13336 }; 13337 // Computes a default event time formatting string if `eventTimeFormat` is not explicitly defined 13338 TimeGridEventRenderer.prototype.computeEventTimeFormat = function () { 13339 return { 13340 hour: 'numeric', 13341 minute: '2-digit', 13342 meridiem: false 13343 }; 13344 }; 13345 // Computes a default `displayEventEnd` value if one is not expliclty defined 13346 TimeGridEventRenderer.prototype.computeDisplayEventEnd = function () { 13347 return true; 13348 }; 13349 // Renders the HTML for a single event segment's default rendering 13350 TimeGridEventRenderer.prototype.renderSegHtml = function (seg, mirrorInfo) { 13351 var view = this.context.view; 13352 var eventRange = seg.eventRange; 13353 var eventDef = eventRange.def; 13354 var eventUi = eventRange.ui; 13355 var allDay = eventDef.allDay; 13356 var isDraggable = view.computeEventDraggable(eventDef, eventUi); 13357 var isResizableFromStart = seg.isStart && view.computeEventStartResizable(eventDef, eventUi); 13358 var isResizableFromEnd = seg.isEnd && view.computeEventEndResizable(eventDef, eventUi);
13359 var classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd, mirrorInfo); 13360 var skinCss = core.cssToStr(this.getSkinCss(eventUi)); 13361 var timeText; 13362 var fullTimeText; // more verbose time text. for the print stylesheet 13363 var startTimeText; // just the start time text 13364 classes.unshift('fc-time-grid-event'); 13365 // if the event appears to span more than one day... 13366 if (core.isMultiDayRange(eventRange.range)) { 13367 // Don't display time text on segments that run entirely through a day. 13368 // That would appear as midnight-midnight and would look dumb. 13369 // Otherwise, display the time text for the *segment's* times (like 6pm-midnight or midnight-10am) 13370 if (seg.isStart || seg.isEnd) { 13371 var unzonedStart = seg.start; 13372 var unzonedEnd = seg.end; 13373 timeText = this._getTimeText(unzonedStart, unzonedEnd, allDay); // TODO: give the timezones 13374 fullTimeText = this._getTimeText(unzonedStart, unzonedEnd, allDay, this.fullTimeFormat); 13375 startTimeText = this._getTimeText(unzonedStart, unzonedEnd, allDay, null, false); // displayEnd=false 13376 } 13377 } 13378 else { 13379 // Display the normal time text for the *event's* times 13380 timeText = this.getTimeText(eventRange); 13381 fullTimeText = this.getTimeText(eventRange, this.fullTimeFormat); 13382 startTimeText = this.getTimeText(eventRange, null, false); // displayEnd=false 13383 } 13384 return '<a class="' + classes.join(' ') + '"' + 13385 (eventDef.url ? 13386 ' href="' + core.htmlEscape(eventDef.url) + '"' : 13387 '') + 13388 (skinCss ? 13389 ' style="' + skinCss + '"' : 13390 '') + 13391 '>' + 13392 '<div class="fc-content">' + 13393 (timeText ? 13394 '<div class="fc-time"' + 13395 ' data-start="' + core.htmlEscape(startTimeText) + '"' + 13396 ' data-full="' + core.htmlEscape(fullTimeText) + '"' + 13397 '>' + 13398 '<span>' + core.htmlEscape(timeText) + '</span>' + 13399 '</div>' : 13400 '') + 13401 (eventDef.title ? 13402 '<div class="fc-title">' + 13403 core.htmlEscape(eventDef.title) + 13404 '</div>' : 13405 '') + 13406 '</div>' + 13407 /* TODO: write CSS for this 13408 (isResizableFromStart ? 13409 '<div class="fc-resizer fc-start-resizer"></div>' : 13410 '' 13411 ) + 13412 */ 13413 (isResizableFromEnd ? 13414 '<div class="fc-resizer fc-end-resizer"></div>' : 13415 '') + 13416 '</a>'; 13417 }; 13418 // Given an array of segments that are all in the same column, sets the backwardCoord and forwardCoord on each. 13419 // Assumed the segs are already ordered. 13420 // NOTE: Also reorders the given array by date! 13421 TimeGridEventRenderer.prototype.computeSegHorizontals = function (segs) { 13422 var levels; 13423 var level0; 13424 var i; 13425 levels = buildSlotSegLevels(segs); 13426 computeForwardSlotSegs(levels); 13427 if ((level0 = levels[0])) { 13428 for (i = 0; i < level0.length; i++) { 13429 computeSlotSegPressures(level0[i]); 13430 } 13431 for (i = 0; i < level0.length; i++) { 13432 this.computeSegForwardBack(level0[i], 0, 0); 13433 } 13434 } 13435 }; 13436 // Calculate seg.forwardCoord and seg.backwardCoord for the segment, where both values range 13437 // from 0 to 1. If the calendar is left-to-right, the seg.backwardCoord maps to "left" and 13438 // seg.forwardCoord maps to "right" (via percentage). Vice-versa if the calendar is right-to-left. 13439 // 13440 // The segment might be part of a "series", which means consecutive segments with the same pressure 13441 // who's width is unknown until an edge has been hit. `seriesBackwardPressure` is the number of 13442 // segments behind this one in the current series, and `seriesBackwardCoord` is the starting 13443 // coordinate of the first segment in the series. 13444 TimeGridEventRenderer.prototype.computeSegForwardBack = function (seg, seriesBackwardPressure, seriesBackwardCoord) { 13445 var forwardSegs = seg.forwardSegs; 13446 var i; 13447 if (seg.forwardCoord === undefined) { // not already computed 13448 if (!forwardSegs.length) { 13449 // if there are no forward segments, this segment should butt up against the edge 13450 seg.forwardCoord = 1; 13451 } 13452 else { 13453 // sort highest pressure first 13454 this.sortForwardSegs(forwardSegs); 13455 // this segment's forwardCoord will be calculated from the backwardCoord of the 13456 // highest-pressure forward segment. 13457 this.computeSegForwardBack(forwardSegs[0], seriesBackwardPressure + 1, seriesBackwardCoord); 13458 seg.forwardCoord = forwardSegs[0].backwardCoord; 13459 } 13460 // calculate the backwardCoord from the forwardCoord. consider the series 13461 seg.backwardCoord = seg.forwardCoord - 13462 (seg.forwardCoord - seriesBackwardCoord) / // available width for series 13463 (seriesBackwardPressure + 1); // # of segments in the series
13464 // use this segment's coordinates to computed the coordinates of the less-pressurized 13465 // forward segments 13466 for (i = 0; i < forwardSegs.length; i++) { 13467 this.computeSegForwardBack(forwardSegs[i], 0, seg.forwardCoord); 13468 } 13469 } 13470 }; 13471 TimeGridEventRenderer.prototype.sortForwardSegs = function (forwardSegs) { 13472 var objs = forwardSegs.map(buildTimeGridSegCompareObj); 13473 var specs = [ 13474 // put higher-pressure first 13475 { field: 'forwardPressure', order: -1 }, 13476 // put segments that are closer to initial edge first (and favor ones with no coords yet) 13477 { field: 'backwardCoord', order: 1 } 13478 ].concat(this.context.view.eventOrderSpecs); 13479 objs.sort(function (obj0, obj1) { 13480 return core.compareByFieldSpecs(obj0, obj1, specs); 13481 }); 13482 return objs.map(function (c) { 13483 return c._seg; 13484 }); 13485 }; 13486 // Given foreground event segments that have already had their position coordinates computed, 13487 // assigns position-related CSS values to their elements. 13488 TimeGridEventRenderer.prototype.assignSegCss = function (segs) { 13489 for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) { 13490 var seg = segs_1[_i]; 13491 core.applyStyle(seg.el, this.generateSegCss(seg)); 13492 if (seg.level > 0) { 13493 seg.el.classList.add('fc-time-grid-event-inset'); 13494 } 13495 // if the event is short that the title will be cut off, 13496 // attach a className that condenses the title into the time area. 13497 if (seg.eventRange.def.title && seg.bottom - seg.top < 30) { 13498 seg.el.classList.add('fc-short'); // TODO: "condensed" is a better name 13499 } 13500 } 13501 }; 13502 // Generates an object with CSS properties/values that should be applied to an event segment element. 13503 // Contains important positioning-related properties that should be applied to any event element, customized or not. 13504 TimeGridEventRenderer.prototype.generateSegCss = function (seg) { 13505 var shouldOverlap = this.context.options.slotEventOverlap; 13506 var backwardCoord = seg.backwardCoord; // the left side if LTR. the right side if RTL. floating-point 13507 var forwardCoord = seg.forwardCoord; // the right side if LTR. the left side if RTL. floating-point 13508 var props = this.timeGrid.generateSegVerticalCss(seg); // get top/bottom first 13509 var isRtl = this.timeGrid.isRtl; 13510 var left; // amount of space from left edge, a fraction of the total width 13511 var right; // amount of space from right edge, a fraction of the total width 13512 if (shouldOverlap) { 13513 // double the width, but don't go beyond the maximum forward coordinate (1.0) 13514 forwardCoord = Math.min(1, backwardCoord + (forwardCoord - backwardCoord) * 2); 13515 } 13516 if (isRtl) { 13517 left = 1 - forwardCoord; 13518 right = backwardCoord; 13519 } 13520 else { 13521 left = backwardCoord; 13522 right = 1 - forwardCoord; 13523 } 13524 props.zIndex = seg.level + 1; // convert from 0-base to 1-based 13525 props.left = left * 100 + '%'; 13526 props.right = right * 100 + '%'; 13527 if (shouldOverlap && seg.forwardPressure) { 13528 // add padding to the edge so that forward stacked events don't cover the resizer's icon 13529 props[isRtl ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width 13530 } 13531 return props; 13532 }; 13533 return TimeGridEventRenderer; 13534 }(core.FgEventRenderer)); 13535 // Builds an array of segments "levels". The first level will be the leftmost tier of segments if the calendar is 13536 // left-to-right, or the rightmost if the calendar is right-to-left. Assumes the segments are already ordered by date. 13537 function buildSlotSegLevels(segs) { 13538 var levels = []; 13539 var i; 13540 var seg; 13541 var j; 13542 for (i = 0; i < segs.length; i++) { 13543 seg = segs[i]; 13544 // go through all the levels and stop on the first level where there are no collisions 13545 for (j = 0; j < levels.length; j++) { 13546 if (!computeSlotSegCollisions(seg, levels[j]).length) { 13547 break; 13548 } 13549 } 13550 seg.level = j; 13551 (levels[j] || (levels[j] = [])).push(seg); 13552 } 13553 return levels; 13554 } 13555 // For every segment, figure out the other segments that are in subsequent 13556 // levels that also occupy the same vertical space. Accumulate in seg.forwardSegs 13557 function computeForwardSlotSegs(levels) { 13558 var i; 13559 var level; 13560 var j; 13561 var seg; 13562 var k; 13563 for (i = 0; i < levels.length; i++) { 13564 level = levels[i]; 13565 for (j = 0; j < level.length; j++) { 13566 seg = level[j]; 13567 seg.forwardSegs = []; 13568 for (k = i + 1; k < levels.length; k++) { 13569 computeSlotSegCollisions(seg, levels[k], seg.forwardSegs); 13570 } 13571 } 13572 } 13573 } 13574 // Figure out which path forward (via seg.forwardSegs) results in the longest path until 13575 // the furthest edge is reached. The number of segments in this path will be seg.forwardPressure 13576 function computeSlotSegPressures(seg) { 13577 var forwardSegs = seg.forwardSegs; 13578 var forwardPressure = 0; 13579 var i; 13580 var forwardSeg; 13581 if (seg.forwardPressure === undefined) { // not already computed 13582 for (i = 0; i < forwardSegs.length; i++) { 13583 forwardSeg = forwardSegs[i]; 13584 // figure out the child's maximum forward path 13585 computeSlotSegPressures(forwardSeg); 13586 // either use the existing maximum, or use the child's forward pressure 13587 // plus one (for the forwardSeg itself) 13588 forwardPressure = Math.max(forwardPressure, 1 + forwardSeg.forwardPressure); 13589 } 13590 seg.forwardPressure = forwardPressure; 13591 } 13592 } 13593 // Find all the segments in `otherSegs` that vertically collide with `seg`. 13594 // Append into an optionally-supplied `results` array and return. 13595 function computeSlotSegCollisions(seg, otherSegs, results) { 13596 if (results === void 0) { results = []; } 13597 for (var i = 0; i < otherSegs.length; i++) { 13598 if (isSlotSegCollision(seg, otherSegs[i])) { 13599 results.push(otherSegs[i]); 13600 } 13601 } 13602 return results; 13603 } 13604 // Do these segments occupy the same vertical space? 13605 function isSlotSegCollision(seg1, seg2) { 13606 return seg1.bottom > seg2.top && seg1.top < seg2.bottom; 13607 } 13608 function buildTimeGridSegCompareObj(seg) { 13609 var obj = core.buildSegCompareObj(seg); 13610 obj.forwardPressure = seg.forwardPressure; 13611 obj.backwardCoord = seg.backwardCoord; 13612 return obj; 13613 } 13614 13615 var TimeGridMirrorRenderer = /** @class */ (function (_super) { 13616 __extends(TimeGridMirrorRenderer, _super); 13617 function TimeGridMirrorRenderer() { 13618 return _super !== null && _super.apply(this, arguments) || this; 13619 } 13620 TimeGridMirrorRenderer.prototype.attachSegs = function (segs, mirrorInfo) { 13621 this.segsByCol = this.timeGrid.groupSegsByCol(segs); 13622 this.timeGrid.attachSegsByCol(this.segsByCol, this.timeGrid.mirrorContainerEls); 13623 this.sourceSeg = mirrorInfo.sourceSeg; 13624 }; 13625 TimeGridMirrorRenderer.prototype.generateSegCss = function (seg) { 13626 var props = _super.prototype.generateSegCss.call(this, seg); 13627 var sourceSeg = this.sourceSeg; 13628 if (sourceSeg && sourceSeg.col === seg.col) { 13629 var sourceSegProps = _super.prototype.generateSegCss.call(this, sourceSeg); 13630 props.left = sourceSegProps.left; 13631 props.right = sourceSegProps.right; 13632 props.marginLeft = sourceSegProps.marginLeft; 13633 props.marginRight = sourceSegProps.marginRight; 13634 } 13635 return props; 13636 }; 13637 return TimeGridMirrorRenderer; 13638 }(TimeGridEventRenderer)); 13639 13640 var TimeGridFillRenderer = /** @class */ (function (_super) { 13641 __extends(TimeGridFillRenderer, _super); 13642 function TimeGridFillRenderer(timeGrid) { 13643 var _this = _super.call(this, timeGrid.context) || this; 13644 _this.timeGrid = timeGrid; 13645 return _this; 13646 } 13647 TimeGridFillRenderer.prototype.attachSegs = function (type, segs) { 13648 var timeGrid = this.timeGrid; 13649 var containerEls; 13650 // TODO: more efficient lookup 13651 if (type === 'bgEvent') { 13652 containerEls = timeGrid.bgContainerEls; 13653 } 13654 else if (type === 'businessHours') { 13655 containerEls = timeGrid.businessContainerEls; 13656 } 13657 else if (type === 'highlight') { 13658 containerEls = timeGrid.highlightContainerEls; 13659 } 13660 timeGrid.attachSegsByCol(timeGrid.groupSegsByCol(segs), containerEls); 13661 return segs.map(function (seg) { 13662 return seg.el; 13663 }); 13664 }; 13665 TimeGridFillRenderer.prototype.computeSegSizes = function (segs) { 13666 this.timeGrid.computeSegVerticals(segs); 13667 }; 13668 TimeGridFillRenderer.prototype.assignSegSizes = function (segs) { 13669 this.timeGrid.assignSegVerticals(segs); 13670 }; 13671 return TimeGridFillRenderer; 13672 }(core.FillRenderer)); 13673 13674 /* A component that renders one or more columns of vertical time slots 13675 ----------------------------------------------------------------------------------------------------------------------*/ 13676 // potential nice values for the slot-duration and interval-duration 13677 // from largest to smallest 13678 var AGENDA_STOCK_SUB_DURATIONS = [ 13679 { hours: 1 }, 13680 { minutes: 30 }, 13681 { minutes: 15 }, 13682 { seconds: 30 }, 13683 { seconds: 15 } 13684 ]; 13685 var TimeGrid = /** @class */ (function (_super) { 13686 __extends(TimeGrid, _super); 13687 function TimeGrid(context, el, renderProps) { 13688 var _this = _super.call(this, context, el) || this; 13689 _this.isSlatSizesDirty = false;
13690 _this.isColSizesDirty = false; 13691 _this.renderSlats = core.memoizeRendering(_this._renderSlats); 13692 var eventRenderer = _this.eventRenderer = new TimeGridEventRenderer(_this); 13693 var fillRenderer = _this.fillRenderer = new TimeGridFillRenderer(_this); 13694 _this.mirrorRenderer = new TimeGridMirrorRenderer(_this); 13695 var renderColumns = _this.renderColumns = core.memoizeRendering(_this._renderColumns, _this._unrenderColumns); 13696 _this.renderBusinessHours = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'businessHours'), fillRenderer.unrender.bind(fillRenderer, 'businessHours'), [renderColumns]); 13697 _this.renderDateSelection = core.memoizeRendering(_this._renderDateSelection, _this._unrenderDateSelection, [renderColumns]); 13698 _this.renderFgEvents = core.memoizeRendering(eventRenderer.renderSegs.bind(eventRenderer), eventRenderer.unrender.bind(eventRenderer), [renderColumns]); 13699 _this.renderBgEvents = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'bgEvent'), fillRenderer.unrender.bind(fillRenderer, 'bgEvent'), [renderColumns]); 13700 _this.renderEventSelection = core.memoizeRendering(eventRenderer.selectByInstanceId.bind(eventRenderer), eventRenderer.unselectByInstanceId.bind(eventRenderer), [_this.renderFgEvents]); 13701 _this.renderEventDrag = core.memoizeRendering(_this._renderEventDrag, _this._unrenderEventDrag, [renderColumns]); 13702 _this.renderEventResize = core.memoizeRendering(_this._renderEventResize, _this._unrenderEventResize, [renderColumns]); 13703 _this.processOptions(); 13704 el.innerHTML = 13705 '<div class="fc-bg"></div>' + 13706 '<div class="fc-slats"></div>' + 13707 '<hr class="fc-divider ' + _this.theme.getClass('widgetHeader') + '" style="display:none" />'; 13708 _this.rootBgContainerEl = el.querySelector('.fc-bg'); 13709 _this.slatContainerEl = el.querySelector('.fc-slats'); 13710 _this.bottomRuleEl = el.querySelector('.fc-divider'); 13711 _this.renderProps = renderProps; 13712 return _this; 13713 } 13714 /* Options 13715 ------------------------------------------------------------------------------------------------------------------*/ 13716 // Parses various options into properties of this object 13717 TimeGrid.prototype.processOptions = function () { 13718 var slotDuration = this.opt('slotDuration'); 13719 var snapDuration = this.opt('snapDuration'); 13720 var snapsPerSlot; 13721 var input; 13722 slotDuration = core.createDuration(slotDuration); 13723 snapDuration = snapDuration ? core.createDuration(snapDuration) : slotDuration; 13724 snapsPerSlot = core.wholeDivideDurations(slotDuration, snapDuration); 13725 if (snapsPerSlot === null) { 13726 snapDuration = slotDuration; 13727 snapsPerSlot = 1; 13728 // TODO: say warning? 13729 } 13730 this.slotDuration = slotDuration; 13731 this.snapDuration = snapDuration; 13732 this.snapsPerSlot = snapsPerSlot; 13733 // might be an array value (for TimelineView). 13734 // if so, getting the most granular entry (the last one probably). 13735 input = this.opt('slotLabelFormat'); 13736 if (Array.isArray(input)) { 13737 input = input[input.length - 1]; 13738 } 13739 this.labelFormat = core.createFormatter(input || { 13740 hour: 'numeric', 13741 minute: '2-digit', 13742 omitZeroMinute: true, 13743 meridiem: 'short' 13744 }); 13745 input = this.opt('slotLabelInterval'); 13746 this.labelInterval = input ? 13747 core.createDuration(input) : 13748 this.computeLabelInterval(slotDuration); 13749 }; 13750 // Computes an automatic value for slotLabelInterval 13751 TimeGrid.prototype.computeLabelInterval = function (slotDuration) { 13752 var i; 13753 var labelInterval; 13754 var slotsPerLabel; 13755 // find the smallest stock label interval that results in more than one slots-per-label 13756 for (i = AGENDA_STOCK_SUB_DURATIONS.length - 1; i >= 0; i--) { 13757 labelInterval = core.createDuration(AGENDA_STOCK_SUB_DURATIONS[i]);
13758 slotsPerLabel = core.wholeDivideDurations(labelInterval, slotDuration); 13759 if (slotsPerLabel !== null && slotsPerLabel > 1) { 13760 return labelInterval; 13761 } 13762 } 13763 return slotDuration; // fall back 13764 }; 13765 /* Rendering 13766 ------------------------------------------------------------------------------------------------------------------*/ 13767 TimeGrid.prototype.render = function (props) { 13768 var cells = props.cells; 13769 this.colCnt = cells.length; 13770 this.renderSlats(props.dateProfile); 13771 this.renderColumns(props.cells, props.dateProfile); 13772 this.renderBusinessHours(props.businessHourSegs); 13773 this.renderDateSelection(props.dateSelectionSegs); 13774 this.renderFgEvents(props.fgEventSegs); 13775 this.renderBgEvents(props.bgEventSegs); 13776 this.renderEventSelection(props.eventSelection); 13777 this.renderEventDrag(props.eventDrag); 13778 this.renderEventResize(props.eventResize); 13779 }; 13780 TimeGrid.prototype.destroy = function () { 13781 _super.prototype.destroy.call(this); 13782 // should unrender everything else too 13783 this.renderSlats.unrender(); 13784 this.renderColumns.unrender(); 13785 }; 13786 TimeGrid.prototype.updateSize = function (isResize) { 13787 var _a = this, fillRenderer = _a.fillRenderer, eventRenderer = _a.eventRenderer, mirrorRenderer = _a.mirrorRenderer; 13788 if (isResize || this.isSlatSizesDirty) { 13789 this.buildSlatPositions(); 13790 this.isSlatSizesDirty = false; 13791 } 13792 if (isResize || this.isColSizesDirty) { 13793 this.buildColPositions(); 13794 this.isColSizesDirty = false; 13795 } 13796 fillRenderer.computeSizes(isResize); 13797 eventRenderer.computeSizes(isResize); 13798 mirrorRenderer.computeSizes(isResize); 13799 fillRenderer.assignSizes(isResize); 13800 eventRenderer.assignSizes(isResize); 13801 mirrorRenderer.assignSizes(isResize); 13802 }; 13803 TimeGrid.prototype._renderSlats = function (dateProfile) { 13804 var theme = this.theme; 13805 this.slatContainerEl.innerHTML = 13806 '<table class="' + theme.getClass('tableGrid') + '">' + 13807 this.renderSlatRowHtml(dateProfile) + 13808 '</table>'; 13809 this.slatEls = core.findElements(this.slatContainerEl, 'tr'); 13810 this.slatPositions = new core.PositionCache(this.el, this.slatEls, false, true // vertical 13811 ); 13812 this.isSlatSizesDirty = true; 13813 }; 13814 // Generates the HTML for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL. 13815 TimeGrid.prototype.renderSlatRowHtml = function (dateProfile) { 13816 var _a = this, dateEnv = _a.dateEnv, theme = _a.theme, isRtl = _a.isRtl; 13817 var html = ''; 13818 var dayStart = core.startOfDay(dateProfile.renderRange.start); 13819 var slotTime = dateProfile.minTime; 13820 var slotIterator = core.createDuration(0); 13821 var slotDate; // will be on the view's first day, but we only care about its time 13822 var isLabeled; 13823 var axisHtml; 13824 // Calculate the time for each slot 13825 while (core.asRoughMs(slotTime) < core.asRoughMs(dateProfile.maxTime)) { 13826 slotDate = dateEnv.add(dayStart, slotTime); 13827 isLabeled = core.wholeDivideDurations(slotIterator, this.labelInterval) !== null; 13828 axisHtml = 13829 '<td class="fc-axis fc-time ' + theme.getClass('widgetContent') + '">' + 13830 (isLabeled ? 13831 '<span>' + // for matchCellWidths 13832 core.htmlEscape(dateEnv.format(slotDate, this.labelFormat)) + 13833 '</span>' : 13834 '') + 13835 '</td>'; 13836 html += 13837 '<tr data-time="' + core.formatIsoTimeString(slotDate) + '"' + 13838 (isLabeled ? '' : ' class="fc-minor"') + 13839 '>' + 13840 (!isRtl ? axisHtml : '') + 13841 '<td class="' + theme.getClass('widgetContent') + '"></td>' + 13842 (isRtl ? axisHtml : '') + 13843 '</tr>'; 13844 slotTime = core.addDurations(slotTime, this.slotDuration); 13845 slotIterator = core.addDurations(slotIterator, this.slotDuration); 13846 } 13847 return html; 13848 }; 13849 TimeGrid.prototype._renderColumns = function (cells, dateProfile) { 13850 var _a = this, theme = _a.theme, dateEnv = _a.dateEnv, view = _a.view; 13851 var bgRow = new daygrid.DayBgRow(this.context);
13852 this.rootBgContainerEl.innerHTML = 13853 '<table class="' + theme.getClass('tableGrid') + '">' + 13854 bgRow.renderHtml({ 13855 cells: cells, 13856 dateProfile: dateProfile, 13857 renderIntroHtml: this.renderProps.renderBgIntroHtml 13858 }) + 13859 '</table>'; 13860 this.colEls = core.findElements(this.el, '.fc-day, .fc-disabled-day'); 13861 for (var col = 0; col < this.colCnt; col++) { 13862 this.publiclyTrigger('dayRender', [ 13863 { 13864 date: dateEnv.toDate(cells[col].date), 13865 el: this.colEls[col], 13866 view: view 13867 } 13868 ]); 13869 } 13870 if (this.isRtl) { 13871 this.colEls.reverse(); 13872 } 13873 this.colPositions = new core.PositionCache(this.el, this.colEls, true, // horizontal 13874 false); 13875 this.renderContentSkeleton(); 13876 this.isColSizesDirty = true; 13877 }; 13878 TimeGrid.prototype._unrenderColumns = function () { 13879 this.unrenderContentSkeleton(); 13880 }; 13881 /* Content Skeleton 13882 ------------------------------------------------------------------------------------------------------------------*/ 13883 // Renders the DOM that the view's content will live in 13884 TimeGrid.prototype.renderContentSkeleton = function () { 13885 var parts = []; 13886 var skeletonEl; 13887 parts.push(this.renderProps.renderIntroHtml()); 13888 for (var i = 0; i < this.colCnt; i++) { 13889 parts.push('<td>' + 13890 '<div class="fc-content-col">' + 13891 '<div class="fc-event-container fc-mirror-container"></div>' + 13892 '<div class="fc-event-container"></div>' + 13893 '<div class="fc-highlight-container"></div>' + 13894 '<div class="fc-bgevent-container"></div>' + 13895 '<div class="fc-business-container"></div>' + 13896 '</div>' + 13897 '</td>'); 13898 } 13899 if (this.isRtl) { 13900 parts.reverse(); 13901 } 13902 skeletonEl = this.contentSkeletonEl = core.htmlToElement('<div class="fc-content-skeleton">' + 13903 '<table>' + 13904 '<tr>' + parts.join('') + '</tr>' + 13905 '</table>' + 13906 '</div>'); 13907 this.colContainerEls = core.findElements(skeletonEl, '.fc-content-col'); 13908 this.mirrorContainerEls = core.findElements(skeletonEl, '.fc-mirror-container'); 13909 this.fgContainerEls = core.findElements(skeletonEl, '.fc-event-container:not(.fc-mirror-container)'); 13910 this.bgContainerEls = core.findElements(skeletonEl, '.fc-bgevent-container'); 13911 this.highlightContainerEls = core.findElements(skeletonEl, '.fc-highlight-container'); 13912 this.businessContainerEls = core.findElements(skeletonEl, '.fc-business-container'); 13913 if (this.isRtl) { 13914 this.colContainerEls.reverse(); 13915 this.mirrorContainerEls.reverse(); 13916 this.fgContainerEls.reverse(); 13917 this.bgContainerEls.reverse(); 13918 this.highlightContainerEls.reverse(); 13919 this.businessContainerEls.reverse(); 13920 } 13921 this.el.appendChild(skeletonEl); 13922 }; 13923 TimeGrid.prototype.unrenderContentSkeleton = function () { 13924 core.removeElement(this.contentSkeletonEl); 13925 }; 13926 // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's col 13927 TimeGrid.prototype.groupSegsByCol = function (segs) { 13928 var segsByCol = []; 13929 var i; 13930 for (i = 0; i < this.colCnt; i++) { 13931 segsByCol.push([]); 13932 } 13933 for (i = 0; i < segs.length; i++) { 13934 segsByCol[segs[i].col].push(segs[i]); 13935 } 13936 return segsByCol; 13937 }; 13938 // Given segments grouped by column, insert the segments' elements into a parallel array of container 13939 // elements, each living within a column. 13940 TimeGrid.prototype.attachSegsByCol = function (segsByCol, containerEls) { 13941 var col; 13942 var segs; 13943 var i; 13944 for (col = 0; col < this.colCnt; col++) { // iterate each column grouping 13945 segs = segsByCol[col]; 13946 for (i = 0; i < segs.length; i++) { 13947 containerEls[col].appendChild(segs[i].el); 13948 } 13949 } 13950 }; 13951 /* Now Indicator 13952 ------------------------------------------------------------------------------------------------------------------*/ 13953 TimeGrid.prototype.getNowIndicatorUnit = function () { 13954 return 'minute'; // will refresh on the minute 13955 }; 13956 TimeGrid.prototype.renderNowIndicator = function (segs, date) { 13957 // HACK: if date columns not ready for some reason (scheduler) 13958 if (!this.colContainerEls) { 13959 return; 13960 } 13961 var top = this.computeDateTop(date); 13962 var nodes = []; 13963 var i; 13964 // render lines within the columns 13965 for (i = 0; i < segs.length; i++) { 13966 var lineEl = core.createElement('div', { className: 'fc-now-indicator fc-now-indicator-line' }); 13967 lineEl.style.top = top + 'px'; 13968 this.colContainerEls[segs[i].col].appendChild(lineEl); 13969 nodes.push(lineEl); 13970 } 13971 // render an arrow over the axis 13972 if (segs.length > 0) { // is the current time in view? 13973 var arrowEl = core.createElement('div', { className: 'fc-now-indicator fc-now-indicator-arrow' }); 13974 arrowEl.style.top = top + 'px'; 13975 this.contentSkeletonEl.appendChild(arrowEl); 13976 nodes.push(arrowEl); 13977 } 13978 this.nowIndicatorEls = nodes; 13979 }; 13980 TimeGrid.prototype.unrenderNowIndicator = function () { 13981 if (this.nowIndicatorEls) {
13982 this.nowIndicatorEls.forEach(core.removeElement); 13983 this.nowIndicatorEls = null; 13984 } 13985 }; 13986 /* Coordinates 13987 ------------------------------------------------------------------------------------------------------------------*/ 13988 TimeGrid.prototype.getTotalSlatHeight = function () { 13989 return this.slatContainerEl.getBoundingClientRect().height; 13990 }; 13991 // Computes the top coordinate, relative to the bounds of the grid, of the given date. 13992 // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight. 13993 TimeGrid.prototype.computeDateTop = function (when, startOfDayDate) { 13994 if (!startOfDayDate) { 13995 startOfDayDate = core.startOfDay(when); 13996 } 13997 return this.computeTimeTop(core.createDuration(when.valueOf() - startOfDayDate.valueOf())); 13998 }; 13999 // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration). 14000 TimeGrid.prototype.computeTimeTop = function (duration) { 14001 var len = this.slatEls.length; 14002 var dateProfile = this.props.dateProfile; 14003 var slatCoverage = (duration.milliseconds - core.asRoughMs(dateProfile.minTime)) / core.asRoughMs(this.slotDuration); // floating-point value of # of slots covered 14004 var slatIndex; 14005 var slatRemainder; 14006 // compute a floating-point number for how many slats should be progressed through. 14007 // from 0 to number of slats (inclusive) 14008 // constrained because minTime/maxTime might be customized. 14009 slatCoverage = Math.max(0, slatCoverage); 14010 slatCoverage = Math.min(len, slatCoverage); 14011 // an integer index of the furthest whole slat 14012 // from 0 to number slats (*exclusive*, so len-1) 14013 slatIndex = Math.floor(slatCoverage); 14014 slatIndex = Math.min(slatIndex, len - 1); 14015 // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition. 14016 // could be 1.0 if slatCoverage is covering *all* the slots 14017 slatRemainder = slatCoverage - slatIndex; 14018 return this.slatPositions.tops[slatIndex] + 14019 this.slatPositions.getHeight(slatIndex) * slatRemainder; 14020 }; 14021 // For each segment in an array, computes and assigns its top and bottom properties 14022 TimeGrid.prototype.computeSegVerticals = function (segs) { 14023 var eventMinHeight = this.opt('timeGridEventMinHeight'); 14024 var i; 14025 var seg; 14026 var dayDate; 14027 for (i = 0; i < segs.length; i++) { 14028 seg = segs[i]; 14029 dayDate = this.props.cells[seg.col].date; 14030 seg.top = this.computeDateTop(seg.start, dayDate); 14031 seg.bottom = Math.max(seg.top + eventMinHeight, this.computeDateTop(seg.end, dayDate)); 14032 } 14033 }; 14034 // Given segments that already have their top/bottom properties computed, applies those values to 14035 // the segments' elements. 14036 TimeGrid.prototype.assignSegVerticals = function (segs) { 14037 var i; 14038 var seg; 14039 for (i = 0; i < segs.length; i++) { 14040 seg = segs[i]; 14041 core.applyStyle(seg.el, this.generateSegVerticalCss(seg)); 14042 } 14043 }; 14044 // Generates an object with CSS properties for the top/bottom coordinates of a segment element 14045 TimeGrid.prototype.generateSegVerticalCss = function (seg) { 14046 return { 14047 top: seg.top, 14048 bottom: -seg.bottom // flipped because needs to be space beyond bottom edge of event container 14049 }; 14050 }; 14051 /* Sizing 14052 ------------------------------------------------------------------------------------------------------------------*/ 14053 TimeGrid.prototype.buildPositionCaches = function () { 14054 this.buildColPositions(); 14055 this.buildSlatPositions(); 14056 }; 14057 TimeGrid.prototype.buildColPositions = function () { 14058 this.colPositions.build(); 14059 }; 14060 TimeGrid.prototype.buildSlatPositions = function () { 14061 this.slatPositions.build(); 14062 }; 14063 /* Hit System 14064 ------------------------------------------------------------------------------------------------------------------*/ 14065 TimeGrid.prototype.positionToHit = function (positionLeft, positionTop) { 14066 var _a = this, dateEnv = _a.dateEnv, snapsPerSlot = _a.snapsPerSlot, slatPositions = _a.slatPositions, colPositions = _a.colPositions; 14067 var colIndex = colPositions.leftToIndex(positionLeft); 14068 var slatIndex = slatPositions.topToIndex(positionTop); 14069 if (colIndex != null && slatIndex != null) { 14070 var slatTop = slatPositions.tops[slatIndex]; 14071 var slatHeight = slatPositions.getHeight(slatIndex); 14072 var partial = (positionTop - slatTop) / slatHeight; // floating point number between 0 and 1 14073 var localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat 14074 var snapIndex = slatIndex * snapsPerSlot + localSnapIndex; 14075 var dayDate = this.props.cells[colIndex].date; 14076 var time = core.addDurations(this.props.dateProfile.minTime, core.multiplyDuration(this.snapDuration, snapIndex)); 14077 var start = dateEnv.add(dayDate, time); 14078 var end = dateEnv.add(start, this.snapDuration); 14079 return { 14080 col: colIndex, 14081 dateSpan: { 14082 range: { start: start, end: end }, 14083 allDay: false 14084 }, 14085 dayEl: this.colEls[colIndex], 14086 relativeRect: { 14087 left: colPositions.lefts[colIndex], 14088 right: colPositions.rights[colIndex], 14089 top: slatTop, 14090 bottom: slatTop + slatHeight 14091 } 14092 }; 14093 } 14094 }; 14095 /* Event Drag Visualization 14096 ------------------------------------------------------------------------------------------------------------------*/ 14097 TimeGrid.prototype._renderEventDrag = function (state) { 14098 if (state) { 14099 this.eventRenderer.hideByHash(state.affectedInstances); 14100 if (state.isEvent) { 14101 this.mirrorRenderer.renderSegs(state.segs, { isDragging: true, sourceSeg: state.sourceSeg }); 14102 } 14103 else { 14104 this.fillRenderer.renderSegs('highlight', state.segs); 14105 } 14106 } 14107 }; 14108 TimeGrid.prototype._unrenderEventDrag = function (state) { 14109 if (state) { 14110 this.eventRenderer.showByHash(state.affectedInstances); 14111 this.mirrorRenderer.unrender(state.segs, { isDragging: true, sourceSeg: state.sourceSeg }); 14112 this.fillRenderer.unrender('highlight'); 14113 } 14114 }; 14115 /* Event Resize Visualization 14116 ------------------------------------------------------------------------------------------------------------------*/ 14117 TimeGrid.prototype._renderEventResize = function (state) { 14118 if (state) { 14119 this.eventRenderer.hideByHash(state.affectedInstances); 14120 this.mirrorRenderer.renderSegs(state.segs, { isResizing: true, sourceSeg: state.sourceSeg }); 14121 } 14122 }; 14123 TimeGrid.prototype._unrenderEventResize = function (state) { 14124 if (state) { 14125 this.eventRenderer.showByHash(state.affectedInstances); 14126 this.mirrorRenderer.unrender(state.segs, { isResizing: true, sourceSeg: state.sourceSeg }); 14127 } 14128 }; 14129 /* Selection 14130 ------------------------------------------------------------------------------------------------------------------*/ 14131 // Renders a visual indication of a selection. Overrides the default, which was to simply render a highlight. 14132 TimeGrid.prototype._renderDateSelection = function (segs) { 14133 if (segs) { 14134 if (this.opt('selectMirror')) { 14135 this.mirrorRenderer.renderSegs(segs, { isSelecting: true }); 14136 } 14137 else { 14138 this.fillRenderer.renderSegs('highlight', segs); 14139 } 14140 } 14141 }; 14142 TimeGrid.prototype._unrenderDateSelection = function (segs) { 14143 this.mirrorRenderer.unrender(segs, { isSelecting: true }); 14144 this.fillRenderer.unrender('highlight'); 14145 }; 14146 return TimeGrid; 14147 }(core.DateComponent)); 14148 14149 var AllDaySplitter = /** @class */ (function (_super) { 14150 __extends(AllDaySplitter, _super); 14151 function AllDaySplitter() { 14152 return _super !== null && _super.apply(this, arguments) || this; 14153 } 14154 AllDaySplitter.prototype.getKeyInfo = function () { 14155 return { 14156 allDay: {}, 14157 timed: {} 14158 }; 14159 }; 14160 AllDaySplitter.prototype.getKeysForDateSpan = function (dateSpan) { 14161 if (dateSpan.allDay) { 14162 return ['allDay']; 14163 } 14164 else {
14165 return ['timed']; 14166 } 14167 }; 14168 AllDaySplitter.prototype.getKeysForEventDef = function (eventDef) { 14169 if (!eventDef.allDay) { 14170 return ['timed']; 14171 } 14172 else if (core.hasBgRendering(eventDef)) { 14173 return ['timed', 'allDay']; 14174 } 14175 else { 14176 return ['allDay']; 14177 } 14178 }; 14179 return AllDaySplitter; 14180 }(core.Splitter)); 14181 14182 var TIMEGRID_ALL_DAY_EVENT_LIMIT = 5; 14183 var WEEK_HEADER_FORMAT = core.createFormatter({ week: 'short' }); 14184 /* An abstract class for all timegrid-related views. Displays one more columns with time slots running vertically. 14185 ----------------------------------------------------------------------------------------------------------------------*/ 14186 // Is a manager for the TimeGrid subcomponent and possibly the DayGrid subcomponent (if allDaySlot is on). 14187 // Responsible for managing width/height. 14188 var TimeGridView = /** @class */ (function (_super) { 14189 __extends(TimeGridView, _super); 14190 function TimeGridView(context, viewSpec, dateProfileGenerator, parentEl) { 14191 var _this = _super.call(this, context, viewSpec, dateProfileGenerator, parentEl) || this; 14192 _this.splitter = new AllDaySplitter(); 14193 /* Header Render Methods 14194 ------------------------------------------------------------------------------------------------------------------*/ 14195 // Generates the HTML that will go before the day-of week header cells 14196 _this.renderHeadIntroHtml = function () { 14197 var _a = _this, theme = _a.theme, dateEnv = _a.dateEnv; 14198 var range = _this.props.dateProfile.renderRange; 14199 var dayCnt = core.diffDays(range.start, range.end); 14200 var weekText; 14201 if (_this.opt('weekNumbers')) { 14202 weekText = dateEnv.format(range.start, WEEK_HEADER_FORMAT); 14203 return '' + 14204 '<th class="fc-axis fc-week-number ' + theme.getClass('widgetHeader') + '" ' + _this.axisStyleAttr() + '>' + 14205 core.buildGotoAnchorHtml(// aside from link, important for matchCellWidths 14206 _this, { date: range.start, type: 'week', forceOff: dayCnt > 1 }, core.htmlEscape(weekText) // inner HTML 14207 ) + 14208 '</th>'; 14209 } 14210 else { 14211 return '<th class="fc-axis ' + theme.getClass('widgetHeader') + '" ' + _this.axisStyleAttr() + '></th>'; 14212 } 14213 }; 14214 /* Time Grid Render Methods 14215 ------------------------------------------------------------------------------------------------------------------*/ 14216 // Generates the HTML that goes before the bg of the TimeGrid slot area. Long vertical column. 14217 _this.renderTimeGridBgIntroHtml = function () { 14218 var theme = _this.theme; 14219 return '<td class="fc-axis ' + theme.getClass('widgetContent') + '" ' + _this.axisStyleAttr() + '></td>'; 14220 }; 14221 // Generates the HTML that goes before all other types of cells. 14222 // Affects content-skeleton, mirror-skeleton, highlight-skeleton for both the time-grid and day-grid. 14223 _this.renderTimeGridIntroHtml = function () { 14224 return '<td class="fc-axis" ' + _this.axisStyleAttr() + '></td>'; 14225 }; 14226 /* Day Grid Render Methods 14227 ------------------------------------------------------------------------------------------------------------------*/ 14228 // Generates the HTML that goes before the all-day cells 14229 _this.renderDayGridBgIntroHtml = function () { 14230 var theme = _this.theme; 14231 return '' + 14232 '<td class="fc-axis ' + theme.getClass('widgetContent') + '" ' + _this.axisStyleAttr() + '>' + 14233 '<span>' + // needed for matchCellWidths 14234 core.getAllDayHtml(_this) + 14235 '</span>' + 14236 '</td>'; 14237 }; 14238 // Generates the HTML that goes before all other types of cells. 14239 // Affects content-skeleton, mirror-skeleton, highlight-skeleton for both the time-grid and day-grid. 14240 _this.renderDayGridIntroHtml = function () { 14241 return '<td class="fc-axis" ' + _this.axisStyleAttr() + '></td>'; 14242 }; 14243 _this.el.classList.add('fc-timeGrid-view'); 14244 _this.el.innerHTML = _this.renderSkeletonHtml();
14245 _this.scroller = new core.ScrollComponent('hidden', // overflow x 14246 'auto' // overflow y 14247 ); 14248 var timeGridWrapEl = _this.scroller.el; 14249 _this.el.querySelector('.fc-body > tr > td').appendChild(timeGridWrapEl); 14250 timeGridWrapEl.classList.add('fc-time-grid-container'); 14251 var timeGridEl = core.createElement('div', { className: 'fc-time-grid' }); 14252 timeGridWrapEl.appendChild(timeGridEl); 14253 _this.timeGrid = new TimeGrid(_this.context, timeGridEl, { 14254 renderBgIntroHtml: _this.renderTimeGridBgIntroHtml, 14255 renderIntroHtml: _this.renderTimeGridIntroHtml 14256 }); 14257 if (_this.opt('allDaySlot')) { // should we display the "all-day" area? 14258 _this.dayGrid = new daygrid.DayGrid(// the all-day subcomponent of this view 14259 _this.context, _this.el.querySelector('.fc-day-grid'), { 14260 renderNumberIntroHtml: _this.renderDayGridIntroHtml, 14261 renderBgIntroHtml: _this.renderDayGridBgIntroHtml, 14262 renderIntroHtml: _this.renderDayGridIntroHtml, 14263 colWeekNumbersVisible: false, 14264 cellWeekNumbersVisible: false 14265 }); 14266 // have the day-grid extend it's coordinate area over the <hr> dividing the two grids 14267 var dividerEl = _this.el.querySelector('.fc-divider'); 14268 _this.dayGrid.bottomCoordPadding = dividerEl.getBoundingClientRect().height; 14269 } 14270 return _this; 14271 } 14272 TimeGridView.prototype.destroy = function () { 14273 _super.prototype.destroy.call(this); 14274 this.timeGrid.destroy(); 14275 if (this.dayGrid) { 14276 this.dayGrid.destroy(); 14277 } 14278 this.scroller.destroy(); 14279 }; 14280 /* Rendering 14281 ------------------------------------------------------------------------------------------------------------------*/ 14282 // Builds the HTML skeleton for the view. 14283 // The day-grid and time-grid components will render inside containers defined by this HTML. 14284 TimeGridView.prototype.renderSkeletonHtml = function () { 14285 var theme = this.theme; 14286 return '' + 14287 '<table class="' + theme.getClass('tableGrid') + '">' + 14288 (this.opt('columnHeader') ? 14289 '<thead class="fc-head">' + 14290 '<tr>' + 14291 '<td class="fc-head-container ' + theme.getClass('widgetHeader') + '"> </td>' + 14292 '</tr>' + 14293 '</thead>' : 14294 '') + 14295 '<tbody class="fc-body">' + 14296 '<tr>' + 14297 '<td class="' + theme.getClass('widgetContent') + '">' + 14298 (this.opt('allDaySlot') ? 14299 '<div class="fc-day-grid"></div>' + 14300 '<hr class="fc-divider ' + theme.getClass('widgetHeader') + '" />' : 14301 '') + 14302 '</td>' + 14303 '</tr>' + 14304 '</tbody>' + 14305 '</table>'; 14306 }; 14307 /* Now Indicator 14308 ------------------------------------------------------------------------------------------------------------------*/ 14309 TimeGridView.prototype.getNowIndicatorUnit = function () { 14310 return this.timeGrid.getNowIndicatorUnit(); 14311 }; 14312 // subclasses should implement 14313 // renderNowIndicator(date: DateMarker) { 14314 // } 14315 TimeGridView.prototype.unrenderNowIndicator = function () { 14316 this.timeGrid.unrenderNowIndicator(); 14317 }; 14318 /* Dimensions 14319 ------------------------------------------------------------------------------------------------------------------*/ 14320 TimeGridView.prototype.updateSize = function (isResize, viewHeight, isAuto) { 14321 _super.prototype.updateSize.call(this, isResize, viewHeight, isAuto); // will call updateBaseSize. important that executes first 14322 this.timeGrid.updateSize(isResize); 14323 if (this.dayGrid) { 14324 this.dayGrid.updateSize(isResize); 14325 } 14326 }; 14327 // Adjusts the vertical dimensions of the view to the specified values 14328 TimeGridView.prototype.updateBaseSize = function (isResize, viewHeight, isAuto) { 14329 var _this = this; 14330 var eventLimit; 14331 var scrollerHeight; 14332 var scrollbarWidths; 14333 // make all axis cells line up 14334 this.axisWidth = core.matchCellWidths(core.findElements(this.el, '.fc-axis')); 14335 // hack to give the view some height prior to timeGrid's columns being rendered 14336 // TODO: separate setting height from scroller VS timeGrid. 14337 if (!this.timeGrid.colEls) { 14338 if (!isAuto) { 14339 scrollerHeight = this.computeScrollerHeight(viewHeight); 14340 this.scroller.setHeight(scrollerHeight); 14341 } 14342 return; 14343 } 14344 // set of fake row elements that must compensate when scroller has scrollbars 14345 var noScrollRowEls = core.findElements(this.el, '.fc-row').filter(function (node) { 14346 return !_this.scroller.el.contains(node); 14347 }); 14348 // reset all dimensions back to the original state 14349 this.timeGrid.bottomRuleEl.style.display = 'none'; // will be shown later if this <hr> is necessary 14350 this.scroller.clear(); // sets height to 'auto' and clears overflow
14351 noScrollRowEls.forEach(core.uncompensateScroll); 14352 // limit number of events in the all-day area 14353 if (this.dayGrid) { 14354 this.dayGrid.removeSegPopover(); // kill the "more" popover if displayed 14355 eventLimit = this.opt('eventLimit'); 14356 if (eventLimit && typeof eventLimit !== 'number') { 14357 eventLimit = TIMEGRID_ALL_DAY_EVENT_LIMIT; // make sure "auto" goes to a real number 14358 } 14359 if (eventLimit) { 14360 this.dayGrid.limitRows(eventLimit); 14361 } 14362 } 14363 if (!isAuto) { // should we force dimensions of the scroll container? 14364 scrollerHeight = this.computeScrollerHeight(viewHeight); 14365 this.scroller.setHeight(scrollerHeight); 14366 scrollbarWidths = this.scroller.getScrollbarWidths(); 14367 if (scrollbarWidths.left || scrollbarWidths.right) { // using scrollbars? 14368 // make the all-day and header rows lines up 14369 noScrollRowEls.forEach(function (rowEl) { 14370 core.compensateScroll(rowEl, scrollbarWidths); 14371 }); 14372 // the scrollbar compensation might have changed text flow, which might affect height, so recalculate 14373 // and reapply the desired height to the scroller. 14374 scrollerHeight = this.computeScrollerHeight(viewHeight); 14375 this.scroller.setHeight(scrollerHeight); 14376 } 14377 // guarantees the same scrollbar widths 14378 this.scroller.lockOverflow(scrollbarWidths); 14379 // if there's any space below the slats, show the horizontal rule. 14380 // this won't cause any new overflow, because lockOverflow already called. 14381 if (this.timeGrid.getTotalSlatHeight() < scrollerHeight) { 14382 this.timeGrid.bottomRuleEl.style.display = ''; 14383 } 14384 } 14385 }; 14386 // given a desired total height of the view, returns what the height of the scroller should be 14387 TimeGridView.prototype.computeScrollerHeight = function (viewHeight) { 14388 return viewHeight - 14389 core.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller 14390 }; 14391 /* Scroll 14392 ------------------------------------------------------------------------------------------------------------------*/ 14393 // Computes the initial pre-configured scroll state prior to allowing the user to change it 14394 TimeGridView.prototype.computeDateScroll = function (duration) { 14395 var top = this.timeGrid.computeTimeTop(duration); 14396 // zoom can give weird floating-point values. rather scroll a little bit further 14397 top = Math.ceil(top); 14398 if (top) { 14399 top++; // to overcome top border that slots beyond the first have. looks better 14400 } 14401 return { top: top }; 14402 }; 14403 TimeGridView.prototype.queryDateScroll = function () { 14404 return { top: this.scroller.getScrollTop() }; 14405 }; 14406 TimeGridView.prototype.applyDateScroll = function (scroll) { 14407 if (scroll.top !== undefined) { 14408 this.scroller.setScrollTop(scroll.top); 14409 } 14410 }; 14411 // Generates an HTML attribute string for setting the width of the axis, if it is known 14412 TimeGridView.prototype.axisStyleAttr = function () { 14413 if (this.axisWidth != null) { 14414 return 'style="width:' + this.axisWidth + 'px"'; 14415 } 14416 return ''; 14417 }; 14418 return TimeGridView; 14419 }(core.View)); 14420 TimeGridView.prototype.usesMinMaxTime = true; // indicates that minTime/maxTime affects rendering 14421 14422 var SimpleTimeGrid = /** @class */ (function (_super) { 14423 __extends(SimpleTimeGrid, _super); 14424 function SimpleTimeGrid(context, timeGrid) { 14425 var _this = _super.call(this, context, timeGrid.el) || this; 14426 _this.buildDayRanges = core.memoize(buildDayRanges); 14427 _this.slicer = new TimeGridSlicer(); 14428 _this.timeGrid = timeGrid; 14429 context.calendar.registerInteractiveComponent(_this, { 14430 el: _this.timeGrid.el 14431 }); 14432 return _this; 14433 } 14434 SimpleTimeGrid.prototype.destroy = function () { 14435 _super.prototype.destroy.call(this); 14436 this.calendar.unregisterInteractiveComponent(this); 14437 }; 14438 SimpleTimeGrid.prototype.render = function (props) { 14439 var dateProfile = props.dateProfile, dayTable = props.dayTable; 14440 var dayRanges = this.dayRanges = this.buildDayRanges(dayTable, dateProfile, this.dateEnv); 14441 this.timeGrid.receiveProps(__assign({}, this.slicer.sliceProps(props, dateProfile, null, this.timeGrid, dayRanges), { dateProfile: dateProfile, cells: dayTable.cells[0] })); 14442 }; 14443 SimpleTimeGrid.prototype.renderNowIndicator = function (date) { 14444 this.timeGrid.renderNowIndicator(this.slicer.sliceNowDate(date, this.timeGrid, this.dayRanges), date); 14445 }; 14446 SimpleTimeGrid.prototype.buildPositionCaches = function () { 14447 this.timeGrid.buildPositionCaches(); 14448 }; 14449 SimpleTimeGrid.prototype.queryHit = function (positionLeft, positionTop) { 14450 var rawHit = this.timeGrid.positionToHit(positionLeft, positionTop); 14451 if (rawHit) { 14452 return { 14453 component: this.timeGrid, 14454 dateSpan: rawHit.dateSpan, 14455 dayEl: rawHit.dayEl, 14456 rect: { 14457 left: rawHit.relativeRect.left, 14458 right: rawHit.relativeRect.right, 14459 top: rawHit.relativeRect.top, 14460 bottom: rawHit.relativeRect.bottom 14461 }, 14462 layer: 0 14463 }; 14464 } 14465 }; 14466 return SimpleTimeGrid; 14467 }(core.DateComponent)); 14468 function buildDayRanges(dayTable, dateProfile, dateEnv) { 14469 var ranges = []; 14470 for (var _i = 0, _a = dayTable.headerDates; _i < _a.length; _i++) { 14471 var date = _a[_i]; 14472 ranges.push({ 14473 start: dateEnv.add(date, dateProfile.minTime), 14474 end: dateEnv.add(date, dateProfile.maxTime) 14475 }); 14476 } 14477 return ranges; 14478 } 14479 var TimeGridSlicer = /** @class */ (function (_super) { 14480 __extends(TimeGridSlicer, _super); 14481 function TimeGridSlicer() { 14482 return _super !== null && _super.apply(this, arguments) || this; 14483 } 14484 TimeGridSlicer.prototype.sliceRange = function (range, dayRanges) { 14485 var segs = []; 14486 for (var col = 0; col < dayRanges.length; col++) { 14487 var segRange = core.intersectRanges(range, dayRanges[col]); 14488 if (segRange) { 14489 segs.push({ 14490 start: segRange.start, 14491 end: segRange.end, 14492 isStart: segRange.start.valueOf() === range.start.valueOf(), 14493 isEnd: segRange.end.valueOf() === range.end.valueOf(), 14494 col: col 14495 }); 14496 } 14497 } 14498 return segs; 14499 }; 14500 return TimeGridSlicer; 14501 }(core.Slicer)); 14502 14503 var TimeGridView$1 = /** @class */ (function (_super) { 14504 __extends(TimeGridView, _super); 14505 function TimeGridView(_context, viewSpec, dateProfileGenerator, parentEl) { 14506 var _this = _super.call(this, _context, viewSpec, dateProfileGenerator, parentEl) || this; 14507 _this.buildDayTable = core.memoize(buildDayTable); 14508 if (_this.opt('columnHeader')) { 14509 _this.header = new core.DayHeader(_this.context, _this.el.querySelector('.fc-head-container')); 14510 } 14511 _this.simpleTimeGrid = new SimpleTimeGrid(_this.context, _this.timeGrid); 14512 if (_this.dayGrid) { 14513 _this.simpleDayGrid = new daygrid.SimpleDayGrid(_this.context, _this.dayGrid); 14514 } 14515 return _this; 14516 } 14517 TimeGridView.prototype.destroy = function () { 14518 _super.prototype.destroy.call(this); 14519 if (this.header) { 14520 this.header.destroy(); 14521 } 14522 this.simpleTimeGrid.destroy(); 14523 if (this.simpleDayGrid) { 14524 this.simpleDayGrid.destroy(); 14525 } 14526 }; 14527 TimeGridView.prototype.render = function (props) { 14528 _super.prototype.render.call(this, props); // for flags for updateSize 14529 var dateProfile = this.props.dateProfile; 14530 var dayTable = this.buildDayTable(dateProfile, this.dateProfileGenerator); 14531 var splitProps = this.splitter.splitProps(props); 14532 if (this.header) { 14533 this.header.receiveProps({ 14534 dateProfile: dateProfile, 14535 dates: dayTable.headerDates, 14536 datesRepDistinctDays: true, 14537 renderIntroHtml: this.renderHeadIntroHtml 14538 }); 14539 } 14540 this.simpleTimeGrid.receiveProps(__assign({}, splitProps['timed'], { dateProfile: dateProfile, 14541 dayTable: dayTable })); 14542 if (this.simpleDayGrid) { 14543 this.simpleDayGrid.receiveProps(__assign({}, splitProps['allDay'], { dateProfile: dateProfile, 14544 dayTable: dayTable, nextDayThreshold: this.nextDayThreshold, isRigid: false })); 14545 } 14546 }; 14547 TimeGridView.prototype.renderNowIndicator = function (date) { 14548 this.simpleTimeGrid.renderNowIndicator(date); 14549 }; 14550 return TimeGridView; 14551 }(TimeGridView)); 14552 function buildDayTable(dateProfile, dateProfileGenerator) { 14553 var daySeries = new core.DaySeries(dateProfile.renderRange, dateProfileGenerator); 14554 return new core.DayTable(daySeries, false); 14555 } 14556 14557 var main = core.createPlugin({ 14558 defaultView: 'timeGridWeek', 14559 views: { 14560 timeGrid: { 14561 class: TimeGridView$1, 14562 allDaySlot: true, 14563 slotDuration: '00:30:00', 14564 slotEventOverlap: true // a bad name. confused with overlap/constraint system 14565 }, 14566 timeGridDay: { 14567 type: 'timeGrid', 14568 duration: { days: 1 } 14569 }, 14570 timeGridWeek: { 14571 type: 'timeGrid', 14572 duration: { weeks: 1 } 14573 } 14574 } 14575 }); 14576 14577 exports.AbstractTimeGridView = TimeGridView; 14578 exports.TimeGrid = TimeGrid; 14579 exports.TimeGridSlicer = TimeGridSlicer; 14580 exports.TimeGridView = TimeGridView$1; 14581 exports.buildDayRanges = buildDayRanges; 14582 exports.buildDayTable = buildDayTable; 14583 exports.default = main; 14584 14585 Object.defineProperty(exports, '__esModule', { value: true }); 14586 14587})); 14588 14589}
14589,{"@fullcalendar/core":2,"@fullcalendar/daygrid":3}],9:[function(require,module,exports){
vendor: 14,690 bytes, line 14590
14590!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.AOS=t():e.AOS=t()}(this,function(){return function(e){function t(o){if(n[o])return n[o].exports;var i=n[o]={exports:{},id:o,loaded:!1};return e[o].call(i.exports,i,i.exports,t),i.loaded=!0,i.exports}var n={};return t.m=e,t.c=n,t.p="dist/",t(0)}([function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}var i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o])}return e},r=n(1),a=(o(r),n(6)),u=o(a),c=n(7),s=o(c),f=n(8),d=o(f),l=n(9),p=o(l),m=n(10),b=o(m),v=n(11),y=o(v),g=n(14),h=o(g),w=[],k=!1,x={offset:120,delay:0,easing:"ease",duration:400,disable:!1,once:!1,startEvent:"DOMContentLoaded",throttleDelay:99,debounceDelay:50,disableMutationObserver:!1},j=function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];if(e&&(k=!0),k)return w=(0,y.default)(w,x),(0,b.default)(w,x.once),w},O=function(){w=(0,h.default)(),j()},M=function(){w.forEach(function(e,t){e.node.removeAttribute("data-aos"),e.node.removeAttribute("data-aos-easing"),e.node.removeAttribute("data-aos-duration"),e.node.removeAttribute("data-aos-delay")})},S=function(e){return e===!0||"mobile"===e&&p.default.mobile()||"phone"===e&&p.default.phone()||"tablet"===e&&p.default.tablet()||"function"==typeof e&&e()===!0},_=function(e){x=i(x,e),w=(0,h.default)();var t=document.all&&!window.atob;return S(x.disable)||t?M():(x.disableMutationObserver||d.default.isSupported()||(console.info('\n aos: MutationObserver is not supported on this browser,\n code mutations observing has been disabled.\n You may have to call "refreshHard()" by yourself.\n '),x.disableMutationObserver=!0),document.querySelector("body").setAttribute("data-aos-easing",x.easing),document.querySelector("body").setAttribute("data-aos-duration",x.duration),document.querySelector("body").setAttribute("data-aos-delay",x.delay),"DOMContentLoaded"===x.startEvent&&["complete","interactive"].indexOf(document.readyState)>-1?j(!0):"load"===x.startEvent?window.addEventListener(x.startEvent,function(){j(!0)}):document.addEventListener(x.startEvent,function(){j(!0)}),window.addEventListener("resize",(0,s.default)(j,x.debounceDelay,!0)),window.addEventListener("orientationchange",(0,s.default)(j,x.debounceDelay,!0)),window.addEventListener("scroll",(0,u.default)(function(){(0,b.default)(w,x.once)},x.throttleDelay)),x.disableMutationObserver||d.default.ready("[data-aos]",O),w)};e.exports={init:_,refresh:j,refreshHard:O}},function(e,t){},,,,,function(e,t){(function(t){"use strict";function n(e,t,n){function o(t){var n=b,o=v;return b=v=void 0,k=t,g=e.apply(o,n)}function r(e){return k=e,h=setTimeout(f,t),M?o(e):g}function a(e){var n=e-w,o=e-k,i=t-n;return S?j(i,y-o):i}function c(e){var n=e-w,o=e-k;return void 0===w||n>=t||n<0||S&&o>=y}function f(){var e=O();return c(e)?d(e):void(h=setTimeout(f,a(e)))}function d(e){return h=void 0,_&&b?o(e):(b=v=void 0,g)}function l(){void 0!==h&&clearTimeout(h),k=0,b=w=v=h=void 0}function p(){return void 0===h?g:d(O())}function m(){var e=O(),n=c(e);if(b=arguments,v=this,w=e,n){if(void 0===h)return r(w);if(S)return h=setTimeout(f,t),o(w)}return void 0===h&&(h=setTimeout(f,t)),g}var b,v,y,g,h,w,k=0,M=!1,S=!1,_=!0;if("function"!=typeof e)throw new TypeError(s);return t=u(t)||0,i(n)&&(M=!!n.leading,S="maxWait"in n,y=S?x(u(n.maxWait)||0,t):y,_="trailing"in n?!!n.trailing:_),m.cancel=l,m.flush=p,m}function o(e,t,o){var r=!0,a=!0;if("function"!=typeof e)throw new TypeError(s);return i(o)&&(r="leading"in o?!!o.leading:r,a="trailing"in o?!!o.trailing:a),n(e,t,{leading:r,maxWait:t,trailing:a})}function i(e){var t="undefined"==typeof e?"undefined":c(e);return!!e&&("object"==t||"function"==t)}function r(e){return!!e&&"object"==("undefined"==typeof e?"undefined":c(e))}function a(e){return"symbol"==("undefined"==typeof e?"undefined":c(e))||r(e)&&k.call(e)==d}function u(e){if("number"==typeof e)return e;if(a(e))return f;if(i(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=i(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(l,"");var n=m.test(e);return n||b.test(e)?v(e.slice(2),n?2:8):p.test(e)?f:+e}var c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},s="Expected a function",f=NaN,d="[object Symbol]",l=/^\s+|\s+$/g,p=/^[-+]0x[0-9a-f]+$/i,m=/^0b[01]+$/i,b=/^0o[0-7]+$/i,v=parseInt,y="object"==("undefined"==typeof t?"undefined":c(t))&&t&&t.Object===Object&&t,g="object"==("undefined"==typeof self?"undefined":c(self))&&self&&self.Object===Object&&self,h=y||g||Function("return this")(),w=Object.prototype,k=w.toString,x=Math.max,j=Math.min,O=function(){return h.Date.now()};e.exports=o}).call(t,function(){return this}())},function(e,t){(function(t){"use strict";function n(e,t,n){function i(t){var n=b,o=v;return b=v=void 0,O=t,g=e.apply(o,n)}function r(e){return O=e,h=setTimeout(f,t),M?i(e):g}function u(e){var n=e-w,o=e-O,i=t-n;return S?x(i,y-o):i}function s(e){var n=e-w,o=e-O;return void 0===w||n>=t||n<0||S&&o>=y}function f(){var e=j();return s(e)?d(e):void(h=setTimeout(f,u(e)))}function d(e){return h=void 0,_&&b?i(e):(b=v=void 0,g)}function l(){void 0!==h&&clearTimeout(h),O=0,b=w=v=h=void 0}function p(){return void 0===h?g:d(j())}function m(){var e=j(),n=s(e);if(b=arguments,v=this,w=e,n){if(void 0===h)return r(w);if(S)return h=setTimeout(f,t),i(w)}return void 0===h&&(h=setTimeout(f,t)),g}var b,v,y,g,h,w,O=0,M=!1,S=!1,_=!0;if("function"!=typeof e)throw new TypeError(c);return t=a(t)||0,o(n)&&(M=!!n.leading,S="maxWait"in n,y=S?k(a(n.maxWait)||0,t):y,_="trailing"in n?!!n.trailing:_),m.cancel=l,m.flush=p,m}function o(e){var t="undefined"==typeof e?"undefined":u(e);return!!e&&("object"==t||"function"==t)}function i(e){return!!e&&"object"==("undefined"==typeof e?"undefined":u(e))}function r(e){return"symbol"==("undefined"==typeof e?"undefined":u(e))||i(e)&&w.call(e)==f}function a(e){if("number"==typeof e)return e;if(r(e))return s;if(o(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=o(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(d,"");var n=p.test(e);return n||m.test(e)?b(e.slice(2),n?2:8):l.test(e)?s:+e}var u="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},c="Expected a function",s=NaN,f="[object Symbol]",d=/^\s+|\s+$/g,l=/^[-+]0x[0-9a-f]+$/i,p=/^0b[01]+$/i,m=/^0o[0-7]+$/i,b=parseInt,v="object"==("undefined"==typeof t?"undefined":u(t))&&t&&t.Object===Object&&t,y="object"==("undefined"==typeof self?"undefined":u(self))&&self&&self.Object===Object&&self,g=v||y||Function("return this")(),h=Object.prototype,w=h.toString,k=Math.max,x=Math.min,j=function(){return g.Date.now()};e.exports=n}).call(t,function(){return this}())},function(e,t){"use strict";function n(e){var t=void 0,o=void 0,i=void 0;for(t=0;t<e.length;t+=1){if(o=e[t],o.dataset&&o.dataset.aos)return!0;if(i=o.children&&n(o.children))return!0}return!1}function o(){return window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver}function i(){return!!o()}function r(e,t){var n=window.document,i=o(),r=new i(a);u=t,r.observe(n.documentElement,{childList:!0,subtree:!0,removedNodes:!0})}function a(e){e&&e.forEach(function(e){var t=Array.prototype.slice.call(e.addedNodes),o=Array.prototype.slice.call(e.removedNodes),i=t.concat(o);if(n(i))return u()})}Object.defineProperty(t,"__esModule",{value:!0});var u=function(){};t.default={isSupported:i,ready:r}},function(e,t){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(){return navigator.userAgent||navigator.vendor||window.opera||""}Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function e(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,n,o){return n&&e(t.prototype,n),o&&e(t,o),t}}(),r=/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i,a=/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i,u=/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i,c=/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i,s=function(){function e(){n(this,e)}return i(e,[{key:"phone",value:function(){var e=o();return!(!r.test(e)&&!a.test(e.substr(0,4)))}},{key:"mobile",value:function(){var e=o();return!(!u.test(e)&&!c.test(e.substr(0,4)))}},{key:"tablet",value:function(){return this.mobile()&&!this.phone()}}]),e}();t.default=new s},function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(e,t,n){var o=e.node.getAttribute("data-aos-once");t>e.position?e.node.classList.add("aos-animate"):"undefined"!=typeof o&&("false"===o||!n&&"true"!==o)&&e.node.classList.remove("aos-animate")},o=function(e,t){var o=window.pageYOffset,i=window.innerHeight;e.forEach(function(e,r){n(e,i+o,t)})};t.default=o},function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(12),r=o(i),a=function(e,t){return e.forEach(function(e,n){e.node.classList.add("aos-init"),e.position=(0,r.default)(e.node,t.offset)}),e};t.default=a},function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(13),r=o(i),a=function(e,t){var n=0,o=0,i=window.innerHeight,a={offset:e.getAttribute("data-aos-offset"),anchor:e.getAttribute("data-aos-anchor"),anchorPlacement:e.getAttribute("data-aos-anchor-placement")};switch(a.offset&&!isNaN(a.offset)&&(o=parseInt(a.offset)),a.anchor&&document.querySelectorAll(a.anchor)&&(e=document.querySelectorAll(a.anchor)[0]),n=(0,r.default)(e).top,a.anchorPlacement){case"top-bottom":break;case"center-bottom":n+=e.offsetHeight/2;break;case"bottom-bottom":n+=e.offsetHeight;break;case"top-center":n+=i/2;break;case"bottom-center":n+=i/2+e.offsetHeight;break;case"center-center":n+=i/2+e.offsetHeight/2;break;case"top-top":n+=i;break;case"bottom-top":n+=e.offsetHeight+i;break;case"center-top":n+=e.offsetHeight/2+i}return a.anchorPlacement||a.offset||isNaN(t)||(o=t),n+o};t.default=a},function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(e){for(var t=0,n=0;e&&!isNaN(e.offsetLeft)&&!isNaN(e.offsetTop);)t+=e.offsetLeft-("BODY"!=e.tagName?e.scrollLeft:0),n+=e.offsetTop-("BODY"!=e.tagName?e.scrollTop:0),e=e.offsetParent;return{top:n,left:t}};t.default=n},function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(e){return e=e||document.querySelectorAll("[data-aos]"),Array.prototype.map.call(e,function(e){return{node:e}})};t.default=n}])});
vendor: 13,029 bytes, lines 14590-14916
14590 14591},{}],10:[function(require,module,exports){ 14592/*! 14593 hey, [be]Lazy.js - v1.8.2 - 2016.10.25 14594 A fast, small and dependency free lazy load script (https://github.com/dinbror/blazy) 14595 (c) Bjoern Klinggaard - @bklinggaard - http://dinbror.dk/blazy 14596*/ 14597; 14598(function(root, blazy) { 14599 if (typeof define === 'function' && define.amd) { 14600 // AMD. Register bLazy as an anonymous module 14601 define(blazy); 14602 } else if (typeof exports === 'object') { 14603 // Node. Does not work with strict CommonJS, but 14604 // only CommonJS-like environments that support module.exports, 14605 // like Node. 14606 module.exports = blazy(); 14607 } else { 14608 // Browser globals. Register bLazy on window 14609 root.Blazy = blazy(); 14610 } 14611})(this, function() { 14612 'use strict'; 14613 14614 //private vars 14615 var _source, _viewport, _isRetina, _supportClosest, _attrSrc = 'src', _attrSrcset = 'srcset'; 14616 14617 // constructor 14618 return function Blazy(options) { 14619 //IE7- fallback for missing querySelectorAll support 14620 if (!document.querySelectorAll) { 14621 var s = document.createStyleSheet(); 14622 document.querySelectorAll = function(r, c, i, j, a) { 14623 a = document.all, c = [], r = r.replace(/\[for\b/gi, '[htmlFor').split(','); 14624 for (i = r.length; i--;) { 14625 s.addRule(r[i], 'k:v'); 14626 for (j = a.length; j--;) a[j].currentStyle.k && c.push(a[j]); 14627 s.removeRule(0); 14628 } 14629 return c; 14630 }; 14631 } 14632 14633 //options and helper vars 14634 var scope = this; 14635 var util = scope._util = {}; 14636 util.elements = []; 14637 util.destroyed = true; 14638 scope.options = options || {}; 14639 scope.options.error = scope.options.error || false; 14640 scope.options.offset = scope.options.offset || 100; 14641 scope.options.root = scope.options.root || document; 14642 scope.options.success = scope.options.success || false; 14643 scope.options.selector = scope.options.selector || '.b-lazy'; 14644 scope.options.separator = scope.options.separator || '|'; 14645 scope.options.containerClass = scope.options.container; 14646 scope.options.container = scope.options.containerClass ? document.querySelectorAll(scope.options.containerClass) : false; 14647 scope.options.errorClass = scope.options.errorClass || 'b-error'; 14648 scope.options.breakpoints = scope.options.breakpoints || false; 14649 scope.options.loadInvisible = scope.options.loadInvisible || false; 14650 scope.options.successClass = scope.options.successClass || 'b-loaded'; 14651 scope.options.validateDelay = scope.options.validateDelay || 25; 14652 scope.options.saveViewportOffsetDelay = scope.options.saveViewportOffsetDelay || 50; 14653 scope.options.srcset = scope.options.srcset || 'data-srcset'; 14654 scope.options.src = _source = scope.options.src || 'data-src'; 14655 _supportClosest = Element.prototype.closest; 14656 _isRetina = window.devicePixelRatio > 1; 14657 _viewport = {}; 14658 _viewport.top = 0 - scope.options.offset; 14659 _viewport.left = 0 - scope.options.offset; 14660 14661 14662 /* public functions 14663 ************************************/ 14664 scope.revalidate = function() { 14665 initialize(scope); 14666 }; 14667 scope.load = function(elements, force) { 14668 var opt = this.options; 14669 if (elements && elements.length === undefined) { 14670 loadElement(elements, force, opt); 14671 } else { 14672 each(elements, function(element) { 14673 loadElement(element, force, opt); 14674 }); 14675 } 14676 }; 14677 scope.destroy = function() { 14678 var util = scope._util; 14679 if (scope.options.container) { 14680 each(scope.options.container, function(object) { 14681 unbindEvent(object, 'scroll', util.validateT); 14682 }); 14683 } 14684 unbindEvent(window, 'scroll', util.validateT); 14685 unbindEvent(window, 'resize', util.validateT); 14686 unbindEvent(window, 'resize', util.saveViewportOffsetT); 14687 util.count = 0; 14688 util.elements.length = 0; 14689 util.destroyed = true; 14690 }; 14691 14692 //throttle, ensures that we don't call the functions too often 14693 util.validateT = throttle(function() { 14694 validate(scope); 14695 }, scope.options.validateDelay, scope); 14696 util.saveViewportOffsetT = throttle(function() { 14697 saveViewportOffset(scope.options.offset); 14698 }, scope.options.saveViewportOffsetDelay, scope); 14699 saveViewportOffset(scope.options.offset); 14700 14701 //handle multi-served image src (obsolete) 14702 each(scope.options.breakpoints, function(object) { 14703 if (object.width >= window.screen.width) { 14704 _source = object.src; 14705 return false; 14706 } 14707 }); 14708 14709 // start lazy load 14710 setTimeout(function() { 14711 initialize(scope); 14712 }); // "dom ready" fix 14713 14714 }; 14715 14716 14717 /* Private helper functions 14718 ************************************/ 14719 function initialize(self) { 14720 var util = self._util; 14721 // First we create an array of elements to lazy load 14722 util.elements = toArray(self.options); 14723 util.count = util.elements.length; 14724 // Then we bind resize and scroll events if not already binded 14725 if (util.destroyed) { 14726 util.destroyed = false; 14727 if (self.options.container) { 14728 each(self.options.container, function(object) { 14729 bindEvent(object, 'scroll', util.validateT); 14730 }); 14731 } 14732 bindEvent(window, 'resize', util.saveViewportOffsetT); 14733 bindEvent(window, 'resize', util.validateT); 14734 bindEvent(window, 'scroll', util.validateT); 14735 } 14736 // And finally, we start to lazy load. 14737 validate(self); 14738 } 14739 14740 function validate(self) { 14741 var util = self._util; 14742 for (var i = 0; i < util.count; i++) { 14743 var element = util.elements[i]; 14744 if (elementInView(element, self.options) || hasClass(element, self.options.successClass)) { 14745 self.load(element); 14746 util.elements.splice(i, 1); 14747 util.count--; 14748 i--; 14749 } 14750 } 14751 if (util.count === 0) { 14752 self.destroy(); 14753 } 14754 } 14755 14756 function elementInView(ele, options) { 14757 var rect = ele.getBoundingClientRect(); 14758 14759 if(options.container && _supportClosest){ 14760 // Is element inside a container? 14761 var elementContainer = ele.closest(options.containerClass); 14762 if(elementContainer){ 14763 var containerRect = elementContainer.getBoundingClientRect(); 14764 // Is container in view? 14765 if(inView(containerRect, _viewport)){ 14766 var top = containerRect.top - options.offset; 14767 var right = containerRect.right + options.offset; 14768 var bottom = containerRect.bottom + options.offset; 14769 var left = containerRect.left - options.offset; 14770 var containerRectWithOffset = { 14771 top: top > _viewport.top ? top : _viewport.top, 14772 right: right < _viewport.right ? right : _viewport.right, 14773 bottom: bottom < _viewport.bottom ? bottom : _viewport.bottom, 14774 left: left > _viewport.left ? left : _viewport.left 14775 }; 14776 // Is element in view of container? 14777 return inView(rect, containerRectWithOffset); 14778 } else { 14779 return false; 14780 } 14781 } 14782 } 14783 return inView(rect, _viewport); 14784 } 14785 14786 function inView(rect, viewport){ 14787 // Intersection 14788 return rect.right >= viewport.left && 14789 rect.bottom >= viewport.top && 14790 rect.left <= viewport.right && 14791 rect.top <= viewport.bottom; 14792 } 14793 14794 function loadElement(ele, force, options) { 14795 // if element is visible, not loaded or forced 14796 if (!hasClass(ele, options.successClass) && (force || options.loadInvisible || (ele.offsetWidth > 0 && ele.offsetHeight > 0))) { 14797 var dataSrc = getAttr(ele, _source) || getAttr(ele, options.src); // fallback to default 'data-src' 14798 if (dataSrc) { 14799 var dataSrcSplitted = dataSrc.split(options.separator); 14800 var src = dataSrcSplitted[_isRetina && dataSrcSplitted.length > 1 ? 1 : 0]; 14801 var srcset = getAttr(ele, options.srcset); 14802 var isImage = equal(ele, 'img'); 14803 var parent = ele.parentNode; 14804 var isPicture = parent && equal(parent, 'picture'); 14805 // Image or background image 14806 if (isImage || ele.src === undefined) { 14807 var img = new Image(); 14808 // using EventListener instead of onerror and onload 14809 // due to bug introduced in chrome v50 14810 // (https://productforums.google.com/forum/#!topic/chrome/p51Lk7vnP2o) 14811 var onErrorHandler = function() { 14812 if (options.error) options.error(ele, "invalid"); 14813 addClass(ele, options.errorClass); 14814 unbindEvent(img, 'error', onErrorHandler); 14815 unbindEvent(img, 'load', onLoadHandler); 14816 }; 14817 var onLoadHandler = function() { 14818 // Is element an image 14819 if (isImage) { 14820 if(!isPicture) { 14821 handleSources(ele, src, srcset); 14822 } 14823 // or background-image 14824 } else { 14825 ele.style.backgroundImage = 'url("' + src + '")'; 14826 } 14827 itemLoaded(ele, options); 14828 unbindEvent(img, 'load', onLoadHandler); 14829 unbindEvent(img, 'error', onErrorHandler); 14830 }; 14831 14832 // Picture element 14833 if (isPicture) { 14834 img = ele; // Image tag inside picture element wont get preloaded 14835 each(parent.getElementsByTagName('source'), function(source) { 14836 handleSource(source, _attrSrcset, options.srcset); 14837 }); 14838 } 14839 bindEvent(img, 'error', onErrorHandler); 14840 bindEvent(img, 'load', onLoadHandler); 14841 handleSources(img, src, srcset); // Preload 14842 14843 } else { // An item with src like iframe, unity games, simpel video etc 14844 ele.src = src; 14845 itemLoaded(ele, options); 14846 } 14847 } else { 14848 // video with child source 14849 if (equal(ele, 'video')) { 14850 each(ele.getElementsByTagName('source'), function(source) { 14851 handleSource(source, _attrSrc, options.src); 14852 }); 14853 ele.load(); 14854 itemLoaded(ele, options); 14855 } else { 14856 if (options.error) options.error(ele, "missing"); 14857 addClass(ele, options.errorClass); 14858 } 14859 } 14860 } 14861 } 14862 14863 function itemLoaded(ele, options) { 14864 addClass(ele, options.successClass); 14865 if (options.success) options.success(ele); 14866 // cleanup markup, remove data source attributes 14867 removeAttr(ele, options.src); 14868 removeAttr(ele, options.srcset); 14869 each(options.breakpoints, function(object) { 14870 removeAttr(ele, object.src); 14871 }); 14872 } 14873 14874 function handleSource(ele, attr, dataAttr) { 14875 var dataSrc = getAttr(ele, dataAttr); 14876 if (dataSrc) { 14877 setAttr(ele, attr, dataSrc); 14878 removeAttr(ele, dataAttr); 14879 } 14880 } 14881 14882 function handleSources(ele, src, srcset){ 14883 if(srcset) { 14884 setAttr(ele, _attrSrcset, srcset); //srcset 14885 } 14886 ele.src = src; //src 14887 } 14888 14889 function setAttr(ele, attr, value){ 14890 ele.setAttribute(attr, value); 14891 } 14892 14893 function getAttr(ele, attr) { 14894 return ele.getAttribute(attr); 14895 } 14896 14897 function removeAttr(ele, attr){ 14898 ele.removeAttribute(attr); 14899 } 14900 14901 function equal(ele, str) { 14902 return ele.nodeName.toLowerCase() === str; 14903 } 14904 14905 function hasClass(ele, className) { 14906 return (' ' + ele.className + ' ').indexOf(' ' + className + ' ') !== -1; 14907 } 14908 14909 function addClass(ele, className) { 14910 if (!hasClass(ele, className)) { 14911 ele.className += ' ' + className; 14912 } 14913 } 14914 14915 function toArray(options) { 14916 var array = [];
14917 var nodelist = (options.root).querySelectorAll(options.selector); 14918 for (var i = nodelist.length; i--; array.unshift(nodelist[i])) {} 14919 return array; 14920 } 14921 14922 function saveViewportOffset(offset) { 14923 _viewport.bottom = (window.innerHeight || document.documentElement.clientHeight) + offset; 14924 _viewport.right = (window.innerWidth || document.documentElement.clientWidth) + offset; 14925 } 14926 14927 function bindEvent(ele, type, fn) { 14928 if (ele.attachEvent) { 14929 ele.attachEvent && ele.attachEvent('on' + type, fn); 14930 } else { 14931 ele.addEventListener(type, fn, { capture: false, passive: true }); 14932 } 14933 } 14934 14935 function unbindEvent(ele, type, fn) { 14936 if (ele.detachEvent) { 14937 ele.detachEvent && ele.detachEvent('on' + type, fn); 14938 } else { 14939 ele.removeEventListener(type, fn, { capture: false, passive: true }); 14940 } 14941 } 14942 14943 function each(object, fn) { 14944 if (object && fn) { 14945 var l = object.length; 14946 for (var i = 0; i < l && fn(object[i], i) !== false; i++) {} 14947 } 14948 } 14949 14950 function throttle(fn, minDelay, scope) { 14951 var lastCall = 0; 14952 return function() { 14953 var now = +new Date(); 14954 if (now - lastCall < minDelay) { 14955 return; 14956 } 14957 lastCall = now; 14958 fn.apply(scope, arguments); 14959 }; 14960 } 14961}); 14962 14963},{}],11:[function(require,module,exports){ 14964/*! 14965 * Bootstrap v4.3.1 (https://getbootstrap.com/) 14966 * Copyright 2011-2019 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) 14967 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 14968 */ 14969(function (global, factory) { 14970 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('jquery'), require('popper.js')) : 14971 typeof define === 'function' && define.amd ? define(['exports', 'jquery', 'popper.js'], factory) : 14972 (global = global || self, factory(global.bootstrap = {}, global.jQuery, global.Popper)); 14973}(this, function (exports, $, Popper) { 'use strict'; 14974 14975 $ = $ && $.hasOwnProperty('default') ? $['default'] : $; 14976 Popper = Popper && Popper.hasOwnProperty('default') ? Popper['default'] : Popper; 14977 14978 function _defineProperties(target, props) { 14979 for (var i = 0; i < props.length; i++) { 14980 var descriptor = props[i]; 14981 descriptor.enumerable = descriptor.enumerable || false; 14982 descriptor.configurable = true; 14983 if ("value" in descriptor) descriptor.writable = true; 14984 Object.defineProperty(target, descriptor.key, descriptor); 14985 } 14986 } 14987 14988 function _createClass(Constructor, protoProps, staticProps) { 14989 if (protoProps) _defineProperties(Constructor.prototype, protoProps); 14990 if (staticProps) _defineProperties(Constructor, staticProps); 14991 return Constructor; 14992 } 14993 14994 function _defineProperty(obj, key, value) { 14995 if (key in obj) { 14996 Object.defineProperty(obj, key, { 14997 value: value, 14998 enumerable: true, 14999 configurable: true, 15000 writable: true 15001 }); 15002 } else { 15003 obj[key] = value; 15004 } 15005 15006 return obj; 15007 } 15008 15009 function _objectSpread(target) { 15010 for (var i = 1; i < arguments.length; i++) { 15011 var source = arguments[i] != null ? arguments[i] : {}; 15012 var ownKeys = Object.keys(source); 15013 15014 if (typeof Object.getOwnPropertySymbols === 'function') { 15015 ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { 15016 return Object.getOwnPropertyDescriptor(source, sym).enumerable; 15017 })); 15018 } 15019 15020 ownKeys.forEach(function (key) { 15021 _defineProperty(target, key, source[key]); 15022 }); 15023 } 15024 15025 return target; 15026 } 15027 15028 function _inheritsLoose(subClass, superClass) { 15029 subClass.prototype = Object.create(superClass.prototype); 15030 subClass.prototype.constructor = subClass; 15031 subClass.__proto__ = superClass; 15032 } 15033 15034 /** 15035 * -------------------------------------------------------------------------- 15036 * Bootstrap (v4.3.1): util.js 15037 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 15038 * -------------------------------------------------------------------------- 15039 */ 15040 /** 15041 * ------------------------------------------------------------------------ 15042 * Private TransitionEnd Helpers 15043 * ------------------------------------------------------------------------ 15044 */ 15045 15046 var TRANSITION_END = 'transitionend'; 15047 var MAX_UID = 1000000; 15048 var MILLISECONDS_MULTIPLIER = 1000; // Shoutout AngusCroll (https://goo.gl/pxwQGp) 15049 15050 function toType(obj) { 15051 return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase(); 15052 } 15053 15054 function getSpecialTransitionEndEvent() { 15055 return { 15056 bindType: TRANSITION_END, 15057 delegateType: TRANSITION_END, 15058 handle: function handle(event) { 15059 if ($(event.target).is(this)) { 15060 return event.handleObj.handler.apply(this, arguments); // eslint-disable-line prefer-rest-params 15061 } 15062 15063 return undefined; // eslint-disable-line no-undefined 15064 } 15065 }; 15066 } 15067 15068 function transitionEndEmulator(duration) { 15069 var _this = this; 15070 15071 var called = false;
vendor: 5,614 bytes, lines 15072-15256
15072 $(this).one(Util.TRANSITION_END, function () { 15073 called = true; 15074 }); 15075 setTimeout(function () { 15076 if (!called) { 15077 Util.triggerTransitionEnd(_this); 15078 } 15079 }, duration); 15080 return this; 15081 } 15082 15083 function setTransitionEndSupport() { 15084 $.fn.emulateTransitionEnd = transitionEndEmulator; 15085 $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent(); 15086 } 15087 /** 15088 * -------------------------------------------------------------------------- 15089 * Public Util Api 15090 * -------------------------------------------------------------------------- 15091 */ 15092 15093 15094 var Util = { 15095 TRANSITION_END: 'bsTransitionEnd', 15096 getUID: function getUID(prefix) { 15097 do { 15098 // eslint-disable-next-line no-bitwise 15099 prefix += ~~(Math.random() * MAX_UID); // "~~" acts like a faster Math.floor() here 15100 } while (document.getElementById(prefix)); 15101 15102 return prefix; 15103 }, 15104 getSelectorFromElement: function getSelectorFromElement(element) { 15105 var selector = element.getAttribute('data-target'); 15106 15107 if (!selector || selector === '#') { 15108 var hrefAttr = element.getAttribute('href'); 15109 selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : ''; 15110 } 15111 15112 try { 15113 return document.querySelector(selector) ? selector : null; 15114 } catch (err) { 15115 return null; 15116 } 15117 }, 15118 getTransitionDurationFromElement: function getTransitionDurationFromElement(element) { 15119 if (!element) { 15120 return 0; 15121 } // Get transition-duration of the element 15122 15123 15124 var transitionDuration = $(element).css('transition-duration'); 15125 var transitionDelay = $(element).css('transition-delay'); 15126 var floatTransitionDuration = parseFloat(transitionDuration); 15127 var floatTransitionDelay = parseFloat(transitionDelay); // Return 0 if element or transition duration is not found 15128 15129 if (!floatTransitionDuration && !floatTransitionDelay) { 15130 return 0; 15131 } // If multiple durations are defined, take the first 15132 15133 15134 transitionDuration = transitionDuration.split(',')[0]; 15135 transitionDelay = transitionDelay.split(',')[0]; 15136 return (parseFloat(transitionDuration) + parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER; 15137 }, 15138 reflow: function reflow(element) { 15139 return element.offsetHeight; 15140 }, 15141 triggerTransitionEnd: function triggerTransitionEnd(element) { 15142 $(element).trigger(TRANSITION_END); 15143 }, 15144 // TODO: Remove in v5 15145 supportsTransitionEnd: function supportsTransitionEnd() { 15146 return Boolean(TRANSITION_END); 15147 }, 15148 isElement: function isElement(obj) { 15149 return (obj[0] || obj).nodeType; 15150 }, 15151 typeCheckConfig: function typeCheckConfig(componentName, config, configTypes) { 15152 for (var property in configTypes) { 15153 if (Object.prototype.hasOwnProperty.call(configTypes, property)) { 15154 var expectedTypes = configTypes[property]; 15155 var value = config[property]; 15156 var valueType = value && Util.isElement(value) ? 'element' : toType(value); 15157 15158 if (!new RegExp(expectedTypes).test(valueType)) { 15159 throw new Error(componentName.toUpperCase() + ": " + ("Option \"" + property + "\" provided type \"" + valueType + "\" ") + ("but expected type \"" + expectedTypes + "\".")); 15160 } 15161 } 15162 } 15163 }, 15164 findShadowRoot: function findShadowRoot(element) { 15165 if (!document.documentElement.attachShadow) { 15166 return null; 15167 } // Can find the shadow root otherwise it'll return the document 15168 15169 15170 if (typeof element.getRootNode === 'function') { 15171 var root = element.getRootNode(); 15172 return root instanceof ShadowRoot ? root : null; 15173 } 15174 15175 if (element instanceof ShadowRoot) { 15176 return element; 15177 } // when we don't find a shadow root 15178 15179 15180 if (!element.parentNode) { 15181 return null; 15182 } 15183 15184 return Util.findShadowRoot(element.parentNode); 15185 } 15186 }; 15187 setTransitionEndSupport(); 15188 15189 /** 15190 * ------------------------------------------------------------------------ 15191 * Constants 15192 * ------------------------------------------------------------------------ 15193 */ 15194 15195 var NAME = 'alert'; 15196 var VERSION = '4.3.1'; 15197 var DATA_KEY = 'bs.alert'; 15198 var EVENT_KEY = "." + DATA_KEY; 15199 var DATA_API_KEY = '.data-api'; 15200 var JQUERY_NO_CONFLICT = $.fn[NAME]; 15201 var Selector = { 15202 DISMISS: '[data-dismiss="alert"]' 15203 }; 15204 var Event = { 15205 CLOSE: "close" + EVENT_KEY, 15206 CLOSED: "closed" + EVENT_KEY, 15207 CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY 15208 }; 15209 var ClassName = { 15210 ALERT: 'alert', 15211 FADE: 'fade', 15212 SHOW: 'show' 15213 /** 15214 * ------------------------------------------------------------------------ 15215 * Class Definition 15216 * ------------------------------------------------------------------------ 15217 */ 15218 15219 }; 15220 15221 var Alert = 15222 /*#__PURE__*/ 15223 function () { 15224 function Alert(element) { 15225 this._element = element; 15226 } // Getters 15227 15228 15229 var _proto = Alert.prototype; 15230 15231 // Public 15232 _proto.close = function close(element) { 15233 var rootElement = this._element; 15234 15235 if (element) { 15236 rootElement = this._getRootElement(element); 15237 } 15238 15239 var customEvent = this._triggerCloseEvent(rootElement); 15240 15241 if (customEvent.isDefaultPrevented()) { 15242 return; 15243 } 15244 15245 this._removeElement(rootElement); 15246 }; 15247 15248 _proto.dispose = function dispose() { 15249 $.removeData(this._element, DATA_KEY); 15250 this._element = null; 15251 } // Private 15252 ; 15253 15254 _proto._getRootElement = function _getRootElement(element) { 15255 var selector = Util.getSelectorFromElement(element); 15256 var parent = false;
15257 15258 if (selector) { 15259 parent = document.querySelector(selector); 15260 } 15261 15262 if (!parent) { 15263 parent = $(element).closest("." + ClassName.ALERT)[0]; 15264 } 15265 15266 return parent; 15267 }; 15268 15269 _proto._triggerCloseEvent = function _triggerCloseEvent(element) { 15270 var closeEvent = $.Event(Event.CLOSE); 15271 $(element).trigger(closeEvent); 15272 return closeEvent; 15273 }; 15274 15275 _proto._removeElement = function _removeElement(element) { 15276 var _this = this; 15277 15278 $(element).removeClass(ClassName.SHOW); 15279 15280 if (!$(element).hasClass(ClassName.FADE)) { 15281 this._destroyElement(element); 15282 15283 return; 15284 } 15285 15286 var transitionDuration = Util.getTransitionDurationFromElement(element); 15287 $(element).one(Util.TRANSITION_END, function (event) { 15288 return _this._destroyElement(element, event); 15289 }).emulateTransitionEnd(transitionDuration); 15290 }; 15291 15292 _proto._destroyElement = function _destroyElement(element) { 15293 $(element).detach().trigger(Event.CLOSED).remove(); 15294 } // Static 15295 ; 15296 15297 Alert._jQueryInterface = function _jQueryInterface(config) { 15298 return this.each(function () { 15299 var $element = $(this); 15300 var data = $element.data(DATA_KEY); 15301 15302 if (!data) { 15303 data = new Alert(this); 15304 $element.data(DATA_KEY, data); 15305 } 15306 15307 if (config === 'close') { 15308 data[config](this); 15309 } 15310 }); 15311 }; 15312 15313 Alert._handleDismiss = function _handleDismiss(alertInstance) { 15314 return function (event) { 15315 if (event) { 15316 event.preventDefault(); 15317 } 15318 15319 alertInstance.close(this); 15320 }; 15321 }; 15322 15323 _createClass(Alert, null, [{ 15324 key: "VERSION", 15325 get: function get() { 15326 return VERSION; 15327 } 15328 }]); 15329 15330 return Alert; 15331 }(); 15332 /** 15333 * ------------------------------------------------------------------------ 15334 * Data Api implementation 15335 * ------------------------------------------------------------------------ 15336 */ 15337 15338 15339 $(document).on(Event.CLICK_DATA_API, Selector.DISMISS, Alert._handleDismiss(new Alert())); 15340 /** 15341 * ------------------------------------------------------------------------ 15342 * jQuery 15343 * ------------------------------------------------------------------------ 15344 */ 15345 15346 $.fn[NAME] = Alert._jQueryInterface; 15347 $.fn[NAME].Constructor = Alert; 15348 15349 $.fn[NAME].noConflict = function () { 15350 $.fn[NAME] = JQUERY_NO_CONFLICT; 15351 return Alert._jQueryInterface; 15352 }; 15353 15354 /** 15355 * ------------------------------------------------------------------------ 15356 * Constants 15357 * ------------------------------------------------------------------------ 15358 */ 15359 15360 var NAME$1 = 'button'; 15361 var VERSION$1 = '4.3.1'; 15362 var DATA_KEY$1 = 'bs.button'; 15363 var EVENT_KEY$1 = "." + DATA_KEY$1; 15364 var DATA_API_KEY$1 = '.data-api'; 15365 var JQUERY_NO_CONFLICT$1 = $.fn[NAME$1]; 15366 var ClassName$1 = { 15367 ACTIVE: 'active', 15368 BUTTON: 'btn', 15369 FOCUS: 'focus' 15370 }; 15371 var Selector$1 = { 15372 DATA_TOGGLE_CARROT: '[data-toggle^="button"]', 15373 DATA_TOGGLE: '[data-toggle="buttons"]', 15374 INPUT: 'input:not([type="hidden"])', 15375 ACTIVE: '.active', 15376 BUTTON: '.btn' 15377 }; 15378 var Event$1 = { 15379 CLICK_DATA_API: "click" + EVENT_KEY$1 + DATA_API_KEY$1, 15380 FOCUS_BLUR_DATA_API: "focus" + EVENT_KEY$1 + DATA_API_KEY$1 + " " + ("blur" + EVENT_KEY$1 + DATA_API_KEY$1) 15381 /** 15382 * ------------------------------------------------------------------------ 15383 * Class Definition 15384 * ------------------------------------------------------------------------ 15385 */ 15386 15387 }; 15388 15389 var Button = 15390 /*#__PURE__*/ 15391 function () { 15392 function Button(element) { 15393 this._element = element; 15394 } // Getters 15395 15396 15397 var _proto = Button.prototype; 15398 15399 // Public 15400 _proto.toggle = function toggle() { 15401 var triggerChangeEvent = true; 15402 var addAriaPressed = true; 15403 var rootElement = $(this._element).closest(Selector$1.DATA_TOGGLE)[0]; 15404 15405 if (rootElement) { 15406 var input = this._element.querySelector(Selector$1.INPUT); 15407 15408 if (input) { 15409 if (input.type === 'radio') { 15410 if (input.checked && this._element.classList.contains(ClassName$1.ACTIVE)) { 15411 triggerChangeEvent = false;
vendor: 4,952 bytes, lines 15412-15581
15412 } else { 15413 var activeElement = rootElement.querySelector(Selector$1.ACTIVE); 15414 15415 if (activeElement) { 15416 $(activeElement).removeClass(ClassName$1.ACTIVE); 15417 } 15418 } 15419 } 15420 15421 if (triggerChangeEvent) { 15422 if (input.hasAttribute('disabled') || rootElement.hasAttribute('disabled') || input.classList.contains('disabled') || rootElement.classList.contains('disabled')) { 15423 return; 15424 } 15425 15426 input.checked = !this._element.classList.contains(ClassName$1.ACTIVE); 15427 $(input).trigger('change'); 15428 } 15429 15430 input.focus(); 15431 addAriaPressed = false; 15432 } 15433 } 15434 15435 if (addAriaPressed) { 15436 this._element.setAttribute('aria-pressed', !this._element.classList.contains(ClassName$1.ACTIVE)); 15437 } 15438 15439 if (triggerChangeEvent) { 15440 $(this._element).toggleClass(ClassName$1.ACTIVE); 15441 } 15442 }; 15443 15444 _proto.dispose = function dispose() { 15445 $.removeData(this._element, DATA_KEY$1); 15446 this._element = null; 15447 } // Static 15448 ; 15449 15450 Button._jQueryInterface = function _jQueryInterface(config) { 15451 return this.each(function () { 15452 var data = $(this).data(DATA_KEY$1); 15453 15454 if (!data) { 15455 data = new Button(this); 15456 $(this).data(DATA_KEY$1, data); 15457 } 15458 15459 if (config === 'toggle') { 15460 data[config](); 15461 } 15462 }); 15463 }; 15464 15465 _createClass(Button, null, [{ 15466 key: "VERSION", 15467 get: function get() { 15468 return VERSION$1; 15469 } 15470 }]); 15471 15472 return Button; 15473 }(); 15474 /** 15475 * ------------------------------------------------------------------------ 15476 * Data Api implementation 15477 * ------------------------------------------------------------------------ 15478 */ 15479 15480 15481 $(document).on(Event$1.CLICK_DATA_API, Selector$1.DATA_TOGGLE_CARROT, function (event) { 15482 event.preventDefault(); 15483 var button = event.target; 15484 15485 if (!$(button).hasClass(ClassName$1.BUTTON)) { 15486 button = $(button).closest(Selector$1.BUTTON); 15487 } 15488 15489 Button._jQueryInterface.call($(button), 'toggle'); 15490 }).on(Event$1.FOCUS_BLUR_DATA_API, Selector$1.DATA_TOGGLE_CARROT, function (event) { 15491 var button = $(event.target).closest(Selector$1.BUTTON)[0]; 15492 $(button).toggleClass(ClassName$1.FOCUS, /^focus(in)?$/.test(event.type)); 15493 }); 15494 /** 15495 * ------------------------------------------------------------------------ 15496 * jQuery 15497 * ------------------------------------------------------------------------ 15498 */ 15499 15500 $.fn[NAME$1] = Button._jQueryInterface; 15501 $.fn[NAME$1].Constructor = Button; 15502 15503 $.fn[NAME$1].noConflict = function () { 15504 $.fn[NAME$1] = JQUERY_NO_CONFLICT$1; 15505 return Button._jQueryInterface; 15506 }; 15507 15508 /** 15509 * ------------------------------------------------------------------------ 15510 * Constants 15511 * ------------------------------------------------------------------------ 15512 */ 15513 15514 var NAME$2 = 'carousel'; 15515 var VERSION$2 = '4.3.1'; 15516 var DATA_KEY$2 = 'bs.carousel'; 15517 var EVENT_KEY$2 = "." + DATA_KEY$2; 15518 var DATA_API_KEY$2 = '.data-api'; 15519 var JQUERY_NO_CONFLICT$2 = $.fn[NAME$2]; 15520 var ARROW_LEFT_KEYCODE = 37; // KeyboardEvent.which value for left arrow key 15521 15522 var ARROW_RIGHT_KEYCODE = 39; // KeyboardEvent.which value for right arrow key 15523 15524 var TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch 15525 15526 var SWIPE_THRESHOLD = 40; 15527 var Default = { 15528 interval: 5000, 15529 keyboard: true, 15530 slide: false, 15531 pause: 'hover', 15532 wrap: true, 15533 touch: true 15534 }; 15535 var DefaultType = { 15536 interval: '(number|boolean)', 15537 keyboard: 'boolean', 15538 slide: '(boolean|string)', 15539 pause: '(string|boolean)', 15540 wrap: 'boolean', 15541 touch: 'boolean' 15542 }; 15543 var Direction = { 15544 NEXT: 'next', 15545 PREV: 'prev', 15546 LEFT: 'left', 15547 RIGHT: 'right' 15548 }; 15549 var Event$2 = { 15550 SLIDE: "slide" + EVENT_KEY$2, 15551 SLID: "slid" + EVENT_KEY$2, 15552 KEYDOWN: "keydown" + EVENT_KEY$2, 15553 MOUSEENTER: "mouseenter" + EVENT_KEY$2, 15554 MOUSELEAVE: "mouseleave" + EVENT_KEY$2, 15555 TOUCHSTART: "touchstart" + EVENT_KEY$2, 15556 TOUCHMOVE: "touchmove" + EVENT_KEY$2, 15557 TOUCHEND: "touchend" + EVENT_KEY$2, 15558 POINTERDOWN: "pointerdown" + EVENT_KEY$2, 15559 POINTERUP: "pointerup" + EVENT_KEY$2, 15560 DRAG_START: "dragstart" + EVENT_KEY$2, 15561 LOAD_DATA_API: "load" + EVENT_KEY$2 + DATA_API_KEY$2, 15562 CLICK_DATA_API: "click" + EVENT_KEY$2 + DATA_API_KEY$2 15563 }; 15564 var ClassName$2 = { 15565 CAROUSEL: 'carousel', 15566 ACTIVE: 'active', 15567 SLIDE: 'slide', 15568 RIGHT: 'carousel-item-right', 15569 LEFT: 'carousel-item-left', 15570 NEXT: 'carousel-item-next', 15571 PREV: 'carousel-item-prev', 15572 ITEM: 'carousel-item', 15573 POINTER_EVENT: 'pointer-event' 15574 }; 15575 var Selector$2 = { 15576 ACTIVE: '.active', 15577 ACTIVE_ITEM: '.active.carousel-item', 15578 ITEM: '.carousel-item', 15579 ITEM_IMG: '.carousel-item img', 15580 NEXT_PREV: '.carousel-item-next, .carousel-item-prev', 15581 INDICATORS: '.carousel-indicators',
15582 DATA_SLIDE: '[data-slide], [data-slide-to]', 15583 DATA_RIDE: '[data-ride="carousel"]' 15584 }; 15585 var PointerType = { 15586 TOUCH: 'touch', 15587 PEN: 'pen' 15588 /** 15589 * ------------------------------------------------------------------------ 15590 * Class Definition 15591 * ------------------------------------------------------------------------ 15592 */ 15593 15594 }; 15595 15596 var Carousel = 15597 /*#__PURE__*/ 15598 function () { 15599 function Carousel(element, config) { 15600 this._items = null; 15601 this._interval = null; 15602 this._activeElement = null; 15603 this._isPaused = false; 15604 this._isSliding = false; 15605 this.touchTimeout = null; 15606 this.touchStartX = 0; 15607 this.touchDeltaX = 0; 15608 this._config = this._getConfig(config); 15609 this._element = element; 15610 this._indicatorsElement = this._element.querySelector(Selector$2.INDICATORS); 15611 this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0; 15612 this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent); 15613 15614 this._addEventListeners(); 15615 } // Getters 15616 15617 15618 var _proto = Carousel.prototype; 15619 15620 // Public 15621 _proto.next = function next() { 15622 if (!this._isSliding) { 15623 this._slide(Direction.NEXT); 15624 } 15625 }; 15626 15627 _proto.nextWhenVisible = function nextWhenVisible() { 15628 // Don't call next when the page isn't visible 15629 // or the carousel or its parent isn't visible 15630 if (!document.hidden && $(this._element).is(':visible') && $(this._element).css('visibility') !== 'hidden') { 15631 this.next(); 15632 } 15633 }; 15634 15635 _proto.prev = function prev() { 15636 if (!this._isSliding) { 15637 this._slide(Direction.PREV); 15638 } 15639 }; 15640 15641 _proto.pause = function pause(event) { 15642 if (!event) { 15643 this._isPaused = true; 15644 } 15645 15646 if (this._element.querySelector(Selector$2.NEXT_PREV)) { 15647 Util.triggerTransitionEnd(this._element); 15648 this.cycle(true); 15649 } 15650 15651 clearInterval(this._interval); 15652 this._interval = null; 15653 }; 15654 15655 _proto.cycle = function cycle(event) { 15656 if (!event) { 15657 this._isPaused = false; 15658 } 15659 15660 if (this._interval) { 15661 clearInterval(this._interval); 15662 this._interval = null; 15663 } 15664 15665 if (this._config.interval && !this._isPaused) { 15666 this._interval = setInterval((document.visibilityState ? this.nextWhenVisible : this.next).bind(this), this._config.interval); 15667 } 15668 }; 15669 15670 _proto.to = function to(index) { 15671 var _this = this; 15672 15673 this._activeElement = this._element.querySelector(Selector$2.ACTIVE_ITEM); 15674 15675 var activeIndex = this._getItemIndex(this._activeElement); 15676 15677 if (index > this._items.length - 1 || index < 0) { 15678 return; 15679 } 15680 15681 if (this._isSliding) { 15682 $(this._element).one(Event$2.SLID, function () { 15683 return _this.to(index); 15684 }); 15685 return; 15686 } 15687 15688 if (activeIndex === index) { 15689 this.pause(); 15690 this.cycle(); 15691 return; 15692 } 15693 15694 var direction = index > activeIndex ? Direction.NEXT : Direction.PREV; 15695 15696 this._slide(direction, this._items[index]); 15697 }; 15698 15699 _proto.dispose = function dispose() { 15700 $(this._element).off(EVENT_KEY$2); 15701 $.removeData(this._element, DATA_KEY$2); 15702 this._items = null; 15703 this._config = null; 15704 this._element = null; 15705 this._interval = null; 15706 this._isPaused = null; 15707 this._isSliding = null; 15708 this._activeElement = null; 15709 this._indicatorsElement = null; 15710 } // Private 15711 ; 15712 15713 _proto._getConfig = function _getConfig(config) { 15714 config = _objectSpread({}, Default, config); 15715 Util.typeCheckConfig(NAME$2, config, DefaultType); 15716 return config; 15717 }; 15718 15719 _proto._handleSwipe = function _handleSwipe() { 15720 var absDeltax = Math.abs(this.touchDeltaX); 15721 15722 if (absDeltax <= SWIPE_THRESHOLD) { 15723 return; 15724 } 15725 15726 var direction = absDeltax / this.touchDeltaX; // swipe left 15727 15728 if (direction > 0) { 15729 this.prev(); 15730 } // swipe right 15731 15732 15733 if (direction < 0) { 15734 this.next(); 15735 } 15736 }; 15737 15738 _proto._addEventListeners = function _addEventListeners() { 15739 var _this2 = this; 15740 15741 if (this._config.keyboard) { 15742 $(this._element).on(Event$2.KEYDOWN, function (event) { 15743 return _this2._keydown(event); 15744 }); 15745 } 15746 15747 if (this._config.pause === 'hover') { 15748 $(this._element).on(Event$2.MOUSEENTER, function (event) { 15749 return _this2.pause(event); 15750 }).on(Event$2.MOUSELEAVE, function (event) { 15751 return _this2.cycle(event); 15752 }); 15753 } 15754 15755 if (this._config.touch) { 15756 this._addTouchEventListeners(); 15757 } 15758 }; 15759 15760 _proto._addTouchEventListeners = function _addTouchEventListeners() { 15761 var _this3 = this; 15762 15763 if (!this._touchSupported) { 15764 return; 15765 } 15766 15767 var start = function start(event) { 15768 if (_this3._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) { 15769 _this3.touchStartX = event.originalEvent.clientX; 15770 } else if (!_this3._pointerEvent) { 15771 _this3.touchStartX = event.originalEvent.touches[0].clientX; 15772 } 15773 }; 15774 15775 var move = function move(event) { 15776 // ensure swiping with one touch and not pinching 15777 if (event.originalEvent.touches && event.originalEvent.touches.length > 1) { 15778 _this3.touchDeltaX = 0; 15779 } else { 15780 _this3.touchDeltaX = event.originalEvent.touches[0].clientX - _this3.touchStartX; 15781 } 15782 }; 15783 15784 var end = function end(event) { 15785 if (_this3._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) { 15786 _this3.touchDeltaX = event.originalEvent.clientX - _this3.touchStartX; 15787 } 15788 15789 _this3._handleSwipe(); 15790 15791 if (_this3._config.pause === 'hover') {
15792 // If it's a touch-enabled device, mouseenter/leave are fired as 15793 // part of the mouse compatibility events on first tap - the carousel 15794 // would stop cycling until user tapped out of it; 15795 // here, we listen for touchend, explicitly pause the carousel 15796 // (as if it's the second time we tap on it, mouseenter compat event 15797 // is NOT fired) and after a timeout (to allow for mouse compatibility 15798 // events to fire) we explicitly restart cycling 15799 _this3.pause(); 15800 15801 if (_this3.touchTimeout) { 15802 clearTimeout(_this3.touchTimeout); 15803 } 15804 15805 _this3.touchTimeout = setTimeout(function (event) { 15806 return _this3.cycle(event); 15807 }, TOUCHEVENT_COMPAT_WAIT + _this3._config.interval); 15808 } 15809 }; 15810 15811 $(this._element.querySelectorAll(Selector$2.ITEM_IMG)).on(Event$2.DRAG_START, function (e) { 15812 return e.preventDefault(); 15813 }); 15814 15815 if (this._pointerEvent) { 15816 $(this._element).on(Event$2.POINTERDOWN, function (event) { 15817 return start(event); 15818 }); 15819 $(this._element).on(Event$2.POINTERUP, function (event) { 15820 return end(event); 15821 }); 15822 15823 this._element.classList.add(ClassName$2.POINTER_EVENT); 15824 } else { 15825 $(this._element).on(Event$2.TOUCHSTART, function (event) { 15826 return start(event); 15827 }); 15828 $(this._element).on(Event$2.TOUCHMOVE, function (event) { 15829 return move(event); 15830 }); 15831 $(this._element).on(Event$2.TOUCHEND, function (event) { 15832 return end(event); 15833 }); 15834 } 15835 }; 15836 15837 _proto._keydown = function _keydown(event) { 15838 if (/input|textarea/i.test(event.target.tagName)) { 15839 return; 15840 } 15841 15842 switch (event.which) { 15843 case ARROW_LEFT_KEYCODE: 15844 event.preventDefault(); 15845 this.prev(); 15846 break; 15847 15848 case ARROW_RIGHT_KEYCODE: 15849 event.preventDefault(); 15850 this.next(); 15851 break; 15852 15853 default: 15854 } 15855 }; 15856 15857 _proto._getItemIndex = function _getItemIndex(element) { 15858 this._items = element && element.parentNode ? [].slice.call(element.parentNode.querySelectorAll(Selector$2.ITEM)) : []; 15859 return this._items.indexOf(element); 15860 }; 15861 15862 _proto._getItemByDirection = function _getItemByDirection(direction, activeElement) { 15863 var isNextDirection = direction === Direction.NEXT; 15864 var isPrevDirection = direction === Direction.PREV; 15865 15866 var activeIndex = this._getItemIndex(activeElement); 15867 15868 var lastItemIndex = this._items.length - 1; 15869 var isGoingToWrap = isPrevDirection && activeIndex === 0 || isNextDirection && activeIndex === lastItemIndex; 15870 15871 if (isGoingToWrap && !this._config.wrap) { 15872 return activeElement; 15873 } 15874 15875 var delta = direction === Direction.PREV ? -1 : 1; 15876 var itemIndex = (activeIndex + delta) % this._items.length; 15877 return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex]; 15878 }; 15879 15880 _proto._triggerSlideEvent = function _triggerSlideEvent(relatedTarget, eventDirectionName) { 15881 var targetIndex = this._getItemIndex(relatedTarget); 15882 15883 var fromIndex = this._getItemIndex(this._element.querySelector(Selector$2.ACTIVE_ITEM)); 15884 15885 var slideEvent = $.Event(Event$2.SLIDE, { 15886 relatedTarget: relatedTarget, 15887 direction: eventDirectionName, 15888 from: fromIndex, 15889 to: targetIndex 15890 }); 15891 $(this._element).trigger(slideEvent); 15892 return slideEvent; 15893 }; 15894 15895 _proto._setActiveIndicatorElement = function _setActiveIndicatorElement(element) { 15896 if (this._indicatorsElement) { 15897 var indicators = [].slice.call(this._indicatorsElement.querySelectorAll(Selector$2.ACTIVE)); 15898 $(indicators).removeClass(ClassName$2.ACTIVE); 15899 15900 var nextIndicator = this._indicatorsElement.children[this._getItemIndex(element)]; 15901 15902 if (nextIndicator) { 15903 $(nextIndicator).addClass(ClassName$2.ACTIVE); 15904 } 15905 } 15906 }; 15907 15908 _proto._slide = function _slide(direction, element) { 15909 var _this4 = this; 15910 15911 var activeElement = this._element.querySelector(Selector$2.ACTIVE_ITEM); 15912 15913 var activeElementIndex = this._getItemIndex(activeElement); 15914 15915 var nextElement = element || activeElement && this._getItemByDirection(direction, activeElement); 15916 15917 var nextElementIndex = this._getItemIndex(nextElement); 15918 15919 var isCycling = Boolean(this._interval); 15920 var directionalClassName; 15921 var orderClassName; 15922 var eventDirectionName; 15923 15924 if (direction === Direction.NEXT) { 15925 directionalClassName = ClassName$2.LEFT; 15926 orderClassName = ClassName$2.NEXT; 15927 eventDirectionName = Direction.LEFT; 15928 } else { 15929 directionalClassName = ClassName$2.RIGHT; 15930 orderClassName = ClassName$2.PREV; 15931 eventDirectionName = Direction.RIGHT; 15932 } 15933 15934 if (nextElement && $(nextElement).hasClass(ClassName$2.ACTIVE)) { 15935 this._isSliding = false;
15936 return; 15937 } 15938 15939 var slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName); 15940 15941 if (slideEvent.isDefaultPrevented()) { 15942 return; 15943 } 15944 15945 if (!activeElement || !nextElement) { 15946 // Some weirdness is happening, so we bail 15947 return; 15948 } 15949 15950 this._isSliding = true; 15951 15952 if (isCycling) { 15953 this.pause(); 15954 } 15955 15956 this._setActiveIndicatorElement(nextElement); 15957 15958 var slidEvent = $.Event(Event$2.SLID, { 15959 relatedTarget: nextElement, 15960 direction: eventDirectionName, 15961 from: activeElementIndex, 15962 to: nextElementIndex 15963 }); 15964 15965 if ($(this._element).hasClass(ClassName$2.SLIDE)) { 15966 $(nextElement).addClass(orderClassName); 15967 Util.reflow(nextElement); 15968 $(activeElement).addClass(directionalClassName); 15969 $(nextElement).addClass(directionalClassName); 15970 var nextElementInterval = parseInt(nextElement.getAttribute('data-interval'), 10); 15971 15972 if (nextElementInterval) { 15973 this._config.defaultInterval = this._config.defaultInterval || this._config.interval; 15974 this._config.interval = nextElementInterval; 15975 } else { 15976 this._config.interval = this._config.defaultInterval || this._config.interval; 15977 } 15978 15979 var transitionDuration = Util.getTransitionDurationFromElement(activeElement); 15980 $(activeElement).one(Util.TRANSITION_END, function () { 15981 $(nextElement).removeClass(directionalClassName + " " + orderClassName).addClass(ClassName$2.ACTIVE); 15982 $(activeElement).removeClass(ClassName$2.ACTIVE + " " + orderClassName + " " + directionalClassName); 15983 _this4._isSliding = false; 15984 setTimeout(function () { 15985 return $(_this4._element).trigger(slidEvent); 15986 }, 0); 15987 }).emulateTransitionEnd(transitionDuration); 15988 } else { 15989 $(activeElement).removeClass(ClassName$2.ACTIVE); 15990 $(nextElement).addClass(ClassName$2.ACTIVE); 15991 this._isSliding = false; 15992 $(this._element).trigger(slidEvent); 15993 } 15994 15995 if (isCycling) { 15996 this.cycle(); 15997 } 15998 } // Static 15999 ; 16000 16001 Carousel._jQueryInterface = function _jQueryInterface(config) { 16002 return this.each(function () { 16003 var data = $(this).data(DATA_KEY$2); 16004 16005 var _config = _objectSpread({}, Default, $(this).data()); 16006 16007 if (typeof config === 'object') { 16008 _config = _objectSpread({}, _config, config); 16009 } 16010 16011 var action = typeof config === 'string' ? config : _config.slide; 16012 16013 if (!data) { 16014 data = new Carousel(this, _config); 16015 $(this).data(DATA_KEY$2, data); 16016 } 16017 16018 if (typeof config === 'number') { 16019 data.to(config); 16020 } else if (typeof action === 'string') { 16021 if (typeof data[action] === 'undefined') { 16022 throw new TypeError("No method named \"" + action + "\""); 16023 } 16024 16025 data[action](); 16026 } else if (_config.interval && _config.ride) { 16027 data.pause(); 16028 data.cycle(); 16029 } 16030 }); 16031 }; 16032 16033 Carousel._dataApiClickHandler = function _dataApiClickHandler(event) { 16034 var selector = Util.getSelectorFromElement(this); 16035 16036 if (!selector) { 16037 return; 16038 } 16039 16040 var target = $(selector)[0]; 16041 16042 if (!target || !$(target).hasClass(ClassName$2.CAROUSEL)) { 16043 return; 16044 } 16045 16046 var config = _objectSpread({}, $(target).data(), $(this).data()); 16047 16048 var slideIndex = this.getAttribute('data-slide-to'); 16049 16050 if (slideIndex) { 16051 config.interval = false; 16052 } 16053 16054 Carousel._jQueryInterface.call($(target), config); 16055 16056 if (slideIndex) { 16057 $(target).data(DATA_KEY$2).to(slideIndex); 16058 } 16059 16060 event.preventDefault(); 16061 }; 16062 16063 _createClass(Carousel, null, [{ 16064 key: "VERSION", 16065 get: function get() { 16066 return VERSION$2; 16067 } 16068 }, { 16069 key: "Default", 16070 get: function get() { 16071 return Default; 16072 } 16073 }]); 16074 16075 return Carousel; 16076 }(); 16077 /** 16078 * ------------------------------------------------------------------------ 16079 * Data Api implementation 16080 * ------------------------------------------------------------------------ 16081 */ 16082 16083 16084 $(document).on(Event$2.CLICK_DATA_API, Selector$2.DATA_SLIDE, Carousel._dataApiClickHandler); 16085 $(window).on(Event$2.LOAD_DATA_API, function () { 16086 var carousels = [].slice.call(document.querySelectorAll(Selector$2.DATA_RIDE)); 16087 16088 for (var i = 0, len = carousels.length; i < len; i++) {
16089 var $carousel = $(carousels[i]); 16090 16091 Carousel._jQueryInterface.call($carousel, $carousel.data()); 16092 } 16093 }); 16094 /** 16095 * ------------------------------------------------------------------------ 16096 * jQuery 16097 * ------------------------------------------------------------------------ 16098 */ 16099 16100 $.fn[NAME$2] = Carousel._jQueryInterface; 16101 $.fn[NAME$2].Constructor = Carousel; 16102 16103 $.fn[NAME$2].noConflict = function () { 16104 $.fn[NAME$2] = JQUERY_NO_CONFLICT$2; 16105 return Carousel._jQueryInterface; 16106 }; 16107 16108 /** 16109 * ------------------------------------------------------------------------ 16110 * Constants 16111 * ------------------------------------------------------------------------ 16112 */ 16113 16114 var NAME$3 = 'collapse'; 16115 var VERSION$3 = '4.3.1'; 16116 var DATA_KEY$3 = 'bs.collapse'; 16117 var EVENT_KEY$3 = "." + DATA_KEY$3; 16118 var DATA_API_KEY$3 = '.data-api'; 16119 var JQUERY_NO_CONFLICT$3 = $.fn[NAME$3]; 16120 var Default$1 = { 16121 toggle: true, 16122 parent: '' 16123 }; 16124 var DefaultType$1 = { 16125 toggle: 'boolean', 16126 parent: '(string|element)' 16127 }; 16128 var Event$3 = { 16129 SHOW: "show" + EVENT_KEY$3, 16130 SHOWN: "shown" + EVENT_KEY$3, 16131 HIDE: "hide" + EVENT_KEY$3, 16132 HIDDEN: "hidden" + EVENT_KEY$3, 16133 CLICK_DATA_API: "click" + EVENT_KEY$3 + DATA_API_KEY$3 16134 }; 16135 var ClassName$3 = { 16136 SHOW: 'show', 16137 COLLAPSE: 'collapse', 16138 COLLAPSING: 'collapsing', 16139 COLLAPSED: 'collapsed' 16140 }; 16141 var Dimension = { 16142 WIDTH: 'width', 16143 HEIGHT: 'height' 16144 }; 16145 var Selector$3 = { 16146 ACTIVES: '.show, .collapsing', 16147 DATA_TOGGLE: '[data-toggle="collapse"]' 16148 /** 16149 * ------------------------------------------------------------------------ 16150 * Class Definition 16151 * ------------------------------------------------------------------------ 16152 */ 16153 16154 }; 16155 16156 var Collapse = 16157 /*#__PURE__*/ 16158 function () { 16159 function Collapse(element, config) { 16160 this._isTransitioning = false; 16161 this._element = element; 16162 this._config = this._getConfig(config); 16163 this._triggerArray = [].slice.call(document.querySelectorAll("[data-toggle=\"collapse\"][href=\"#" + element.id + "\"]," + ("[data-toggle=\"collapse\"][data-target=\"#" + element.id + "\"]"))); 16164 var toggleList = [].slice.call(document.querySelectorAll(Selector$3.DATA_TOGGLE)); 16165 16166 for (var i = 0, len = toggleList.length; i < len; i++) { 16167 var elem = toggleList[i]; 16168 var selector = Util.getSelectorFromElement(elem); 16169 var filterElement = [].slice.call(document.querySelectorAll(selector)).filter(function (foundElem) { 16170 return foundElem === element; 16171 }); 16172 16173 if (selector !== null && filterElement.length > 0) { 16174 this._selector = selector; 16175 16176 this._triggerArray.push(elem); 16177 } 16178 } 16179 16180 this._parent = this._config.parent ? this._getParent() : null; 16181 16182 if (!this._config.parent) { 16183 this._addAriaAndCollapsedClass(this._element, this._triggerArray); 16184 } 16185 16186 if (this._config.toggle) { 16187 this.toggle(); 16188 } 16189 } // Getters 16190 16191 16192 var _proto = Collapse.prototype; 16193 16194 // Public 16195 _proto.toggle = function toggle() { 16196 if ($(this._element).hasClass(ClassName$3.SHOW)) { 16197 this.hide(); 16198 } else { 16199 this.show(); 16200 } 16201 }; 16202 16203 _proto.show = function show() { 16204 var _this = this; 16205 16206 if (this._isTransitioning || $(this._element).hasClass(ClassName$3.SHOW)) { 16207 return; 16208 } 16209 16210 var actives; 16211 var activesData; 16212 16213 if (this._parent) { 16214 actives = [].slice.call(this._parent.querySelectorAll(Selector$3.ACTIVES)).filter(function (elem) { 16215 if (typeof _this._config.parent === 'string') { 16216 return elem.getAttribute('data-parent') === _this._config.parent; 16217 } 16218 16219 return elem.classList.contains(ClassName$3.COLLAPSE); 16220 }); 16221 16222 if (actives.length === 0) { 16223 actives = null; 16224 } 16225 } 16226 16227 if (actives) { 16228 activesData = $(actives).not(this._selector).data(DATA_KEY$3); 16229 16230 if (activesData && activesData._isTransitioning) { 16231 return; 16232 } 16233 } 16234 16235 var startEvent = $.Event(Event$3.SHOW); 16236 $(this._element).trigger(startEvent); 16237 16238 if (startEvent.isDefaultPrevented()) { 16239 return; 16240 } 16241 16242 if (actives) { 16243 Collapse._jQueryInterface.call($(actives).not(this._selector), 'hide'); 16244 16245 if (!activesData) { 16246 $(actives).data(DATA_KEY$3, null); 16247 } 16248 } 16249 16250 var dimension = this._getDimension(); 16251 16252 $(this._element).removeClass(ClassName$3.COLLAPSE).addClass(ClassName$3.COLLAPSING); 16253 this._element.style[dimension] = 0; 16254 16255 if (this._triggerArray.length) { 16256 $(this._triggerArray).removeClass(ClassName$3.COLLAPSED).attr('aria-expanded', true); 16257 } 16258 16259 this.setTransitioning(true); 16260 16261 var complete = function complete() { 16262 $(_this._element).removeClass(ClassName$3.COLLAPSING).addClass(ClassName$3.COLLAPSE).addClass(ClassName$3.SHOW); 16263 _this._element.style[dimension] = ''; 16264 16265 _this.setTransitioning(false); 16266 16267 $(_this._element).trigger(Event$3.SHOWN); 16268 }; 16269 16270 var capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1); 16271 var scrollSize = "scroll" + capitalizedDimension; 16272 var transitionDuration = Util.getTransitionDurationFromElement(this._element); 16273 $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); 16274 this._element.style[dimension] = this._element[scrollSize] + "px"; 16275 }; 16276 16277 _proto.hide = function hide() { 16278 var _this2 = this; 16279 16280 if (this._isTransitioning || !$(this._element).hasClass(ClassName$3.SHOW)) { 16281 return; 16282 } 16283 16284 var startEvent = $.Event(Event$3.HIDE); 16285 $(this._element).trigger(startEvent); 16286 16287 if (startEvent.isDefaultPrevented()) { 16288 return; 16289 } 16290 16291 var dimension = this._getDimension(); 16292 16293 this._element.style[dimension] = this._element.getBoundingClientRect()[dimension] + "px"; 16294 Util.reflow(this._element); 16295 $(this._element).addClass(ClassName$3.COLLAPSING).removeClass(ClassName$3.COLLAPSE).removeClass(ClassName$3.SHOW); 16296 var triggerArrayLength = this._triggerArray.length; 16297 16298 if (triggerArrayLength > 0) { 16299 for (var i = 0; i < triggerArrayLength; i++) { 16300 var trigger = this._triggerArray[i]; 16301 var selector = Util.getSelectorFromElement(trigger); 16302 16303 if (selector !== null) { 16304 var $elem = $([].slice.call(document.querySelectorAll(selector))); 16305 16306 if (!$elem.hasClass(ClassName$3.SHOW)) { 16307 $(trigger).addClass(ClassName$3.COLLAPSED).attr('aria-expanded', false); 16308 } 16309 } 16310 } 16311 } 16312 16313 this.setTransitioning(true); 16314 16315 var complete = function complete() { 16316 _this2.setTransitioning(false); 16317 16318 $(_this2._element).removeClass(ClassName$3.COLLAPSING).addClass(ClassName$3.COLLAPSE).trigger(Event$3.HIDDEN); 16319 }; 16320 16321 this._element.style[dimension] = ''; 16322 var transitionDuration = Util.getTransitionDurationFromElement(this._element); 16323 $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); 16324 }; 16325 16326 _proto.setTransitioning = function setTransitioning(isTransitioning) { 16327 this._isTransitioning = isTransitioning; 16328 }; 16329 16330 _proto.dispose = function dispose() { 16331 $.removeData(this._element, DATA_KEY$3); 16332 this._config = null; 16333 this._parent = null; 16334 this._element = null; 16335 this._triggerArray = null; 16336 this._isTransitioning = null; 16337 } // Private 16338 ; 16339 16340 _proto._getConfig = function _getConfig(config) { 16341 config = _objectSpread({}, Default$1, config); 16342 config.toggle = Boolean(config.toggle); // Coerce string values 16343 16344 Util.typeCheckConfig(NAME$3, config, DefaultType$1); 16345 return config; 16346 }; 16347 16348 _proto._getDimension = function _getDimension() { 16349 var hasWidth = $(this._element).hasClass(Dimension.WIDTH); 16350 return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT; 16351 }; 16352 16353 _proto._getParent = function _getParent() { 16354 var _this3 = this; 16355 16356 var parent; 16357 16358 if (Util.isElement(this._config.parent)) { 16359 parent = this._config.parent; // It's a jQuery object 16360 16361 if (typeof this._config.parent.jquery !== 'undefined') { 16362 parent = this._config.parent[0]; 16363 } 16364 } else { 16365 parent = document.querySelector(this._config.parent); 16366 } 16367 16368 var selector = "[data-toggle=\"collapse\"][data-parent=\"" + this._config.parent + "\"]"; 16369 var children = [].slice.call(parent.querySelectorAll(selector)); 16370 $(children).each(function (i, element) { 16371 _this3._addAriaAndCollapsedClass(Collapse._getTargetFromElement(element), [element]); 16372 }); 16373 return parent; 16374 }; 16375 16376 _proto._addAriaAndCollapsedClass = function _addAriaAndCollapsedClass(element, triggerArray) { 16377 var isOpen = $(element).hasClass(ClassName$3.SHOW); 16378 16379 if (triggerArray.length) { 16380 $(triggerArray).toggleClass(ClassName$3.COLLAPSED, !isOpen).attr('aria-expanded', isOpen); 16381 } 16382 } // Static 16383 ; 16384 16385 Collapse._getTargetFromElement = function _getTargetFromElement(element) { 16386 var selector = Util.getSelectorFromElement(element); 16387 return selector ? document.querySelector(selector) : null; 16388 }; 16389 16390 Collapse._jQueryInterface = function _jQueryInterface(config) { 16391 return this.each(function () { 16392 var $this = $(this); 16393 var data = $this.data(DATA_KEY$3); 16394 16395 var _config = _objectSpread({}, Default$1, $this.data(), typeof config === 'object' && config ? config : {}); 16396 16397 if (!data && _config.toggle && /show|hide/.test(config)) { 16398 _config.toggle = false;
16399 } 16400 16401 if (!data) { 16402 data = new Collapse(this, _config); 16403 $this.data(DATA_KEY$3, data); 16404 } 16405 16406 if (typeof config === 'string') { 16407 if (typeof data[config] === 'undefined') { 16408 throw new TypeError("No method named \"" + config + "\""); 16409 } 16410 16411 data[config](); 16412 } 16413 }); 16414 }; 16415 16416 _createClass(Collapse, null, [{ 16417 key: "VERSION", 16418 get: function get() { 16419 return VERSION$3; 16420 } 16421 }, { 16422 key: "Default", 16423 get: function get() { 16424 return Default$1; 16425 } 16426 }]); 16427 16428 return Collapse; 16429 }(); 16430 /** 16431 * ------------------------------------------------------------------------ 16432 * Data Api implementation 16433 * ------------------------------------------------------------------------ 16434 */ 16435 16436 16437 $(document).on(Event$3.CLICK_DATA_API, Selector$3.DATA_TOGGLE, function (event) { 16438 // preventDefault only for <a> elements (which change the URL) not inside the collapsible element 16439 if (event.currentTarget.tagName === 'A') { 16440 event.preventDefault(); 16441 } 16442 16443 var $trigger = $(this); 16444 var selector = Util.getSelectorFromElement(this); 16445 var selectors = [].slice.call(document.querySelectorAll(selector)); 16446 $(selectors).each(function () { 16447 var $target = $(this); 16448 var data = $target.data(DATA_KEY$3); 16449 var config = data ? 'toggle' : $trigger.data(); 16450 16451 Collapse._jQueryInterface.call($target, config); 16452 }); 16453 }); 16454 /** 16455 * ------------------------------------------------------------------------ 16456 * jQuery 16457 * ------------------------------------------------------------------------ 16458 */ 16459 16460 $.fn[NAME$3] = Collapse._jQueryInterface; 16461 $.fn[NAME$3].Constructor = Collapse; 16462 16463 $.fn[NAME$3].noConflict = function () { 16464 $.fn[NAME$3] = JQUERY_NO_CONFLICT$3; 16465 return Collapse._jQueryInterface; 16466 }; 16467 16468 /** 16469 * ------------------------------------------------------------------------ 16470 * Constants 16471 * ------------------------------------------------------------------------ 16472 */ 16473 16474 var NAME$4 = 'dropdown'; 16475 var VERSION$4 = '4.3.1'; 16476 var DATA_KEY$4 = 'bs.dropdown'; 16477 var EVENT_KEY$4 = "." + DATA_KEY$4; 16478 var DATA_API_KEY$4 = '.data-api'; 16479 var JQUERY_NO_CONFLICT$4 = $.fn[NAME$4]; 16480 var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key 16481 16482 var SPACE_KEYCODE = 32; // KeyboardEvent.which value for space key 16483 16484 var TAB_KEYCODE = 9; // KeyboardEvent.which value for tab key 16485 16486 var ARROW_UP_KEYCODE = 38; // KeyboardEvent.which value for up arrow key 16487 16488 var ARROW_DOWN_KEYCODE = 40; // KeyboardEvent.which value for down arrow key 16489 16490 var RIGHT_MOUSE_BUTTON_WHICH = 3; // MouseEvent.which value for the right button (assuming a right-handed mouse) 16491 16492 var REGEXP_KEYDOWN = new RegExp(ARROW_UP_KEYCODE + "|" + ARROW_DOWN_KEYCODE + "|" + ESCAPE_KEYCODE); 16493 var Event$4 = { 16494 HIDE: "hide" + EVENT_KEY$4, 16495 HIDDEN: "hidden" + EVENT_KEY$4, 16496 SHOW: "show" + EVENT_KEY$4, 16497 SHOWN: "shown" + EVENT_KEY$4, 16498 CLICK: "click" + EVENT_KEY$4, 16499 CLICK_DATA_API: "click" + EVENT_KEY$4 + DATA_API_KEY$4, 16500 KEYDOWN_DATA_API: "keydown" + EVENT_KEY$4 + DATA_API_KEY$4, 16501 KEYUP_DATA_API: "keyup" + EVENT_KEY$4 + DATA_API_KEY$4 16502 }; 16503 var ClassName$4 = { 16504 DISABLED: 'disabled', 16505 SHOW: 'show', 16506 DROPUP: 'dropup', 16507 DROPRIGHT: 'dropright', 16508 DROPLEFT: 'dropleft', 16509 MENURIGHT: 'dropdown-menu-right', 16510 MENULEFT: 'dropdown-menu-left', 16511 POSITION_STATIC: 'position-static' 16512 }; 16513 var Selector$4 = { 16514 DATA_TOGGLE: '[data-toggle="dropdown"]', 16515 FORM_CHILD: '.dropdown form', 16516 MENU: '.dropdown-menu', 16517 NAVBAR_NAV: '.navbar-nav', 16518 VISIBLE_ITEMS: '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)' 16519 }; 16520 var AttachmentMap = { 16521 TOP: 'top-start', 16522 TOPEND: 'top-end', 16523 BOTTOM: 'bottom-start', 16524 BOTTOMEND: 'bottom-end', 16525 RIGHT: 'right-start', 16526 RIGHTEND: 'right-end', 16527 LEFT: 'left-start', 16528 LEFTEND: 'left-end' 16529 }; 16530 var Default$2 = { 16531 offset: 0, 16532 flip: true, 16533 boundary: 'scrollParent', 16534 reference: 'toggle', 16535 display: 'dynamic' 16536 }; 16537 var DefaultType$2 = { 16538 offset: '(number|string|function)', 16539 flip: 'boolean', 16540 boundary: '(string|element)', 16541 reference: '(string|element)', 16542 display: 'string' 16543 /** 16544 * ------------------------------------------------------------------------ 16545 * Class Definition 16546 * ------------------------------------------------------------------------ 16547 */ 16548 16549 }; 16550 16551 var Dropdown = 16552 /*#__PURE__*/ 16553 function () { 16554 function Dropdown(element, config) { 16555 this._element = element; 16556 this._popper = null; 16557 this._config = this._getConfig(config); 16558 this._menu = this._getMenuElement(); 16559 this._inNavbar = this._detectNavbar(); 16560 16561 this._addEventListeners(); 16562 } // Getters 16563 16564 16565 var _proto = Dropdown.prototype; 16566 16567 // Public
16568 _proto.toggle = function toggle() { 16569 if (this._element.disabled || $(this._element).hasClass(ClassName$4.DISABLED)) { 16570 return; 16571 } 16572 16573 var parent = Dropdown._getParentFromElement(this._element); 16574 16575 var isActive = $(this._menu).hasClass(ClassName$4.SHOW); 16576 16577 Dropdown._clearMenus(); 16578 16579 if (isActive) { 16580 return; 16581 } 16582 16583 var relatedTarget = { 16584 relatedTarget: this._element 16585 }; 16586 var showEvent = $.Event(Event$4.SHOW, relatedTarget); 16587 $(parent).trigger(showEvent); 16588 16589 if (showEvent.isDefaultPrevented()) { 16590 return; 16591 } // Disable totally Popper.js for Dropdown in Navbar 16592 16593 16594 if (!this._inNavbar) { 16595 /** 16596 * Check for Popper dependency 16597 * Popper - https://popper.js.org 16598 */ 16599 if (typeof Popper === 'undefined') { 16600 throw new TypeError('Bootstrap\'s dropdowns require Popper.js (https://popper.js.org/)'); 16601 } 16602 16603 var referenceElement = this._element; 16604 16605 if (this._config.reference === 'parent') { 16606 referenceElement = parent; 16607 } else if (Util.isElement(this._config.reference)) { 16608 referenceElement = this._config.reference; // Check if it's jQuery element 16609 16610 if (typeof this._config.reference.jquery !== 'undefined') { 16611 referenceElement = this._config.reference[0]; 16612 } 16613 } // If boundary is not `scrollParent`, then set position to `static` 16614 // to allow the menu to "escape" the scroll parent's boundaries 16615 // https://github.com/twbs/bootstrap/issues/24251 16616 16617 16618 if (this._config.boundary !== 'scrollParent') { 16619 $(parent).addClass(ClassName$4.POSITION_STATIC); 16620 } 16621 16622 this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig()); 16623 } // If this is a touch-enabled device we add extra 16624 // empty mouseover listeners to the body's immediate children; 16625 // only needed because of broken event delegation on iOS 16626 // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html 16627 16628 16629 if ('ontouchstart' in document.documentElement && $(parent).closest(Selector$4.NAVBAR_NAV).length === 0) { 16630 $(document.body).children().on('mouseover', null, $.noop); 16631 } 16632 16633 this._element.focus(); 16634 16635 this._element.setAttribute('aria-expanded', true); 16636 16637 $(this._menu).toggleClass(ClassName$4.SHOW); 16638 $(parent).toggleClass(ClassName$4.SHOW).trigger($.Event(Event$4.SHOWN, relatedTarget)); 16639 }; 16640 16641 _proto.show = function show() { 16642 if (this._element.disabled || $(this._element).hasClass(ClassName$4.DISABLED) || $(this._menu).hasClass(ClassName$4.SHOW)) { 16643 return; 16644 } 16645 16646 var relatedTarget = { 16647 relatedTarget: this._element 16648 }; 16649 var showEvent = $.Event(Event$4.SHOW, relatedTarget); 16650 16651 var parent = Dropdown._getParentFromElement(this._element); 16652 16653 $(parent).trigger(showEvent); 16654 16655 if (showEvent.isDefaultPrevented()) { 16656 return; 16657 } 16658 16659 $(this._menu).toggleClass(ClassName$4.SHOW); 16660 $(parent).toggleClass(ClassName$4.SHOW).trigger($.Event(Event$4.SHOWN, relatedTarget)); 16661 }; 16662 16663 _proto.hide = function hide() { 16664 if (this._element.disabled || $(this._element).hasClass(ClassName$4.DISABLED) || !$(this._menu).hasClass(ClassName$4.SHOW)) { 16665 return; 16666 } 16667 16668 var relatedTarget = { 16669 relatedTarget: this._element 16670 }; 16671 var hideEvent = $.Event(Event$4.HIDE, relatedTarget); 16672 16673 var parent = Dropdown._getParentFromElement(this._element); 16674 16675 $(parent).trigger(hideEvent); 16676 16677 if (hideEvent.isDefaultPrevented()) { 16678 return; 16679 } 16680 16681 $(this._menu).toggleClass(ClassName$4.SHOW); 16682 $(parent).toggleClass(ClassName$4.SHOW).trigger($.Event(Event$4.HIDDEN, relatedTarget)); 16683 }; 16684 16685 _proto.dispose = function dispose() { 16686 $.removeData(this._element, DATA_KEY$4); 16687 $(this._element).off(EVENT_KEY$4); 16688 this._element = null; 16689 this._menu = null; 16690 16691 if (this._popper !== null) { 16692 this._popper.destroy(); 16693 16694 this._popper = null; 16695 } 16696 }; 16697
16698 _proto.update = function update() { 16699 this._inNavbar = this._detectNavbar(); 16700 16701 if (this._popper !== null) { 16702 this._popper.scheduleUpdate(); 16703 } 16704 } // Private 16705 ; 16706 16707 _proto._addEventListeners = function _addEventListeners() { 16708 var _this = this; 16709 16710 $(this._element).on(Event$4.CLICK, function (event) { 16711 event.preventDefault(); 16712 event.stopPropagation(); 16713 16714 _this.toggle(); 16715 }); 16716 }; 16717 16718 _proto._getConfig = function _getConfig(config) { 16719 config = _objectSpread({}, this.constructor.Default, $(this._element).data(), config); 16720 Util.typeCheckConfig(NAME$4, config, this.constructor.DefaultType); 16721 return config; 16722 }; 16723 16724 _proto._getMenuElement = function _getMenuElement() { 16725 if (!this._menu) { 16726 var parent = Dropdown._getParentFromElement(this._element); 16727 16728 if (parent) { 16729 this._menu = parent.querySelector(Selector$4.MENU); 16730 } 16731 } 16732 16733 return this._menu; 16734 }; 16735 16736 _proto._getPlacement = function _getPlacement() { 16737 var $parentDropdown = $(this._element.parentNode); 16738 var placement = AttachmentMap.BOTTOM; // Handle dropup 16739 16740 if ($parentDropdown.hasClass(ClassName$4.DROPUP)) { 16741 placement = AttachmentMap.TOP; 16742 16743 if ($(this._menu).hasClass(ClassName$4.MENURIGHT)) { 16744 placement = AttachmentMap.TOPEND; 16745 } 16746 } else if ($parentDropdown.hasClass(ClassName$4.DROPRIGHT)) { 16747 placement = AttachmentMap.RIGHT; 16748 } else if ($parentDropdown.hasClass(ClassName$4.DROPLEFT)) { 16749 placement = AttachmentMap.LEFT; 16750 } else if ($(this._menu).hasClass(ClassName$4.MENURIGHT)) { 16751 placement = AttachmentMap.BOTTOMEND; 16752 } 16753 16754 return placement; 16755 }; 16756 16757 _proto._detectNavbar = function _detectNavbar() { 16758 return $(this._element).closest('.navbar').length > 0; 16759 }; 16760 16761 _proto._getOffset = function _getOffset() { 16762 var _this2 = this; 16763 16764 var offset = {}; 16765 16766 if (typeof this._config.offset === 'function') { 16767 offset.fn = function (data) { 16768 data.offsets = _objectSpread({}, data.offsets, _this2._config.offset(data.offsets, _this2._element) || {}); 16769 return data; 16770 }; 16771 } else { 16772 offset.offset = this._config.offset; 16773 } 16774 16775 return offset; 16776 }; 16777 16778 _proto._getPopperConfig = function _getPopperConfig() { 16779 var popperConfig = { 16780 placement: this._getPlacement(), 16781 modifiers: { 16782 offset: this._getOffset(), 16783 flip: { 16784 enabled: this._config.flip 16785 }, 16786 preventOverflow: { 16787 boundariesElement: this._config.boundary 16788 } 16789 } // Disable Popper.js if we have a static display 16790 16791 }; 16792 16793 if (this._config.display === 'static') { 16794 popperConfig.modifiers.applyStyle = { 16795 enabled: false 16796 }; 16797 } 16798 16799 return popperConfig; 16800 } // Static 16801 ; 16802 16803 Dropdown._jQueryInterface = function _jQueryInterface(config) { 16804 return this.each(function () { 16805 var data = $(this).data(DATA_KEY$4); 16806 16807 var _config = typeof config === 'object' ? config : null; 16808 16809 if (!data) { 16810 data = new Dropdown(this, _config); 16811 $(this).data(DATA_KEY$4, data); 16812 } 16813 16814 if (typeof config === 'string') { 16815 if (typeof data[config] === 'undefined') { 16816 throw new TypeError("No method named \"" + config + "\""); 16817 } 16818 16819 data[config](); 16820 } 16821 }); 16822 }; 16823 16824 Dropdown._clearMenus = function _clearMenus(event) { 16825 if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH || event.type === 'keyup' && event.which !== TAB_KEYCODE)) { 16826 return; 16827 } 16828 16829 var toggles = [].slice.call(document.querySelectorAll(Selector$4.DATA_TOGGLE)); 16830 16831 for (var i = 0, len = toggles.length; i < len; i++) { 16832 var parent = Dropdown._getParentFromElement(toggles[i]); 16833 16834 var context = $(toggles[i]).data(DATA_KEY$4); 16835 var relatedTarget = { 16836 relatedTarget: toggles[i] 16837 }; 16838 16839 if (event && event.type === 'click') { 16840 relatedTarget.clickEvent = event; 16841 } 16842 16843 if (!context) { 16844 continue; 16845 } 16846 16847 var dropdownMenu = context._menu; 16848 16849 if (!$(parent).hasClass(ClassName$4.SHOW)) { 16850 continue; 16851 } 16852 16853 if (event && (event.type === 'click' && /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) && $.contains(parent, event.target)) { 16854 continue; 16855 } 16856 16857 var hideEvent = $.Event(Event$4.HIDE, relatedTarget); 16858 $(parent).trigger(hideEvent); 16859 16860 if (hideEvent.isDefaultPrevented()) { 16861 continue; 16862 } // If this is a touch-enabled device we remove the extra 16863 // empty mouseover listeners we added for iOS support 16864 16865 16866 if ('ontouchstart' in document.documentElement) { 16867 $(document.body).children().off('mouseover', null, $.noop); 16868 } 16869 16870 toggles[i].setAttribute('aria-expanded', 'false'); 16871 $(dropdownMenu).removeClass(ClassName$4.SHOW); 16872 $(parent).removeClass(ClassName$4.SHOW).trigger($.Event(Event$4.HIDDEN, relatedTarget)); 16873 } 16874 }; 16875 16876 Dropdown._getParentFromElement = function _getParentFromElement(element) { 16877 var parent; 16878 var selector = Util.getSelectorFromElement(element); 16879 16880 if (selector) { 16881 parent = document.querySelector(selector); 16882 } 16883 16884 return parent || element.parentNode; 16885 } // eslint-disable-next-line complexity 16886 ; 16887 16888 Dropdown._dataApiKeydownHandler = function _dataApiKeydownHandler(event) { 16889 // If not input/textarea: 16890 // - And not a key in REGEXP_KEYDOWN => not a dropdown command 16891 // If input/textarea: 16892 // - If space key => not a dropdown command 16893 // - If key is other than escape 16894 // - If key is not up or down => not a dropdown command 16895 // - If trigger inside the menu =>
16895 not a dropdown command 16896 if (/input|textarea/i.test(event.target.tagName) ? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE && (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE || $(event.target).closest(Selector$4.MENU).length) : !REGEXP_KEYDOWN.test(event.which)) { 16897 return; 16898 } 16899 16900 event.preventDefault(); 16901 event.stopPropagation(); 16902 16903 if (this.disabled || $(this).hasClass(ClassName$4.DISABLED)) { 16904 return; 16905 } 16906 16907 var parent = Dropdown._getParentFromElement(this); 16908 16909 var isActive = $(parent).hasClass(ClassName$4.SHOW); 16910 16911 if (!isActive || isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) { 16912 if (event.which === ESCAPE_KEYCODE) { 16913 var toggle = parent.querySelector(Selector$4.DATA_TOGGLE); 16914 $(toggle).trigger('focus'); 16915 } 16916 16917 $(this).trigger('click'); 16918 return; 16919 } 16920 16921 var items = [].slice.call(parent.querySelectorAll(Selector$4.VISIBLE_ITEMS)); 16922 16923 if (items.length === 0) { 16924 return; 16925 } 16926 16927 var index = items.indexOf(event.target); 16928 16929 if (event.which === ARROW_UP_KEYCODE && index > 0) { 16930 // Up 16931 index--; 16932 } 16933 16934 if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { 16935 // Down 16936 index++; 16937 } 16938 16939 if (index < 0) { 16940 index = 0; 16941 } 16942 16943 items[index].focus(); 16944 }; 16945 16946 _createClass(Dropdown, null, [{ 16947 key: "VERSION", 16948 get: function get() { 16949 return VERSION$4; 16950 } 16951 }, { 16952 key: "Default", 16953 get: function get() { 16954 return Default$2; 16955 } 16956 }, { 16957 key: "DefaultType", 16958 get: function get() { 16959 return DefaultType$2; 16960 } 16961 }]); 16962 16963 return Dropdown; 16964 }(); 16965 /** 16966 * ------------------------------------------------------------------------ 16967 * Data Api implementation 16968 * ------------------------------------------------------------------------ 16969 */ 16970 16971 16972 $(document).on(Event$4.KEYDOWN_DATA_API, Selector$4.DATA_TOGGLE, Dropdown._dataApiKeydownHandler).on(Event$4.KEYDOWN_DATA_API, Selector$4.MENU, Dropdown._dataApiKeydownHandler).on(Event$4.CLICK_DATA_API + " " + Event$4.KEYUP_DATA_API, Dropdown._clearMenus).on(Event$4.CLICK_DATA_API, Selector$4.DATA_TOGGLE, function (event) { 16973 event.preventDefault(); 16974 event.stopPropagation(); 16975 16976 Dropdown._jQueryInterface.call($(this), 'toggle'); 16977 }).on(Event$4.CLICK_DATA_API, Selector$4.FORM_CHILD, function (e) { 16978 e.stopPropagation(); 16979 }); 16980 /** 16981 * ------------------------------------------------------------------------ 16982 * jQuery 16983 * ------------------------------------------------------------------------ 16984 */ 16985 16986 $.fn[NAME$4] = Dropdown._jQueryInterface; 16987 $.fn[NAME$4].Constructor = Dropdown; 16988 16989 $.fn[NAME$4].noConflict = function () { 16990 $.fn[NAME$4] = JQUERY_NO_CONFLICT$4; 16991 return Dropdown._jQueryInterface; 16992 }; 16993 16994 /** 16995 * ------------------------------------------------------------------------ 16996 * Constants 16997 * ------------------------------------------------------------------------ 16998 */ 16999 17000 var NAME$5 = 'modal'; 17001 var VERSION$5 = '4.3.1'; 17002 var DATA_KEY$5 = 'bs.modal'; 17003 var EVENT_KEY$5 = "." + DATA_KEY$5; 17004 var DATA_API_KEY$5 = '.data-api'; 17005 var JQUERY_NO_CONFLICT$5 = $.fn[NAME$5]; 17006 var ESCAPE_KEYCODE$1 = 27; // KeyboardEvent.which value for Escape (Esc) key 17007 17008 var Default$3 = { 17009 backdrop: true, 17010 keyboard: true, 17011 focus: true, 17012 show: true 17013 }; 17014 var DefaultType$3 = { 17015 backdrop: '(boolean|string)', 17016 keyboard: 'boolean', 17017 focus: 'boolean', 17018 show: 'boolean' 17019 }; 17020 var Event$5 = { 17021 HIDE: "hide" + EVENT_KEY$5, 17022 HIDDEN: "hidden" + EVENT_KEY$5, 17023 SHOW: "show" + EVENT_KEY$5, 17024 SHOWN: "shown" + EVENT_KEY$5, 17025 FOCUSIN: "focusin" + EVENT_KEY$5, 17026 RESIZE: "resize" + EVENT_KEY$5, 17027 CLICK_DISMISS: "click.dismiss" + EVENT_KEY$5, 17028 KEYDOWN_DISMISS: "keydown.dismiss" + EVENT_KEY$5, 17029 MOUSEUP_DISMISS: "mouseup.dismiss" + EVENT_KEY$5, 17030 MOUSEDOWN_DISMISS: "mousedown.dismiss" + EVENT_KEY$5, 17031 CLICK_DATA_API: "click" + EVENT_KEY$5 + DATA_API_KEY$5 17032 }; 17033 var ClassName$5 = {
17034 SCROLLABLE: 'modal-dialog-scrollable', 17035 SCROLLBAR_MEASURER: 'modal-scrollbar-measure', 17036 BACKDROP: 'modal-backdrop', 17037 OPEN: 'modal-open', 17038 FADE: 'fade', 17039 SHOW: 'show' 17040 }; 17041 var Selector$5 = { 17042 DIALOG: '.modal-dialog', 17043 MODAL_BODY: '.modal-body', 17044 DATA_TOGGLE: '[data-toggle="modal"]', 17045 DATA_DISMISS: '[data-dismiss="modal"]', 17046 FIXED_CONTENT: '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top', 17047 STICKY_CONTENT: '.sticky-top' 17048 /** 17049 * ------------------------------------------------------------------------ 17050 * Class Definition 17051 * ------------------------------------------------------------------------ 17052 */ 17053 17054 }; 17055 17056 var Modal = 17057 /*#__PURE__*/ 17058 function () { 17059 function Modal(element, config) { 17060 this._config = this._getConfig(config); 17061 this._element = element; 17062 this._dialog = element.querySelector(Selector$5.DIALOG); 17063 this._backdrop = null; 17064 this._isShown = false; 17065 this._isBodyOverflowing = false; 17066 this._ignoreBackdropClick = false; 17067 this._isTransitioning = false; 17068 this._scrollbarWidth = 0; 17069 } // Getters 17070 17071 17072 var _proto = Modal.prototype; 17073 17074 // Public 17075 _proto.toggle = function toggle(relatedTarget) { 17076 return this._isShown ? this.hide() : this.show(relatedTarget); 17077 }; 17078 17079 _proto.show = function show(relatedTarget) { 17080 var _this = this; 17081 17082 if (this._isShown || this._isTransitioning) { 17083 return; 17084 } 17085 17086 if ($(this._element).hasClass(ClassName$5.FADE)) { 17087 this._isTransitioning = true; 17088 } 17089 17090 var showEvent = $.Event(Event$5.SHOW, { 17091 relatedTarget: relatedTarget 17092 }); 17093 $(this._element).trigger(showEvent); 17094 17095 if (this._isShown || showEvent.isDefaultPrevented()) { 17096 return; 17097 } 17098 17099 this._isShown = true; 17100 17101 this._checkScrollbar(); 17102 17103 this._setScrollbar(); 17104 17105 this._adjustDialog(); 17106 17107 this._setEscapeEvent(); 17108 17109 this._setResizeEvent(); 17110 17111 $(this._element).on(Event$5.CLICK_DISMISS, Selector$5.DATA_DISMISS, function (event) { 17112 return _this.hide(event); 17113 }); 17114 $(this._dialog).on(Event$5.MOUSEDOWN_DISMISS, function () { 17115 $(_this._element).one(Event$5.MOUSEUP_DISMISS, function (event) { 17116 if ($(event.target).is(_this._element)) { 17117 _this._ignoreBackdropClick = true; 17118 } 17119 }); 17120 }); 17121 17122 this._showBackdrop(function () { 17123 return _this._showElement(relatedTarget); 17124 }); 17125 }; 17126 17127 _proto.hide = function hide(event) { 17128 var _this2 = this; 17129 17130 if (event) { 17131 event.preventDefault(); 17132 } 17133 17134 if (!this._isShown || this._isTransitioning) { 17135 return; 17136 } 17137 17138 var hideEvent = $.Event(Event$5.HIDE); 17139 $(this._element).trigger(hideEvent); 17140 17141 if (!this._isShown || hideEvent.isDefaultPrevented()) { 17142 return; 17143 } 17144 17145 this._isShown = false; 17146 var transition = $(this._element).hasClass(ClassName$5.FADE); 17147 17148 if (transition) { 17149 this._isTransitioning = true; 17150 } 17151 17152 this._setEscapeEvent(); 17153 17154 this._setResizeEvent(); 17155 17156 $(document).off(Event$5.FOCUSIN); 17157 $(this._element).removeClass(ClassName$5.SHOW); 17158 $(this._element).off(Event$5.CLICK_DISMISS); 17159 $(this._dialog).off(Event$5.MOUSEDOWN_DISMISS); 17160 17161 if (transition) { 17162 var transitionDuration = Util.getTransitionDurationFromElement(this._element); 17163 $(this._element).one(Util.TRANSITION_END, function (event) { 17164 return _this2._hideModal(event); 17165 }).emulateTransitionEnd(transitionDuration); 17166 } else { 17167 this._hideModal(); 17168 } 17169 }; 17170 17171 _proto.dispose = function dispose() { 17172 [window, this._element, this._dialog].forEach(function (htmlElement) { 17173 return $(htmlElement).off(EVENT_KEY$5); 17174 }); 17175 /** 17176 * `document` has 2 events `Event.FOCUSIN` and `Event.CLICK_DATA_API` 17177 * Do not move `document` in `htmlElements` array 17178 * It will remove `Event.CLICK_DATA_API` event that should remain 17179 */ 17180 17181 $(document).off(Event$5.FOCUSIN); 17182 $.removeData(this._element, DATA_KEY$5); 17183 this._config = null; 17184 this._element = null; 17185 this._dialog = null; 17186 this._backdrop = null; 17187 this._isShown = null; 17188 this._isBodyOverflowing = null; 17189 this._ignoreBackdropClick = null; 17190 this._isTransitioning = null; 17191 this._scrollbarWidth = null; 17192 }; 17193 17194 _proto.handleUpdate = function handleUpdate() { 17195 this._adjustDialog(); 17196 } // Private 17197 ; 17198 17199 _proto._getConfig = function _getConfig(config) { 17200 config = _objectSpread({}, Default$3, config); 17201 Util.typeCheckConfig(NAME$5, config, DefaultType$3); 17202 return config; 17203 }; 17204 17205 _proto._showElement = function _showElement(relatedTarget) { 17206 var _this3 = this; 17207 17208 var transition = $(this._element).hasClass(ClassName$5.FADE); 17209 17210 if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) { 17211 // Don't move modal's DOM position 17212 document.body.appendChild(this._element); 17213 } 17214 17215 this._element.style.display = 'block'; 17216 17217 this._element.removeAttribute('aria-hidden'); 17218 17219 this._element.setAttribute('aria-modal', true); 17220 17221 if ($(this._dialog).hasClass(ClassName$5.SCROLLABLE)) { 17222 this._dialog.querySelector(Selector$5.MODAL_BODY).scrollTop = 0; 17223 } else { 17224 this._element.scrollTop = 0; 17225 } 17226 17227 if (transition) { 17228 Util.reflow(this._element); 17229 } 17230 17231 $(this._element).addClass(ClassName$5.SHOW); 17232 17233 if (this._config.focus) { 17234 this._enforceFocus(); 17235 } 17236 17237 var shownEvent = $.Event(Event$5.SHOWN, { 17238 relatedTarget: relatedTarget 17239 }); 17240 17241 var transitionComplete = function transitionComplete() { 17242 if (_this3._config.focus) { 17243 _this3._element.focus(); 17244 } 17245 17246 _this3._isTransitioning = false;
17247 $(_this3._element).trigger(shownEvent); 17248 }; 17249 17250 if (transition) { 17251 var transitionDuration = Util.getTransitionDurationFromElement(this._dialog); 17252 $(this._dialog).one(Util.TRANSITION_END, transitionComplete).emulateTransitionEnd(transitionDuration); 17253 } else { 17254 transitionComplete(); 17255 } 17256 }; 17257 17258 _proto._enforceFocus = function _enforceFocus() { 17259 var _this4 = this; 17260 17261 $(document).off(Event$5.FOCUSIN) // Guard against infinite focus loop 17262 .on(Event$5.FOCUSIN, function (event) { 17263 if (document !== event.target && _this4._element !== event.target && $(_this4._element).has(event.target).length === 0) { 17264 _this4._element.focus(); 17265 } 17266 }); 17267 }; 17268 17269 _proto._setEscapeEvent = function _setEscapeEvent() { 17270 var _this5 = this; 17271 17272 if (this._isShown && this._config.keyboard) { 17273 $(this._element).on(Event$5.KEYDOWN_DISMISS, function (event) { 17274 if (event.which === ESCAPE_KEYCODE$1) { 17275 event.preventDefault(); 17276 17277 _this5.hide(); 17278 } 17279 }); 17280 } else if (!this._isShown) { 17281 $(this._element).off(Event$5.KEYDOWN_DISMISS); 17282 } 17283 }; 17284 17285 _proto._setResizeEvent = function _setResizeEvent() { 17286 var _this6 = this; 17287 17288 if (this._isShown) { 17289 $(window).on(Event$5.RESIZE, function (event) { 17290 return _this6.handleUpdate(event); 17291 }); 17292 } else { 17293 $(window).off(Event$5.RESIZE); 17294 } 17295 }; 17296 17297 _proto._hideModal = function _hideModal() { 17298 var _this7 = this; 17299 17300 this._element.style.display = 'none'; 17301 17302 this._element.setAttribute('aria-hidden', true); 17303 17304 this._element.removeAttribute('aria-modal'); 17305 17306 this._isTransitioning = false; 17307 17308 this._showBackdrop(function () { 17309 $(document.body).removeClass(ClassName$5.OPEN); 17310 17311 _this7._resetAdjustments(); 17312 17313 _this7._resetScrollbar(); 17314 17315 $(_this7._element).trigger(Event$5.HIDDEN); 17316 }); 17317 }; 17318 17319 _proto._removeBackdrop = function _removeBackdrop() { 17320 if (this._backdrop) { 17321 $(this._backdrop).remove(); 17322 this._backdrop = null; 17323 } 17324 }; 17325 17326 _proto._showBackdrop = function _showBackdrop(callback) { 17327 var _this8 = this; 17328 17329 var animate = $(this._element).hasClass(ClassName$5.FADE) ? ClassName$5.FADE : ''; 17330 17331 if (this._isShown && this._config.backdrop) { 17332 this._backdrop = document.createElement('div'); 17333 this._backdrop.className = ClassName$5.BACKDROP; 17334 17335 if (animate) { 17336 this._backdrop.classList.add(animate); 17337 } 17338 17339 $(this._backdrop).appendTo(document.body); 17340 $(this._element).on(Event$5.CLICK_DISMISS, function (event) { 17341 if (_this8._ignoreBackdropClick) { 17342 _this8._ignoreBackdropClick = false; 17343 return; 17344 } 17345 17346 if (event.target !== event.currentTarget) { 17347 return; 17348 } 17349 17350 if (_this8._config.backdrop === 'static') { 17351 _this8._element.focus(); 17352 } else { 17353 _this8.hide(); 17354 } 17355 }); 17356 17357 if (animate) { 17358 Util.reflow(this._backdrop); 17359 } 17360 17361 $(this._backdrop).addClass(ClassName$5.SHOW); 17362 17363 if (!callback) { 17364 return; 17365 } 17366 17367 if (!animate) { 17368 callback(); 17369 return; 17370 } 17371 17372 var backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop); 17373 $(this._backdrop).one(Util.TRANSITION_END, callback).emulateTransitionEnd(backdropTransitionDuration); 17374 } else if (!this._isShown && this._backdrop) { 17375 $(this._backdrop).removeClass(ClassName$5.SHOW); 17376 17377 var callbackRemove = function callbackRemove() { 17378 _this8._removeBackdrop(); 17379 17380 if (callback) { 17381 callback(); 17382 } 17383 }; 17384 17385 if ($(this._element).hasClass(ClassName$5.FADE)) { 17386 var _backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop); 17387 17388 $(this._backdrop).one(Util.TRANSITION_END, callbackRemove).emulateTransitionEnd(_backdropTransitionDuration); 17389 } else { 17390 callbackRemove(); 17391 } 17392 } else if (callback) { 17393 callback(); 17394 } 17395 } // ---------------------------------------------------------------------- 17396 // the following methods are used to handle overflowing modals 17397 // todo (fat): these should probably be refactored out of modal.js 17398 // ---------------------------------------------------------------------- 17399 ; 17400
17401 _proto._adjustDialog = function _adjustDialog() { 17402 var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; 17403 17404 if (!this._isBodyOverflowing && isModalOverflowing) { 17405 this._element.style.paddingLeft = this._scrollbarWidth + "px"; 17406 } 17407 17408 if (this._isBodyOverflowing && !isModalOverflowing) { 17409 this._element.style.paddingRight = this._scrollbarWidth + "px"; 17410 } 17411 }; 17412 17413 _proto._resetAdjustments = function _resetAdjustments() { 17414 this._element.style.paddingLeft = ''; 17415 this._element.style.paddingRight = ''; 17416 }; 17417 17418 _proto._checkScrollbar = function _checkScrollbar() { 17419 var rect = document.body.getBoundingClientRect(); 17420 this._isBodyOverflowing = rect.left + rect.right < window.innerWidth; 17421 this._scrollbarWidth = this._getScrollbarWidth(); 17422 }; 17423 17424 _proto._setScrollbar = function _setScrollbar() { 17425 var _this9 = this; 17426 17427 if (this._isBodyOverflowing) { 17428 // Note: DOMNode.style.paddingRight returns the actual value or '' if not set 17429 // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set 17430 var fixedContent = [].slice.call(document.querySelectorAll(Selector$5.FIXED_CONTENT)); 17431 var stickyContent = [].slice.call(document.querySelectorAll(Selector$5.STICKY_CONTENT)); // Adjust fixed content padding 17432 17433 $(fixedContent).each(function (index, element) { 17434 var actualPadding = element.style.paddingRight; 17435 var calculatedPadding = $(element).css('padding-right'); 17436 $(element).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + _this9._scrollbarWidth + "px"); 17437 }); // Adjust sticky content margin 17438 17439 $(stickyContent).each(function (index, element) { 17440 var actualMargin = element.style.marginRight; 17441 var calculatedMargin = $(element).css('margin-right'); 17442 $(element).data('margin-right', actualMargin).css('margin-right', parseFloat(calculatedMargin) - _this9._scrollbarWidth + "px"); 17443 }); // Adjust body padding 17444 17445 var actualPadding = document.body.style.paddingRight; 17446 var calculatedPadding = $(document.body).css('padding-right'); 17447 $(document.body).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + this._scrollbarWidth + "px"); 17448 } 17449 17450 $(document.body).addClass(ClassName$5.OPEN); 17451 }; 17452 17453 _proto._resetScrollbar = function _resetScrollbar() { 17454 // Restore fixed content padding 17455 var fixedContent = [].slice.call(document.querySelectorAll(Selector$5.FIXED_CONTENT)); 17456 $(fixedContent).each(function (index, element) { 17457 var padding = $(element).data('padding-right'); 17458 $(element).removeData('padding-right'); 17459 element.style.paddingRight = padding ? padding : ''; 17460 }); // Restore sticky content 17461 17462 var elements = [].slice.call(document.querySelectorAll("" + Selector$5.STICKY_CONTENT)); 17463 $(elements).each(function (index, element) { 17464 var margin = $(element).data('margin-right'); 17465 17466 if (typeof margin !== 'undefined') { 17467 $(element).css('margin-right', margin).removeData('margin-right'); 17468 } 17469 }); // Restore body padding 17470 17471 var padding = $(document.body).data('padding-right'); 17472 $(document.body).removeData('padding-right'); 17473 document.body.style.paddingRight = padding ? padding : ''; 17474 }; 17475 17476 _proto._getScrollbarWidth = function _getScrollbarWidth() { 17477 // thx d.walsh 17478 var scrollDiv = document.createElement('div'); 17479 scrollDiv.className = ClassName$5.SCROLLBAR_MEASURER; 17480 document.body.appendChild(scrollDiv); 17481 var scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth; 17482 document.body.removeChild(scrollDiv); 17483 return scrollbarWidth; 17484 } // Static 17485 ; 17486 17487 Modal._jQueryInterface = function _jQueryInterface(config, relatedTarget) { 17488 return this.each(function () { 17489 var data = $(this).data(DATA_KEY$5); 17490 17491 var _config = _objectSpread({}, Default$3, $(this).data(), typeof config === 'object' && config ? config : {}); 17492 17493 if (!data) { 17494 data = new Modal(this, _config); 17495 $(this).data(DATA_KEY$5, data); 17496 } 17497 17498 if (typeof config === 'string') { 17499 if (typeof data[config] === 'undefined') {
17500 throw new TypeError("No method named \"" + config + "\""); 17501 } 17502 17503 data[config](relatedTarget); 17504 } else if (_config.show) { 17505 data.show(relatedTarget); 17506 } 17507 }); 17508 }; 17509 17510 _createClass(Modal, null, [{ 17511 key: "VERSION", 17512 get: function get() { 17513 return VERSION$5; 17514 } 17515 }, { 17516 key: "Default", 17517 get: function get() { 17518 return Default$3; 17519 } 17520 }]); 17521 17522 return Modal; 17523 }(); 17524 /** 17525 * ------------------------------------------------------------------------ 17526 * Data Api implementation 17527 * ------------------------------------------------------------------------ 17528 */ 17529 17530 17531 $(document).on(Event$5.CLICK_DATA_API, Selector$5.DATA_TOGGLE, function (event) { 17532 var _this10 = this; 17533 17534 var target; 17535 var selector = Util.getSelectorFromElement(this); 17536 17537 if (selector) { 17538 target = document.querySelector(selector); 17539 } 17540 17541 var config = $(target).data(DATA_KEY$5) ? 'toggle' : _objectSpread({}, $(target).data(), $(this).data()); 17542 17543 if (this.tagName === 'A' || this.tagName === 'AREA') { 17544 event.preventDefault(); 17545 } 17546 17547 var $target = $(target).one(Event$5.SHOW, function (showEvent) { 17548 if (showEvent.isDefaultPrevented()) { 17549 // Only register focus restorer if modal will actually get shown 17550 return; 17551 } 17552 17553 $target.one(Event$5.HIDDEN, function () { 17554 if ($(_this10).is(':visible')) { 17555 _this10.focus(); 17556 } 17557 }); 17558 }); 17559 17560 Modal._jQueryInterface.call($(target), config, this); 17561 }); 17562 /** 17563 * ------------------------------------------------------------------------ 17564 * jQuery 17565 * ------------------------------------------------------------------------ 17566 */ 17567 17568 $.fn[NAME$5] = Modal._jQueryInterface; 17569 $.fn[NAME$5].Constructor = Modal; 17570 17571 $.fn[NAME$5].noConflict = function () { 17572 $.fn[NAME$5] = JQUERY_NO_CONFLICT$5; 17573 return Modal._jQueryInterface; 17574 }; 17575 17576 /** 17577 * -------------------------------------------------------------------------- 17578 * Bootstrap (v4.3.1): tools/sanitizer.js 17579 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 17580 * -------------------------------------------------------------------------- 17581 */ 17582 var uriAttrs = ['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']; 17583 var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i; 17584 var DefaultWhitelist = { 17585 // Global attributes allowed on any supplied element below. 17586 '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN], 17587 a: ['target', 'href', 'title', 'rel'], 17588 area: [], 17589 b: [], 17590 br: [], 17591 col: [], 17592 code: [], 17593 div: [], 17594 em: [], 17595 hr: [], 17596 h1: [], 17597 h2: [], 17598 h3: [], 17599 h4: [], 17600 h5: [], 17601 h6: [], 17602 i: [], 17603 img: ['src', 'alt', 'title', 'width', 'height'], 17604 li: [], 17605 ol: [], 17606 p: [], 17607 pre: [], 17608 s: [], 17609 small: [], 17610 span: [], 17611 sub: [], 17612 sup: [], 17613 strong: [], 17614 u: [], 17615 ul: [] 17616 /** 17617 * A pattern that recognizes a commonly useful subset of URLs that are safe. 17618 * 17619 * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts 17620 */ 17621 17622 }; 17623 var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi; 17624 /** 17625 * A pattern that matches safe data URLs. Only matches image, video and audio types. 17626 * 17627 * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts 17628 */ 17629 17630 var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i; 17631 17632 function allowedAttribute(attr, allowedAttributeList) { 17633 var attrName = attr.nodeName.toLowerCase(); 17634 17635 if (allowedAttributeList.indexOf(attrName) !== -1) { 17636 if (uriAttrs.indexOf(attrName) !== -1) { 17637 return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN)); 17638 } 17639 17640 return true; 17641 } 17642 17643 var regExp = allowedAttributeList.filter(function (attrRegex) {
vendor: 4,926 bytes, lines 17644-17825
17644 return attrRegex instanceof RegExp; 17645 }); // Check if a regular expression validates the attribute. 17646 17647 for (var i = 0, l = regExp.length; i < l; i++) { 17648 if (attrName.match(regExp[i])) { 17649 return true; 17650 } 17651 } 17652 17653 return false; 17654 } 17655 17656 function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) { 17657 if (unsafeHtml.length === 0) { 17658 return unsafeHtml; 17659 } 17660 17661 if (sanitizeFn && typeof sanitizeFn === 'function') { 17662 return sanitizeFn(unsafeHtml); 17663 } 17664 17665 var domParser = new window.DOMParser(); 17666 var createdDocument = domParser.parseFromString(unsafeHtml, 'text/html'); 17667 var whitelistKeys = Object.keys(whiteList); 17668 var elements = [].slice.call(createdDocument.body.querySelectorAll('*')); 17669 17670 var _loop = function _loop(i, len) { 17671 var el = elements[i]; 17672 var elName = el.nodeName.toLowerCase(); 17673 17674 if (whitelistKeys.indexOf(el.nodeName.toLowerCase()) === -1) { 17675 el.parentNode.removeChild(el); 17676 return "continue"; 17677 } 17678 17679 var attributeList = [].slice.call(el.attributes); 17680 var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || []); 17681 attributeList.forEach(function (attr) { 17682 if (!allowedAttribute(attr, whitelistedAttributes)) { 17683 el.removeAttribute(attr.nodeName); 17684 } 17685 }); 17686 }; 17687 17688 for (var i = 0, len = elements.length; i < len; i++) { 17689 var _ret = _loop(i, len); 17690 17691 if (_ret === "continue") continue; 17692 } 17693 17694 return createdDocument.body.innerHTML; 17695 } 17696 17697 /** 17698 * ------------------------------------------------------------------------ 17699 * Constants 17700 * ------------------------------------------------------------------------ 17701 */ 17702 17703 var NAME$6 = 'tooltip'; 17704 var VERSION$6 = '4.3.1'; 17705 var DATA_KEY$6 = 'bs.tooltip'; 17706 var EVENT_KEY$6 = "." + DATA_KEY$6; 17707 var JQUERY_NO_CONFLICT$6 = $.fn[NAME$6]; 17708 var CLASS_PREFIX = 'bs-tooltip'; 17709 var BSCLS_PREFIX_REGEX = new RegExp("(^|\\s)" + CLASS_PREFIX + "\\S+", 'g'); 17710 var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']; 17711 var DefaultType$4 = { 17712 animation: 'boolean', 17713 template: 'string', 17714 title: '(string|element|function)', 17715 trigger: 'string', 17716 delay: '(number|object)', 17717 html: 'boolean', 17718 selector: '(string|boolean)', 17719 placement: '(string|function)', 17720 offset: '(number|string|function)', 17721 container: '(string|element|boolean)', 17722 fallbackPlacement: '(string|array)', 17723 boundary: '(string|element)', 17724 sanitize: 'boolean', 17725 sanitizeFn: '(null|function)', 17726 whiteList: 'object' 17727 }; 17728 var AttachmentMap$1 = { 17729 AUTO: 'auto', 17730 TOP: 'top', 17731 RIGHT: 'right', 17732 BOTTOM: 'bottom', 17733 LEFT: 'left' 17734 }; 17735 var Default$4 = { 17736 animation: true, 17737 template: '<div class="tooltip" role="tooltip">' + '<div class="arrow"></div>' + '<div class="tooltip-inner"></div></div>', 17738 trigger: 'hover focus', 17739 title: '', 17740 delay: 0, 17741 html: false, 17742 selector: false, 17743 placement: 'top', 17744 offset: 0, 17745 container: false, 17746 fallbackPlacement: 'flip', 17747 boundary: 'scrollParent', 17748 sanitize: true, 17749 sanitizeFn: null, 17750 whiteList: DefaultWhitelist 17751 }; 17752 var HoverState = { 17753 SHOW: 'show', 17754 OUT: 'out' 17755 }; 17756 var Event$6 = { 17757 HIDE: "hide" + EVENT_KEY$6, 17758 HIDDEN: "hidden" + EVENT_KEY$6, 17759 SHOW: "show" + EVENT_KEY$6, 17760 SHOWN: "shown" + EVENT_KEY$6, 17761 INSERTED: "inserted" + EVENT_KEY$6, 17762 CLICK: "click" + EVENT_KEY$6, 17763 FOCUSIN: "focusin" + EVENT_KEY$6, 17764 FOCUSOUT: "focusout" + EVENT_KEY$6, 17765 MOUSEENTER: "mouseenter" + EVENT_KEY$6, 17766 MOUSELEAVE: "mouseleave" + EVENT_KEY$6 17767 }; 17768 var ClassName$6 = { 17769 FADE: 'fade', 17770 SHOW: 'show' 17771 }; 17772 var Selector$6 = { 17773 TOOLTIP: '.tooltip', 17774 TOOLTIP_INNER: '.tooltip-inner', 17775 ARROW: '.arrow' 17776 }; 17777 var Trigger = { 17778 HOVER: 'hover', 17779 FOCUS: 'focus', 17780 CLICK: 'click', 17781 MANUAL: 'manual' 17782 /** 17783 * ------------------------------------------------------------------------ 17784 * Class Definition 17785 * ------------------------------------------------------------------------ 17786 */ 17787 17788 }; 17789 17790 var Tooltip = 17791 /*#__PURE__*/ 17792 function () { 17793 function Tooltip(element, config) { 17794 /** 17795 * Check for Popper dependency 17796 * Popper - https://popper.js.org 17797 */ 17798 if (typeof Popper === 'undefined') { 17799 throw new TypeError('Bootstrap\'s tooltips require Popper.js (https://popper.js.org/)'); 17800 } // private 17801 17802 17803 this._isEnabled = true; 17804 this._timeout = 0; 17805 this._hoverState = ''; 17806 this._activeTrigger = {}; 17807 this._popper = null; // Protected 17808 17809 this.element = element; 17810 this.config = this._getConfig(config); 17811 this.tip = null; 17812 17813 this._setListeners(); 17814 } // Getters 17815 17816 17817 var _proto = Tooltip.prototype; 17818 17819 // Public 17820 _proto.enable = function enable() { 17821 this._isEnabled = true; 17822 }; 17823 17824 _proto.disable = function disable() { 17825 this._isEnabled = false;
17826 }; 17827 17828 _proto.toggleEnabled = function toggleEnabled() { 17829 this._isEnabled = !this._isEnabled; 17830 }; 17831 17832 _proto.toggle = function toggle(event) { 17833 if (!this._isEnabled) { 17834 return; 17835 } 17836 17837 if (event) { 17838 var dataKey = this.constructor.DATA_KEY; 17839 var context = $(event.currentTarget).data(dataKey); 17840 17841 if (!context) { 17842 context = new this.constructor(event.currentTarget, this._getDelegateConfig()); 17843 $(event.currentTarget).data(dataKey, context); 17844 } 17845 17846 context._activeTrigger.click = !context._activeTrigger.click; 17847 17848 if (context._isWithActiveTrigger()) { 17849 context._enter(null, context); 17850 } else { 17851 context._leave(null, context); 17852 } 17853 } else { 17854 if ($(this.getTipElement()).hasClass(ClassName$6.SHOW)) { 17855 this._leave(null, this); 17856 17857 return; 17858 } 17859 17860 this._enter(null, this); 17861 } 17862 }; 17863 17864 _proto.dispose = function dispose() { 17865 clearTimeout(this._timeout); 17866 $.removeData(this.element, this.constructor.DATA_KEY); 17867 $(this.element).off(this.constructor.EVENT_KEY); 17868 $(this.element).closest('.modal').off('hide.bs.modal'); 17869 17870 if (this.tip) { 17871 $(this.tip).remove(); 17872 } 17873 17874 this._isEnabled = null; 17875 this._timeout = null; 17876 this._hoverState = null; 17877 this._activeTrigger = null; 17878 17879 if (this._popper !== null) { 17880 this._popper.destroy(); 17881 } 17882 17883 this._popper = null; 17884 this.element = null; 17885 this.config = null; 17886 this.tip = null; 17887 }; 17888 17889 _proto.show = function show() { 17890 var _this = this; 17891 17892 if ($(this.element).css('display') === 'none') { 17893 throw new Error('Please use show on visible elements'); 17894 } 17895 17896 var showEvent = $.Event(this.constructor.Event.SHOW); 17897 17898 if (this.isWithContent() && this._isEnabled) { 17899 $(this.element).trigger(showEvent); 17900 var shadowRoot = Util.findShadowRoot(this.element); 17901 var isInTheDom = $.contains(shadowRoot !== null ? shadowRoot : this.element.ownerDocument.documentElement, this.element); 17902 17903 if (showEvent.isDefaultPrevented() || !isInTheDom) { 17904 return; 17905 } 17906 17907 var tip = this.getTipElement(); 17908 var tipId = Util.getUID(this.constructor.NAME);
17909 tip.setAttribute('id', tipId); 17910 this.element.setAttribute('aria-describedby', tipId); 17911 this.setContent(); 17912 17913 if (this.config.animation) { 17914 $(tip).addClass(ClassName$6.FADE); 17915 } 17916 17917 var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this.element) : this.config.placement; 17918 17919 var attachment = this._getAttachment(placement); 17920 17921 this.addAttachmentClass(attachment); 17922 17923 var container = this._getContainer(); 17924 17925 $(tip).data(this.constructor.DATA_KEY, this); 17926 17927 if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) { 17928 $(tip).appendTo(container); 17929 } 17930 17931 $(this.element).trigger(this.constructor.Event.INSERTED); 17932 this._popper = new Popper(this.element, tip, { 17933 placement: attachment, 17934 modifiers: { 17935 offset: this._getOffset(), 17936 flip: { 17937 behavior: this.config.fallbackPlacement 17938 }, 17939 arrow: { 17940 element: Selector$6.ARROW 17941 }, 17942 preventOverflow: { 17943 boundariesElement: this.config.boundary 17944 } 17945 }, 17946 onCreate: function onCreate(data) { 17947 if (data.originalPlacement !== data.placement) { 17948 _this._handlePopperPlacementChange(data); 17949 } 17950 }, 17951 onUpdate: function onUpdate(data) { 17952 return _this._handlePopperPlacementChange(data); 17953 } 17954 }); 17955 $(tip).addClass(ClassName$6.SHOW); // If this is a touch-enabled device we add extra 17956 // empty mouseover listeners to the body's immediate children; 17957 // only needed because of broken event delegation on iOS 17958 // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html 17959 17960 if ('ontouchstart' in document.documentElement) { 17961 $(document.body).children().on('mouseover', null, $.noop); 17962 } 17963 17964 var complete = function complete() { 17965 if (_this.config.animation) { 17966 _this._fixTransition(); 17967 } 17968 17969 var prevHoverState = _this._hoverState; 17970 _this._hoverState = null; 17971 $(_this.element).trigger(_this.constructor.Event.SHOWN); 17972 17973 if (prevHoverState === HoverState.OUT) { 17974 _this._leave(null, _this); 17975 } 17976 }; 17977 17978 if ($(this.tip).hasClass(ClassName$6.FADE)) { 17979 var transitionDuration = Util.getTransitionDurationFromElement(this.tip); 17980 $(this.tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); 17981 } else { 17982 complete(); 17983 } 17984 } 17985 }; 17986 17987 _proto.hide = function hide(callback) { 17988 var _this2 = this; 17989 17990 var tip = this.getTipElement(); 17991 var hideEvent = $.Event(this.constructor.Event.HIDE); 17992 17993 var complete = function complete() { 17994 if (_this2._hoverState !== HoverState.SHOW && tip.parentNode) { 17995 tip.parentNode.removeChild(tip); 17996 } 17997 17998 _this2._cleanTipClass(); 17999 18000 _this2.element.removeAttribute('aria-describedby'); 18001 18002 $(_this2.element).trigger(_this2.constructor.Event.HIDDEN); 18003 18004 if (_this2._popper !== null) { 18005 _this2._popper.destroy(); 18006 } 18007 18008 if (callback) { 18009 callback(); 18010 } 18011 }; 18012 18013 $(this.element).trigger(hideEvent); 18014 18015 if (hideEvent.isDefaultPrevented()) { 18016 return; 18017 } 18018 18019 $(tip).removeClass(ClassName$6.SHOW); // If this is a touch-enabled device we remove the extra 18020 // empty mouseover listeners we added for iOS support 18021 18022 if ('ontouchstart' in document.documentElement) { 18023 $(document.body).children().off('mouseover', null, $.noop); 18024 } 18025 18026 this._activeTrigger[Trigger.CLICK] = false; 18027 this._activeTrigger[Trigger.FOCUS] = false; 18028 this._activeTrigger[Trigger.HOVER] = false; 18029 18030 if ($(this.tip).hasClass(ClassName$6.FADE)) { 18031 var transitionDuration = Util.getTransitionDurationFromElement(tip); 18032 $(tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); 18033 } else { 18034 complete(); 18035 } 18036 18037 this._hoverState = ''; 18038 }; 18039
18040 _proto.update = function update() { 18041 if (this._popper !== null) { 18042 this._popper.scheduleUpdate(); 18043 } 18044 } // Protected 18045 ; 18046 18047 _proto.isWithContent = function isWithContent() { 18048 return Boolean(this.getTitle()); 18049 }; 18050 18051 _proto.addAttachmentClass = function addAttachmentClass(attachment) { 18052 $(this.getTipElement()).addClass(CLASS_PREFIX + "-" + attachment); 18053 }; 18054 18055 _proto.getTipElement = function getTipElement() { 18056 this.tip = this.tip || $(this.config.template)[0]; 18057 return this.tip; 18058 }; 18059 18060 _proto.setContent = function setContent() { 18061 var tip = this.getTipElement(); 18062 this.setElementContent($(tip.querySelectorAll(Selector$6.TOOLTIP_INNER)), this.getTitle()); 18063 $(tip).removeClass(ClassName$6.FADE + " " + ClassName$6.SHOW); 18064 }; 18065 18066 _proto.setElementContent = function setElementContent($element, content) { 18067 if (typeof content === 'object' && (content.nodeType || content.jquery)) { 18068 // Content is a DOM node or a jQuery 18069 if (this.config.html) { 18070 if (!$(content).parent().is($element)) { 18071 $element.empty().append(content); 18072 } 18073 } else { 18074 $element.text($(content).text()); 18075 } 18076 18077 return; 18078 } 18079 18080 if (this.config.html) { 18081 if (this.config.sanitize) { 18082 content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn); 18083 } 18084 18085 $element.html(content); 18086 } else { 18087 $element.text(content); 18088 } 18089 }; 18090 18091 _proto.getTitle = function getTitle() { 18092 var title = this.element.getAttribute('data-original-title'); 18093 18094 if (!title) { 18095 title = typeof this.config.title === 'function' ? this.config.title.call(this.element) : this.config.title; 18096 } 18097 18098 return title; 18099 } // Private 18100 ; 18101 18102 _proto._getOffset = function _getOffset() { 18103 var _this3 = this; 18104 18105 var offset = {}; 18106 18107 if (typeof this.config.offset === 'function') { 18108 offset.fn = function (data) { 18109 data.offsets = _objectSpread({}, data.offsets, _this3.config.offset(data.offsets, _this3.element) || {}); 18110 return data; 18111 }; 18112 } else { 18113 offset.offset = this.config.offset; 18114 } 18115 18116 return offset; 18117 }; 18118 18119 _proto._getContainer = function _getContainer() { 18120 if (this.config.container === false) { 18121 return document.body; 18122 } 18123 18124 if (Util.isElement(this.config.container)) { 18125 return $(this.config.container); 18126 } 18127 18128 return $(document).find(this.config.container); 18129 }; 18130 18131 _proto._getAttachment = function _getAttachment(placement) { 18132 return AttachmentMap$1[placement.toUpperCase()]; 18133 }; 18134 18135 _proto._setListeners = function _setListeners() { 18136 var _this4 = this; 18137 18138 var triggers = this.config.trigger.split(' '); 18139 triggers.forEach(function (trigger) { 18140 if (trigger === 'click') { 18141 $(_this4.element).on(_this4.constructor.Event.CLICK, _this4.config.selector, function (event) { 18142 return _this4.toggle(event); 18143 }); 18144 } else if (trigger !== Trigger.MANUAL) { 18145 var eventIn = trigger === Trigger.HOVER ? _this4.constructor.Event.MOUSEENTER : _this4.constructor.Event.FOCUSIN; 18146 var eventOut = trigger === Trigger.HOVER ? _this4.constructor.Event.MOUSELEAVE : _this4.constructor.Event.FOCUSOUT; 18147 $(_this4.element).on(eventIn, _this4.config.selector, function (event) { 18148 return _this4._enter(event); 18149 }).on(eventOut, _this4.config.selector, function (event) { 18150 return _this4._leave(event); 18151 }); 18152 } 18153 }); 18154 $(this.element).closest('.modal').on('hide.bs.modal', function () { 18155 if (_this4.element) { 18156 _this4.hide(); 18157 } 18158 }); 18159 18160 if (this.config.selector) { 18161 this.config = _objectSpread({}, this.config, { 18162 trigger: 'manual', 18163 selector: '' 18164 }); 18165 } else { 18166 this._fixTitle(); 18167 } 18168 }; 18169 18170 _proto._fixTitle = function _fixTitle() { 18171 var titleType = typeof this.element.getAttribute('data-original-title'); 18172 18173 if (this.element.getAttribute('title') || titleType !== 'string') { 18174 this.element.setAttribute('data-original-title', this.element.getAttribute('title') || ''); 18175 this.element.setAttribute('title', ''); 18176 } 18177 }; 18178 18179 _proto._enter = function _enter(event, context) { 18180 var dataKey = this.constructor.DATA_KEY; 18181 context = context || $(event.currentTarget).data(dataKey); 18182 18183 if (!context) { 18184 context = new this.constructor(event.currentTarget, this._getDelegateConfig()); 18185 $(event.currentTarget).data(dataKey, context); 18186 } 18187 18188 if (event) { 18189 context._activeTrigger[event.type === 'focusin' ? Trigger.FOCUS : Trigger.HOVER] = true; 18190 } 18191 18192 if ($(context.getTipElement()).hasClass(ClassName$6.SHOW) || context._hoverState === HoverState.SHOW) { 18193 context._hoverState = HoverState.SHOW; 18194 return; 18195 } 18196 18197 clearTimeout(context._timeout); 18198 context._hoverState = HoverState.SHOW; 18199 18200 if (!context.config.delay || !context.config.delay.show) { 18201 context.show(); 18202 return; 18203 } 18204 18205 context._timeout = setTimeout(function () { 18206 if (context._hoverState === HoverState.SHOW) { 18207 context.show(); 18208 } 18209 }, context.config.delay.show); 18210 }; 18211 18212 _proto._leave = function _leave(event, context) { 18213 var dataKey = this.constructor.DATA_KEY; 18214 context = context || $(event.currentTarget).data(dataKey); 18215 18216 if (!context) { 18217 context = new this.constructor(event.currentTarget, this._getDelegateConfig()); 18218 $(event.currentTarget).data(dataKey, context); 18219 } 18220 18221 if (event) { 18222 context._activeTrigger[event.type === 'focusout' ? Trigger.FOCUS : Trigger.HOVER] = false;
vendor: 4,166 bytes, lines 18223-18385
18223 } 18224 18225 if (context._isWithActiveTrigger()) { 18226 return; 18227 } 18228 18229 clearTimeout(context._timeout); 18230 context._hoverState = HoverState.OUT; 18231 18232 if (!context.config.delay || !context.config.delay.hide) { 18233 context.hide(); 18234 return; 18235 } 18236 18237 context._timeout = setTimeout(function () { 18238 if (context._hoverState === HoverState.OUT) { 18239 context.hide(); 18240 } 18241 }, context.config.delay.hide); 18242 }; 18243 18244 _proto._isWithActiveTrigger = function _isWithActiveTrigger() { 18245 for (var trigger in this._activeTrigger) { 18246 if (this._activeTrigger[trigger]) { 18247 return true; 18248 } 18249 } 18250 18251 return false; 18252 }; 18253 18254 _proto._getConfig = function _getConfig(config) { 18255 var dataAttributes = $(this.element).data(); 18256 Object.keys(dataAttributes).forEach(function (dataAttr) { 18257 if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) { 18258 delete dataAttributes[dataAttr]; 18259 } 18260 }); 18261 config = _objectSpread({}, this.constructor.Default, dataAttributes, typeof config === 'object' && config ? config : {}); 18262 18263 if (typeof config.delay === 'number') { 18264 config.delay = { 18265 show: config.delay, 18266 hide: config.delay 18267 }; 18268 } 18269 18270 if (typeof config.title === 'number') { 18271 config.title = config.title.toString(); 18272 } 18273 18274 if (typeof config.content === 'number') { 18275 config.content = config.content.toString(); 18276 } 18277 18278 Util.typeCheckConfig(NAME$6, config, this.constructor.DefaultType); 18279 18280 if (config.sanitize) { 18281 config.template = sanitizeHtml(config.template, config.whiteList, config.sanitizeFn); 18282 } 18283 18284 return config; 18285 }; 18286 18287 _proto._getDelegateConfig = function _getDelegateConfig() { 18288 var config = {}; 18289 18290 if (this.config) { 18291 for (var key in this.config) { 18292 if (this.constructor.Default[key] !== this.config[key]) { 18293 config[key] = this.config[key]; 18294 } 18295 } 18296 } 18297 18298 return config; 18299 }; 18300 18301 _proto._cleanTipClass = function _cleanTipClass() { 18302 var $tip = $(this.getTipElement()); 18303 var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX); 18304 18305 if (tabClass !== null && tabClass.length) { 18306 $tip.removeClass(tabClass.join('')); 18307 } 18308 }; 18309 18310 _proto._handlePopperPlacementChange = function _handlePopperPlacementChange(popperData) { 18311 var popperInstance = popperData.instance; 18312 this.tip = popperInstance.popper; 18313 18314 this._cleanTipClass(); 18315 18316 this.addAttachmentClass(this._getAttachment(popperData.placement)); 18317 }; 18318 18319 _proto._fixTransition = function _fixTransition() { 18320 var tip = this.getTipElement(); 18321 var initConfigAnimation = this.config.animation; 18322 18323 if (tip.getAttribute('x-placement') !== null) { 18324 return; 18325 } 18326 18327 $(tip).removeClass(ClassName$6.FADE); 18328 this.config.animation = false; 18329 this.hide(); 18330 this.show(); 18331 this.config.animation = initConfigAnimation; 18332 } // Static 18333 ; 18334 18335 Tooltip._jQueryInterface = function _jQueryInterface(config) { 18336 return this.each(function () { 18337 var data = $(this).data(DATA_KEY$6); 18338 18339 var _config = typeof config === 'object' && config; 18340 18341 if (!data && /dispose|hide/.test(config)) { 18342 return; 18343 } 18344 18345 if (!data) { 18346 data = new Tooltip(this, _config); 18347 $(this).data(DATA_KEY$6, data); 18348 } 18349 18350 if (typeof config === 'string') { 18351 if (typeof data[config] === 'undefined') { 18352 throw new TypeError("No method named \"" + config + "\""); 18353 } 18354 18355 data[config](); 18356 } 18357 }); 18358 }; 18359 18360 _createClass(Tooltip, null, [{ 18361 key: "VERSION", 18362 get: function get() { 18363 return VERSION$6; 18364 } 18365 }, { 18366 key: "Default", 18367 get: function get() { 18368 return Default$4; 18369 } 18370 }, { 18371 key: "NAME", 18372 get: function get() { 18373 return NAME$6; 18374 } 18375 }, { 18376 key: "DATA_KEY", 18377 get: function get() { 18378 return DATA_KEY$6; 18379 } 18380 }, { 18381 key: "Event", 18382 get: function get() { 18383 return Event$6; 18384 } 18385 }, {
18386 key: "EVENT_KEY", 18387 get: function get() { 18388 return EVENT_KEY$6; 18389 } 18390 }, { 18391 key: "DefaultType", 18392 get: function get() { 18393 return DefaultType$4; 18394 } 18395 }]); 18396 18397 return Tooltip; 18398 }(); 18399 /** 18400 * ------------------------------------------------------------------------ 18401 * jQuery 18402 * ------------------------------------------------------------------------ 18403 */ 18404 18405 18406 $.fn[NAME$6] = Tooltip._jQueryInterface; 18407 $.fn[NAME$6].Constructor = Tooltip; 18408 18409 $.fn[NAME$6].noConflict = function () { 18410 $.fn[NAME$6] = JQUERY_NO_CONFLICT$6; 18411 return Tooltip._jQueryInterface; 18412 }; 18413 18414 /** 18415 * ------------------------------------------------------------------------ 18416 * Constants 18417 * ------------------------------------------------------------------------ 18418 */ 18419 18420 var NAME$7 = 'popover'; 18421 var VERSION$7 = '4.3.1'; 18422 var DATA_KEY$7 = 'bs.popover'; 18423 var EVENT_KEY$7 = "." + DATA_KEY$7; 18424 var JQUERY_NO_CONFLICT$7 = $.fn[NAME$7]; 18425 var CLASS_PREFIX$1 = 'bs-popover'; 18426 var BSCLS_PREFIX_REGEX$1 = new RegExp("(^|\\s)" + CLASS_PREFIX$1 + "\\S+", 'g'); 18427 18428 var Default$5 = _objectSpread({}, Tooltip.Default, { 18429 placement: 'right', 18430 trigger: 'click', 18431 content: '', 18432 template: '<div class="popover" role="tooltip">' + '<div class="arrow"></div>' + '<h3 class="popover-header"></h3>' + '<div class="popover-body"></div></div>' 18433 }); 18434 18435 var DefaultType$5 = _objectSpread({}, Tooltip.DefaultType, { 18436 content: '(string|element|function)' 18437 }); 18438 18439 var ClassName$7 = { 18440 FADE: 'fade', 18441 SHOW: 'show' 18442 }; 18443 var Selector$7 = { 18444 TITLE: '.popover-header', 18445 CONTENT: '.popover-body' 18446 }; 18447 var Event$7 = { 18448 HIDE: "hide" + EVENT_KEY$7, 18449 HIDDEN: "hidden" + EVENT_KEY$7, 18450 SHOW: "show" + EVENT_KEY$7, 18451 SHOWN: "shown" + EVENT_KEY$7, 18452 INSERTED: "inserted" + EVENT_KEY$7, 18453 CLICK: "click" + EVENT_KEY$7, 18454 FOCUSIN: "focusin" + EVENT_KEY$7, 18455 FOCUSOUT: "focusout" + EVENT_KEY$7, 18456 MOUSEENTER: "mouseenter" + EVENT_KEY$7, 18457 MOUSELEAVE: "mouseleave" + EVENT_KEY$7 18458 /** 18459 * ------------------------------------------------------------------------ 18460 * Class Definition 18461 * ------------------------------------------------------------------------ 18462 */ 18463 18464 }; 18465 18466 var Popover = 18467 /*#__PURE__*/ 18468 function (_Tooltip) { 18469 _inheritsLoose(Popover, _Tooltip); 18470 18471 function Popover() { 18472 return _Tooltip.apply(this, arguments) || this; 18473 } 18474 18475 var _proto = Popover.prototype; 18476 18477 // Overrides 18478 _proto.isWithContent = function isWithContent() { 18479 return this.getTitle() || this._getContent(); 18480 }; 18481 18482 _proto.addAttachmentClass = function addAttachmentClass(attachment) { 18483 $(this.getTipElement()).addClass(CLASS_PREFIX$1 + "-" + attachment); 18484 }; 18485 18486 _proto.getTipElement = function getTipElement() { 18487 this.tip = this.tip || $(this.config.template)[0]; 18488 return this.tip; 18489 }; 18490 18491 _proto.setContent = function setContent() { 18492 var $tip = $(this.getTipElement()); // We use append for html objects to maintain js events 18493 18494 this.setElementContent($tip.find(Selector$7.TITLE), this.getTitle()); 18495 18496 var content = this._getContent(); 18497 18498 if (typeof content === 'function') { 18499 content = content.call(this.element); 18500 } 18501 18502 this.setElementContent($tip.find(Selector$7.CONTENT), content); 18503 $tip.removeClass(ClassName$7.FADE + " " + ClassName$7.SHOW); 18504 } // Private 18505 ; 18506 18507 _proto._getContent = function _getContent() { 18508 return this.element.getAttribute('data-content') || this.config.content; 18509 }; 18510 18511 _proto._cleanTipClass = function _cleanTipClass() { 18512 var $tip = $(this.getTipElement()); 18513 var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX$1); 18514 18515 if (tabClass !== null && tabClass.length > 0) { 18516 $tip.removeClass(tabClass.join('')); 18517 } 18518 } // Static 18519 ; 18520 18521 Popover._jQueryInterface = function _jQueryInterface(config) { 18522 return this.each(function () { 18523 var data = $(this).data(DATA_KEY$7); 18524 18525 var _config = typeof config === 'object' ? config : null; 18526 18527 if (!data && /dispose|hide/.test(config)) { 18528 return; 18529 } 18530 18531 if (!data) { 18532 data = new Popover(this, _config); 18533 $(this).data(DATA_KEY$7, data); 18534 } 18535 18536 if (typeof config === 'string') { 18537 if (typeof data[config] === 'undefined') {
18538 throw new TypeError("No method named \"" + config + "\""); 18539 } 18540 18541 data[config](); 18542 } 18543 }); 18544 }; 18545 18546 _createClass(Popover, null, [{ 18547 key: "VERSION", 18548 // Getters 18549 get: function get() { 18550 return VERSION$7; 18551 } 18552 }, { 18553 key: "Default", 18554 get: function get() { 18555 return Default$5; 18556 } 18557 }, { 18558 key: "NAME", 18559 get: function get() { 18560 return NAME$7; 18561 } 18562 }, { 18563 key: "DATA_KEY", 18564 get: function get() { 18565 return DATA_KEY$7; 18566 } 18567 }, { 18568 key: "Event", 18569 get: function get() { 18570 return Event$7; 18571 } 18572 }, { 18573 key: "EVENT_KEY", 18574 get: function get() { 18575 return EVENT_KEY$7; 18576 } 18577 }, { 18578 key: "DefaultType", 18579 get: function get() { 18580 return DefaultType$5; 18581 } 18582 }]); 18583 18584 return Popover; 18585 }(Tooltip); 18586 /** 18587 * ------------------------------------------------------------------------ 18588 * jQuery 18589 * ------------------------------------------------------------------------ 18590 */ 18591 18592 18593 $.fn[NAME$7] = Popover._jQueryInterface; 18594 $.fn[NAME$7].Constructor = Popover; 18595 18596 $.fn[NAME$7].noConflict = function () { 18597 $.fn[NAME$7] = JQUERY_NO_CONFLICT$7; 18598 return Popover._jQueryInterface; 18599 }; 18600 18601 /** 18602 * ------------------------------------------------------------------------ 18603 * Constants 18604 * ------------------------------------------------------------------------ 18605 */ 18606 18607 var NAME$8 = 'scrollspy'; 18608 var VERSION$8 = '4.3.1'; 18609 var DATA_KEY$8 = 'bs.scrollspy'; 18610 var EVENT_KEY$8 = "." + DATA_KEY$8; 18611 var DATA_API_KEY$6 = '.data-api'; 18612 var JQUERY_NO_CONFLICT$8 = $.fn[NAME$8]; 18613 var Default$6 = { 18614 offset: 10, 18615 method: 'auto', 18616 target: '' 18617 }; 18618 var DefaultType$6 = { 18619 offset: 'number', 18620 method: 'string', 18621 target: '(string|element)' 18622 }; 18623 var Event$8 = { 18624 ACTIVATE: "activate" + EVENT_KEY$8, 18625 SCROLL: "scroll" + EVENT_KEY$8, 18626 LOAD_DATA_API: "load" + EVENT_KEY$8 + DATA_API_KEY$6 18627 }; 18628 var ClassName$8 = { 18629 DROPDOWN_ITEM: 'dropdown-item', 18630 DROPDOWN_MENU: 'dropdown-menu', 18631 ACTIVE: 'active' 18632 }; 18633 var Selector$8 = { 18634 DATA_SPY: '[data-spy="scroll"]', 18635 ACTIVE: '.active', 18636 NAV_LIST_GROUP: '.nav, .list-group', 18637 NAV_LINKS: '.nav-link', 18638 NAV_ITEMS: '.nav-item', 18639 LIST_ITEMS: '.list-group-item', 18640 DROPDOWN: '.dropdown', 18641 DROPDOWN_ITEMS: '.dropdown-item', 18642 DROPDOWN_TOGGLE: '.dropdown-toggle' 18643 }; 18644 var OffsetMethod = { 18645 OFFSET: 'offset', 18646 POSITION: 'position' 18647 /** 18648 * ------------------------------------------------------------------------ 18649 * Class Definition 18650 * ------------------------------------------------------------------------ 18651 */ 18652 18653 }; 18654 18655 var ScrollSpy = 18656 /*#__PURE__*/ 18657 function () { 18658 function ScrollSpy(element, config) { 18659 var _this = this; 18660 18661 this._element = element; 18662 this._scrollElement = element.tagName === 'BODY' ? window : element; 18663 this._config = this._getConfig(config); 18664 this._selector = this._config.target + " " + Selector$8.NAV_LINKS + "," + (this._config.target + " " + Selector$8.LIST_ITEMS + ",") + (this._config.target + " " + Selector$8.DROPDOWN_ITEMS); 18665 this._offsets = []; 18666 this._targets = []; 18667 this._activeTarget = null; 18668 this._scrollHeight = 0; 18669 $(this._scrollElement).on(Event$8.SCROLL, function (event) { 18670 return _this._process(event); 18671 }); 18672 this.refresh(); 18673 18674 this._process(); 18675 } // Getters 18676 18677 18678 var _proto = ScrollSpy.prototype; 18679 18680 // Public 18681 _proto.refresh = function refresh() { 18682 var _this2 = this; 18683 18684 var autoMethod = this._scrollElement === this._scrollElement.window ? OffsetMethod.OFFSET : OffsetMethod.POSITION; 18685 var offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method; 18686 var offsetBase = offsetMethod === OffsetMethod.POSITION ? this._getScrollTop() : 0; 18687 this._offsets = []; 18688 this._targets = []; 18689 this._scrollHeight = this._getScrollHeight(); 18690 var targets = [].slice.call(document.querySelectorAll(this._selector)); 18691 targets.map(function (element) { 18692 var target; 18693 var targetSelector = Util.getSelectorFromElement(element); 18694
vendor: 4,133 bytes, lines 18695-18823
18695 if (targetSelector) { 18696 target = document.querySelector(targetSelector); 18697 } 18698 18699 if (target) { 18700 var targetBCR = target.getBoundingClientRect(); 18701 18702 if (targetBCR.width || targetBCR.height) { 18703 // TODO (fat): remove sketch reliance on jQuery position/offset 18704 return [$(target)[offsetMethod]().top + offsetBase, targetSelector]; 18705 } 18706 } 18707 18708 return null; 18709 }).filter(function (item) { 18710 return item; 18711 }).sort(function (a, b) { 18712 return a[0] - b[0]; 18713 }).forEach(function (item) { 18714 _this2._offsets.push(item[0]); 18715 18716 _this2._targets.push(item[1]); 18717 }); 18718 }; 18719 18720 _proto.dispose = function dispose() { 18721 $.removeData(this._element, DATA_KEY$8); 18722 $(this._scrollElement).off(EVENT_KEY$8); 18723 this._element = null; 18724 this._scrollElement = null; 18725 this._config = null; 18726 this._selector = null; 18727 this._offsets = null; 18728 this._targets = null; 18729 this._activeTarget = null; 18730 this._scrollHeight = null; 18731 } // Private 18732 ; 18733 18734 _proto._getConfig = function _getConfig(config) { 18735 config = _objectSpread({}, Default$6, typeof config === 'object' && config ? config : {}); 18736 18737 if (typeof config.target !== 'string') { 18738 var id = $(config.target).attr('id'); 18739 18740 if (!id) { 18741 id = Util.getUID(NAME$8); 18742 $(config.target).attr('id', id); 18743 } 18744 18745 config.target = "#" + id; 18746 } 18747 18748 Util.typeCheckConfig(NAME$8, config, DefaultType$6); 18749 return config; 18750 }; 18751 18752 _proto._getScrollTop = function _getScrollTop() { 18753 return this._scrollElement === window ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop; 18754 }; 18755 18756 _proto._getScrollHeight = function _getScrollHeight() { 18757 return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight); 18758 }; 18759 18760 _proto._getOffsetHeight = function _getOffsetHeight() { 18761 return this._scrollElement === window ? window.innerHeight : this._scrollElement.getBoundingClientRect().height; 18762 }; 18763 18764 _proto._process = function _process() { 18765 var scrollTop = this._getScrollTop() + this._config.offset; 18766 18767 var scrollHeight = this._getScrollHeight(); 18768 18769 var maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight(); 18770 18771 if (this._scrollHeight !== scrollHeight) { 18772 this.refresh(); 18773 } 18774 18775 if (scrollTop >= maxScroll) { 18776 var target = this._targets[this._targets.length - 1]; 18777 18778 if (this._activeTarget !== target) { 18779 this._activate(target); 18780 } 18781 18782 return; 18783 } 18784 18785 if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) { 18786 this._activeTarget = null; 18787 18788 this._clear(); 18789 18790 return; 18791 } 18792 18793 var offsetLength = this._offsets.length; 18794 18795 for (var i = offsetLength; i--;) { 18796 var isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1]); 18797 18798 if (isActiveTarget) { 18799 this._activate(this._targets[i]); 18800 } 18801 } 18802 }; 18803 18804 _proto._activate = function _activate(target) { 18805 this._activeTarget = target; 18806 18807 this._clear(); 18808 18809 var queries = this._selector.split(',').map(function (selector) { 18810 return selector + "[data-target=\"" + target + "\"]," + selector + "[href=\"" + target + "\"]"; 18811 }); 18812 18813 var $link = $([].slice.call(document.querySelectorAll(queries.join(',')))); 18814 18815 if ($link.hasClass(ClassName$8.DROPDOWN_ITEM)) { 18816 $link.closest(Selector$8.DROPDOWN).find(Selector$8.DROPDOWN_TOGGLE).addClass(ClassName$8.ACTIVE); 18817 $link.addClass(ClassName$8.ACTIVE); 18818 } else { 18819 // Set triggered link as active 18820 $link.addClass(ClassName$8.ACTIVE); // Set triggered links parents as active 18821 // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor 18822 18823 $link.parents(Selector$8.NAV_LIST_GROUP).prev(Selector$8.NAV_LINKS + ", " + Selector$8.
18823LIST_ITEMS).addClass(ClassName$8.ACTIVE); // Handle special case when .nav-link is inside .nav-item 18824 18825 $link.parents(Selector$8.NAV_LIST_GROUP).prev(Selector$8.NAV_ITEMS).children(Selector$8.NAV_LINKS).addClass(ClassName$8.ACTIVE); 18826 } 18827 18828 $(this._scrollElement).trigger(Event$8.ACTIVATE, { 18829 relatedTarget: target 18830 }); 18831 }; 18832 18833 _proto._clear = function _clear() { 18834 [].slice.call(document.querySelectorAll(this._selector)).filter(function (node) { 18835 return node.classList.contains(ClassName$8.ACTIVE); 18836 }).forEach(function (node) { 18837 return node.classList.remove(ClassName$8.ACTIVE); 18838 }); 18839 } // Static 18840 ; 18841 18842 ScrollSpy._jQueryInterface = function _jQueryInterface(config) { 18843 return this.each(function () { 18844 var data = $(this).data(DATA_KEY$8); 18845 18846 var _config = typeof config === 'object' && config; 18847 18848 if (!data) { 18849 data = new ScrollSpy(this, _config); 18850 $(this).data(DATA_KEY$8, data); 18851 } 18852 18853 if (typeof config === 'string') { 18854 if (typeof data[config] === 'undefined') { 18855 throw new TypeError("No method named \"" + config + "\""); 18856 } 18857 18858 data[config](); 18859 } 18860 }); 18861 }; 18862 18863 _createClass(ScrollSpy, null, [{ 18864 key: "VERSION", 18865 get: function get() { 18866 return VERSION$8; 18867 } 18868 }, { 18869 key: "Default", 18870 get: function get() { 18871 return Default$6; 18872 } 18873 }]); 18874 18875 return ScrollSpy; 18876 }(); 18877 /** 18878 * ------------------------------------------------------------------------ 18879 * Data Api implementation 18880 * ------------------------------------------------------------------------ 18881 */ 18882 18883 18884 $(window).on(Event$8.LOAD_DATA_API, function () { 18885 var scrollSpys = [].slice.call(document.querySelectorAll(Selector$8.DATA_SPY)); 18886 var scrollSpysLength = scrollSpys.length; 18887 18888 for (var i = scrollSpysLength; i--;) { 18889 var $spy = $(scrollSpys[i]); 18890 18891 ScrollSpy._jQueryInterface.call($spy, $spy.data()); 18892 } 18893 }); 18894 /** 18895 * ------------------------------------------------------------------------ 18896 * jQuery 18897 * ------------------------------------------------------------------------ 18898 */ 18899 18900 $.fn[NAME$8] = ScrollSpy._jQueryInterface; 18901 $.fn[NAME$8].Constructor = ScrollSpy; 18902 18903 $.fn[NAME$8].noConflict = function () { 18904 $.fn[NAME$8] = JQUERY_NO_CONFLICT$8; 18905 return ScrollSpy._jQueryInterface; 18906 }; 18907 18908 /** 18909 * ------------------------------------------------------------------------ 18910 * Constants 18911 * ------------------------------------------------------------------------ 18912 */ 18913 18914 var NAME$9 = 'tab'; 18915 var VERSION$9 = '4.3.1'; 18916 var DATA_KEY$9 = 'bs.tab'; 18917 var EVENT_KEY$9 = "." + DATA_KEY$9; 18918 var DATA_API_KEY$7 = '.data-api'; 18919 var JQUERY_NO_CONFLICT$9 = $.fn[NAME$9]; 18920 var Event$9 = { 18921 HIDE: "hide" + EVENT_KEY$9, 18922 HIDDEN: "hidden" + EVENT_KEY$9, 18923 SHOW: "show" + EVENT_KEY$9, 18924 SHOWN: "shown" + EVENT_KEY$9, 18925 CLICK_DATA_API: "click" + EVENT_KEY$9 + DATA_API_KEY$7 18926 }; 18927 var ClassName$9 = { 18928 DROPDOWN_MENU: 'dropdown-menu', 18929 ACTIVE: 'active', 18930 DISABLED: 'disabled', 18931 FADE: 'fade', 18932 SHOW: 'show' 18933 }; 18934 var Selector$9 = { 18935 DROPDOWN: '.dropdown', 18936 NAV_LIST_GROUP: '.nav, .list-group', 18937 ACTIVE: '.active', 18938 ACTIVE_UL: '> li > .active', 18939 DATA_TOGGLE: '[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]', 18940 DROPDOWN_TOGGLE: '.dropdown-toggle', 18941 DROPDOWN_ACTIVE_CHILD: '> .dropdown-menu .active' 18942 /** 18943 * ------------------------------------------------------------------------ 18944 * Class Definition 18945 * ------------------------------------------------------------------------ 18946 */ 18947 18948 }; 18949 18950 var Tab = 18951 /*#__PURE__*/ 18952 function () { 18953 function Tab(element) { 18954 this._element = element; 18955 } // Getters 18956 18957 18958 var _proto = Tab.prototype; 18959 18960 // Public 18961 _proto.show = function show() { 18962 var _this = this; 18963 18964 if (this._element.parentNode && this._element.parentNode.nodeType === Node.ELEMENT_NODE && $(this._element).hasClass(ClassName$9.ACTIVE) || $(this._element).hasClass(ClassName$9.DISABLED)) { 18965 return; 18966 } 18967 18968 var target; 18969 var previous; 18970 var listElement = $(this._element).closest(Selector$9.NAV_LIST_GROUP)[0]; 18971 var selector = Util.getSelectorFromElement(this._element); 18972 18973 if (listElement) { 18974 var itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? Selector$9.ACTIVE_UL : Selector$9.ACTIVE; 18975 previous = $.makeArray($(listElement).find(itemSelector)); 18976 previous = previous[previous.length - 1]; 18977 } 18978 18979 var hideEvent = $.Event(Event$9.HIDE, { 18980 relatedTarget: this._element 18981 }); 18982 var showEvent = $.Event(Event$9.SHOW, { 18983 relatedTarget: previous 18984 }); 18985 18986 if (previous) { 18987 $(previous).trigger(hideEvent); 18988 } 18989 18990 $(this._element).trigger(showEvent); 18991 18992 if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) { 18993 return; 18994 } 18995 18996 if (selector) { 18997 target = document.querySelector(selector); 18998 } 18999 19000 this._activate(this._element, listElement); 19001 19002 var complete = function complete() { 19003 var hiddenEvent = $.Event(Event$9.HIDDEN, { 19004 relatedTarget: _this._element 19005 }); 19006 var shownEvent = $.Event(Event$9.SHOWN, { 19007 relatedTarget: previous 19008 }); 19009 $(previous).trigger(hiddenEvent); 19010 $(_this._element).trigger(shownEvent); 19011 }; 19012 19013 if (target) { 19014 this._activate(target, target.parentNode, complete); 19015 } else { 19016 complete(); 19017 } 19018 }; 19019 19020 _proto.dispose = function dispose() { 19021 $.removeData(this._element, DATA_KEY$9); 19022 this._element = null; 19023 } // Private 19024 ; 19025 19026 _proto._activate = function _activate(element, container, callback) { 19027 var _this2 = this; 19028 19029 var activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ? $(container).find(Selector$9.ACTIVE_UL) : $(container).children(Selector$9.ACTIVE); 19030 var active = activeElements[0]; 19031 var isTransitioning = callback && active && $(active).hasClass(ClassName$9.FADE); 19032 19033 var complete = function complete() { 19034 return _this2._transitionComplete(element, active, callback); 19035 }; 19036 19037 if (active && isTransitioning) { 19038 var transitionDuration = Util.getTransitionDurationFromElement(active); 19039 $(active).removeClass(ClassName$9.SHOW).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); 19040 } else { 19041 complete(); 19042 } 19043 }; 19044 19045 _proto._transitionComplete = function _transitionComplete(element, active, callback) { 19046 if (active) { 19047 $(active).removeClass(ClassName$9.ACTIVE);
19048 var dropdownChild = $(active.parentNode).find(Selector$9.DROPDOWN_ACTIVE_CHILD)[0]; 19049 19050 if (dropdownChild) { 19051 $(dropdownChild).removeClass(ClassName$9.ACTIVE); 19052 } 19053 19054 if (active.getAttribute('role') === 'tab') { 19055 active.setAttribute('aria-selected', false); 19056 } 19057 } 19058 19059 $(element).addClass(ClassName$9.ACTIVE); 19060 19061 if (element.getAttribute('role') === 'tab') { 19062 element.setAttribute('aria-selected', true); 19063 } 19064 19065 Util.reflow(element); 19066 19067 if (element.classList.contains(ClassName$9.FADE)) { 19068 element.classList.add(ClassName$9.SHOW); 19069 } 19070 19071 if (element.parentNode && $(element.parentNode).hasClass(ClassName$9.DROPDOWN_MENU)) { 19072 var dropdownElement = $(element).closest(Selector$9.DROPDOWN)[0]; 19073 19074 if (dropdownElement) { 19075 var dropdownToggleList = [].slice.call(dropdownElement.querySelectorAll(Selector$9.DROPDOWN_TOGGLE)); 19076 $(dropdownToggleList).addClass(ClassName$9.ACTIVE); 19077 } 19078 19079 element.setAttribute('aria-expanded', true); 19080 } 19081 19082 if (callback) { 19083 callback(); 19084 } 19085 } // Static 19086 ; 19087 19088 Tab._jQueryInterface = function _jQueryInterface(config) { 19089 return this.each(function () { 19090 var $this = $(this); 19091 var data = $this.data(DATA_KEY$9); 19092 19093 if (!data) { 19094 data = new Tab(this); 19095 $this.data(DATA_KEY$9, data); 19096 } 19097 19098 if (typeof config === 'string') { 19099 if (typeof data[config] === 'undefined') { 19100 throw new TypeError("No method named \"" + config + "\""); 19101 } 19102 19103 data[config](); 19104 } 19105 }); 19106 }; 19107 19108 _createClass(Tab, null, [{ 19109 key: "VERSION", 19110 get: function get() { 19111 return VERSION$9; 19112 } 19113 }]); 19114 19115 return Tab; 19116 }(); 19117 /** 19118 * ------------------------------------------------------------------------ 19119 * Data Api implementation 19120 * ------------------------------------------------------------------------ 19121 */ 19122 19123 19124 $(document).on(Event$9.CLICK_DATA_API, Selector$9.DATA_TOGGLE, function (event) { 19125 event.preventDefault(); 19126 19127 Tab._jQueryInterface.call($(this), 'show'); 19128 }); 19129 /** 19130 * ------------------------------------------------------------------------ 19131 * jQuery 19132 * ------------------------------------------------------------------------ 19133 */ 19134 19135 $.fn[NAME$9] = Tab._jQueryInterface; 19136 $.fn[NAME$9].Constructor = Tab; 19137 19138 $.fn[NAME$9].noConflict = function () { 19139 $.fn[NAME$9] = JQUERY_NO_CONFLICT$9; 19140 return Tab._jQueryInterface; 19141 }; 19142 19143 /** 19144 * ------------------------------------------------------------------------ 19145 * Constants 19146 * ------------------------------------------------------------------------ 19147 */ 19148 19149 var NAME$a = 'toast'; 19150 var VERSION$a = '4.3.1'; 19151 var DATA_KEY$a = 'bs.toast'; 19152 var EVENT_KEY$a = "." + DATA_KEY$a; 19153 var JQUERY_NO_CONFLICT$a = $.fn[NAME$a]; 19154 var Event$a = { 19155 CLICK_DISMISS: "click.dismiss" + EVENT_KEY$a, 19156 HIDE: "hide" + EVENT_KEY$a, 19157 HIDDEN: "hidden" + EVENT_KEY$a, 19158 SHOW: "show" + EVENT_KEY$a, 19159 SHOWN: "shown" + EVENT_KEY$a 19160 }; 19161 var ClassName$a = { 19162 FADE: 'fade', 19163 HIDE: 'hide', 19164 SHOW: 'show', 19165 SHOWING: 'showing' 19166 }; 19167 var DefaultType$7 = { 19168 animation: 'boolean', 19169 autohide: 'boolean', 19170 delay: 'number' 19171 }; 19172 var Default$7 = { 19173 animation: true, 19174 autohide: true, 19175 delay: 500 19176 }; 19177 var Selector$a = { 19178 DATA_DISMISS: '[data-dismiss="toast"]' 19179 /** 19180 * ------------------------------------------------------------------------ 19181 * Class Definition 19182 * ------------------------------------------------------------------------ 19183 */ 19184 19185 }; 19186 19187 var Toast = 19188 /*#__PURE__*/ 19189 function () { 19190 function Toast(element, config) { 19191 this._element = element; 19192 this._config = this._getConfig(config); 19193 this._timeout = null; 19194 19195 this._setListeners(); 19196 } // Getters 19197 19198 19199 var _proto = Toast.prototype; 19200 19201 // Public 19202 _proto.show = function show() { 19203 var _this = this; 19204 19205 $(this._element).trigger(Event$a.SHOW); 19206 19207 if (this._config.animation) { 19208 this._element.classList.add(ClassName$a.FADE); 19209 } 19210 19211 var complete = function complete() { 19212 _this._element.classList.remove(ClassName$a.SHOWING); 19213 19214 _this._element.classList.add(ClassName$a.SHOW); 19215 19216 $(_this._element).trigger(Event$a.SHOWN); 19217 19218 if (_this._config.autohide) { 19219 _this.hide(); 19220 } 19221 }; 19222 19223 this._element.classList.remove(ClassName$a.HIDE); 19224 19225 this._element.classList.add(ClassName$a.SHOWING); 19226 19227 if (this._config.animation) { 19228 var transitionDuration = Util.getTransitionDurationFromElement(this._element); 19229 $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); 19230 } else { 19231 complete(); 19232 } 19233 }; 19234 19235 _proto.hide = function hide(withoutTimeout) { 19236 var _this2 = this; 19237 19238 if (!this._element.classList.contains(ClassName$a.SHOW)) { 19239 return; 19240 } 19241 19242 $(this._element).trigger(Event$a.HIDE); 19243 19244 if (withoutTimeout) { 19245 this._close(); 19246 } else { 19247 this._timeout = setTimeout(function () { 19248 _this2._close(); 19249 }, this._config.delay); 19250 } 19251 }; 19252 19253 _proto.dispose = function dispose() { 19254 clearTimeout(this._timeout); 19255 this._timeout = null; 19256 19257 if (this._element.classList.contains(ClassName$a.SHOW)) { 19258 this._element.classList.remove(ClassName$a.SHOW); 19259 } 19260 19261 $(this._element).off(Event$a.CLICK_DISMISS); 19262 $.removeData(this._element, DATA_KEY$a); 19263 this._element = null; 19264 this._config = null; 19265 } // Private 19266 ; 19267 19268 _proto._getConfig = function _getConfig(config) { 19269 config = _objectSpread({}, Default$7, $(this._element).data(), typeof config === 'object' && config ? config : {}); 19270 Util.typeCheckConfig(NAME$a, config, this.constructor.DefaultType); 19271 return config; 19272 }; 19273 19274 _proto._setListeners = function _setListeners() { 19275 var _this3 = this; 19276 19277 $(this._element).on(Event$a.CLICK_DISMISS, Selector$a.DATA_DISMISS, function () { 19278 return _this3.hide(true); 19279 }); 19280 }; 19281 19282 _proto._close = function _close() { 19283 var _this4 = this; 19284 19285 var complete = function complete() { 19286 _this4._element.classList.add(ClassName$a.HIDE); 19287 19288 $(_this4._element).trigger(Event$a.HIDDEN); 19289 }; 19290 19291 this._element.classList.remove(ClassName$a.SHOW); 19292 19293 if (this._config.animation) { 19294 var transitionDuration = Util.getTransitionDurationFromElement(this._element); 19295 $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); 19296 } else { 19297 complete(); 19298 } 19299 } // Static 19300 ; 19301 19302 Toast._jQueryInterface = function _jQueryInterface(config) { 19303 return this.each(function () { 19304 var $element = $(this); 19305 var data = $element.data(DATA_KEY$a); 19306 19307 var _config = typeof config === 'object' && config; 19308 19309 if (!data) { 19310 data = new Toast(this, _config); 19311 $element.data(DATA_KEY$a, data); 19312 } 19313 19314 if (typeof config === 'string') { 19315 if (typeof data[config] === 'undefined') {
19316 throw new TypeError("No method named \"" + config + "\""); 19317 } 19318 19319 data[config](this); 19320 } 19321 }); 19322 }; 19323 19324 _createClass(Toast, null, [{ 19325 key: "VERSION", 19326 get: function get() { 19327 return VERSION$a; 19328 } 19329 }, { 19330 key: "DefaultType", 19331 get: function get() { 19332 return DefaultType$7; 19333 } 19334 }, { 19335 key: "Default", 19336 get: function get() { 19337 return Default$7; 19338 } 19339 }]); 19340 19341 return Toast; 19342 }(); 19343 /** 19344 * ------------------------------------------------------------------------ 19345 * jQuery 19346 * ------------------------------------------------------------------------ 19347 */ 19348 19349 19350 $.fn[NAME$a] = Toast._jQueryInterface; 19351 $.fn[NAME$a].Constructor = Toast; 19352 19353 $.fn[NAME$a].noConflict = function () { 19354 $.fn[NAME$a] = JQUERY_NO_CONFLICT$a; 19355 return Toast._jQueryInterface; 19356 }; 19357 19358 /** 19359 * -------------------------------------------------------------------------- 19360 * Bootstrap (v4.3.1): index.js 19361 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 19362 * -------------------------------------------------------------------------- 19363 */ 19364 19365 (function () { 19366 if (typeof $ === 'undefined') { 19367 throw new TypeError('Bootstrap\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\'s JavaScript.'); 19368 } 19369 19370 var version = $.fn.jquery.split(' ')[0].split('.'); 19371 var minMajor = 1; 19372 var ltMajor = 2; 19373 var minMinor = 9; 19374 var minPatch = 1; 19375 var maxMajor = 4; 19376 19377 if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) { 19378 throw new Error('Bootstrap\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0'); 19379 } 19380 })(); 19381 19382 exports.Util = Util; 19383 exports.Alert = Alert; 19384 exports.Button = Button; 19385 exports.Carousel = Carousel; 19386 exports.Collapse = Collapse; 19387 exports.Dropdown = Dropdown; 19388 exports.Modal = Modal; 19389 exports.Popover = Popover; 19390 exports.Scrollspy = ScrollSpy; 19391 exports.Tab = Tab; 19392 exports.Toast = Toast; 19393 exports.Tooltip = Tooltip; 19394 19395 Object.defineProperty(exports, '__esModule', { value: true }); 19396 19397})); 19398 19399 19400},{"jquery":13,"popper.js":15}],12:[function(require,module,exports){ 19401/** 19402* @version: 3.0.5 19403* @author: Dan Grossman http://www.dangrossman.info/ 19404* @copyright: Copyright (c) 2012-2019 Dan Grossman. All rights reserved. 19405* @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php 19406* @website: http://www.daterangepicker.com/ 19407*/ 19408// Following the UMD template https://github.com/umdjs/umd/blob/master/templates/returnExportsGlobal.js 19409(function (root, factory) { 19410 if (typeof define === 'function' && define.amd) { 19411 // AMD. Make globaly available as well 19412 define(['moment', 'jquery'], function (moment, jquery) { 19413 if (!jquery.fn) jquery.fn = {}; // webpack server rendering 19414 if (typeof moment !== 'function' && moment.default) moment = moment.default 19415 return factory(moment, jquery); 19416 }); 19417 } else if (typeof module === 'object' && module.exports) { 19418 // Node / Browserify 19419 //isomorphic issue 19420 var jQuery = (typeof window != 'undefined') ? window.jQuery : undefined; 19421 if (!jQuery) { 19422 jQuery = require('jquery'); 19423 if (!jQuery.fn) jQuery.fn = {}; 19424 } 19425 var moment = (typeof window != 'undefined' && typeof window.moment != 'undefined') ? window.moment : require('moment'); 19426 module.exports = factory(moment, jQuery); 19427 } else { 19428 // Browser globals 19429 root.daterangepicker = factory(root.moment, root.jQuery); 19430 } 19431}(this, function(moment, $) { 19432 var DateRangePicker = function(element, options, cb) { 19433 19434 //default settings for options 19435 this.parentEl = 'body'; 19436 this.element = $(element); 19437 this.startDate = moment().startOf('day'); 19438 this.endDate = moment().endOf('day'); 19439 this.minDate = false; 19440 this.maxDate = false; 19441 this.maxSpan = false; 19442 this.autoApply = false; 19443 this.singleDatePicker = false; 19444 this.showDropdowns = false; 19445 this.minYear = moment().subtract(100, 'year').format('YYYY'); 19446 this.maxYear = moment().add(100, 'year').format('YYYY'); 19447 this.showWeekNumbers = false; 19448 this.showISOWeekNumbers = false; 19449 this.showCustomRangeLabel = true; 19450 this.timePicker = false; 19451 this.timePicker24Hour = false; 19452 this.timePickerIncrement = 1; 19453 this.timePickerSeconds = false; 19454 this.linkedCalendars = true; 19455 this.autoUpdateInput = true; 19456 this.alwaysShowCalendars = false; 19457 this.ranges = {}; 19458 19459 this.opens = 'right'; 19460 if (this.element.hasClass('pull-right')) 19461 this.opens = 'left'; 19462 19463 this.drops = 'down'; 19464 if (this.element.hasClass('dropup')) 19465 this.drops = 'up'; 19466
vendor: 19,404 bytes, lines 19467-19931
19467 this.buttonClasses = 'btn btn-sm'; 19468 this.applyButtonClasses = 'btn-primary'; 19469 this.cancelButtonClasses = 'btn-default'; 19470 19471 this.locale = { 19472 direction: 'ltr', 19473 format: moment.localeData().longDateFormat('L'), 19474 separator: ' - ', 19475 applyLabel: 'Apply', 19476 cancelLabel: 'Cancel', 19477 weekLabel: 'W', 19478 customRangeLabel: 'Custom Range', 19479 daysOfWeek: moment.weekdaysMin(), 19480 monthNames: moment.monthsShort(), 19481 firstDay: moment.localeData().firstDayOfWeek() 19482 }; 19483 19484 this.callback = function() { }; 19485 19486 //some state information 19487 this.isShowing = false; 19488 this.leftCalendar = {}; 19489 this.rightCalendar = {}; 19490 19491 //custom options from user 19492 if (typeof options !== 'object' || options === null) 19493 options = {}; 19494 19495 //allow setting options with data attributes 19496 //data-api options will be overwritten with custom javascript options 19497 options = $.extend(this.element.data(), options); 19498 19499 //html template for the picker UI 19500 if (typeof options.template !== 'string' && !(options.template instanceof $)) 19501 options.template = 19502 '<div class="daterangepicker">' + 19503 '<div class="ranges"></div>' + 19504 '<div class="drp-calendar left">' + 19505 '<div class="calendar-table"></div>' + 19506 '<div class="calendar-time"></div>' + 19507 '</div>' + 19508 '<div class="drp-calendar right">' + 19509 '<div class="calendar-table"></div>' + 19510 '<div class="calendar-time"></div>' + 19511 '</div>' + 19512 '<div class="drp-buttons">' + 19513 '<span class="drp-selected"></span>' + 19514 '<button class="cancelBtn" type="button"></button>' + 19515 '<button class="applyBtn" disabled="disabled" type="button"></button> ' + 19516 '</div>' + 19517 '</div>'; 19518 19519 this.parentEl = (options.parentEl && $(options.parentEl).length) ? $(options.parentEl) : $(this.parentEl); 19520 this.container = $(options.template).appendTo(this.parentEl); 19521 19522 // 19523 // handle all the possible options overriding defaults 19524 // 19525 19526 if (typeof options.locale === 'object') { 19527 19528 if (typeof options.locale.direction === 'string') 19529 this.locale.direction = options.locale.direction; 19530 19531 if (typeof options.locale.format === 'string') 19532 this.locale.format = options.locale.format; 19533 19534 if (typeof options.locale.separator === 'string') 19535 this.locale.separator = options.locale.separator; 19536 19537 if (typeof options.locale.daysOfWeek === 'object') 19538 this.locale.daysOfWeek = options.locale.daysOfWeek.slice(); 19539 19540 if (typeof options.locale.monthNames === 'object') 19541 this.locale.monthNames = options.locale.monthNames.slice(); 19542 19543 if (typeof options.locale.firstDay === 'number') 19544 this.locale.firstDay = options.locale.firstDay; 19545 19546 if (typeof options.locale.applyLabel === 'string') 19547 this.locale.applyLabel = options.locale.applyLabel; 19548 19549 if (typeof options.locale.cancelLabel === 'string') 19550 this.locale.cancelLabel = options.locale.cancelLabel; 19551 19552 if (typeof options.locale.weekLabel === 'string') 19553 this.locale.weekLabel = options.locale.weekLabel; 19554 19555 if (typeof options.locale.customRangeLabel === 'string'){ 19556 //Support unicode chars in the custom range name. 19557 var elem = document.createElement('textarea'); 19558 elem.innerHTML = options.locale.customRangeLabel; 19559 var rangeHtml = elem.value; 19560 this.locale.customRangeLabel = rangeHtml; 19561 } 19562 } 19563 this.container.addClass(this.locale.direction); 19564 19565 if (typeof options.startDate === 'string') 19566 this.startDate = moment(options.startDate, this.locale.format); 19567 19568 if (typeof options.endDate === 'string') 19569 this.endDate = moment(options.endDate, this.locale.format); 19570 19571 if (typeof options.minDate === 'string') 19572 this.minDate = moment(options.minDate, this.locale.format); 19573 19574 if (typeof options.maxDate === 'string') 19575 this.maxDate = moment(options.maxDate, this.locale.format); 19576 19577 if (typeof options.startDate === 'object') 19578 this.startDate = moment(options.startDate); 19579 19580 if (typeof options.endDate === 'object') 19581 this.endDate = moment(options.endDate); 19582 19583 if (typeof options.minDate === 'object') 19584 this.minDate = moment(options.minDate); 19585 19586 if (typeof options.maxDate === 'object') 19587 this.maxDate = moment(options.maxDate); 19588 19589 // sanity check for bad options 19590 if (this.minDate && this.startDate.isBefore(this.minDate)) 19591 this.startDate = this.minDate.clone(); 19592 19593 // sanity check for bad options 19594 if (this.maxDate && this.endDate.isAfter(this.maxDate)) 19595 this.endDate = this.maxDate.clone(); 19596 19597 if (typeof options.applyButtonClasses === 'string') 19598 this.applyButtonClasses = options.applyButtonClasses; 19599 19600 if (typeof options.applyClass === 'string') //backwards compat 19601 this.applyButtonClasses = options.applyClass; 19602 19603 if (typeof options.cancelButtonClasses === 'string') 19604 this.cancelButtonClasses = options.cancelButtonClasses; 19605 19606 if (typeof options.cancelClass === 'string') //backwards compat 19607 this.cancelButtonClasses = options.cancelClass; 19608 19609 if (typeof options.maxSpan === 'object') 19610 this.maxSpan = options.maxSpan; 19611 19612 if (typeof options.dateLimit === 'object') //backwards compat 19613 this.maxSpan = options.dateLimit; 19614 19615 if (typeof options.opens === 'string') 19616 this.opens = options.opens; 19617 19618 if (typeof options.drops === 'string') 19619 this.drops = options.drops; 19620 19621 if (typeof options.showWeekNumbers === 'boolean') 19622 this.showWeekNumbers = options.showWeekNumbers; 19623 19624 if (typeof options.showISOWeekNumbers === 'boolean') 19625 this.showISOWeekNumbers = options.showISOWeekNumbers; 19626 19627 if (typeof options.buttonClasses === 'string') 19628 this.buttonClasses = options.buttonClasses; 19629 19630 if (typeof options.buttonClasses === 'object') 19631 this.buttonClasses = options.buttonClasses.join(' '); 19632 19633 if (typeof options.showDropdowns === 'boolean') 19634 this.showDropdowns = options.showDropdowns; 19635 19636 if (typeof options.minYear === 'number') 19637 this.minYear = options.minYear; 19638 19639 if (typeof options.maxYear === 'number') 19640 this.maxYear = options.maxYear; 19641 19642 if (typeof options.showCustomRangeLabel === 'boolean') 19643 this.showCustomRangeLabel = options.showCustomRangeLabel; 19644 19645 if (typeof options.singleDatePicker === 'boolean') { 19646 this.singleDatePicker = options.singleDatePicker; 19647 if (this.singleDatePicker) 19648 this.endDate = this.startDate.clone(); 19649 } 19650 19651 if (typeof options.timePicker === 'boolean') 19652 this.timePicker = options.timePicker; 19653 19654 if (typeof options.timePickerSeconds === 'boolean') 19655 this.timePickerSeconds = options.timePickerSeconds; 19656 19657 if (typeof options.timePickerIncrement === 'number') 19658 this.timePickerIncrement = options.timePickerIncrement; 19659 19660 if (typeof options.timePicker24Hour === 'boolean') 19661 this.timePicker24Hour = options.timePicker24Hour; 19662 19663 if (typeof options.autoApply === 'boolean') 19664 this.autoApply = options.autoApply; 19665 19666 if (typeof options.autoUpdateInput === 'boolean') 19667 this.autoUpdateInput = options.autoUpdateInput; 19668 19669 if (typeof options.linkedCalendars === 'boolean') 19670 this.linkedCalendars = options.linkedCalendars; 19671 19672 if (typeof options.isInvalidDate === 'function') 19673 this.isInvalidDate = options.isInvalidDate; 19674 19675 if (typeof options.isCustomDate === 'function') 19676 this.isCustomDate = options.isCustomDate; 19677 19678 if (typeof options.alwaysShowCalendars === 'boolean') 19679 this.alwaysShowCalendars = options.alwaysShowCalendars; 19680 19681 // update day names order to firstDay 19682 if (this.locale.firstDay != 0) { 19683 var iterator = this.locale.firstDay; 19684 while (iterator > 0) { 19685 this.locale.daysOfWeek.push(this.locale.daysOfWeek.shift()); 19686 iterator--; 19687 } 19688 } 19689 19690 var start, end, range; 19691 19692 //if no start/end dates set, check if an input element contains initial values 19693 if (typeof options.startDate === 'undefined' && typeof options.endDate === 'undefined') { 19694 if ($(this.element).is(':text')) { 19695 var val = $(this.element).val(), 19696 split = val.split(this.locale.separator); 19697 19698 start = end = null; 19699 19700 if (split.length == 2) { 19701 start = moment(split[0], this.locale.format); 19702 end = moment(split[1], this.locale.format); 19703 } else if (this.singleDatePicker && val !== "") { 19704 start = moment(val, this.locale.format); 19705 end = moment(val, this.locale.format); 19706 } 19707 if (start !== null && end !== null) { 19708 this.setStartDate(start); 19709 this.setEndDate(end); 19710 } 19711 } 19712 } 19713 19714 if (typeof options.ranges === 'object') { 19715 for (range in options.ranges) { 19716 19717 if (typeof options.ranges[range][0] === 'string') 19718 start = moment(options.ranges[range][0], this.locale.format); 19719 else 19720 start = moment(options.ranges[range][0]); 19721 19722 if (typeof options.ranges[range][1] === 'string') 19723 end = moment(options.ranges[range][1], this.locale.format); 19724 else 19725 end = moment(options.ranges[range][1]); 19726 19727 // If the start or end date exceed those allowed by the minDate or maxSpan 19728 // options, shorten the range to the allowable period. 19729 if (this.minDate && start.isBefore(this.minDate)) 19730 start = this.minDate.clone(); 19731 19732 var maxDate = this.maxDate; 19733 if (this.maxSpan && maxDate && start.clone().add(this.maxSpan).isAfter(maxDate)) 19734 maxDate = start.clone().add(this.maxSpan); 19735 if (maxDate && end.isAfter(maxDate)) 19736 end = maxDate.clone(); 19737 19738 // If the end of the range is before the minimum or the start of the range is 19739 // after the maximum, don't display this range option at all. 19740 if ((this.minDate && end.isBefore(this.minDate, this.timepicker ? 'minute' : 'day')) 19741 || (maxDate && start.isAfter(maxDate, this.timepicker ? 'minute' : 'day'))) 19742 continue; 19743 19744 //Support unicode chars in the range names. 19745 var elem = document.createElement('textarea'); 19746 elem.innerHTML = range; 19747 var rangeHtml = elem.value; 19748 19749 this.ranges[rangeHtml] = [start, end]; 19750 } 19751 19752 var list = '<ul>'; 19753 for (range in this.ranges) { 19754 list += '<li data-range-key="' + range + '">' + range + '</li>'; 19755 } 19756 if (this.showCustomRangeLabel) { 19757 list += '<li data-range-key="' + this.locale.customRangeLabel + '">' + this.locale.customRangeLabel + '</li>'; 19758 } 19759 list += '</ul>'; 19760 this.container.find('.ranges').prepend(list); 19761 } 19762 19763 if (typeof cb === 'function') { 19764 this.callback = cb; 19765 } 19766 19767 if (!this.timePicker) { 19768 this.startDate = this.startDate.startOf('day'); 19769 this.endDate = this.endDate.endOf('day'); 19770 this.container.find('.calendar-time').hide(); 19771 } 19772 19773 //can't be used together for now 19774 if (this.timePicker && this.autoApply) 19775 this.autoApply = false; 19776 19777 if (this.autoApply) { 19778 this.container.addClass('auto-apply'); 19779 } 19780 19781 if (typeof options.ranges === 'object') 19782 this.container.addClass('show-ranges'); 19783 19784 if (this.singleDatePicker) { 19785 this.container.addClass('single'); 19786 this.container.find('.drp-calendar.left').addClass('single'); 19787 this.container.find('.drp-calendar.left').show(); 19788 this.container.find('.drp-calendar.right').hide(); 19789 if (!this.timePicker) { 19790 this.container.addClass('auto-apply'); 19791 } 19792 } 19793 19794 if ((typeof options.ranges === 'undefined' && !this.singleDatePicker) || this.alwaysShowCalendars) { 19795 this.container.addClass('show-calendar'); 19796 } 19797 19798 this.container.addClass('opens' + this.opens); 19799 19800 //apply CSS classes and labels to buttons 19801 this.container.find('.applyBtn, .cancelBtn').addClass(this.buttonClasses); 19802 if (this.applyButtonClasses.length) 19803 this.container.find('.applyBtn').addClass(this.applyButtonClasses); 19804 if (this.cancelButtonClasses.length) 19805 this.container.find('.cancelBtn').addClass(this.cancelButtonClasses); 19806 this.container.find('.applyBtn').html(this.locale.applyLabel); 19807 this.container.find('.cancelBtn').html(this.locale.cancelLabel); 19808 19809 // 19810 // event listeners 19811 // 19812 19813 this.container.find('.drp-calendar') 19814 .on('click.daterangepicker', '.prev', $.proxy(this.clickPrev, this)) 19815 .on('click.daterangepicker', '.next', $.proxy(this.clickNext, this)) 19816 .on('mousedown.daterangepicker', 'td.available', $.proxy(this.clickDate, this)) 19817 .on('mouseenter.daterangepicker', 'td.available', $.proxy(this.hoverDate, this)) 19818 .on('change.daterangepicker', 'select.yearselect', $.proxy(this.monthOrYearChanged, this)) 19819 .on('change.daterangepicker', 'select.monthselect', $.proxy(this.monthOrYearChanged, this)) 19820 .on('change.daterangepicker', 'select.hourselect,select.minuteselect,select.secondselect,select.ampmselect', $.proxy(this.timeChanged, this)) 19821 19822 this.container.find('.ranges') 19823 .on('click.daterangepicker', 'li', $.proxy(this.clickRange, this)) 19824 19825 this.container.find('.drp-buttons') 19826 .on('click.daterangepicker', 'button.applyBtn', $.proxy(this.clickApply, this)) 19827 .on('click.daterangepicker', 'button.cancelBtn', $.proxy(this.clickCancel, this)) 19828 19829 if (this.element.is('input') || this.element.is('button')) { 19830 this.element.on({ 19831 'click.daterangepicker': $.proxy(this.show, this), 19832 'focus.daterangepicker': $.proxy(this.show, this), 19833 'keyup.daterangepicker': $.proxy(this.elementChanged, this), 19834 'keydown.daterangepicker': $.proxy(this.keydown, this) //IE 11 compatibility 19835 }); 19836 } else { 19837 this.element.on('click.daterangepicker', $.proxy(this.toggle, this)); 19838 this.element.on('keydown.daterangepicker', $.proxy(this.toggle, this)); 19839 } 19840 19841 // 19842 // if attached to a text input, set the initial value 19843 // 19844 19845 this.updateElement(); 19846 19847 }; 19848 19849 DateRangePicker.prototype = { 19850 19851 constructor: DateRangePicker, 19852 19853 setStartDate: function(startDate) { 19854 if (typeof startDate === 'string') 19855 this.startDate = moment(startDate, this.locale.format); 19856 19857 if (typeof startDate === 'object') 19858 this.startDate = moment(startDate); 19859 19860 if (!this.timePicker) 19861 this.startDate = this.startDate.startOf('day'); 19862 19863 if (this.timePicker && this.timePickerIncrement) 19864 this.startDate.minute(Math.round(this.startDate.minute() / this.timePickerIncrement) * this.timePickerIncrement); 19865 19866 if (this.minDate && this.startDate.isBefore(this.minDate)) { 19867 this.startDate = this.minDate.clone(); 19868 if (this.timePicker && this.timePickerIncrement) 19869 this.startDate.minute(Math.round(this.startDate.minute() / this.timePickerIncrement) * this.timePickerIncrement); 19870 } 19871 19872 if (this.maxDate && this.startDate.isAfter(this.maxDate)) { 19873 this.startDate = this.maxDate.clone(); 19874 if (this.timePicker && this.timePickerIncrement) 19875 this.startDate.minute(Math.floor(this.startDate.minute() / this.timePickerIncrement) * this.timePickerIncrement); 19876 } 19877 19878 if (!this.isShowing) 19879 this.updateElement(); 19880 19881 this.updateMonthsInView(); 19882 }, 19883 19884 setEndDate: function(endDate) { 19885 if (typeof endDate === 'string') 19886 this.endDate = moment(endDate, this.locale.format); 19887 19888 if (typeof endDate === 'object') 19889 this.endDate = moment(endDate); 19890 19891 if (!this.timePicker) 19892 this.endDate = this.endDate.endOf('day'); 19893 19894 if (this.timePicker && this.timePickerIncrement) 19895 this.endDate.minute(Math.round(this.endDate.minute() / this.timePickerIncrement) * this.timePickerIncrement); 19896 19897 if (this.endDate.isBefore(this.startDate)) 19898 this.endDate = this.startDate.clone(); 19899 19900 if (this.maxDate && this.endDate.isAfter(this.maxDate)) 19901 this.endDate = this.maxDate.clone(); 19902 19903 if (this.maxSpan && this.startDate.clone().add(this.maxSpan).isBefore(this.endDate)) 19904 this.endDate = this.startDate.clone().add(this.maxSpan); 19905 19906 this.previousRightTime = this.endDate.clone(); 19907 19908 this.container.find('.drp-selected').html(this.startDate.format(this.locale.format) + this.locale.separator + this.endDate.format(this.locale.format)); 19909 19910 if (!this.isShowing) 19911 this.updateElement(); 19912 19913 this.updateMonthsInView(); 19914 }, 19915 19916 isInvalidDate: function() { 19917 return false; 19918 }, 19919 19920 isCustomDate: function() { 19921 return false; 19922 }, 19923 19924 updateView: function() { 19925 if (this.timePicker) { 19926 this.renderTimePicker('left'); 19927 this.renderTimePicker('right'); 19928 if (!this.endDate) { 19929 this.container.find('.right .calendar-time select').attr('disabled', 'disabled').addClass('disabled'); 19930 } else { 19931 this.container.find('.right .calendar-time select').removeAttr('disabled'
vendor: 22,094 bytes, lines 19931-20417
19931).removeClass('disabled'); 19932 } 19933 } 19934 if (this.endDate) 19935 this.container.find('.drp-selected').html(this.startDate.format(this.locale.format) + this.locale.separator + this.endDate.format(this.locale.format)); 19936 this.updateMonthsInView(); 19937 this.updateCalendars(); 19938 this.updateFormInputs(); 19939 }, 19940 19941 updateMonthsInView: function() { 19942 if (this.endDate) { 19943 19944 //if both dates are visible already, do nothing 19945 if (!this.singleDatePicker && this.leftCalendar.month && this.rightCalendar.month && 19946 (this.startDate.format('YYYY-MM') == this.leftCalendar.month.format('YYYY-MM') || this.startDate.format('YYYY-MM') == this.rightCalendar.month.format('YYYY-MM')) 19947 && 19948 (this.endDate.format('YYYY-MM') == this.leftCalendar.month.format('YYYY-MM') || this.endDate.format('YYYY-MM') == this.rightCalendar.month.format('YYYY-MM')) 19949 ) { 19950 return; 19951 } 19952 19953 this.leftCalendar.month = this.startDate.clone().date(2); 19954 if (!this.linkedCalendars && (this.endDate.month() != this.startDate.month() || this.endDate.year() != this.startDate.year())) { 19955 this.rightCalendar.month = this.endDate.clone().date(2); 19956 } else { 19957 this.rightCalendar.month = this.startDate.clone().date(2).add(1, 'month'); 19958 } 19959 19960 } else { 19961 if (this.leftCalendar.month.format('YYYY-MM') != this.startDate.format('YYYY-MM') && this.rightCalendar.month.format('YYYY-MM') != this.startDate.format('YYYY-MM')) { 19962 this.leftCalendar.month = this.startDate.clone().date(2); 19963 this.rightCalendar.month = this.startDate.clone().date(2).add(1, 'month'); 19964 } 19965 } 19966 if (this.maxDate && this.linkedCalendars && !this.singleDatePicker && this.rightCalendar.month > this.maxDate) { 19967 this.rightCalendar.month = this.maxDate.clone().date(2); 19968 this.leftCalendar.month = this.maxDate.clone().date(2).subtract(1, 'month'); 19969 } 19970 }, 19971 19972 updateCalendars: function() { 19973 19974 if (this.timePicker) { 19975 var hour, minute, second; 19976 if (this.endDate) { 19977 hour = parseInt(this.container.find('.left .hourselect').val(), 10); 19978 minute = parseInt(this.container.find('.left .minuteselect').val(), 10); 19979 if (isNaN(minute)) { 19980 minute = parseInt(this.container.find('.left .minuteselect option:last').val(), 10); 19981 } 19982 second = this.timePickerSeconds ? parseInt(this.container.find('.left .secondselect').val(), 10) : 0; 19983 if (!this.timePicker24Hour) { 19984 var ampm = this.container.find('.left .ampmselect').val(); 19985 if (ampm === 'PM' && hour < 12) 19986 hour += 12; 19987 if (ampm === 'AM' && hour === 12) 19988 hour = 0; 19989 } 19990 } else { 19991 hour = parseInt(this.container.find('.right .hourselect').val(), 10); 19992 minute = parseInt(this.container.find('.right .minuteselect').val(), 10); 19993 if (isNaN(minute)) { 19994 minute = parseInt(this.container.find('.right .minuteselect option:last').val(), 10); 19995 } 19996 second = this.timePickerSeconds ? parseInt(this.container.find('.right .secondselect').val(), 10) : 0; 19997 if (!this.timePicker24Hour) { 19998 var ampm = this.container.find('.right .ampmselect').val(); 19999 if (ampm === 'PM' && hour < 12) 20000 hour += 12; 20001 if (ampm === 'AM' && hour === 12) 20002 hour = 0; 20003 } 20004 } 20005 this.leftCalendar.month.hour(hour).minute(minute).second(second); 20006 this.rightCalendar.month.hour(hour).minute(minute).second(second); 20007 } 20008 20009 this.renderCalendar('left'); 20010 this.renderCalendar('right'); 20011 20012 //highlight any predefined range matching the current start and end dates 20013 this.container.find('.ranges li').removeClass('active'); 20014 if (this.endDate == null) return; 20015 20016 this.calculateChosenLabel(); 20017 }, 20018 20019 renderCalendar: function(side) { 20020 20021 // 20022 // Build the matrix of dates that will populate the calendar 20023 // 20024 20025 var calendar = side == 'left' ? this.leftCalendar : this.rightCalendar; 20026 var month = calendar.month.month(); 20027 var year = calendar.month.year(); 20028 var hour = calendar.month.hour(); 20029 var minute = calendar.month.minute(); 20030 var second = calendar.month.second(); 20031 var daysInMonth = moment([year, month]).daysInMonth(); 20032 var firstDay = moment([year, month, 1]); 20033 var lastDay = moment([year, month, daysInMonth]); 20034 var lastMonth = moment(firstDay).subtract(1, 'month').month(); 20035 var lastYear = moment(firstDay).subtract(1, 'month').year(); 20036 var daysInLastMonth = moment([lastYear, lastMonth]).daysInMonth(); 20037 var dayOfWeek = firstDay.day(); 20038 20039 //initialize a 6 rows x 7 columns array for the calendar 20040 var calendar = []; 20041 calendar.firstDay = firstDay; 20042 calendar.lastDay = lastDay; 20043 20044 for (var i = 0; i < 6; i++) { 20045 calendar[i] = []; 20046 } 20047 20048 //populate the calendar with date objects 20049 var startDay = daysInLastMonth - dayOfWeek + this.locale.firstDay + 1; 20050 if (startDay > daysInLastMonth) 20051 startDay -= 7; 20052 20053 if (dayOfWeek == this.locale.firstDay) 20054 startDay = daysInLastMonth - 6; 20055 20056 var curDate = moment([lastYear, lastMonth, startDay, 12, minute, second]); 20057 20058 var col, row; 20059 for (var i = 0, col = 0, row = 0; i < 42; i++, col++, curDate = moment(curDate).add(24, 'hour')) { 20060 if (i > 0 && col % 7 === 0) { 20061 col = 0; 20062 row++; 20063 } 20064 calendar[row][col] = curDate.clone().hour(hour).minute(minute).second(second); 20065 curDate.hour(12); 20066 20067 if (this.minDate && calendar[row][col].format('YYYY-MM-DD') == this.minDate.format('YYYY-MM-DD') && calendar[row][col].isBefore(this.minDate) && side == 'left') { 20068 calendar[row][col] = this.minDate.clone(); 20069 } 20070 20071 if (this.maxDate && calendar[row][col].format('YYYY-MM-DD') == this.maxDate.format('YYYY-MM-DD') && calendar[row][col].isAfter(this.maxDate) && side == 'right') { 20072 calendar[row][col] = this.maxDate.clone(); 20073 } 20074 20075 } 20076 20077 //make the calendar object available to hoverDate/clickDate 20078 if (side == 'left') { 20079 this.leftCalendar.calendar = calendar; 20080 } else { 20081 this.rightCalendar.calendar = calendar; 20082 } 20083 20084 // 20085 // Display the calendar 20086 // 20087 20088 var minDate = side == 'left' ? this.minDate : this.startDate; 20089 var maxDate = this.maxDate; 20090 var selected = side == 'left' ? this.startDate : this.endDate; 20091 var arrow = this.locale.direction == 'ltr' ? {left: 'chevron-left', right: 'chevron-right'} : {left: 'chevron-right', right: 'chevron-left'}; 20092 20093 var html = '<table class="table-condensed">'; 20094 html += '<thead>'; 20095 html += '<tr>'; 20096 20097 // add empty cell for week number 20098 if (this.showWeekNumbers || this.showISOWeekNumbers) 20099 html += '<th></th>'; 20100 20101 if ((!minDate || minDate.isBefore(calendar.firstDay)) && (!this.linkedCalendars || side == 'left')) { 20102 html += '<th class="prev available"><span></span></th>'; 20103 } else { 20104 html += '<th></th>'; 20105 } 20106 20107 var dateHtml = this.locale.monthNames[calendar[1][1].month()] + calendar[1][1].format(" YYYY"); 20108 20109 if (this.showDropdowns) { 20110 var currentMonth = calendar[1][1].month(); 20111 var currentYear = calendar[1][1].year(); 20112 var maxYear = (maxDate && maxDate.year()) || (this.maxYear); 20113 var minYear = (minDate && minDate.year()) || (this.minYear); 20114 var inMinYear = currentYear == minYear; 20115 var inMaxYear = currentYear == maxYear; 20116 20117 var monthHtml = '<select class="monthselect">'; 20118 for (var m = 0; m < 12; m++) { 20119 if ((!inMinYear || (minDate && m >= minDate.month())) && (!inMaxYear || (maxDate && m <= maxDate.month()))) { 20120 monthHtml += "<option value='" + m + "'" + 20121 (m === currentMonth ? " selected='selected'" : "") + 20122 ">" + this.locale.monthNames[m] + "</option>"; 20123 } else { 20124 monthHtml += "<option value='" + m + "'" + 20125 (m === currentMonth ? " selected='selected'" : "") + 20126 " disabled='disabled'>" + this.locale.monthNames[m] + "</option>"; 20127 } 20128 } 20129 monthHtml += "</select>"; 20130 20131 var yearHtml = '<select class="yearselect">'; 20132 for (var y = minYear; y <= maxYear; y++) { 20133 yearHtml += '<option value="' + y + '"' + 20134 (y === currentYear ? ' selected="selected"' : '') + 20135 '>' + y + '</option>'; 20136 } 20137 yearHtml += '</select>'; 20138 20139 dateHtml = monthHtml + yearHtml; 20140 } 20141 20142 html += '<th colspan="5" class="month">' + dateHtml + '</th>'; 20143 if ((!maxDate || maxDate.isAfter(calendar.lastDay)) && (!this.linkedCalendars || side == 'right' || this.singleDatePicker)) { 20144 html += '<th class="next available"><span></span></th>'; 20145 } else { 20146 html += '<th></th>'; 20147 } 20148 20149 html += '</tr>'; 20150 html += '<tr>'; 20151 20152 // add week number label 20153 if (this.showWeekNumbers || this.showISOWeekNumbers) 20154 html += '<th class="week">' + this.locale.weekLabel + '</th>'; 20155 20156 $.each(this.locale.daysOfWeek, function(index, dayOfWeek) { 20157 html += '<th>' + dayOfWeek + '</th>'; 20158 }); 20159 20160 html += '</tr>'; 20161 html += '</thead>'; 20162 html += '<tbody>'; 20163 20164 //adjust maxDate to reflect the maxSpan setting in order to 20165 //grey out end dates beyond the maxSpan 20166 if (this.endDate == null && this.maxSpan) { 20167 var maxLimit = this.startDate.clone().add(this.maxSpan).endOf('day'); 20168 if (!maxDate || maxLimit.isBefore(maxDate)) { 20169 maxDate = maxLimit; 20170 } 20171 } 20172 20173 for (var row = 0; row < 6; row++) { 20174 html += '<tr>'; 20175 20176 // add week number 20177 if (this.showWeekNumbers) 20178 html += '<td class="week">' + calendar[row][0].week() + '</td>'; 20179 else if (this.showISOWeekNumbers) 20180 html += '<td class="week">' + calendar[row][0].isoWeek() + '</td>'; 20181 20182 for (var col = 0; col < 7; col++) { 20183 20184 var classes = []; 20185 20186 //highlight today's date 20187 if (calendar[row][col].isSame(new Date(), "day")) 20188 classes.push('today'); 20189 20190 //highlight weekends 20191 if (calendar[row][col].isoWeekday() > 5) 20192 classes.push('weekend'); 20193 20194 //grey out the dates in other months displayed at beginning and end of this calendar 20195 if (calendar[row][col].month() != calendar[1][1].month()) 20196 classes.push('off', 'ends'); 20197 20198 //don't allow selection of dates before the minimum date 20199 if (this.minDate && calendar[row][col].isBefore(this.minDate, 'day')) 20200 classes.push('off', 'disabled'); 20201 20202 //don't allow selection of dates after the maximum date 20203 if (maxDate && calendar[row][col].isAfter(maxDate, 'day')) 20204 classes.push('off', 'disabled'); 20205 20206 //don't allow selection of date if a custom function decides it's invalid 20207 if (this.isInvalidDate(calendar[row][col])) 20208 classes.push('off', 'disabled'); 20209 20210 //highlight the currently selected start date 20211 if (calendar[row][col].format('YYYY-MM-DD') == this.startDate.format('YYYY-MM-DD')) 20212 classes.push('active', 'start-date'); 20213 20214 //highlight the currently selected end date 20215 if (this.endDate != null && calendar[row][col].format('YYYY-MM-DD') == this.endDate.format('YYYY-MM-DD')) 20216 classes.push('active', 'end-date'); 20217 20218 //highlight dates in-between the selected dates 20219 if (this.endDate != null && calendar[row][col] > this.startDate && calendar[row][col] < this.endDate) 20220 classes.push('in-range'); 20221 20222 //apply custom classes for this date 20223 var isCustom = this.isCustomDate(calendar[row][col]); 20224 if (isCustom !== false) { 20225 if (typeof isCustom === 'string') 20226 classes.push(isCustom); 20227 else 20228 Array.prototype.push.apply(classes, isCustom); 20229 } 20230 20231 var cname = '', disabled = false; 20232 for (var i = 0; i < classes.length; i++) { 20233 cname += classes[i] + ' '; 20234 if (classes[i] == 'disabled') 20235 disabled = true; 20236 } 20237 if (!disabled) 20238 cname += 'available'; 20239 20240 html += '<td class="' + cname.replace(/^\s+|\s+$/g, '') + '" data-title="' + 'r' + row + 'c' + col + '">' + calendar[row][col].date() + '</td>'; 20241 20242 } 20243 html += '</tr>'; 20244 } 20245 20246 html += '</tbody>'; 20247 html += '</table>'; 20248 20249 this.container.find('.drp-calendar.' + side + ' .calendar-table').html(html); 20250 20251 }, 20252 20253 renderTimePicker: function(side) { 20254 20255 // Don't bother updating the time picker if it's currently disabled 20256 // because an end date hasn't been clicked yet 20257 if (side == 'right' && !this.endDate) return; 20258 20259 var html, selected, minDate, maxDate = this.maxDate; 20260 20261 if (this.maxSpan && (!this.maxDate || this.startDate.clone().add(this.maxSpan).isBefore(this.maxDate))) 20262 maxDate = this.startDate.clone().add(this.maxSpan); 20263 20264 if (side == 'left') { 20265 selected = this.startDate.clone(); 20266 minDate = this.minDate; 20267 } else if (side == 'right') { 20268 selected = this.endDate.clone(); 20269 minDate = this.startDate; 20270 20271 //Preserve the time already selected 20272 var timeSelector = this.container.find('.drp-calendar.right .calendar-time'); 20273 if (timeSelector.html() != '') { 20274 20275 selected.hour(!isNaN(selected.hour()) ? selected.hour() : timeSelector.find('.hourselect option:selected').val()); 20276 selected.minute(!isNaN(selected.minute()) ? selected.minute() : timeSelector.find('.minuteselect option:selected').val()); 20277 selected.second(!isNaN(selected.second()) ? selected.second() : timeSelector.find('.secondselect option:selected').val()); 20278 20279 if (!this.timePicker24Hour) { 20280 var ampm = timeSelector.find('.ampmselect option:selected').val(); 20281 if (ampm === 'PM' && selected.hour() < 12) 20282 selected.hour(selected.hour() + 12); 20283 if (ampm === 'AM' && selected.hour() === 12) 20284 selected.hour(0); 20285 } 20286 20287 } 20288 20289 if (selected.isBefore(this.startDate)) 20290 selected = this.startDate.clone(); 20291 20292 if (maxDate && selected.isAfter(maxDate)) 20293 selected = maxDate.clone(); 20294 20295 } 20296 20297 // 20298 // hours 20299 // 20300 20301 html = '<select class="hourselect">'; 20302 20303 var start = this.timePicker24Hour ? 0 : 1; 20304 var end = this.timePicker24Hour ? 23 : 12; 20305 20306 for (var i = start; i <= end; i++) { 20307 var i_in_24 = i; 20308 if (!this.timePicker24Hour) 20309 i_in_24 = selected.hour() >= 12 ? (i == 12 ? 12 : i + 12) : (i == 12 ? 0 : i); 20310 20311 var time = selected.clone().hour(i_in_24); 20312 var disabled = false; 20313 if (minDate && time.minute(59).isBefore(minDate)) 20314 disabled = true; 20315 if (maxDate && time.minute(0).isAfter(maxDate)) 20316 disabled = true; 20317 20318 if (i_in_24 == selected.hour() && !disabled) { 20319 html += '<option value="' + i + '" selected="selected">' + i + '</option>'; 20320 } else if (disabled) { 20321 html += '<option value="' + i + '" disabled="disabled" class="disabled">' + i + '</option>'; 20322 } else { 20323 html += '<option value="' + i + '">' + i + '</option>'; 20324 } 20325 } 20326 20327 html += '</select> '; 20328 20329 // 20330 // minutes 20331 // 20332 20333 html += ': <select class="minuteselect">'; 20334 20335 for (var i = 0; i < 60; i += this.timePickerIncrement) { 20336 var padded = i < 10 ? '0' + i : i; 20337 var time = selected.clone().minute(i); 20338 20339 var disabled = false; 20340 if (minDate && time.second(59).isBefore(minDate)) 20341 disabled = true; 20342 if (maxDate && time.second(0).isAfter(maxDate)) 20343 disabled = true; 20344 20345 if (selected.minute() == i && !disabled) { 20346 html += '<option value="' + i + '" selected="selected">' + padded + '</option>'; 20347 } else if (disabled) { 20348 html += '<option value="' + i + '" disabled="disabled" class="disabled">' + padded + '</option>'; 20349 } else { 20350 html += '<option value="' + i + '">' + padded + '</option>'; 20351 } 20352 } 20353 20354 html += '</select> '; 20355 20356 // 20357 // seconds 20358 // 20359 20360 if (this.timePickerSeconds) { 20361 html += ': <select class="secondselect">'; 20362 20363 for (var i = 0; i < 60; i++) { 20364 var padded = i < 10 ? '0' + i : i; 20365 var time = selected.clone().second(i); 20366 20367 var disabled = false; 20368 if (minDate && time.isBefore(minDate)) 20369 disabled = true; 20370 if (maxDate && time.isAfter(maxDate)) 20371 disabled = true; 20372 20373 if (selected.second() == i && !disabled) { 20374 html += '<option value="' + i + '" selected="selected">' + padded + '</option>'; 20375 } else if (disabled) { 20376 html += '<option value="' + i + '" disabled="disabled" class="disabled">' + padded + '</option>'; 20377 } else { 20378 html += '<option value="' + i + '">' + padded + '</option>'; 20379 } 20380 } 20381 20382 html += '</select> '; 20383 } 20384 20385 // 20386 // AM/PM 20387 // 20388 20389 if (!this.timePicker24Hour) { 20390 html += '<select class="ampmselect">'; 20391 20392 var am_html = ''; 20393 var pm_html = ''; 20394 20395 if (minDate && selected.clone().hour(12).minute(0).second(0).isBefore(minDate)) 20396 am_html = ' disabled="disabled" class="disabled"'; 20397 20398 if (maxDate && selected.clone().hour(0).minute(0).second(0).isAfter(maxDate)) 20399 pm_html = ' disabled="disabled" class="disabled"'; 20400 20401 if (selected.hour() >= 12) { 20402 html += '<option value="AM"' + am_html + '>AM</option><option value="PM" selected="selected"' + pm_html + '>PM</option>'; 20403 } else { 20404 html += '<option value="AM" selected="selected"' + am_html + '>AM</option><option value="PM"' + pm_html + '>PM</option>'; 20405 } 20406 20407 html += '</select>'; 20408 } 20409 20410 this.container.find('.drp-calendar.' + side + ' .calendar-time').html(html); 20411 20412 }, 20413 20414 updateFormInputs: function() { 20415 20416 if (this.singleDatePicker || (this.endDate && (this.startDate.isBefore(this.endDate) || this.startDate.isSame(this.endDate)))) { 20417 this.container.find('button.applyBtn').
vendor: 1,312 bytes, lines 20417-20449
20417removeAttr('disabled'); 20418 } else { 20419 this.container.find('button.applyBtn').attr('disabled', 'disabled'); 20420 } 20421 20422 }, 20423 20424 move: function() { 20425 var parentOffset = { top: 0, left: 0 }, 20426 containerTop; 20427 var parentRightEdge = $(window).width(); 20428 if (!this.parentEl.is('body')) { 20429 parentOffset = { 20430 top: this.parentEl.offset().top - this.parentEl.scrollTop(), 20431 left: this.parentEl.offset().left - this.parentEl.scrollLeft() 20432 }; 20433 parentRightEdge = this.parentEl[0].clientWidth + this.parentEl.offset().left; 20434 } 20435 20436 if (this.drops == 'up') 20437 containerTop = this.element.offset().top - this.container.outerHeight() - parentOffset.top; 20438 else 20439 containerTop = this.element.offset().top + this.element.outerHeight() - parentOffset.top; 20440 20441 // Force the container to it's actual width 20442 this.container.css({ 20443 top: 0, 20444 left: 0, 20445 right: 'auto' 20446 }); 20447 var containerWidth = this.container.outerWidth(); 20448 20449 this.container[this.drops == 'up' ? 'addClass' : 'removeClass']('drop-
vendor: 21,720 bytes, lines 20449-20965
20449up'); 20450 20451 if (this.opens == 'left') { 20452 var containerRight = parentRightEdge - this.element.offset().left - this.element.outerWidth(); 20453 if (containerWidth + containerRight > $(window).width()) { 20454 this.container.css({ 20455 top: containerTop, 20456 right: 'auto', 20457 left: 9 20458 }); 20459 } else { 20460 this.container.css({ 20461 top: containerTop, 20462 right: containerRight, 20463 left: 'auto' 20464 }); 20465 } 20466 } else if (this.opens == 'center') { 20467 var containerLeft = this.element.offset().left - parentOffset.left + this.element.outerWidth() / 2 20468 - containerWidth / 2; 20469 if (containerLeft < 0) { 20470 this.container.css({ 20471 top: containerTop, 20472 right: 'auto', 20473 left: 9 20474 }); 20475 } else if (containerLeft + containerWidth > $(window).width()) { 20476 this.container.css({ 20477 top: containerTop, 20478 left: 'auto', 20479 right: 0 20480 }); 20481 } else { 20482 this.container.css({ 20483 top: containerTop, 20484 left: containerLeft, 20485 right: 'auto' 20486 }); 20487 } 20488 } else { 20489 var containerLeft = this.element.offset().left - parentOffset.left; 20490 if (containerLeft + containerWidth > $(window).width()) { 20491 this.container.css({ 20492 top: containerTop, 20493 left: 'auto', 20494 right: 0 20495 }); 20496 } else { 20497 this.container.css({ 20498 top: containerTop, 20499 left: containerLeft, 20500 right: 'auto' 20501 }); 20502 } 20503 } 20504 }, 20505 20506 show: function(e) { 20507 if (this.isShowing) return; 20508 20509 // Create a click proxy that is private to this instance of datepicker, for unbinding 20510 this._outsideClickProxy = $.proxy(function(e) { this.outsideClick(e); }, this); 20511 20512 // Bind global datepicker mousedown for hiding and 20513 $(document) 20514 .on('mousedown.daterangepicker', this._outsideClickProxy) 20515 // also support mobile devices 20516 .on('touchend.daterangepicker', this._outsideClickProxy) 20517 // also explicitly play nice with Bootstrap dropdowns, which stopPropagation when clicking them 20518 .on('click.daterangepicker', '[data-toggle=dropdown]', this._outsideClickProxy) 20519 // and also close when focus changes to outside the picker (eg. tabbing between controls) 20520 .on('focusin.daterangepicker', this._outsideClickProxy); 20521 20522 // Reposition the picker if the window is resized while it's open 20523 $(window).on('resize.daterangepicker', $.proxy(function(e) { this.move(e); }, this)); 20524 20525 this.oldStartDate = this.startDate.clone(); 20526 this.oldEndDate = this.endDate.clone(); 20527 this.previousRightTime = this.endDate.clone(); 20528 20529 this.updateView(); 20530 this.container.show(); 20531 this.move(); 20532 this.element.trigger('show.daterangepicker', this); 20533 this.isShowing = true; 20534 }, 20535 20536 hide: function(e) { 20537 if (!this.isShowing) return; 20538 20539 //incomplete date selection, revert to last values 20540 if (!this.endDate) { 20541 this.startDate = this.oldStartDate.clone(); 20542 this.endDate = this.oldEndDate.clone(); 20543 } 20544 20545 //if a new date range was selected, invoke the user callback function 20546 if (!this.startDate.isSame(this.oldStartDate) || !this.endDate.isSame(this.oldEndDate)) 20547 this.callback(this.startDate.clone(), this.endDate.clone(), this.chosenLabel); 20548 20549 //if picker is attached to a text input, update it 20550 this.updateElement(); 20551 20552 $(document).off('.daterangepicker'); 20553 $(window).off('.daterangepicker'); 20554 this.container.hide(); 20555 this.element.trigger('hide.daterangepicker', this); 20556 this.isShowing = false; 20557 }, 20558 20559 toggle: function(e) { 20560 if (this.isShowing) { 20561 this.hide(); 20562 } else { 20563 this.show(); 20564 } 20565 }, 20566 20567 outsideClick: function(e) { 20568 var target = $(e.target); 20569 // if the page is clicked anywhere except within the daterangerpicker/button 20570 // itself then call this.hide() 20571 if ( 20572 // ie modal dialog fix 20573 e.type == "focusin" || 20574 target.closest(this.element).length || 20575 target.closest(this.container).length || 20576 target.closest('.calendar-table').length 20577 ) return; 20578 this.hide(); 20579 this.element.trigger('outsideClick.daterangepicker', this); 20580 }, 20581 20582 showCalendars: function() { 20583 this.container.addClass('show-calendar'); 20584 this.move(); 20585 this.element.trigger('showCalendar.daterangepicker', this); 20586 }, 20587 20588 hideCalendars: function() { 20589 this.container.removeClass('show-calendar'); 20590 this.element.trigger('hideCalendar.daterangepicker', this); 20591 }, 20592 20593 clickRange: function(e) { 20594 var label = e.target.getAttribute('data-range-key'); 20595 this.chosenLabel = label; 20596 if (label == this.locale.customRangeLabel) { 20597 this.showCalendars(); 20598 } else { 20599 var dates = this.ranges[label]; 20600 this.startDate = dates[0]; 20601 this.endDate = dates[1]; 20602 20603 if (!this.timePicker) { 20604 this.startDate.startOf('day'); 20605 this.endDate.endOf('day'); 20606 } 20607 20608 if (!this.alwaysShowCalendars) 20609 this.hideCalendars(); 20610 this.clickApply(); 20611 } 20612 }, 20613 20614 clickPrev: function(e) { 20615 var cal = $(e.target).parents('.drp-calendar'); 20616 if (cal.hasClass('left')) { 20617 this.leftCalendar.month.subtract(1, 'month'); 20618 if (this.linkedCalendars) 20619 this.rightCalendar.month.subtract(1, 'month'); 20620 } else { 20621 this.rightCalendar.month.subtract(1, 'month'); 20622 } 20623 this.updateCalendars(); 20624 }, 20625 20626 clickNext: function(e) { 20627 var cal = $(e.target).parents('.drp-calendar'); 20628 if (cal.hasClass('left')) { 20629 this.leftCalendar.month.add(1, 'month'); 20630 } else { 20631 this.rightCalendar.month.add(1, 'month'); 20632 if (this.linkedCalendars) 20633 this.leftCalendar.month.add(1, 'month'); 20634 } 20635 this.updateCalendars(); 20636 }, 20637 20638 hoverDate: function(e) { 20639 20640 //ignore dates that can't be selected 20641 if (!$(e.target).hasClass('available')) return; 20642 20643 var title = $(e.target).attr('data-title'); 20644 var row = title.substr(1, 1); 20645 var col = title.substr(3, 1); 20646 var cal = $(e.target).parents('.drp-calendar'); 20647 var date = cal.hasClass('left') ? this.leftCalendar.calendar[row][col] : this.rightCalendar.calendar[row][col]; 20648 20649 //highlight the dates between the start date and the date being hovered as a potential end date 20650 var leftCalendar = this.leftCalendar; 20651 var rightCalendar = this.rightCalendar; 20652 var startDate = this.startDate; 20653 if (!this.endDate) { 20654 this.container.find('.drp-calendar tbody td').each(function(index, el) { 20655 20656 //skip week numbers, only look at dates 20657 if ($(el).hasClass('week')) return; 20658 20659 var title = $(el).attr('data-title'); 20660 var row = title.substr(1, 1); 20661 var col = title.substr(3, 1); 20662 var cal = $(el).parents('.drp-calendar'); 20663 var dt = cal.hasClass('left') ? leftCalendar.calendar[row][col] : rightCalendar.calendar[row][col]; 20664 20665 if ((dt.isAfter(startDate) && dt.isBefore(date)) || dt.isSame(date, 'day')) { 20666 $(el).addClass('in-range'); 20667 } else { 20668 $(el).removeClass('in-range'); 20669 } 20670 20671 }); 20672 } 20673 20674 }, 20675 20676 clickDate: function(e) { 20677 20678 if (!$(e.target).hasClass('available')) return; 20679 20680 var title = $(e.target).attr('data-title'); 20681 var row = title.substr(1, 1); 20682 var col = title.substr(3, 1); 20683 var cal = $(e.target).parents('.drp-calendar'); 20684 var date = cal.hasClass('left') ? this.leftCalendar.calendar[row][col] : this.rightCalendar.calendar[row][col]; 20685 20686 // 20687 // this function needs to do a few things: 20688 // * alternate between selecting a start and end date for the range, 20689 // * if the time picker is enabled, apply the hour/minute/second from the select boxes to the clicked date 20690 // * if autoapply is enabled, and an end date was chosen, apply the selection 20691 // * if single date picker mode, and time picker isn't enabled, apply the selection immediately 20692 // * if one of the inputs above the calendars was focused, cancel that manual input 20693 // 20694 20695 if (this.endDate || date.isBefore(this.startDate, 'day')) { //picking start 20696 if (this.timePicker) { 20697 var hour = parseInt(this.container.find('.left .hourselect').val(), 10); 20698 if (!this.timePicker24Hour) { 20699 var ampm = this.container.find('.left .ampmselect').val(); 20700 if (ampm === 'PM' && hour < 12) 20701 hour += 12; 20702 if (ampm === 'AM' && hour === 12) 20703 hour = 0; 20704 } 20705 var minute = parseInt(this.container.find('.left .minuteselect').val(), 10); 20706 if (isNaN(minute)) { 20707 minute = parseInt(this.container.find('.left .minuteselect option:last').val(), 10); 20708 } 20709 var second = this.timePickerSeconds ? parseInt(this.container.find('.left .secondselect').val(), 10) : 0; 20710 date = date.clone().hour(hour).minute(minute).second(second); 20711 } 20712 this.endDate = null; 20713 this.setStartDate(date.clone()); 20714 } else if (!this.endDate && date.isBefore(this.startDate)) { 20715 //special case: clicking the same date for start/end, 20716 //but the time of the end date is before the start date 20717 this.setEndDate(this.startDate.clone()); 20718 } else { // picking end 20719 if (this.timePicker) { 20720 var hour = parseInt(this.container.find('.right .hourselect').val(), 10); 20721 if (!this.timePicker24Hour) { 20722 var ampm = this.container.find('.right .ampmselect').val(); 20723 if (ampm === 'PM' && hour < 12) 20724 hour += 12; 20725 if (ampm === 'AM' && hour === 12) 20726 hour = 0; 20727 } 20728 var minute = parseInt(this.container.find('.right .minuteselect').val(), 10); 20729 if (isNaN(minute)) { 20730 minute = parseInt(this.container.find('.right .minuteselect option:last').val(), 10); 20731 } 20732 var second = this.timePickerSeconds ? parseInt(this.container.find('.right .secondselect').val(), 10) : 0; 20733 date = date.clone().hour(hour).minute(minute).second(second); 20734 } 20735 this.setEndDate(date.clone()); 20736 if (this.autoApply) { 20737 this.calculateChosenLabel(); 20738 this.clickApply(); 20739 } 20740 } 20741 20742 if (this.singleDatePicker) { 20743 this.setEndDate(this.startDate); 20744 if (!this.timePicker) 20745 this.clickApply(); 20746 } 20747 20748 this.updateView(); 20749 20750 //This is to cancel the blur event handler if the mouse was in one of the inputs 20751 e.stopPropagation(); 20752 20753 }, 20754 20755 calculateChosenLabel: function () { 20756 var customRange = true; 20757 var i = 0; 20758 for (var range in this.ranges) { 20759 if (this.timePicker) { 20760 var format = this.timePickerSeconds ? "YYYY-MM-DD HH:mm:ss" : "YYYY-MM-DD HH:mm"; 20761 //ignore times when comparing dates if time picker seconds is not enabled 20762 if (this.startDate.format(format) == this.ranges[range][0].format(format) && this.endDate.format(format) == this.ranges[range][1].format(format)) { 20763 customRange = false; 20764 this.chosenLabel = this.container.find('.ranges li:eq(' + i + ')').addClass('active').attr('data-range-key'); 20765 break; 20766 } 20767 } else { 20768 //ignore times when comparing dates if time picker is not enabled 20769 if (this.startDate.format('YYYY-MM-DD') == this.ranges[range][0].format('YYYY-MM-DD') && this.endDate.format('YYYY-MM-DD') == this.ranges[range][1].format('YYYY-MM-DD')) { 20770 customRange = false; 20771 this.chosenLabel = this.container.find('.ranges li:eq(' + i + ')').addClass('active').attr('data-range-key'); 20772 break; 20773 } 20774 } 20775 i++; 20776 } 20777 if (customRange) { 20778 if (this.showCustomRangeLabel) { 20779 this.chosenLabel = this.container.find('.ranges li:last').addClass('active').attr('data-range-key'); 20780 } else { 20781 this.chosenLabel = null; 20782 } 20783 this.showCalendars(); 20784 } 20785 }, 20786 20787 clickApply: function(e) { 20788 this.hide(); 20789 this.element.trigger('apply.daterangepicker', this); 20790 }, 20791 20792 clickCancel: function(e) { 20793 this.startDate = this.oldStartDate; 20794 this.endDate = this.oldEndDate; 20795 this.hide(); 20796 this.element.trigger('cancel.daterangepicker', this); 20797 }, 20798 20799 monthOrYearChanged: function(e) { 20800 var isLeft = $(e.target).closest('.drp-calendar').hasClass('left'), 20801 leftOrRight = isLeft ? 'left' : 'right', 20802 cal = this.container.find('.drp-calendar.'+leftOrRight); 20803 20804 // Month must be Number for new moment versions 20805 var month = parseInt(cal.find('.monthselect').val(), 10); 20806 var year = cal.find('.yearselect').val(); 20807 20808 if (!isLeft) { 20809 if (year < this.startDate.year() || (year == this.startDate.year() && month < this.startDate.month())) { 20810 month = this.startDate.month(); 20811 year = this.startDate.year(); 20812 } 20813 } 20814 20815 if (this.minDate) { 20816 if (year < this.minDate.year() || (year == this.minDate.year() && month < this.minDate.month())) { 20817 month = this.minDate.month(); 20818 year = this.minDate.year(); 20819 } 20820 } 20821 20822 if (this.maxDate) { 20823 if (year > this.maxDate.year() || (year == this.maxDate.year() && month > this.maxDate.month())) { 20824 month = this.maxDate.month(); 20825 year = this.maxDate.year(); 20826 } 20827 } 20828 20829 if (isLeft) { 20830 this.leftCalendar.month.month(month).year(year); 20831 if (this.linkedCalendars) 20832 this.rightCalendar.month = this.leftCalendar.month.clone().add(1, 'month'); 20833 } else { 20834 this.rightCalendar.month.month(month).year(year); 20835 if (this.linkedCalendars) 20836 this.leftCalendar.month = this.rightCalendar.month.clone().subtract(1, 'month'); 20837 } 20838 this.updateCalendars(); 20839 }, 20840 20841 timeChanged: function(e) { 20842 20843 var cal = $(e.target).closest('.drp-calendar'), 20844 isLeft = cal.hasClass('left'); 20845 20846 var hour = parseInt(cal.find('.hourselect').val(), 10); 20847 var minute = parseInt(cal.find('.minuteselect').val(), 10); 20848 if (isNaN(minute)) { 20849 minute = parseInt(cal.find('.minuteselect option:last').val(), 10); 20850 } 20851 var second = this.timePickerSeconds ? parseInt(cal.find('.secondselect').val(), 10) : 0; 20852 20853 if (!this.timePicker24Hour) { 20854 var ampm = cal.find('.ampmselect').val(); 20855 if (ampm === 'PM' && hour < 12) 20856 hour += 12; 20857 if (ampm === 'AM' && hour === 12) 20858 hour = 0; 20859 } 20860 20861 if (isLeft) { 20862 var start = this.startDate.clone(); 20863 start.hour(hour); 20864 start.minute(minute); 20865 start.second(second); 20866 this.setStartDate(start); 20867 if (this.singleDatePicker) { 20868 this.endDate = this.startDate.clone(); 20869 } else if (this.endDate && this.endDate.format('YYYY-MM-DD') == start.format('YYYY-MM-DD') && this.endDate.isBefore(start)) { 20870 this.setEndDate(start.clone()); 20871 } 20872 } else if (this.endDate) { 20873 var end = this.endDate.clone(); 20874 end.hour(hour); 20875 end.minute(minute); 20876 end.second(second); 20877 this.setEndDate(end); 20878 } 20879 20880 //update the calendars so all clickable dates reflect the new time component 20881 this.updateCalendars(); 20882 20883 //update the form inputs above the calendars with the new time 20884 this.updateFormInputs(); 20885 20886 //re-render the time pickers because changing one selection can affect what's enabled in another 20887 this.renderTimePicker('left'); 20888 this.renderTimePicker('right'); 20889 20890 }, 20891 20892 elementChanged: function() { 20893 if (!this.element.is('input')) return; 20894 if (!this.element.val().length) return; 20895 20896 var dateString = this.element.val().split(this.locale.separator), 20897 start = null, 20898 end = null; 20899 20900 if (dateString.length === 2) { 20901 start = moment(dateString[0], this.locale.format); 20902 end = moment(dateString[1], this.locale.format); 20903 } 20904 20905 if (this.singleDatePicker || start === null || end === null) { 20906 start = moment(this.element.val(), this.locale.format); 20907 end = start; 20908 } 20909 20910 if (!start.isValid() || !end.isValid()) return; 20911 20912 this.setStartDate(start); 20913 this.setEndDate(end); 20914 this.updateView(); 20915 }, 20916 20917 keydown: function(e) { 20918 //hide on tab or enter 20919 if ((e.keyCode === 9) || (e.keyCode === 13)) { 20920 this.hide(); 20921 } 20922 20923 //hide on esc and prevent propagation 20924 if (e.keyCode === 27) { 20925 e.preventDefault(); 20926 e.stopPropagation(); 20927 20928 this.hide(); 20929 } 20930 }, 20931 20932 updateElement: function() { 20933 if (this.element.is('input') && this.autoUpdateInput) { 20934 var newValue = this.startDate.format(this.locale.format); 20935 if (!this.singleDatePicker) { 20936 newValue += this.locale.separator + this.endDate.format(this.locale.format); 20937 } 20938 if (newValue !== this.element.val()) { 20939 this.element.val(newValue).trigger('change'); 20940 } 20941 } 20942 }, 20943 20944 remove: function() { 20945 this.container.remove(); 20946 this.element.off('.daterangepicker'); 20947 this.element.removeData(); 20948 } 20949 20950 }; 20951 20952 $.fn.daterangepicker = function(options, callback) { 20953 var implementOptions = $.extend(true, {}, $.fn.daterangepicker.defaultOptions, options); 20954 this.each(function() { 20955 var el = $(this); 20956 if (el.data('daterangepicker')) 20957 el.data('daterangepicker').remove(); 20958 el.data('daterangepicker', new DateRangePicker(el, implementOptions, callback)); 20959 }); 20960 return this; 20961 }; 20962 20963 return DateRangePicker; 20964 20965}));
20966 20967},{"jquery":13,"moment":14}],13:[function(require,module,exports){ 20968/*! 20969 * jQuery JavaScript Library v3.4.1 20970 * https://jquery.com/ 20971 * 20972 * Includes Sizzle.js 20973 * https://sizzlejs.com/ 20974 * 20975 * Copyright JS Foundation and other contributors 20976 * Released under the MIT license 20977 * https://jquery.org/license 20978 * 20979 * Date: 2019-05-01T21:04Z 20980 */ 20981( function( global, factory ) { 20982 20983 "use strict"; 20984 20985 if ( typeof module === "object" && typeof module.exports === "object" ) { 20986 20987 // For CommonJS and CommonJS-like environments where a proper `window` 20988 // is present, execute the factory and get jQuery. 20989 // For environments that do not have a `window` with a `document` 20990 // (such as Node.js), expose a factory as module.exports. 20991 // This accentuates the need for the creation of a real `window`. 20992 // e.g. var jQuery = require("jquery")(window); 20993 // See ticket #14549 for more info. 20994 module.exports = global.document ? 20995 factory( global, true ) : 20996 function( w ) { 20997 if ( !w.document ) { 20998 throw new Error( "jQuery requires a window with a document" ); 20999 } 21000 return factory( w ); 21001 }; 21002 } else { 21003 factory( global ); 21004 } 21005 21006// Pass this if window is not defined yet 21007} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { 21008 21009// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 21010// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode 21011// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), str
vendor: 4,911 bytes, lines 21011-21212
21011ict mode should be common 21012// enough that all such attempts are guarded in a try block. 21013"use strict"; 21014 21015var arr = []; 21016 21017var document = window.document; 21018 21019var getProto = Object.getPrototypeOf; 21020 21021var slice = arr.slice; 21022 21023var concat = arr.concat; 21024 21025var push = arr.push; 21026 21027var indexOf = arr.indexOf; 21028 21029var class2type = {}; 21030 21031var toString = class2type.toString; 21032 21033var hasOwn = class2type.hasOwnProperty; 21034 21035var fnToString = hasOwn.toString; 21036 21037var ObjectFunctionString = fnToString.call( Object ); 21038 21039var support = {}; 21040 21041var isFunction = function isFunction( obj ) { 21042 21043 // Support: Chrome <=57, Firefox <=52 21044 // In some browsers, typeof returns "function" for HTML <object> elements 21045 // (i.e., `typeof document.createElement( "object" ) === "function"`). 21046 // We don't want to classify *any* DOM node as a function. 21047 return typeof obj === "function" && typeof obj.nodeType !== "number"; 21048 }; 21049 21050 21051var isWindow = function isWindow( obj ) { 21052 return obj != null && obj === obj.window; 21053 }; 21054 21055 21056 21057 21058 var preservedScriptAttributes = { 21059 type: true, 21060 src: true, 21061 nonce: true, 21062 noModule: true 21063 }; 21064 21065 function DOMEval( code, node, doc ) { 21066 doc = doc || document; 21067 21068 var i, val, 21069 script = doc.createElement( "script" ); 21070 21071 script.text = code; 21072 if ( node ) { 21073 for ( i in preservedScriptAttributes ) { 21074 21075 // Support: Firefox 64+, Edge 18+ 21076 // Some browsers don't support the "nonce" property on scripts. 21077 // On the other hand, just using `getAttribute` is not enough as 21078 // the `nonce` attribute is reset to an empty string whenever it 21079 // becomes browsing-context connected. 21080 // See https://github.com/whatwg/html/issues/2369 21081 // See https://html.spec.whatwg.org/#nonce-attributes 21082 // The `node.getAttribute` check was added for the sake of 21083 // `jQuery.globalEval` so that it can fake a nonce-containing node 21084 // via an object. 21085 val = node[ i ] || node.getAttribute && node.getAttribute( i ); 21086 if ( val ) { 21087 script.setAttribute( i, val ); 21088 } 21089 } 21090 } 21091 doc.head.appendChild( script ).parentNode.removeChild( script ); 21092 } 21093 21094 21095function toType( obj ) { 21096 if ( obj == null ) { 21097 return obj + ""; 21098 } 21099 21100 // Support: Android <=2.3 only (functionish RegExp) 21101 return typeof obj === "object" || typeof obj === "function" ? 21102 class2type[ toString.call( obj ) ] || "object" : 21103 typeof obj; 21104} 21105/* global Symbol */ 21106// Defining this global in .eslintrc.json would create a danger of using the global 21107// unguarded in another place, it seems safer to define global only for this module 21108 21109 21110 21111var 21112 version = "3.4.1", 21113 21114 // Define a local copy of jQuery 21115 jQuery = function( selector, context ) { 21116 21117 // The jQuery object is actually just the init constructor 'enhanced' 21118 // Need init if jQuery is called (just allow error to be thrown if not included) 21119 return new jQuery.fn.init( selector, context ); 21120 }, 21121 21122 // Support: Android <=4.0 only 21123 // Make sure we trim BOM and NBSP 21124 rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; 21125 21126jQuery.fn = jQuery.prototype = { 21127 21128 // The current version of jQuery being used 21129 jquery: version, 21130 21131 constructor: jQuery, 21132 21133 // The default length of a jQuery object is 0 21134 length: 0, 21135 21136 toArray: function() { 21137 return slice.call( this ); 21138 }, 21139 21140 // Get the Nth element in the matched element set OR 21141 // Get the whole matched element set as a clean array 21142 get: function( num ) { 21143 21144 // Return all the elements in a clean array 21145 if ( num == null ) { 21146 return slice.call( this ); 21147 } 21148 21149 // Return just the one element from the set 21150 return num < 0 ? this[ num + this.length ] : this[ num ]; 21151 }, 21152 21153 // Take an array of elements and push it onto the stack 21154 // (returning the new matched element set) 21155 pushStack: function( elems ) { 21156 21157 // Build a new jQuery matched element set 21158 var ret = jQuery.merge( this.constructor(), elems ); 21159 21160 // Add the old object onto the stack (as a reference) 21161 ret.prevObject = this; 21162 21163 // Return the newly-formed element set 21164 return ret; 21165 }, 21166 21167 // Execute a callback for every element in the matched set. 21168 each: function( callback ) { 21169 return jQuery.each( this, callback ); 21170 }, 21171 21172 map: function( callback ) { 21173 return this.pushStack( jQuery.map( this, function( elem, i ) { 21174 return callback.call( elem, i, elem ); 21175 } ) ); 21176 }, 21177 21178 slice: function() { 21179 return this.pushStack( slice.apply( this, arguments ) ); 21180 }, 21181 21182 first: function() { 21183 return this.eq( 0 ); 21184 }, 21185 21186 last: function() { 21187 return this.eq( -1 ); 21188 }, 21189 21190 eq: function( i ) { 21191 var len = this.length, 21192 j = +i + ( i < 0 ? len : 0 ); 21193 return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); 21194 }, 21195 21196 end: function() { 21197 return this.prevObject || this.constructor(); 21198 }, 21199 21200 // For internal use only. 21201 // Behaves like an Array's method, not like a jQuery method. 21202 push: push, 21203 sort: arr.sort, 21204 splice: arr.splice 21205}; 21206 21207jQuery.extend = jQuery.fn.extend = function() { 21208 var options, name, src, copy, copyIsArray, clone, 21209 target = arguments[ 0 ] || {}, 21210 i = 1, 21211 length = arguments.length, 21212 deep = false;
vendor: 4,724 bytes, lines 21213-21425
21213 21214 // Handle a deep copy situation 21215 if ( typeof target === "boolean" ) { 21216 deep = target; 21217 21218 // Skip the boolean and the target 21219 target = arguments[ i ] || {}; 21220 i++; 21221 } 21222 21223 // Handle case when target is a string or something (possible in deep copy) 21224 if ( typeof target !== "object" && !isFunction( target ) ) { 21225 target = {}; 21226 } 21227 21228 // Extend jQuery itself if only one argument is passed 21229 if ( i === length ) { 21230 target = this; 21231 i--; 21232 } 21233 21234 for ( ; i < length; i++ ) { 21235 21236 // Only deal with non-null/undefined values 21237 if ( ( options = arguments[ i ] ) != null ) { 21238 21239 // Extend the base object 21240 for ( name in options ) { 21241 copy = options[ name ]; 21242 21243 // Prevent Object.prototype pollution 21244 // Prevent never-ending loop 21245 if ( name === "__proto__" || target === copy ) { 21246 continue; 21247 } 21248 21249 // Recurse if we're merging plain objects or arrays 21250 if ( deep && copy && ( jQuery.isPlainObject( copy ) || 21251 ( copyIsArray = Array.isArray( copy ) ) ) ) { 21252 src = target[ name ]; 21253 21254 // Ensure proper type for the source value 21255 if ( copyIsArray && !Array.isArray( src ) ) { 21256 clone = []; 21257 } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { 21258 clone = {}; 21259 } else { 21260 clone = src; 21261 } 21262 copyIsArray = false; 21263 21264 // Never move original objects, clone them 21265 target[ name ] = jQuery.extend( deep, clone, copy ); 21266 21267 // Don't bring in undefined values 21268 } else if ( copy !== undefined ) { 21269 target[ name ] = copy; 21270 } 21271 } 21272 } 21273 } 21274 21275 // Return the modified object 21276 return target; 21277}; 21278 21279jQuery.extend( { 21280 21281 // Unique for each copy of jQuery on the page 21282 expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), 21283 21284 // Assume jQuery is ready without the ready module 21285 isReady: true, 21286 21287 error: function( msg ) { 21288 throw new Error( msg ); 21289 }, 21290 21291 noop: function() {}, 21292 21293 isPlainObject: function( obj ) { 21294 var proto, Ctor; 21295 21296 // Detect obvious negatives 21297 // Use toString instead of jQuery.type to catch host objects 21298 if ( !obj || toString.call( obj ) !== "[object Object]" ) { 21299 return false; 21300 } 21301 21302 proto = getProto( obj ); 21303 21304 // Objects with no prototype (e.g., `Object.create( null )`) are plain 21305 if ( !proto ) { 21306 return true; 21307 } 21308 21309 // Objects with prototype are plain iff they were constructed by a global Object function 21310 Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; 21311 return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; 21312 }, 21313 21314 isEmptyObject: function( obj ) { 21315 var name; 21316 21317 for ( name in obj ) { 21318 return false; 21319 } 21320 return true; 21321 }, 21322 21323 // Evaluates a script in a global context 21324 globalEval: function( code, options ) { 21325 DOMEval( code, { nonce: options && options.nonce } ); 21326 }, 21327 21328 each: function( obj, callback ) { 21329 var length, i = 0; 21330 21331 if ( isArrayLike( obj ) ) { 21332 length = obj.length; 21333 for ( ; i < length; i++ ) { 21334 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { 21335 break; 21336 } 21337 } 21338 } else { 21339 for ( i in obj ) { 21340 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { 21341 break; 21342 } 21343 } 21344 } 21345 21346 return obj; 21347 }, 21348 21349 // Support: Android <=4.0 only 21350 trim: function( text ) { 21351 return text == null ? 21352 "" : 21353 ( text + "" ).replace( rtrim, "" ); 21354 }, 21355 21356 // results is for internal usage only 21357 makeArray: function( arr, results ) { 21358 var ret = results || []; 21359 21360 if ( arr != null ) { 21361 if ( isArrayLike( Object( arr ) ) ) { 21362 jQuery.merge( ret, 21363 typeof arr === "string" ? 21364 [ arr ] : arr 21365 ); 21366 } else { 21367 push.call( ret, arr ); 21368 } 21369 } 21370 21371 return ret; 21372 }, 21373 21374 inArray: function( elem, arr, i ) { 21375 return arr == null ? -1 : indexOf.call( arr, elem, i ); 21376 }, 21377 21378 // Support: Android <=4.0 only, PhantomJS 1 only 21379 // push.apply(_, arraylike) throws on ancient WebKit 21380 merge: function( first, second ) { 21381 var len = +second.length, 21382 j = 0, 21383 i = first.length; 21384 21385 for ( ; j < len; j++ ) { 21386 first[ i++ ] = second[ j ]; 21387 } 21388 21389 first.length = i; 21390 21391 return first; 21392 }, 21393 21394 grep: function( elems, callback, invert ) { 21395 var callbackInverse, 21396 matches = [], 21397 i = 0, 21398 length = elems.length, 21399 callbackExpect = !invert; 21400 21401 // Go through the array, only saving the items 21402 // that pass the validator function 21403 for ( ; i < length; i++ ) { 21404 callbackInverse = !callback( elems[ i ], i ); 21405 if ( callbackInverse !== callbackExpect ) { 21406 matches.push( elems[ i ] ); 21407 } 21408 } 21409 21410 return matches; 21411 }, 21412 21413 // arg is for internal usage only 21414 map: function( elems, callback, arg ) { 21415 var length, value, 21416 i = 0, 21417 ret = []; 21418 21419 // Go through the array, translating each of the items to their new values 21420 if ( isArrayLike( elems ) ) { 21421 length = elems.length; 21422 for ( ; i < length; i++ ) { 21423 value = callback( elems[ i ], i, arg ); 21424 21425 if ( value != null ) {
vendor: 4,136 bytes, lines 21426-21583
21426 ret.push( value ); 21427 } 21428 } 21429 21430 // Go through every key on the object, 21431 } else { 21432 for ( i in elems ) { 21433 value = callback( elems[ i ], i, arg ); 21434 21435 if ( value != null ) { 21436 ret.push( value ); 21437 } 21438 } 21439 } 21440 21441 // Flatten any nested arrays 21442 return concat.apply( [], ret ); 21443 }, 21444 21445 // A global GUID counter for objects 21446 guid: 1, 21447 21448 // jQuery.support is not used in Core but other projects attach their 21449 // properties to it so it needs to exist. 21450 support: support 21451} ); 21452 21453if ( typeof Symbol === "function" ) { 21454 jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; 21455} 21456 21457// Populate the class2type map 21458jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), 21459function( i, name ) { 21460 class2type[ "[object " + name + "]" ] = name.toLowerCase(); 21461} ); 21462 21463function isArrayLike( obj ) { 21464 21465 // Support: real iOS 8.2 only (not reproducible in simulator) 21466 // `in` check used to prevent JIT error (gh-2145) 21467 // hasOwn isn't used here due to false negatives 21468 // regarding Nodelist length in IE 21469 var length = !!obj && "length" in obj && obj.length, 21470 type = toType( obj ); 21471 21472 if ( isFunction( obj ) || isWindow( obj ) ) { 21473 return false; 21474 } 21475 21476 return type === "array" || length === 0 || 21477 typeof length === "number" && length > 0 && ( length - 1 ) in obj; 21478} 21479var Sizzle = 21480/*! 21481 * Sizzle CSS Selector Engine v2.3.4 21482 * https://sizzlejs.com/ 21483 * 21484 * Copyright JS Foundation and other contributors 21485 * Released under the MIT license 21486 * https://js.foundation/ 21487 * 21488 * Date: 2019-04-08 21489 */ 21490(function( window ) { 21491 21492var i, 21493 support, 21494 Expr, 21495 getText, 21496 isXML, 21497 tokenize, 21498 compile, 21499 select, 21500 outermostContext, 21501 sortInput, 21502 hasDuplicate, 21503 21504 // Local document vars 21505 setDocument, 21506 document, 21507 docElem, 21508 documentIsHTML, 21509 rbuggyQSA, 21510 rbuggyMatches, 21511 matches, 21512 contains, 21513 21514 // Instance-specific data 21515 expando = "sizzle" + 1 * new Date(), 21516 preferredDoc = window.document, 21517 dirruns = 0, 21518 done = 0, 21519 classCache = createCache(), 21520 tokenCache = createCache(), 21521 compilerCache = createCache(), 21522 nonnativeSelectorCache = createCache(), 21523 sortOrder = function( a, b ) { 21524 if ( a === b ) { 21525 hasDuplicate = true; 21526 } 21527 return 0; 21528 }, 21529 21530 // Instance methods 21531 hasOwn = ({}).hasOwnProperty, 21532 arr = [], 21533 pop = arr.pop, 21534 push_native = arr.push, 21535 push = arr.push, 21536 slice = arr.slice, 21537 // Use a stripped-down indexOf as it's faster than native 21538 // https://jsperf.com/thor-indexof-vs-for/5 21539 indexOf = function( list, elem ) { 21540 var i = 0, 21541 len = list.length; 21542 for ( ; i < len; i++ ) { 21543 if ( list[i] === elem ) { 21544 return i; 21545 } 21546 } 21547 return -1; 21548 }, 21549 21550 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", 21551 21552 // Regular expressions 21553 21554 // http://www.w3.org/TR/css3-selectors/#whitespace 21555 whitespace = "[\\x20\\t\\r\\n\\f]", 21556 21557 // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier 21558 identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", 21559 21560 // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors 21561 attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + 21562 // Operator (capture 2) 21563 "*([*^$|!~]?=)" + whitespace + 21564 // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" 21565 "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + 21566 "*\\]", 21567 21568 pseudos = ":(" + identifier + ")(?:\\((" + 21569 // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: 21570 // 1. quoted (capture 3; capture 4 or capture 5) 21571 "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + 21572 // 2. simple (capture 6) 21573 "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + 21574 // 3. anything else (capture 2) 21575 ".*" + 21576 ")\\)|)", 21577 21578 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter 21579 rwhitespace = new RegExp( whitespace + "+", "g" ), 21580 rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), 21581 21582 rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), 21583 rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
vendor: 4,615 bytes, lines 21584-21732
21584 rdescend = new RegExp( whitespace + "|>" ), 21585 21586 rpseudo = new RegExp( pseudos ), 21587 ridentifier = new RegExp( "^" + identifier + "$" ), 21588 21589 matchExpr = { 21590 "ID": new RegExp( "^#(" + identifier + ")" ), 21591 "CLASS": new RegExp( "^\\.(" + identifier + ")" ), 21592 "TAG": new RegExp( "^(" + identifier + "|[*])" ), 21593 "ATTR": new RegExp( "^" + attributes ), 21594 "PSEUDO": new RegExp( "^" + pseudos ), 21595 "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + 21596 "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + 21597 "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), 21598 "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), 21599 // For use in libraries implementing .is() 21600 // We use this for POS matching in `select` 21601 "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + 21602 whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) 21603 }, 21604 21605 rhtml = /HTML$/i, 21606 rinputs = /^(?:input|select|textarea|button)$/i, 21607 rheader = /^h\d$/i, 21608 21609 rnative = /^[^{]+\{\s*\[native \w/, 21610 21611 // Easily-parseable/retrievable ID or TAG or CLASS selectors 21612 rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, 21613 21614 rsibling = /[+~]/, 21615 21616 // CSS escapes 21617 // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters 21618 runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), 21619 funescape = function( _, escaped, escapedWhitespace ) { 21620 var high = "0x" + escaped - 0x10000; 21621 // NaN means non-codepoint 21622 // Support: Firefox<24 21623 // Workaround erroneous numeric interpretation of +"0x" 21624 return high !== high || escapedWhitespace ? 21625 escaped : 21626 high < 0 ? 21627 // BMP codepoint 21628 String.fromCharCode( high + 0x10000 ) : 21629 // Supplemental Plane codepoint (surrogate pair) 21630 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); 21631 }, 21632 21633 // CSS string/identifier serialization 21634 // https://drafts.csswg.org/cssom/#common-serializing-idioms 21635 rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, 21636 fcssescape = function( ch, asCodePoint ) { 21637 if ( asCodePoint ) { 21638 21639 // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER 21640 if ( ch === "\0" ) { 21641 return "\uFFFD"; 21642 } 21643 21644 // Control characters and (dependent upon position) numbers get escaped as code points 21645 return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; 21646 } 21647 21648 // Other potentially-special ASCII characters get backslash-escaped 21649 return "\\" + ch; 21650 }, 21651 21652 // Used for iframes 21653 // See setDocument() 21654 // Removing the function wrapper causes a "Permission Denied" 21655 // error in IE 21656 unloadHandler = function() { 21657 setDocument(); 21658 }, 21659 21660 inDisabledFieldset = addCombinator( 21661 function( elem ) { 21662 return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; 21663 }, 21664 { dir: "parentNode", next: "legend" } 21665 ); 21666 21667// Optimize for push.apply( _, NodeList ) 21668try { 21669 push.apply( 21670 (arr = slice.call( preferredDoc.childNodes )), 21671 preferredDoc.childNodes 21672 ); 21673 // Support: Android<4.0 21674 // Detect silently failing push.apply 21675 arr[ preferredDoc.childNodes.length ].nodeType; 21676} catch ( e ) { 21677 push = { apply: arr.length ? 21678 21679 // Leverage slice if possible 21680 function( target, els ) { 21681 push_native.apply( target, slice.call(els) ); 21682 } : 21683 21684 // Support: IE<9 21685 // Otherwise append directly 21686 function( target, els ) { 21687 var j = target.length, 21688 i = 0; 21689 // Can't trust NodeList.length 21690 while ( (target[j++] = els[i++]) ) {} 21691 target.length = j - 1; 21692 } 21693 }; 21694} 21695 21696function Sizzle( selector, context, results, seed ) { 21697 var m, i, elem, nid, match, groups, newSelector, 21698 newContext = context && context.ownerDocument, 21699 21700 // nodeType defaults to 9, since context defaults to document 21701 nodeType = context ? context.nodeType : 9; 21702 21703 results = results || []; 21704 21705 // Return early from calls with invalid selector or context 21706 if ( typeof selector !== "string" || !selector || 21707 nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { 21708 21709 return results; 21710 } 21711 21712 // Try to shortcut find operations (as opposed to filters) in HTML documents 21713 if ( !seed ) { 21714 21715 if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { 21716 setDocument( context ); 21717 } 21718 context = context || document; 21719 21720 if ( documentIsHTML ) { 21721 21722 // If the selector is sufficiently simple, try using a "get*By*" DOM method 21723 // (excepting DocumentFragment context, where the methods don't exist) 21724 if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { 21725 21726 // ID selector 21727 if ( (m = match[1]) ) { 21728 21729 // Document context 21730 if ( nodeType === 9 ) { 21731 if ( (elem = context.getElementById( m )) ) { 21732
vendor: 11,833 bytes, lines 21733-22140
21733 // Support: IE, Opera, Webkit 21734 // TODO: identify versions 21735 // getElementById can match elements by name instead of ID 21736 if ( elem.id === m ) { 21737 results.push( elem ); 21738 return results; 21739 } 21740 } else { 21741 return results; 21742 } 21743 21744 // Element context 21745 } else { 21746 21747 // Support: IE, Opera, Webkit 21748 // TODO: identify versions 21749 // getElementById can match elements by name instead of ID 21750 if ( newContext && (elem = newContext.getElementById( m )) && 21751 contains( context, elem ) && 21752 elem.id === m ) { 21753 21754 results.push( elem ); 21755 return results; 21756 } 21757 } 21758 21759 // Type selector 21760 } else if ( match[2] ) { 21761 push.apply( results, context.getElementsByTagName( selector ) ); 21762 return results; 21763 21764 // Class selector 21765 } else if ( (m = match[3]) && support.getElementsByClassName && 21766 context.getElementsByClassName ) { 21767 21768 push.apply( results, context.getElementsByClassName( m ) ); 21769 return results; 21770 } 21771 } 21772 21773 // Take advantage of querySelectorAll 21774 if ( support.qsa && 21775 !nonnativeSelectorCache[ selector + " " ] && 21776 (!rbuggyQSA || !rbuggyQSA.test( selector )) && 21777 21778 // Support: IE 8 only 21779 // Exclude object elements 21780 (nodeType !== 1 || context.nodeName.toLowerCase() !== "object") ) { 21781 21782 newSelector = selector; 21783 newContext = context; 21784 21785 // qSA considers elements outside a scoping root when evaluating child or 21786 // descendant combinators, which is not what we want. 21787 // In such cases, we work around the behavior by prefixing every selector in the 21788 // list with an ID selector referencing the scope context. 21789 // Thanks to Andrew Dupont for this technique. 21790 if ( nodeType === 1 && rdescend.test( selector ) ) { 21791 21792 // Capture the context ID, setting it first if necessary 21793 if ( (nid = context.getAttribute( "id" )) ) { 21794 nid = nid.replace( rcssescape, fcssescape ); 21795 } else { 21796 context.setAttribute( "id", (nid = expando) ); 21797 } 21798 21799 // Prefix every selector in the list 21800 groups = tokenize( selector ); 21801 i = groups.length; 21802 while ( i-- ) { 21803 groups[i] = "#" + nid + " " + toSelector( groups[i] ); 21804 } 21805 newSelector = groups.join( "," ); 21806 21807 // Expand context for sibling selectors 21808 newContext = rsibling.test( selector ) && testContext( context.parentNode ) || 21809 context; 21810 } 21811 21812 try { 21813 push.apply( results, 21814 newContext.querySelectorAll( newSelector ) 21815 ); 21816 return results; 21817 } catch ( qsaError ) { 21818 nonnativeSelectorCache( selector, true ); 21819 } finally { 21820 if ( nid === expando ) { 21821 context.removeAttribute( "id" ); 21822 } 21823 } 21824 } 21825 } 21826 } 21827 21828 // All others 21829 return select( selector.replace( rtrim, "$1" ), context, results, seed ); 21830} 21831 21832/** 21833 * Create key-value caches of limited size 21834 * @returns {function(string, object)} Returns the Object data after storing it on itself with 21835 * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) 21836 * deleting the oldest entry 21837 */ 21838function createCache() { 21839 var keys = []; 21840 21841 function cache( key, value ) { 21842 // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) 21843 if ( keys.push( key + " " ) > Expr.cacheLength ) { 21844 // Only keep the most recent entries 21845 delete cache[ keys.shift() ]; 21846 } 21847 return (cache[ key + " " ] = value); 21848 } 21849 return cache; 21850} 21851 21852/** 21853 * Mark a function for special use by Sizzle 21854 * @param {Function} fn The function to mark 21855 */ 21856function markFunction( fn ) { 21857 fn[ expando ] = true; 21858 return fn; 21859} 21860 21861/** 21862 * Support testing using an element 21863 * @param {Function} fn Passed the created element and returns a boolean result 21864 */ 21865function assert( fn ) { 21866 var el = document.createElement("fieldset"); 21867 21868 try { 21869 return !!fn( el ); 21870 } catch (e) { 21871 return false; 21872 } finally { 21873 // Remove from its parent by default 21874 if ( el.parentNode ) { 21875 el.parentNode.removeChild( el ); 21876 } 21877 // release memory in IE 21878 el = null; 21879 } 21880} 21881 21882/** 21883 * Adds the same handler for all of the specified attrs 21884 * @param {String} attrs Pipe-separated list of attributes 21885 * @param {Function} handler The method that will be applied 21886 */ 21887function addHandle( attrs, handler ) { 21888 var arr = attrs.split("|"), 21889 i = arr.length; 21890 21891 while ( i-- ) { 21892 Expr.attrHandle[ arr[i] ] = handler; 21893 } 21894} 21895 21896/** 21897 * Checks document order of two siblings 21898 * @param {Element} a 21899 * @param {Element} b 21900 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b 21901 */ 21902function siblingCheck( a, b ) { 21903 var cur = b && a, 21904 diff = cur && a.nodeType === 1 && b.nodeType === 1 && 21905 a.sourceIndex - b.sourceIndex; 21906 21907 // Use IE sourceIndex if available on both nodes 21908 if ( diff ) { 21909 return diff; 21910 } 21911 21912 // Check if b follows a 21913 if ( cur ) { 21914 while ( (cur = cur.nextSibling) ) { 21915 if ( cur === b ) { 21916 return -1; 21917 } 21918 } 21919 } 21920 21921 return a ? 1 : -1; 21922} 21923 21924/** 21925 * Returns a function to use in pseudos for input types 21926 * @param {String} type 21927 */ 21928function createInputPseudo( type ) { 21929 return function( elem ) { 21930 var name = elem.nodeName.toLowerCase(); 21931 return name === "input" && elem.type === type; 21932 }; 21933} 21934 21935/** 21936 * Returns a function to use in pseudos for buttons 21937 * @param {String} type 21938 */ 21939function createButtonPseudo( type ) { 21940 return function( elem ) { 21941 var name = elem.nodeName.toLowerCase(); 21942 return (name === "input" || name === "button") && elem.type === type; 21943 }; 21944} 21945 21946/** 21947 * Returns a function to use in pseudos for :enabled/:disabled 21948 * @param {Boolean} disabled true for :disabled; false for :enabled 21949 */ 21950function createDisabledPseudo( disabled ) { 21951 21952 // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable 21953 return function( elem ) { 21954 21955 // Only certain elements can match :enabled or :disabled 21956 // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled 21957 // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled 21958 if ( "form" in elem ) { 21959 21960 // Check for inherited disabledness on relevant non-disabled elements: 21961 // * listed form-associated elements in a disabled fieldset 21962 // https://html.spec.whatwg.org/multipage/forms.html#category-listed 21963 // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled 21964 // * option elements in a disabled optgroup 21965 // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled 21966 // All such elements have a "form" property. 21967 if ( elem.parentNode && elem.disabled === false ) { 21968 21969 // Option elements defer to a parent optgroup if present 21970 if ( "label" in elem ) { 21971 if ( "label" in elem.parentNode ) { 21972 return elem.parentNode.disabled === disabled; 21973 } else { 21974 return elem.disabled === disabled; 21975 } 21976 } 21977 21978 // Support: IE 6 - 11 21979 // Use the isDisabled shortcut property to check for disabled fieldset ancestors 21980 return elem.isDisabled === disabled || 21981 21982 // Where there is no isDisabled, check manually 21983 /* jshint -W018 */ 21984 elem.isDisabled !== !disabled && 21985 inDisabledFieldset( elem ) === disabled; 21986 } 21987 21988 return elem.disabled === disabled; 21989 21990 // Try to winnow out elements that can't be disabled before trusting the disabled property. 21991 // Some victims get caught in our net (label, legend, menu, track), but it shouldn't 21992 // even exist on them, let alone have a boolean value. 21993 } else if ( "label" in elem ) { 21994 return elem.disabled === disabled; 21995 } 21996 21997 // Remaining elements are neither :enabled nor :disabled 21998 return false; 21999 }; 22000} 22001 22002/** 22003 * Returns a function to use in pseudos for positionals 22004 * @param {Function} fn 22005 */ 22006function createPositionalPseudo( fn ) { 22007 return markFunction(function( argument ) { 22008 argument = +argument; 22009 return markFunction(function( seed, matches ) { 22010 var j, 22011 matchIndexes = fn( [], seed.length, argument ), 22012 i = matchIndexes.length; 22013 22014 // Match elements found at the specified indexes 22015 while ( i-- ) { 22016 if ( seed[ (j = matchIndexes[i]) ] ) { 22017 seed[j] = !(matches[j] = seed[j]); 22018 } 22019 } 22020 }); 22021 }); 22022} 22023 22024/** 22025 * Checks a node for validity as a Sizzle context 22026 * @param {Element|Object=} context 22027 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value 22028 */ 22029function testContext( context ) { 22030 return context && typeof context.getElementsByTagName !== "undefined" && context; 22031} 22032 22033// Expose support vars for convenience 22034support = Sizzle.support = {}; 22035 22036/** 22037 * Detects XML nodes 22038 * @param {Element|Object} elem An element or a document 22039 * @returns {Boolean} True iff elem is a non-HTML XML node 22040 */ 22041isXML = Sizzle.isXML = function( elem ) { 22042 var namespace = elem.namespaceURI, 22043 docElem = (elem.ownerDocument || elem).documentElement; 22044 22045 // Support: IE <=8 22046 // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes 22047 // https://bugs.jquery.com/ticket/4833 22048 return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); 22049}; 22050 22051/** 22052 * Sets document-related variables once based on the current document 22053 * @param {Element|Object} [doc] An element or document object to use to set the document 22054 * @returns {Object} Returns the current document 22055 */ 22056setDocument = Sizzle.setDocument = function( node ) { 22057 var hasCompare, subWindow, 22058 doc = node ? node.ownerDocument || node : preferredDoc; 22059 22060 // Return early if doc is invalid or already selected 22061 if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { 22062 return document; 22063 } 22064 22065 // Update global variables 22066 document = doc; 22067 docElem = document.documentElement; 22068 documentIsHTML = !isXML( document ); 22069 22070 // Support: IE 9-11, Edge 22071 // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) 22072 if ( preferredDoc !== document && 22073 (subWindow = document.defaultView) && subWindow.top !== subWindow ) { 22074 22075 // Support: IE 11, Edge 22076 if ( subWindow.addEventListener ) { 22077 subWindow.addEventListener( "unload", unloadHandler, false ); 22078 22079 // Support: IE 9 - 10 only 22080 } else if ( subWindow.attachEvent ) { 22081 subWindow.attachEvent( "onunload", unloadHandler ); 22082 } 22083 } 22084 22085 /* Attributes 22086 ---------------------------------------------------------------------- */ 22087 22088 // Support: IE<8 22089 // Verify that getAttribute really returns attributes and not properties 22090 // (excepting IE8 booleans) 22091 support.attributes = assert(function( el ) { 22092 el.className = "i"; 22093 return !el.getAttribute("className"); 22094 }); 22095 22096 /* getElement(s)By* 22097 ---------------------------------------------------------------------- */ 22098 22099 // Check if getElementsByTagName("*") returns only elements 22100 support.getElementsByTagName = assert(function( el ) { 22101 el.appendChild( document.createComment("") ); 22102 return !el.getElementsByTagName("*").length; 22103 }); 22104 22105 // Support: IE<9 22106 support.getElementsByClassName = rnative.test( document.getElementsByClassName ); 22107 22108 // Support: IE<10 22109 // Check if getElementById returns elements by name 22110 // The broken getElementById methods don't pick up programmatically-set names, 22111 // so use a roundabout getElementsByName test 22112 support.getById = assert(function( el ) { 22113 docElem.appendChild( el ).id = expando; 22114 return !document.getElementsByName || !document.getElementsByName( expando ).length; 22115 }); 22116 22117 // ID filter and find 22118 if ( support.getById ) { 22119 Expr.filter["ID"] = function( id ) { 22120 var attrId = id.replace( runescape, funescape ); 22121 return function( elem ) { 22122 return elem.getAttribute("id") === attrId; 22123 }; 22124 }; 22125 Expr.find["ID"] = function( id, context ) { 22126 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { 22127 var elem = context.getElementById( id ); 22128 return elem ? [ elem ] : []; 22129 } 22130 }; 22131 } else { 22132 Expr.filter["ID"] = function( id ) { 22133 var attrId = id.replace( runescape, funescape ); 22134 return function( elem ) { 22135 var node = typeof elem.getAttributeNode !== "undefined" && 22136 elem.getAttributeNode("id"); 22137 return node && node.value === attrId; 22138 }; 22139 }; 22140
vendor: 4,318 bytes, lines 22141-22276
22141 // Support: IE 6 - 7 only 22142 // getElementById is not reliable as a find shortcut 22143 Expr.find["ID"] = function( id, context ) { 22144 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { 22145 var node, i, elems, 22146 elem = context.getElementById( id ); 22147 22148 if ( elem ) { 22149 22150 // Verify the id attribute 22151 node = elem.getAttributeNode("id"); 22152 if ( node && node.value === id ) { 22153 return [ elem ]; 22154 } 22155 22156 // Fall back on getElementsByName 22157 elems = context.getElementsByName( id ); 22158 i = 0; 22159 while ( (elem = elems[i++]) ) { 22160 node = elem.getAttributeNode("id"); 22161 if ( node && node.value === id ) { 22162 return [ elem ]; 22163 } 22164 } 22165 } 22166 22167 return []; 22168 } 22169 }; 22170 } 22171 22172 // Tag 22173 Expr.find["TAG"] = support.getElementsByTagName ? 22174 function( tag, context ) { 22175 if ( typeof context.getElementsByTagName !== "undefined" ) { 22176 return context.getElementsByTagName( tag ); 22177 22178 // DocumentFragment nodes don't have gEBTN 22179 } else if ( support.qsa ) { 22180 return context.querySelectorAll( tag ); 22181 } 22182 } : 22183 22184 function( tag, context ) { 22185 var elem, 22186 tmp = [], 22187 i = 0, 22188 // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too 22189 results = context.getElementsByTagName( tag ); 22190 22191 // Filter out possible comments 22192 if ( tag === "*" ) { 22193 while ( (elem = results[i++]) ) { 22194 if ( elem.nodeType === 1 ) { 22195 tmp.push( elem ); 22196 } 22197 } 22198 22199 return tmp; 22200 } 22201 return results; 22202 }; 22203 22204 // Class 22205 Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { 22206 if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { 22207 return context.getElementsByClassName( className ); 22208 } 22209 }; 22210 22211 /* QSA/matchesSelector 22212 ---------------------------------------------------------------------- */ 22213 22214 // QSA and matchesSelector support 22215 22216 // matchesSelector(:active) reports false when true (IE9/Opera 11.5) 22217 rbuggyMatches = []; 22218 22219 // qSa(:focus) reports false when true (Chrome 21) 22220 // We allow this because of a bug in IE8/9 that throws an error 22221 // whenever `document.activeElement` is accessed on an iframe 22222 // So, we allow :focus to pass through QSA all the time to avoid the IE error 22223 // See https://bugs.jquery.com/ticket/13378 22224 rbuggyQSA = []; 22225 22226 if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { 22227 // Build QSA regex 22228 // Regex strategy adopted from Diego Perini 22229 assert(function( el ) { 22230 // Select is set to empty string on purpose 22231 // This is to test IE's treatment of not explicitly 22232 // setting a boolean content attribute, 22233 // since its presence should be enough 22234 // https://bugs.jquery.com/ticket/12359 22235 docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" + 22236 "<select id='" + expando + "-\r\\' msallowcapture=''>" + 22237 "<option selected=''></option></select>"; 22238 22239 // Support: IE8, Opera 11-12.16 22240 // Nothing should be selected when empty strings follow ^= or $= or *= 22241 // The test attribute must be unknown in Opera but "safe" for WinRT 22242 // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section 22243 if ( el.querySelectorAll("[msallowcapture^='']").length ) { 22244 rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); 22245 } 22246 22247 // Support: IE8 22248 // Boolean attributes and "value" are not treated correctly 22249 if ( !el.querySelectorAll("[selected]").length ) { 22250 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); 22251 } 22252 22253 // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ 22254 if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { 22255 rbuggyQSA.push("~="); 22256 } 22257 22258 // Webkit/Opera - :checked should return selected option elements 22259 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 22260 // IE8 throws error here and will not see later tests 22261 if ( !el.querySelectorAll(":checked").length ) { 22262 rbuggyQSA.push(":checked"); 22263 } 22264 22265 // Support: Safari 8+, iOS 8+ 22266 // https://bugs.webkit.org/show_bug.cgi?id=136851 22267 // In-page `selector#id sibling-combinator selector` fails 22268 if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { 22269 rbuggyQSA.push(".#.+[+~]"); 22270 } 22271 }); 22272 22273 assert(function( el ) { 22274 el.innerHTML = "<a href='' disabled='disabled'></a>" + 22275 "<select disabled='disabled'><option/></select>"; 22276
vendor: 6,799 bytes, lines 22277-22523
22277 // Support: Windows 8 Native Apps 22278 // The type and name attributes are restricted during .innerHTML assignment 22279 var input = document.createElement("input"); 22280 input.setAttribute( "type", "hidden" ); 22281 el.appendChild( input ).setAttribute( "name", "D" ); 22282 22283 // Support: IE8 22284 // Enforce case-sensitivity of name attribute 22285 if ( el.querySelectorAll("[name=d]").length ) { 22286 rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); 22287 } 22288 22289 // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) 22290 // IE8 throws error here and will not see later tests 22291 if ( el.querySelectorAll(":enabled").length !== 2 ) { 22292 rbuggyQSA.push( ":enabled", ":disabled" ); 22293 } 22294 22295 // Support: IE9-11+ 22296 // IE's :disabled selector does not pick up the children of disabled fieldsets 22297 docElem.appendChild( el ).disabled = true; 22298 if ( el.querySelectorAll(":disabled").length !== 2 ) { 22299 rbuggyQSA.push( ":enabled", ":disabled" ); 22300 } 22301 22302 // Opera 10-11 does not throw on post-comma invalid pseudos 22303 el.querySelectorAll("*,:x"); 22304 rbuggyQSA.push(",.*:"); 22305 }); 22306 } 22307 22308 if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || 22309 docElem.webkitMatchesSelector || 22310 docElem.mozMatchesSelector || 22311 docElem.oMatchesSelector || 22312 docElem.msMatchesSelector) )) ) { 22313 22314 assert(function( el ) { 22315 // Check to see if it's possible to do matchesSelector 22316 // on a disconnected node (IE 9) 22317 support.disconnectedMatch = matches.call( el, "*" ); 22318 22319 // This should fail with an exception 22320 // Gecko does not error, returns false instead 22321 matches.call( el, "[s!='']:x" ); 22322 rbuggyMatches.push( "!=", pseudos ); 22323 }); 22324 } 22325 22326 rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); 22327 rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); 22328 22329 /* Contains 22330 ---------------------------------------------------------------------- */ 22331 hasCompare = rnative.test( docElem.compareDocumentPosition ); 22332 22333 // Element contains another 22334 // Purposefully self-exclusive 22335 // As in, an element does not contain itself 22336 contains = hasCompare || rnative.test( docElem.contains ) ? 22337 function( a, b ) { 22338 var adown = a.nodeType === 9 ? a.documentElement : a, 22339 bup = b && b.parentNode; 22340 return a === bup || !!( bup && bup.nodeType === 1 && ( 22341 adown.contains ? 22342 adown.contains( bup ) : 22343 a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 22344 )); 22345 } : 22346 function( a, b ) { 22347 if ( b ) { 22348 while ( (b = b.parentNode) ) { 22349 if ( b === a ) { 22350 return true; 22351 } 22352 } 22353 } 22354 return false; 22355 }; 22356 22357 /* Sorting 22358 ---------------------------------------------------------------------- */ 22359 22360 // Document order sorting 22361 sortOrder = hasCompare ? 22362 function( a, b ) { 22363 22364 // Flag for duplicate removal 22365 if ( a === b ) { 22366 hasDuplicate = true; 22367 return 0; 22368 } 22369 22370 // Sort on method existence if only one input has compareDocumentPosition 22371 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; 22372 if ( compare ) { 22373 return compare; 22374 } 22375 22376 // Calculate position if both inputs belong to the same document 22377 compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? 22378 a.compareDocumentPosition( b ) : 22379 22380 // Otherwise we know they are disconnected 22381 1; 22382 22383 // Disconnected nodes 22384 if ( compare & 1 || 22385 (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { 22386 22387 // Choose the first element that is related to our preferred document 22388 if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { 22389 return -1; 22390 } 22391 if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { 22392 return 1; 22393 } 22394 22395 // Maintain original order 22396 return sortInput ? 22397 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 22398 0; 22399 } 22400 22401 return compare & 4 ? -1 : 1; 22402 } : 22403 function( a, b ) { 22404 // Exit early if the nodes are identical 22405 if ( a === b ) { 22406 hasDuplicate = true; 22407 return 0; 22408 } 22409 22410 var cur, 22411 i = 0, 22412 aup = a.parentNode, 22413 bup = b.parentNode, 22414 ap = [ a ], 22415 bp = [ b ]; 22416 22417 // Parentless nodes are either documents or disconnected 22418 if ( !aup || !bup ) { 22419 return a === document ? -1 : 22420 b === document ? 1 : 22421 aup ? -1 : 22422 bup ? 1 : 22423 sortInput ? 22424 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 22425 0; 22426 22427 // If the nodes are siblings, we can do a quick check 22428 } else if ( aup === bup ) { 22429 return siblingCheck( a, b ); 22430 } 22431 22432 // Otherwise we need full lists of their ancestors for comparison 22433 cur = a; 22434 while ( (cur = cur.parentNode) ) { 22435 ap.unshift( cur ); 22436 } 22437 cur = b; 22438 while ( (cur = cur.parentNode) ) { 22439 bp.unshift( cur ); 22440 } 22441 22442 // Walk down the tree looking for a discrepancy 22443 while ( ap[i] === bp[i] ) { 22444 i++; 22445 } 22446 22447 return i ? 22448 // Do a sibling check if the nodes have a common ancestor 22449 siblingCheck( ap[i], bp[i] ) : 22450 22451 // Otherwise nodes in our document sort first 22452 ap[i] === preferredDoc ? -1 : 22453 bp[i] === preferredDoc ? 1 : 22454 0; 22455 }; 22456 22457 return document; 22458}; 22459 22460Sizzle.matches = function( expr, elements ) { 22461 return Sizzle( expr, null, null, elements ); 22462}; 22463 22464Sizzle.matchesSelector = function( elem, expr ) { 22465 // Set document vars if needed 22466 if ( ( elem.ownerDocument || elem ) !== document ) { 22467 setDocument( elem ); 22468 } 22469 22470 if ( support.matchesSelector && documentIsHTML && 22471 !nonnativeSelectorCache[ expr + " " ] && 22472 ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && 22473 ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { 22474 22475 try { 22476 var ret = matches.call( elem, expr ); 22477 22478 // IE 9's matchesSelector returns false on disconnected nodes 22479 if ( ret || support.disconnectedMatch || 22480 // As well, disconnected nodes are said to be in a document 22481 // fragment in IE 9 22482 elem.document && elem.document.nodeType !== 11 ) { 22483 return ret; 22484 } 22485 } catch (e) { 22486 nonnativeSelectorCache( expr, true ); 22487 } 22488 } 22489 22490 return Sizzle( expr, document, null, [ elem ] ).length > 0; 22491}; 22492 22493Sizzle.contains = function( context, elem ) { 22494 // Set document vars if needed 22495 if ( ( context.ownerDocument || context ) !== document ) { 22496 setDocument( context ); 22497 } 22498 return contains( context, elem ); 22499}; 22500 22501Sizzle.attr = function( elem, name ) { 22502 // Set document vars if needed 22503 if ( ( elem.ownerDocument || elem ) !== document ) { 22504 setDocument( elem ); 22505 } 22506 22507 var fn = Expr.attrHandle[ name.toLowerCase() ], 22508 // Don't get fooled by Object.prototype properties (jQuery #13807) 22509 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? 22510 fn( elem, name, !documentIsHTML ) : 22511 undefined; 22512 22513 return val !== undefined ? 22514 val : 22515 support.attributes || !documentIsHTML ? 22516 elem.getAttribute( name ) : 22517 (val = elem.getAttributeNode(name)) && val.specified ? 22518 val.value : 22519 null; 22520}; 22521 22522Sizzle.escape = function( sel ) { 22523 return (sel + "").replace( rcssescape, fcssescape )
vendor: 11,991 bytes, lines 22523-22946
22523; 22524}; 22525 22526Sizzle.error = function( msg ) { 22527 throw new Error( "Syntax error, unrecognized expression: " + msg ); 22528}; 22529 22530/** 22531 * Document sorting and removing duplicates 22532 * @param {ArrayLike} results 22533 */ 22534Sizzle.uniqueSort = function( results ) { 22535 var elem, 22536 duplicates = [], 22537 j = 0, 22538 i = 0; 22539 22540 // Unless we *know* we can detect duplicates, assume their presence 22541 hasDuplicate = !support.detectDuplicates; 22542 sortInput = !support.sortStable && results.slice( 0 ); 22543 results.sort( sortOrder ); 22544 22545 if ( hasDuplicate ) { 22546 while ( (elem = results[i++]) ) { 22547 if ( elem === results[ i ] ) { 22548 j = duplicates.push( i ); 22549 } 22550 } 22551 while ( j-- ) { 22552 results.splice( duplicates[ j ], 1 ); 22553 } 22554 } 22555 22556 // Clear input after sorting to release objects 22557 // See https://github.com/jquery/sizzle/pull/225 22558 sortInput = null; 22559 22560 return results; 22561}; 22562 22563/** 22564 * Utility function for retrieving the text value of an array of DOM nodes 22565 * @param {Array|Element} elem 22566 */ 22567getText = Sizzle.getText = function( elem ) { 22568 var node, 22569 ret = "", 22570 i = 0, 22571 nodeType = elem.nodeType; 22572 22573 if ( !nodeType ) { 22574 // If no nodeType, this is expected to be an array 22575 while ( (node = elem[i++]) ) { 22576 // Do not traverse comment nodes 22577 ret += getText( node ); 22578 } 22579 } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { 22580 // Use textContent for elements 22581 // innerText usage removed for consistency of new lines (jQuery #11153) 22582 if ( typeof elem.textContent === "string" ) { 22583 return elem.textContent; 22584 } else { 22585 // Traverse its children 22586 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 22587 ret += getText( elem ); 22588 } 22589 } 22590 } else if ( nodeType === 3 || nodeType === 4 ) { 22591 return elem.nodeValue; 22592 } 22593 // Do not include comment or processing instruction nodes 22594 22595 return ret; 22596}; 22597 22598Expr = Sizzle.selectors = { 22599 22600 // Can be adjusted by the user 22601 cacheLength: 50, 22602 22603 createPseudo: markFunction, 22604 22605 match: matchExpr, 22606 22607 attrHandle: {}, 22608 22609 find: {}, 22610 22611 relative: { 22612 ">": { dir: "parentNode", first: true }, 22613 " ": { dir: "parentNode" }, 22614 "+": { dir: "previousSibling", first: true }, 22615 "~": { dir: "previousSibling" } 22616 }, 22617 22618 preFilter: { 22619 "ATTR": function( match ) { 22620 match[1] = match[1].replace( runescape, funescape ); 22621 22622 // Move the given value to match[3] whether quoted or unquoted 22623 match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); 22624 22625 if ( match[2] === "~=" ) { 22626 match[3] = " " + match[3] + " "; 22627 } 22628 22629 return match.slice( 0, 4 ); 22630 }, 22631 22632 "CHILD": function( match ) { 22633 /* matches from matchExpr["CHILD"] 22634 1 type (only|nth|...) 22635 2 what (child|of-type) 22636 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 22637 4 xn-component of xn+y argument ([+-]?\d*n|) 22638 5 sign of xn-component 22639 6 x of xn-component 22640 7 sign of y-component 22641 8 y of y-component 22642 */ 22643 match[1] = match[1].toLowerCase(); 22644 22645 if ( match[1].slice( 0, 3 ) === "nth" ) { 22646 // nth-* requires argument 22647 if ( !match[3] ) { 22648 Sizzle.error( match[0] ); 22649 } 22650 22651 // numeric x and y parameters for Expr.filter.CHILD 22652 // remember that false/true cast respectively to 0/1 22653 match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); 22654 match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); 22655 22656 // other types prohibit arguments 22657 } else if ( match[3] ) { 22658 Sizzle.error( match[0] ); 22659 } 22660 22661 return match; 22662 }, 22663 22664 "PSEUDO": function( match ) { 22665 var excess, 22666 unquoted = !match[6] && match[2]; 22667 22668 if ( matchExpr["CHILD"].test( match[0] ) ) { 22669 return null; 22670 } 22671 22672 // Accept quoted arguments as-is 22673 if ( match[3] ) { 22674 match[2] = match[4] || match[5] || ""; 22675 22676 // Strip excess characters from unquoted arguments 22677 } else if ( unquoted && rpseudo.test( unquoted ) && 22678 // Get excess from tokenize (recursively) 22679 (excess = tokenize( unquoted, true )) && 22680 // advance to the next closing parenthesis 22681 (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { 22682 22683 // excess is a negative index 22684 match[0] = match[0].slice( 0, excess ); 22685 match[2] = unquoted.slice( 0, excess ); 22686 } 22687 22688 // Return only captures needed by the pseudo filter method (type and argument) 22689 return match.slice( 0, 3 ); 22690 } 22691 }, 22692 22693 filter: { 22694 22695 "TAG": function( nodeNameSelector ) { 22696 var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); 22697 return nodeNameSelector === "*" ? 22698 function() { return true; } : 22699 function( elem ) { 22700 return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; 22701 }; 22702 }, 22703 22704 "CLASS": function( className ) { 22705 var pattern = classCache[ className + " " ]; 22706 22707 return pattern || 22708 (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && 22709 classCache( className, function( elem ) { 22710 return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); 22711 }); 22712 }, 22713 22714 "ATTR": function( name, operator, check ) { 22715 return function( elem ) { 22716 var result = Sizzle.attr( elem, name ); 22717 22718 if ( result == null ) { 22719 return operator === "!="; 22720 } 22721 if ( !operator ) { 22722 return true; 22723 } 22724 22725 result += ""; 22726 22727 return operator === "=" ? result === check : 22728 operator === "!=" ? result !== check : 22729 operator === "^=" ? check && result.indexOf( check ) === 0 : 22730 operator === "*=" ? check && result.indexOf( check ) > -1 : 22731 operator === "$=" ? check && result.slice( -check.length ) === check : 22732 operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : 22733 operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : 22734 false; 22735 }; 22736 }, 22737 22738 "CHILD": function( type, what, argument, first, last ) { 22739 var simple = type.slice( 0, 3 ) !== "nth", 22740 forward = type.slice( -4 ) !== "last", 22741 ofType = what === "of-type"; 22742 22743 return first === 1 && last === 0 ? 22744 22745 // Shortcut for :nth-*(n) 22746 function( elem ) { 22747 return !!elem.parentNode; 22748 } : 22749 22750 function( elem, context, xml ) { 22751 var cache, uniqueCache, outerCache, node, nodeIndex, start, 22752 dir = simple !== forward ? "nextSibling" : "previousSibling", 22753 parent = elem.parentNode, 22754 name = ofType && elem.nodeName.toLowerCase(), 22755 useCache = !xml && !ofType, 22756 diff = false; 22757 22758 if ( parent ) { 22759 22760 // :(first|last|only)-(child|of-type) 22761 if ( simple ) { 22762 while ( dir ) { 22763 node = elem; 22764 while ( (node = node[ dir ]) ) { 22765 if ( ofType ? 22766 node.nodeName.toLowerCase() === name : 22767 node.nodeType === 1 ) { 22768 22769 return false; 22770 } 22771 } 22772 // Reverse direction for :only-* (if we haven't yet done so) 22773 start = dir = type === "only" && !start && "nextSibling"; 22774 } 22775 return true; 22776 } 22777 22778 start = [ forward ? parent.firstChild : parent.lastChild ]; 22779 22780 // non-xml :nth-child(...) stores cache data on `parent` 22781 if ( forward && useCache ) { 22782 22783 // Seek `elem` from a previously-cached index 22784 22785 // ...in a gzip-friendly way 22786 node = parent; 22787 outerCache = node[ expando ] || (node[ expando ] = {}); 22788 22789 // Support: IE <9 only 22790 // Defend against cloned attroperties (jQuery gh-1709) 22791 uniqueCache = outerCache[ node.uniqueID ] || 22792 (outerCache[ node.uniqueID ] = {}); 22793 22794 cache = uniqueCache[ type ] || []; 22795 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; 22796 diff = nodeIndex && cache[ 2 ]; 22797 node = nodeIndex && parent.childNodes[ nodeIndex ]; 22798 22799 while ( (node = ++nodeIndex && node && node[ dir ] || 22800 22801 // Fallback to seeking `elem` from the start 22802 (diff = nodeIndex = 0) || start.pop()) ) { 22803 22804 // When found, cache indexes on `parent` and break 22805 if ( node.nodeType === 1 && ++diff && node === elem ) { 22806 uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; 22807 break; 22808 } 22809 } 22810 22811 } else { 22812 // Use previously-cached element index if available 22813 if ( useCache ) { 22814 // ...in a gzip-friendly way 22815 node = elem; 22816 outerCache = node[ expando ] || (node[ expando ] = {}); 22817 22818 // Support: IE <9 only 22819 // Defend against cloned attroperties (jQuery gh-1709) 22820 uniqueCache = outerCache[ node.uniqueID ] || 22821 (outerCache[ node.uniqueID ] = {}); 22822 22823 cache = uniqueCache[ type ] || []; 22824 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; 22825 diff = nodeIndex; 22826 } 22827 22828 // xml :nth-child(...) 22829 // or :nth-last-child(...) or :nth(-last)?-of-type(...) 22830 if ( diff === false ) { 22831 // Use the same loop as above to seek `elem` from the start 22832 while ( (node = ++nodeIndex && node && node[ dir ] || 22833 (diff = nodeIndex = 0) || start.pop()) ) { 22834 22835 if ( ( ofType ? 22836 node.nodeName.toLowerCase() === name : 22837 node.nodeType === 1 ) && 22838 ++diff ) { 22839 22840 // Cache the index of each encountered element 22841 if ( useCache ) { 22842 outerCache = node[ expando ] || (node[ expando ] = {}); 22843 22844 // Support: IE <9 only 22845 // Defend against cloned attroperties (jQuery gh-1709) 22846 uniqueCache = outerCache[ node.uniqueID ] || 22847 (outerCache[ node.uniqueID ] = {}); 22848 22849 uniqueCache[ type ] = [ dirruns, diff ]; 22850 } 22851 22852 if ( node === elem ) { 22853 break; 22854 } 22855 } 22856 } 22857 } 22858 } 22859 22860 // Incorporate the offset, then check against cycle size 22861 diff -= last; 22862 return diff === first || ( diff % first === 0 && diff / first >= 0 ); 22863 } 22864 }; 22865 }, 22866 22867 "PSEUDO": function( pseudo, argument ) { 22868 // pseudo-class names are case-insensitive 22869 // http://www.w3.org/TR/selectors/#pseudo-classes 22870 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters 22871 // Remember that setFilters inherits from pseudos 22872 var args, 22873 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || 22874 Sizzle.error( "unsupported pseudo: " + pseudo ); 22875 22876 // The user may use createPseudo to indicate that 22877 // arguments are needed to create the filter function 22878 // just as Sizzle does 22879 if ( fn[ expando ] ) { 22880 return fn( argument ); 22881 } 22882 22883 // But maintain support for old signatures 22884 if ( fn.length > 1 ) { 22885 args = [ pseudo, pseudo, "", argument ]; 22886 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? 22887 markFunction(function( seed, matches ) { 22888 var idx, 22889 matched = fn( seed, argument ), 22890 i = matched.length; 22891 while ( i-- ) { 22892 idx = indexOf( seed, matched[i] ); 22893 seed[ idx ] = !( matches[ idx ] = matched[i] ); 22894 } 22895 }) : 22896 function( elem ) { 22897 return fn( elem, 0, args ); 22898 }; 22899 } 22900 22901 return fn; 22902 } 22903 }, 22904 22905 pseudos: { 22906 // Potentially complex pseudos 22907 "not": markFunction(function( selector ) { 22908 // Trim the selector passed to compile 22909 // to avoid treating leading and trailing 22910 // spaces as combinators 22911 var input = [], 22912 results = [], 22913 matcher = compile( selector.replace( rtrim, "$1" ) ); 22914 22915 return matcher[ expando ] ? 22916 markFunction(function( seed, matches, context, xml ) { 22917 var elem, 22918 unmatched = matcher( seed, null, xml, [] ), 22919 i = seed.length; 22920 22921 // Match elements unmatched by `matcher` 22922 while ( i-- ) { 22923 if ( (elem = unmatched[i]) ) { 22924 seed[i] = !(matches[i] = elem); 22925 } 22926 } 22927 }) : 22928 function( elem, context, xml ) { 22929 input[0] = elem; 22930 matcher( input, null, xml, results ); 22931 // Don't keep the element (issue #299) 22932 input[0] = null; 22933 return !results.pop(); 22934 }; 22935 }), 22936 22937 "has": markFunction(function( selector ) { 22938 return function( elem ) { 22939 return Sizzle( selector, elem ).length > 0; 22940 }; 22941 }), 22942 22943 "contains": markFunction(function( text ) { 22944 text = text.replace( runescape, funescape ); 22945 return function( elem ) { 22946 return ( elem.textContent ||
vendor: 1,115 bytes, lines 22946-22974
22946getText( elem ) ).indexOf( text ) > -1; 22947 }; 22948 }), 22949 22950 // "Whether an element is represented by a :lang() selector 22951 // is based solely on the element's language value 22952 // being equal to the identifier C, 22953 // or beginning with the identifier C immediately followed by "-". 22954 // The matching of C against the element's language value is performed case-insensitively. 22955 // The identifier C does not have to be a valid language name." 22956 // http://www.w3.org/TR/selectors/#lang-pseudo 22957 "lang": markFunction( function( lang ) { 22958 // lang value must be a valid identifier 22959 if ( !ridentifier.test(lang || "") ) { 22960 Sizzle.error( "unsupported lang: " + lang ); 22961 } 22962 lang = lang.replace( runescape, funescape ).toLowerCase(); 22963 return function( elem ) { 22964 var elemLang; 22965 do { 22966 if ( (elemLang = documentIsHTML ? 22967 elem.lang : 22968 elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { 22969 22970 elemLang = elemLang.toLowerCase(); 22971 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; 22972 } 22973 } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); 22974 return false;
vendor: 3,169 bytes, lines 22975-23089
22975 }; 22976 }), 22977 22978 // Miscellaneous 22979 "target": function( elem ) { 22980 var hash = window.location && window.location.hash; 22981 return hash && hash.slice( 1 ) === elem.id; 22982 }, 22983 22984 "root": function( elem ) { 22985 return elem === docElem; 22986 }, 22987 22988 "focus": function( elem ) { 22989 return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); 22990 }, 22991 22992 // Boolean properties 22993 "enabled": createDisabledPseudo( false ), 22994 "disabled": createDisabledPseudo( true ), 22995 22996 "checked": function( elem ) { 22997 // In CSS3, :checked should return both checked and selected elements 22998 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 22999 var nodeName = elem.nodeName.toLowerCase(); 23000 return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); 23001 }, 23002 23003 "selected": function( elem ) { 23004 // Accessing this property makes selected-by-default 23005 // options in Safari work properly 23006 if ( elem.parentNode ) { 23007 elem.parentNode.selectedIndex; 23008 } 23009 23010 return elem.selected === true; 23011 }, 23012 23013 // Contents 23014 "empty": function( elem ) { 23015 // http://www.w3.org/TR/selectors/#empty-pseudo 23016 // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), 23017 // but not by others (comment: 8; processing instruction: 7; etc.) 23018 // nodeType < 6 works because attributes (2) do not appear as children 23019 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 23020 if ( elem.nodeType < 6 ) { 23021 return false; 23022 } 23023 } 23024 return true; 23025 }, 23026 23027 "parent": function( elem ) { 23028 return !Expr.pseudos["empty"]( elem ); 23029 }, 23030 23031 // Element/input types 23032 "header": function( elem ) { 23033 return rheader.test( elem.nodeName ); 23034 }, 23035 23036 "input": function( elem ) { 23037 return rinputs.test( elem.nodeName ); 23038 }, 23039 23040 "button": function( elem ) { 23041 var name = elem.nodeName.toLowerCase(); 23042 return name === "input" && elem.type === "button" || name === "button"; 23043 }, 23044 23045 "text": function( elem ) { 23046 var attr; 23047 return elem.nodeName.toLowerCase() === "input" && 23048 elem.type === "text" && 23049 23050 // Support: IE<8 23051 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" 23052 ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); 23053 }, 23054 23055 // Position-in-collection 23056 "first": createPositionalPseudo(function() { 23057 return [ 0 ]; 23058 }), 23059 23060 "last": createPositionalPseudo(function( matchIndexes, length ) { 23061 return [ length - 1 ]; 23062 }), 23063 23064 "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { 23065 return [ argument < 0 ? argument + length : argument ]; 23066 }), 23067 23068 "even": createPositionalPseudo(function( matchIndexes, length ) { 23069 var i = 0; 23070 for ( ; i < length; i += 2 ) { 23071 matchIndexes.push( i ); 23072 } 23073 return matchIndexes; 23074 }), 23075 23076 "odd": createPositionalPseudo(function( matchIndexes, length ) { 23077 var i = 1; 23078 for ( ; i < length; i += 2 ) { 23079 matchIndexes.push( i ); 23080 } 23081 return matchIndexes; 23082 }), 23083 23084 "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { 23085 var i = argument < 0 ? 23086 argument + length : 23087 argument > length ? 23088 length : 23089
vendor: 20,845 bytes, lines 23089-23850
23089argument; 23090 for ( ; --i >= 0; ) { 23091 matchIndexes.push( i ); 23092 } 23093 return matchIndexes; 23094 }), 23095 23096 "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { 23097 var i = argument < 0 ? argument + length : argument; 23098 for ( ; ++i < length; ) { 23099 matchIndexes.push( i ); 23100 } 23101 return matchIndexes; 23102 }) 23103 } 23104}; 23105 23106Expr.pseudos["nth"] = Expr.pseudos["eq"]; 23107 23108// Add button/input type pseudos 23109for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { 23110 Expr.pseudos[ i ] = createInputPseudo( i ); 23111} 23112for ( i in { submit: true, reset: true } ) { 23113 Expr.pseudos[ i ] = createButtonPseudo( i ); 23114} 23115 23116// Easy API for creating new setFilters 23117function setFilters() {} 23118setFilters.prototype = Expr.filters = Expr.pseudos; 23119Expr.setFilters = new setFilters(); 23120 23121tokenize = Sizzle.tokenize = function( selector, parseOnly ) { 23122 var matched, match, tokens, type, 23123 soFar, groups, preFilters, 23124 cached = tokenCache[ selector + " " ]; 23125 23126 if ( cached ) { 23127 return parseOnly ? 0 : cached.slice( 0 ); 23128 } 23129 23130 soFar = selector; 23131 groups = []; 23132 preFilters = Expr.preFilter; 23133 23134 while ( soFar ) { 23135 23136 // Comma and first run 23137 if ( !matched || (match = rcomma.exec( soFar )) ) { 23138 if ( match ) { 23139 // Don't consume trailing commas as valid 23140 soFar = soFar.slice( match[0].length ) || soFar; 23141 } 23142 groups.push( (tokens = []) ); 23143 } 23144 23145 matched = false; 23146 23147 // Combinators 23148 if ( (match = rcombinators.exec( soFar )) ) { 23149 matched = match.shift(); 23150 tokens.push({ 23151 value: matched, 23152 // Cast descendant combinators to space 23153 type: match[0].replace( rtrim, " " ) 23154 }); 23155 soFar = soFar.slice( matched.length ); 23156 } 23157 23158 // Filters 23159 for ( type in Expr.filter ) { 23160 if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || 23161 (match = preFilters[ type ]( match ))) ) { 23162 matched = match.shift(); 23163 tokens.push({ 23164 value: matched, 23165 type: type, 23166 matches: match 23167 }); 23168 soFar = soFar.slice( matched.length ); 23169 } 23170 } 23171 23172 if ( !matched ) { 23173 break; 23174 } 23175 } 23176 23177 // Return the length of the invalid excess 23178 // if we're just parsing 23179 // Otherwise, throw an error or return tokens 23180 return parseOnly ? 23181 soFar.length : 23182 soFar ? 23183 Sizzle.error( selector ) : 23184 // Cache the tokens 23185 tokenCache( selector, groups ).slice( 0 ); 23186}; 23187 23188function toSelector( tokens ) { 23189 var i = 0, 23190 len = tokens.length, 23191 selector = ""; 23192 for ( ; i < len; i++ ) { 23193 selector += tokens[i].value; 23194 } 23195 return selector; 23196} 23197 23198function addCombinator( matcher, combinator, base ) { 23199 var dir = combinator.dir, 23200 skip = combinator.next, 23201 key = skip || dir, 23202 checkNonElements = base && key === "parentNode", 23203 doneName = done++; 23204 23205 return combinator.first ? 23206 // Check against closest ancestor/preceding element 23207 function( elem, context, xml ) { 23208 while ( (elem = elem[ dir ]) ) { 23209 if ( elem.nodeType === 1 || checkNonElements ) { 23210 return matcher( elem, context, xml ); 23211 } 23212 } 23213 return false; 23214 } : 23215 23216 // Check against all ancestor/preceding elements 23217 function( elem, context, xml ) { 23218 var oldCache, uniqueCache, outerCache, 23219 newCache = [ dirruns, doneName ]; 23220 23221 // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching 23222 if ( xml ) { 23223 while ( (elem = elem[ dir ]) ) { 23224 if ( elem.nodeType === 1 || checkNonElements ) { 23225 if ( matcher( elem, context, xml ) ) { 23226 return true; 23227 } 23228 } 23229 } 23230 } else { 23231 while ( (elem = elem[ dir ]) ) { 23232 if ( elem.nodeType === 1 || checkNonElements ) { 23233 outerCache = elem[ expando ] || (elem[ expando ] = {}); 23234 23235 // Support: IE <9 only 23236 // Defend against cloned attroperties (jQuery gh-1709) 23237 uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); 23238 23239 if ( skip && skip === elem.nodeName.toLowerCase() ) { 23240 elem = elem[ dir ] || elem; 23241 } else if ( (oldCache = uniqueCache[ key ]) && 23242 oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { 23243 23244 // Assign to newCache so results back-propagate to previous elements 23245 return (newCache[ 2 ] = oldCache[ 2 ]); 23246 } else { 23247 // Reuse newcache so results back-propagate to previous elements 23248 uniqueCache[ key ] = newCache; 23249 23250 // A match means we're done; a fail means we have to keep checking 23251 if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { 23252 return true; 23253 } 23254 } 23255 } 23256 } 23257 } 23258 return false; 23259 }; 23260} 23261 23262function elementMatcher( matchers ) { 23263 return matchers.length > 1 ? 23264 function( elem, context, xml ) { 23265 var i = matchers.length; 23266 while ( i-- ) { 23267 if ( !matchers[i]( elem, context, xml ) ) { 23268 return false; 23269 } 23270 } 23271 return true; 23272 } : 23273 matchers[0]; 23274} 23275 23276function multipleContexts( selector, contexts, results ) { 23277 var i = 0, 23278 len = contexts.length; 23279 for ( ; i < len; i++ ) { 23280 Sizzle( selector, contexts[i], results ); 23281 } 23282 return results; 23283} 23284 23285function condense( unmatched, map, filter, context, xml ) { 23286 var elem, 23287 newUnmatched = [], 23288 i = 0, 23289 len = unmatched.length, 23290 mapped = map != null; 23291 23292 for ( ; i < len; i++ ) { 23293 if ( (elem = unmatched[i]) ) { 23294 if ( !filter || filter( elem, context, xml ) ) { 23295 newUnmatched.push( elem ); 23296 if ( mapped ) { 23297 map.push( i ); 23298 } 23299 } 23300 } 23301 } 23302 23303 return newUnmatched; 23304} 23305 23306function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { 23307 if ( postFilter && !postFilter[ expando ] ) { 23308 postFilter = setMatcher( postFilter ); 23309 } 23310 if ( postFinder && !postFinder[ expando ] ) { 23311 postFinder = setMatcher( postFinder, postSelector ); 23312 } 23313 return markFunction(function( seed, results, context, xml ) { 23314 var temp, i, elem, 23315 preMap = [], 23316 postMap = [], 23317 preexisting = results.length, 23318 23319 // Get initial elements from seed or context 23320 elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), 23321 23322 // Prefilter to get matcher input, preserving a map for seed-results synchronization 23323 matcherIn = preFilter && ( seed || !selector ) ? 23324 condense( elems, preMap, preFilter, context, xml ) : 23325 elems, 23326 23327 matcherOut = matcher ? 23328 // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, 23329 postFinder || ( seed ? preFilter : preexisting || postFilter ) ? 23330 23331 // ...intermediate processing is necessary 23332 [] : 23333 23334 // ...otherwise use results directly 23335 results : 23336 matcherIn; 23337 23338 // Find primary matches 23339 if ( matcher ) { 23340 matcher( matcherIn, matcherOut, context, xml ); 23341 } 23342 23343 // Apply postFilter 23344 if ( postFilter ) { 23345 temp = condense( matcherOut, postMap ); 23346 postFilter( temp, [], context, xml ); 23347 23348 // Un-match failing elements by moving them back to matcherIn 23349 i = temp.length; 23350 while ( i-- ) { 23351 if ( (elem = temp[i]) ) { 23352 matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); 23353 } 23354 } 23355 } 23356 23357 if ( seed ) { 23358 if ( postFinder || preFilter ) { 23359 if ( postFinder ) { 23360 // Get the final matcherOut by condensing this intermediate into postFinder contexts 23361 temp = []; 23362 i = matcherOut.length; 23363 while ( i-- ) { 23364 if ( (elem = matcherOut[i]) ) { 23365 // Restore matcherIn since elem is not yet a final match 23366 temp.push( (matcherIn[i] = elem) ); 23367 } 23368 } 23369 postFinder( null, (matcherOut = []), temp, xml ); 23370 } 23371 23372 // Move matched elements from seed to results to keep them synchronized 23373 i = matcherOut.length; 23374 while ( i-- ) { 23375 if ( (elem = matcherOut[i]) && 23376 (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { 23377 23378 seed[temp] = !(results[temp] = elem); 23379 } 23380 } 23381 } 23382 23383 // Add elements to results, through postFinder if defined 23384 } else { 23385 matcherOut = condense( 23386 matcherOut === results ? 23387 matcherOut.splice( preexisting, matcherOut.length ) : 23388 matcherOut 23389 ); 23390 if ( postFinder ) { 23391 postFinder( null, results, matcherOut, xml ); 23392 } else { 23393 push.apply( results, matcherOut ); 23394 } 23395 } 23396 }); 23397} 23398 23399function matcherFromTokens( tokens ) { 23400 var checkContext, matcher, j, 23401 len = tokens.length, 23402 leadingRelative = Expr.relative[ tokens[0].type ], 23403 implicitRelative = leadingRelative || Expr.relative[" "], 23404 i = leadingRelative ? 1 : 0, 23405 23406 // The foundational matcher ensures that elements are reachable from top-level context(s) 23407 matchContext = addCombinator( function( elem ) { 23408 return elem === checkContext; 23409 }, implicitRelative, true ), 23410 matchAnyContext = addCombinator( function( elem ) { 23411 return indexOf( checkContext, elem ) > -1; 23412 }, implicitRelative, true ), 23413 matchers = [ function( elem, context, xml ) { 23414 var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( 23415 (checkContext = context).nodeType ? 23416 matchContext( elem, context, xml ) : 23417 matchAnyContext( elem, context, xml ) ); 23418 // Avoid hanging onto element (issue #299) 23419 checkContext = null; 23420 return ret; 23421 } ]; 23422 23423 for ( ; i < len; i++ ) { 23424 if ( (matcher = Expr.relative[ tokens[i].type ]) ) { 23425 matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; 23426 } else { 23427 matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); 23428 23429 // Return special upon seeing a positional matcher 23430 if ( matcher[ expando ] ) { 23431 // Find the next relative operator (if any) for proper handling 23432 j = ++i; 23433 for ( ; j < len; j++ ) { 23434 if ( Expr.relative[ tokens[j].type ] ) { 23435 break; 23436 } 23437 } 23438 return setMatcher( 23439 i > 1 && elementMatcher( matchers ), 23440 i > 1 && toSelector( 23441 // If the preceding token was a descendant combinator, insert an implicit any-element `*` 23442 tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) 23443 ).replace( rtrim, "$1" ), 23444 matcher, 23445 i < j && matcherFromTokens( tokens.slice( i, j ) ), 23446 j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), 23447 j < len && toSelector( tokens ) 23448 ); 23449 } 23450 matchers.push( matcher ); 23451 } 23452 } 23453 23454 return elementMatcher( matchers ); 23455} 23456 23457function matcherFromGroupMatchers( elementMatchers, setMatchers ) { 23458 var bySet = setMatchers.length > 0, 23459 byElement = elementMatchers.length > 0, 23460 superMatcher = function( seed, context, xml, results, outermost ) { 23461 var elem, j, matcher, 23462 matchedCount = 0, 23463 i = "0", 23464 unmatched = seed && [], 23465 setMatched = [], 23466 contextBackup = outermostContext, 23467 // We must always have either seed elements or outermost context 23468 elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), 23469 // Use integer dirruns iff this is the outermost matcher 23470 dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), 23471 len = elems.length; 23472 23473 if ( outermost ) { 23474 outermostContext = context === document || context || outermost; 23475 } 23476 23477 // Add elements passing elementMatchers directly to results 23478 // Support: IE<9, Safari 23479 // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id 23480 for ( ; i !== len && (elem = elems[i]) != null; i++ ) { 23481 if ( byElement && elem ) { 23482 j = 0; 23483 if ( !context && elem.ownerDocument !== document ) { 23484 setDocument( elem ); 23485 xml = !documentIsHTML; 23486 } 23487 while ( (matcher = elementMatchers[j++]) ) { 23488 if ( matcher( elem, context || document, xml) ) { 23489 results.push( elem ); 23490 break; 23491 } 23492 } 23493 if ( outermost ) { 23494 dirruns = dirrunsUnique; 23495 } 23496 } 23497 23498 // Track unmatched elements for set filters 23499 if ( bySet ) { 23500 // They will have gone through all possible matchers 23501 if ( (elem = !matcher && elem) ) { 23502 matchedCount--; 23503 } 23504 23505 // Lengthen the array for every element, matched or not 23506 if ( seed ) { 23507 unmatched.push( elem ); 23508 } 23509 } 23510 } 23511 23512 // `i` is now the count of elements visited above, and adding it to `matchedCount` 23513 // makes the latter nonnegative. 23514 matchedCount += i; 23515 23516 // Apply set filters to unmatched elements 23517 // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` 23518 // equals `i`), unless we didn't visit _any_ elements in the above loop because we have 23519 // no element matchers and no seed. 23520 // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that 23521 // case, which will result in a "00" `matchedCount` that differs from `i` but is also 23522 // numerically zero. 23523 if ( bySet && i !== matchedCount ) { 23524 j = 0; 23525 while ( (matcher = setMatchers[j++]) ) { 23526 matcher( unmatched, setMatched, context, xml ); 23527 } 23528 23529 if ( seed ) { 23530 // Reintegrate element matches to eliminate the need for sorting 23531 if ( matchedCount > 0 ) { 23532 while ( i-- ) { 23533 if ( !(unmatched[i] || setMatched[i]) ) { 23534 setMatched[i] = pop.call( results ); 23535 } 23536 } 23537 } 23538 23539 // Discard index placeholder values to get only actual matches 23540 setMatched = condense( setMatched ); 23541 } 23542 23543 // Add matches to results 23544 push.apply( results, setMatched ); 23545 23546 // Seedless set matches succeeding multiple successful matchers stipulate sorting 23547 if ( outermost && !seed && setMatched.length > 0 && 23548 ( matchedCount + setMatchers.length ) > 1 ) { 23549 23550 Sizzle.uniqueSort( results ); 23551 } 23552 } 23553 23554 // Override manipulation of globals by nested matchers 23555 if ( outermost ) { 23556 dirruns = dirrunsUnique; 23557 outermostContext = contextBackup; 23558 } 23559 23560 return unmatched; 23561 }; 23562 23563 return bySet ? 23564 markFunction( superMatcher ) : 23565 superMatcher; 23566} 23567 23568compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { 23569 var i, 23570 setMatchers = [], 23571 elementMatchers = [], 23572 cached = compilerCache[ selector + " " ]; 23573 23574 if ( !cached ) { 23575 // Generate a function of recursive functions that can be used to check each element 23576 if ( !match ) { 23577 match = tokenize( selector ); 23578 } 23579 i = match.length; 23580 while ( i-- ) { 23581 cached = matcherFromTokens( match[i] ); 23582 if ( cached[ expando ] ) { 23583 setMatchers.push( cached ); 23584 } else { 23585 elementMatchers.push( cached ); 23586 } 23587 } 23588 23589 // Cache the compiled function 23590 cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); 23591 23592 // Save selector and tokenization 23593 cached.selector = selector; 23594 } 23595 return cached; 23596}; 23597 23598/** 23599 * A low-level selection function that works with Sizzle's compiled 23600 * selector functions 23601 * @param {String|Function} selector A selector or a pre-compiled 23602 * selector function built with Sizzle.compile 23603 * @param {Element} context 23604 * @param {Array} [results] 23605 * @param {Array} [seed] A set of elements to match against 23606 */ 23607select = Sizzle.select = function( selector, context, results, seed ) { 23608 var i, tokens, token, type, find, 23609 compiled = typeof selector === "function" && selector, 23610 match = !seed && tokenize( (selector = compiled.selector || selector) ); 23611 23612 results = results || []; 23613 23614 // Try to minimize operations if there is only one selector in the list and no seed 23615 // (the latter of which guarantees us context) 23616 if ( match.length === 1 ) { 23617 23618 // Reduce context if the leading compound selector is an ID 23619 tokens = match[0] = match[0].slice( 0 ); 23620 if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && 23621 context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) { 23622 23623 context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; 23624 if ( !context ) { 23625 return results; 23626 23627 // Precompiled matchers will still verify ancestry, so step up a level 23628 } else if ( compiled ) { 23629 context = context.parentNode; 23630 } 23631 23632 selector = selector.slice( tokens.shift().value.length ); 23633 } 23634 23635 // Fetch a seed set for right-to-left matching 23636 i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; 23637 while ( i-- ) { 23638 token = tokens[i]; 23639 23640 // Abort if we hit a combinator 23641 if ( Expr.relative[ (type = token.type) ] ) { 23642 break; 23643 } 23644 if ( (find = Expr.find[ type ]) ) { 23645 // Search, expanding context for leading sibling combinators 23646 if ( (seed = find( 23647 token.matches[0].replace( runescape, funescape ), 23648 rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context 23649 )) ) { 23650 23651 // If seed is empty or no tokens remain, we can return early 23652 tokens.splice( i, 1 ); 23653 selector = seed.length && toSelector( tokens ); 23654 if ( !selector ) { 23655 push.apply( results, seed ); 23656 return results; 23657 } 23658 23659 break; 23660 } 23661 } 23662 } 23663 } 23664 23665 // Compile and execute a filtering function if one is not provided 23666 // Provide `match` to avoid retokenization if we modified the selector above 23667 ( compiled || compile( selector, match ) )( 23668 seed, 23669 context, 23670 !documentIsHTML, 23671 results, 23672 !context || rsibling.test( selector ) && testContext( context.parentNode ) || context 23673 ); 23674 return results; 23675}; 23676 23677// One-time assignments 23678 23679// Sort stability 23680support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; 23681 23682// Support: Chrome 14-35+ 23683// Always assume duplicates if they aren't passed to the comparison function 23684support.detectDuplicates = !!hasDuplicate; 23685 23686// Initialize against the default document 23687setDocument(); 23688 23689// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) 23690// Detached nodes confoundingly follow *each other* 23691support.sortDetached = assert(function( el ) { 23692 // Should return 1, but returns 4 (following) 23693 return el.compareDocumentPosition( document.createElement("fieldset") ) & 1; 23694}); 23695 23696// Support: IE<8 23697// Prevent attribute/property "interpolation" 23698// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx 23699if ( !assert(function( el ) { 23700 el.innerHTML = "<a href='#'></a>"; 23701 return el.firstChild.getAttribute("href") === "#" ; 23702}) ) { 23703 addHandle( "type|href|height|width", function( elem, name, isXML ) { 23704 if ( !isXML ) { 23705 return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); 23706 } 23707 }); 23708} 23709 23710// Support: IE<9 23711// Use defaultValue in place of getAttribute("value") 23712if ( !support.attributes || !assert(function( el ) { 23713 el.innerHTML = "<input/>"; 23714 el.firstChild.setAttribute( "value", "" ); 23715 return el.firstChild.getAttribute( "value" ) === ""; 23716}) ) { 23717 addHandle( "value", function( elem, name, isXML ) { 23718 if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { 23719 return elem.defaultValue; 23720 } 23721 }); 23722} 23723 23724// Support: IE<9 23725// Use getAttributeNode to fetch booleans when getAttribute lies 23726if ( !assert(function( el ) { 23727 return el.getAttribute("disabled") == null; 23728}) ) { 23729 addHandle( booleans, function( elem, name, isXML ) { 23730 var val; 23731 if ( !isXML ) { 23732 return elem[ name ] === true ? name.toLowerCase() : 23733 (val = elem.getAttributeNode( name )) && val.specified ? 23734 val.value : 23735 null; 23736 } 23737 }); 23738} 23739 23740return Sizzle; 23741 23742})( window ); 23743 23744 23745 23746jQuery.find = Sizzle; 23747jQuery.expr = Sizzle.selectors; 23748 23749// Deprecated 23750jQuery.expr[ ":" ] = jQuery.expr.pseudos; 23751jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; 23752jQuery.text = Sizzle.getText; 23753jQuery.isXMLDoc = Sizzle.isXML; 23754jQuery.contains = Sizzle.contains; 23755jQuery.escapeSelector = Sizzle.escape; 23756 23757 23758 23759 23760var dir = function( elem, dir, until ) { 23761 var matched = [], 23762 truncate = until !== undefined; 23763 23764 while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { 23765 if ( elem.nodeType === 1 ) { 23766 if ( truncate && jQuery( elem ).is( until ) ) { 23767 break; 23768 } 23769 matched.push( elem ); 23770 } 23771 } 23772 return matched; 23773}; 23774 23775 23776var siblings = function( n, elem ) { 23777 var matched = []; 23778 23779 for ( ; n; n = n.nextSibling ) { 23780 if ( n.nodeType === 1 && n !== elem ) { 23781 matched.push( n ); 23782 } 23783 } 23784 23785 return matched; 23786}; 23787 23788 23789var rneedsContext = jQuery.expr.match.needsContext; 23790 23791 23792 23793function nodeName( elem, name ) { 23794 23795 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); 23796 23797}; 23798var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); 23799 23800 23801 23802// Implement the identical functionality for filter and not 23803function winnow( elements, qualifier, not ) { 23804 if ( isFunction( qualifier ) ) { 23805 return jQuery.grep( elements, function( elem, i ) { 23806 return !!qualifier.call( elem, i, elem ) !== not; 23807 } ); 23808 } 23809 23810 // Single element 23811 if ( qualifier.nodeType ) { 23812 return jQuery.grep( elements, function( elem ) { 23813 return ( elem === qualifier ) !== not; 23814 } ); 23815 } 23816 23817 // Arraylike of elements (jQuery, arguments, Array) 23818 if ( typeof qualifier !== "string" ) { 23819 return jQuery.grep( elements, function( elem ) { 23820 return ( indexOf.call( qualifier, elem ) > -1 ) !== not; 23821 } ); 23822 } 23823 23824 // Filtered directly for both simple and complex selectors 23825 return jQuery.filter( qualifier, elements, not ); 23826} 23827 23828jQuery.filter = function( expr, elems, not ) { 23829 var elem = elems[ 0 ]; 23830 23831 if ( not ) { 23832 expr = ":not(" + expr + ")"; 23833 } 23834 23835 if ( elems.length === 1 && elem.nodeType === 1 ) { 23836 return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; 23837 } 23838 23839 return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { 23840 return elem.nodeType === 1; 23841 } ) ); 23842}; 23843 23844jQuery.fn.extend( { 23845 find: function( selector ) { 23846 var i, ret, 23847 len = this.length, 23848 self = this; 23849 23850 if ( typeof selector !== "string" ) {
vendor: 6,536 bytes, lines 23851-24111
23851 return this.pushStack( jQuery( selector ).filter( function() { 23852 for ( i = 0; i < len; i++ ) { 23853 if ( jQuery.contains( self[ i ], this ) ) { 23854 return true; 23855 } 23856 } 23857 } ) ); 23858 } 23859 23860 ret = this.pushStack( [] ); 23861 23862 for ( i = 0; i < len; i++ ) { 23863 jQuery.find( selector, self[ i ], ret ); 23864 } 23865 23866 return len > 1 ? jQuery.uniqueSort( ret ) : ret; 23867 }, 23868 filter: function( selector ) { 23869 return this.pushStack( winnow( this, selector || [], false ) ); 23870 }, 23871 not: function( selector ) { 23872 return this.pushStack( winnow( this, selector || [], true ) ); 23873 }, 23874 is: function( selector ) { 23875 return !!winnow( 23876 this, 23877 23878 // If this is a positional/relative selector, check membership in the returned set 23879 // so $("p:first").is("p:last") won't return true for a doc with two "p". 23880 typeof selector === "string" && rneedsContext.test( selector ) ? 23881 jQuery( selector ) : 23882 selector || [], 23883 false 23884 ).length; 23885 } 23886} ); 23887 23888 23889// Initialize a jQuery object 23890 23891 23892// A central reference to the root jQuery(document) 23893var rootjQuery, 23894 23895 // A simple way to check for HTML strings 23896 // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) 23897 // Strict HTML recognition (#11290: must start with <) 23898 // Shortcut simple #id case for speed 23899 rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, 23900 23901 init = jQuery.fn.init = function( selector, context, root ) { 23902 var match, elem; 23903 23904 // HANDLE: $(""), $(null), $(undefined), $(false) 23905 if ( !selector ) { 23906 return this; 23907 } 23908 23909 // Method init() accepts an alternate rootjQuery 23910 // so migrate can support jQuery.sub (gh-2101) 23911 root = root || rootjQuery; 23912 23913 // Handle HTML strings 23914 if ( typeof selector === "string" ) { 23915 if ( selector[ 0 ] === "<" && 23916 selector[ selector.length - 1 ] === ">" && 23917 selector.length >= 3 ) { 23918 23919 // Assume that strings that start and end with <> are HTML and skip the regex check 23920 match = [ null, selector, null ]; 23921 23922 } else { 23923 match = rquickExpr.exec( selector ); 23924 } 23925 23926 // Match html or make sure no context is specified for #id 23927 if ( match && ( match[ 1 ] || !context ) ) { 23928 23929 // HANDLE: $(html) -> $(array) 23930 if ( match[ 1 ] ) { 23931 context = context instanceof jQuery ? context[ 0 ] : context; 23932 23933 // Option to run scripts is true for back-compat 23934 // Intentionally let the error be thrown if parseHTML is not present 23935 jQuery.merge( this, jQuery.parseHTML( 23936 match[ 1 ], 23937 context && context.nodeType ? context.ownerDocument || context : document, 23938 true 23939 ) ); 23940 23941 // HANDLE: $(html, props) 23942 if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { 23943 for ( match in context ) { 23944 23945 // Properties of context are called as methods if possible 23946 if ( isFunction( this[ match ] ) ) { 23947 this[ match ]( context[ match ] ); 23948 23949 // ...and otherwise set as attributes 23950 } else { 23951 this.attr( match, context[ match ] ); 23952 } 23953 } 23954 } 23955 23956 return this; 23957 23958 // HANDLE: $(#id) 23959 } else { 23960 elem = document.getElementById( match[ 2 ] ); 23961 23962 if ( elem ) { 23963 23964 // Inject the element directly into the jQuery object 23965 this[ 0 ] = elem; 23966 this.length = 1; 23967 } 23968 return this; 23969 } 23970 23971 // HANDLE: $(expr, $(...)) 23972 } else if ( !context || context.jquery ) { 23973 return ( context || root ).find( selector ); 23974 23975 // HANDLE: $(expr, context) 23976 // (which is just equivalent to: $(context).find(expr) 23977 } else { 23978 return this.constructor( context ).find( selector ); 23979 } 23980 23981 // HANDLE: $(DOMElement) 23982 } else if ( selector.nodeType ) { 23983 this[ 0 ] = selector; 23984 this.length = 1; 23985 return this; 23986 23987 // HANDLE: $(function) 23988 // Shortcut for document ready 23989 } else if ( isFunction( selector ) ) { 23990 return root.ready !== undefined ? 23991 root.ready( selector ) : 23992 23993 // Execute immediately if ready is not present 23994 selector( jQuery ); 23995 } 23996 23997 return jQuery.makeArray( selector, this ); 23998 }; 23999 24000// Give the init function the jQuery prototype for later instantiation 24001init.prototype = jQuery.fn; 24002 24003// Initialize central reference 24004rootjQuery = jQuery( document ); 24005 24006 24007var rparentsprev = /^(?:parents|prev(?:Until|All))/, 24008 24009 // Methods guaranteed to produce a unique set when starting from a unique set 24010 guaranteedUnique = { 24011 children: true, 24012 contents: true, 24013 next: true, 24014 prev: true 24015 }; 24016 24017jQuery.fn.extend( { 24018 has: function( target ) { 24019 var targets = jQuery( target, this ), 24020 l = targets.length; 24021 24022 return this.filter( function() { 24023 var i = 0; 24024 for ( ; i < l; i++ ) { 24025 if ( jQuery.contains( this, targets[ i ] ) ) { 24026 return true; 24027 } 24028 } 24029 } ); 24030 }, 24031 24032 closest: function( selectors, context ) { 24033 var cur, 24034 i = 0, 24035 l = this.length, 24036 matched = [], 24037 targets = typeof selectors !== "string" && jQuery( selectors ); 24038 24039 // Positional selectors never match, since there's no _selection_ context 24040 if ( !rneedsContext.test( selectors ) ) { 24041 for ( ; i < l; i++ ) { 24042 for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { 24043 24044 // Always skip document fragments 24045 if ( cur.nodeType < 11 && ( targets ? 24046 targets.index( cur ) > -1 : 24047 24048 // Don't pass non-elements to Sizzle 24049 cur.nodeType === 1 && 24050 jQuery.find.matchesSelector( cur, selectors ) ) ) { 24051 24052 matched.push( cur ); 24053 break; 24054 } 24055 } 24056 } 24057 } 24058 24059 return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); 24060 }, 24061 24062 // Determine the position of an element within the set 24063 index: function( elem ) { 24064 24065 // No argument, return index in parent 24066 if ( !elem ) { 24067 return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; 24068 } 24069 24070 // Index in selector 24071 if ( typeof elem === "string" ) { 24072 return indexOf.call( jQuery( elem ), this[ 0 ] ); 24073 } 24074 24075 // Locate the position of the desired element 24076 return indexOf.call( this, 24077 24078 // If it receives a jQuery object, the first element is used 24079 elem.jquery ? elem[ 0 ] : elem 24080 ); 24081 }, 24082 24083 add: function( selector, context ) { 24084 return this.pushStack( 24085 jQuery.uniqueSort( 24086 jQuery.merge( this.get(), jQuery( selector, context ) ) 24087 ) 24088 ); 24089 }, 24090 24091 addBack: function( selector ) { 24092 return this.add( selector == null ? 24093 this.prevObject : this.prevObject.filter( selector ) 24094 ); 24095 } 24096} ); 24097 24098function sibling( cur, dir ) { 24099 while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} 24100 return cur; 24101} 24102 24103jQuery.each( { 24104 parent: function( elem ) { 24105 var parent = elem.parentNode; 24106 return parent && parent.nodeType !== 11 ? parent : null; 24107 }, 24108 parents: function( elem ) { 24109 return dir( elem, "parentNode" ); 24110 }, 24111 parentsUntil: function( elem,
24111i, until ) { 24112 return dir( elem, "parentNode", until ); 24113 }, 24114 next: function( elem ) { 24115 return sibling( elem, "nextSibling" ); 24116 }, 24117 prev: function( elem ) { 24118 return sibling( elem, "previousSibling" ); 24119 }, 24120 nextAll: function( elem ) { 24121 return dir( elem, "nextSibling" ); 24122 }, 24123 prevAll: function( elem ) { 24124 return dir( elem, "previousSibling" ); 24125 }, 24126 nextUntil: function( elem, i, until ) { 24127 return dir( elem, "nextSibling", until ); 24128 }, 24129 prevUntil: function( elem, i, until ) { 24130 return dir( elem, "previousSibling", until ); 24131 }, 24132 siblings: function( elem ) { 24133 return siblings( ( elem.parentNode || {} ).firstChild, elem ); 24134 }, 24135 children: function( elem ) { 24136 return siblings( elem.firstChild ); 24137 }, 24138 contents: function( elem ) { 24139 if ( typeof elem.contentDocument !== "undefined" ) {
vendor: 8,211 bytes, lines 24139-24473
24139 24140 return elem.contentDocument; 24141 } 24142 24143 // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only 24144 // Treat the template element as a regular one in browsers that 24145 // don't support it. 24146 if ( nodeName( elem, "template" ) ) { 24147 elem = elem.content || elem; 24148 } 24149 24150 return jQuery.merge( [], elem.childNodes ); 24151 } 24152}, function( name, fn ) { 24153 jQuery.fn[ name ] = function( until, selector ) { 24154 var matched = jQuery.map( this, fn, until ); 24155 24156 if ( name.slice( -5 ) !== "Until" ) { 24157 selector = until; 24158 } 24159 24160 if ( selector && typeof selector === "string" ) { 24161 matched = jQuery.filter( selector, matched ); 24162 } 24163 24164 if ( this.length > 1 ) { 24165 24166 // Remove duplicates 24167 if ( !guaranteedUnique[ name ] ) { 24168 jQuery.uniqueSort( matched ); 24169 } 24170 24171 // Reverse order for parents* and prev-derivatives 24172 if ( rparentsprev.test( name ) ) { 24173 matched.reverse(); 24174 } 24175 } 24176 24177 return this.pushStack( matched ); 24178 }; 24179} ); 24180var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); 24181 24182 24183 24184// Convert String-formatted options into Object-formatted ones 24185function createOptions( options ) { 24186 var object = {}; 24187 jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { 24188 object[ flag ] = true; 24189 } ); 24190 return object; 24191} 24192 24193/* 24194 * Create a callback list using the following parameters: 24195 * 24196 * options: an optional list of space-separated options that will change how 24197 * the callback list behaves or a more traditional option object 24198 * 24199 * By default a callback list will act like an event callback list and can be 24200 * "fired" multiple times. 24201 * 24202 * Possible options: 24203 * 24204 * once: will ensure the callback list can only be fired once (like a Deferred) 24205 * 24206 * memory: will keep track of previous values and will call any callback added 24207 * after the list has been fired right away with the latest "memorized" 24208 * values (like a Deferred) 24209 * 24210 * unique: will ensure a callback can only be added once (no duplicate in the list) 24211 * 24212 * stopOnFalse: interrupt callings when a callback returns false 24213 * 24214 */ 24215jQuery.Callbacks = function( options ) { 24216 24217 // Convert options from String-formatted to Object-formatted if needed 24218 // (we check in cache first) 24219 options = typeof options === "string" ? 24220 createOptions( options ) : 24221 jQuery.extend( {}, options ); 24222 24223 var // Flag to know if list is currently firing 24224 firing, 24225 24226 // Last fire value for non-forgettable lists 24227 memory, 24228 24229 // Flag to know if list was already fired 24230 fired, 24231 24232 // Flag to prevent firing 24233 locked, 24234 24235 // Actual callback list 24236 list = [], 24237 24238 // Queue of execution data for repeatable lists 24239 queue = [], 24240 24241 // Index of currently firing callback (modified by add/remove as needed) 24242 firingIndex = -1, 24243 24244 // Fire callbacks 24245 fire = function() { 24246 24247 // Enforce single-firing 24248 locked = locked || options.once; 24249 24250 // Execute callbacks for all pending executions, 24251 // respecting firingIndex overrides and runtime changes 24252 fired = firing = true; 24253 for ( ; queue.length; firingIndex = -1 ) { 24254 memory = queue.shift(); 24255 while ( ++firingIndex < list.length ) { 24256 24257 // Run callback and check for early termination 24258 if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && 24259 options.stopOnFalse ) { 24260 24261 // Jump to end and forget the data so .add doesn't re-fire 24262 firingIndex = list.length; 24263 memory = false; 24264 } 24265 } 24266 } 24267 24268 // Forget the data if we're done with it 24269 if ( !options.memory ) { 24270 memory = false; 24271 } 24272 24273 firing = false; 24274 24275 // Clean up if we're done firing for good 24276 if ( locked ) { 24277 24278 // Keep an empty list if we have data for future add calls 24279 if ( memory ) { 24280 list = []; 24281 24282 // Otherwise, this object is spent 24283 } else { 24284 list = ""; 24285 } 24286 } 24287 }, 24288 24289 // Actual Callbacks object 24290 self = { 24291 24292 // Add a callback or a collection of callbacks to the list 24293 add: function() { 24294 if ( list ) { 24295 24296 // If we have memory from a past run, we should fire after adding 24297 if ( memory && !firing ) { 24298 firingIndex = list.length - 1; 24299 queue.push( memory ); 24300 } 24301 24302 ( function add( args ) { 24303 jQuery.each( args, function( _, arg ) { 24304 if ( isFunction( arg ) ) { 24305 if ( !options.unique || !self.has( arg ) ) { 24306 list.push( arg ); 24307 } 24308 } else if ( arg && arg.length && toType( arg ) !== "string" ) { 24309 24310 // Inspect recursively 24311 add( arg ); 24312 } 24313 } ); 24314 } )( arguments ); 24315 24316 if ( memory && !firing ) { 24317 fire(); 24318 } 24319 } 24320 return this; 24321 }, 24322 24323 // Remove a callback from the list 24324 remove: function() { 24325 jQuery.each( arguments, function( _, arg ) { 24326 var index; 24327 while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { 24328 list.splice( index, 1 ); 24329 24330 // Handle firing indexes 24331 if ( index <= firingIndex ) { 24332 firingIndex--; 24333 } 24334 } 24335 } ); 24336 return this; 24337 }, 24338 24339 // Check if a given callback is in the list. 24340 // If no argument is given, return whether or not list has callbacks attached. 24341 has: function( fn ) { 24342 return fn ? 24343 jQuery.inArray( fn, list ) > -1 : 24344 list.length > 0; 24345 }, 24346 24347 // Remove all callbacks from the list 24348 empty: function() { 24349 if ( list ) { 24350 list = []; 24351 } 24352 return this; 24353 }, 24354 24355 // Disable .fire and .add 24356 // Abort any current/pending executions 24357 // Clear all callbacks and values 24358 disable: function() { 24359 locked = queue = []; 24360 list = memory = ""; 24361 return this; 24362 }, 24363 disabled: function() { 24364 return !list; 24365 }, 24366 24367 // Disable .fire 24368 // Also disable .add unless we have memory (since it would have no effect) 24369 // Abort any pending executions 24370 lock: function() { 24371 locked = queue = []; 24372 if ( !memory && !firing ) { 24373 list = memory = ""; 24374 } 24375 return this; 24376 }, 24377 locked: function() { 24378 return !!locked; 24379 }, 24380 24381 // Call all callbacks with the given context and arguments 24382 fireWith: function( context, args ) { 24383 if ( !locked ) { 24384 args = args || []; 24385 args = [ context, args.slice ? args.slice() : args ]; 24386 queue.push( args ); 24387 if ( !firing ) { 24388 fire(); 24389 } 24390 } 24391 return this; 24392 }, 24393 24394 // Call all the callbacks with the given arguments 24395 fire: function() { 24396 self.fireWith( this, arguments ); 24397 return this; 24398 }, 24399 24400 // To know if the callbacks have already been called at least once 24401 fired: function() { 24402 return !!fired; 24403 } 24404 }; 24405 24406 return self; 24407}; 24408 24409 24410function Identity( v ) { 24411 return v; 24412} 24413function Thrower( ex ) { 24414 throw ex; 24415} 24416 24417function adoptValue( value, resolve, reject, noValue ) { 24418 var method; 24419 24420 try { 24421 24422 // Check for promise aspect first to privilege synchronous behavior 24423 if ( value && isFunction( ( method = value.promise ) ) ) { 24424 method.call( value ).done( resolve ).fail( reject ); 24425 24426 // Other thenables 24427 } else if ( value && isFunction( ( method = value.then ) ) ) { 24428 method.call( value, resolve, reject ); 24429 24430 // Other non-thenables 24431 } else { 24432 24433 // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: 24434 // * false: [ value ].slice( 0 ) => resolve( value ) 24435 // * true: [ value ].slice( 1 ) => resolve() 24436 resolve.apply( undefined, [ value ].slice( noValue ) ); 24437 } 24438 24439 // For Promises/A+, convert exceptions into rejections 24440 // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in 24441 // Deferred#then to conditionally suppress rejection. 24442 } catch ( value ) { 24443 24444 // Support: Android 4.0 only 24445 // Strict mode functions invoked without .call/.apply get global-object context 24446 reject.apply( undefined, [ value ] ); 24447 } 24448} 24449 24450jQuery.extend( { 24451 24452 Deferred: function( func ) { 24453 var tuples = [ 24454 24455 // action, add listener, callbacks, 24456 // ... .then handlers, argument index, [final state] 24457 [ "notify", "progress", jQuery.Callbacks( "memory" ), 24458 jQuery.Callbacks( "memory" ), 2 ], 24459 [ "resolve", "done", jQuery.Callbacks( "once memory" ), 24460 jQuery.Callbacks( "once memory" ), 0, "resolved" ], 24461 [ "reject", "fail", jQuery.Callbacks( "once memory" ), 24462 jQuery.Callbacks( "once memory" ), 1, "rejected" ] 24463 ], 24464 state = "pending", 24465 promise = { 24466 state: function() { 24467 return state; 24468 }, 24469 always: function() { 24470 deferred.done( arguments ).fail( arguments ); 24471 return this; 24472 }, 24473 "catch": function( fn ) {
vendor: 15,167 bytes, lines 24474-25065
24474 return promise.then( null, fn ); 24475 }, 24476 24477 // Keep pipe for back-compat 24478 pipe: function( /* fnDone, fnFail, fnProgress */ ) { 24479 var fns = arguments; 24480 24481 return jQuery.Deferred( function( newDefer ) { 24482 jQuery.each( tuples, function( i, tuple ) { 24483 24484 // Map tuples (progress, done, fail) to arguments (done, fail, progress) 24485 var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; 24486 24487 // deferred.progress(function() { bind to newDefer or newDefer.notify }) 24488 // deferred.done(function() { bind to newDefer or newDefer.resolve }) 24489 // deferred.fail(function() { bind to newDefer or newDefer.reject }) 24490 deferred[ tuple[ 1 ] ]( function() { 24491 var returned = fn && fn.apply( this, arguments ); 24492 if ( returned && isFunction( returned.promise ) ) { 24493 returned.promise() 24494 .progress( newDefer.notify ) 24495 .done( newDefer.resolve ) 24496 .fail( newDefer.reject ); 24497 } else { 24498 newDefer[ tuple[ 0 ] + "With" ]( 24499 this, 24500 fn ? [ returned ] : arguments 24501 ); 24502 } 24503 } ); 24504 } ); 24505 fns = null; 24506 } ).promise(); 24507 }, 24508 then: function( onFulfilled, onRejected, onProgress ) { 24509 var maxDepth = 0; 24510 function resolve( depth, deferred, handler, special ) { 24511 return function() { 24512 var that = this, 24513 args = arguments, 24514 mightThrow = function() { 24515 var returned, then; 24516 24517 // Support: Promises/A+ section 2.3.3.3.3 24518 // https://promisesaplus.com/#point-59 24519 // Ignore double-resolution attempts 24520 if ( depth < maxDepth ) { 24521 return; 24522 } 24523 24524 returned = handler.apply( that, args ); 24525 24526 // Support: Promises/A+ section 2.3.1 24527 // https://promisesaplus.com/#point-48 24528 if ( returned === deferred.promise() ) { 24529 throw new TypeError( "Thenable self-resolution" ); 24530 } 24531 24532 // Support: Promises/A+ sections 2.3.3.1, 3.5 24533 // https://promisesaplus.com/#point-54 24534 // https://promisesaplus.com/#point-75 24535 // Retrieve `then` only once 24536 then = returned && 24537 24538 // Support: Promises/A+ section 2.3.4 24539 // https://promisesaplus.com/#point-64 24540 // Only check objects and functions for thenability 24541 ( typeof returned === "object" || 24542 typeof returned === "function" ) && 24543 returned.then; 24544 24545 // Handle a returned thenable 24546 if ( isFunction( then ) ) { 24547 24548 // Special processors (notify) just wait for resolution 24549 if ( special ) { 24550 then.call( 24551 returned, 24552 resolve( maxDepth, deferred, Identity, special ), 24553 resolve( maxDepth, deferred, Thrower, special ) 24554 ); 24555 24556 // Normal processors (resolve) also hook into progress 24557 } else { 24558 24559 // ...and disregard older resolution values 24560 maxDepth++; 24561 24562 then.call( 24563 returned, 24564 resolve( maxDepth, deferred, Identity, special ), 24565 resolve( maxDepth, deferred, Thrower, special ), 24566 resolve( maxDepth, deferred, Identity, 24567 deferred.notifyWith ) 24568 ); 24569 } 24570 24571 // Handle all other returned values 24572 } else { 24573 24574 // Only substitute handlers pass on context 24575 // and multiple values (non-spec behavior) 24576 if ( handler !== Identity ) { 24577 that = undefined; 24578 args = [ returned ]; 24579 } 24580 24581 // Process the value(s) 24582 // Default process is resolve 24583 ( special || deferred.resolveWith )( that, args ); 24584 } 24585 }, 24586 24587 // Only normal processors (resolve) catch and reject exceptions 24588 process = special ? 24589 mightThrow : 24590 function() { 24591 try { 24592 mightThrow(); 24593 } catch ( e ) { 24594 24595 if ( jQuery.Deferred.exceptionHook ) { 24596 jQuery.Deferred.exceptionHook( e, 24597 process.stackTrace ); 24598 } 24599 24600 // Support: Promises/A+ section 2.3.3.3.4.1 24601 // https://promisesaplus.com/#point-61 24602 // Ignore post-resolution exceptions 24603 if ( depth + 1 >= maxDepth ) { 24604 24605 // Only substitute handlers pass on context 24606 // and multiple values (non-spec behavior) 24607 if ( handler !== Thrower ) { 24608 that = undefined; 24609 args = [ e ]; 24610 } 24611 24612 deferred.rejectWith( that, args ); 24613 } 24614 } 24615 }; 24616 24617 // Support: Promises/A+ section 2.3.3.3.1 24618 // https://promisesaplus.com/#point-57 24619 // Re-resolve promises immediately to dodge false rejection from 24620 // subsequent errors 24621 if ( depth ) { 24622 process(); 24623 } else { 24624 24625 // Call an optional hook to record the stack, in case of exception 24626 // since it's otherwise lost when execution goes async 24627 if ( jQuery.Deferred.getStackHook ) { 24628 process.stackTrace = jQuery.Deferred.getStackHook(); 24629 } 24630 window.setTimeout( process ); 24631 } 24632 }; 24633 } 24634 24635 return jQuery.Deferred( function( newDefer ) { 24636 24637 // progress_handlers.add( ... ) 24638 tuples[ 0 ][ 3 ].add( 24639 resolve( 24640 0, 24641 newDefer, 24642 isFunction( onProgress ) ? 24643 onProgress : 24644 Identity, 24645 newDefer.notifyWith 24646 ) 24647 ); 24648 24649 // fulfilled_handlers.add( ... ) 24650 tuples[ 1 ][ 3 ].add( 24651 resolve( 24652 0, 24653 newDefer, 24654 isFunction( onFulfilled ) ? 24655 onFulfilled : 24656 Identity 24657 ) 24658 ); 24659 24660 // rejected_handlers.add( ... ) 24661 tuples[ 2 ][ 3 ].add( 24662 resolve( 24663 0, 24664 newDefer, 24665 isFunction( onRejected ) ? 24666 onRejected : 24667 Thrower 24668 ) 24669 ); 24670 } ).promise(); 24671 }, 24672 24673 // Get a promise for this deferred 24674 // If obj is provided, the promise aspect is added to the object 24675 promise: function( obj ) { 24676 return obj != null ? jQuery.extend( obj, promise ) : promise; 24677 } 24678 }, 24679 deferred = {}; 24680 24681 // Add list-specific methods 24682 jQuery.each( tuples, function( i, tuple ) { 24683 var list = tuple[ 2 ], 24684 stateString = tuple[ 5 ]; 24685 24686 // promise.progress = list.add 24687 // promise.done = list.add 24688 // promise.fail = list.add 24689 promise[ tuple[ 1 ] ] = list.add; 24690 24691 // Handle state 24692 if ( stateString ) { 24693 list.add( 24694 function() { 24695 24696 // state = "resolved" (i.e., fulfilled) 24697 // state = "rejected" 24698 state = stateString; 24699 }, 24700 24701 // rejected_callbacks.disable 24702 // fulfilled_callbacks.disable 24703 tuples[ 3 - i ][ 2 ].disable, 24704 24705 // rejected_handlers.disable 24706 // fulfilled_handlers.disable 24707 tuples[ 3 - i ][ 3 ].disable, 24708 24709 // progress_callbacks.lock 24710 tuples[ 0 ][ 2 ].lock, 24711 24712 // progress_handlers.lock 24713 tuples[ 0 ][ 3 ].lock 24714 ); 24715 } 24716 24717 // progress_handlers.fire 24718 // fulfilled_handlers.fire 24719 // rejected_handlers.fire 24720 list.add( tuple[ 3 ].fire ); 24721 24722 // deferred.notify = function() { deferred.notifyWith(...) } 24723 // deferred.resolve = function() { deferred.resolveWith(...) } 24724 // deferred.reject = function() { deferred.rejectWith(...) } 24725 deferred[ tuple[ 0 ] ] = function() { 24726 deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); 24727 return this; 24728 }; 24729 24730 // deferred.notifyWith = list.fireWith 24731 // deferred.resolveWith = list.fireWith 24732 // deferred.rejectWith = list.fireWith 24733 deferred[ tuple[ 0 ] + "With" ] = list.fireWith; 24734 } ); 24735 24736 // Make the deferred a promise 24737 promise.promise( deferred ); 24738 24739 // Call given func if any 24740 if ( func ) { 24741 func.call( deferred, deferred ); 24742 } 24743 24744 // All done! 24745 return deferred; 24746 }, 24747 24748 // Deferred helper 24749 when: function( singleValue ) { 24750 var 24751 24752 // count of uncompleted subordinates 24753 remaining = arguments.length, 24754 24755 // count of unprocessed arguments 24756 i = remaining, 24757 24758 // subordinate fulfillment data 24759 resolveContexts = Array( i ), 24760 resolveValues = slice.call( arguments ), 24761 24762 // the master Deferred 24763 master = jQuery.Deferred(), 24764 24765 // subordinate callback factory 24766 updateFunc = function( i ) { 24767 return function( value ) { 24768 resolveContexts[ i ] = this; 24769 resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; 24770 if ( !( --remaining ) ) { 24771 master.resolveWith( resolveContexts, resolveValues ); 24772 } 24773 }; 24774 }; 24775 24776 // Single- and empty arguments are adopted like Promise.resolve 24777 if ( remaining <= 1 ) { 24778 adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, 24779 !remaining ); 24780 24781 // Use .then() to unwrap secondary thenables (cf. gh-3000) 24782 if ( master.state() === "pending" || 24783 isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { 24784 24785 return master.then(); 24786 } 24787 } 24788 24789 // Multiple arguments are aggregated like Promise.all array elements 24790 while ( i-- ) { 24791 adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); 24792 } 24793 24794 return master.promise(); 24795 } 24796} ); 24797 24798 24799// These usually indicate a programmer mistake during development, 24800// warn about them ASAP rather than swallowing them by default. 24801var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; 24802 24803jQuery.Deferred.exceptionHook = function( error, stack ) { 24804 24805 // Support: IE 8 - 9 only 24806 // Console exists when dev tools are open, which can happen at any time 24807 if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { 24808 window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); 24809 } 24810}; 24811 24812 24813 24814 24815jQuery.readyException = function( error ) { 24816 window.setTimeout( function() { 24817 throw error; 24818 } ); 24819}; 24820 24821 24822 24823 24824// The deferred used on DOM ready 24825var readyList = jQuery.Deferred(); 24826 24827jQuery.fn.ready = function( fn ) { 24828 24829 readyList 24830 .then( fn ) 24831 24832 // Wrap jQuery.readyException in a function so that the lookup 24833 // happens at the time of error handling instead of callback 24834 // registration. 24835 .catch( function( error ) { 24836 jQuery.readyException( error ); 24837 } ); 24838 24839 return this; 24840}; 24841 24842jQuery.extend( { 24843 24844 // Is the DOM ready to be used? Set to true once it occurs. 24845 isReady: false, 24846 24847 // A counter to track how many items to wait for before 24848 // the ready event fires. See #6781 24849 readyWait: 1, 24850 24851 // Handle when the DOM is ready 24852 ready: function( wait ) { 24853 24854 // Abort if there are pending holds or we're already ready 24855 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { 24856 return; 24857 } 24858 24859 // Remember that the DOM is ready 24860 jQuery.isReady = true; 24861 24862 // If a normal DOM Ready event fired, decrement, and wait if need be 24863 if ( wait !== true && --jQuery.readyWait > 0 ) { 24864 return; 24865 } 24866 24867 // If there are functions bound, to execute 24868 readyList.resolveWith( document, [ jQuery ] ); 24869 } 24870} ); 24871 24872jQuery.ready.then = readyList.then; 24873 24874// The ready event handler and self cleanup method 24875function completed() { 24876 document.removeEventListener( "DOMContentLoaded", completed ); 24877 window.removeEventListener( "load", completed ); 24878 jQuery.ready(); 24879} 24880 24881// Catch cases where $(document).ready() is called 24882// after the browser event has already occurred. 24883// Support: IE <=9 - 10 only 24884// Older IE sometimes signals "interactive" too soon 24885if ( document.readyState === "complete" || 24886 ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { 24887 24888 // Handle it asynchronously to allow scripts the opportunity to delay ready 24889 window.setTimeout( jQuery.ready ); 24890 24891} else { 24892 24893 // Use the handy event callback 24894 document.addEventListener( "DOMContentLoaded", completed ); 24895 24896 // A fallback to window.onload, that will always work 24897 window.addEventListener( "load", completed ); 24898} 24899 24900 24901 24902 24903// Multifunctional method to get and set values of a collection 24904// The value/s can optionally be executed if it's a function 24905var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { 24906 var i = 0, 24907 len = elems.length, 24908 bulk = key == null; 24909 24910 // Sets many values 24911 if ( toType( key ) === "object" ) { 24912 chainable = true; 24913 for ( i in key ) { 24914 access( elems, fn, i, key[ i ], true, emptyGet, raw ); 24915 } 24916 24917 // Sets one value 24918 } else if ( value !== undefined ) { 24919 chainable = true; 24920 24921 if ( !isFunction( value ) ) { 24922 raw = true; 24923 } 24924 24925 if ( bulk ) { 24926 24927 // Bulk operations run against the entire set 24928 if ( raw ) { 24929 fn.call( elems, value ); 24930 fn = null; 24931 24932 // ...except when executing function values 24933 } else { 24934 bulk = fn; 24935 fn = function( elem, key, value ) { 24936 return bulk.call( jQuery( elem ), value ); 24937 }; 24938 } 24939 } 24940 24941 if ( fn ) { 24942 for ( ; i < len; i++ ) { 24943 fn( 24944 elems[ i ], key, raw ? 24945 value : 24946 value.call( elems[ i ], i, fn( elems[ i ], key ) ) 24947 ); 24948 } 24949 } 24950 } 24951 24952 if ( chainable ) { 24953 return elems; 24954 } 24955 24956 // Gets 24957 if ( bulk ) { 24958 return fn.call( elems ); 24959 } 24960 24961 return len ? fn( elems[ 0 ], key ) : emptyGet; 24962}; 24963 24964 24965// Matches dashed string for camelizing 24966var rmsPrefix = /^-ms-/, 24967 rdashAlpha = /-([a-z])/g; 24968 24969// Used by camelCase as callback to replace() 24970function fcamelCase( all, letter ) { 24971 return letter.toUpperCase(); 24972} 24973 24974// Convert dashed to camelCase; used by the css and data modules 24975// Support: IE <=9 - 11, Edge 12 - 15 24976// Microsoft forgot to hump their vendor prefix (#9572) 24977function camelCase( string ) { 24978 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); 24979} 24980var acceptData = function( owner ) { 24981 24982 // Accepts only: 24983 // - Node 24984 // - Node.ELEMENT_NODE 24985 // - Node.DOCUMENT_NODE 24986 // - Object 24987 // - Any 24988 return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); 24989}; 24990 24991 24992 24993 24994function Data() { 24995 this.expando = jQuery.expando + Data.uid++; 24996} 24997 24998Data.uid = 1; 24999 25000Data.prototype = { 25001 25002 cache: function( owner ) { 25003 25004 // Check if the owner object already has a cache 25005 var value = owner[ this.expando ]; 25006 25007 // If not, create one 25008 if ( !value ) { 25009 value = {}; 25010 25011 // We can accept data for non-element nodes in modern browsers, 25012 // but we should not, see #8335. 25013 // Always return an empty object. 25014 if ( acceptData( owner ) ) { 25015 25016 // If it is a node unlikely to be stringify-ed or looped over 25017 // use plain assignment 25018 if ( owner.nodeType ) { 25019 owner[ this.expando ] = value; 25020 25021 // Otherwise secure it in a non-enumerable property 25022 // configurable must be true to allow the property to be 25023 // deleted when data is removed 25024 } else { 25025 Object.defineProperty( owner, this.expando, { 25026 value: value, 25027 configurable: true 25028 } ); 25029 } 25030 } 25031 } 25032 25033 return value; 25034 }, 25035 set: function( owner, data, value ) { 25036 var prop, 25037 cache = this.cache( owner ); 25038 25039 // Handle: [ owner, key, value ] args 25040 // Always use camelCase key (gh-2257) 25041 if ( typeof data === "string" ) { 25042 cache[ camelCase( data ) ] = value; 25043 25044 // Handle: [ owner, { properties } ] args 25045 } else { 25046 25047 // Copy the properties one-by-one to the cache object 25048 for ( prop in data ) { 25049 cache[ camelCase( prop ) ] = data[ prop ]; 25050 } 25051 } 25052 return cache; 25053 }, 25054 get: function( owner, key ) { 25055 return key === undefined ? 25056 this.cache( owner ) : 25057 25058 // Always use camelCase key (gh-2257) 25059 owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; 25060 }, 25061 access: function( owner, key, value ) { 25062 25063 // In cases where either: 25064 // 25065 // 1. No key was specified
vendor: 10,628 bytes, lines 25066-25497
25066 // 2. A string key was specified, but no value provided 25067 // 25068 // Take the "read" path and allow the get method to determine 25069 // which value to return, respectively either: 25070 // 25071 // 1. The entire cache object 25072 // 2. The data stored at the key 25073 // 25074 if ( key === undefined || 25075 ( ( key && typeof key === "string" ) && value === undefined ) ) { 25076 25077 return this.get( owner, key ); 25078 } 25079 25080 // When the key is not a string, or both a key and value 25081 // are specified, set or extend (existing objects) with either: 25082 // 25083 // 1. An object of properties 25084 // 2. A key and value 25085 // 25086 this.set( owner, key, value ); 25087 25088 // Since the "set" path can have two possible entry points 25089 // return the expected data based on which path was taken[*] 25090 return value !== undefined ? value : key; 25091 }, 25092 remove: function( owner, key ) { 25093 var i, 25094 cache = owner[ this.expando ]; 25095 25096 if ( cache === undefined ) { 25097 return; 25098 } 25099 25100 if ( key !== undefined ) { 25101 25102 // Support array or space separated string of keys 25103 if ( Array.isArray( key ) ) { 25104 25105 // If key is an array of keys... 25106 // We always set camelCase keys, so remove that. 25107 key = key.map( camelCase ); 25108 } else { 25109 key = camelCase( key ); 25110 25111 // If a key with the spaces exists, use it. 25112 // Otherwise, create an array by matching non-whitespace 25113 key = key in cache ? 25114 [ key ] : 25115 ( key.match( rnothtmlwhite ) || [] ); 25116 } 25117 25118 i = key.length; 25119 25120 while ( i-- ) { 25121 delete cache[ key[ i ] ]; 25122 } 25123 } 25124 25125 // Remove the expando if there's no more data 25126 if ( key === undefined || jQuery.isEmptyObject( cache ) ) { 25127 25128 // Support: Chrome <=35 - 45 25129 // Webkit & Blink performance suffers when deleting properties 25130 // from DOM nodes, so set to undefined instead 25131 // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) 25132 if ( owner.nodeType ) { 25133 owner[ this.expando ] = undefined; 25134 } else { 25135 delete owner[ this.expando ]; 25136 } 25137 } 25138 }, 25139 hasData: function( owner ) { 25140 var cache = owner[ this.expando ]; 25141 return cache !== undefined && !jQuery.isEmptyObject( cache ); 25142 } 25143}; 25144var dataPriv = new Data(); 25145 25146var dataUser = new Data(); 25147 25148 25149 25150// Implementation Summary 25151// 25152// 1. Enforce API surface and semantic compatibility with 1.9.x branch 25153// 2. Improve the module's maintainability by reducing the storage 25154// paths to a single mechanism. 25155// 3. Use the same single mechanism to support "private" and "user" data. 25156// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) 25157// 5. Avoid exposing implementation details on user objects (eg. expando properties) 25158// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 25159 25160var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, 25161 rmultiDash = /[A-Z]/g; 25162 25163function getData( data ) { 25164 if ( data === "true" ) { 25165 return true; 25166 } 25167 25168 if ( data === "false" ) { 25169 return false; 25170 } 25171 25172 if ( data === "null" ) { 25173 return null; 25174 } 25175 25176 // Only convert to a number if it doesn't change the string 25177 if ( data === +data + "" ) { 25178 return +data; 25179 } 25180 25181 if ( rbrace.test( data ) ) { 25182 return JSON.parse( data ); 25183 } 25184 25185 return data; 25186} 25187 25188function dataAttr( elem, key, data ) { 25189 var name; 25190 25191 // If nothing was found internally, try to fetch any 25192 // data from the HTML5 data-* attribute 25193 if ( data === undefined && elem.nodeType === 1 ) { 25194 name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); 25195 data = elem.getAttribute( name ); 25196 25197 if ( typeof data === "string" ) { 25198 try { 25199 data = getData( data ); 25200 } catch ( e ) {} 25201 25202 // Make sure we set the data so it isn't changed later 25203 dataUser.set( elem, key, data ); 25204 } else { 25205 data = undefined; 25206 } 25207 } 25208 return data; 25209} 25210 25211jQuery.extend( { 25212 hasData: function( elem ) { 25213 return dataUser.hasData( elem ) || dataPriv.hasData( elem ); 25214 }, 25215 25216 data: function( elem, name, data ) { 25217 return dataUser.access( elem, name, data ); 25218 }, 25219 25220 removeData: function( elem, name ) { 25221 dataUser.remove( elem, name ); 25222 }, 25223 25224 // TODO: Now that all calls to _data and _removeData have been replaced 25225 // with direct calls to dataPriv methods, these can be deprecated. 25226 _data: function( elem, name, data ) { 25227 return dataPriv.access( elem, name, data ); 25228 }, 25229 25230 _removeData: function( elem, name ) { 25231 dataPriv.remove( elem, name ); 25232 } 25233} ); 25234 25235jQuery.fn.extend( { 25236 data: function( key, value ) { 25237 var i, name, data, 25238 elem = this[ 0 ], 25239 attrs = elem && elem.attributes; 25240 25241 // Gets all values 25242 if ( key === undefined ) { 25243 if ( this.length ) { 25244 data = dataUser.get( elem ); 25245 25246 if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { 25247 i = attrs.length; 25248 while ( i-- ) { 25249 25250 // Support: IE 11 only 25251 // The attrs elements can be null (#14894) 25252 if ( attrs[ i ] ) { 25253 name = attrs[ i ].name; 25254 if ( name.indexOf( "data-" ) === 0 ) { 25255 name = camelCase( name.slice( 5 ) ); 25256 dataAttr( elem, name, data[ name ] ); 25257 } 25258 } 25259 } 25260 dataPriv.set( elem, "hasDataAttrs", true ); 25261 } 25262 } 25263 25264 return data; 25265 } 25266 25267 // Sets multiple values 25268 if ( typeof key === "object" ) { 25269 return this.each( function() { 25270 dataUser.set( this, key ); 25271 } ); 25272 } 25273 25274 return access( this, function( value ) { 25275 var data; 25276 25277 // The calling jQuery object (element matches) is not empty 25278 // (and therefore has an element appears at this[ 0 ]) and the 25279 // `value` parameter was not undefined. An empty jQuery object 25280 // will result in `undefined` for elem = this[ 0 ] which will 25281 // throw an exception if an attempt to read a data cache is made. 25282 if ( elem && value === undefined ) { 25283 25284 // Attempt to get data from the cache 25285 // The key will always be camelCased in Data 25286 data = dataUser.get( elem, key ); 25287 if ( data !== undefined ) { 25288 return data; 25289 } 25290 25291 // Attempt to "discover" the data in 25292 // HTML5 custom data-* attrs 25293 data = dataAttr( elem, key ); 25294 if ( data !== undefined ) { 25295 return data; 25296 } 25297 25298 // We tried really hard, but the data doesn't exist. 25299 return; 25300 } 25301 25302 // Set the data... 25303 this.each( function() { 25304 25305 // We always store the camelCased key 25306 dataUser.set( this, key, value ); 25307 } ); 25308 }, null, value, arguments.length > 1, null, true ); 25309 }, 25310 25311 removeData: function( key ) { 25312 return this.each( function() { 25313 dataUser.remove( this, key ); 25314 } ); 25315 } 25316} ); 25317 25318 25319jQuery.extend( { 25320 queue: function( elem, type, data ) { 25321 var queue; 25322 25323 if ( elem ) { 25324 type = ( type || "fx" ) + "queue"; 25325 queue = dataPriv.get( elem, type ); 25326 25327 // Speed up dequeue by getting out quickly if this is just a lookup 25328 if ( data ) { 25329 if ( !queue || Array.isArray( data ) ) { 25330 queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); 25331 } else { 25332 queue.push( data ); 25333 } 25334 } 25335 return queue || []; 25336 } 25337 }, 25338 25339 dequeue: function( elem, type ) { 25340 type = type || "fx"; 25341 25342 var queue = jQuery.queue( elem, type ), 25343 startLength = queue.length, 25344 fn = queue.shift(), 25345 hooks = jQuery._queueHooks( elem, type ), 25346 next = function() { 25347 jQuery.dequeue( elem, type ); 25348 }; 25349 25350 // If the fx queue is dequeued, always remove the progress sentinel 25351 if ( fn === "inprogress" ) { 25352 fn = queue.shift(); 25353 startLength--; 25354 } 25355 25356 if ( fn ) { 25357 25358 // Add a progress sentinel to prevent the fx queue from being 25359 // automatically dequeued 25360 if ( type === "fx" ) { 25361 queue.unshift( "inprogress" ); 25362 } 25363 25364 // Clear up the last queue stop function 25365 delete hooks.stop; 25366 fn.call( elem, next, hooks ); 25367 } 25368 25369 if ( !startLength && hooks ) { 25370 hooks.empty.fire(); 25371 } 25372 }, 25373 25374 // Not public - generate a queueHooks object, or return the current one 25375 _queueHooks: function( elem, type ) { 25376 var key = type + "queueHooks"; 25377 return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { 25378 empty: jQuery.Callbacks( "once memory" ).add( function() { 25379 dataPriv.remove( elem, [ type + "queue", key ] ); 25380 } ) 25381 } ); 25382 } 25383} ); 25384 25385jQuery.fn.extend( { 25386 queue: function( type, data ) { 25387 var setter = 2; 25388 25389 if ( typeof type !== "string" ) { 25390 data = type; 25391 type = "fx"; 25392 setter--; 25393 } 25394 25395 if ( arguments.length < setter ) { 25396 return jQuery.queue( this[ 0 ], type ); 25397 } 25398 25399 return data === undefined ? 25400 this : 25401 this.each( function() { 25402 var queue = jQuery.queue( this, type, data ); 25403 25404 // Ensure a hooks for this queue 25405 jQuery._queueHooks( this, type ); 25406 25407 if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { 25408 jQuery.dequeue( this, type ); 25409 } 25410 } ); 25411 }, 25412 dequeue: function( type ) { 25413 return this.each( function() { 25414 jQuery.dequeue( this, type ); 25415 } ); 25416 }, 25417 clearQueue: function( type ) { 25418 return this.queue( type || "fx", [] ); 25419 }, 25420 25421 // Get a promise resolved when queues of a certain type 25422 // are emptied (fx is the type by default) 25423 promise: function( type, obj ) { 25424 var tmp, 25425 count = 1, 25426 defer = jQuery.Deferred(), 25427 elements = this, 25428 i = this.length, 25429 resolve = function() { 25430 if ( !( --count ) ) { 25431 defer.resolveWith( elements, [ elements ] ); 25432 } 25433 }; 25434 25435 if ( typeof type !== "string" ) { 25436 obj = type; 25437 type = undefined; 25438 } 25439 type = type || "fx"; 25440 25441 while ( i-- ) { 25442 tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); 25443 if ( tmp && tmp.empty ) { 25444 count++; 25445 tmp.empty.add( resolve ); 25446 } 25447 } 25448 resolve(); 25449 return defer.promise( obj ); 25450 } 25451} ); 25452var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; 25453 25454var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); 25455 25456 25457var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; 25458 25459var documentElement = document.documentElement; 25460 25461 25462 25463 var isAttached = function( elem ) { 25464 return jQuery.contains( elem.ownerDocument, elem ); 25465 }, 25466 composed = { composed: true }; 25467 25468 // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only 25469 // Check attachment across shadow DOM boundaries when possible (gh-3504) 25470 // Support: iOS 10.0-10.2 only 25471 // Early iOS 10 versions support `attachShadow` but not `getRootNode`, 25472 // leading to errors. We need to check for `getRootNode`. 25473 if ( documentElement.getRootNode ) { 25474 isAttached = function( elem ) { 25475 return jQuery.contains( elem.ownerDocument, elem ) || 25476 elem.getRootNode( composed ) === elem.ownerDocument; 25477 }; 25478 } 25479var isHiddenWithinTree = function( elem, el ) { 25480 25481 // isHiddenWithinTree might be called from jQuery#filter function; 25482 // in that case, element will be second argument 25483 elem = el || elem; 25484 25485 // Inline style trumps all 25486 return elem.style.display === "none" || 25487 elem.style.display === "" && 25488 25489 // Otherwise, check computed style 25490 // Support: Firefox <=43 - 45 25491 // Disconnected elements can have computed display: none, so first confirm that elem is 25492 // in the document. 25493 isAttached( elem ) && 25494 25495 jQuery.css( elem, "display" ) === "none"; 25496 }; 25497
vendor: 2,487 bytes, lines 25498-25595
25498var swap = function( elem, options, callback, args ) { 25499 var ret, name, 25500 old = {}; 25501 25502 // Remember the old values, and insert the new ones 25503 for ( name in options ) { 25504 old[ name ] = elem.style[ name ]; 25505 elem.style[ name ] = options[ name ]; 25506 } 25507 25508 ret = callback.apply( elem, args || [] ); 25509 25510 // Revert the old values 25511 for ( name in options ) { 25512 elem.style[ name ] = old[ name ]; 25513 } 25514 25515 return ret; 25516}; 25517 25518 25519 25520 25521function adjustCSS( elem, prop, valueParts, tween ) { 25522 var adjusted, scale, 25523 maxIterations = 20, 25524 currentValue = tween ? 25525 function() { 25526 return tween.cur(); 25527 } : 25528 function() { 25529 return jQuery.css( elem, prop, "" ); 25530 }, 25531 initial = currentValue(), 25532 unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), 25533 25534 // Starting value computation is required for potential unit mismatches 25535 initialInUnit = elem.nodeType && 25536 ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && 25537 rcssNum.exec( jQuery.css( elem, prop ) ); 25538 25539 if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { 25540 25541 // Support: Firefox <=54 25542 // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) 25543 initial = initial / 2; 25544 25545 // Trust units reported by jQuery.css 25546 unit = unit || initialInUnit[ 3 ]; 25547 25548 // Iteratively approximate from a nonzero starting point 25549 initialInUnit = +initial || 1; 25550 25551 while ( maxIterations-- ) { 25552 25553 // Evaluate and update our best guess (doubling guesses that zero out). 25554 // Finish if the scale equals or crosses 1 (making the old*new product non-positive). 25555 jQuery.style( elem, prop, initialInUnit + unit ); 25556 if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { 25557 maxIterations = 0; 25558 } 25559 initialInUnit = initialInUnit / scale; 25560 25561 } 25562 25563 initialInUnit = initialInUnit * 2; 25564 jQuery.style( elem, prop, initialInUnit + unit ); 25565 25566 // Make sure we update the tween properties later on 25567 valueParts = valueParts || []; 25568 } 25569 25570 if ( valueParts ) { 25571 initialInUnit = +initialInUnit || +initial || 0; 25572 25573 // Apply relative offset (+=/-=) if specified 25574 adjusted = valueParts[ 1 ] ? 25575 initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : 25576 +valueParts[ 2 ]; 25577 if ( tween ) { 25578 tween.unit = unit; 25579 tween.start = initialInUnit; 25580 tween.end = adjusted; 25581 } 25582 } 25583 return adjusted; 25584} 25585 25586 25587var defaultDisplayMap = {}; 25588 25589function getDefaultDisplay( elem ) { 25590 var temp, 25591 doc = elem.ownerDocument, 25592 nodeName = elem.nodeName, 25593 display = defaultDisplayMap[ nodeName ]; 25594 25595 if ( display ) {
vendor: 4,818 bytes, lines 25596-25791
25596 return display; 25597 } 25598 25599 temp = doc.body.appendChild( doc.createElement( nodeName ) ); 25600 display = jQuery.css( temp, "display" ); 25601 25602 temp.parentNode.removeChild( temp ); 25603 25604 if ( display === "none" ) { 25605 display = "block"; 25606 } 25607 defaultDisplayMap[ nodeName ] = display; 25608 25609 return display; 25610} 25611 25612function showHide( elements, show ) { 25613 var display, elem, 25614 values = [], 25615 index = 0, 25616 length = elements.length; 25617 25618 // Determine new display value for elements that need to change 25619 for ( ; index < length; index++ ) { 25620 elem = elements[ index ]; 25621 if ( !elem.style ) { 25622 continue; 25623 } 25624 25625 display = elem.style.display; 25626 if ( show ) { 25627 25628 // Since we force visibility upon cascade-hidden elements, an immediate (and slow) 25629 // check is required in this first loop unless we have a nonempty display value (either 25630 // inline or about-to-be-restored) 25631 if ( display === "none" ) { 25632 values[ index ] = dataPriv.get( elem, "display" ) || null; 25633 if ( !values[ index ] ) { 25634 elem.style.display = ""; 25635 } 25636 } 25637 if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { 25638 values[ index ] = getDefaultDisplay( elem ); 25639 } 25640 } else { 25641 if ( display !== "none" ) { 25642 values[ index ] = "none"; 25643 25644 // Remember what we're overwriting 25645 dataPriv.set( elem, "display", display ); 25646 } 25647 } 25648 } 25649 25650 // Set the display of the elements in a second loop to avoid constant reflow 25651 for ( index = 0; index < length; index++ ) { 25652 if ( values[ index ] != null ) { 25653 elements[ index ].style.display = values[ index ]; 25654 } 25655 } 25656 25657 return elements; 25658} 25659 25660jQuery.fn.extend( { 25661 show: function() { 25662 return showHide( this, true ); 25663 }, 25664 hide: function() { 25665 return showHide( this ); 25666 }, 25667 toggle: function( state ) { 25668 if ( typeof state === "boolean" ) { 25669 return state ? this.show() : this.hide(); 25670 } 25671 25672 return this.each( function() { 25673 if ( isHiddenWithinTree( this ) ) { 25674 jQuery( this ).show(); 25675 } else { 25676 jQuery( this ).hide(); 25677 } 25678 } ); 25679 } 25680} ); 25681var rcheckableType = ( /^(?:checkbox|radio)$/i ); 25682 25683var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); 25684 25685var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); 25686 25687 25688 25689// We have to close these tags to support XHTML (#13200) 25690var wrapMap = { 25691 25692 // Support: IE <=9 only 25693 option: [ 1, "<select multiple='multiple'>", "</select>" ], 25694 25695 // XHTML parsers do not magically insert elements in the 25696 // same way that tag soup parsers do. So we cannot shorten 25697 // this by omitting <tbody> or other required elements. 25698 thead: [ 1, "<table>", "</table>" ], 25699 col: [ 2, "<table><colgroup>", "</colgroup></table>" ], 25700 tr: [ 2, "<table><tbody>", "</tbody></table>" ], 25701 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], 25702 25703 _default: [ 0, "", "" ] 25704}; 25705 25706// Support: IE <=9 only 25707wrapMap.optgroup = wrapMap.option; 25708 25709wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; 25710wrapMap.th = wrapMap.td; 25711 25712 25713function getAll( context, tag ) { 25714 25715 // Support: IE <=9 - 11 only 25716 // Use typeof to avoid zero-argument method invocation on host objects (#15151) 25717 var ret; 25718 25719 if ( typeof context.getElementsByTagName !== "undefined" ) { 25720 ret = context.getElementsByTagName( tag || "*" ); 25721 25722 } else if ( typeof context.querySelectorAll !== "undefined" ) { 25723 ret = context.querySelectorAll( tag || "*" ); 25724 25725 } else { 25726 ret = []; 25727 } 25728 25729 if ( tag === undefined || tag && nodeName( context, tag ) ) { 25730 return jQuery.merge( [ context ], ret ); 25731 } 25732 25733 return ret; 25734} 25735 25736 25737// Mark scripts as having already been evaluated 25738function setGlobalEval( elems, refElements ) { 25739 var i = 0, 25740 l = elems.length; 25741 25742 for ( ; i < l; i++ ) { 25743 dataPriv.set( 25744 elems[ i ], 25745 "globalEval", 25746 !refElements || dataPriv.get( refElements[ i ], "globalEval" ) 25747 ); 25748 } 25749} 25750 25751 25752var rhtml = /<|&#?\w+;/; 25753 25754function buildFragment( elems, context, scripts, selection, ignored ) { 25755 var elem, tmp, tag, wrap, attached, j, 25756 fragment = context.createDocumentFragment(), 25757 nodes = [], 25758 i = 0, 25759 l = elems.length; 25760 25761 for ( ; i < l; i++ ) { 25762 elem = elems[ i ]; 25763 25764 if ( elem || elem === 0 ) { 25765 25766 // Add nodes directly 25767 if ( toType( elem ) === "object" ) { 25768 25769 // Support: Android <=4.0 only, PhantomJS 1 only 25770 // push.apply(_, arraylike) throws on ancient WebKit 25771 jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); 25772 25773 // Convert non-html into a text node 25774 } else if ( !rhtml.test( elem ) ) { 25775 nodes.push( context.createTextNode( elem ) ); 25776 25777 // Convert html into DOM nodes 25778 } else { 25779 tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); 25780 25781 // Deserialize a standard representation 25782 tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); 25783 wrap = wrapMap[ tag ] || wrapMap._default; 25784 tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; 25785 25786 // Descend through wrappers to the right content 25787 j = wrap[ 0 ]; 25788 while ( j-- ) { 25789 tmp = tmp.lastChild; 25790 } 25791
vendor: 1,252 bytes, lines 25792-25849
25792 // Support: Android <=4.0 only, PhantomJS 1 only 25793 // push.apply(_, arraylike) throws on ancient WebKit 25794 jQuery.merge( nodes, tmp.childNodes ); 25795 25796 // Remember the top-level container 25797 tmp = fragment.firstChild; 25798 25799 // Ensure the created nodes are orphaned (#12392) 25800 tmp.textContent = ""; 25801 } 25802 } 25803 } 25804 25805 // Remove wrapper from fragment 25806 fragment.textContent = ""; 25807 25808 i = 0; 25809 while ( ( elem = nodes[ i++ ] ) ) { 25810 25811 // Skip elements already in the context collection (trac-4087) 25812 if ( selection && jQuery.inArray( elem, selection ) > -1 ) { 25813 if ( ignored ) { 25814 ignored.push( elem ); 25815 } 25816 continue; 25817 } 25818 25819 attached = isAttached( elem ); 25820 25821 // Append to fragment 25822 tmp = getAll( fragment.appendChild( elem ), "script" ); 25823 25824 // Preserve script evaluation history 25825 if ( attached ) { 25826 setGlobalEval( tmp ); 25827 } 25828 25829 // Capture executables 25830 if ( scripts ) { 25831 j = 0; 25832 while ( ( elem = tmp[ j++ ] ) ) { 25833 if ( rscriptType.test( elem.type || "" ) ) { 25834 scripts.push( elem ); 25835 } 25836 } 25837 } 25838 } 25839 25840 return fragment; 25841} 25842 25843 25844( function() { 25845 var fragment = document.createDocumentFragment(), 25846 div = fragment.appendChild( document.createElement( "div" ) ), 25847 input = document.createElement( "input" ); 25848 25849 // Support: Android 4.0 - 4.3 only
vendor: 6,890 bytes, lines 25850-26096
25850 // Check state lost if the name is set (#11217) 25851 // Support: Windows Web Apps (WWA) 25852 // `name` and `type` must use .setAttribute for WWA (#14901) 25853 input.setAttribute( "type", "radio" ); 25854 input.setAttribute( "checked", "checked" ); 25855 input.setAttribute( "name", "t" ); 25856 25857 div.appendChild( input ); 25858 25859 // Support: Android <=4.1 only 25860 // Older WebKit doesn't clone checked state correctly in fragments 25861 support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; 25862 25863 // Support: IE <=11 only 25864 // Make sure textarea (and checkbox) defaultValue is properly cloned 25865 div.innerHTML = "<textarea>x</textarea>"; 25866 support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; 25867} )(); 25868 25869 25870var 25871 rkeyEvent = /^key/, 25872 rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, 25873 rtypenamespace = /^([^.]*)(?:\.(.+)|)/; 25874 25875function returnTrue() { 25876 return true; 25877} 25878 25879function returnFalse() { 25880 return false; 25881} 25882 25883// Support: IE <=9 - 11+ 25884// focus() and blur() are asynchronous, except when they are no-op. 25885// So expect focus to be synchronous when the element is already active, 25886// and blur to be synchronous when the element is not already active. 25887// (focus and blur are always synchronous in other supported browsers, 25888// this just defines when we can count on it). 25889function expectSync( elem, type ) { 25890 return ( elem === safeActiveElement() ) === ( type === "focus" ); 25891} 25892 25893// Support: IE <=9 only 25894// Accessing document.activeElement can throw unexpectedly 25895// https://bugs.jquery.com/ticket/13393 25896function safeActiveElement() { 25897 try { 25898 return document.activeElement; 25899 } catch ( err ) { } 25900} 25901 25902function on( elem, types, selector, data, fn, one ) { 25903 var origFn, type; 25904 25905 // Types can be a map of types/handlers 25906 if ( typeof types === "object" ) { 25907 25908 // ( types-Object, selector, data ) 25909 if ( typeof selector !== "string" ) { 25910 25911 // ( types-Object, data ) 25912 data = data || selector; 25913 selector = undefined; 25914 } 25915 for ( type in types ) { 25916 on( elem, type, selector, data, types[ type ], one ); 25917 } 25918 return elem; 25919 } 25920 25921 if ( data == null && fn == null ) { 25922 25923 // ( types, fn ) 25924 fn = selector; 25925 data = selector = undefined; 25926 } else if ( fn == null ) { 25927 if ( typeof selector === "string" ) { 25928 25929 // ( types, selector, fn ) 25930 fn = data; 25931 data = undefined; 25932 } else { 25933 25934 // ( types, data, fn ) 25935 fn = data; 25936 data = selector; 25937 selector = undefined; 25938 } 25939 } 25940 if ( fn === false ) { 25941 fn = returnFalse; 25942 } else if ( !fn ) { 25943 return elem; 25944 } 25945 25946 if ( one === 1 ) { 25947 origFn = fn; 25948 fn = function( event ) { 25949 25950 // Can use an empty set, since event contains the info 25951 jQuery().off( event ); 25952 return origFn.apply( this, arguments ); 25953 }; 25954 25955 // Use same guid so caller can remove using origFn 25956 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); 25957 } 25958 return elem.each( function() { 25959 jQuery.event.add( this, types, fn, data, selector ); 25960 } ); 25961} 25962 25963/* 25964 * Helper functions for managing events -- not part of the public interface. 25965 * Props to Dean Edwards' addEvent library for many of the ideas. 25966 */ 25967jQuery.event = { 25968 25969 global: {}, 25970 25971 add: function( elem, types, handler, data, selector ) { 25972 25973 var handleObjIn, eventHandle, tmp, 25974 events, t, handleObj, 25975 special, handlers, type, namespaces, origType, 25976 elemData = dataPriv.get( elem ); 25977 25978 // Don't attach events to noData or text/comment nodes (but allow plain objects) 25979 if ( !elemData ) { 25980 return; 25981 } 25982 25983 // Caller can pass in an object of custom data in lieu of the handler 25984 if ( handler.handler ) { 25985 handleObjIn = handler; 25986 handler = handleObjIn.handler; 25987 selector = handleObjIn.selector; 25988 } 25989 25990 // Ensure that invalid selectors throw exceptions at attach time 25991 // Evaluate against documentElement in case elem is a non-element node (e.g., document) 25992 if ( selector ) { 25993 jQuery.find.matchesSelector( documentElement, selector ); 25994 } 25995 25996 // Make sure that the handler has a unique ID, used to find/remove it later 25997 if ( !handler.guid ) { 25998 handler.guid = jQuery.guid++; 25999 } 26000 26001 // Init the element's event structure and main handler, if this is the first 26002 if ( !( events = elemData.events ) ) { 26003 events = elemData.events = {}; 26004 } 26005 if ( !( eventHandle = elemData.handle ) ) { 26006 eventHandle = elemData.handle = function( e ) { 26007 26008 // Discard the second event of a jQuery.event.trigger() and 26009 // when an event is called after a page has unloaded 26010 return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? 26011 jQuery.event.dispatch.apply( elem, arguments ) : undefined; 26012 }; 26013 } 26014 26015 // Handle multiple events separated by a space 26016 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; 26017 t = types.length; 26018 while ( t-- ) { 26019 tmp = rtypenamespace.exec( types[ t ] ) || []; 26020 type = origType = tmp[ 1 ]; 26021 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); 26022 26023 // There *must* be a type, no attaching namespace-only handlers 26024 if ( !type ) { 26025 continue; 26026 } 26027 26028 // If event changes its type, use the special event handlers for the changed type 26029 special = jQuery.event.special[ type ] || {}; 26030 26031 // If selector defined, determine special event api type, otherwise given type 26032 type = ( selector ? special.delegateType : special.bindType ) || type; 26033 26034 // Update special based on newly reset type 26035 special = jQuery.event.special[ type ] || {}; 26036 26037 // handleObj is passed to all event handlers 26038 handleObj = jQuery.extend( { 26039 type: type, 26040 origType: origType, 26041 data: data, 26042 handler: handler, 26043 guid: handler.guid, 26044 selector: selector, 26045 needsContext: selector && jQuery.expr.match.needsContext.test( selector ), 26046 namespace: namespaces.join( "." ) 26047 }, handleObjIn ); 26048 26049 // Init the event handler queue if we're the first 26050 if ( !( handlers = events[ type ] ) ) { 26051 handlers = events[ type ] = []; 26052 handlers.delegateCount = 0; 26053 26054 // Only use addEventListener if the special events handler returns false 26055 if ( !special.setup || 26056 special.setup.call( elem, data, namespaces, eventHandle ) === false ) { 26057 26058 if ( elem.addEventListener ) { 26059 elem.addEventListener( type, eventHandle ); 26060 } 26061 } 26062 } 26063 26064 if ( special.add ) { 26065 special.add.call( elem, handleObj ); 26066 26067 if ( !handleObj.handler.guid ) { 26068 handleObj.handler.guid = handler.guid; 26069 } 26070 } 26071 26072 // Add to the element's handler list, delegates in front 26073 if ( selector ) { 26074 handlers.splice( handlers.delegateCount++, 0, handleObj ); 26075 } else { 26076 handlers.push( handleObj ); 26077 } 26078 26079 // Keep track of which events have ever been used, for event optimization 26080 jQuery.event.global[ type ] = true; 26081 } 26082 26083 }, 26084 26085 // Detach an event or set of events from an element 26086 remove: function( elem, types, handler, selector, mappedTypes ) { 26087 26088 var j, origCount, tmp, 26089 events, t, handleObj, 26090 special, handlers, type, namespaces, origType, 26091 elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); 26092 26093 if ( !elemData || !( events = elemData.events ) ) { 26094 return; 26095 } 26096
vendor: 4,172 bytes, lines 26097-26232
26097 // Once for each type.namespace in types; type may be omitted 26098 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; 26099 t = types.length; 26100 while ( t-- ) { 26101 tmp = rtypenamespace.exec( types[ t ] ) || []; 26102 type = origType = tmp[ 1 ]; 26103 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); 26104 26105 // Unbind all events (on this namespace, if provided) for the element 26106 if ( !type ) { 26107 for ( type in events ) { 26108 jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); 26109 } 26110 continue; 26111 } 26112 26113 special = jQuery.event.special[ type ] || {}; 26114 type = ( selector ? special.delegateType : special.bindType ) || type; 26115 handlers = events[ type ] || []; 26116 tmp = tmp[ 2 ] && 26117 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); 26118 26119 // Remove matching events 26120 origCount = j = handlers.length; 26121 while ( j-- ) { 26122 handleObj = handlers[ j ]; 26123 26124 if ( ( mappedTypes || origType === handleObj.origType ) && 26125 ( !handler || handler.guid === handleObj.guid ) && 26126 ( !tmp || tmp.test( handleObj.namespace ) ) && 26127 ( !selector || selector === handleObj.selector || 26128 selector === "**" && handleObj.selector ) ) { 26129 handlers.splice( j, 1 ); 26130 26131 if ( handleObj.selector ) { 26132 handlers.delegateCount--; 26133 } 26134 if ( special.remove ) { 26135 special.remove.call( elem, handleObj ); 26136 } 26137 } 26138 } 26139 26140 // Remove generic event handler if we removed something and no more handlers exist 26141 // (avoids potential for endless recursion during removal of special event handlers) 26142 if ( origCount && !handlers.length ) { 26143 if ( !special.teardown || 26144 special.teardown.call( elem, namespaces, elemData.handle ) === false ) { 26145 26146 jQuery.removeEvent( elem, type, elemData.handle ); 26147 } 26148 26149 delete events[ type ]; 26150 } 26151 } 26152 26153 // Remove data and the expando if it's no longer used 26154 if ( jQuery.isEmptyObject( events ) ) { 26155 dataPriv.remove( elem, "handle events" ); 26156 } 26157 }, 26158 26159 dispatch: function( nativeEvent ) { 26160 26161 // Make a writable jQuery.Event from the native event object 26162 var event = jQuery.event.fix( nativeEvent ); 26163 26164 var i, j, ret, matched, handleObj, handlerQueue, 26165 args = new Array( arguments.length ), 26166 handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], 26167 special = jQuery.event.special[ event.type ] || {}; 26168 26169 // Use the fix-ed jQuery.Event rather than the (read-only) native event 26170 args[ 0 ] = event; 26171 26172 for ( i = 1; i < arguments.length; i++ ) { 26173 args[ i ] = arguments[ i ]; 26174 } 26175 26176 event.delegateTarget = this; 26177 26178 // Call the preDispatch hook for the mapped type, and let it bail if desired 26179 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { 26180 return; 26181 } 26182 26183 // Determine handlers 26184 handlerQueue = jQuery.event.handlers.call( this, event, handlers ); 26185 26186 // Run delegates first; they may want to stop propagation beneath us 26187 i = 0; 26188 while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { 26189 event.currentTarget = matched.elem; 26190 26191 j = 0; 26192 while ( ( handleObj = matched.handlers[ j++ ] ) && 26193 !event.isImmediatePropagationStopped() ) { 26194 26195 // If the event is namespaced, then each handler is only invoked if it is 26196 // specially universal or its namespaces are a superset of the event's. 26197 if ( !event.rnamespace || handleObj.namespace === false || 26198 event.rnamespace.test( handleObj.namespace ) ) { 26199 26200 event.handleObj = handleObj; 26201 event.data = handleObj.data; 26202 26203 ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || 26204 handleObj.handler ).apply( matched.elem, args ); 26205 26206 if ( ret !== undefined ) { 26207 if ( ( event.result = ret ) === false ) { 26208 event.preventDefault(); 26209 event.stopPropagation(); 26210 } 26211 } 26212 } 26213 } 26214 } 26215 26216 // Call the postDispatch hook for the mapped type 26217 if ( special.postDispatch ) { 26218 special.postDispatch.call( this, event ); 26219 } 26220 26221 return event.result; 26222 }, 26223 26224 handlers: function( event, handlers ) { 26225 var i, handleObj, sel, matchedHandlers, matchedSelectors, 26226 handlerQueue = [], 26227 delegateCount = handlers.delegateCount, 26228 cur = event.target; 26229 26230 // Find delegate handlers 26231 if ( delegateCount && 26232
vendor: 5,718 bytes, lines 26233-26418
26233 // Support: IE <=9 26234 // Black-hole SVG <use> instance trees (trac-13180) 26235 cur.nodeType && 26236 26237 // Support: Firefox <=42 26238 // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) 26239 // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click 26240 // Support: IE 11 only 26241 // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) 26242 !( event.type === "click" && event.button >= 1 ) ) { 26243 26244 for ( ; cur !== this; cur = cur.parentNode || this ) { 26245 26246 // Don't check non-elements (#13208) 26247 // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) 26248 if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { 26249 matchedHandlers = []; 26250 matchedSelectors = {}; 26251 for ( i = 0; i < delegateCount; i++ ) { 26252 handleObj = handlers[ i ]; 26253 26254 // Don't conflict with Object.prototype properties (#13203) 26255 sel = handleObj.selector + " "; 26256 26257 if ( matchedSelectors[ sel ] === undefined ) { 26258 matchedSelectors[ sel ] = handleObj.needsContext ? 26259 jQuery( sel, this ).index( cur ) > -1 : 26260 jQuery.find( sel, this, null, [ cur ] ).length; 26261 } 26262 if ( matchedSelectors[ sel ] ) { 26263 matchedHandlers.push( handleObj ); 26264 } 26265 } 26266 if ( matchedHandlers.length ) { 26267 handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); 26268 } 26269 } 26270 } 26271 } 26272 26273 // Add the remaining (directly-bound) handlers 26274 cur = this; 26275 if ( delegateCount < handlers.length ) { 26276 handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); 26277 } 26278 26279 return handlerQueue; 26280 }, 26281 26282 addProp: function( name, hook ) { 26283 Object.defineProperty( jQuery.Event.prototype, name, { 26284 enumerable: true, 26285 configurable: true, 26286 26287 get: isFunction( hook ) ? 26288 function() { 26289 if ( this.originalEvent ) { 26290 return hook( this.originalEvent ); 26291 } 26292 } : 26293 function() { 26294 if ( this.originalEvent ) { 26295 return this.originalEvent[ name ]; 26296 } 26297 }, 26298 26299 set: function( value ) { 26300 Object.defineProperty( this, name, { 26301 enumerable: true, 26302 configurable: true, 26303 writable: true, 26304 value: value 26305 } ); 26306 } 26307 } ); 26308 }, 26309 26310 fix: function( originalEvent ) { 26311 return originalEvent[ jQuery.expando ] ? 26312 originalEvent : 26313 new jQuery.Event( originalEvent ); 26314 }, 26315 26316 special: { 26317 load: { 26318 26319 // Prevent triggered image.load events from bubbling to window.load 26320 noBubble: true 26321 }, 26322 click: { 26323 26324 // Utilize native event to ensure correct state for checkable inputs 26325 setup: function( data ) { 26326 26327 // For mutual compressibility with _default, replace `this` access with a local var. 26328 // `|| data` is dead code meant only to preserve the variable through minification. 26329 var el = this || data; 26330 26331 // Claim the first handler 26332 if ( rcheckableType.test( el.type ) && 26333 el.click && nodeName( el, "input" ) ) { 26334 26335 // dataPriv.set( el, "click", ... ) 26336 leverageNative( el, "click", returnTrue ); 26337 } 26338 26339 // Return false to allow normal processing in the caller 26340 return false; 26341 }, 26342 trigger: function( data ) { 26343 26344 // For mutual compressibility with _default, replace `this` access with a local var. 26345 // `|| data` is dead code meant only to preserve the variable through minification. 26346 var el = this || data; 26347 26348 // Force setup before triggering a click 26349 if ( rcheckableType.test( el.type ) && 26350 el.click && nodeName( el, "input" ) ) { 26351 26352 leverageNative( el, "click" ); 26353 } 26354 26355 // Return non-false to allow normal event-path propagation 26356 return true; 26357 }, 26358 26359 // For cross-browser consistency, suppress native .click() on links 26360 // Also prevent it if we're currently inside a leveraged native-event stack 26361 _default: function( event ) { 26362 var target = event.target; 26363 return rcheckableType.test( target.type ) && 26364 target.click && nodeName( target, "input" ) && 26365 dataPriv.get( target, "click" ) || 26366 nodeName( target, "a" ); 26367 } 26368 }, 26369 26370 beforeunload: { 26371 postDispatch: function( event ) { 26372 26373 // Support: Firefox 20+ 26374 // Firefox doesn't alert if the returnValue field is not set. 26375 if ( event.result !== undefined && event.originalEvent ) { 26376 event.originalEvent.returnValue = event.result; 26377 } 26378 } 26379 } 26380 } 26381}; 26382 26383// Ensure the presence of an event listener that handles manually-triggered 26384// synthetic events by interrupting progress until reinvoked in response to 26385// *native* events that it fires directly, ensuring that state changes have 26386// already occurred before other listeners are invoked. 26387function leverageNative( el, type, expectSync ) { 26388 26389 // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add 26390 if ( !expectSync ) { 26391 if ( dataPriv.get( el, type ) === undefined ) { 26392 jQuery.event.add( el, type, returnTrue ); 26393 } 26394 return; 26395 } 26396 26397 // Register the controller as a special universal handler for all event namespaces 26398 dataPriv.set( el, type, false ); 26399 jQuery.event.add( el, type, { 26400 namespace: false, 26401 handler: function( event ) { 26402 var notAsync, result, 26403 saved = dataPriv.get( this, type ); 26404 26405 if ( ( event.isTrigger & 1 ) && this[ type ] ) { 26406 26407 // Interrupt processing of the outer synthetic .trigger()ed event 26408 // Saved data should be false in such cases, but might be a leftover capture object 26409 // from an async native handler (gh-4350) 26410 if ( !saved.length ) { 26411 26412 // Store arguments for use when handling the inner native event 26413 // There will always be at least one argument (an event object), so this array 26414 // will not be confused with a leftover capture object. 26415 saved = slice.call( arguments ); 26416 dataPriv.set( this, type, saved ); 26417 26418 // Trigger the native event and capture its result
26419 // Support: IE <=9 - 11+ 26420 // focus() and blur() are asynchronous 26421 notAsync = expectSync( this, type ); 26422 this[ type ](); 26423 result = dataPriv.get( this, type ); 26424 if ( saved !== result || notAsync ) { 26425 dataPriv.set( this, type, false ); 26426 } else { 26427 result = {}; 26428 } 26429 if ( saved !== result ) { 26430 26431 // Cancel the outer synthetic event 26432 event.stopImmediatePropagation(); 26433 event.preventDefault(); 26434 return result.value; 26435 } 26436 26437 // If this is an inner synthetic event for an event with a bubbling surrogate 26438 // (focus or blur), assume that the surrogate already propagated from triggering the 26439 // native event and prevent that from happening again here. 26440 // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the 26441 // bubbling surrogate propagates *after* the non-bubbling base), but that seems 26442 // less bad than duplication. 26443 } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { 26444 event.stopPropagation(); 26445 } 26446 26447 // If this is a native event triggered above, everything is now in order 26448 // Fire an inner synthetic event with the original arguments 26449 } else if ( saved.length ) { 26450 26451 // ...and capture the result 26452 dataPriv.set( this, type, { 26453 value: jQuery.event.trigger( 26454 26455 // Support: IE <=9 - 11+ 26456 // Extend with the prototype to reset the above stopImmediatePropagation() 26457 jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), 26458 saved.slice( 1 ), 26459 this 26460 ) 26461 } ); 26462 26463 // Abort handling of the native event 26464 event.stopImmediatePropagation(); 26465 } 26466 } 26467 } ); 26468} 26469 26470jQuery.removeEvent = function( elem, type, handle ) { 26471 26472 // This "if" is needed for plain objects 26473 if ( elem.removeEventListener ) { 26474 elem.removeEventListener( type, handle ); 26475 } 26476}; 26477 26478jQuery.Event = function( src, props ) { 26479 26480 // Allow instantiation without the 'new' keyword 26481 if ( !( this instanceof jQuery.Event ) ) { 26482 return new jQuery.Event( src, props ); 26483 } 26484 26485 // Event object 26486 if ( src && src.type ) { 26487 this.originalEvent = src; 26488 this.type = src.type; 26489 26490 // Events bubbling up the document may have been marked as prevented 26491 // by a handler lower down the tree; reflect the correct value. 26492 this.isDefaultPrevented = src.defaultPrevented || 26493 src.defaultPrevented === undefined && 26494 26495 // Support: Android <=2.3 only 26496 src.returnValue === false ? 26497 returnTrue : 26498 returnFalse; 26499 26500 // Create target properties 26501 // Support: Safari <=6 - 7 only 26502 // Target should not be a text node (#504, #13143) 26503 this.target = ( src.target && src.target.nodeType === 3 ) ? 26504 src.target.parentNode : 26505 src.target; 26506 26507 this.currentTarget = src.currentTarget; 26508 this.relatedTarget = src.relatedTarget; 26509 26510 // Event type 26511 } else { 26512 this.type = src; 26513 } 26514 26515 // Put explicitly provided properties onto the event object 26516 if ( props ) { 26517 jQuery.extend( this, props ); 26518 } 26519 26520 // Create a timestamp if incoming event doesn't have one 26521 this.timeStamp = src && src.timeStamp || Date.now(); 26522 26523 // Mark it as fixed 26524 this[ jQuery.expando ] = true; 26525}; 26526 26527// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding 26528// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html 26529jQuery.Event.prototype = { 26530 constructor: jQuery.Event, 26531 isDefaultPrevented: returnFalse, 26532 isPropagationStopped: returnFalse, 26533 isImmediatePropagationStopped: returnFalse, 26534 isSimulated: false, 26535 26536 preventDefault: function() { 26537 var e = this.originalEvent; 26538 26539 this.isDefaultPrevented = returnTrue; 26540 26541 if ( e && !this.isSimulated ) { 26542 e.preventDefault(); 26543 } 26544 }, 26545 stopPropagation: function() { 26546 var e = this.originalEvent; 26547 26548 this.isPropagationStopped = returnTrue; 26549 26550 if ( e && !this.isSimulated ) { 26551 e.stopPropagation(); 26552 } 26553 }, 26554 stopImmediatePropagation: function() { 26555 var e = this.originalEvent; 26556 26557 this.isImmediatePropagationStopped = returnTrue; 26558 26559 if ( e && !this.isSimulated ) { 26560 e.stopImmediatePropagation(); 26561 } 26562 26563 this.stopPropagation(); 26564 } 26565}; 26566 26567// Includes all common event props including KeyEvent and MouseEvent specific props 26568jQuery.each( { 26569 altKey: true, 26570 bubbles: true, 26571 cancelable: true, 26572 changedTouches: true, 26573 ctrlKey: true, 26574 detail: true, 26575 eventPhase: true, 26576 metaKey: true, 26577 pageX: true, 26578 pageY: true, 26579 shiftKey: true, 26580 view: true, 26581 "char": true, 26582 code: true, 26583 charCode: true, 26584 key: true, 26585 keyCode: true, 26586 button: true, 26587 buttons: true, 26588 clientX: true, 26589 clientY: true, 26590 offsetX: true, 26591 offsetY: true, 26592 pointerId: true, 26593 pointerType: true, 26594 screenX: true, 26595 screenY: true, 26596 targetTouches: true, 26597 toElement: true, 26598 touches: true, 26599 26600 which: function( event ) { 26601 var button = event.button; 26602 26603 // Add which for key events 26604 if ( event.which == null && rkeyEvent.test( event.type ) ) { 26605 return event.charCode != null ? event.charCode : event.keyCode; 26606 } 26607 26608 // Add which for click: 1 === left; 2 === middle; 3 === right 26609 if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { 26610 if ( button & 1 ) { 26611 return 1; 26612 } 26613 26614 if ( button & 2 ) { 26615 return 3; 26616 } 26617 26618 if ( button & 4 ) { 26619 return 2; 26620 } 26621 26622 return 0; 26623 } 26624 26625 return event.which; 26626 } 26627}, jQuery.event.addProp ); 26628 26629jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { 26630 jQuery.event.special[ type ] = { 26631 26632 // Utilize native event if possible so blur/focus sequence is correct 26633 setup: function() { 26634 26635 // Claim the first handler 26636 // dataPriv.set( this, "focus", ... ) 26637 // dataPriv.set( this, "blur", ... ) 26638 leverageNative( this, type, expectSync ); 26639 26640 // Return false to allow normal processing in the caller 26641 return false;
vendor: 4,563 bytes, lines 26642-26818
26642 }, 26643 trigger: function() { 26644 26645 // Force setup before trigger 26646 leverageNative( this, type ); 26647 26648 // Return non-false to allow normal event-path propagation 26649 return true; 26650 }, 26651 26652 delegateType: delegateType 26653 }; 26654} ); 26655 26656// Create mouseenter/leave events using mouseover/out and event-time checks 26657// so that event delegation works in jQuery. 26658// Do the same for pointerenter/pointerleave and pointerover/pointerout 26659// 26660// Support: Safari 7 only 26661// Safari sends mouseenter too often; see: 26662// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 26663// for the description of the bug (it existed in older Chrome versions as well). 26664jQuery.each( { 26665 mouseenter: "mouseover", 26666 mouseleave: "mouseout", 26667 pointerenter: "pointerover", 26668 pointerleave: "pointerout" 26669}, function( orig, fix ) { 26670 jQuery.event.special[ orig ] = { 26671 delegateType: fix, 26672 bindType: fix, 26673 26674 handle: function( event ) { 26675 var ret, 26676 target = this, 26677 related = event.relatedTarget, 26678 handleObj = event.handleObj; 26679 26680 // For mouseenter/leave call the handler if related is outside the target. 26681 // NB: No relatedTarget if the mouse left/entered the browser window 26682 if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { 26683 event.type = handleObj.origType; 26684 ret = handleObj.handler.apply( this, arguments ); 26685 event.type = fix; 26686 } 26687 return ret; 26688 } 26689 }; 26690} ); 26691 26692jQuery.fn.extend( { 26693 26694 on: function( types, selector, data, fn ) { 26695 return on( this, types, selector, data, fn ); 26696 }, 26697 one: function( types, selector, data, fn ) { 26698 return on( this, types, selector, data, fn, 1 ); 26699 }, 26700 off: function( types, selector, fn ) { 26701 var handleObj, type; 26702 if ( types && types.preventDefault && types.handleObj ) { 26703 26704 // ( event ) dispatched jQuery.Event 26705 handleObj = types.handleObj; 26706 jQuery( types.delegateTarget ).off( 26707 handleObj.namespace ? 26708 handleObj.origType + "." + handleObj.namespace : 26709 handleObj.origType, 26710 handleObj.selector, 26711 handleObj.handler 26712 ); 26713 return this; 26714 } 26715 if ( typeof types === "object" ) { 26716 26717 // ( types-object [, selector] ) 26718 for ( type in types ) { 26719 this.off( type, selector, types[ type ] ); 26720 } 26721 return this; 26722 } 26723 if ( selector === false || typeof selector === "function" ) { 26724 26725 // ( types [, fn] ) 26726 fn = selector; 26727 selector = undefined; 26728 } 26729 if ( fn === false ) { 26730 fn = returnFalse; 26731 } 26732 return this.each( function() { 26733 jQuery.event.remove( this, types, fn, selector ); 26734 } ); 26735 } 26736} ); 26737 26738 26739var 26740 26741 /* eslint-disable max-len */ 26742 26743 // See https://github.com/eslint/eslint/issues/3229 26744 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, 26745 26746 /* eslint-enable */ 26747 26748 // Support: IE <=10 - 11, Edge 12 - 13 only 26749 // In IE/Edge using regex groups here causes severe slowdowns. 26750 // See https://connect.microsoft.com/IE/feedback/details/1736512/ 26751 rnoInnerhtml = /<script|<style|<link/i, 26752 26753 // checked="checked" or checked 26754 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, 26755 rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g; 26756 26757// Prefer a tbody over its parent table for containing new rows 26758function manipulationTarget( elem, content ) { 26759 if ( nodeName( elem, "table" ) && 26760 nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { 26761 26762 return jQuery( elem ).children( "tbody" )[ 0 ] || elem; 26763 } 26764 26765 return elem; 26766} 26767 26768// Replace/restore the type attribute of script elements for safe DOM manipulation 26769function disableScript( elem ) { 26770 elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; 26771 return elem; 26772} 26773function restoreScript( elem ) { 26774 if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { 26775 elem.type = elem.type.slice( 5 ); 26776 } else { 26777 elem.removeAttribute( "type" ); 26778 } 26779 26780 return elem; 26781} 26782 26783function cloneCopyEvent( src, dest ) { 26784 var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; 26785 26786 if ( dest.nodeType !== 1 ) { 26787 return; 26788 } 26789 26790 // 1. Copy private data: events, handlers, etc. 26791 if ( dataPriv.hasData( src ) ) { 26792 pdataOld = dataPriv.access( src ); 26793 pdataCur = dataPriv.set( dest, pdataOld ); 26794 events = pdataOld.events; 26795 26796 if ( events ) { 26797 delete pdataCur.handle; 26798 pdataCur.events = {}; 26799 26800 for ( type in events ) { 26801 for ( i = 0, l = events[ type ].length; i < l; i++ ) { 26802 jQuery.event.add( dest, type, events[ type ][ i ] ); 26803 } 26804 } 26805 } 26806 } 26807 26808 // 2. Copy user data 26809 if ( dataUser.hasData( src ) ) { 26810 udataOld = dataUser.access( src ); 26811 udataCur = jQuery.extend( {}, udataOld ); 26812 26813 dataUser.set( dest, udataCur ); 26814 } 26815} 26816 26817// Fix IE bugs, see support tests 26818function fixInput( src, dest ) {
vendor: 3,609 bytes, lines 26819-26946
26819 var nodeName = dest.nodeName.toLowerCase(); 26820 26821 // Fails to persist the checked state of a cloned checkbox or radio button. 26822 if ( nodeName === "input" && rcheckableType.test( src.type ) ) { 26823 dest.checked = src.checked; 26824 26825 // Fails to return the selected option to the default selected state when cloning options 26826 } else if ( nodeName === "input" || nodeName === "textarea" ) { 26827 dest.defaultValue = src.defaultValue; 26828 } 26829} 26830 26831function domManip( collection, args, callback, ignored ) { 26832 26833 // Flatten any nested arrays 26834 args = concat.apply( [], args ); 26835 26836 var fragment, first, scripts, hasScripts, node, doc, 26837 i = 0, 26838 l = collection.length, 26839 iNoClone = l - 1, 26840 value = args[ 0 ], 26841 valueIsFunction = isFunction( value ); 26842 26843 // We can't cloneNode fragments that contain checked, in WebKit 26844 if ( valueIsFunction || 26845 ( l > 1 && typeof value === "string" && 26846 !support.checkClone && rchecked.test( value ) ) ) { 26847 return collection.each( function( index ) { 26848 var self = collection.eq( index ); 26849 if ( valueIsFunction ) { 26850 args[ 0 ] = value.call( this, index, self.html() ); 26851 } 26852 domManip( self, args, callback, ignored ); 26853 } ); 26854 } 26855 26856 if ( l ) { 26857 fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); 26858 first = fragment.firstChild; 26859 26860 if ( fragment.childNodes.length === 1 ) { 26861 fragment = first; 26862 } 26863 26864 // Require either new content or an interest in ignored elements to invoke the callback 26865 if ( first || ignored ) { 26866 scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); 26867 hasScripts = scripts.length; 26868 26869 // Use the original fragment for the last item 26870 // instead of the first because it can end up 26871 // being emptied incorrectly in certain situations (#8070). 26872 for ( ; i < l; i++ ) { 26873 node = fragment; 26874 26875 if ( i !== iNoClone ) { 26876 node = jQuery.clone( node, true, true ); 26877 26878 // Keep references to cloned scripts for later restoration 26879 if ( hasScripts ) { 26880 26881 // Support: Android <=4.0 only, PhantomJS 1 only 26882 // push.apply(_, arraylike) throws on ancient WebKit 26883 jQuery.merge( scripts, getAll( node, "script" ) ); 26884 } 26885 } 26886 26887 callback.call( collection[ i ], node, i ); 26888 } 26889 26890 if ( hasScripts ) { 26891 doc = scripts[ scripts.length - 1 ].ownerDocument; 26892 26893 // Reenable scripts 26894 jQuery.map( scripts, restoreScript ); 26895 26896 // Evaluate executable scripts on first document insertion 26897 for ( i = 0; i < hasScripts; i++ ) { 26898 node = scripts[ i ]; 26899 if ( rscriptType.test( node.type || "" ) && 26900 !dataPriv.access( node, "globalEval" ) && 26901 jQuery.contains( doc, node ) ) { 26902 26903 if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { 26904 26905 // Optional AJAX dependency, but won't run scripts if not present 26906 if ( jQuery._evalUrl && !node.noModule ) { 26907 jQuery._evalUrl( node.src, { 26908 nonce: node.nonce || node.getAttribute( "nonce" ) 26909 } ); 26910 } 26911 } else { 26912 DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); 26913 } 26914 } 26915 } 26916 } 26917 } 26918 } 26919 26920 return collection; 26921} 26922 26923function remove( elem, selector, keepData ) { 26924 var node, 26925 nodes = selector ? jQuery.filter( selector, elem ) : elem, 26926 i = 0; 26927 26928 for ( ; ( node = nodes[ i ] ) != null; i++ ) { 26929 if ( !keepData && node.nodeType === 1 ) { 26930 jQuery.cleanData( getAll( node ) ); 26931 } 26932 26933 if ( node.parentNode ) { 26934 if ( keepData && isAttached( node ) ) { 26935 setGlobalEval( getAll( node, "script" ) ); 26936 } 26937 node.parentNode.removeChild( node ); 26938 } 26939 } 26940 26941 return elem; 26942} 26943 26944jQuery.extend( { 26945 htmlPrefilter: function( html ) { 26946 return html.replace( rxhtmlTag, "<$1></$2>" )
vendor: 2,889 bytes, lines 26946-27055
26946; 26947 }, 26948 26949 clone: function( elem, dataAndEvents, deepDataAndEvents ) { 26950 var i, l, srcElements, destElements, 26951 clone = elem.cloneNode( true ), 26952 inPage = isAttached( elem ); 26953 26954 // Fix IE cloning issues 26955 if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && 26956 !jQuery.isXMLDoc( elem ) ) { 26957 26958 // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 26959 destElements = getAll( clone ); 26960 srcElements = getAll( elem ); 26961 26962 for ( i = 0, l = srcElements.length; i < l; i++ ) { 26963 fixInput( srcElements[ i ], destElements[ i ] ); 26964 } 26965 } 26966 26967 // Copy the events from the original to the clone 26968 if ( dataAndEvents ) { 26969 if ( deepDataAndEvents ) { 26970 srcElements = srcElements || getAll( elem ); 26971 destElements = destElements || getAll( clone ); 26972 26973 for ( i = 0, l = srcElements.length; i < l; i++ ) { 26974 cloneCopyEvent( srcElements[ i ], destElements[ i ] ); 26975 } 26976 } else { 26977 cloneCopyEvent( elem, clone ); 26978 } 26979 } 26980 26981 // Preserve script evaluation history 26982 destElements = getAll( clone, "script" ); 26983 if ( destElements.length > 0 ) { 26984 setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); 26985 } 26986 26987 // Return the cloned set 26988 return clone; 26989 }, 26990 26991 cleanData: function( elems ) { 26992 var data, elem, type, 26993 special = jQuery.event.special, 26994 i = 0; 26995 26996 for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { 26997 if ( acceptData( elem ) ) { 26998 if ( ( data = elem[ dataPriv.expando ] ) ) { 26999 if ( data.events ) { 27000 for ( type in data.events ) { 27001 if ( special[ type ] ) { 27002 jQuery.event.remove( elem, type ); 27003 27004 // This is a shortcut to avoid jQuery.event.remove's overhead 27005 } else { 27006 jQuery.removeEvent( elem, type, data.handle ); 27007 } 27008 } 27009 } 27010 27011 // Support: Chrome <=35 - 45+ 27012 // Assign undefined instead of using delete, see Data#remove 27013 elem[ dataPriv.expando ] = undefined; 27014 } 27015 if ( elem[ dataUser.expando ] ) { 27016 27017 // Support: Chrome <=35 - 45+ 27018 // Assign undefined instead of using delete, see Data#remove 27019 elem[ dataUser.expando ] = undefined; 27020 } 27021 } 27022 } 27023 } 27024} ); 27025 27026jQuery.fn.extend( { 27027 detach: function( selector ) { 27028 return remove( this, selector, true ); 27029 }, 27030 27031 remove: function( selector ) { 27032 return remove( this, selector ); 27033 }, 27034 27035 text: function( value ) { 27036 return access( this, function( value ) { 27037 return value === undefined ? 27038 jQuery.text( this ) : 27039 this.empty().each( function() { 27040 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 27041 this.textContent = value; 27042 } 27043 } ); 27044 }, null, value, arguments.length ); 27045 }, 27046 27047 append: function() { 27048 return domManip( this, arguments, function( elem ) { 27049 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 27050 var target = manipulationTarget( this, elem ); 27051 target.appendChild( elem ); 27052 } 27053 } ); 27054 }, 27055
vendor: 5,129 bytes, lines 27056-27248
27056 prepend: function() { 27057 return domManip( this, arguments, function( elem ) { 27058 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 27059 var target = manipulationTarget( this, elem ); 27060 target.insertBefore( elem, target.firstChild ); 27061 } 27062 } ); 27063 }, 27064 27065 before: function() { 27066 return domManip( this, arguments, function( elem ) { 27067 if ( this.parentNode ) { 27068 this.parentNode.insertBefore( elem, this ); 27069 } 27070 } ); 27071 }, 27072 27073 after: function() { 27074 return domManip( this, arguments, function( elem ) { 27075 if ( this.parentNode ) { 27076 this.parentNode.insertBefore( elem, this.nextSibling ); 27077 } 27078 } ); 27079 }, 27080 27081 empty: function() { 27082 var elem, 27083 i = 0; 27084 27085 for ( ; ( elem = this[ i ] ) != null; i++ ) { 27086 if ( elem.nodeType === 1 ) { 27087 27088 // Prevent memory leaks 27089 jQuery.cleanData( getAll( elem, false ) ); 27090 27091 // Remove any remaining nodes 27092 elem.textContent = ""; 27093 } 27094 } 27095 27096 return this; 27097 }, 27098 27099 clone: function( dataAndEvents, deepDataAndEvents ) { 27100 dataAndEvents = dataAndEvents == null ? false : dataAndEvents; 27101 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; 27102 27103 return this.map( function() { 27104 return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); 27105 } ); 27106 }, 27107 27108 html: function( value ) { 27109 return access( this, function( value ) { 27110 var elem = this[ 0 ] || {}, 27111 i = 0, 27112 l = this.length; 27113 27114 if ( value === undefined && elem.nodeType === 1 ) { 27115 return elem.innerHTML; 27116 } 27117 27118 // See if we can take a shortcut and just use innerHTML 27119 if ( typeof value === "string" && !rnoInnerhtml.test( value ) && 27120 !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { 27121 27122 value = jQuery.htmlPrefilter( value ); 27123 27124 try { 27125 for ( ; i < l; i++ ) { 27126 elem = this[ i ] || {}; 27127 27128 // Remove element nodes and prevent memory leaks 27129 if ( elem.nodeType === 1 ) { 27130 jQuery.cleanData( getAll( elem, false ) ); 27131 elem.innerHTML = value; 27132 } 27133 } 27134 27135 elem = 0; 27136 27137 // If using innerHTML throws an exception, use the fallback method 27138 } catch ( e ) {} 27139 } 27140 27141 if ( elem ) { 27142 this.empty().append( value ); 27143 } 27144 }, null, value, arguments.length ); 27145 }, 27146 27147 replaceWith: function() { 27148 var ignored = []; 27149 27150 // Make the changes, replacing each non-ignored context element with the new content 27151 return domManip( this, arguments, function( elem ) { 27152 var parent = this.parentNode; 27153 27154 if ( jQuery.inArray( this, ignored ) < 0 ) { 27155 jQuery.cleanData( getAll( this ) ); 27156 if ( parent ) { 27157 parent.replaceChild( elem, this ); 27158 } 27159 } 27160 27161 // Force callback invocation 27162 }, ignored ); 27163 } 27164} ); 27165 27166jQuery.each( { 27167 appendTo: "append", 27168 prependTo: "prepend", 27169 insertBefore: "before", 27170 insertAfter: "after", 27171 replaceAll: "replaceWith" 27172}, function( name, original ) { 27173 jQuery.fn[ name ] = function( selector ) { 27174 var elems, 27175 ret = [], 27176 insert = jQuery( selector ), 27177 last = insert.length - 1, 27178 i = 0; 27179 27180 for ( ; i <= last; i++ ) { 27181 elems = i === last ? this : this.clone( true ); 27182 jQuery( insert[ i ] )[ original ]( elems ); 27183 27184 // Support: Android <=4.0 only, PhantomJS 1 only 27185 // .get() because push.apply(_, arraylike) throws on ancient WebKit 27186 push.apply( ret, elems.get() ); 27187 } 27188 27189 return this.pushStack( ret ); 27190 }; 27191} ); 27192var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); 27193 27194var getStyles = function( elem ) { 27195 27196 // Support: IE <=11 only, Firefox <=30 (#15098, #14150) 27197 // IE throws on elements created in popups 27198 // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" 27199 var view = elem.ownerDocument.defaultView; 27200 27201 if ( !view || !view.opener ) { 27202 view = window; 27203 } 27204 27205 return view.getComputedStyle( elem ); 27206 }; 27207 27208var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); 27209 27210 27211 27212( function() { 27213 27214 // Executing both pixelPosition & boxSizingReliable tests require only one layout 27215 // so they're executed at the same time to save the second computation. 27216 function computeStyleTests() { 27217 27218 // This is a singleton, we need to execute it only once 27219 if ( !div ) { 27220 return; 27221 } 27222 27223 container.style.cssText = "position:absolute;left:-11111px;width:60px;" + 27224 "margin-top:1px;padding:0;border:0"; 27225 div.style.cssText = 27226 "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + 27227 "margin:auto;border:1px;padding:1px;" + 27228 "width:60%;top:1%"; 27229 documentElement.appendChild( container ).appendChild( div ); 27230 27231 var divStyle = window.getComputedStyle( div ); 27232 pixelPositionVal = divStyle.top !== "1%"; 27233 27234 // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 27235 reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; 27236 27237 // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 27238 // Some styles come back with percentage values, even though they shouldn't 27239 div.style.right = "60%"; 27240 pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; 27241 27242 // Support: IE 9 - 11 only 27243 // Detect misreporting of content dimensions for box-sizing:border-box elements 27244 boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; 27245 27246 // Support: IE 9 only 27247 // Detect overflow:scroll screwiness (gh-3699) 27248
vendor: 8,298 bytes, lines 27248-27538
27248// Support: Chrome <=64 27249 // Don't get tricked when zoom affects offsetWidth (gh-4029) 27250 div.style.position = "absolute"; 27251 scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; 27252 27253 documentElement.removeChild( container ); 27254 27255 // Nullify the div so it wouldn't be stored in the memory and 27256 // it will also be a sign that checks already performed 27257 div = null; 27258 } 27259 27260 function roundPixelMeasures( measure ) { 27261 return Math.round( parseFloat( measure ) ); 27262 } 27263 27264 var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, 27265 reliableMarginLeftVal, 27266 container = document.createElement( "div" ), 27267 div = document.createElement( "div" ); 27268 27269 // Finish early in limited (non-browser) environments 27270 if ( !div.style ) { 27271 return; 27272 } 27273 27274 // Support: IE <=9 - 11 only 27275 // Style of cloned element affects source element cloned (#8908) 27276 div.style.backgroundClip = "content-box"; 27277 div.cloneNode( true ).style.backgroundClip = ""; 27278 support.clearCloneStyle = div.style.backgroundClip === "content-box"; 27279 27280 jQuery.extend( support, { 27281 boxSizingReliable: function() { 27282 computeStyleTests(); 27283 return boxSizingReliableVal; 27284 }, 27285 pixelBoxStyles: function() { 27286 computeStyleTests(); 27287 return pixelBoxStylesVal; 27288 }, 27289 pixelPosition: function() { 27290 computeStyleTests(); 27291 return pixelPositionVal; 27292 }, 27293 reliableMarginLeft: function() { 27294 computeStyleTests(); 27295 return reliableMarginLeftVal; 27296 }, 27297 scrollboxSize: function() { 27298 computeStyleTests(); 27299 return scrollboxSizeVal; 27300 } 27301 } ); 27302} )(); 27303 27304 27305function curCSS( elem, name, computed ) { 27306 var width, minWidth, maxWidth, ret, 27307 27308 // Support: Firefox 51+ 27309 // Retrieving style before computed somehow 27310 // fixes an issue with getting wrong values 27311 // on detached elements 27312 style = elem.style; 27313 27314 computed = computed || getStyles( elem ); 27315 27316 // getPropertyValue is needed for: 27317 // .css('filter') (IE 9 only, #12537) 27318 // .css('--customProperty) (#3144) 27319 if ( computed ) { 27320 ret = computed.getPropertyValue( name ) || computed[ name ]; 27321 27322 if ( ret === "" && !isAttached( elem ) ) { 27323 ret = jQuery.style( elem, name ); 27324 } 27325 27326 // A tribute to the "awesome hack by Dean Edwards" 27327 // Android Browser returns percentage for some values, 27328 // but width seems to be reliably pixels. 27329 // This is against the CSSOM draft spec: 27330 // https://drafts.csswg.org/cssom/#resolved-values 27331 if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { 27332 27333 // Remember the original values 27334 width = style.width; 27335 minWidth = style.minWidth; 27336 maxWidth = style.maxWidth; 27337 27338 // Put in the new values to get a computed value out 27339 style.minWidth = style.maxWidth = style.width = ret; 27340 ret = computed.width; 27341 27342 // Revert the changed values 27343 style.width = width; 27344 style.minWidth = minWidth; 27345 style.maxWidth = maxWidth; 27346 } 27347 } 27348 27349 return ret !== undefined ? 27350 27351 // Support: IE <=9 - 11 only 27352 // IE returns zIndex value as an integer. 27353 ret + "" : 27354 ret; 27355} 27356 27357 27358function addGetHookIf( conditionFn, hookFn ) { 27359 27360 // Define the hook, we'll check on the first run if it's really needed. 27361 return { 27362 get: function() { 27363 if ( conditionFn() ) { 27364 27365 // Hook not needed (or it's not possible to use it due 27366 // to missing dependency), remove it. 27367 delete this.get; 27368 return; 27369 } 27370 27371 // Hook needed; redefine it so that the support test is not executed again. 27372 return ( this.get = hookFn ).apply( this, arguments ); 27373 } 27374 }; 27375} 27376 27377 27378var cssPrefixes = [ "Webkit", "Moz", "ms" ], 27379 emptyStyle = document.createElement( "div" ).style, 27380 vendorProps = {}; 27381 27382// Return a vendor-prefixed property or undefined 27383function vendorPropName( name ) { 27384 27385 // Check for vendor prefixed names 27386 var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), 27387 i = cssPrefixes.length; 27388 27389 while ( i-- ) { 27390 name = cssPrefixes[ i ] + capName; 27391 if ( name in emptyStyle ) { 27392 return name; 27393 } 27394 } 27395} 27396 27397// Return a potentially-mapped jQuery.cssProps or vendor prefixed property 27398function finalPropName( name ) { 27399 var final = jQuery.cssProps[ name ] || vendorProps[ name ]; 27400 27401 if ( final ) { 27402 return final; 27403 } 27404 if ( name in emptyStyle ) { 27405 return name; 27406 } 27407 return vendorProps[ name ] = vendorPropName( name ) || name; 27408} 27409 27410 27411var 27412 27413 // Swappable if display is none or starts with table 27414 // except "table", "table-cell", or "table-caption" 27415 // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display 27416 rdisplayswap = /^(none|table(?!-c[ea]).+)/, 27417 rcustomProp = /^--/, 27418 cssShow = { position: "absolute", visibility: "hidden", display: "block" }, 27419 cssNormalTransform = { 27420 letterSpacing: "0", 27421 fontWeight: "400" 27422 }; 27423 27424function setPositiveNumber( elem, value, subtract ) { 27425 27426 // Any relative (+/-) values have already been 27427 // normalized at this point 27428 var matches = rcssNum.exec( value ); 27429 return matches ? 27430 27431 // Guard against undefined "subtract", e.g., when used as in cssHooks 27432 Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : 27433 value; 27434} 27435 27436function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { 27437 var i = dimension === "width" ? 1 : 0, 27438 extra = 0, 27439 delta = 0; 27440 27441 // Adjustment may not be necessary 27442 if ( box === ( isBorderBox ? "border" : "content" ) ) { 27443 return 0; 27444 } 27445 27446 for ( ; i < 4; i += 2 ) { 27447 27448 // Both box models exclude margin 27449 if ( box === "margin" ) { 27450 delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); 27451 } 27452 27453 // If we get here with a content-box, we're seeking "padding" or "border" or "margin" 27454 if ( !isBorderBox ) { 27455 27456 // Add padding 27457 delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); 27458 27459 // For "border" or "margin", add border 27460 if ( box !== "padding" ) { 27461 delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 27462 27463 // But still keep track of it otherwise 27464 } else { 27465 extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 27466 } 27467 27468 // If we get here with a border-box (content + padding + border), we're seeking "content" or 27469 // "padding" or "margin" 27470 } else { 27471 27472 // For "content", subtract padding 27473 if ( box === "content" ) { 27474 delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); 27475 } 27476 27477 // For "content" or "padding", subtract border 27478 if ( box !== "margin" ) { 27479 delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 27480 } 27481 } 27482 } 27483 27484 // Account for positive content-box scroll gutter when requested by providing computedVal 27485 if ( !isBorderBox && computedVal >= 0 ) { 27486 27487 // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border 27488 // Assuming integer scroll gutter, subtract the rest and round down 27489 delta += Math.max( 0, Math.ceil( 27490 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - 27491 computedVal - 27492 delta - 27493 extra - 27494 0.5 27495 27496 // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter 27497 // Use an explicit zero to avoid NaN (gh-3964) 27498 ) ) || 0; 27499 } 27500 27501 return delta; 27502} 27503 27504function getWidthOrHeight( elem, dimension, extra ) { 27505 27506 // Start with computed style 27507 var styles = getStyles( elem ), 27508 27509 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). 27510 // Fake content-box until we know it's needed to know the true value. 27511 boxSizingNeeded = !support.boxSizingReliable() || extra, 27512 isBorderBox = boxSizingNeeded && 27513 jQuery.css( elem, "boxSizing", false, styles ) === "border-box", 27514 valueIsBorderBox = isBorderBox, 27515 27516 val = curCSS( elem, dimension, styles ), 27517 offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); 27518 27519 // Support: Firefox <=54 27520 // Return a confounding non-pixel value or feign ignorance, as appropriate. 27521 if ( rnumnonpx.test( val ) ) { 27522 if ( !extra ) { 27523 return val; 27524 } 27525 val = "auto"; 27526 } 27527 27528 27529 // Fall back to offsetWidth/offsetHeight when value is "auto" 27530 // This happens for inline elements with no explicit setting (gh-3571) 27531 // Support: Android <=4.1 - 4.3 only 27532 // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) 27533 // Support: IE 9-11 only 27534 // Also use offsetWidth/offsetHeight for when box sizing is unreliable 27535 // We use getClientRects() to check for hidden/disconnected. 27536 // In those cases, the computed value can be trusted to be border-box 27537 if ( ( !support.boxSizingReliable() && isBorderBox || 27538 val === "auto" ||
vendor: 3,698 bytes, lines 27539-27669
27539 !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && 27540 elem.getClientRects().length ) { 27541 27542 isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; 27543 27544 // Where available, offsetWidth/offsetHeight approximate border box dimensions. 27545 // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the 27546 // retrieved value as a content box dimension. 27547 valueIsBorderBox = offsetProp in elem; 27548 if ( valueIsBorderBox ) { 27549 val = elem[ offsetProp ]; 27550 } 27551 } 27552 27553 // Normalize "" and auto 27554 val = parseFloat( val ) || 0; 27555 27556 // Adjust for the element's box model 27557 return ( val + 27558 boxModelAdjustment( 27559 elem, 27560 dimension, 27561 extra || ( isBorderBox ? "border" : "content" ), 27562 valueIsBorderBox, 27563 styles, 27564 27565 // Provide the current computed size to request scroll gutter calculation (gh-3589) 27566 val 27567 ) 27568 ) + "px"; 27569} 27570 27571jQuery.extend( { 27572 27573 // Add in style property hooks for overriding the default 27574 // behavior of getting and setting a style property 27575 cssHooks: { 27576 opacity: { 27577 get: function( elem, computed ) { 27578 if ( computed ) { 27579 27580 // We should always get a number back from opacity 27581 var ret = curCSS( elem, "opacity" ); 27582 return ret === "" ? "1" : ret; 27583 } 27584 } 27585 } 27586 }, 27587 27588 // Don't automatically add "px" to these possibly-unitless properties 27589 cssNumber: { 27590 "animationIterationCount": true, 27591 "columnCount": true, 27592 "fillOpacity": true, 27593 "flexGrow": true, 27594 "flexShrink": true, 27595 "fontWeight": true, 27596 "gridArea": true, 27597 "gridColumn": true, 27598 "gridColumnEnd": true, 27599 "gridColumnStart": true, 27600 "gridRow": true, 27601 "gridRowEnd": true, 27602 "gridRowStart": true, 27603 "lineHeight": true, 27604 "opacity": true, 27605 "order": true, 27606 "orphans": true, 27607 "widows": true, 27608 "zIndex": true, 27609 "zoom": true 27610 }, 27611 27612 // Add in properties whose names you wish to fix before 27613 // setting or getting the value 27614 cssProps: {}, 27615 27616 // Get and set the style property on a DOM Node 27617 style: function( elem, name, value, extra ) { 27618 27619 // Don't set styles on text and comment nodes 27620 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { 27621 return; 27622 } 27623 27624 // Make sure that we're working with the right name 27625 var ret, type, hooks, 27626 origName = camelCase( name ), 27627 isCustomProp = rcustomProp.test( name ), 27628 style = elem.style; 27629 27630 // Make sure that we're working with the right name. We don't 27631 // want to query the value if it is a CSS custom property 27632 // since they are user-defined. 27633 if ( !isCustomProp ) { 27634 name = finalPropName( origName ); 27635 } 27636 27637 // Gets hook for the prefixed version, then unprefixed version 27638 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 27639 27640 // Check if we're setting a value 27641 if ( value !== undefined ) { 27642 type = typeof value; 27643 27644 // Convert "+=" or "-=" to relative numbers (#7345) 27645 if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { 27646 value = adjustCSS( elem, name, ret ); 27647 27648 // Fixes bug #9237 27649 type = "number"; 27650 } 27651 27652 // Make sure that null and NaN values aren't set (#7116) 27653 if ( value == null || value !== value ) { 27654 return; 27655 } 27656 27657 // If a number was passed in, add the unit (except for certain CSS properties) 27658 // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append 27659 // "px" to a few hardcoded values. 27660 if ( type === "number" && !isCustomProp ) { 27661 value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); 27662 } 27663 27664 // background-* props affect original clone's values 27665 if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { 27666 style[ name ] = "inherit"; 27667 } 27668 27669 // If a hook was provided, use that value, otherwise just set the specified value
vendor: 7,976 bytes, lines 27670-27952
27670 if ( !hooks || !( "set" in hooks ) || 27671 ( value = hooks.set( elem, value, extra ) ) !== undefined ) { 27672 27673 if ( isCustomProp ) { 27674 style.setProperty( name, value ); 27675 } else { 27676 style[ name ] = value; 27677 } 27678 } 27679 27680 } else { 27681 27682 // If a hook was provided get the non-computed value from there 27683 if ( hooks && "get" in hooks && 27684 ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { 27685 27686 return ret; 27687 } 27688 27689 // Otherwise just get the value from the style object 27690 return style[ name ]; 27691 } 27692 }, 27693 27694 css: function( elem, name, extra, styles ) { 27695 var val, num, hooks, 27696 origName = camelCase( name ), 27697 isCustomProp = rcustomProp.test( name ); 27698 27699 // Make sure that we're working with the right name. We don't 27700 // want to modify the value if it is a CSS custom property 27701 // since they are user-defined. 27702 if ( !isCustomProp ) { 27703 name = finalPropName( origName ); 27704 } 27705 27706 // Try prefixed name followed by the unprefixed name 27707 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 27708 27709 // If a hook was provided get the computed value from there 27710 if ( hooks && "get" in hooks ) { 27711 val = hooks.get( elem, true, extra ); 27712 } 27713 27714 // Otherwise, if a way to get the computed value exists, use that 27715 if ( val === undefined ) { 27716 val = curCSS( elem, name, styles ); 27717 } 27718 27719 // Convert "normal" to computed value 27720 if ( val === "normal" && name in cssNormalTransform ) { 27721 val = cssNormalTransform[ name ]; 27722 } 27723 27724 // Make numeric if forced or a qualifier was provided and val looks numeric 27725 if ( extra === "" || extra ) { 27726 num = parseFloat( val ); 27727 return extra === true || isFinite( num ) ? num || 0 : val; 27728 } 27729 27730 return val; 27731 } 27732} ); 27733 27734jQuery.each( [ "height", "width" ], function( i, dimension ) { 27735 jQuery.cssHooks[ dimension ] = { 27736 get: function( elem, computed, extra ) { 27737 if ( computed ) { 27738 27739 // Certain elements can have dimension info if we invisibly show them 27740 // but it must have a current display style that would benefit 27741 return rdisplayswap.test( jQuery.css( elem, "display" ) ) && 27742 27743 // Support: Safari 8+ 27744 // Table columns in Safari have non-zero offsetWidth & zero 27745 // getBoundingClientRect().width unless display is changed. 27746 // Support: IE <=11 only 27747 // Running getBoundingClientRect on a disconnected node 27748 // in IE throws an error. 27749 ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? 27750 swap( elem, cssShow, function() { 27751 return getWidthOrHeight( elem, dimension, extra ); 27752 } ) : 27753 getWidthOrHeight( elem, dimension, extra ); 27754 } 27755 }, 27756 27757 set: function( elem, value, extra ) { 27758 var matches, 27759 styles = getStyles( elem ), 27760 27761 // Only read styles.position if the test has a chance to fail 27762 // to avoid forcing a reflow. 27763 scrollboxSizeBuggy = !support.scrollboxSize() && 27764 styles.position === "absolute", 27765 27766 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) 27767 boxSizingNeeded = scrollboxSizeBuggy || extra, 27768 isBorderBox = boxSizingNeeded && 27769 jQuery.css( elem, "boxSizing", false, styles ) === "border-box", 27770 subtract = extra ? 27771 boxModelAdjustment( 27772 elem, 27773 dimension, 27774 extra, 27775 isBorderBox, 27776 styles 27777 ) : 27778 0; 27779 27780 // Account for unreliable border-box dimensions by comparing offset* to computed and 27781 // faking a content-box to get border and padding (gh-3699) 27782 if ( isBorderBox && scrollboxSizeBuggy ) { 27783 subtract -= Math.ceil( 27784 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - 27785 parseFloat( styles[ dimension ] ) - 27786 boxModelAdjustment( elem, dimension, "border", false, styles ) - 27787 0.5 27788 ); 27789 } 27790 27791 // Convert to pixels if value adjustment is needed 27792 if ( subtract && ( matches = rcssNum.exec( value ) ) && 27793 ( matches[ 3 ] || "px" ) !== "px" ) { 27794 27795 elem.style[ dimension ] = value; 27796 value = jQuery.css( elem, dimension ); 27797 } 27798 27799 return setPositiveNumber( elem, value, subtract ); 27800 } 27801 }; 27802} ); 27803 27804jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, 27805 function( elem, computed ) { 27806 if ( computed ) { 27807 return ( parseFloat( curCSS( elem, "marginLeft" ) ) || 27808 elem.getBoundingClientRect().left - 27809 swap( elem, { marginLeft: 0 }, function() { 27810 return elem.getBoundingClientRect().left; 27811 } ) 27812 ) + "px"; 27813 } 27814 } 27815); 27816 27817// These hooks are used by animate to expand properties 27818jQuery.each( { 27819 margin: "", 27820 padding: "", 27821 border: "Width" 27822}, function( prefix, suffix ) { 27823 jQuery.cssHooks[ prefix + suffix ] = { 27824 expand: function( value ) { 27825 var i = 0, 27826 expanded = {}, 27827 27828 // Assumes a single number if not a string 27829 parts = typeof value === "string" ? value.split( " " ) : [ value ]; 27830 27831 for ( ; i < 4; i++ ) { 27832 expanded[ prefix + cssExpand[ i ] + suffix ] = 27833 parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; 27834 } 27835 27836 return expanded; 27837 } 27838 }; 27839 27840 if ( prefix !== "margin" ) { 27841 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; 27842 } 27843} ); 27844 27845jQuery.fn.extend( { 27846 css: function( name, value ) { 27847 return access( this, function( elem, name, value ) { 27848 var styles, len, 27849 map = {}, 27850 i = 0; 27851 27852 if ( Array.isArray( name ) ) { 27853 styles = getStyles( elem ); 27854 len = name.length; 27855 27856 for ( ; i < len; i++ ) { 27857 map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); 27858 } 27859 27860 return map; 27861 } 27862 27863 return value !== undefined ? 27864 jQuery.style( elem, name, value ) : 27865 jQuery.css( elem, name ); 27866 }, name, value, arguments.length > 1 ); 27867 } 27868} ); 27869 27870 27871function Tween( elem, options, prop, end, easing ) { 27872 return new Tween.prototype.init( elem, options, prop, end, easing ); 27873} 27874jQuery.Tween = Tween; 27875 27876Tween.prototype = { 27877 constructor: Tween, 27878 init: function( elem, options, prop, end, easing, unit ) { 27879 this.elem = elem; 27880 this.prop = prop; 27881 this.easing = easing || jQuery.easing._default; 27882 this.options = options; 27883 this.start = this.now = this.cur(); 27884 this.end = end; 27885 this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); 27886 }, 27887 cur: function() { 27888 var hooks = Tween.propHooks[ this.prop ]; 27889 27890 return hooks && hooks.get ? 27891 hooks.get( this ) : 27892 Tween.propHooks._default.get( this ); 27893 }, 27894 run: function( percent ) { 27895 var eased, 27896 hooks = Tween.propHooks[ this.prop ]; 27897 27898 if ( this.options.duration ) { 27899 this.pos = eased = jQuery.easing[ this.easing ]( 27900 percent, this.options.duration * percent, 0, 1, this.options.duration 27901 ); 27902 } else { 27903 this.pos = eased = percent; 27904 } 27905 this.now = ( this.end - this.start ) * eased + this.start; 27906 27907 if ( this.options.step ) { 27908 this.options.step.call( this.elem, this.now, this ); 27909 } 27910 27911 if ( hooks && hooks.set ) { 27912 hooks.set( this ); 27913 } else { 27914 Tween.propHooks._default.set( this ); 27915 } 27916 return this; 27917 } 27918}; 27919 27920Tween.prototype.init.prototype = Tween.prototype; 27921 27922Tween.propHooks = { 27923 _default: { 27924 get: function( tween ) { 27925 var result; 27926 27927 // Use a property on the element directly when it is not a DOM element, 27928 // or when there is no matching style property that exists. 27929 if ( tween.elem.nodeType !== 1 || 27930 tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { 27931 return tween.elem[ tween.prop ]; 27932 } 27933 27934 // Passing an empty string as a 3rd parameter to .css will automatically 27935 // attempt a parseFloat and fallback to a string if the parse fails. 27936 // Simple values such as "10px" are parsed to Float; 27937 // complex values such as "rotate(1rad)" are returned as-is. 27938 result = jQuery.css( tween.elem, tween.prop, "" ); 27939 27940 // Empty strings, null, undefined and "auto" are converted to 0. 27941 return !result || result === "auto" ? 0 : result; 27942 }, 27943 set: function( tween ) { 27944 27945 // Use step hook for back compat. 27946 // Use cssHook if its there. 27947 // Use .style if available and use plain properties where available. 27948 if ( jQuery.fx.step[ tween.prop ] ) { 27949 jQuery.fx.step[ tween.prop ]( tween ); 27950 } else if ( tween.elem.nodeType === 1 && ( 27951 jQuery.cssHooks[ tween.prop ] || 27952 tween.elem.style[ finalPropName( tween.prop ) ] != null
vendor: 29,107 bytes, lines 27952-29149
27952 ) ) { 27953 jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); 27954 } else { 27955 tween.elem[ tween.prop ] = tween.now; 27956 } 27957 } 27958 } 27959}; 27960 27961// Support: IE <=9 only 27962// Panic based approach to setting things on disconnected nodes 27963Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { 27964 set: function( tween ) { 27965 if ( tween.elem.nodeType && tween.elem.parentNode ) { 27966 tween.elem[ tween.prop ] = tween.now; 27967 } 27968 } 27969}; 27970 27971jQuery.easing = { 27972 linear: function( p ) { 27973 return p; 27974 }, 27975 swing: function( p ) { 27976 return 0.5 - Math.cos( p * Math.PI ) / 2; 27977 }, 27978 _default: "swing" 27979}; 27980 27981jQuery.fx = Tween.prototype.init; 27982 27983// Back compat <1.8 extension point 27984jQuery.fx.step = {}; 27985 27986 27987 27988 27989var 27990 fxNow, inProgress, 27991 rfxtypes = /^(?:toggle|show|hide)$/, 27992 rrun = /queueHooks$/; 27993 27994function schedule() { 27995 if ( inProgress ) { 27996 if ( document.hidden === false && window.requestAnimationFrame ) { 27997 window.requestAnimationFrame( schedule ); 27998 } else { 27999 window.setTimeout( schedule, jQuery.fx.interval ); 28000 } 28001 28002 jQuery.fx.tick(); 28003 } 28004} 28005 28006// Animations created synchronously will run synchronously 28007function createFxNow() { 28008 window.setTimeout( function() { 28009 fxNow = undefined; 28010 } ); 28011 return ( fxNow = Date.now() ); 28012} 28013 28014// Generate parameters to create a standard animation 28015function genFx( type, includeWidth ) { 28016 var which, 28017 i = 0, 28018 attrs = { height: type }; 28019 28020 // If we include width, step value is 1 to do all cssExpand values, 28021 // otherwise step value is 2 to skip over Left and Right 28022 includeWidth = includeWidth ? 1 : 0; 28023 for ( ; i < 4; i += 2 - includeWidth ) { 28024 which = cssExpand[ i ]; 28025 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; 28026 } 28027 28028 if ( includeWidth ) { 28029 attrs.opacity = attrs.width = type; 28030 } 28031 28032 return attrs; 28033} 28034 28035function createTween( value, prop, animation ) { 28036 var tween, 28037 collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), 28038 index = 0, 28039 length = collection.length; 28040 for ( ; index < length; index++ ) { 28041 if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { 28042 28043 // We're done with this property 28044 return tween; 28045 } 28046 } 28047} 28048 28049function defaultPrefilter( elem, props, opts ) { 28050 var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, 28051 isBox = "width" in props || "height" in props, 28052 anim = this, 28053 orig = {}, 28054 style = elem.style, 28055 hidden = elem.nodeType && isHiddenWithinTree( elem ), 28056 dataShow = dataPriv.get( elem, "fxshow" ); 28057 28058 // Queue-skipping animations hijack the fx hooks 28059 if ( !opts.queue ) { 28060 hooks = jQuery._queueHooks( elem, "fx" ); 28061 if ( hooks.unqueued == null ) { 28062 hooks.unqueued = 0; 28063 oldfire = hooks.empty.fire; 28064 hooks.empty.fire = function() { 28065 if ( !hooks.unqueued ) { 28066 oldfire(); 28067 } 28068 }; 28069 } 28070 hooks.unqueued++; 28071 28072 anim.always( function() { 28073 28074 // Ensure the complete handler is called before this completes 28075 anim.always( function() { 28076 hooks.unqueued--; 28077 if ( !jQuery.queue( elem, "fx" ).length ) { 28078 hooks.empty.fire(); 28079 } 28080 } ); 28081 } ); 28082 } 28083 28084 // Detect show/hide animations 28085 for ( prop in props ) { 28086 value = props[ prop ]; 28087 if ( rfxtypes.test( value ) ) { 28088 delete props[ prop ]; 28089 toggle = toggle || value === "toggle"; 28090 if ( value === ( hidden ? "hide" : "show" ) ) { 28091 28092 // Pretend to be hidden if this is a "show" and 28093 // there is still data from a stopped show/hide 28094 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { 28095 hidden = true; 28096 28097 // Ignore all other no-op show/hide data 28098 } else { 28099 continue; 28100 } 28101 } 28102 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); 28103 } 28104 } 28105 28106 // Bail out if this is a no-op like .hide().hide() 28107 propTween = !jQuery.isEmptyObject( props ); 28108 if ( !propTween && jQuery.isEmptyObject( orig ) ) { 28109 return; 28110 } 28111 28112 // Restrict "overflow" and "display" styles during box animations 28113 if ( isBox && elem.nodeType === 1 ) { 28114 28115 // Support: IE <=9 - 11, Edge 12 - 15 28116 // Record all 3 overflow attributes because IE does not infer the shorthand 28117 // from identically-valued overflowX and overflowY and Edge just mirrors 28118 // the overflowX value there. 28119 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; 28120 28121 // Identify a display type, preferring old show/hide data over the CSS cascade 28122 restoreDisplay = dataShow && dataShow.display; 28123 if ( restoreDisplay == null ) { 28124 restoreDisplay = dataPriv.get( elem, "display" ); 28125 } 28126 display = jQuery.css( elem, "display" ); 28127 if ( display === "none" ) { 28128 if ( restoreDisplay ) { 28129 display = restoreDisplay; 28130 } else { 28131 28132 // Get nonempty value(s) by temporarily forcing visibility 28133 showHide( [ elem ], true ); 28134 restoreDisplay = elem.style.display || restoreDisplay; 28135 display = jQuery.css( elem, "display" ); 28136 showHide( [ elem ] ); 28137 } 28138 } 28139 28140 // Animate inline elements as inline-block 28141 if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { 28142 if ( jQuery.css( elem, "float" ) === "none" ) { 28143 28144 // Restore the original display value at the end of pure show/hide animations 28145 if ( !propTween ) { 28146 anim.done( function() { 28147 style.display = restoreDisplay; 28148 } ); 28149 if ( restoreDisplay == null ) { 28150 display = style.display; 28151 restoreDisplay = display === "none" ? "" : display; 28152 } 28153 } 28154 style.display = "inline-block"; 28155 } 28156 } 28157 } 28158 28159 if ( opts.overflow ) { 28160 style.overflow = "hidden"; 28161 anim.always( function() { 28162 style.overflow = opts.overflow[ 0 ]; 28163 style.overflowX = opts.overflow[ 1 ]; 28164 style.overflowY = opts.overflow[ 2 ]; 28165 } ); 28166 } 28167 28168 // Implement show/hide animations 28169 propTween = false; 28170 for ( prop in orig ) { 28171 28172 // General show/hide setup for this element animation 28173 if ( !propTween ) { 28174 if ( dataShow ) { 28175 if ( "hidden" in dataShow ) { 28176 hidden = dataShow.hidden; 28177 } 28178 } else { 28179 dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); 28180 } 28181 28182 // Store hidden/visible for toggle so `.stop().toggle()` "reverses" 28183 if ( toggle ) { 28184 dataShow.hidden = !hidden; 28185 } 28186 28187 // Show elements before animating them 28188 if ( hidden ) { 28189 showHide( [ elem ], true ); 28190 } 28191 28192 /* eslint-disable no-loop-func */ 28193 28194 anim.done( function() { 28195 28196 /* eslint-enable no-loop-func */ 28197 28198 // The final step of a "hide" animation is actually hiding the element 28199 if ( !hidden ) { 28200 showHide( [ elem ] ); 28201 } 28202 dataPriv.remove( elem, "fxshow" ); 28203 for ( prop in orig ) { 28204 jQuery.style( elem, prop, orig[ prop ] ); 28205 } 28206 } ); 28207 } 28208 28209 // Per-property setup 28210 propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); 28211 if ( !( prop in dataShow ) ) { 28212 dataShow[ prop ] = propTween.start; 28213 if ( hidden ) { 28214 propTween.end = propTween.start; 28215 propTween.start = 0; 28216 } 28217 } 28218 } 28219} 28220 28221function propFilter( props, specialEasing ) { 28222 var index, name, easing, value, hooks; 28223 28224 // camelCase, specialEasing and expand cssHook pass 28225 for ( index in props ) { 28226 name = camelCase( index ); 28227 easing = specialEasing[ name ]; 28228 value = props[ index ]; 28229 if ( Array.isArray( value ) ) { 28230 easing = value[ 1 ]; 28231 value = props[ index ] = value[ 0 ]; 28232 } 28233 28234 if ( index !== name ) { 28235 props[ name ] = value; 28236 delete props[ index ]; 28237 } 28238 28239 hooks = jQuery.cssHooks[ name ]; 28240 if ( hooks && "expand" in hooks ) { 28241 value = hooks.expand( value ); 28242 delete props[ name ]; 28243 28244 // Not quite $.extend, this won't overwrite existing keys. 28245 // Reusing 'index' because we have the correct "name" 28246 for ( index in value ) { 28247 if ( !( index in props ) ) { 28248 props[ index ] = value[ index ]; 28249 specialEasing[ index ] = easing; 28250 } 28251 } 28252 } else { 28253 specialEasing[ name ] = easing; 28254 } 28255 } 28256} 28257 28258function Animation( elem, properties, options ) { 28259 var result, 28260 stopped, 28261 index = 0, 28262 length = Animation.prefilters.length, 28263 deferred = jQuery.Deferred().always( function() { 28264 28265 // Don't match elem in the :animated selector 28266 delete tick.elem; 28267 } ), 28268 tick = function() { 28269 if ( stopped ) { 28270 return false; 28271 } 28272 var currentTime = fxNow || createFxNow(), 28273 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), 28274 28275 // Support: Android 2.3 only 28276 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) 28277 temp = remaining / animation.duration || 0, 28278 percent = 1 - temp, 28279 index = 0, 28280 length = animation.tweens.length; 28281 28282 for ( ; index < length; index++ ) { 28283 animation.tweens[ index ].run( percent ); 28284 } 28285 28286 deferred.notifyWith( elem, [ animation, percent, remaining ] ); 28287 28288 // If there's more to do, yield 28289 if ( percent < 1 && length ) { 28290 return remaining; 28291 } 28292 28293 // If this was an empty animation, synthesize a final progress notification 28294 if ( !length ) { 28295 deferred.notifyWith( elem, [ animation, 1, 0 ] ); 28296 } 28297 28298 // Resolve the animation and report its conclusion 28299 deferred.resolveWith( elem, [ animation ] ); 28300 return false; 28301 }, 28302 animation = deferred.promise( { 28303 elem: elem, 28304 props: jQuery.extend( {}, properties ), 28305 opts: jQuery.extend( true, { 28306 specialEasing: {}, 28307 easing: jQuery.easing._default 28308 }, options ), 28309 originalProperties: properties, 28310 originalOptions: options, 28311 startTime: fxNow || createFxNow(), 28312 duration: options.duration, 28313 tweens: [], 28314 createTween: function( prop, end ) { 28315 var tween = jQuery.Tween( elem, animation.opts, prop, end, 28316 animation.opts.specialEasing[ prop ] || animation.opts.easing ); 28317 animation.tweens.push( tween ); 28318 return tween; 28319 }, 28320 stop: function( gotoEnd ) { 28321 var index = 0, 28322 28323 // If we are going to the end, we want to run all the tweens 28324 // otherwise we skip this part 28325 length = gotoEnd ? animation.tweens.length : 0; 28326 if ( stopped ) { 28327 return this; 28328 } 28329 stopped = true; 28330 for ( ; index < length; index++ ) { 28331 animation.tweens[ index ].run( 1 ); 28332 } 28333 28334 // Resolve when we played the last frame; otherwise, reject 28335 if ( gotoEnd ) { 28336 deferred.notifyWith( elem, [ animation, 1, 0 ] ); 28337 deferred.resolveWith( elem, [ animation, gotoEnd ] ); 28338 } else { 28339 deferred.rejectWith( elem, [ animation, gotoEnd ] ); 28340 } 28341 return this; 28342 } 28343 } ), 28344 props = animation.props; 28345 28346 propFilter( props, animation.opts.specialEasing ); 28347 28348 for ( ; index < length; index++ ) { 28349 result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); 28350 if ( result ) { 28351 if ( isFunction( result.stop ) ) { 28352 jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = 28353 result.stop.bind( result ); 28354 } 28355 return result; 28356 } 28357 } 28358 28359 jQuery.map( props, createTween, animation ); 28360 28361 if ( isFunction( animation.opts.start ) ) { 28362 animation.opts.start.call( elem, animation ); 28363 } 28364 28365 // Attach callbacks from options 28366 animation 28367 .progress( animation.opts.progress ) 28368 .done( animation.opts.done, animation.opts.complete ) 28369 .fail( animation.opts.fail ) 28370 .always( animation.opts.always ); 28371 28372 jQuery.fx.timer( 28373 jQuery.extend( tick, { 28374 elem: elem, 28375 anim: animation, 28376 queue: animation.opts.queue 28377 } ) 28378 ); 28379 28380 return animation; 28381} 28382 28383jQuery.Animation = jQuery.extend( Animation, { 28384 28385 tweeners: { 28386 "*": [ function( prop, value ) { 28387 var tween = this.createTween( prop, value ); 28388 adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); 28389 return tween; 28390 } ] 28391 }, 28392 28393 tweener: function( props, callback ) { 28394 if ( isFunction( props ) ) { 28395 callback = props; 28396 props = [ "*" ]; 28397 } else { 28398 props = props.match( rnothtmlwhite ); 28399 } 28400 28401 var prop, 28402 index = 0, 28403 length = props.length; 28404 28405 for ( ; index < length; index++ ) { 28406 prop = props[ index ]; 28407 Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; 28408 Animation.tweeners[ prop ].unshift( callback ); 28409 } 28410 }, 28411 28412 prefilters: [ defaultPrefilter ], 28413 28414 prefilter: function( callback, prepend ) { 28415 if ( prepend ) { 28416 Animation.prefilters.unshift( callback ); 28417 } else { 28418 Animation.prefilters.push( callback ); 28419 } 28420 } 28421} ); 28422 28423jQuery.speed = function( speed, easing, fn ) { 28424 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { 28425 complete: fn || !fn && easing || 28426 isFunction( speed ) && speed, 28427 duration: speed, 28428 easing: fn && easing || easing && !isFunction( easing ) && easing 28429 }; 28430 28431 // Go to the end state if fx are off 28432 if ( jQuery.fx.off ) { 28433 opt.duration = 0; 28434 28435 } else { 28436 if ( typeof opt.duration !== "number" ) { 28437 if ( opt.duration in jQuery.fx.speeds ) { 28438 opt.duration = jQuery.fx.speeds[ opt.duration ]; 28439 28440 } else { 28441 opt.duration = jQuery.fx.speeds._default; 28442 } 28443 } 28444 } 28445 28446 // Normalize opt.queue - true/undefined/null -> "fx" 28447 if ( opt.queue == null || opt.queue === true ) { 28448 opt.queue = "fx"; 28449 } 28450 28451 // Queueing 28452 opt.old = opt.complete; 28453 28454 opt.complete = function() { 28455 if ( isFunction( opt.old ) ) { 28456 opt.old.call( this ); 28457 } 28458 28459 if ( opt.queue ) { 28460 jQuery.dequeue( this, opt.queue ); 28461 } 28462 }; 28463 28464 return opt; 28465}; 28466 28467jQuery.fn.extend( { 28468 fadeTo: function( speed, to, easing, callback ) { 28469 28470 // Show any hidden elements after setting opacity to 0 28471 return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() 28472 28473 // Animate to the value specified 28474 .end().animate( { opacity: to }, speed, easing, callback ); 28475 }, 28476 animate: function( prop, speed, easing, callback ) { 28477 var empty = jQuery.isEmptyObject( prop ), 28478 optall = jQuery.speed( speed, easing, callback ), 28479 doAnimation = function() { 28480 28481 // Operate on a copy of prop so per-property easing won't be lost 28482 var anim = Animation( this, jQuery.extend( {}, prop ), optall ); 28483 28484 // Empty animations, or finishing resolves immediately 28485 if ( empty || dataPriv.get( this, "finish" ) ) { 28486 anim.stop( true ); 28487 } 28488 }; 28489 doAnimation.finish = doAnimation; 28490 28491 return empty || optall.queue === false ? 28492 this.each( doAnimation ) : 28493 this.queue( optall.queue, doAnimation ); 28494 }, 28495 stop: function( type, clearQueue, gotoEnd ) { 28496 var stopQueue = function( hooks ) { 28497 var stop = hooks.stop; 28498 delete hooks.stop; 28499 stop( gotoEnd ); 28500 }; 28501 28502 if ( typeof type !== "string" ) { 28503 gotoEnd = clearQueue; 28504 clearQueue = type; 28505 type = undefined; 28506 } 28507 if ( clearQueue && type !== false ) { 28508 this.queue( type || "fx", [] ); 28509 } 28510 28511 return this.each( function() { 28512 var dequeue = true, 28513 index = type != null && type + "queueHooks", 28514 timers = jQuery.timers, 28515 data = dataPriv.get( this ); 28516 28517 if ( index ) { 28518 if ( data[ index ] && data[ index ].stop ) { 28519 stopQueue( data[ index ] ); 28520 } 28521 } else { 28522 for ( index in data ) { 28523 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { 28524 stopQueue( data[ index ] ); 28525 } 28526 } 28527 } 28528 28529 for ( index = timers.length; index--; ) { 28530 if ( timers[ index ].elem === this && 28531 ( type == null || timers[ index ].queue === type ) ) { 28532 28533 timers[ index ].anim.stop( gotoEnd ); 28534 dequeue = false; 28535 timers.splice( index, 1 ); 28536 } 28537 } 28538 28539 // Start the next in the queue if the last step wasn't forced. 28540 // Timers currently will call their complete callbacks, which 28541 // will dequeue but only if they were gotoEnd. 28542 if ( dequeue || !gotoEnd ) { 28543 jQuery.dequeue( this, type ); 28544 } 28545 } ); 28546 }, 28547 finish: function( type ) { 28548 if ( type !== false ) { 28549 type = type || "fx"; 28550 } 28551 return this.each( function() { 28552 var index, 28553 data = dataPriv.get( this ), 28554 queue = data[ type + "queue" ], 28555 hooks = data[ type + "queueHooks" ], 28556 timers = jQuery.timers, 28557 length = queue ? queue.length : 0; 28558 28559 // Enable finishing flag on private data 28560 data.finish = true; 28561 28562 // Empty the queue first 28563 jQuery.queue( this, type, [] ); 28564 28565 if ( hooks && hooks.stop ) { 28566 hooks.stop.call( this, true ); 28567 } 28568 28569 // Look for any active animations, and finish them 28570 for ( index = timers.length; index--; ) { 28571 if ( timers[ index ].elem === this && timers[ index ].queue === type ) { 28572 timers[ index ].anim.stop( true ); 28573 timers.splice( index, 1 ); 28574 } 28575 } 28576 28577 // Look for any animations in the old queue and finish them 28578 for ( index = 0; index < length; index++ ) { 28579 if ( queue[ index ] && queue[ index ].finish ) { 28580 queue[ index ].finish.call( this ); 28581 } 28582 } 28583 28584 // Turn off finishing flag 28585 delete data.finish; 28586 } ); 28587 } 28588} ); 28589 28590jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) { 28591 var cssFn = jQuery.fn[ name ]; 28592 jQuery.fn[ name ] = function( speed, easing, callback ) { 28593 return speed == null || typeof speed === "boolean" ? 28594 cssFn.apply( this, arguments ) : 28595 this.animate( genFx( name, true ), speed, easing, callback ); 28596 }; 28597} ); 28598 28599// Generate shortcuts for custom animations 28600jQuery.each( { 28601 slideDown: genFx( "show" ), 28602 slideUp: genFx( "hide" ), 28603 slideToggle: genFx( "toggle" ), 28604 fadeIn: { opacity: "show" }, 28605 fadeOut: { opacity: "hide" }, 28606 fadeToggle: { opacity: "toggle" } 28607}, function( name, props ) { 28608 jQuery.fn[ name ] = function( speed, easing, callback ) { 28609 return this.animate( props, speed, easing, callback ); 28610 }; 28611} ); 28612 28613jQuery.timers = []; 28614jQuery.fx.tick = function() { 28615 var timer, 28616 i = 0, 28617 timers = jQuery.timers; 28618 28619 fxNow = Date.now(); 28620 28621 for ( ; i < timers.length; i++ ) { 28622 timer = timers[ i ]; 28623 28624 // Run the timer and safely remove it when done (allowing for external removal) 28625 if ( !timer() && timers[ i ] === timer ) { 28626 timers.splice( i--, 1 ); 28627 } 28628 } 28629 28630 if ( !timers.length ) { 28631 jQuery.fx.stop(); 28632 } 28633 fxNow = undefined; 28634}; 28635 28636jQuery.fx.timer = function( timer ) { 28637 jQuery.timers.push( timer ); 28638 jQuery.fx.start(); 28639}; 28640 28641jQuery.fx.interval = 13; 28642jQuery.fx.start = function() { 28643 if ( inProgress ) { 28644 return; 28645 } 28646 28647 inProgress = true; 28648 schedule(); 28649}; 28650 28651jQuery.fx.stop = function() { 28652 inProgress = null; 28653}; 28654 28655jQuery.fx.speeds = { 28656 slow: 600, 28657 fast: 200, 28658 28659 // Default speed 28660 _default: 400 28661}; 28662 28663 28664// Based off of the plugin by Clint Helfers, with permission. 28665// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ 28666jQuery.fn.delay = function( time, type ) { 28667 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; 28668 type = type || "fx"; 28669 28670 return this.queue( type, function( next, hooks ) { 28671 var timeout = window.setTimeout( next, time ); 28672 hooks.stop = function() { 28673 window.clearTimeout( timeout ); 28674 }; 28675 } ); 28676}; 28677 28678 28679( function() { 28680 var input = document.createElement( "input" ), 28681 select = document.createElement( "select" ), 28682 opt = select.appendChild( document.createElement( "option" ) ); 28683 28684 input.type = "checkbox"; 28685 28686 // Support: Android <=4.3 only 28687 // Default value for a checkbox should be "on" 28688 support.checkOn = input.value !== ""; 28689 28690 // Support: IE <=11 only 28691 // Must access selectedIndex to make default options select 28692 support.optSelected = opt.selected; 28693 28694 // Support: IE <=11 only 28695 // An input loses its value after becoming a radio 28696 input = document.createElement( "input" ); 28697 input.value = "t"; 28698 input.type = "radio"; 28699 support.radioValue = input.value === "t"; 28700} )(); 28701 28702 28703var boolHook, 28704 attrHandle = jQuery.expr.attrHandle; 28705 28706jQuery.fn.extend( { 28707 attr: function( name, value ) { 28708 return access( this, jQuery.attr, name, value, arguments.length > 1 ); 28709 }, 28710 28711 removeAttr: function( name ) { 28712 return this.each( function() { 28713 jQuery.removeAttr( this, name ); 28714 } ); 28715 } 28716} ); 28717 28718jQuery.extend( { 28719 attr: function( elem, name, value ) { 28720 var ret, hooks, 28721 nType = elem.nodeType; 28722 28723 // Don't get/set attributes on text, comment and attribute nodes 28724 if ( nType === 3 || nType === 8 || nType === 2 ) { 28725 return; 28726 } 28727 28728 // Fallback to prop when attributes are not supported 28729 if ( typeof elem.getAttribute === "undefined" ) { 28730 return jQuery.prop( elem, name, value ); 28731 } 28732 28733 // Attribute hooks are determined by the lowercase version 28734 // Grab necessary hook if one is defined 28735 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { 28736 hooks = jQuery.attrHooks[ name.toLowerCase() ] || 28737 ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); 28738 } 28739 28740 if ( value !== undefined ) { 28741 if ( value === null ) { 28742 jQuery.removeAttr( elem, name ); 28743 return; 28744 } 28745 28746 if ( hooks && "set" in hooks && 28747 ( ret = hooks.set( elem, value, name ) ) !== undefined ) { 28748 return ret; 28749 } 28750 28751 elem.setAttribute( name, value + "" ); 28752 return value; 28753 } 28754 28755 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { 28756 return ret; 28757 } 28758 28759 ret = jQuery.find.attr( elem, name ); 28760 28761 // Non-existent attributes return null, we normalize to undefined 28762 return ret == null ? undefined : ret; 28763 }, 28764 28765 attrHooks: { 28766 type: { 28767 set: function( elem, value ) { 28768 if ( !support.radioValue && value === "radio" && 28769 nodeName( elem, "input" ) ) { 28770 var val = elem.value; 28771 elem.setAttribute( "type", value ); 28772 if ( val ) { 28773 elem.value = val; 28774 } 28775 return value; 28776 } 28777 } 28778 } 28779 }, 28780 28781 removeAttr: function( elem, value ) { 28782 var name, 28783 i = 0, 28784 28785 // Attribute names can contain non-HTML whitespace characters 28786 // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 28787 attrNames = value && value.match( rnothtmlwhite ); 28788 28789 if ( attrNames && elem.nodeType === 1 ) { 28790 while ( ( name = attrNames[ i++ ] ) ) { 28791 elem.removeAttribute( name ); 28792 } 28793 } 28794 } 28795} ); 28796 28797// Hooks for boolean attributes 28798boolHook = { 28799 set: function( elem, value, name ) { 28800 if ( value === false ) { 28801 28802 // Remove boolean attributes when set to false 28803 jQuery.removeAttr( elem, name ); 28804 } else { 28805 elem.setAttribute( name, name ); 28806 } 28807 return name; 28808 } 28809}; 28810 28811jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { 28812 var getter = attrHandle[ name ] || jQuery.find.attr; 28813 28814 attrHandle[ name ] = function( elem, name, isXML ) { 28815 var ret, handle, 28816 lowercaseName = name.toLowerCase(); 28817 28818 if ( !isXML ) { 28819 28820 // Avoid an infinite loop by temporarily removing this function from the getter 28821 handle = attrHandle[ lowercaseName ]; 28822 attrHandle[ lowercaseName ] = ret; 28823 ret = getter( elem, name, isXML ) != null ? 28824 lowercaseName : 28825 null; 28826 attrHandle[ lowercaseName ] = handle; 28827 } 28828 return ret; 28829 }; 28830} ); 28831 28832 28833 28834 28835var rfocusable = /^(?:input|select|textarea|button)$/i, 28836 rclickable = /^(?:a|area)$/i; 28837 28838jQuery.fn.extend( { 28839 prop: function( name, value ) { 28840 return access( this, jQuery.prop, name, value, arguments.length > 1 ); 28841 }, 28842 28843 removeProp: function( name ) { 28844 return this.each( function() { 28845 delete this[ jQuery.propFix[ name ] || name ]; 28846 } ); 28847 } 28848} ); 28849 28850jQuery.extend( { 28851 prop: function( elem, name, value ) { 28852 var ret, hooks, 28853 nType = elem.nodeType; 28854 28855 // Don't get/set properties on text, comment and attribute nodes 28856 if ( nType === 3 || nType === 8 || nType === 2 ) { 28857 return; 28858 } 28859 28860 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { 28861 28862 // Fix name and attach hooks 28863 name = jQuery.propFix[ name ] || name; 28864 hooks = jQuery.propHooks[ name ]; 28865 } 28866 28867 if ( value !== undefined ) { 28868 if ( hooks && "set" in hooks && 28869 ( ret = hooks.set( elem, value, name ) ) !== undefined ) { 28870 return ret; 28871 } 28872 28873 return ( elem[ name ] = value ); 28874 } 28875 28876 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { 28877 return ret; 28878 } 28879 28880 return elem[ name ]; 28881 }, 28882 28883 propHooks: { 28884 tabIndex: { 28885 get: function( elem ) { 28886 28887 // Support: IE <=9 - 11 only 28888 // elem.tabIndex doesn't always return the 28889 // correct value when it hasn't been explicitly set 28890 // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ 28891 // Use proper attribute retrieval(#12072) 28892 var tabindex = jQuery.find.attr( elem, "tabindex" ); 28893 28894 if ( tabindex ) { 28895 return parseInt( tabindex, 10 ); 28896 } 28897 28898 if ( 28899 rfocusable.test( elem.nodeName ) || 28900 rclickable.test( elem.nodeName ) && 28901 elem.href 28902 ) { 28903 return 0; 28904 } 28905 28906 return -1; 28907 } 28908 } 28909 }, 28910 28911 propFix: { 28912 "for": "htmlFor", 28913 "class": "className" 28914 } 28915} ); 28916 28917// Support: IE <=11 only 28918// Accessing the selectedIndex property 28919// forces the browser to respect setting selected 28920// on the option 28921// The getter ensures a default option is selected 28922// when in an optgroup 28923// eslint rule "no-unused-expressions" is disabled for this code 28924// since it considers such accessions noop 28925if ( !support.optSelected ) { 28926 jQuery.propHooks.selected = { 28927 get: function( elem ) { 28928 28929 /* eslint no-unused-expressions: "off" */ 28930 28931 var parent = elem.parentNode; 28932 if ( parent && parent.parentNode ) { 28933 parent.parentNode.selectedIndex; 28934 } 28935 return null; 28936 }, 28937 set: function( elem ) { 28938 28939 /* eslint no-unused-expressions: "off" */ 28940 28941 var parent = elem.parentNode; 28942 if ( parent ) { 28943 parent.selectedIndex; 28944 28945 if ( parent.parentNode ) { 28946 parent.parentNode.selectedIndex; 28947 } 28948 } 28949 } 28950 }; 28951} 28952 28953jQuery.each( [ 28954 "tabIndex", 28955 "readOnly", 28956 "maxLength", 28957 "cellSpacing", 28958 "cellPadding", 28959 "rowSpan", 28960 "colSpan", 28961 "useMap", 28962 "frameBorder", 28963 "contentEditable" 28964], function() { 28965 jQuery.propFix[ this.toLowerCase() ] = this; 28966} ); 28967 28968 28969 28970 28971 // Strip and collapse whitespace according to HTML spec 28972 // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace 28973 function stripAndCollapse( value ) { 28974 var tokens = value.match( rnothtmlwhite ) || []; 28975 return tokens.join( " " ); 28976 } 28977 28978 28979function getClass( elem ) { 28980 return elem.getAttribute && elem.getAttribute( "class" ) || ""; 28981} 28982 28983function classesToArray( value ) { 28984 if ( Array.isArray( value ) ) { 28985 return value; 28986 } 28987 if ( typeof value === "string" ) { 28988 return value.match( rnothtmlwhite ) || []; 28989 } 28990 return []; 28991} 28992 28993jQuery.fn.extend( { 28994 addClass: function( value ) { 28995 var classes, elem, cur, curValue, clazz, j, finalValue, 28996 i = 0; 28997 28998 if ( isFunction( value ) ) { 28999 return this.each( function( j ) { 29000 jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); 29001 } ); 29002 } 29003 29004 classes = classesToArray( value ); 29005 29006 if ( classes.length ) { 29007 while ( ( elem = this[ i++ ] ) ) { 29008 curValue = getClass( elem ); 29009 cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); 29010 29011 if ( cur ) { 29012 j = 0; 29013 while ( ( clazz = classes[ j++ ] ) ) { 29014 if ( cur.indexOf( " " + clazz + " " ) < 0 ) { 29015 cur += clazz + " "; 29016 } 29017 } 29018 29019 // Only assign if different to avoid unneeded rendering. 29020 finalValue = stripAndCollapse( cur ); 29021 if ( curValue !== finalValue ) { 29022 elem.setAttribute( "class", finalValue ); 29023 } 29024 } 29025 } 29026 } 29027 29028 return this; 29029 }, 29030 29031 removeClass: function( value ) { 29032 var classes, elem, cur, curValue, clazz, j, finalValue, 29033 i = 0; 29034 29035 if ( isFunction( value ) ) { 29036 return this.each( function( j ) { 29037 jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); 29038 } ); 29039 } 29040 29041 if ( !arguments.length ) { 29042 return this.attr( "class", "" ); 29043 } 29044 29045 classes = classesToArray( value ); 29046 29047 if ( classes.length ) { 29048 while ( ( elem = this[ i++ ] ) ) { 29049 curValue = getClass( elem ); 29050 29051 // This expression is here for better compressibility (see addClass) 29052 cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); 29053 29054 if ( cur ) { 29055 j = 0; 29056 while ( ( clazz = classes[ j++ ] ) ) { 29057 29058 // Remove *all* instances 29059 while ( cur.indexOf( " " + clazz + " " ) > -1 ) { 29060 cur = cur.replace( " " + clazz + " ", " " ); 29061 } 29062 } 29063 29064 // Only assign if different to avoid unneeded rendering. 29065 finalValue = stripAndCollapse( cur ); 29066 if ( curValue !== finalValue ) { 29067 elem.setAttribute( "class", finalValue ); 29068 } 29069 } 29070 } 29071 } 29072 29073 return this; 29074 }, 29075 29076 toggleClass: function( value, stateVal ) { 29077 var type = typeof value, 29078 isValidValue = type === "string" || Array.isArray( value ); 29079 29080 if ( typeof stateVal === "boolean" && isValidValue ) { 29081 return stateVal ? this.addClass( value ) : this.removeClass( value ); 29082 } 29083 29084 if ( isFunction( value ) ) { 29085 return this.each( function( i ) { 29086 jQuery( this ).toggleClass( 29087 value.call( this, i, getClass( this ), stateVal ), 29088 stateVal 29089 ); 29090 } ); 29091 } 29092 29093 return this.each( function() { 29094 var className, i, self, classNames; 29095 29096 if ( isValidValue ) { 29097 29098 // Toggle individual class names 29099 i = 0; 29100 self = jQuery( this ); 29101 classNames = classesToArray( value ); 29102 29103 while ( ( className = classNames[ i++ ] ) ) { 29104 29105 // Check each className given, space separated list 29106 if ( self.hasClass( className ) ) { 29107 self.removeClass( className ); 29108 } else { 29109 self.addClass( className ); 29110 } 29111 } 29112 29113 // Toggle whole class name 29114 } else if ( value === undefined || type === "boolean" ) { 29115 className = getClass( this ); 29116 if ( className ) { 29117 29118 // Store className if set 29119 dataPriv.set( this, "__className__", className ); 29120 } 29121 29122 // If the element has a class name or if we're passed `false`, 29123 // then remove the whole classname (if there was one, the above saved it). 29124 // Otherwise bring back whatever was previously saved (if anything), 29125 // falling back to the empty string if nothing was stored. 29126 if ( this.setAttribute ) { 29127 this.setAttribute( "class", 29128 className || value === false ? 29129 "" : 29130 dataPriv.get( this, "__className__" ) || "" 29131 ); 29132 } 29133 } 29134 } ); 29135 }, 29136 29137 hasClass: function( selector ) { 29138 var className, elem, 29139 i = 0; 29140 29141 className = " " + selector + " "; 29142 while ( ( elem = this[ i++ ] ) ) { 29143 if ( elem.nodeType === 1 && 29144 ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { 29145 return true; 29146 } 29147 } 29148 29149 return false;
vendor: 5,544 bytes, lines 29150-29385
29150 } 29151} ); 29152 29153 29154 29155 29156var rreturn = /\r/g; 29157 29158jQuery.fn.extend( { 29159 val: function( value ) { 29160 var hooks, ret, valueIsFunction, 29161 elem = this[ 0 ]; 29162 29163 if ( !arguments.length ) { 29164 if ( elem ) { 29165 hooks = jQuery.valHooks[ elem.type ] || 29166 jQuery.valHooks[ elem.nodeName.toLowerCase() ]; 29167 29168 if ( hooks && 29169 "get" in hooks && 29170 ( ret = hooks.get( elem, "value" ) ) !== undefined 29171 ) { 29172 return ret; 29173 } 29174 29175 ret = elem.value; 29176 29177 // Handle most common string cases 29178 if ( typeof ret === "string" ) { 29179 return ret.replace( rreturn, "" ); 29180 } 29181 29182 // Handle cases where value is null/undef or number 29183 return ret == null ? "" : ret; 29184 } 29185 29186 return; 29187 } 29188 29189 valueIsFunction = isFunction( value ); 29190 29191 return this.each( function( i ) { 29192 var val; 29193 29194 if ( this.nodeType !== 1 ) { 29195 return; 29196 } 29197 29198 if ( valueIsFunction ) { 29199 val = value.call( this, i, jQuery( this ).val() ); 29200 } else { 29201 val = value; 29202 } 29203 29204 // Treat null/undefined as ""; convert numbers to string 29205 if ( val == null ) { 29206 val = ""; 29207 29208 } else if ( typeof val === "number" ) { 29209 val += ""; 29210 29211 } else if ( Array.isArray( val ) ) { 29212 val = jQuery.map( val, function( value ) { 29213 return value == null ? "" : value + ""; 29214 } ); 29215 } 29216 29217 hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; 29218 29219 // If set returns undefined, fall back to normal setting 29220 if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { 29221 this.value = val; 29222 } 29223 } ); 29224 } 29225} ); 29226 29227jQuery.extend( { 29228 valHooks: { 29229 option: { 29230 get: function( elem ) { 29231 29232 var val = jQuery.find.attr( elem, "value" ); 29233 return val != null ? 29234 val : 29235 29236 // Support: IE <=10 - 11 only 29237 // option.text throws exceptions (#14686, #14858) 29238 // Strip and collapse whitespace 29239 // https://html.spec.whatwg.org/#strip-and-collapse-whitespace 29240 stripAndCollapse( jQuery.text( elem ) ); 29241 } 29242 }, 29243 select: { 29244 get: function( elem ) { 29245 var value, option, i, 29246 options = elem.options, 29247 index = elem.selectedIndex, 29248 one = elem.type === "select-one", 29249 values = one ? null : [], 29250 max = one ? index + 1 : options.length; 29251 29252 if ( index < 0 ) { 29253 i = max; 29254 29255 } else { 29256 i = one ? index : 0; 29257 } 29258 29259 // Loop through all the selected options 29260 for ( ; i < max; i++ ) { 29261 option = options[ i ]; 29262 29263 // Support: IE <=9 only 29264 // IE8-9 doesn't update selected after form reset (#2551) 29265 if ( ( option.selected || i === index ) && 29266 29267 // Don't return options that are disabled or in a disabled optgroup 29268 !option.disabled && 29269 ( !option.parentNode.disabled || 29270 !nodeName( option.parentNode, "optgroup" ) ) ) { 29271 29272 // Get the specific value for the option 29273 value = jQuery( option ).val(); 29274 29275 // We don't need an array for one selects 29276 if ( one ) { 29277 return value; 29278 } 29279 29280 // Multi-Selects return an array 29281 values.push( value ); 29282 } 29283 } 29284 29285 return values; 29286 }, 29287 29288 set: function( elem, value ) { 29289 var optionSet, option, 29290 options = elem.options, 29291 values = jQuery.makeArray( value ), 29292 i = options.length; 29293 29294 while ( i-- ) { 29295 option = options[ i ]; 29296 29297 /* eslint-disable no-cond-assign */ 29298 29299 if ( option.selected = 29300 jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 29301 ) { 29302 optionSet = true; 29303 } 29304 29305 /* eslint-enable no-cond-assign */ 29306 } 29307 29308 // Force browsers to behave consistently when non-matching value is set 29309 if ( !optionSet ) { 29310 elem.selectedIndex = -1; 29311 } 29312 return values; 29313 } 29314 } 29315 } 29316} ); 29317 29318// Radios and checkboxes getter/setter 29319jQuery.each( [ "radio", "checkbox" ], function() { 29320 jQuery.valHooks[ this ] = { 29321 set: function( elem, value ) { 29322 if ( Array.isArray( value ) ) { 29323 return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); 29324 } 29325 } 29326 }; 29327 if ( !support.checkOn ) { 29328 jQuery.valHooks[ this ].get = function( elem ) { 29329 return elem.getAttribute( "value" ) === null ? "on" : elem.value; 29330 }; 29331 } 29332} ); 29333 29334 29335 29336 29337// Return jQuery for attributes-only inclusion 29338 29339 29340support.focusin = "onfocusin" in window; 29341 29342 29343var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, 29344 stopPropagationCallback = function( e ) { 29345 e.stopPropagation(); 29346 }; 29347 29348jQuery.extend( jQuery.event, { 29349 29350 trigger: function( event, data, elem, onlyHandlers ) { 29351 29352 var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, 29353 eventPath = [ elem || document ], 29354 type = hasOwn.call( event, "type" ) ? event.type : event, 29355 namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; 29356 29357 cur = lastElement = tmp = elem = elem || document; 29358 29359 // Don't do events on text and comment nodes 29360 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { 29361 return; 29362 } 29363 29364 // focus/blur morphs to focusin/out; ensure we're not firing them right now 29365 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { 29366 return; 29367 } 29368 29369 if ( type.indexOf( "." ) > -1 ) { 29370 29371 // Namespaced trigger; create a regexp to match event type in handle() 29372 namespaces = type.split( "." ); 29373 type = namespaces.shift(); 29374 namespaces.sort(); 29375 } 29376 ontype = type.indexOf( ":" ) < 0 && "on" + type; 29377 29378 // Caller can pass in a jQuery.Event object, Object, or just an event type string 29379 event = event[ jQuery.expando ] ? 29380 event : 29381 new jQuery.Event( type, typeof event === "object" && event ); 29382 29383 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) 29384 event.isTrigger = onlyHandlers ? 2 : 3; 29385 event.namespace = namespaces.join( "." );
vendor: 7,012 bytes, lines 29386-29659
29386 event.rnamespace = event.namespace ? 29387 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : 29388 null; 29389 29390 // Clean up the event in case it is being reused 29391 event.result = undefined; 29392 if ( !event.target ) { 29393 event.target = elem; 29394 } 29395 29396 // Clone any incoming data and prepend the event, creating the handler arg list 29397 data = data == null ? 29398 [ event ] : 29399 jQuery.makeArray( data, [ event ] ); 29400 29401 // Allow special events to draw outside the lines 29402 special = jQuery.event.special[ type ] || {}; 29403 if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { 29404 return; 29405 } 29406 29407 // Determine event propagation path in advance, per W3C events spec (#9951) 29408 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) 29409 if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { 29410 29411 bubbleType = special.delegateType || type; 29412 if ( !rfocusMorph.test( bubbleType + type ) ) { 29413 cur = cur.parentNode; 29414 } 29415 for ( ; cur; cur = cur.parentNode ) { 29416 eventPath.push( cur ); 29417 tmp = cur; 29418 } 29419 29420 // Only add window if we got to document (e.g., not plain obj or detached DOM) 29421 if ( tmp === ( elem.ownerDocument || document ) ) { 29422 eventPath.push( tmp.defaultView || tmp.parentWindow || window ); 29423 } 29424 } 29425 29426 // Fire handlers on the event path 29427 i = 0; 29428 while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { 29429 lastElement = cur; 29430 event.type = i > 1 ? 29431 bubbleType : 29432 special.bindType || type; 29433 29434 // jQuery handler 29435 handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] && 29436 dataPriv.get( cur, "handle" ); 29437 if ( handle ) { 29438 handle.apply( cur, data ); 29439 } 29440 29441 // Native handler 29442 handle = ontype && cur[ ontype ]; 29443 if ( handle && handle.apply && acceptData( cur ) ) { 29444 event.result = handle.apply( cur, data ); 29445 if ( event.result === false ) { 29446 event.preventDefault(); 29447 } 29448 } 29449 } 29450 event.type = type; 29451 29452 // If nobody prevented the default action, do it now 29453 if ( !onlyHandlers && !event.isDefaultPrevented() ) { 29454 29455 if ( ( !special._default || 29456 special._default.apply( eventPath.pop(), data ) === false ) && 29457 acceptData( elem ) ) { 29458 29459 // Call a native DOM method on the target with the same name as the event. 29460 // Don't do default actions on window, that's where global variables be (#6170) 29461 if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { 29462 29463 // Don't re-trigger an onFOO event when we call its FOO() method 29464 tmp = elem[ ontype ]; 29465 29466 if ( tmp ) { 29467 elem[ ontype ] = null; 29468 } 29469 29470 // Prevent re-triggering of the same event, since we already bubbled it above 29471 jQuery.event.triggered = type; 29472 29473 if ( event.isPropagationStopped() ) { 29474 lastElement.addEventListener( type, stopPropagationCallback ); 29475 } 29476 29477 elem[ type ](); 29478 29479 if ( event.isPropagationStopped() ) { 29480 lastElement.removeEventListener( type, stopPropagationCallback ); 29481 } 29482 29483 jQuery.event.triggered = undefined; 29484 29485 if ( tmp ) { 29486 elem[ ontype ] = tmp; 29487 } 29488 } 29489 } 29490 } 29491 29492 return event.result; 29493 }, 29494 29495 // Piggyback on a donor event to simulate a different one 29496 // Used only for `focus(in | out)` events 29497 simulate: function( type, elem, event ) { 29498 var e = jQuery.extend( 29499 new jQuery.Event(), 29500 event, 29501 { 29502 type: type, 29503 isSimulated: true 29504 } 29505 ); 29506 29507 jQuery.event.trigger( e, null, elem ); 29508 } 29509 29510} ); 29511 29512jQuery.fn.extend( { 29513 29514 trigger: function( type, data ) { 29515 return this.each( function() { 29516 jQuery.event.trigger( type, data, this ); 29517 } ); 29518 }, 29519 triggerHandler: function( type, data ) { 29520 var elem = this[ 0 ]; 29521 if ( elem ) { 29522 return jQuery.event.trigger( type, data, elem, true ); 29523 } 29524 } 29525} ); 29526 29527 29528// Support: Firefox <=44 29529// Firefox doesn't have focus(in | out) events 29530// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 29531// 29532// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 29533// focus(in | out) events fire after focus & blur events, 29534// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order 29535// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 29536if ( !support.focusin ) { 29537 jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { 29538 29539 // Attach a single capturing handler on the document while someone wants focusin/focusout 29540 var handler = function( event ) { 29541 jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); 29542 }; 29543 29544 jQuery.event.special[ fix ] = { 29545 setup: function() { 29546 var doc = this.ownerDocument || this, 29547 attaches = dataPriv.access( doc, fix ); 29548 29549 if ( !attaches ) { 29550 doc.addEventListener( orig, handler, true ); 29551 } 29552 dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); 29553 }, 29554 teardown: function() { 29555 var doc = this.ownerDocument || this, 29556 attaches = dataPriv.access( doc, fix ) - 1; 29557 29558 if ( !attaches ) { 29559 doc.removeEventListener( orig, handler, true ); 29560 dataPriv.remove( doc, fix ); 29561 29562 } else { 29563 dataPriv.access( doc, fix, attaches ); 29564 } 29565 } 29566 }; 29567 } ); 29568} 29569var location = window.location; 29570 29571var nonce = Date.now(); 29572 29573var rquery = ( /\?/ ); 29574 29575 29576 29577// Cross-browser xml parsing 29578jQuery.parseXML = function( data ) { 29579 var xml; 29580 if ( !data || typeof data !== "string" ) { 29581 return null; 29582 } 29583 29584 // Support: IE 9 - 11 only 29585 // IE throws on parseFromString with invalid input. 29586 try { 29587 xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); 29588 } catch ( e ) { 29589 xml = undefined; 29590 } 29591 29592 if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { 29593 jQuery.error( "Invalid XML: " + data ); 29594 } 29595 return xml; 29596}; 29597 29598 29599var 29600 rbracket = /\[\]$/, 29601 rCRLF = /\r?\n/g, 29602 rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, 29603 rsubmittable = /^(?:input|select|textarea|keygen)/i; 29604 29605function buildParams( prefix, obj, traditional, add ) { 29606 var name; 29607 29608 if ( Array.isArray( obj ) ) { 29609 29610 // Serialize array item. 29611 jQuery.each( obj, function( i, v ) { 29612 if ( traditional || rbracket.test( prefix ) ) { 29613 29614 // Treat each array item as a scalar. 29615 add( prefix, v ); 29616 29617 } else { 29618 29619 // Item is non-scalar (array or object), encode its numeric index. 29620 buildParams( 29621 prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", 29622 v, 29623 traditional, 29624 add 29625 ); 29626 } 29627 } ); 29628 29629 } else if ( !traditional && toType( obj ) === "object" ) { 29630 29631 // Serialize object item. 29632 for ( name in obj ) { 29633 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); 29634 } 29635 29636 } else { 29637 29638 // Serialize scalar item. 29639 add( prefix, obj ); 29640 } 29641} 29642 29643// Serialize an array of form elements or a set of 29644// key/values into a query string 29645jQuery.param = function( a, traditional ) { 29646 var prefix, 29647 s = [], 29648 add = function( key, valueOrFunction ) { 29649 29650 // If value is a function, invoke it and use its return value 29651 var value = isFunction( valueOrFunction ) ? 29652 valueOrFunction() : 29653 valueOrFunction; 29654 29655 s[ s.length ] = encodeURIComponent( key ) + "=" + 29656 encodeURIComponent( value == null ? "" : value ); 29657 }; 29658 29659
29659if ( a == null ) { 29660 return ""; 29661 }
vendor: 12,730 bytes, lines 29661-30165
29661 29662 29663 // If an array was passed in, assume that it is an array of form elements. 29664 if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { 29665 29666 // Serialize the form elements 29667 jQuery.each( a, function() { 29668 add( this.name, this.value ); 29669 } ); 29670 29671 } else { 29672 29673 // If traditional, encode the "old" way (the way 1.3.2 or older 29674 // did it), otherwise encode params recursively. 29675 for ( prefix in a ) { 29676 buildParams( prefix, a[ prefix ], traditional, add ); 29677 } 29678 } 29679 29680 // Return the resulting serialization 29681 return s.join( "&" ); 29682}; 29683 29684jQuery.fn.extend( { 29685 serialize: function() { 29686 return jQuery.param( this.serializeArray() ); 29687 }, 29688 serializeArray: function() { 29689 return this.map( function() { 29690 29691 // Can add propHook for "elements" to filter or add form elements 29692 var elements = jQuery.prop( this, "elements" ); 29693 return elements ? jQuery.makeArray( elements ) : this; 29694 } ) 29695 .filter( function() { 29696 var type = this.type; 29697 29698 // Use .is( ":disabled" ) so that fieldset[disabled] works 29699 return this.name && !jQuery( this ).is( ":disabled" ) && 29700 rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && 29701 ( this.checked || !rcheckableType.test( type ) ); 29702 } ) 29703 .map( function( i, elem ) { 29704 var val = jQuery( this ).val(); 29705 29706 if ( val == null ) { 29707 return null; 29708 } 29709 29710 if ( Array.isArray( val ) ) { 29711 return jQuery.map( val, function( val ) { 29712 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 29713 } ); 29714 } 29715 29716 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 29717 } ).get(); 29718 } 29719} ); 29720 29721 29722var 29723 r20 = /%20/g, 29724 rhash = /#.*$/, 29725 rantiCache = /([?&])_=[^&]*/, 29726 rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, 29727 29728 // #7653, #8125, #8152: local protocol detection 29729 rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, 29730 rnoContent = /^(?:GET|HEAD)$/, 29731 rprotocol = /^\/\//, 29732 29733 /* Prefilters 29734 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) 29735 * 2) These are called: 29736 * - BEFORE asking for a transport 29737 * - AFTER param serialization (s.data is a string if s.processData is true) 29738 * 3) key is the dataType 29739 * 4) the catchall symbol "*" can be used 29740 * 5) execution will start with transport dataType and THEN continue down to "*" if needed 29741 */ 29742 prefilters = {}, 29743 29744 /* Transports bindings 29745 * 1) key is the dataType 29746 * 2) the catchall symbol "*" can be used 29747 * 3) selection will start with transport dataType and THEN go to "*" if needed 29748 */ 29749 transports = {}, 29750 29751 // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression 29752 allTypes = "*/".concat( "*" ), 29753 29754 // Anchor tag for parsing the document origin 29755 originAnchor = document.createElement( "a" ); 29756 originAnchor.href = location.href; 29757 29758// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport 29759function addToPrefiltersOrTransports( structure ) { 29760 29761 // dataTypeExpression is optional and defaults to "*" 29762 return function( dataTypeExpression, func ) { 29763 29764 if ( typeof dataTypeExpression !== "string" ) { 29765 func = dataTypeExpression; 29766 dataTypeExpression = "*"; 29767 } 29768 29769 var dataType, 29770 i = 0, 29771 dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; 29772 29773 if ( isFunction( func ) ) { 29774 29775 // For each dataType in the dataTypeExpression 29776 while ( ( dataType = dataTypes[ i++ ] ) ) { 29777 29778 // Prepend if requested 29779 if ( dataType[ 0 ] === "+" ) { 29780 dataType = dataType.slice( 1 ) || "*"; 29781 ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); 29782 29783 // Otherwise append 29784 } else { 29785 ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); 29786 } 29787 } 29788 } 29789 }; 29790} 29791 29792// Base inspection function for prefilters and transports 29793function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { 29794 29795 var inspected = {}, 29796 seekingTransport = ( structure === transports ); 29797 29798 function inspect( dataType ) { 29799 var selected; 29800 inspected[ dataType ] = true; 29801 jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { 29802 var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); 29803 if ( typeof dataTypeOrTransport === "string" && 29804 !seekingTransport && !inspected[ dataTypeOrTransport ] ) { 29805 29806 options.dataTypes.unshift( dataTypeOrTransport ); 29807 inspect( dataTypeOrTransport ); 29808 return false; 29809 } else if ( seekingTransport ) { 29810 return !( selected = dataTypeOrTransport ); 29811 } 29812 } ); 29813 return selected; 29814 } 29815 29816 return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); 29817} 29818 29819// A special extend for ajax options 29820// that takes "flat" options (not to be deep extended) 29821// Fixes #9887 29822function ajaxExtend( target, src ) { 29823 var key, deep, 29824 flatOptions = jQuery.ajaxSettings.flatOptions || {}; 29825 29826 for ( key in src ) { 29827 if ( src[ key ] !== undefined ) { 29828 ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; 29829 } 29830 } 29831 if ( deep ) { 29832 jQuery.extend( true, target, deep ); 29833 } 29834 29835 return target; 29836} 29837 29838/* Handles responses to an ajax request: 29839 * - finds the right dataType (mediates between content-type and expected dataType) 29840 * - returns the corresponding response 29841 */ 29842function ajaxHandleResponses( s, jqXHR, responses ) { 29843 29844 var ct, type, finalDataType, firstDataType, 29845 contents = s.contents, 29846 dataTypes = s.dataTypes; 29847 29848 // Remove auto dataType and get content-type in the process 29849 while ( dataTypes[ 0 ] === "*" ) { 29850 dataTypes.shift(); 29851 if ( ct === undefined ) { 29852 ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); 29853 } 29854 } 29855 29856 // Check if we're dealing with a known content-type 29857 if ( ct ) { 29858 for ( type in contents ) { 29859 if ( contents[ type ] && contents[ type ].test( ct ) ) { 29860 dataTypes.unshift( type ); 29861 break; 29862 } 29863 } 29864 } 29865 29866 // Check to see if we have a response for the expected dataType 29867 if ( dataTypes[ 0 ] in responses ) { 29868 finalDataType = dataTypes[ 0 ]; 29869 } else { 29870 29871 // Try convertible dataTypes 29872 for ( type in responses ) { 29873 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { 29874 finalDataType = type; 29875 break; 29876 } 29877 if ( !firstDataType ) { 29878 firstDataType = type; 29879 } 29880 } 29881 29882 // Or just use first one 29883 finalDataType = finalDataType || firstDataType; 29884 } 29885 29886 // If we found a dataType 29887 // We add the dataType to the list if needed 29888 // and return the corresponding response 29889 if ( finalDataType ) { 29890 if ( finalDataType !== dataTypes[ 0 ] ) { 29891 dataTypes.unshift( finalDataType ); 29892 } 29893 return responses[ finalDataType ]; 29894 } 29895} 29896 29897/* Chain conversions given the request and the original response 29898 * Also sets the responseXXX fields on the jqXHR instance 29899 */ 29900function ajaxConvert( s, response, jqXHR, isSuccess ) { 29901 var conv2, current, conv, tmp, prev, 29902 converters = {}, 29903 29904 // Work with a copy of dataTypes in case we need to modify it for conversion 29905 dataTypes = s.dataTypes.slice(); 29906 29907 // Create converters map with lowercased keys 29908 if ( dataTypes[ 1 ] ) { 29909 for ( conv in s.converters ) { 29910 converters[ conv.toLowerCase() ] = s.converters[ conv ]; 29911 } 29912 } 29913 29914 current = dataTypes.shift(); 29915 29916 // Convert to each sequential dataType 29917 while ( current ) { 29918 29919 if ( s.responseFields[ current ] ) { 29920 jqXHR[ s.responseFields[ current ] ] = response; 29921 } 29922 29923 // Apply the dataFilter if provided 29924 if ( !prev && isSuccess && s.dataFilter ) { 29925 response = s.dataFilter( response, s.dataType ); 29926 } 29927 29928 prev = current; 29929 current = dataTypes.shift(); 29930 29931 if ( current ) { 29932 29933 // There's only work to do if current dataType is non-auto 29934 if ( current === "*" ) { 29935 29936 current = prev; 29937 29938 // Convert response if prev dataType is non-auto and differs from current 29939 } else if ( prev !== "*" && prev !== current ) { 29940 29941 // Seek a direct converter 29942 conv = converters[ prev + " " + current ] || converters[ "* " + current ]; 29943 29944 // If none found, seek a pair 29945 if ( !conv ) { 29946 for ( conv2 in converters ) { 29947 29948 // If conv2 outputs current 29949 tmp = conv2.split( " " ); 29950 if ( tmp[ 1 ] === current ) { 29951 29952 // If prev can be converted to accepted input 29953 conv = converters[ prev + " " + tmp[ 0 ] ] || 29954 converters[ "* " + tmp[ 0 ] ]; 29955 if ( conv ) { 29956 29957 // Condense equivalence converters 29958 if ( conv === true ) { 29959 conv = converters[ conv2 ]; 29960 29961 // Otherwise, insert the intermediate dataType 29962 } else if ( converters[ conv2 ] !== true ) { 29963 current = tmp[ 0 ]; 29964 dataTypes.unshift( tmp[ 1 ] ); 29965 } 29966 break; 29967 } 29968 } 29969 } 29970 } 29971 29972 // Apply converter (if not an equivalence) 29973 if ( conv !== true ) { 29974 29975 // Unless errors are allowed to bubble, catch and return them 29976 if ( conv && s.throws ) { 29977 response = conv( response ); 29978 } else { 29979 try { 29980 response = conv( response ); 29981 } catch ( e ) { 29982 return { 29983 state: "parsererror", 29984 error: conv ? e : "No conversion from " + prev + " to " + current 29985 }; 29986 } 29987 } 29988 } 29989 } 29990 } 29991 } 29992 29993 return { state: "success", data: response }; 29994} 29995 29996jQuery.extend( { 29997 29998 // Counter for holding the number of active queries 29999 active: 0, 30000 30001 // Last-Modified header cache for next request 30002 lastModified: {}, 30003 etag: {}, 30004 30005 ajaxSettings: { 30006 url: location.href, 30007 type: "GET", 30008 isLocal: rlocalProtocol.test( location.protocol ), 30009 global: true, 30010 processData: true, 30011 async: true, 30012 contentType: "application/x-www-form-urlencoded; charset=UTF-8", 30013 30014 /* 30015 timeout: 0, 30016 data: null, 30017 dataType: null, 30018 username: null, 30019 password: null, 30020 cache: null, 30021 throws: false, 30022 traditional: false, 30023 headers: {}, 30024 */ 30025 30026 accepts: { 30027 "*": allTypes, 30028 text: "text/plain", 30029 html: "text/html", 30030 xml: "application/xml, text/xml", 30031 json: "application/json, text/javascript" 30032 }, 30033 30034 contents: { 30035 xml: /\bxml\b/, 30036 html: /\bhtml/, 30037 json: /\bjson\b/ 30038 }, 30039 30040 responseFields: { 30041 xml: "responseXML", 30042 text: "responseText", 30043 json: "responseJSON" 30044 }, 30045 30046 // Data converters 30047 // Keys separate source (or catchall "*") and destination types with a single space 30048 converters: { 30049 30050 // Convert anything to text 30051 "* text": String, 30052 30053 // Text to html (true = no transformation) 30054 "text html": true, 30055 30056 // Evaluate text as a json expression 30057 "text json": JSON.parse, 30058 30059 // Parse text as xml 30060 "text xml": jQuery.parseXML 30061 }, 30062 30063 // For options that shouldn't be deep extended: 30064 // you can add your own custom options here if 30065 // and when you create one that shouldn't be 30066 // deep extended (see ajaxExtend) 30067 flatOptions: { 30068 url: true, 30069 context: true 30070 } 30071 }, 30072 30073 // Creates a full fledged settings object into target 30074 // with both ajaxSettings and settings fields. 30075 // If target is omitted, writes into ajaxSettings. 30076 ajaxSetup: function( target, settings ) { 30077 return settings ? 30078 30079 // Building a settings object 30080 ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : 30081 30082 // Extending ajaxSettings 30083 ajaxExtend( jQuery.ajaxSettings, target ); 30084 }, 30085 30086 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), 30087 ajaxTransport: addToPrefiltersOrTransports( transports ), 30088 30089 // Main method 30090 ajax: function( url, options ) { 30091 30092 // If url is an object, simulate pre-1.5 signature 30093 if ( typeof url === "object" ) { 30094 options = url; 30095 url = undefined; 30096 } 30097 30098 // Force options to be an object 30099 options = options || {}; 30100 30101 var transport, 30102 30103 // URL without anti-cache param 30104 cacheURL, 30105 30106 // Response headers 30107 responseHeadersString, 30108 responseHeaders, 30109 30110 // timeout handle 30111 timeoutTimer, 30112 30113 // Url cleanup var 30114 urlAnchor, 30115 30116 // Request state (becomes false upon send and true upon completion) 30117 completed, 30118 30119 // To know if global events are to be dispatched 30120 fireGlobals, 30121 30122 // Loop variable 30123 i, 30124 30125 // uncached part of the url 30126 uncached, 30127 30128 // Create the final options object 30129 s = jQuery.ajaxSetup( {}, options ), 30130 30131 // Callbacks context 30132 callbackContext = s.context || s, 30133 30134 // Context for global events is callbackContext if it is a DOM node or jQuery collection 30135 globalEventContext = s.context && 30136 ( callbackContext.nodeType || callbackContext.jquery ) ? 30137 jQuery( callbackContext ) : 30138 jQuery.event, 30139 30140 // Deferreds 30141 deferred = jQuery.Deferred(), 30142 completeDeferred = jQuery.Callbacks( "once memory" ), 30143 30144 // Status-dependent callbacks 30145 statusCode = s.statusCode || {}, 30146 30147 // Headers (they are sent all at once) 30148 requestHeaders = {}, 30149 requestHeadersNames = {}, 30150 30151 // Default abort message 30152 strAbort = "canceled", 30153 30154 // Fake xhr 30155 jqXHR = { 30156 readyState: 0, 30157 30158 // Builds headers hashtable if needed 30159 getResponseHeader: function( key ) { 30160 var match; 30161 if ( completed ) { 30162 if ( !responseHeaders ) { 30163 responseHeaders = {}; 30164 while ( ( match = rheaders.exec( responseHeadersString ) ) ) { 30165 responseHeaders[ match[ 1 ].toLowerCase()
30165+ " " ] = 30166 ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) 30167 .concat( match[ 2 ] ); 30168 } 30169 } 30170 match = responseHeaders[ key.toLowerCase() + " " ]; 30171 } 30172 return match == null ? null : match.join( ", " )
vendor: 10,702 bytes, lines 30172-30561
30172; 30173 }, 30174 30175 // Raw string 30176 getAllResponseHeaders: function() { 30177 return completed ? responseHeadersString : null; 30178 }, 30179 30180 // Caches the header 30181 setRequestHeader: function( name, value ) { 30182 if ( completed == null ) { 30183 name = requestHeadersNames[ name.toLowerCase() ] = 30184 requestHeadersNames[ name.toLowerCase() ] || name; 30185 requestHeaders[ name ] = value; 30186 } 30187 return this; 30188 }, 30189 30190 // Overrides response content-type header 30191 overrideMimeType: function( type ) { 30192 if ( completed == null ) { 30193 s.mimeType = type; 30194 } 30195 return this; 30196 }, 30197 30198 // Status-dependent callbacks 30199 statusCode: function( map ) { 30200 var code; 30201 if ( map ) { 30202 if ( completed ) { 30203 30204 // Execute the appropriate callbacks 30205 jqXHR.always( map[ jqXHR.status ] ); 30206 } else { 30207 30208 // Lazy-add the new callbacks in a way that preserves old ones 30209 for ( code in map ) { 30210 statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; 30211 } 30212 } 30213 } 30214 return this; 30215 }, 30216 30217 // Cancel the request 30218 abort: function( statusText ) { 30219 var finalText = statusText || strAbort; 30220 if ( transport ) { 30221 transport.abort( finalText ); 30222 } 30223 done( 0, finalText ); 30224 return this; 30225 } 30226 }; 30227 30228 // Attach deferreds 30229 deferred.promise( jqXHR ); 30230 30231 // Add protocol if not provided (prefilters might expect it) 30232 // Handle falsy url in the settings object (#10093: consistency with old signature) 30233 // We also use the url parameter if available 30234 s.url = ( ( url || s.url || location.href ) + "" ) 30235 .replace( rprotocol, location.protocol + "//" ); 30236 30237 // Alias method option to type as per ticket #12004 30238 s.type = options.method || options.type || s.method || s.type; 30239 30240 // Extract dataTypes list 30241 s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; 30242 30243 // A cross-domain request is in order when the origin doesn't match the current origin. 30244 if ( s.crossDomain == null ) { 30245 urlAnchor = document.createElement( "a" ); 30246 30247 // Support: IE <=8 - 11, Edge 12 - 15 30248 // IE throws exception on accessing the href property if url is malformed, 30249 // e.g. http://example.com:80x/ 30250 try { 30251 urlAnchor.href = s.url; 30252 30253 // Support: IE <=8 - 11 only 30254 // Anchor's host property isn't correctly set when s.url is relative 30255 urlAnchor.href = urlAnchor.href; 30256 s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== 30257 urlAnchor.protocol + "//" + urlAnchor.host; 30258 } catch ( e ) { 30259 30260 // If there is an error parsing the URL, assume it is crossDomain, 30261 // it can be rejected by the transport if it is invalid 30262 s.crossDomain = true; 30263 } 30264 } 30265 30266 // Convert data if not already a string 30267 if ( s.data && s.processData && typeof s.data !== "string" ) { 30268 s.data = jQuery.param( s.data, s.traditional ); 30269 } 30270 30271 // Apply prefilters 30272 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); 30273 30274 // If request was aborted inside a prefilter, stop there 30275 if ( completed ) { 30276 return jqXHR; 30277 } 30278 30279 // We can fire global events as of now if asked to 30280 // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) 30281 fireGlobals = jQuery.event && s.global; 30282 30283 // Watch for a new set of requests 30284 if ( fireGlobals && jQuery.active++ === 0 ) { 30285 jQuery.event.trigger( "ajaxStart" ); 30286 } 30287 30288 // Uppercase the type 30289 s.type = s.type.toUpperCase(); 30290 30291 // Determine if request has content 30292 s.hasContent = !rnoContent.test( s.type ); 30293 30294 // Save the URL in case we're toying with the If-Modified-Since 30295 // and/or If-None-Match header later on 30296 // Remove hash to simplify url manipulation 30297 cacheURL = s.url.replace( rhash, "" ); 30298 30299 // More options handling for requests with no content 30300 if ( !s.hasContent ) { 30301 30302 // Remember the hash so we can put it back 30303 uncached = s.url.slice( cacheURL.length ); 30304 30305 // If data is available and should be processed, append data to url 30306 if ( s.data && ( s.processData || typeof s.data === "string" ) ) { 30307 cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; 30308 30309 // #9682: remove data so that it's not used in an eventual retry 30310 delete s.data; 30311 } 30312 30313 // Add or update anti-cache param if needed 30314 if ( s.cache === false ) { 30315 cacheURL = cacheURL.replace( rantiCache, "$1" ); 30316 uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached; 30317 } 30318 30319 // Put hash and anti-cache on the URL that will be requested (gh-1732) 30320 s.url = cacheURL + uncached; 30321 30322 // Change '%20' to '+' if this is encoded form body content (gh-2658) 30323 } else if ( s.data && s.processData && 30324 ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { 30325 s.data = s.data.replace( r20, "+" ); 30326 } 30327 30328 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 30329 if ( s.ifModified ) { 30330 if ( jQuery.lastModified[ cacheURL ] ) { 30331 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); 30332 } 30333 if ( jQuery.etag[ cacheURL ] ) { 30334 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); 30335 } 30336 } 30337 30338 // Set the correct header, if data is being sent 30339 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { 30340 jqXHR.setRequestHeader( "Content-Type", s.contentType ); 30341 } 30342 30343 // Set the Accepts header for the server, depending on the dataType 30344 jqXHR.setRequestHeader( 30345 "Accept", 30346 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? 30347 s.accepts[ s.dataTypes[ 0 ] ] + 30348 ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : 30349 s.accepts[ "*" ] 30350 ); 30351 30352 // Check for headers option 30353 for ( i in s.headers ) { 30354 jqXHR.setRequestHeader( i, s.headers[ i ] ); 30355 } 30356 30357 // Allow custom headers/mimetypes and early abort 30358 if ( s.beforeSend && 30359 ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { 30360 30361 // Abort if not done already and return 30362 return jqXHR.abort(); 30363 } 30364 30365 // Aborting is no longer a cancellation 30366 strAbort = "abort"; 30367 30368 // Install callbacks on deferreds 30369 completeDeferred.add( s.complete ); 30370 jqXHR.done( s.success ); 30371 jqXHR.fail( s.error ); 30372 30373 // Get transport 30374 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); 30375 30376 // If no transport, we auto-abort 30377 if ( !transport ) { 30378 done( -1, "No Transport" ); 30379 } else { 30380 jqXHR.readyState = 1; 30381 30382 // Send global event 30383 if ( fireGlobals ) { 30384 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); 30385 } 30386 30387 // If request was aborted inside ajaxSend, stop there 30388 if ( completed ) { 30389 return jqXHR; 30390 } 30391 30392 // Timeout 30393 if ( s.async && s.timeout > 0 ) { 30394 timeoutTimer = window.setTimeout( function() { 30395 jqXHR.abort( "timeout" ); 30396 }, s.timeout ); 30397 } 30398 30399 try { 30400 completed = false; 30401 transport.send( requestHeaders, done ); 30402 } catch ( e ) { 30403 30404 // Rethrow post-completion exceptions 30405 if ( completed ) { 30406 throw e; 30407 } 30408 30409 // Propagate others as results 30410 done( -1, e ); 30411 } 30412 } 30413 30414 // Callback for when everything is done 30415 function done( status, nativeStatusText, responses, headers ) { 30416 var isSuccess, success, error, response, modified, 30417 statusText = nativeStatusText; 30418 30419 // Ignore repeat invocations 30420 if ( completed ) { 30421 return; 30422 } 30423 30424 completed = true; 30425 30426 // Clear timeout if it exists 30427 if ( timeoutTimer ) { 30428 window.clearTimeout( timeoutTimer ); 30429 } 30430 30431 // Dereference transport for early garbage collection 30432 // (no matter how long the jqXHR object will be used) 30433 transport = undefined; 30434 30435 // Cache response headers 30436 responseHeadersString = headers || ""; 30437 30438 // Set readyState 30439 jqXHR.readyState = status > 0 ? 4 : 0; 30440 30441 // Determine if successful 30442 isSuccess = status >= 200 && status < 300 || status === 304; 30443 30444 // Get response data 30445 if ( responses ) { 30446 response = ajaxHandleResponses( s, jqXHR, responses ); 30447 } 30448 30449 // Convert no matter what (that way responseXXX fields are always set) 30450 response = ajaxConvert( s, response, jqXHR, isSuccess ); 30451 30452 // If successful, handle type chaining 30453 if ( isSuccess ) { 30454 30455 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 30456 if ( s.ifModified ) { 30457 modified = jqXHR.getResponseHeader( "Last-Modified" ); 30458 if ( modified ) { 30459 jQuery.lastModified[ cacheURL ] = modified; 30460 } 30461 modified = jqXHR.getResponseHeader( "etag" ); 30462 if ( modified ) { 30463 jQuery.etag[ cacheURL ] = modified; 30464 } 30465 } 30466 30467 // if no content 30468 if ( status === 204 || s.type === "HEAD" ) { 30469 statusText = "nocontent"; 30470 30471 // if not modified 30472 } else if ( status === 304 ) { 30473 statusText = "notmodified"; 30474 30475 // If we have data, let's convert it 30476 } else { 30477 statusText = response.state; 30478 success = response.data; 30479 error = response.error; 30480 isSuccess = !error; 30481 } 30482 } else { 30483 30484 // Extract error from statusText and normalize for non-aborts 30485 error = statusText; 30486 if ( status || !statusText ) { 30487 statusText = "error"; 30488 if ( status < 0 ) { 30489 status = 0; 30490 } 30491 } 30492 } 30493 30494 // Set data for the fake xhr object 30495 jqXHR.status = status; 30496 jqXHR.statusText = ( nativeStatusText || statusText ) + ""; 30497 30498 // Success/Error 30499 if ( isSuccess ) { 30500 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); 30501 } else { 30502 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); 30503 } 30504 30505 // Status-dependent callbacks 30506 jqXHR.statusCode( statusCode ); 30507 statusCode = undefined; 30508 30509 if ( fireGlobals ) { 30510 globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", 30511 [ jqXHR, s, isSuccess ? success : error ] ); 30512 } 30513 30514 // Complete 30515 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); 30516 30517 if ( fireGlobals ) { 30518 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); 30519 30520 // Handle the global AJAX counter 30521 if ( !( --jQuery.active ) ) { 30522 jQuery.event.trigger( "ajaxStop" ); 30523 } 30524 } 30525 } 30526 30527 return jqXHR; 30528 }, 30529 30530 getJSON: function( url, data, callback ) { 30531 return jQuery.get( url, data, callback, "json" ); 30532 }, 30533 30534 getScript: function( url, callback ) { 30535 return jQuery.get( url, undefined, callback, "script" ); 30536 } 30537} ); 30538 30539jQuery.each( [ "get", "post" ], function( i, method ) { 30540 jQuery[ method ] = function( url, data, callback, type ) { 30541 30542 // Shift arguments if data argument was omitted 30543 if ( isFunction( data ) ) { 30544 type = type || callback; 30545 callback = data; 30546 data = undefined; 30547 } 30548 30549 // The url can be an options object (which then must have .url) 30550 return jQuery.ajax( jQuery.extend( { 30551 url: url, 30552 type: method, 30553 dataType: type, 30554 data: data, 30555 success: callback 30556 }, jQuery.isPlainObject( url ) && url ) ); 30557 }; 30558} ); 30559 30560 30561jQuery._evalUrl = function( url
30561, options ) { 30562 return jQuery.ajax( { 30563 url: url, 30564 30565 // Make this explicit, since user can override this through ajaxSetup (#11264) 30566 type: "GET", 30567 dataType: "script", 30568 cache: true, 30569 async: false, 30570 global: false, 30571 30572 // Only evaluate the response if it is successful (gh-4126) 30573 // dataFilter is not invoked for failure responses, so using it instead 30574 // of the default converter is kludgy but it works. 30575 converters: { 30576 "text script": function() {} 30577 }, 30578 dataFilter: function( response ) { 30579 jQuery.globalEval( response, options
vendor: 11,651 bytes, lines 30579-31044
30579 ); 30580 } 30581 } ); 30582}; 30583 30584 30585jQuery.fn.extend( { 30586 wrapAll: function( html ) { 30587 var wrap; 30588 30589 if ( this[ 0 ] ) { 30590 if ( isFunction( html ) ) { 30591 html = html.call( this[ 0 ] ); 30592 } 30593 30594 // The elements to wrap the target around 30595 wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); 30596 30597 if ( this[ 0 ].parentNode ) { 30598 wrap.insertBefore( this[ 0 ] ); 30599 } 30600 30601 wrap.map( function() { 30602 var elem = this; 30603 30604 while ( elem.firstElementChild ) { 30605 elem = elem.firstElementChild; 30606 } 30607 30608 return elem; 30609 } ).append( this ); 30610 } 30611 30612 return this; 30613 }, 30614 30615 wrapInner: function( html ) { 30616 if ( isFunction( html ) ) { 30617 return this.each( function( i ) { 30618 jQuery( this ).wrapInner( html.call( this, i ) ); 30619 } ); 30620 } 30621 30622 return this.each( function() { 30623 var self = jQuery( this ), 30624 contents = self.contents(); 30625 30626 if ( contents.length ) { 30627 contents.wrapAll( html ); 30628 30629 } else { 30630 self.append( html ); 30631 } 30632 } ); 30633 }, 30634 30635 wrap: function( html ) { 30636 var htmlIsFunction = isFunction( html ); 30637 30638 return this.each( function( i ) { 30639 jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); 30640 } ); 30641 }, 30642 30643 unwrap: function( selector ) { 30644 this.parent( selector ).not( "body" ).each( function() { 30645 jQuery( this ).replaceWith( this.childNodes ); 30646 } ); 30647 return this; 30648 } 30649} ); 30650 30651 30652jQuery.expr.pseudos.hidden = function( elem ) { 30653 return !jQuery.expr.pseudos.visible( elem ); 30654}; 30655jQuery.expr.pseudos.visible = function( elem ) { 30656 return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); 30657}; 30658 30659 30660 30661 30662jQuery.ajaxSettings.xhr = function() { 30663 try { 30664 return new window.XMLHttpRequest(); 30665 } catch ( e ) {} 30666}; 30667 30668var xhrSuccessStatus = { 30669 30670 // File protocol always yields status code 0, assume 200 30671 0: 200, 30672 30673 // Support: IE <=9 only 30674 // #1450: sometimes IE returns 1223 when it should be 204 30675 1223: 204 30676 }, 30677 xhrSupported = jQuery.ajaxSettings.xhr(); 30678 30679support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); 30680support.ajax = xhrSupported = !!xhrSupported; 30681 30682jQuery.ajaxTransport( function( options ) { 30683 var callback, errorCallback; 30684 30685 // Cross domain only allowed if supported through XMLHttpRequest 30686 if ( support.cors || xhrSupported && !options.crossDomain ) { 30687 return { 30688 send: function( headers, complete ) { 30689 var i, 30690 xhr = options.xhr(); 30691 30692 xhr.open( 30693 options.type, 30694 options.url, 30695 options.async, 30696 options.username, 30697 options.password 30698 ); 30699 30700 // Apply custom fields if provided 30701 if ( options.xhrFields ) { 30702 for ( i in options.xhrFields ) { 30703 xhr[ i ] = options.xhrFields[ i ]; 30704 } 30705 } 30706 30707 // Override mime type if needed 30708 if ( options.mimeType && xhr.overrideMimeType ) { 30709 xhr.overrideMimeType( options.mimeType ); 30710 } 30711 30712 // X-Requested-With header 30713 // For cross-domain requests, seeing as conditions for a preflight are 30714 // akin to a jigsaw puzzle, we simply never set it to be sure. 30715 // (it can always be set on a per-request basis or even using ajaxSetup) 30716 // For same-domain requests, won't change header if already provided. 30717 if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { 30718 headers[ "X-Requested-With" ] = "XMLHttpRequest"; 30719 } 30720 30721 // Set headers 30722 for ( i in headers ) { 30723 xhr.setRequestHeader( i, headers[ i ] ); 30724 } 30725 30726 // Callback 30727 callback = function( type ) { 30728 return function() { 30729 if ( callback ) { 30730 callback = errorCallback = xhr.onload = 30731 xhr.onerror = xhr.onabort = xhr.ontimeout = 30732 xhr.onreadystatechange = null; 30733 30734 if ( type === "abort" ) { 30735 xhr.abort(); 30736 } else if ( type === "error" ) { 30737 30738 // Support: IE <=9 only 30739 // On a manual native abort, IE9 throws 30740 // errors on any property access that is not readyState 30741 if ( typeof xhr.status !== "number" ) { 30742 complete( 0, "error" ); 30743 } else { 30744 complete( 30745 30746 // File: protocol always yields status 0; see #8605, #14207 30747 xhr.status, 30748 xhr.statusText 30749 ); 30750 } 30751 } else { 30752 complete( 30753 xhrSuccessStatus[ xhr.status ] || xhr.status, 30754 xhr.statusText, 30755 30756 // Support: IE <=9 only 30757 // IE9 has no XHR2 but throws on binary (trac-11426) 30758 // For XHR2 non-text, let the caller handle it (gh-2498) 30759 ( xhr.responseType || "text" ) !== "text" || 30760 typeof xhr.responseText !== "string" ? 30761 { binary: xhr.response } : 30762 { text: xhr.responseText }, 30763 xhr.getAllResponseHeaders() 30764 ); 30765 } 30766 } 30767 }; 30768 }; 30769 30770 // Listen to events 30771 xhr.onload = callback(); 30772 errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); 30773 30774 // Support: IE 9 only 30775 // Use onreadystatechange to replace onabort 30776 // to handle uncaught aborts 30777 if ( xhr.onabort !== undefined ) { 30778 xhr.onabort = errorCallback; 30779 } else { 30780 xhr.onreadystatechange = function() { 30781 30782 // Check readyState before timeout as it changes 30783 if ( xhr.readyState === 4 ) { 30784 30785 // Allow onerror to be called first, 30786 // but that will not handle a native abort 30787 // Also, save errorCallback to a variable 30788 // as xhr.onerror cannot be accessed 30789 window.setTimeout( function() { 30790 if ( callback ) { 30791 errorCallback(); 30792 } 30793 } ); 30794 } 30795 }; 30796 } 30797 30798 // Create the abort callback 30799 callback = callback( "abort" ); 30800 30801 try { 30802 30803 // Do send the request (this may raise an exception) 30804 xhr.send( options.hasContent && options.data || null ); 30805 } catch ( e ) { 30806 30807 // #14683: Only rethrow if this hasn't been notified as an error yet 30808 if ( callback ) { 30809 throw e; 30810 } 30811 } 30812 }, 30813 30814 abort: function() { 30815 if ( callback ) { 30816 callback(); 30817 } 30818 } 30819 }; 30820 } 30821} ); 30822 30823 30824 30825 30826// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) 30827jQuery.ajaxPrefilter( function( s ) { 30828 if ( s.crossDomain ) { 30829 s.contents.script = false; 30830 } 30831} ); 30832 30833// Install script dataType 30834jQuery.ajaxSetup( { 30835 accepts: { 30836 script: "text/javascript, application/javascript, " + 30837 "application/ecmascript, application/x-ecmascript" 30838 }, 30839 contents: { 30840 script: /\b(?:java|ecma)script\b/ 30841 }, 30842 converters: { 30843 "text script": function( text ) { 30844 jQuery.globalEval( text ); 30845 return text; 30846 } 30847 } 30848} ); 30849 30850// Handle cache's special case and crossDomain 30851jQuery.ajaxPrefilter( "script", function( s ) { 30852 if ( s.cache === undefined ) { 30853 s.cache = false; 30854 } 30855 if ( s.crossDomain ) { 30856 s.type = "GET"; 30857 } 30858} ); 30859 30860// Bind script tag hack transport 30861jQuery.ajaxTransport( "script", function( s ) { 30862 30863 // This transport only deals with cross domain or forced-by-attrs requests 30864 if ( s.crossDomain || s.scriptAttrs ) { 30865 var script, callback; 30866 return { 30867 send: function( _, complete ) { 30868 script = jQuery( "<script>" ) 30869 .attr( s.scriptAttrs || {} ) 30870 .prop( { charset: s.scriptCharset, src: s.url } ) 30871 .on( "load error", callback = function( evt ) { 30872 script.remove(); 30873 callback = null; 30874 if ( evt ) { 30875 complete( evt.type === "error" ? 404 : 200, evt.type ); 30876 } 30877 } ); 30878 30879 // Use native DOM manipulation to avoid our domManip AJAX trickery 30880 document.head.appendChild( script[ 0 ] ); 30881 }, 30882 abort: function() { 30883 if ( callback ) { 30884 callback(); 30885 } 30886 } 30887 }; 30888 } 30889} ); 30890 30891 30892 30893 30894var oldCallbacks = [], 30895 rjsonp = /(=)\?(?=&|$)|\?\?/; 30896 30897// Default jsonp settings 30898jQuery.ajaxSetup( { 30899 jsonp: "callback", 30900 jsonpCallback: function() { 30901 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); 30902 this[ callback ] = true; 30903 return callback; 30904 } 30905} ); 30906 30907// Detect, normalize options and install callbacks for jsonp requests 30908jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { 30909 30910 var callbackName, overwritten, responseContainer, 30911 jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? 30912 "url" : 30913 typeof s.data === "string" && 30914 ( s.contentType || "" ) 30915 .indexOf( "application/x-www-form-urlencoded" ) === 0 && 30916 rjsonp.test( s.data ) && "data" 30917 ); 30918 30919 // Handle iff the expected data type is "jsonp" or we have a parameter to set 30920 if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { 30921 30922 // Get callback name, remembering preexisting value associated with it 30923 callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ? 30924 s.jsonpCallback() : 30925 s.jsonpCallback; 30926 30927 // Insert callback into url or form data 30928 if ( jsonProp ) { 30929 s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); 30930 } else if ( s.jsonp !== false ) { 30931 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; 30932 } 30933 30934 // Use data converter to retrieve json after script execution 30935 s.converters[ "script json" ] = function() { 30936 if ( !responseContainer ) { 30937 jQuery.error( callbackName + " was not called" ); 30938 } 30939 return responseContainer[ 0 ]; 30940 }; 30941 30942 // Force json dataType 30943 s.dataTypes[ 0 ] = "json"; 30944 30945 // Install callback 30946 overwritten = window[ callbackName ]; 30947 window[ callbackName ] = function() { 30948 responseContainer = arguments; 30949 }; 30950 30951 // Clean-up function (fires after converters) 30952 jqXHR.always( function() { 30953 30954 // If previous value didn't exist - remove it 30955 if ( overwritten === undefined ) { 30956 jQuery( window ).removeProp( callbackName ); 30957 30958 // Otherwise restore preexisting value 30959 } else { 30960 window[ callbackName ] = overwritten; 30961 } 30962 30963 // Save back as free 30964 if ( s[ callbackName ] ) { 30965 30966 // Make sure that re-using the options doesn't screw things around 30967 s.jsonpCallback = originalSettings.jsonpCallback; 30968 30969 // Save the callback name for future use 30970 oldCallbacks.push( callbackName ); 30971 } 30972 30973 // Call if it was a function and we have a response 30974 if ( responseContainer && isFunction( overwritten ) ) { 30975 overwritten( responseContainer[ 0 ] ); 30976 } 30977 30978 responseContainer = overwritten = undefined; 30979 } ); 30980 30981 // Delegate to script 30982 return "script"; 30983 } 30984} ); 30985 30986 30987 30988 30989// Support: Safari 8 only 30990// In Safari 8 documents created via document.implementation.createHTMLDocument 30991// collapse sibling forms: the second one becomes a child of the first one. 30992// Because of that, this security measure has to be disabled in Safari 8. 30993// https://bugs.webkit.org/show_bug.cgi?id=137337 30994support.createHTMLDocument = ( function() { 30995 var body = document.implementation.createHTMLDocument( "" ).body; 30996 body.innerHTML = "<form></form><form></form>"; 30997 return body.childNodes.length === 2; 30998} )(); 30999 31000 31001// Argument "data" should be string of html 31002// context (optional): If specified, the fragment will be created in this context, 31003// defaults to document 31004// keepScripts (optional): If true, will include scripts passed in the html string 31005jQuery.parseHTML = function( data, context, keepScripts ) { 31006 if ( typeof data !== "string" ) { 31007 return []; 31008 } 31009 if ( typeof context === "boolean" ) { 31010 keepScripts = context; 31011 context = false; 31012 } 31013 31014 var base, parsed, scripts; 31015 31016 if ( !context ) { 31017 31018 // Stop scripts or inline event handlers from being executed immediately 31019 // by using document.implementation 31020 if ( support.createHTMLDocument ) { 31021 context = document.implementation.createHTMLDocument( "" ); 31022 31023 // Set the base href for the created document 31024 // so any parsed elements with URLs 31025 // are based on the document's URL (gh-2965) 31026 base = context.createElement( "base" ); 31027 base.href = document.location.href; 31028 context.head.appendChild( base ); 31029 } else { 31030 context = document; 31031 } 31032 } 31033 31034 parsed = rsingleTag.exec( data ); 31035 scripts = !keepScripts && []; 31036 31037 // Single tag 31038 if ( parsed ) { 31039 return [ context.createElement( parsed[ 1 ] ) ]; 31040 } 31041 31042 parsed = buildFragment( [ data ], context, scripts ); 31043 31044 if ( scripts && scripts.length ) {
vendor: 14,511 bytes, lines 31045-31565
31045 jQuery( scripts ).remove(); 31046 } 31047 31048 return jQuery.merge( [], parsed.childNodes ); 31049}; 31050 31051 31052/** 31053 * Load a url into a page 31054 */ 31055jQuery.fn.load = function( url, params, callback ) { 31056 var selector, type, response, 31057 self = this, 31058 off = url.indexOf( " " ); 31059 31060 if ( off > -1 ) { 31061 selector = stripAndCollapse( url.slice( off ) ); 31062 url = url.slice( 0, off ); 31063 } 31064 31065 // If it's a function 31066 if ( isFunction( params ) ) { 31067 31068 // We assume that it's the callback 31069 callback = params; 31070 params = undefined; 31071 31072 // Otherwise, build a param string 31073 } else if ( params && typeof params === "object" ) { 31074 type = "POST"; 31075 } 31076 31077 // If we have elements to modify, make the request 31078 if ( self.length > 0 ) { 31079 jQuery.ajax( { 31080 url: url, 31081 31082 // If "type" variable is undefined, then "GET" method will be used. 31083 // Make value of this field explicit since 31084 // user can override it through ajaxSetup method 31085 type: type || "GET", 31086 dataType: "html", 31087 data: params 31088 } ).done( function( responseText ) { 31089 31090 // Save response for use in complete callback 31091 response = arguments; 31092 31093 self.html( selector ? 31094 31095 // If a selector was specified, locate the right elements in a dummy div 31096 // Exclude scripts to avoid IE 'Permission Denied' errors 31097 jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) : 31098 31099 // Otherwise use the full result 31100 responseText ); 31101 31102 // If the request succeeds, this function gets "data", "status", "jqXHR" 31103 // but they are ignored because response was set above. 31104 // If it fails, this function gets "jqXHR", "status", "error" 31105 } ).always( callback && function( jqXHR, status ) { 31106 self.each( function() { 31107 callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] ); 31108 } ); 31109 } ); 31110 } 31111 31112 return this; 31113}; 31114 31115 31116 31117 31118// Attach a bunch of functions for handling common AJAX events 31119jQuery.each( [ 31120 "ajaxStart", 31121 "ajaxStop", 31122 "ajaxComplete", 31123 "ajaxError", 31124 "ajaxSuccess", 31125 "ajaxSend" 31126], function( i, type ) { 31127 jQuery.fn[ type ] = function( fn ) { 31128 return this.on( type, fn ); 31129 }; 31130} ); 31131 31132 31133 31134 31135jQuery.expr.pseudos.animated = function( elem ) { 31136 return jQuery.grep( jQuery.timers, function( fn ) { 31137 return elem === fn.elem; 31138 } ).length; 31139}; 31140 31141 31142 31143 31144jQuery.offset = { 31145 setOffset: function( elem, options, i ) { 31146 var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, 31147 position = jQuery.css( elem, "position" ), 31148 curElem = jQuery( elem ), 31149 props = {}; 31150 31151 // Set position first, in-case top/left are set even on static elem 31152 if ( position === "static" ) { 31153 elem.style.position = "relative"; 31154 } 31155 31156 curOffset = curElem.offset(); 31157 curCSSTop = jQuery.css( elem, "top" ); 31158 curCSSLeft = jQuery.css( elem, "left" ); 31159 calculatePosition = ( position === "absolute" || position === "fixed" ) && 31160 ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1; 31161 31162 // Need to be able to calculate position if either 31163 // top or left is auto and position is either absolute or fixed 31164 if ( calculatePosition ) { 31165 curPosition = curElem.position(); 31166 curTop = curPosition.top; 31167 curLeft = curPosition.left; 31168 31169 } else { 31170 curTop = parseFloat( curCSSTop ) || 0; 31171 curLeft = parseFloat( curCSSLeft ) || 0; 31172 } 31173 31174 if ( isFunction( options ) ) { 31175 31176 // Use jQuery.extend here to allow modification of coordinates argument (gh-1848) 31177 options = options.call( elem, i, jQuery.extend( {}, curOffset ) ); 31178 } 31179 31180 if ( options.top != null ) { 31181 props.top = ( options.top - curOffset.top ) + curTop; 31182 } 31183 if ( options.left != null ) { 31184 props.left = ( options.left - curOffset.left ) + curLeft; 31185 } 31186 31187 if ( "using" in options ) { 31188 options.using.call( elem, props ); 31189 31190 } else { 31191 curElem.css( props ); 31192 } 31193 } 31194}; 31195 31196jQuery.fn.extend( { 31197 31198 // offset() relates an element's border box to the document origin 31199 offset: function( options ) { 31200 31201 // Preserve chaining for setter 31202 if ( arguments.length ) { 31203 return options === undefined ? 31204 this : 31205 this.each( function( i ) { 31206 jQuery.offset.setOffset( this, options, i ); 31207 } ); 31208 } 31209 31210 var rect, win, 31211 elem = this[ 0 ]; 31212 31213 if ( !elem ) { 31214 return; 31215 } 31216 31217 // Return zeros for disconnected and hidden (display: none) elements (gh-2310) 31218 // Support: IE <=11 only 31219 // Running getBoundingClientRect on a 31220 // disconnected node in IE throws an error 31221 if ( !elem.getClientRects().length ) { 31222 return { top: 0, left: 0 }; 31223 } 31224 31225 // Get document-relative position by adding viewport scroll to viewport-relative gBCR 31226 rect = elem.getBoundingClientRect(); 31227 win = elem.ownerDocument.defaultView; 31228 return { 31229 top: rect.top + win.pageYOffset, 31230 left: rect.left + win.pageXOffset 31231 }; 31232 }, 31233 31234 // position() relates an element's margin box to its offset parent's padding box 31235 // This corresponds to the behavior of CSS absolute positioning 31236 position: function() { 31237 if ( !this[ 0 ] ) { 31238 return; 31239 } 31240 31241 var offsetParent, offset, doc, 31242 elem = this[ 0 ], 31243 parentOffset = { top: 0, left: 0 }; 31244 31245 // position:fixed elements are offset from the viewport, which itself always has zero offset 31246 if ( jQuery.css( elem, "position" ) === "fixed" ) { 31247 31248 // Assume position:fixed implies availability of getBoundingClientRect 31249 offset = elem.getBoundingClientRect(); 31250 31251 } else { 31252 offset = this.offset(); 31253 31254 // Account for the *real* offset parent, which can be the document or its root element 31255 // when a statically positioned element is identified 31256 doc = elem.ownerDocument; 31257 offsetParent = elem.offsetParent || doc.documentElement; 31258 while ( offsetParent && 31259 ( offsetParent === doc.body || offsetParent === doc.documentElement ) && 31260 jQuery.css( offsetParent, "position" ) === "static" ) { 31261 31262 offsetParent = offsetParent.parentNode; 31263 } 31264 if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) { 31265 31266 // Incorporate borders into its offset, since they are outside its content origin 31267 parentOffset = jQuery( offsetParent ).offset(); 31268 parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true ); 31269 parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true ); 31270 } 31271 } 31272 31273 // Subtract parent offsets and element margins 31274 return { 31275 top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), 31276 left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true ) 31277 }; 31278 }, 31279 31280 // This method will return documentElement in the following cases: 31281 // 1) For the element inside the iframe without offsetParent, this method will return 31282 // documentElement of the parent window 31283 // 2) For the hidden or detached element 31284 // 3) For body or html element, i.e. in case of the html node - it will return itself 31285 // 31286 // but those exceptions were never presented as a real life use-cases 31287 // and might be considered as more preferable results. 31288 // 31289 // This logic, however, is not guaranteed and can change at any point in the future 31290 offsetParent: function() { 31291 return this.map( function() { 31292 var offsetParent = this.offsetParent; 31293 31294 while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) { 31295 offsetParent = offsetParent.offsetParent; 31296 } 31297 31298 return offsetParent || documentElement; 31299 } ); 31300 } 31301} ); 31302 31303// Create scrollLeft and scrollTop methods 31304jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) { 31305 var top = "pageYOffset" === prop; 31306 31307 jQuery.fn[ method ] = function( val ) { 31308 return access( this, function( elem, method, val ) { 31309 31310 // Coalesce documents and windows 31311 var win; 31312 if ( isWindow( elem ) ) { 31313 win = elem; 31314 } else if ( elem.nodeType === 9 ) { 31315 win = elem.defaultView; 31316 } 31317 31318 if ( val === undefined ) { 31319 return win ? win[ prop ] : elem[ method ]; 31320 } 31321 31322 if ( win ) { 31323 win.scrollTo( 31324 !top ? val : win.pageXOffset, 31325 top ? val : win.pageYOffset 31326 ); 31327 31328 } else { 31329 elem[ method ] = val; 31330 } 31331 }, method, val, arguments.length ); 31332 }; 31333} ); 31334 31335// Support: Safari <=7 - 9.1, Chrome <=37 - 49 31336// Add the top/left cssHooks using jQuery.fn.position 31337// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 31338// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347 31339// getComputedStyle returns percent when specified for top/left/bottom/right; 31340// rather than make the css module depend on the offset module, just check for it here 31341jQuery.each( [ "top", "left" ], function( i, prop ) { 31342 jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, 31343 function( elem, computed ) { 31344 if ( computed ) { 31345 computed = curCSS( elem, prop ); 31346 31347 // If curCSS returns percentage, fallback to offset 31348 return rnumnonpx.test( computed ) ? 31349 jQuery( elem ).position()[ prop ] + "px" : 31350 computed; 31351 } 31352 } 31353 ); 31354} ); 31355 31356 31357// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods 31358jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { 31359 jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, 31360 function( defaultExtra, funcName ) { 31361 31362 // Margin is only for outerHeight, outerWidth 31363 jQuery.fn[ funcName ] = function( margin, value ) { 31364 var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), 31365 extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); 31366 31367 return access( this, function( elem, type, value ) { 31368 var doc; 31369 31370 if ( isWindow( elem ) ) { 31371 31372 // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729) 31373 return funcName.indexOf( "outer" ) === 0 ? 31374 elem[ "inner" + name ] : 31375 elem.document.documentElement[ "client" + name ]; 31376 } 31377 31378 // Get document width or height 31379 if ( elem.nodeType === 9 ) { 31380 doc = elem.documentElement; 31381 31382 // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], 31383 // whichever is greatest 31384 return Math.max( 31385 elem.body[ "scroll" + name ], doc[ "scroll" + name ], 31386 elem.body[ "offset" + name ], doc[ "offset" + name ], 31387 doc[ "client" + name ] 31388 ); 31389 } 31390 31391 return value === undefined ? 31392 31393 // Get width or height on the element, requesting but not forcing parseFloat 31394 jQuery.css( elem, type, extra ) : 31395 31396 // Set width or height on the element 31397 jQuery.style( elem, type, value, extra ); 31398 }, type, chainable ? margin : undefined, chainable ); 31399 }; 31400 } ); 31401} ); 31402 31403 31404jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " + 31405 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + 31406 "change select submit keydown keypress keyup contextmenu" ).split( " " ), 31407 function( i, name ) { 31408 31409 // Handle event binding 31410 jQuery.fn[ name ] = function( data, fn ) { 31411 return arguments.length > 0 ? 31412 this.on( name, null, data, fn ) : 31413 this.trigger( name ); 31414 }; 31415} ); 31416 31417jQuery.fn.extend( { 31418 hover: function( fnOver, fnOut ) { 31419 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); 31420 } 31421} ); 31422 31423 31424 31425 31426jQuery.fn.extend( { 31427 31428 bind: function( types, data, fn ) { 31429 return this.on( types, null, data, fn ); 31430 }, 31431 unbind: function( types, fn ) { 31432 return this.off( types, null, fn ); 31433 }, 31434 31435 delegate: function( selector, types, data, fn ) { 31436 return this.on( types, selector, data, fn ); 31437 }, 31438 undelegate: function( selector, types, fn ) { 31439 31440 // ( namespace ) or ( selector, types [, fn] ) 31441 return arguments.length === 1 ? 31442 this.off( selector, "**" ) : 31443 this.off( types, selector || "**", fn ); 31444 } 31445} ); 31446 31447// Bind a function to a context, optionally partially applying any 31448// arguments. 31449// jQuery.proxy is deprecated to promote standards (specifically Function#bind) 31450// However, it is not slated for removal any time soon 31451jQuery.proxy = function( fn, context ) { 31452 var tmp, args, proxy; 31453 31454 if ( typeof context === "string" ) { 31455 tmp = fn[ context ]; 31456 context = fn; 31457 fn = tmp; 31458 } 31459 31460 // Quick check to determine if target is callable, in the spec 31461 // this throws a TypeError, but we will just return undefined. 31462 if ( !isFunction( fn ) ) { 31463 return undefined; 31464 } 31465 31466 // Simulated bind 31467 args = slice.call( arguments, 2 ); 31468 proxy = function() { 31469 return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); 31470 }; 31471 31472 // Set the guid of unique handler to the same of original handler, so it can be removed 31473 proxy.guid = fn.guid = fn.guid || jQuery.guid++; 31474 31475 return proxy; 31476}; 31477 31478jQuery.holdReady = function( hold ) { 31479 if ( hold ) { 31480 jQuery.readyWait++; 31481 } else { 31482 jQuery.ready( true ); 31483 } 31484}; 31485jQuery.isArray = Array.isArray; 31486jQuery.parseJSON = JSON.parse; 31487jQuery.nodeName = nodeName; 31488jQuery.isFunction = isFunction; 31489jQuery.isWindow = isWindow; 31490jQuery.camelCase = camelCase; 31491jQuery.type = toType; 31492 31493jQuery.now = Date.now; 31494 31495jQuery.isNumeric = function( obj ) { 31496 31497 // As of jQuery 3.0, isNumeric is limited to 31498 // strings and numbers (primitives or objects) 31499 // that can be coerced to finite numbers (gh-2662) 31500 var type = jQuery.type( obj ); 31501 return ( type === "number" || type === "string" ) && 31502 31503 // parseFloat NaNs numeric-cast false positives ("") 31504 // ...but misinterprets leading-number strings, particularly hex literals ("0x...") 31505 // subtraction forces infinities to NaN 31506 !isNaN( obj - parseFloat( obj ) ); 31507}; 31508 31509 31510 31511 31512// Register as a named AMD module, since jQuery can be concatenated with other 31513// files that may use define, but not via a proper concatenation script that 31514// understands anonymous AMD modules. A named AMD is safest and most robust 31515// way to register. Lowercase jquery is used because AMD module names are 31516// derived from file names, and jQuery is normally delivered in a lowercase 31517// file name. Do this after creating the global so that if an AMD module wants 31518// to call noConflict to hide this version of jQuery, it will work. 31519 31520// Note that for maximum portability, libraries that are not jQuery should 31521// declare themselves as anonymous modules, and avoid setting a global if an 31522// AMD loader is present. jQuery is a special case. For more information, see 31523// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon 31524 31525if ( typeof define === "function" && define.amd ) { 31526 define( "jquery", [], function() { 31527 return jQuery; 31528 } ); 31529} 31530 31531 31532 31533 31534var 31535 31536 // Map over jQuery in case of overwrite 31537 _jQuery = window.jQuery, 31538 31539 // Map over the $ in case of overwrite 31540 _$ = window.$; 31541 31542jQuery.noConflict = function( deep ) { 31543 if ( window.$ === jQuery ) { 31544 window.$ = _$; 31545 } 31546 31547 if ( deep && window.jQuery === jQuery ) { 31548 window.jQuery = _jQuery; 31549 } 31550 31551 return jQuery; 31552}; 31553 31554// Expose jQuery and $ identifiers, even in AMD 31555// (#7102#comment:10, https://github.com/jquery/jquery/pull/557) 31556// and CommonJS for browser emulators (#13566) 31557if ( !noGlobal ) { 31558 window.jQuery = window.$ = jQuery; 31559} 31560 31561 31562 31563 31564return jQuery; 31565} );
31566 31567},{}],14:[function(require,module,exports){ 31568//! moment.js 31569 31570;(function (global, factory) { 31571 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 31572 typeof define === 'function' && define.amd ? define(factory) : 31573 global.moment = factory()
vendor: 56,293 bytes, lines 31573-33333
31573 31574}(this, (function () { 'use strict'; 31575 31576 var hookCallback; 31577 31578 function hooks () { 31579 return hookCallback.apply(null, arguments); 31580 } 31581 31582 // This is done to register the method called with moment() 31583 // without creating circular dependencies. 31584 function setHookCallback (callback) { 31585 hookCallback = callback; 31586 } 31587 31588 function isArray(input) { 31589 return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]'; 31590 } 31591 31592 function isObject(input) { 31593 // IE8 will treat undefined and null as object if it wasn't for 31594 // input != null 31595 return input != null && Object.prototype.toString.call(input) === '[object Object]'; 31596 } 31597 31598 function isObjectEmpty(obj) { 31599 if (Object.getOwnPropertyNames) { 31600 return (Object.getOwnPropertyNames(obj).length === 0); 31601 } else { 31602 var k; 31603 for (k in obj) { 31604 if (obj.hasOwnProperty(k)) { 31605 return false; 31606 } 31607 } 31608 return true; 31609 } 31610 } 31611 31612 function isUndefined(input) { 31613 return input === void 0; 31614 } 31615 31616 function isNumber(input) { 31617 return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]'; 31618 } 31619 31620 function isDate(input) { 31621 return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]'; 31622 } 31623 31624 function map(arr, fn) { 31625 var res = [], i; 31626 for (i = 0; i < arr.length; ++i) { 31627 res.push(fn(arr[i], i)); 31628 } 31629 return res; 31630 } 31631 31632 function hasOwnProp(a, b) { 31633 return Object.prototype.hasOwnProperty.call(a, b); 31634 } 31635 31636 function extend(a, b) { 31637 for (var i in b) { 31638 if (hasOwnProp(b, i)) { 31639 a[i] = b[i]; 31640 } 31641 } 31642 31643 if (hasOwnProp(b, 'toString')) { 31644 a.toString = b.toString; 31645 } 31646 31647 if (hasOwnProp(b, 'valueOf')) { 31648 a.valueOf = b.valueOf; 31649 } 31650 31651 return a; 31652 } 31653 31654 function createUTC (input, format, locale, strict) { 31655 return createLocalOrUTC(input, format, locale, strict, true).utc(); 31656 } 31657 31658 function defaultParsingFlags() { 31659 // We need to deep clone this object. 31660 return { 31661 empty : false, 31662 unusedTokens : [], 31663 unusedInput : [], 31664 overflow : -2, 31665 charsLeftOver : 0, 31666 nullInput : false, 31667 invalidMonth : null, 31668 invalidFormat : false, 31669 userInvalidated : false, 31670 iso : false, 31671 parsedDateParts : [], 31672 meridiem : null, 31673 rfc2822 : false, 31674 weekdayMismatch : false 31675 }; 31676 } 31677 31678 function getParsingFlags(m) { 31679 if (m._pf == null) { 31680 m._pf = defaultParsingFlags(); 31681 } 31682 return m._pf; 31683 } 31684 31685 var some; 31686 if (Array.prototype.some) { 31687 some = Array.prototype.some; 31688 } else { 31689 some = function (fun) { 31690 var t = Object(this); 31691 var len = t.length >>> 0; 31692 31693 for (var i = 0; i < len; i++) { 31694 if (i in t && fun.call(this, t[i], i, t)) { 31695 return true; 31696 } 31697 } 31698 31699 return false; 31700 }; 31701 } 31702 31703 function isValid(m) { 31704 if (m._isValid == null) { 31705 var flags = getParsingFlags(m); 31706 var parsedParts = some.call(flags.parsedDateParts, function (i) { 31707 return i != null; 31708 }); 31709 var isNowValid = !isNaN(m._d.getTime()) && 31710 flags.overflow < 0 && 31711 !flags.empty && 31712 !flags.invalidMonth && 31713 !flags.invalidWeekday && 31714 !flags.weekdayMismatch && 31715 !flags.nullInput && 31716 !flags.invalidFormat && 31717 !flags.userInvalidated && 31718 (!flags.meridiem || (flags.meridiem && parsedParts)); 31719 31720 if (m._strict) { 31721 isNowValid = isNowValid && 31722 flags.charsLeftOver === 0 && 31723 flags.unusedTokens.length === 0 && 31724 flags.bigHour === undefined; 31725 } 31726 31727 if (Object.isFrozen == null || !Object.isFrozen(m)) { 31728 m._isValid = isNowValid; 31729 } 31730 else { 31731 return isNowValid; 31732 } 31733 } 31734 return m._isValid; 31735 } 31736 31737 function createInvalid (flags) { 31738 var m = createUTC(NaN); 31739 if (flags != null) { 31740 extend(getParsingFlags(m), flags); 31741 } 31742 else { 31743 getParsingFlags(m).userInvalidated = true; 31744 } 31745 31746 return m; 31747 } 31748 31749 // Plugins that add properties should also add the key here (null value), 31750 // so we can properly clone ourselves. 31751 var momentProperties = hooks.momentProperties = []; 31752 31753 function copyConfig(to, from) { 31754 var i, prop, val; 31755 31756 if (!isUndefined(from._isAMomentObject)) { 31757 to._isAMomentObject = from._isAMomentObject; 31758 } 31759 if (!isUndefined(from._i)) { 31760 to._i = from._i; 31761 } 31762 if (!isUndefined(from._f)) { 31763 to._f = from._f; 31764 } 31765 if (!isUndefined(from._l)) { 31766 to._l = from._l; 31767 } 31768 if (!isUndefined(from._strict)) { 31769 to._strict = from._strict; 31770 } 31771 if (!isUndefined(from._tzm)) { 31772 to._tzm = from._tzm; 31773 } 31774 if (!isUndefined(from._isUTC)) { 31775 to._isUTC = from._isUTC; 31776 } 31777 if (!isUndefined(from._offset)) { 31778 to._offset = from._offset; 31779 } 31780 if (!isUndefined(from._pf)) { 31781 to._pf = getParsingFlags(from); 31782 } 31783 if (!isUndefined(from._locale)) { 31784 to._locale = from._locale; 31785 } 31786 31787 if (momentProperties.length > 0) { 31788 for (i = 0; i < momentProperties.length; i++) { 31789 prop = momentProperties[i]; 31790 val = from[prop]; 31791 if (!isUndefined(val)) { 31792 to[prop] = val; 31793 } 31794 } 31795 } 31796 31797 return to; 31798 } 31799 31800 var updateInProgress = false; 31801 31802 // Moment prototype object 31803 function Moment(config) { 31804 copyConfig(this, config); 31805 this._d = new Date(config._d != null ? config._d.getTime() : NaN); 31806 if (!this.isValid()) { 31807 this._d = new Date(NaN); 31808 } 31809 // Prevent infinite loop in case updateOffset creates new moment 31810 // objects. 31811 if (updateInProgress === false) { 31812 updateInProgress = true; 31813 hooks.updateOffset(this); 31814 updateInProgress = false; 31815 } 31816 } 31817 31818 function isMoment (obj) { 31819 return obj instanceof Moment || (obj != null && obj._isAMomentObject != null); 31820 } 31821 31822 function absFloor (number) { 31823 if (number < 0) { 31824 // -0 -> 0 31825 return Math.ceil(number) || 0; 31826 } else { 31827 return Math.floor(number); 31828 } 31829 } 31830 31831 function toInt(argumentForCoercion) { 31832 var coercedNumber = +argumentForCoercion, 31833 value = 0; 31834 31835 if (coercedNumber !== 0 && isFinite(coercedNumber)) { 31836 value = absFloor(coercedNumber); 31837 } 31838 31839 return value; 31840 } 31841 31842 // compare two arrays, return the number of differences 31843 function compareArrays(array1, array2, dontConvert) { 31844 var len = Math.min(array1.length, array2.length), 31845 lengthDiff = Math.abs(array1.length - array2.length), 31846 diffs = 0, 31847 i; 31848 for (i = 0; i < len; i++) { 31849 if ((dontConvert && array1[i] !== array2[i]) || 31850 (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) { 31851 diffs++; 31852 } 31853 } 31854 return diffs + lengthDiff; 31855 } 31856 31857 function warn(msg) { 31858 if (hooks.suppressDeprecationWarnings === false && 31859 (typeof console !== 'undefined') && console.warn) { 31860 console.warn('Deprecation warning: ' + msg); 31861 } 31862 } 31863 31864 function deprecate(msg, fn) { 31865 var firstTime = true; 31866 31867 return extend(function () { 31868 if (hooks.deprecationHandler != null) { 31869 hooks.deprecationHandler(null, msg); 31870 } 31871 if (firstTime) { 31872 var args = []; 31873 var arg; 31874 for (var i = 0; i < arguments.length; i++) { 31875 arg = ''; 31876 if (typeof arguments[i] === 'object') { 31877 arg += '\n[' + i + '] '; 31878 for (var key in arguments[0]) { 31879 arg += key + ': ' + arguments[0][key] + ', '; 31880 } 31881 arg = arg.slice(0, -2); // Remove trailing comma and space 31882 } else { 31883 arg = arguments[i]; 31884 } 31885 args.push(arg); 31886 } 31887 warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack); 31888 firstTime = false; 31889 } 31890 return fn.apply(this, arguments); 31891 }, fn); 31892 } 31893 31894 var deprecations = {}; 31895 31896 function deprecateSimple(name, msg) { 31897 if (hooks.deprecationHandler != null) { 31898 hooks.deprecationHandler(name, msg); 31899 } 31900 if (!deprecations[name]) { 31901 warn(msg); 31902 deprecations[name] = true; 31903 } 31904 } 31905 31906 hooks.suppressDeprecationWarnings = false; 31907 hooks.deprecationHandler = null; 31908 31909 function isFunction(input) { 31910 return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]'; 31911 } 31912 31913 function set (config) { 31914 var prop, i; 31915 for (i in config) { 31916 prop = config[i]; 31917 if (isFunction(prop)) { 31918 this[i] = prop; 31919 } else { 31920 this['_' + i] = prop; 31921 } 31922 } 31923 this._config = config; 31924 // Lenient ordinal parsing accepts just a number in addition to 31925 // number + (possibly) stuff coming from _dayOfMonthOrdinalParse. 31926 // TODO: Remove "ordinalParse" fallback in next major release. 31927 this._dayOfMonthOrdinalParseLenient = new RegExp( 31928 (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + 31929 '|' + (/\d{1,2}/).source); 31930 } 31931 31932 function mergeConfigs(parentConfig, childConfig) { 31933 var res = extend({}, parentConfig), prop; 31934 for (prop in childConfig) { 31935 if (hasOwnProp(childConfig, prop)) { 31936 if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) { 31937 res[prop] = {}; 31938 extend(res[prop], parentConfig[prop]); 31939 extend(res[prop], childConfig[prop]); 31940 } else if (childConfig[prop] != null) { 31941 res[prop] = childConfig[prop]; 31942 } else { 31943 delete res[prop]; 31944 } 31945 } 31946 } 31947 for (prop in parentConfig) { 31948 if (hasOwnProp(parentConfig, prop) && 31949 !hasOwnProp(childConfig, prop) && 31950 isObject(parentConfig[prop])) { 31951 // make sure changes to properties don't modify parent config 31952 res[prop] = extend({}, res[prop]); 31953 } 31954 } 31955 return res; 31956 } 31957 31958 function Locale(config) { 31959 if (config != null) { 31960 this.set(config); 31961 } 31962 } 31963 31964 var keys; 31965 31966 if (Object.keys) { 31967 keys = Object.keys; 31968 } else { 31969 keys = function (obj) { 31970 var i, res = []; 31971 for (i in obj) { 31972 if (hasOwnProp(obj, i)) { 31973 res.push(i); 31974 } 31975 } 31976 return res; 31977 }; 31978 } 31979 31980 var defaultCalendar = { 31981 sameDay : '[Today at] LT', 31982 nextDay : '[Tomorrow at] LT', 31983 nextWeek : 'dddd [at] LT', 31984 lastDay : '[Yesterday at] LT', 31985 lastWeek : '[Last] dddd [at] LT', 31986 sameElse : 'L' 31987 }; 31988 31989 function calendar (key, mom, now) { 31990 var output = this._calendar[key] || this._calendar['sameElse']; 31991 return isFunction(output) ? output.call(mom, now) : output; 31992 } 31993 31994 var defaultLongDateFormat = { 31995 LTS : 'h:mm:ss A', 31996 LT : 'h:mm A', 31997 L : 'MM/DD/YYYY', 31998 LL : 'MMMM D, YYYY', 31999 LLL : 'MMMM D, YYYY h:mm A', 32000 LLLL : 'dddd, MMMM D, YYYY h:mm A' 32001 }; 32002 32003 function longDateFormat (key) { 32004 var format = this._longDateFormat[key], 32005 formatUpper = this._longDateFormat[key.toUpperCase()]; 32006 32007 if (format || !formatUpper) { 32008 return format; 32009 } 32010 32011 this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) { 32012 return val.slice(1); 32013 }); 32014 32015 return this._longDateFormat[key]; 32016 } 32017 32018 var defaultInvalidDate = 'Invalid date'; 32019 32020 function invalidDate () { 32021 return this._invalidDate; 32022 } 32023 32024 var defaultOrdinal = '%d'; 32025 var defaultDayOfMonthOrdinalParse = /\d{1,2}/; 32026 32027 function ordinal (number) { 32028 return this._ordinal.replace('%d', number); 32029 } 32030 32031 var defaultRelativeTime = { 32032 future : 'in %s', 32033 past : '%s ago', 32034 s : 'a few seconds', 32035 ss : '%d seconds', 32036 m : 'a minute', 32037 mm : '%d minutes', 32038 h : 'an hour', 32039 hh : '%d hours', 32040 d : 'a day', 32041 dd : '%d days', 32042 M : 'a month', 32043 MM : '%d months', 32044 y : 'a year', 32045 yy : '%d years' 32046 }; 32047 32048 function relativeTime (number, withoutSuffix, string, isFuture) { 32049 var output = this._relativeTime[string]; 32050 return (isFunction(output)) ? 32051 output(number, withoutSuffix, string, isFuture) : 32052 output.replace(/%d/i, number); 32053 } 32054 32055 function pastFuture (diff, output) { 32056 var format = this._relativeTime[diff > 0 ? 'future' : 'past']; 32057 return isFunction(format) ? format(output) : format.replace(/%s/i, output); 32058 } 32059 32060 var aliases = {}; 32061 32062 function addUnitAlias (unit, shorthand) { 32063 var lowerCase = unit.toLowerCase(); 32064 aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit; 32065 } 32066 32067 function normalizeUnits(units) { 32068 return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined; 32069 } 32070 32071 function normalizeObjectUnits(inputObject) { 32072 var normalizedInput = {}, 32073 normalizedProp, 32074 prop; 32075 32076 for (prop in inputObject) { 32077 if (hasOwnProp(inputObject, prop)) { 32078 normalizedProp = normalizeUnits(prop); 32079 if (normalizedProp) { 32080 normalizedInput[normalizedProp] = inputObject[prop]; 32081 } 32082 } 32083 } 32084 32085 return normalizedInput; 32086 } 32087 32088 var priorities = {}; 32089 32090 function addUnitPriority(unit, priority) { 32091 priorities[unit] = priority; 32092 } 32093 32094 function getPrioritizedUnits(unitsObj) { 32095 var units = []; 32096 for (var u in unitsObj) { 32097 units.push({unit: u, priority: priorities[u]}); 32098 } 32099 units.sort(function (a, b) { 32100 return a.priority - b.priority; 32101 }); 32102 return units; 32103 } 32104 32105 function zeroFill(number, targetLength, forceSign) { 32106 var absNumber = '' + Math.abs(number), 32107 zerosToFill = targetLength - absNumber.length, 32108 sign = number >= 0; 32109 return (sign ? (forceSign ? '+' : '') : '-') + 32110 Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber; 32111 } 32112 32113 var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g; 32114 32115 var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g; 32116 32117 var formatFunctions = {}; 32118 32119 var formatTokenFunctions = {}; 32120 32121 // token: 'M' 32122 // padded: ['MM', 2] 32123 // ordinal: 'Mo' 32124 // callback: function () { this.month() + 1 } 32125 function addFormatToken (token, padded, ordinal, callback) { 32126 var func = callback; 32127 if (typeof callback === 'string') { 32128 func = function () { 32129 return this[callback](); 32130 }; 32131 } 32132 if (token) { 32133 formatTokenFunctions[token] = func; 32134 } 32135 if (padded) { 32136 formatTokenFunctions[padded[0]] = function () { 32137 return zeroFill(func.apply(this, arguments), padded[1], padded[2]); 32138 }; 32139 } 32140 if (ordinal) { 32141 formatTokenFunctions[ordinal] = function () { 32142 return this.localeData().ordinal(func.apply(this, arguments), token); 32143 }; 32144 } 32145 } 32146 32147 function removeFormattingTokens(input) { 32148 if (input.match(/\[[\s\S]/)) { 32149 return input.replace(/^\[|\]$/g, ''); 32150 } 32151 return input.replace(/\\/g, ''); 32152 } 32153 32154 function makeFormatFunction(format) { 32155 var array = format.match(formattingTokens), i, length; 32156 32157 for (i = 0, length = array.length; i < length; i++) { 32158 if (formatTokenFunctions[array[i]]) { 32159 array[i] = formatTokenFunctions[array[i]]; 32160 } else { 32161 array[i] = removeFormattingTokens(array[i]); 32162 } 32163 } 32164 32165 return function (mom) { 32166 var output = '', i; 32167 for (i = 0; i < length; i++) { 32168 output += isFunction(array[i]) ? array[i].call(mom, format) : array[i]; 32169 } 32170 return output; 32171 }; 32172 } 32173 32174 // format date using native date object 32175 function formatMoment(m, format) { 32176 if (!m.isValid()) { 32177 return m.localeData().invalidDate(); 32178 } 32179 32180 format = expandFormat(format, m.localeData()); 32181 formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format); 32182 32183 return formatFunctions[format](m); 32184 } 32185 32186 function expandFormat(format, locale) { 32187 var i = 5; 32188 32189 function replaceLongDateFormatTokens(input) { 32190 return locale.longDateFormat(input) || input; 32191 } 32192 32193 localFormattingTokens.lastIndex = 0; 32194 while (i >= 0 && localFormattingTokens.test(format)) { 32195 format = format.replace(localFormattingTokens, replaceLongDateFormatTokens); 32196 localFormattingTokens.lastIndex = 0; 32197 i -= 1; 32198 } 32199 32200 return format; 32201 } 32202 32203 var match1 = /\d/; // 0 - 9 32204 var match2 = /\d\d/; // 00 - 99 32205 var match3 = /\d{3}/; // 000 - 999 32206 var match4 = /\d{4}/; // 0000 - 9999 32207 var match6 = /[+-]?\d{6}/; // -999999 - 999999 32208 var match1to2 = /\d\d?/; // 0 - 99 32209 var match3to4 = /\d\d\d\d?/; // 999 - 9999 32210 var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999 32211 var match1to3 = /\d{1,3}/; // 0 - 999 32212 var match1to4 = /\d{1,4}/; // 0 - 9999 32213 var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999 32214 32215 var matchUnsigned = /\d+/; // 0 - inf 32216 var matchSigned = /[+-]?\d+/; // -inf - inf 32217 32218 var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z 32219 var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z 32220 32221 var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123 32222 32223 // any word (or two) characters or numbers including two/three word month in arabic. 32224 // includes scottish gaelic two word and hyphenated months 32225 var matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i; 32226 32227 var regexes = {}; 32228 32229 function addRegexToken (token, regex, strictRegex) { 32230 regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) { 32231 return (isStrict && strictRegex) ? strictRegex : regex; 32232 }; 32233 } 32234 32235 function getParseRegexForToken (token, config) { 32236 if (!hasOwnProp(regexes, token)) { 32237 return new RegExp(unescapeFormat(token)); 32238 } 32239 32240 return regexes[token](config._strict, config._locale); 32241 } 32242 32243 // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript 32244 function unescapeFormat(s) { 32245 return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) { 32246 return p1 || p2 || p3 || p4; 32247 })); 32248 } 32249 32250 function regexEscape(s) { 32251 return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); 32252 } 32253 32254 var tokens = {}; 32255 32256 function addParseToken (token, callback) { 32257 var i, func = callback; 32258 if (typeof token === 'string') { 32259 token = [token]; 32260 } 32261 if (isNumber(callback)) { 32262 func = function (input, array) { 32263 array[callback] = toInt(input); 32264 }; 32265 } 32266 for (i = 0; i < token.length; i++) { 32267 tokens[token[i]] = func; 32268 } 32269 } 32270 32271 function addWeekParseToken (token, callback) { 32272 addParseToken(token, function (input, array, config, token) { 32273 config._w = config._w || {}; 32274 callback(input, config._w, config, token); 32275 }); 32276 } 32277 32278 function addTimeToArrayFromToken(token, input, config) { 32279 if (input != null && hasOwnProp(tokens, token)) { 32280 tokens[token](input, config._a, config, token); 32281 } 32282 } 32283 32284 var YEAR = 0; 32285 var MONTH = 1; 32286 var DATE = 2; 32287 var HOUR = 3; 32288 var MINUTE = 4; 32289 var SECOND = 5; 32290 var MILLISECOND = 6; 32291 var WEEK = 7; 32292 var WEEKDAY = 8; 32293 32294 // FORMATTING 32295 32296 addFormatToken('Y', 0, 0, function () { 32297 var y = this.year(); 32298 return y <= 9999 ? '' + y : '+' + y; 32299 }); 32300 32301 addFormatToken(0, ['YY', 2], 0, function () { 32302 return this.year() % 100; 32303 }); 32304 32305 addFormatToken(0, ['YYYY', 4], 0, 'year'); 32306 addFormatToken(0, ['YYYYY', 5], 0, 'year'); 32307 addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); 32308 32309 // ALIASES 32310 32311 addUnitAlias('year', 'y'); 32312 32313 // PRIORITIES 32314 32315 addUnitPriority('year', 1); 32316 32317 // PARSING 32318 32319 addRegexToken('Y', matchSigned); 32320 addRegexToken('YY', match1to2, match2); 32321 addRegexToken('YYYY', match1to4, match4); 32322 addRegexToken('YYYYY', match1to6, match6); 32323 addRegexToken('YYYYYY', match1to6, match6); 32324 32325 addParseToken(['YYYYY', 'YYYYYY'], YEAR); 32326 addParseToken('YYYY', function (input, array) { 32327 array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input); 32328 }); 32329 addParseToken('YY', function (input, array) { 32330 array[YEAR] = hooks.parseTwoDigitYear(input); 32331 }); 32332 addParseToken('Y', function (input, array) { 32333 array[YEAR] = parseInt(input, 10); 32334 }); 32335 32336 // HELPERS 32337 32338 function daysInYear(year) { 32339 return isLeapYear(year) ? 366 : 365; 32340 } 32341 32342 function isLeapYear(year) { 32343 return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; 32344 } 32345 32346 // HOOKS 32347 32348 hooks.parseTwoDigitYear = function (input) { 32349 return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); 32350 }; 32351 32352 // MOMENTS 32353 32354 var getSetYear = makeGetSet('FullYear', true); 32355 32356 function getIsLeapYear () { 32357 return isLeapYear(this.year()); 32358 } 32359 32360 function makeGetSet (unit, keepTime) { 32361 return function (value) { 32362 if (value != null) { 32363 set$1(this, unit, value); 32364 hooks.updateOffset(this, keepTime); 32365 return this; 32366 } else { 32367 return get(this, unit); 32368 } 32369 }; 32370 } 32371 32372 function get (mom, unit) { 32373 return mom.isValid() ? 32374 mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN; 32375 } 32376 32377 function set$1 (mom, unit, value) { 32378 if (mom.isValid() && !isNaN(value)) { 32379 if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) { 32380 mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month())); 32381 } 32382 else { 32383 mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); 32384 } 32385 } 32386 } 32387 32388 // MOMENTS 32389 32390 function stringGet (units) { 32391 units = normalizeUnits(units); 32392 if (isFunction(this[units])) { 32393 return this[units](); 32394 } 32395 return this; 32396 } 32397 32398 32399 function stringSet (units, value) { 32400 if (typeof units === 'object') { 32401 units = normalizeObjectUnits(units); 32402 var prioritized = getPrioritizedUnits(units); 32403 for (var i = 0; i < prioritized.length; i++) { 32404 this[prioritized[i].unit](units[prioritized[i].unit]); 32405 } 32406 } else { 32407 units = normalizeUnits(units); 32408 if (isFunction(this[units])) { 32409 return this[units](value); 32410 } 32411 } 32412 return this; 32413 } 32414 32415 function mod(n, x) { 32416 return ((n % x) + x) % x; 32417 } 32418 32419 var indexOf; 32420 32421 if (Array.prototype.indexOf) { 32422 indexOf = Array.prototype.indexOf; 32423 } else { 32424 indexOf = function (o) { 32425 // I know 32426 var i; 32427 for (i = 0; i < this.length; ++i) { 32428 if (this[i] === o) { 32429 return i; 32430 } 32431 } 32432 return -1; 32433 }; 32434 } 32435 32436 function daysInMonth(year, month) { 32437 if (isNaN(year) || isNaN(month)) { 32438 return NaN; 32439 } 32440 var modMonth = mod(month, 12); 32441 year += (month - modMonth) / 12; 32442 return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2); 32443 } 32444 32445 // FORMATTING 32446 32447 addFormatToken('M', ['MM', 2], 'Mo', function () { 32448 return this.month() + 1; 32449 }); 32450 32451 addFormatToken('MMM', 0, 0, function (format) { 32452 return this.localeData().monthsShort(this, format); 32453 }); 32454 32455 addFormatToken('MMMM', 0, 0, function (format) { 32456 return this.localeData().months(this, format); 32457 }); 32458 32459 // ALIASES 32460 32461 addUnitAlias('month', 'M'); 32462 32463 // PRIORITY 32464 32465 addUnitPriority('month', 8); 32466 32467 // PARSING 32468 32469 addRegexToken('M', match1to2); 32470 addRegexToken('MM', match1to2, match2); 32471 addRegexToken('MMM', function (isStrict, locale) { 32472 return locale.monthsShortRegex(isStrict); 32473 }); 32474 addRegexToken('MMMM', function (isStrict, locale) { 32475 return locale.monthsRegex(isStrict); 32476 }); 32477 32478 addParseToken(['M', 'MM'], function (input, array) { 32479 array[MONTH] = toInt(input) - 1; 32480 }); 32481 32482 addParseToken(['MMM', 'MMMM'], function (input, array, config, token) { 32483 var month = config._locale.monthsParse(input, token, config._strict); 32484 // if we didn't find a month name, mark the date as invalid. 32485 if (month != null) { 32486 array[MONTH] = month; 32487 } else { 32488 getParsingFlags(config).invalidMonth = input; 32489 } 32490 }); 32491 32492 // LOCALES 32493 32494 var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/; 32495 var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'); 32496 function localeMonths (m, format) { 32497 if (!m) { 32498 return isArray(this._months) ? this._months : 32499 this._months['standalone']; 32500 } 32501 return isArray(this._months) ? this._months[m.month()] : 32502 this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()]; 32503 } 32504 32505 var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'); 32506 function localeMonthsShort (m, format) { 32507 if (!m) { 32508 return isArray(this._monthsShort) ? this._monthsShort : 32509 this._monthsShort['standalone']; 32510 } 32511 return isArray(this._monthsShort) ? this._monthsShort[m.month()] : 32512 this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()]; 32513 } 32514 32515 function handleStrictParse(monthName, format, strict) { 32516 var i, ii, mom, llc = monthName.toLocaleLowerCase(); 32517 if (!this._monthsParse) { 32518 // this is not used 32519 this._monthsParse = []; 32520 this._longMonthsParse = []; 32521 this._shortMonthsParse = []; 32522 for (i = 0; i < 12; ++i) { 32523 mom = createUTC([2000, i]); 32524 this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase(); 32525 this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase(); 32526 } 32527 } 32528 32529 if (strict) { 32530 if (format === 'MMM') { 32531 ii = indexOf.call(this._shortMonthsParse, llc); 32532 return ii !== -1 ? ii : null; 32533 } else { 32534 ii = indexOf.call(this._longMonthsParse, llc); 32535 return ii !== -1 ? ii : null; 32536 } 32537 } else { 32538 if (format === 'MMM') { 32539 ii = indexOf.call(this._shortMonthsParse, llc); 32540 if (ii !== -1) { 32541 return ii; 32542 } 32543 ii = indexOf.call(this._longMonthsParse, llc); 32544 return ii !== -1 ? ii : null; 32545 } else { 32546 ii = indexOf.call(this._longMonthsParse, llc); 32547 if (ii !== -1) { 32548 return ii; 32549 } 32550 ii = indexOf.call(this._shortMonthsParse, llc); 32551 return ii !== -1 ? ii : null; 32552 } 32553 } 32554 } 32555 32556 function localeMonthsParse (monthName, format, strict) { 32557 var i, mom, regex; 32558 32559 if (this._monthsParseExact) { 32560 return handleStrictParse.call(this, monthName, format, strict); 32561 } 32562 32563 if (!this._monthsParse) { 32564 this._monthsParse = []; 32565 this._longMonthsParse = []; 32566 this._shortMonthsParse = []; 32567 } 32568 32569 // TODO: add sorting 32570 // Sorting makes sure if one month (or abbr) is a prefix of another 32571 // see sorting in computeMonthsParse 32572 for (i = 0; i < 12; i++) { 32573 // make the regex if we don't have it already 32574 mom = createUTC([2000, i]); 32575 if (strict && !this._longMonthsParse[i]) { 32576 this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i'); 32577 this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i'); 32578 } 32579 if (!strict && !this._monthsParse[i]) { 32580 regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); 32581 this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); 32582 } 32583 // test the regex 32584 if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) { 32585 return i; 32586 } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) { 32587 return i; 32588 } else if (!strict && this._monthsParse[i].test(monthName)) { 32589 return i; 32590 } 32591 } 32592 } 32593 32594 // MOMENTS 32595 32596 function setMonth (mom, value) { 32597 var dayOfMonth; 32598 32599 if (!mom.isValid()) { 32600 // No op 32601 return mom; 32602 } 32603 32604 if (typeof value === 'string') { 32605 if (/^\d+$/.test(value)) { 32606 value = toInt(value); 32607 } else { 32608 value = mom.localeData().monthsParse(value); 32609 // TODO: Another silent failure? 32610 if (!isNumber(value)) { 32611 return mom; 32612 } 32613 } 32614 } 32615 32616 dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value)); 32617 mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); 32618 return mom; 32619 } 32620 32621 function getSetMonth (value) { 32622 if (value != null) { 32623 setMonth(this, value); 32624 hooks.updateOffset(this, true); 32625 return this; 32626 } else { 32627 return get(this, 'Month'); 32628 } 32629 } 32630 32631 function getDaysInMonth () { 32632 return daysInMonth(this.year(), this.month()); 32633 } 32634 32635 var defaultMonthsShortRegex = matchWord; 32636 function monthsShortRegex (isStrict) { 32637 if (this._monthsParseExact) { 32638 if (!hasOwnProp(this, '_monthsRegex')) { 32639 computeMonthsParse.call(this); 32640 } 32641 if (isStrict) { 32642 return this._monthsShortStrictRegex; 32643 } else { 32644 return this._monthsShortRegex; 32645 } 32646 } else { 32647 if (!hasOwnProp(this, '_monthsShortRegex')) { 32648 this._monthsShortRegex = defaultMonthsShortRegex; 32649 } 32650 return this._monthsShortStrictRegex && isStrict ? 32651 this._monthsShortStrictRegex : this._monthsShortRegex; 32652 } 32653 } 32654 32655 var defaultMonthsRegex = matchWord; 32656 function monthsRegex (isStrict) { 32657 if (this._monthsParseExact) { 32658 if (!hasOwnProp(this, '_monthsRegex')) { 32659 computeMonthsParse.call(this); 32660 } 32661 if (isStrict) { 32662 return this._monthsStrictRegex; 32663 } else { 32664 return this._monthsRegex; 32665 } 32666 } else { 32667 if (!hasOwnProp(this, '_monthsRegex')) { 32668 this._monthsRegex = defaultMonthsRegex; 32669 } 32670 return this._monthsStrictRegex && isStrict ? 32671 this._monthsStrictRegex : this._monthsRegex; 32672 } 32673 } 32674 32675 function computeMonthsParse () { 32676 function cmpLenRev(a, b) { 32677 return b.length - a.length; 32678 } 32679 32680 var shortPieces = [], longPieces = [], mixedPieces = [], 32681 i, mom; 32682 for (i = 0; i < 12; i++) { 32683 // make the regex if we don't have it already 32684 mom = createUTC([2000, i]); 32685 shortPieces.push(this.monthsShort(mom, '')); 32686 longPieces.push(this.months(mom, '')); 32687 mixedPieces.push(this.months(mom, '')); 32688 mixedPieces.push(this.monthsShort(mom, '')); 32689 } 32690 // Sorting makes sure if one month (or abbr) is a prefix of another it 32691 // will match the longer piece. 32692 shortPieces.sort(cmpLenRev); 32693 longPieces.sort(cmpLenRev); 32694 mixedPieces.sort(cmpLenRev); 32695 for (i = 0; i < 12; i++) { 32696 shortPieces[i] = regexEscape(shortPieces[i]); 32697 longPieces[i] = regexEscape(longPieces[i]); 32698 } 32699 for (i = 0; i < 24; i++) { 32700 mixedPieces[i] = regexEscape(mixedPieces[i]); 32701 } 32702 32703 this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); 32704 this._monthsShortRegex = this._monthsRegex; 32705 this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); 32706 this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); 32707 } 32708 32709 function createDate (y, m, d, h, M, s, ms) { 32710 // can't just apply() to create a date: 32711 // https://stackoverflow.com/q/181348 32712 var date; 32713 // the date constructor remaps years 0-99 to 1900-1999 32714 if (y < 100 && y >= 0) { 32715 // preserve leap years using a full 400 year cycle, then reset 32716 date = new Date(y + 400, m, d, h, M, s, ms); 32717 if (isFinite(date.getFullYear())) { 32718 date.setFullYear(y); 32719 } 32720 } else { 32721 date = new Date(y, m, d, h, M, s, ms); 32722 } 32723 32724 return date; 32725 } 32726 32727 function createUTCDate (y) { 32728 var date; 32729 // the Date.UTC function remaps years 0-99 to 1900-1999 32730 if (y < 100 && y >= 0) { 32731 var args = Array.prototype.slice.call(arguments); 32732 // preserve leap years using a full 400 year cycle, then reset 32733 args[0] = y + 400; 32734 date = new Date(Date.UTC.apply(null, args)); 32735 if (isFinite(date.getUTCFullYear())) { 32736 date.setUTCFullYear(y); 32737 } 32738 } else { 32739 date = new Date(Date.UTC.apply(null, arguments)); 32740 } 32741 32742 return date; 32743 } 32744 32745 // start-of-first-week - start-of-year 32746 function firstWeekOffset(year, dow, doy) { 32747 var // first-week day -- which january is always in the first week (4 for iso, 1 for other) 32748 fwd = 7 + dow - doy, 32749 // first-week day local weekday -- which local weekday is fwd 32750 fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7; 32751 32752 return -fwdlw + fwd - 1; 32753 } 32754 32755 // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday 32756 function dayOfYearFromWeeks(year, week, weekday, dow, doy) { 32757 var localWeekday = (7 + weekday - dow) % 7, 32758 weekOffset = firstWeekOffset(year, dow, doy), 32759 dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset, 32760 resYear, resDayOfYear; 32761 32762 if (dayOfYear <= 0) { 32763 resYear = year - 1; 32764 resDayOfYear = daysInYear(resYear) + dayOfYear; 32765 } else if (dayOfYear > daysInYear(year)) { 32766 resYear = year + 1; 32767 resDayOfYear = dayOfYear - daysInYear(year); 32768 } else { 32769 resYear = year; 32770 resDayOfYear = dayOfYear; 32771 } 32772 32773 return { 32774 year: resYear, 32775 dayOfYear: resDayOfYear 32776 }; 32777 } 32778 32779 function weekOfYear(mom, dow, doy) { 32780 var weekOffset = firstWeekOffset(mom.year(), dow, doy), 32781 week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1, 32782 resWeek, resYear; 32783 32784 if (week < 1) { 32785 resYear = mom.year() - 1; 32786 resWeek = week + weeksInYear(resYear, dow, doy); 32787 } else if (week > weeksInYear(mom.year(), dow, doy)) { 32788 resWeek = week - weeksInYear(mom.year(), dow, doy); 32789 resYear = mom.year() + 1; 32790 } else { 32791 resYear = mom.year(); 32792 resWeek = week; 32793 } 32794 32795 return { 32796 week: resWeek, 32797 year: resYear 32798 }; 32799 } 32800 32801 function weeksInYear(year, dow, doy) { 32802 var weekOffset = firstWeekOffset(year, dow, doy), 32803 weekOffsetNext = firstWeekOffset(year + 1, dow, doy); 32804 return (daysInYear(year) - weekOffset + weekOffsetNext) / 7; 32805 } 32806 32807 // FORMATTING 32808 32809 addFormatToken('w', ['ww', 2], 'wo', 'week'); 32810 addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); 32811 32812 // ALIASES 32813 32814 addUnitAlias('week', 'w'); 32815 addUnitAlias('isoWeek', 'W'); 32816 32817 // PRIORITIES 32818 32819 addUnitPriority('week', 5); 32820 addUnitPriority('isoWeek', 5); 32821 32822 // PARSING 32823 32824 addRegexToken('w', match1to2); 32825 addRegexToken('ww', match1to2, match2); 32826 addRegexToken('W', match1to2); 32827 addRegexToken('WW', match1to2, match2); 32828 32829 addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) { 32830 week[token.substr(0, 1)] = toInt(input); 32831 }); 32832 32833 // HELPERS 32834 32835 // LOCALES 32836 32837 function localeWeek (mom) { 32838 return weekOfYear(mom, this._week.dow, this._week.doy).week; 32839 } 32840 32841 var defaultLocaleWeek = { 32842 dow : 0, // Sunday is the first day of the week. 32843 doy : 6 // The week that contains Jan 6th is the first week of the year. 32844 }; 32845 32846 function localeFirstDayOfWeek () { 32847 return this._week.dow; 32848 } 32849 32850 function localeFirstDayOfYear () { 32851 return this._week.doy; 32852 } 32853 32854 // MOMENTS 32855 32856 function getSetWeek (input) { 32857 var week = this.localeData().week(this); 32858 return input == null ? week : this.add((input - week) * 7, 'd'); 32859 } 32860 32861 function getSetISOWeek (input) { 32862 var week = weekOfYear(this, 1, 4).week; 32863 return input == null ? week : this.add((input - week) * 7, 'd'); 32864 } 32865 32866 // FORMATTING 32867 32868 addFormatToken('d', 0, 'do', 'day'); 32869 32870 addFormatToken('dd', 0, 0, function (format) { 32871 return this.localeData().weekdaysMin(this, format); 32872 }); 32873 32874 addFormatToken('ddd', 0, 0, function (format) { 32875 return this.localeData().weekdaysShort(this, format); 32876 }); 32877 32878 addFormatToken('dddd', 0, 0, function (format) { 32879 return this.localeData().weekdays(this, format); 32880 }); 32881 32882 addFormatToken('e', 0, 0, 'weekday'); 32883 addFormatToken('E', 0, 0, 'isoWeekday'); 32884 32885 // ALIASES 32886 32887 addUnitAlias('day', 'd'); 32888 addUnitAlias('weekday', 'e'); 32889 addUnitAlias('isoWeekday', 'E'); 32890 32891 // PRIORITY 32892 addUnitPriority('day', 11); 32893 addUnitPriority('weekday', 11); 32894 addUnitPriority('isoWeekday', 11); 32895 32896 // PARSING 32897 32898 addRegexToken('d', match1to2); 32899 addRegexToken('e', match1to2); 32900 addRegexToken('E', match1to2); 32901 addRegexToken('dd', function (isStrict, locale) { 32902 return locale.weekdaysMinRegex(isStrict); 32903 }); 32904 addRegexToken('ddd', function (isStrict, locale) { 32905 return locale.weekdaysShortRegex(isStrict); 32906 }); 32907 addRegexToken('dddd', function (isStrict, locale) { 32908 return locale.weekdaysRegex(isStrict); 32909 }); 32910 32911 addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) { 32912 var weekday = config._locale.weekdaysParse(input, token, config._strict); 32913 // if we didn't get a weekday name, mark the date as invalid 32914 if (weekday != null) { 32915 week.d = weekday; 32916 } else { 32917 getParsingFlags(config).invalidWeekday = input; 32918 } 32919 }); 32920 32921 addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) { 32922 week[token] = toInt(input); 32923 }); 32924 32925 // HELPERS 32926 32927 function parseWeekday(input, locale) { 32928 if (typeof input !== 'string') { 32929 return input; 32930 } 32931 32932 if (!isNaN(input)) { 32933 return parseInt(input, 10); 32934 } 32935 32936 input = locale.weekdaysParse(input); 32937 if (typeof input === 'number') { 32938 return input; 32939 } 32940 32941 return null; 32942 } 32943 32944 function parseIsoWeekday(input, locale) { 32945 if (typeof input === 'string') { 32946 return locale.weekdaysParse(input) % 7 || 7; 32947 } 32948 return isNaN(input) ? null : input; 32949 } 32950 32951 // LOCALES 32952 function shiftWeekdays (ws, n) { 32953 return ws.slice(n, 7).concat(ws.slice(0, n)); 32954 } 32955 32956 var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'); 32957 function localeWeekdays (m, format) { 32958 var weekdays = isArray(this._weekdays) ? this._weekdays : 32959 this._weekdays[(m && m !== true && this._weekdays.isFormat.test(format)) ? 'format' : 'standalone']; 32960 return (m === true) ? shiftWeekdays(weekdays, this._week.dow) 32961 : (m) ? weekdays[m.day()] : weekdays; 32962 } 32963 32964 var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'); 32965 function localeWeekdaysShort (m) { 32966 return (m === true) ? shiftWeekdays(this._weekdaysShort, this._week.dow) 32967 : (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort; 32968 } 32969 32970 var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'); 32971 function localeWeekdaysMin (m) { 32972 return (m === true) ? shiftWeekdays(this._weekdaysMin, this._week.dow) 32973 : (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin; 32974 } 32975 32976 function handleStrictParse$1(weekdayName, format, strict) { 32977 var i, ii, mom, llc = weekdayName.toLocaleLowerCase(); 32978 if (!this._weekdaysParse) { 32979 this._weekdaysParse = []; 32980 this._shortWeekdaysParse = []; 32981 this._minWeekdaysParse = []; 32982 32983 for (i = 0; i < 7; ++i) { 32984 mom = createUTC([2000, 1]).day(i); 32985 this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase(); 32986 this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase(); 32987 this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase(); 32988 } 32989 } 32990 32991 if (strict) { 32992 if (format === 'dddd') { 32993 ii = indexOf.call(this._weekdaysParse, llc); 32994 return ii !== -1 ? ii : null; 32995 } else if (format === 'ddd') { 32996 ii = indexOf.call(this._shortWeekdaysParse, llc); 32997 return ii !== -1 ? ii : null; 32998 } else { 32999 ii = indexOf.call(this._minWeekdaysParse, llc); 33000 return ii !== -1 ? ii : null; 33001 } 33002 } else { 33003 if (format === 'dddd') { 33004 ii = indexOf.call(this._weekdaysParse, llc); 33005 if (ii !== -1) { 33006 return ii; 33007 } 33008 ii = indexOf.call(this._shortWeekdaysParse, llc); 33009 if (ii !== -1) { 33010 return ii; 33011 } 33012 ii = indexOf.call(this._minWeekdaysParse, llc); 33013 return ii !== -1 ? ii : null; 33014 } else if (format === 'ddd') { 33015 ii = indexOf.call(this._shortWeekdaysParse, llc); 33016 if (ii !== -1) { 33017 return ii; 33018 } 33019 ii = indexOf.call(this._weekdaysParse, llc); 33020 if (ii !== -1) { 33021 return ii; 33022 } 33023 ii = indexOf.call(this._minWeekdaysParse, llc); 33024 return ii !== -1 ? ii : null; 33025 } else { 33026 ii = indexOf.call(this._minWeekdaysParse, llc); 33027 if (ii !== -1) { 33028 return ii; 33029 } 33030 ii = indexOf.call(this._weekdaysParse, llc); 33031 if (ii !== -1) { 33032 return ii; 33033 } 33034 ii = indexOf.call(this._shortWeekdaysParse, llc); 33035 return ii !== -1 ? ii : null; 33036 } 33037 } 33038 } 33039 33040 function localeWeekdaysParse (weekdayName, format, strict) { 33041 var i, mom, regex; 33042 33043 if (this._weekdaysParseExact) { 33044 return handleStrictParse$1.call(this, weekdayName, format, strict); 33045 } 33046 33047 if (!this._weekdaysParse) { 33048 this._weekdaysParse = []; 33049 this._minWeekdaysParse = []; 33050 this._shortWeekdaysParse = []; 33051 this._fullWeekdaysParse = []; 33052 } 33053 33054 for (i = 0; i < 7; i++) { 33055 // make the regex if we don't have it already 33056 33057 mom = createUTC([2000, 1]).day(i); 33058 if (strict && !this._fullWeekdaysParse[i]) { 33059 this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i'); 33060 this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i'); 33061 this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i'); 33062 } 33063 if (!this._weekdaysParse[i]) { 33064 regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, ''); 33065 this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i'); 33066 } 33067 // test the regex 33068 if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) { 33069 return i; 33070 } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) { 33071 return i; 33072 } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) { 33073 return i; 33074 } else if (!strict && this._weekdaysParse[i].test(weekdayName)) { 33075 return i; 33076 } 33077 } 33078 } 33079 33080 // MOMENTS 33081 33082 function getSetDayOfWeek (input) { 33083 if (!this.isValid()) { 33084 return input != null ? this : NaN; 33085 } 33086 var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); 33087 if (input != null) { 33088 input = parseWeekday(input, this.localeData()); 33089 return this.add(input - day, 'd'); 33090 } else { 33091 return day; 33092 } 33093 } 33094 33095 function getSetLocaleDayOfWeek (input) { 33096 if (!this.isValid()) { 33097 return input != null ? this : NaN; 33098 } 33099 var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; 33100 return input == null ? weekday : this.add(input - weekday, 'd'); 33101 } 33102 33103 function getSetISODayOfWeek (input) { 33104 if (!this.isValid()) { 33105 return input != null ? this : NaN; 33106 } 33107 33108 // behaves the same as moment#day except 33109 // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) 33110 // as a setter, sunday should belong to the previous week. 33111 33112 if (input != null) { 33113 var weekday = parseIsoWeekday(input, this.localeData()); 33114 return this.day(this.day() % 7 ? weekday : weekday - 7); 33115 } else { 33116 return this.day() || 7; 33117 } 33118 } 33119 33120 var defaultWeekdaysRegex = matchWord; 33121 function weekdaysRegex (isStrict) { 33122 if (this._weekdaysParseExact) { 33123 if (!hasOwnProp(this, '_weekdaysRegex')) { 33124 computeWeekdaysParse.call(this); 33125 } 33126 if (isStrict) { 33127 return this._weekdaysStrictRegex; 33128 } else { 33129 return this._weekdaysRegex; 33130 } 33131 } else { 33132 if (!hasOwnProp(this, '_weekdaysRegex')) { 33133 this._weekdaysRegex = defaultWeekdaysRegex; 33134 } 33135 return this._weekdaysStrictRegex && isStrict ? 33136 this._weekdaysStrictRegex : this._weekdaysRegex; 33137 } 33138 } 33139 33140 var defaultWeekdaysShortRegex = matchWord; 33141 function weekdaysShortRegex (isStrict) { 33142 if (this._weekdaysParseExact) { 33143 if (!hasOwnProp(this, '_weekdaysRegex')) { 33144 computeWeekdaysParse.call(this); 33145 } 33146 if (isStrict) { 33147 return this._weekdaysShortStrictRegex; 33148 } else { 33149 return this._weekdaysShortRegex; 33150 } 33151 } else { 33152 if (!hasOwnProp(this, '_weekdaysShortRegex')) { 33153 this._weekdaysShortRegex = defaultWeekdaysShortRegex; 33154 } 33155 return this._weekdaysShortStrictRegex && isStrict ? 33156 this._weekdaysShortStrictRegex : this._weekdaysShortRegex; 33157 } 33158 } 33159 33160 var defaultWeekdaysMinRegex = matchWord; 33161 function weekdaysMinRegex (isStrict) { 33162 if (this._weekdaysParseExact) { 33163 if (!hasOwnProp(this, '_weekdaysRegex')) { 33164 computeWeekdaysParse.call(this); 33165 } 33166 if (isStrict) { 33167 return this._weekdaysMinStrictRegex; 33168 } else { 33169 return this._weekdaysMinRegex; 33170 } 33171 } else { 33172 if (!hasOwnProp(this, '_weekdaysMinRegex')) { 33173 this._weekdaysMinRegex = defaultWeekdaysMinRegex; 33174 } 33175 return this._weekdaysMinStrictRegex && isStrict ? 33176 this._weekdaysMinStrictRegex : this._weekdaysMinRegex; 33177 } 33178 } 33179 33180 33181 function computeWeekdaysParse () { 33182 function cmpLenRev(a, b) { 33183 return b.length - a.length; 33184 } 33185 33186 var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [], 33187 i, mom, minp, shortp, longp; 33188 for (i = 0; i < 7; i++) { 33189 // make the regex if we don't have it already 33190 mom = createUTC([2000, 1]).day(i); 33191 minp = this.weekdaysMin(mom, ''); 33192 shortp = this.weekdaysShort(mom, ''); 33193 longp = this.weekdays(mom, ''); 33194 minPieces.push(minp); 33195 shortPieces.push(shortp); 33196 longPieces.push(longp); 33197 mixedPieces.push(minp); 33198 mixedPieces.push(shortp); 33199 mixedPieces.push(longp); 33200 } 33201 // Sorting makes sure if one weekday (or abbr) is a prefix of another it 33202 // will match the longer piece. 33203 minPieces.sort(cmpLenRev); 33204 shortPieces.sort(cmpLenRev); 33205 longPieces.sort(cmpLenRev); 33206 mixedPieces.sort(cmpLenRev); 33207 for (i = 0; i < 7; i++) { 33208 shortPieces[i] = regexEscape(shortPieces[i]); 33209 longPieces[i] = regexEscape(longPieces[i]); 33210 mixedPieces[i] = regexEscape(mixedPieces[i]); 33211 } 33212 33213 this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); 33214 this._weekdaysShortRegex = this._weekdaysRegex; 33215 this._weekdaysMinRegex = this._weekdaysRegex; 33216 33217 this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); 33218 this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); 33219 this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i'); 33220 } 33221 33222 // FORMATTING 33223 33224 function hFormat() { 33225 return this.hours() % 12 || 12; 33226 } 33227 33228 function kFormat() { 33229 return this.hours() || 24; 33230 } 33231 33232 addFormatToken('H', ['HH', 2], 0, 'hour'); 33233 addFormatToken('h', ['hh', 2], 0, hFormat); 33234 addFormatToken('k', ['kk', 2], 0, kFormat); 33235 33236 addFormatToken('hmm', 0, 0, function () { 33237 return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2); 33238 }); 33239 33240 addFormatToken('hmmss', 0, 0, function () { 33241 return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) + 33242 zeroFill(this.seconds(), 2); 33243 }); 33244 33245 addFormatToken('Hmm', 0, 0, function () { 33246 return '' + this.hours() + zeroFill(this.minutes(), 2); 33247 }); 33248 33249 addFormatToken('Hmmss', 0, 0, function () { 33250 return '' + this.hours() + zeroFill(this.minutes(), 2) + 33251 zeroFill(this.seconds(), 2); 33252 }); 33253 33254 function meridiem (token, lowercase) { 33255 addFormatToken(token, 0, 0, function () { 33256 return this.localeData().meridiem(this.hours(), this.minutes(), lowercase); 33257 }); 33258 } 33259 33260 meridiem('a', true); 33261 meridiem('A', false); 33262 33263 // ALIASES 33264 33265 addUnitAlias('hour', 'h'); 33266 33267 // PRIORITY 33268 addUnitPriority('hour', 13); 33269 33270 // PARSING 33271 33272 function matchMeridiem (isStrict, locale) { 33273 return locale._meridiemParse; 33274 } 33275 33276 addRegexToken('a', matchMeridiem); 33277 addRegexToken('A', matchMeridiem); 33278 addRegexToken('H', match1to2); 33279 addRegexToken('h', match1to2); 33280 addRegexToken('k', match1to2); 33281 addRegexToken('HH', match1to2, match2); 33282 addRegexToken('hh', match1to2, match2); 33283 addRegexToken('kk', match1to2, match2); 33284 33285 addRegexToken('hmm', match3to4); 33286 addRegexToken('hmmss', match5to6); 33287 addRegexToken('Hmm', match3to4); 33288 addRegexToken('Hmmss', match5to6); 33289 33290 addParseToken(['H', 'HH'], HOUR); 33291 addParseToken(['k', 'kk'], function (input, array, config) { 33292 var kInput = toInt(input); 33293 array[HOUR] = kInput === 24 ? 0 : kInput; 33294 }); 33295 addParseToken(['a', 'A'], function (input, array, config) { 33296 config._isPm = config._locale.isPM(input); 33297 config._meridiem = input; 33298 }); 33299 addParseToken(['h', 'hh'], function (input, array, config) { 33300 array[HOUR] = toInt(input); 33301 getParsingFlags(config).bigHour = true; 33302 }); 33303 addParseToken('hmm', function (input, array, config) { 33304 var pos = input.length - 2; 33305 array[HOUR] = toInt(input.substr(0, pos)); 33306 array[MINUTE] = toInt(input.substr(pos)); 33307 getParsingFlags(config).bigHour = true; 33308 }); 33309 addParseToken('hmmss', function (input, array, config) { 33310 var pos1 = input.length - 4; 33311 var pos2 = input.length - 2; 33312 array[HOUR] = toInt(input.substr(0, pos1)); 33313 array[MINUTE] = toInt(input.substr(pos1, 2)); 33314 array[SECOND] = toInt(input.substr(pos2)); 33315 getParsingFlags(config).bigHour = true; 33316 }); 33317 addParseToken('Hmm', function (input, array, config) { 33318 var pos = input.length - 2; 33319 array[HOUR] = toInt(input.substr(0, pos)); 33320 array[MINUTE] = toInt(input.substr(pos)); 33321 }); 33322 addParseToken('Hmmss', function (input, array, config) { 33323 var pos1 = input.length - 4; 33324 var pos2 = input.length - 2; 33325 array[HOUR] = toInt(input.substr(0, pos1)); 33326 array[MINUTE] = toInt(input.substr(pos1, 2)); 33327 array[SECOND] = toInt(input.substr(pos2)); 33328 }); 33329 33330 // LOCALES 33331 33332 function localeIsPM (input) { 33333 // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing str
vendor: 11,105 bytes, lines 33333-33649
33333ings like arrays 33334 // Using charAt should be more compatible. 33335 return ((input + '').toLowerCase().charAt(0) === 'p'); 33336 } 33337 33338 var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i; 33339 function localeMeridiem (hours, minutes, isLower) { 33340 if (hours > 11) { 33341 return isLower ? 'pm' : 'PM'; 33342 } else { 33343 return isLower ? 'am' : 'AM'; 33344 } 33345 } 33346 33347 33348 // MOMENTS 33349 33350 // Setting the hour should keep the time, because the user explicitly 33351 // specified which hour they want. So trying to maintain the same hour (in 33352 // a new timezone) makes sense. Adding/subtracting hours does not follow 33353 // this rule. 33354 var getSetHour = makeGetSet('Hours', true); 33355 33356 var baseConfig = { 33357 calendar: defaultCalendar, 33358 longDateFormat: defaultLongDateFormat, 33359 invalidDate: defaultInvalidDate, 33360 ordinal: defaultOrdinal, 33361 dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse, 33362 relativeTime: defaultRelativeTime, 33363 33364 months: defaultLocaleMonths, 33365 monthsShort: defaultLocaleMonthsShort, 33366 33367 week: defaultLocaleWeek, 33368 33369 weekdays: defaultLocaleWeekdays, 33370 weekdaysMin: defaultLocaleWeekdaysMin, 33371 weekdaysShort: defaultLocaleWeekdaysShort, 33372 33373 meridiemParse: defaultLocaleMeridiemParse 33374 }; 33375 33376 // internal storage for locale config files 33377 var locales = {}; 33378 var localeFamilies = {}; 33379 var globalLocale; 33380 33381 function normalizeLocale(key) { 33382 return key ? key.toLowerCase().replace('_', '-') : key; 33383 } 33384 33385 // pick the locale from the array 33386 // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each 33387 // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root 33388 function chooseLocale(names) { 33389 var i = 0, j, next, locale, split; 33390 33391 while (i < names.length) { 33392 split = normalizeLocale(names[i]).split('-'); 33393 j = split.length; 33394 next = normalizeLocale(names[i + 1]); 33395 next = next ? next.split('-') : null; 33396 while (j > 0) { 33397 locale = loadLocale(split.slice(0, j).join('-')); 33398 if (locale) { 33399 return locale; 33400 } 33401 if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { 33402 //the next array item is better than a shallower substring of this one 33403 break; 33404 } 33405 j--; 33406 } 33407 i++; 33408 } 33409 return globalLocale; 33410 } 33411 33412 function loadLocale(name) { 33413 var oldLocale = null; 33414 // TODO: Find a better way to register and load all the locales in Node 33415 if (!locales[name] && (typeof module !== 'undefined') && 33416 module && module.exports) { 33417 try { 33418 oldLocale = globalLocale._abbr; 33419 var aliasedRequire = require; 33420 aliasedRequire('./locale/' + name); 33421 getSetGlobalLocale(oldLocale); 33422 } catch (e) {} 33423 } 33424 return locales[name]; 33425 } 33426 33427 // This function will load locale and then set the global locale. If 33428 // no arguments are passed in, it will simply return the current global 33429 // locale key. 33430 function getSetGlobalLocale (key, values) { 33431 var data; 33432 if (key) { 33433 if (isUndefined(values)) { 33434 data = getLocale(key); 33435 } 33436 else { 33437 data = defineLocale(key, values); 33438 } 33439 33440 if (data) { 33441 // moment.duration._locale = moment._locale = data; 33442 globalLocale = data; 33443 } 33444 else { 33445 if ((typeof console !== 'undefined') && console.warn) { 33446 //warn user if arguments are passed but the locale could not be set 33447 console.warn('Locale ' + key + ' not found. Did you forget to load it?'); 33448 } 33449 } 33450 } 33451 33452 return globalLocale._abbr; 33453 } 33454 33455 function defineLocale (name, config) { 33456 if (config !== null) { 33457 var locale, parentConfig = baseConfig; 33458 config.abbr = name; 33459 if (locales[name] != null) { 33460 deprecateSimple('defineLocaleOverride', 33461 'use moment.updateLocale(localeName, config) to change ' + 33462 'an existing locale. moment.defineLocale(localeName, ' + 33463 'config) should only be used for creating a new locale ' + 33464 'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.'); 33465 parentConfig = locales[name]._config; 33466 } else if (config.parentLocale != null) { 33467 if (locales[config.parentLocale] != null) { 33468 parentConfig = locales[config.parentLocale]._config; 33469 } else { 33470 locale = loadLocale(config.parentLocale); 33471 if (locale != null) { 33472 parentConfig = locale._config; 33473 } else { 33474 if (!localeFamilies[config.parentLocale]) { 33475 localeFamilies[config.parentLocale] = []; 33476 } 33477 localeFamilies[config.parentLocale].push({ 33478 name: name, 33479 config: config 33480 }); 33481 return null; 33482 } 33483 } 33484 } 33485 locales[name] = new Locale(mergeConfigs(parentConfig, config)); 33486 33487 if (localeFamilies[name]) { 33488 localeFamilies[name].forEach(function (x) { 33489 defineLocale(x.name, x.config); 33490 }); 33491 } 33492 33493 // backwards compat for now: also set the locale 33494 // make sure we set the locale AFTER all child locales have been 33495 // created, so we won't end up with the child locale set. 33496 getSetGlobalLocale(name); 33497 33498 33499 return locales[name]; 33500 } else { 33501 // useful for testing 33502 delete locales[name]; 33503 return null; 33504 } 33505 } 33506 33507 function updateLocale(name, config) { 33508 if (config != null) { 33509 var locale, tmpLocale, parentConfig = baseConfig; 33510 // MERGE 33511 tmpLocale = loadLocale(name); 33512 if (tmpLocale != null) { 33513 parentConfig = tmpLocale._config; 33514 } 33515 config = mergeConfigs(parentConfig, config); 33516 locale = new Locale(config); 33517 locale.parentLocale = locales[name]; 33518 locales[name] = locale; 33519 33520 // backwards compat for now: also set the locale 33521 getSetGlobalLocale(name); 33522 } else { 33523 // pass null for config to unupdate, useful for tests 33524 if (locales[name] != null) { 33525 if (locales[name].parentLocale != null) { 33526 locales[name] = locales[name].parentLocale; 33527 } else if (locales[name] != null) { 33528 delete locales[name]; 33529 } 33530 } 33531 } 33532 return locales[name]; 33533 } 33534 33535 // returns locale data 33536 function getLocale (key) { 33537 var locale; 33538 33539 if (key && key._locale && key._locale._abbr) { 33540 key = key._locale._abbr; 33541 } 33542 33543 if (!key) { 33544 return globalLocale; 33545 } 33546 33547 if (!isArray(key)) { 33548 //short-circuit everything else 33549 locale = loadLocale(key); 33550 if (locale) { 33551 return locale; 33552 } 33553 key = [key]; 33554 } 33555 33556 return chooseLocale(key); 33557 } 33558 33559 function listLocales() { 33560 return keys(locales); 33561 } 33562 33563 function checkOverflow (m) { 33564 var overflow; 33565 var a = m._a; 33566 33567 if (a && getParsingFlags(m).overflow === -2) { 33568 overflow = 33569 a[MONTH] < 0 || a[MONTH] > 11 ? MONTH : 33570 a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE : 33571 a[HOUR] < 0 || a[HOUR] > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR : 33572 a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE : 33573 a[SECOND] < 0 || a[SECOND] > 59 ? SECOND : 33574 a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND : 33575 -1; 33576 33577 if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) { 33578 overflow = DATE; 33579 } 33580 if (getParsingFlags(m)._overflowWeeks && overflow === -1) { 33581 overflow = WEEK; 33582 } 33583 if (getParsingFlags(m)._overflowWeekday && overflow === -1) { 33584 overflow = WEEKDAY; 33585 } 33586 33587 getParsingFlags(m).overflow = overflow; 33588 } 33589 33590 return m; 33591 } 33592 33593 // Pick the first defined of two or three arguments. 33594 function defaults(a, b, c) { 33595 if (a != null) { 33596 return a; 33597 } 33598 if (b != null) { 33599 return b; 33600 } 33601 return c; 33602 } 33603 33604 function currentDateArray(config) { 33605 // hooks is actually the exported moment object 33606 var nowValue = new Date(hooks.now()); 33607 if (config._useUTC) { 33608 return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()]; 33609 } 33610 return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()]; 33611 } 33612 33613 // convert an array to a date. 33614 // the array should mirror the parameters below 33615 // note: all values past the year are optional and will default to the lowest possible value. 33616 // [year, month, day , hour, minute, second, millisecond] 33617 function configFromArray (config) { 33618 var i, date, input = [], currentDate, expectedWeekday, yearToUse; 33619 33620 if (config._d) { 33621 return; 33622 } 33623 33624 currentDate = currentDateArray(config); 33625 33626 //compute day of the year from weeks and weekdays 33627 if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { 33628 dayOfYearFromWeekInfo(config); 33629 } 33630 33631 //if the day of the year is set, figure out what it is 33632 if (config._dayOfYear != null) { 33633 yearToUse = defaults(config._a[YEAR], currentDate[YEAR]); 33634 33635 if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) { 33636 getParsingFlags(config)._overflowDayOfYear = true; 33637 } 33638 33639 date = createUTCDate(yearToUse, 0, config._dayOfYear); 33640 config._a[MONTH] = date.getUTCMonth(); 33641 config._a[DATE] = date.getUTCDate(); 33642 } 33643 33644 // Default to current date. 33645 // * if no year, month, day of month are given, default to today 33646 // * if day of month is given, default month and year 33647 // * if month is given, default only year 33648 // * if year is given, don't default anything 33649 for (i = 0; i < 3 && config._a[i] == null; ++i) {
vendor: 83,306 bytes, lines 33650-36170
33650 config._a[i] = input[i] = currentDate[i]; 33651 } 33652 33653 // Zero out whatever was not defaulted, including time 33654 for (; i < 7; i++) { 33655 config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; 33656 } 33657 33658 // Check for 24:00:00.000 33659 if (config._a[HOUR] === 24 && 33660 config._a[MINUTE] === 0 && 33661 config._a[SECOND] === 0 && 33662 config._a[MILLISECOND] === 0) { 33663 config._nextDay = true; 33664 config._a[HOUR] = 0; 33665 } 33666 33667 config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input); 33668 expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay(); 33669 33670 // Apply timezone offset from input. The actual utcOffset can be changed 33671 // with parseZone. 33672 if (config._tzm != null) { 33673 config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); 33674 } 33675 33676 if (config._nextDay) { 33677 config._a[HOUR] = 24; 33678 } 33679 33680 // check for mismatching day of week 33681 if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) { 33682 getParsingFlags(config).weekdayMismatch = true; 33683 } 33684 } 33685 33686 function dayOfYearFromWeekInfo(config) { 33687 var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow; 33688 33689 w = config._w; 33690 if (w.GG != null || w.W != null || w.E != null) { 33691 dow = 1; 33692 doy = 4; 33693 33694 // TODO: We need to take the current isoWeekYear, but that depends on 33695 // how we interpret now (local, utc, fixed offset). So create 33696 // a now version of current config (take local/utc/offset flags, and 33697 // create now). 33698 weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year); 33699 week = defaults(w.W, 1); 33700 weekday = defaults(w.E, 1); 33701 if (weekday < 1 || weekday > 7) { 33702 weekdayOverflow = true; 33703 } 33704 } else { 33705 dow = config._locale._week.dow; 33706 doy = config._locale._week.doy; 33707 33708 var curWeek = weekOfYear(createLocal(), dow, doy); 33709 33710 weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); 33711 33712 // Default to current week. 33713 week = defaults(w.w, curWeek.week); 33714 33715 if (w.d != null) { 33716 // weekday -- low day numbers are considered next week 33717 weekday = w.d; 33718 if (weekday < 0 || weekday > 6) { 33719 weekdayOverflow = true; 33720 } 33721 } else if (w.e != null) { 33722 // local weekday -- counting starts from beginning of week 33723 weekday = w.e + dow; 33724 if (w.e < 0 || w.e > 6) { 33725 weekdayOverflow = true; 33726 } 33727 } else { 33728 // default to beginning of week 33729 weekday = dow; 33730 } 33731 } 33732 if (week < 1 || week > weeksInYear(weekYear, dow, doy)) { 33733 getParsingFlags(config)._overflowWeeks = true; 33734 } else if (weekdayOverflow != null) { 33735 getParsingFlags(config)._overflowWeekday = true; 33736 } else { 33737 temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy); 33738 config._a[YEAR] = temp.year; 33739 config._dayOfYear = temp.dayOfYear; 33740 } 33741 } 33742 33743 // iso 8601 regex 33744 // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00) 33745 var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; 33746 var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; 33747 33748 var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/; 33749 33750 var isoDates = [ 33751 ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/], 33752 ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/], 33753 ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/], 33754 ['GGGG-[W]WW', /\d{4}-W\d\d/, false], 33755 ['YYYY-DDD', /\d{4}-\d{3}/], 33756 ['YYYY-MM', /\d{4}-\d\d/, false], 33757 ['YYYYYYMMDD', /[+-]\d{10}/], 33758 ['YYYYMMDD', /\d{8}/], 33759 // YYYYMM is NOT allowed by the standard 33760 ['GGGG[W]WWE', /\d{4}W\d{3}/], 33761 ['GGGG[W]WW', /\d{4}W\d{2}/, false], 33762 ['YYYYDDD', /\d{7}/] 33763 ]; 33764 33765 // iso time formats and regexes 33766 var isoTimes = [ 33767 ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/], 33768 ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/], 33769 ['HH:mm:ss', /\d\d:\d\d:\d\d/], 33770 ['HH:mm', /\d\d:\d\d/], 33771 ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/], 33772 ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/], 33773 ['HHmmss', /\d\d\d\d\d\d/], 33774 ['HHmm', /\d\d\d\d/], 33775 ['HH', /\d\d/] 33776 ]; 33777 33778 var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i; 33779 33780 // date from iso format 33781 function configFromISO(config) { 33782 var i, l, 33783 string = config._i, 33784 match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string), 33785 allowTime, dateFormat, timeFormat, tzFormat; 33786 33787 if (match) { 33788 getParsingFlags(config).iso = true; 33789 33790 for (i = 0, l = isoDates.length; i < l; i++) { 33791 if (isoDates[i][1].exec(match[1])) { 33792 dateFormat = isoDates[i][0]; 33793 allowTime = isoDates[i][2] !== false; 33794 break; 33795 } 33796 } 33797 if (dateFormat == null) { 33798 config._isValid = false; 33799 return; 33800 } 33801 if (match[3]) { 33802 for (i = 0, l = isoTimes.length; i < l; i++) { 33803 if (isoTimes[i][1].exec(match[3])) { 33804 // match[2] should be 'T' or space 33805 timeFormat = (match[2] || ' ') + isoTimes[i][0]; 33806 break; 33807 } 33808 } 33809 if (timeFormat == null) { 33810 config._isValid = false; 33811 return; 33812 } 33813 } 33814 if (!allowTime && timeFormat != null) { 33815 config._isValid = false; 33816 return; 33817 } 33818 if (match[4]) { 33819 if (tzRegex.exec(match[4])) { 33820 tzFormat = 'Z'; 33821 } else { 33822 config._isValid = false; 33823 return; 33824 } 33825 } 33826 config._f = dateFormat + (timeFormat || '') + (tzFormat || ''); 33827 configFromStringAndFormat(config); 33828 } else { 33829 config._isValid = false; 33830 } 33831 } 33832 33833 // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3 33834 var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/; 33835 33836 function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) { 33837 var result = [ 33838 untruncateYear(yearStr), 33839 defaultLocaleMonthsShort.indexOf(monthStr), 33840 parseInt(dayStr, 10), 33841 parseInt(hourStr, 10), 33842 parseInt(minuteStr, 10) 33843 ]; 33844 33845 if (secondStr) { 33846 result.push(parseInt(secondStr, 10)); 33847 } 33848 33849 return result; 33850 } 33851 33852 function untruncateYear(yearStr) { 33853 var year = parseInt(yearStr, 10); 33854 if (year <= 49) { 33855 return 2000 + year; 33856 } else if (year <= 999) { 33857 return 1900 + year; 33858 } 33859 return year; 33860 } 33861 33862 function preprocessRFC2822(s) { 33863 // Remove comments and folding whitespace and replace multiple-spaces with a single space 33864 return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, ''); 33865 } 33866 33867 function checkWeekday(weekdayStr, parsedInput, config) { 33868 if (weekdayStr) { 33869 // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check. 33870 var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr), 33871 weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay(); 33872 if (weekdayProvided !== weekdayActual) { 33873 getParsingFlags(config).weekdayMismatch = true; 33874 config._isValid = false; 33875 return false; 33876 } 33877 } 33878 return true; 33879 } 33880 33881 var obsOffsets = { 33882 UT: 0, 33883 GMT: 0, 33884 EDT: -4 * 60, 33885 EST: -5 * 60, 33886 CDT: -5 * 60, 33887 CST: -6 * 60, 33888 MDT: -6 * 60, 33889 MST: -7 * 60, 33890 PDT: -7 * 60, 33891 PST: -8 * 60 33892 }; 33893 33894 function calculateOffset(obsOffset, militaryOffset, numOffset) { 33895 if (obsOffset) { 33896 return obsOffsets[obsOffset]; 33897 } else if (militaryOffset) { 33898 // the only allowed military tz is Z 33899 return 0; 33900 } else { 33901 var hm = parseInt(numOffset, 10); 33902 var m = hm % 100, h = (hm - m) / 100; 33903 return h * 60 + m; 33904 } 33905 } 33906 33907 // date and time from ref 2822 format 33908 function configFromRFC2822(config) { 33909 var match = rfc2822.exec(preprocessRFC2822(config._i)); 33910 if (match) { 33911 var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]); 33912 if (!checkWeekday(match[1], parsedArray, config)) { 33913 return; 33914 } 33915 33916 config._a = parsedArray; 33917 config._tzm = calculateOffset(match[8], match[9], match[10]); 33918 33919 config._d = createUTCDate.apply(null, config._a); 33920 config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); 33921 33922 getParsingFlags(config).rfc2822 = true; 33923 } else { 33924 config._isValid = false; 33925 } 33926 } 33927 33928 // date from iso format or fallback 33929 function configFromString(config) { 33930 var matched = aspNetJsonRegex.exec(config._i); 33931 33932 if (matched !== null) { 33933 config._d = new Date(+matched[1]); 33934 return; 33935 } 33936 33937 configFromISO(config); 33938 if (config._isValid === false) { 33939 delete config._isValid; 33940 } else { 33941 return; 33942 } 33943 33944 configFromRFC2822(config); 33945 if (config._isValid === false) { 33946 delete config._isValid; 33947 } else { 33948 return; 33949 } 33950 33951 // Final attempt, use Input Fallback 33952 hooks.createFromInputFallback(config); 33953 } 33954 33955 hooks.createFromInputFallback = deprecate( 33956 'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' + 33957 'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' + 33958 'discouraged and will be removed in an upcoming major release. Please refer to ' + 33959 'http://momentjs.com/guides/#/warnings/js-date/ for more info.', 33960 function (config) { 33961 config._d = new Date(config._i + (config._useUTC ? ' UTC' : '')); 33962 } 33963 ); 33964 33965 // constant that refers to the ISO standard 33966 hooks.ISO_8601 = function () {}; 33967 33968 // constant that refers to the RFC 2822 form 33969 hooks.RFC_2822 = function () {}; 33970 33971 // date from string and format string 33972 function configFromStringAndFormat(config) { 33973 // TODO: Move this to another part of the creation flow to prevent circular deps 33974 if (config._f === hooks.ISO_8601) { 33975 configFromISO(config); 33976 return; 33977 } 33978 if (config._f === hooks.RFC_2822) { 33979 configFromRFC2822(config); 33980 return; 33981 } 33982 config._a = []; 33983 getParsingFlags(config).empty = true; 33984 33985 // This array is used to make a Date, either with `new Date` or `Date.UTC` 33986 var string = '' + config._i, 33987 i, parsedInput, tokens, token, skipped, 33988 stringLength = string.length, 33989 totalParsedInputLength = 0; 33990 33991 tokens = expandFormat(config._f, config._locale).match(formattingTokens) || []; 33992 33993 for (i = 0; i < tokens.length; i++) { 33994 token = tokens[i]; 33995 parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; 33996 // console.log('token', token, 'parsedInput', parsedInput, 33997 // 'regex', getParseRegexForToken(token, config)); 33998 if (parsedInput) { 33999 skipped = string.substr(0, string.indexOf(parsedInput)); 34000 if (skipped.length > 0) { 34001 getParsingFlags(config).unusedInput.push(skipped); 34002 } 34003 string = string.slice(string.indexOf(parsedInput) + parsedInput.length); 34004 totalParsedInputLength += parsedInput.length; 34005 } 34006 // don't parse if it's not a known token 34007 if (formatTokenFunctions[token]) { 34008 if (parsedInput) { 34009 getParsingFlags(config).empty = false; 34010 } 34011 else { 34012 getParsingFlags(config).unusedTokens.push(token); 34013 } 34014 addTimeToArrayFromToken(token, parsedInput, config); 34015 } 34016 else if (config._strict && !parsedInput) { 34017 getParsingFlags(config).unusedTokens.push(token); 34018 } 34019 } 34020 34021 // add remaining unparsed input length to the string 34022 getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength; 34023 if (string.length > 0) { 34024 getParsingFlags(config).unusedInput.push(string); 34025 } 34026 34027 // clear _12h flag if hour is <= 12 34028 if (config._a[HOUR] <= 12 && 34029 getParsingFlags(config).bigHour === true && 34030 config._a[HOUR] > 0) { 34031 getParsingFlags(config).bigHour = undefined; 34032 } 34033 34034 getParsingFlags(config).parsedDateParts = config._a.slice(0); 34035 getParsingFlags(config).meridiem = config._meridiem; 34036 // handle meridiem 34037 config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem); 34038 34039 configFromArray(config); 34040 checkOverflow(config); 34041 } 34042 34043 34044 function meridiemFixWrap (locale, hour, meridiem) { 34045 var isPm; 34046 34047 if (meridiem == null) { 34048 // nothing to do 34049 return hour; 34050 } 34051 if (locale.meridiemHour != null) { 34052 return locale.meridiemHour(hour, meridiem); 34053 } else if (locale.isPM != null) { 34054 // Fallback 34055 isPm = locale.isPM(meridiem); 34056 if (isPm && hour < 12) { 34057 hour += 12; 34058 } 34059 if (!isPm && hour === 12) { 34060 hour = 0; 34061 } 34062 return hour; 34063 } else { 34064 // this is not supposed to happen 34065 return hour; 34066 } 34067 } 34068 34069 // date from string and array of format strings 34070 function configFromStringAndArray(config) { 34071 var tempConfig, 34072 bestMoment, 34073 34074 scoreToBeat, 34075 i, 34076 currentScore; 34077 34078 if (config._f.length === 0) { 34079 getParsingFlags(config).invalidFormat = true; 34080 config._d = new Date(NaN); 34081 return; 34082 } 34083 34084 for (i = 0; i < config._f.length; i++) { 34085 currentScore = 0; 34086 tempConfig = copyConfig({}, config); 34087 if (config._useUTC != null) { 34088 tempConfig._useUTC = config._useUTC; 34089 } 34090 tempConfig._f = config._f[i]; 34091 configFromStringAndFormat(tempConfig); 34092 34093 if (!isValid(tempConfig)) { 34094 continue; 34095 } 34096 34097 // if there is any input that was not parsed add a penalty for that format 34098 currentScore += getParsingFlags(tempConfig).charsLeftOver; 34099 34100 //or tokens 34101 currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10; 34102 34103 getParsingFlags(tempConfig).score = currentScore; 34104 34105 if (scoreToBeat == null || currentScore < scoreToBeat) { 34106 scoreToBeat = currentScore; 34107 bestMoment = tempConfig; 34108 } 34109 } 34110 34111 extend(config, bestMoment || tempConfig); 34112 } 34113 34114 function configFromObject(config) { 34115 if (config._d) { 34116 return; 34117 } 34118 34119 var i = normalizeObjectUnits(config._i); 34120 config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) { 34121 return obj && parseInt(obj, 10); 34122 }); 34123 34124 configFromArray(config); 34125 } 34126 34127 function createFromConfig (config) { 34128 var res = new Moment(checkOverflow(prepareConfig(config))); 34129 if (res._nextDay) { 34130 // Adding is smart enough around DST 34131 res.add(1, 'd'); 34132 res._nextDay = undefined; 34133 } 34134 34135 return res; 34136 } 34137 34138 function prepareConfig (config) { 34139 var input = config._i, 34140 format = config._f; 34141 34142 config._locale = config._locale || getLocale(config._l); 34143 34144 if (input === null || (format === undefined && input === '')) { 34145 return createInvalid({nullInput: true}); 34146 } 34147 34148 if (typeof input === 'string') { 34149 config._i = input = config._locale.preparse(input); 34150 } 34151 34152 if (isMoment(input)) { 34153 return new Moment(checkOverflow(input)); 34154 } else if (isDate(input)) { 34155 config._d = input; 34156 } else if (isArray(format)) { 34157 configFromStringAndArray(config); 34158 } else if (format) { 34159 configFromStringAndFormat(config); 34160 } else { 34161 configFromInput(config); 34162 } 34163 34164 if (!isValid(config)) { 34165 config._d = null; 34166 } 34167 34168 return config; 34169 } 34170 34171 function configFromInput(config) { 34172 var input = config._i; 34173 if (isUndefined(input)) { 34174 config._d = new Date(hooks.now()); 34175 } else if (isDate(input)) { 34176 config._d = new Date(input.valueOf()); 34177 } else if (typeof input === 'string') { 34178 configFromString(config); 34179 } else if (isArray(input)) { 34180 config._a = map(input.slice(0), function (obj) { 34181 return parseInt(obj, 10); 34182 }); 34183 configFromArray(config); 34184 } else if (isObject(input)) { 34185 configFromObject(config); 34186 } else if (isNumber(input)) { 34187 // from milliseconds 34188 config._d = new Date(input); 34189 } else { 34190 hooks.createFromInputFallback(config); 34191 } 34192 } 34193 34194 function createLocalOrUTC (input, format, locale, strict, isUTC) { 34195 var c = {}; 34196 34197 if (locale === true || locale === false) { 34198 strict = locale; 34199 locale = undefined; 34200 } 34201 34202 if ((isObject(input) && isObjectEmpty(input)) || 34203 (isArray(input) && input.length === 0)) { 34204 input = undefined; 34205 } 34206 // object construction must be done this way. 34207 // https://github.com/moment/moment/issues/1423 34208 c._isAMomentObject = true; 34209 c._useUTC = c._isUTC = isUTC; 34210 c._l = locale; 34211 c._i = input; 34212 c._f = format; 34213 c._strict = strict; 34214 34215 return createFromConfig(c); 34216 } 34217 34218 function createLocal (input, format, locale, strict) { 34219 return createLocalOrUTC(input, format, locale, strict, false); 34220 } 34221 34222 var prototypeMin = deprecate( 34223 'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/', 34224 function () { 34225 var other = createLocal.apply(null, arguments); 34226 if (this.isValid() && other.isValid()) { 34227 return other < this ? this : other; 34228 } else { 34229 return createInvalid(); 34230 } 34231 } 34232 ); 34233 34234 var prototypeMax = deprecate( 34235 'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/', 34236 function () { 34237 var other = createLocal.apply(null, arguments); 34238 if (this.isValid() && other.isValid()) { 34239 return other > this ? this : other; 34240 } else { 34241 return createInvalid(); 34242 } 34243 } 34244 ); 34245 34246 // Pick a moment m from moments so that m[fn](other) is true for all 34247 // other. This relies on the function fn to be transitive. 34248 // 34249 // moments should either be an array of moment objects or an array, whose 34250 // first element is an array of moment objects. 34251 function pickBy(fn, moments) { 34252 var res, i; 34253 if (moments.length === 1 && isArray(moments[0])) { 34254 moments = moments[0]; 34255 } 34256 if (!moments.length) { 34257 return createLocal(); 34258 } 34259 res = moments[0]; 34260 for (i = 1; i < moments.length; ++i) { 34261 if (!moments[i].isValid() || moments[i][fn](res)) { 34262 res = moments[i]; 34263 } 34264 } 34265 return res; 34266 } 34267 34268 // TODO: Use [].sort instead? 34269 function min () { 34270 var args = [].slice.call(arguments, 0); 34271 34272 return pickBy('isBefore', args); 34273 } 34274 34275 function max () { 34276 var args = [].slice.call(arguments, 0); 34277 34278 return pickBy('isAfter', args); 34279 } 34280 34281 var now = function () { 34282 return Date.now ? Date.now() : +(new Date()); 34283 }; 34284 34285 var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond']; 34286 34287 function isDurationValid(m) { 34288 for (var key in m) { 34289 if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) { 34290 return false; 34291 } 34292 } 34293 34294 var unitHasDecimal = false; 34295 for (var i = 0; i < ordering.length; ++i) { 34296 if (m[ordering[i]]) { 34297 if (unitHasDecimal) { 34298 return false; // only allow non-integers for smallest unit 34299 } 34300 if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) { 34301 unitHasDecimal = true; 34302 } 34303 } 34304 } 34305 34306 return true; 34307 } 34308 34309 function isValid$1() { 34310 return this._isValid; 34311 } 34312 34313 function createInvalid$1() { 34314 return createDuration(NaN); 34315 } 34316 34317 function Duration (duration) { 34318 var normalizedInput = normalizeObjectUnits(duration), 34319 years = normalizedInput.year || 0, 34320 quarters = normalizedInput.quarter || 0, 34321 months = normalizedInput.month || 0, 34322 weeks = normalizedInput.week || normalizedInput.isoWeek || 0, 34323 days = normalizedInput.day || 0, 34324 hours = normalizedInput.hour || 0, 34325 minutes = normalizedInput.minute || 0, 34326 seconds = normalizedInput.second || 0, 34327 milliseconds = normalizedInput.millisecond || 0; 34328 34329 this._isValid = isDurationValid(normalizedInput); 34330 34331 // representation for dateAddRemove 34332 this._milliseconds = +milliseconds + 34333 seconds * 1e3 + // 1000 34334 minutes * 6e4 + // 1000 * 60 34335 hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978 34336 // Because of dateAddRemove treats 24 hours as different from a 34337 // day when working around DST, we need to store them separately 34338 this._days = +days + 34339 weeks * 7; 34340 // It is impossible to translate months into days without knowing 34341 // which months you are are talking about, so we have to store 34342 // it separately. 34343 this._months = +months + 34344 quarters * 3 + 34345 years * 12; 34346 34347 this._data = {}; 34348 34349 this._locale = getLocale(); 34350 34351 this._bubble(); 34352 } 34353 34354 function isDuration (obj) { 34355 return obj instanceof Duration; 34356 } 34357 34358 function absRound (number) { 34359 if (number < 0) { 34360 return Math.round(-1 * number) * -1; 34361 } else { 34362 return Math.round(number); 34363 } 34364 } 34365 34366 // FORMATTING 34367 34368 function offset (token, separator) { 34369 addFormatToken(token, 0, 0, function () { 34370 var offset = this.utcOffset(); 34371 var sign = '+'; 34372 if (offset < 0) { 34373 offset = -offset; 34374 sign = '-'; 34375 } 34376 return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2); 34377 }); 34378 } 34379 34380 offset('Z', ':'); 34381 offset('ZZ', ''); 34382 34383 // PARSING 34384 34385 addRegexToken('Z', matchShortOffset); 34386 addRegexToken('ZZ', matchShortOffset); 34387 addParseToken(['Z', 'ZZ'], function (input, array, config) { 34388 config._useUTC = true; 34389 config._tzm = offsetFromString(matchShortOffset, input); 34390 }); 34391 34392 // HELPERS 34393 34394 // timezone chunker 34395 // '+10:00' > ['10', '00'] 34396 // '-1530' > ['-15', '30'] 34397 var chunkOffset = /([\+\-]|\d\d)/gi; 34398 34399 function offsetFromString(matcher, string) { 34400 var matches = (string || '').match(matcher); 34401 34402 if (matches === null) { 34403 return null; 34404 } 34405 34406 var chunk = matches[matches.length - 1] || []; 34407 var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0]; 34408 var minutes = +(parts[1] * 60) + toInt(parts[2]); 34409 34410 return minutes === 0 ? 34411 0 : 34412 parts[0] === '+' ? minutes : -minutes; 34413 } 34414 34415 // Return a moment from input, that is local/utc/zone equivalent to model. 34416 function cloneWithOffset(input, model) { 34417 var res, diff; 34418 if (model._isUTC) { 34419 res = model.clone(); 34420 diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf(); 34421 // Use low-level api, because this fn is low-level api. 34422 res._d.setTime(res._d.valueOf() + diff); 34423 hooks.updateOffset(res, false); 34424 return res; 34425 } else { 34426 return createLocal(input).local(); 34427 } 34428 } 34429 34430 function getDateOffset (m) { 34431 // On Firefox.24 Date#getTimezoneOffset returns a floating point. 34432 // https://github.com/moment/moment/pull/1871 34433 return -Math.round(m._d.getTimezoneOffset() / 15) * 15; 34434 } 34435 34436 // HOOKS 34437 34438 // This function will be called whenever a moment is mutated. 34439 // It is intended to keep the offset in sync with the timezone. 34440 hooks.updateOffset = function () {}; 34441 34442 // MOMENTS 34443 34444 // keepLocalTime = true means only change the timezone, without 34445 // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]--> 34446 // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset 34447 // +0200, so we adjust the time as needed, to be valid. 34448 // 34449 // Keeping the time actually adds/subtracts (one hour) 34450 // from the actual represented time. That is why we call updateOffset 34451 // a second time. In case it wants us to change the offset again 34452 // _changeInProgress == true case, then we have to adjust, because 34453 // there is no such time in the given timezone. 34454 function getSetOffset (input, keepLocalTime, keepMinutes) { 34455 var offset = this._offset || 0, 34456 localAdjust; 34457 if (!this.isValid()) { 34458 return input != null ? this : NaN; 34459 } 34460 if (input != null) { 34461 if (typeof input === 'string') { 34462 input = offsetFromString(matchShortOffset, input); 34463 if (input === null) { 34464 return this; 34465 } 34466 } else if (Math.abs(input) < 16 && !keepMinutes) { 34467 input = input * 60; 34468 } 34469 if (!this._isUTC && keepLocalTime) { 34470 localAdjust = getDateOffset(this); 34471 } 34472 this._offset = input; 34473 this._isUTC = true; 34474 if (localAdjust != null) { 34475 this.add(localAdjust, 'm'); 34476 } 34477 if (offset !== input) { 34478 if (!keepLocalTime || this._changeInProgress) { 34479 addSubtract(this, createDuration(input - offset, 'm'), 1, false); 34480 } else if (!this._changeInProgress) { 34481 this._changeInProgress = true; 34482 hooks.updateOffset(this, true); 34483 this._changeInProgress = null; 34484 } 34485 } 34486 return this; 34487 } else { 34488 return this._isUTC ? offset : getDateOffset(this); 34489 } 34490 } 34491 34492 function getSetZone (input, keepLocalTime) { 34493 if (input != null) { 34494 if (typeof input !== 'string') { 34495 input = -input; 34496 } 34497 34498 this.utcOffset(input, keepLocalTime); 34499 34500 return this; 34501 } else { 34502 return -this.utcOffset(); 34503 } 34504 } 34505 34506 function setOffsetToUTC (keepLocalTime) { 34507 return this.utcOffset(0, keepLocalTime); 34508 } 34509 34510 function setOffsetToLocal (keepLocalTime) { 34511 if (this._isUTC) { 34512 this.utcOffset(0, keepLocalTime); 34513 this._isUTC = false; 34514 34515 if (keepLocalTime) { 34516 this.subtract(getDateOffset(this), 'm'); 34517 } 34518 } 34519 return this; 34520 } 34521 34522 function setOffsetToParsedOffset () { 34523 if (this._tzm != null) { 34524 this.utcOffset(this._tzm, false, true); 34525 } else if (typeof this._i === 'string') { 34526 var tZone = offsetFromString(matchOffset, this._i); 34527 if (tZone != null) { 34528 this.utcOffset(tZone); 34529 } 34530 else { 34531 this.utcOffset(0, true); 34532 } 34533 } 34534 return this; 34535 } 34536 34537 function hasAlignedHourOffset (input) { 34538 if (!this.isValid()) { 34539 return false; 34540 } 34541 input = input ? createLocal(input).utcOffset() : 0; 34542 34543 return (this.utcOffset() - input) % 60 === 0; 34544 } 34545 34546 function isDaylightSavingTime () { 34547 return ( 34548 this.utcOffset() > this.clone().month(0).utcOffset() || 34549 this.utcOffset() > this.clone().month(5).utcOffset() 34550 ); 34551 } 34552 34553 function isDaylightSavingTimeShifted () { 34554 if (!isUndefined(this._isDSTShifted)) { 34555 return this._isDSTShifted; 34556 } 34557 34558 var c = {}; 34559 34560 copyConfig(c, this); 34561 c = prepareConfig(c); 34562 34563 if (c._a) { 34564 var other = c._isUTC ? createUTC(c._a) : createLocal(c._a); 34565 this._isDSTShifted = this.isValid() && 34566 compareArrays(c._a, other.toArray()) > 0; 34567 } else { 34568 this._isDSTShifted = false; 34569 } 34570 34571 return this._isDSTShifted; 34572 } 34573 34574 function isLocal () { 34575 return this.isValid() ? !this._isUTC : false; 34576 } 34577 34578 function isUtcOffset () { 34579 return this.isValid() ? this._isUTC : false; 34580 } 34581 34582 function isUtc () { 34583 return this.isValid() ? this._isUTC && this._offset === 0 : false; 34584 } 34585 34586 // ASP.NET json date format regex 34587 var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/; 34588 34589 // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html 34590 // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere 34591 // and further modified to allow for strings containing both week and day 34592 var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/; 34593 34594 function createDuration (input, key) { 34595 var duration = input, 34596 // matching against regexp is expensive, do it on demand 34597 match = null, 34598 sign, 34599 ret, 34600 diffRes; 34601 34602 if (isDuration(input)) { 34603 duration = { 34604 ms : input._milliseconds, 34605 d : input._days, 34606 M : input._months 34607 }; 34608 } else if (isNumber(input)) { 34609 duration = {}; 34610 if (key) { 34611 duration[key] = input; 34612 } else { 34613 duration.milliseconds = input; 34614 } 34615 } else if (!!(match = aspNetRegex.exec(input))) { 34616 sign = (match[1] === '-') ? -1 : 1; 34617 duration = { 34618 y : 0, 34619 d : toInt(match[DATE]) * sign, 34620 h : toInt(match[HOUR]) * sign, 34621 m : toInt(match[MINUTE]) * sign, 34622 s : toInt(match[SECOND]) * sign, 34623 ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match 34624 }; 34625 } else if (!!(match = isoRegex.exec(input))) { 34626 sign = (match[1] === '-') ? -1 : 1; 34627 duration = { 34628 y : parseIso(match[2], sign), 34629 M : parseIso(match[3], sign), 34630 w : parseIso(match[4], sign), 34631 d : parseIso(match[5], sign), 34632 h : parseIso(match[6], sign), 34633 m : parseIso(match[7], sign), 34634 s : parseIso(match[8], sign) 34635 }; 34636 } else if (duration == null) {// checks for null or undefined 34637 duration = {}; 34638 } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) { 34639 diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to)); 34640 34641 duration = {}; 34642 duration.ms = diffRes.milliseconds; 34643 duration.M = diffRes.months; 34644 } 34645 34646 ret = new Duration(duration); 34647 34648 if (isDuration(input) && hasOwnProp(input, '_locale')) { 34649 ret._locale = input._locale; 34650 } 34651 34652 return ret; 34653 } 34654 34655 createDuration.fn = Duration.prototype; 34656 createDuration.invalid = createInvalid$1; 34657 34658 function parseIso (inp, sign) { 34659 // We'd normally use ~~inp for this, but unfortunately it also 34660 // converts floats to ints. 34661 // inp may be undefined, so careful calling replace on it. 34662 var res = inp && parseFloat(inp.replace(',', '.')); 34663 // apply sign while we're at it 34664 return (isNaN(res) ? 0 : res) * sign; 34665 } 34666 34667 function positiveMomentsDifference(base, other) { 34668 var res = {}; 34669 34670 res.months = other.month() - base.month() + 34671 (other.year() - base.year()) * 12; 34672 if (base.clone().add(res.months, 'M').isAfter(other)) { 34673 --res.months; 34674 } 34675 34676 res.milliseconds = +other - +(base.clone().add(res.months, 'M')); 34677 34678 return res; 34679 } 34680 34681 function momentsDifference(base, other) { 34682 var res; 34683 if (!(base.isValid() && other.isValid())) { 34684 return {milliseconds: 0, months: 0}; 34685 } 34686 34687 other = cloneWithOffset(other, base); 34688 if (base.isBefore(other)) { 34689 res = positiveMomentsDifference(base, other); 34690 } else { 34691 res = positiveMomentsDifference(other, base); 34692 res.milliseconds = -res.milliseconds; 34693 res.months = -res.months; 34694 } 34695 34696 return res; 34697 } 34698 34699 // TODO: remove 'name' arg after deprecation is removed 34700 function createAdder(direction, name) { 34701 return function (val, period) { 34702 var dur, tmp; 34703 //invert the arguments, but complain about it 34704 if (period !== null && !isNaN(+period)) { 34705 deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' + 34706 'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.'); 34707 tmp = val; val = period; period = tmp; 34708 } 34709 34710 val = typeof val === 'string' ? +val : val; 34711 dur = createDuration(val, period); 34712 addSubtract(this, dur, direction); 34713 return this; 34714 }; 34715 } 34716 34717 function addSubtract (mom, duration, isAdding, updateOffset) { 34718 var milliseconds = duration._milliseconds, 34719 days = absRound(duration._days), 34720 months = absRound(duration._months); 34721 34722 if (!mom.isValid()) { 34723 // No op 34724 return; 34725 } 34726 34727 updateOffset = updateOffset == null ? true : updateOffset; 34728 34729 if (months) { 34730 setMonth(mom, get(mom, 'Month') + months * isAdding); 34731 } 34732 if (days) { 34733 set$1(mom, 'Date', get(mom, 'Date') + days * isAdding); 34734 } 34735 if (milliseconds) { 34736 mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding); 34737 } 34738 if (updateOffset) { 34739 hooks.updateOffset(mom, days || months); 34740 } 34741 } 34742 34743 var add = createAdder(1, 'add'); 34744 var subtract = createAdder(-1, 'subtract'); 34745 34746 function getCalendarFormat(myMoment, now) { 34747 var diff = myMoment.diff(now, 'days', true); 34748 return diff < -6 ? 'sameElse' : 34749 diff < -1 ? 'lastWeek' : 34750 diff < 0 ? 'lastDay' : 34751 diff < 1 ? 'sameDay' : 34752 diff < 2 ? 'nextDay' : 34753 diff < 7 ? 'nextWeek' : 'sameElse'; 34754 } 34755 34756 function calendar$1 (time, formats) { 34757 // We want to compare the start of today, vs this. 34758 // Getting start-of-today depends on whether we're local/utc/offset or not. 34759 var now = time || createLocal(), 34760 sod = cloneWithOffset(now, this).startOf('day'), 34761 format = hooks.calendarFormat(this, sod) || 'sameElse'; 34762 34763 var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]); 34764 34765 return this.format(output || this.localeData().calendar(format, this, createLocal(now))); 34766 } 34767 34768 function clone () { 34769 return new Moment(this); 34770 } 34771 34772 function isAfter (input, units) { 34773 var localInput = isMoment(input) ? input : createLocal(input); 34774 if (!(this.isValid() && localInput.isValid())) { 34775 return false; 34776 } 34777 units = normalizeUnits(units) || 'millisecond'; 34778 if (units === 'millisecond') { 34779 return this.valueOf() > localInput.valueOf(); 34780 } else { 34781 return localInput.valueOf() < this.clone().startOf(units).valueOf(); 34782 } 34783 } 34784 34785 function isBefore (input, units) { 34786 var localInput = isMoment(input) ? input : createLocal(input); 34787 if (!(this.isValid() && localInput.isValid())) { 34788 return false; 34789 } 34790 units = normalizeUnits(units) || 'millisecond'; 34791 if (units === 'millisecond') { 34792 return this.valueOf() < localInput.valueOf(); 34793 } else { 34794 return this.clone().endOf(units).valueOf() < localInput.valueOf(); 34795 } 34796 } 34797 34798 function isBetween (from, to, units, inclusivity) { 34799 var localFrom = isMoment(from) ? from : createLocal(from), 34800 localTo = isMoment(to) ? to : createLocal(to); 34801 if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) { 34802 return false; 34803 } 34804 inclusivity = inclusivity || '()'; 34805 return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) && 34806 (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units)); 34807 } 34808 34809 function isSame (input, units) { 34810 var localInput = isMoment(input) ? input : createLocal(input), 34811 inputMs; 34812 if (!(this.isValid() && localInput.isValid())) { 34813 return false; 34814 } 34815 units = normalizeUnits(units) || 'millisecond'; 34816 if (units === 'millisecond') { 34817 return this.valueOf() === localInput.valueOf(); 34818 } else { 34819 inputMs = localInput.valueOf(); 34820 return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf(); 34821 } 34822 } 34823 34824 function isSameOrAfter (input, units) { 34825 return this.isSame(input, units) || this.isAfter(input, units); 34826 } 34827 34828 function isSameOrBefore (input, units) { 34829 return this.isSame(input, units) || this.isBefore(input, units); 34830 } 34831 34832 function diff (input, units, asFloat) { 34833 var that, 34834 zoneDelta, 34835 output; 34836 34837 if (!this.isValid()) { 34838 return NaN; 34839 } 34840 34841 that = cloneWithOffset(input, this); 34842 34843 if (!that.isValid()) { 34844 return NaN; 34845 } 34846 34847 zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4; 34848 34849 units = normalizeUnits(units); 34850 34851 switch (units) { 34852 case 'year': output = monthDiff(this, that) / 12; break; 34853 case 'month': output = monthDiff(this, that); break; 34854 case 'quarter': output = monthDiff(this, that) / 3; break; 34855 case 'second': output = (this - that) / 1e3; break; // 1000 34856 case 'minute': output = (this - that) / 6e4; break; // 1000 * 60 34857 case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60 34858 case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst 34859 case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst 34860 default: output = this - that; 34861 } 34862 34863 return asFloat ? output : absFloor(output); 34864 } 34865 34866 function monthDiff (a, b) { 34867 // difference in months 34868 var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()), 34869 // b is in (anchor - 1 month, anchor + 1 month) 34870 anchor = a.clone().add(wholeMonthDiff, 'months'), 34871 anchor2, adjust; 34872 34873 if (b - anchor < 0) { 34874 anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); 34875 // linear across the month 34876 adjust = (b - anchor) / (anchor - anchor2); 34877 } else { 34878 anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); 34879 // linear across the month 34880 adjust = (b - anchor) / (anchor2 - anchor); 34881 } 34882 34883 //check for negative zero, return zero if negative zero 34884 return -(wholeMonthDiff + adjust) || 0; 34885 } 34886 34887 hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ'; 34888 hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]'; 34889 34890 function toString () { 34891 return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); 34892 } 34893 34894 function toISOString(keepOffset) { 34895 if (!this.isValid()) { 34896 return null; 34897 } 34898 var utc = keepOffset !== true; 34899 var m = utc ? this.clone().utc() : this; 34900 if (m.year() < 0 || m.year() > 9999) { 34901 return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ'); 34902 } 34903 if (isFunction(Date.prototype.toISOString)) { 34904 // native implementation is ~50x faster, use it when we can 34905 if (utc) { 34906 return this.toDate().toISOString(); 34907 } else { 34908 return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z')); 34909 } 34910 } 34911 return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ'); 34912 } 34913 34914 /** 34915 * Return a human readable representation of a moment that can 34916 * also be evaluated to get a new moment which is the same 34917 * 34918 * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects 34919 */ 34920 function inspect () { 34921 if (!this.isValid()) { 34922 return 'moment.invalid(/* ' + this._i + ' */)'; 34923 } 34924 var func = 'moment'; 34925 var zone = ''; 34926 if (!this.isLocal()) { 34927 func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone'; 34928 zone = 'Z'; 34929 } 34930 var prefix = '[' + func + '("]'; 34931 var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY'; 34932 var datetime = '-MM-DD[T]HH:mm:ss.SSS'; 34933 var suffix = zone + '[")]'; 34934 34935 return this.format(prefix + year + datetime + suffix); 34936 } 34937 34938 function format (inputString) { 34939 if (!inputString) { 34940 inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat; 34941 } 34942 var output = formatMoment(this, inputString); 34943 return this.localeData().postformat(output); 34944 } 34945 34946 function from (time, withoutSuffix) { 34947 if (this.isValid() && 34948 ((isMoment(time) && time.isValid()) || 34949 createLocal(time).isValid())) { 34950 return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix); 34951 } else { 34952 return this.localeData().invalidDate(); 34953 } 34954 } 34955 34956 function fromNow (withoutSuffix) { 34957 return this.from(createLocal(), withoutSuffix); 34958 } 34959 34960 function to (time, withoutSuffix) { 34961 if (this.isValid() && 34962 ((isMoment(time) && time.isValid()) || 34963 createLocal(time).isValid())) { 34964 return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix); 34965 } else { 34966 return this.localeData().invalidDate(); 34967 } 34968 } 34969 34970 function toNow (withoutSuffix) { 34971 return this.to(createLocal(), withoutSuffix); 34972 } 34973 34974 // If passed a locale key, it will set the locale for this 34975 // instance. Otherwise, it will return the locale configuration 34976 // variables for this instance. 34977 function locale (key) { 34978 var newLocaleData; 34979 34980 if (key === undefined) { 34981 return this._locale._abbr; 34982 } else { 34983 newLocaleData = getLocale(key); 34984 if (newLocaleData != null) { 34985 this._locale = newLocaleData; 34986 } 34987 return this; 34988 } 34989 } 34990 34991 var lang = deprecate( 34992 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', 34993 function (key) { 34994 if (key === undefined) { 34995 return this.localeData(); 34996 } else { 34997 return this.locale(key); 34998 } 34999 } 35000 ); 35001 35002 function localeData () { 35003 return this._locale; 35004 } 35005 35006 var MS_PER_SECOND = 1000; 35007 var MS_PER_MINUTE = 60 * MS_PER_SECOND; 35008 var MS_PER_HOUR = 60 * MS_PER_MINUTE; 35009 var MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR; 35010 35011 // actual modulo - handles negative numbers (for dates before 1970): 35012 function mod$1(dividend, divisor) { 35013 return (dividend % divisor + divisor) % divisor; 35014 } 35015 35016 function localStartOfDate(y, m, d) { 35017 // the date constructor remaps years 0-99 to 1900-1999 35018 if (y < 100 && y >= 0) { 35019 // preserve leap years using a full 400 year cycle, then reset 35020 return new Date(y + 400, m, d) - MS_PER_400_YEARS; 35021 } else { 35022 return new Date(y, m, d).valueOf(); 35023 } 35024 } 35025 35026 function utcStartOfDate(y, m, d) { 35027 // Date.UTC remaps years 0-99 to 1900-1999 35028 if (y < 100 && y >= 0) { 35029 // preserve leap years using a full 400 year cycle, then reset 35030 return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS; 35031 } else { 35032 return Date.UTC(y, m, d); 35033 } 35034 } 35035 35036 function startOf (units) { 35037 var time; 35038 units = normalizeUnits(units); 35039 if (units === undefined || units === 'millisecond' || !this.isValid()) { 35040 return this; 35041 } 35042 35043 var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate; 35044 35045 switch (units) { 35046 case 'year': 35047 time = startOfDate(this.year(), 0, 1); 35048 break; 35049 case 'quarter': 35050 time = startOfDate(this.year(), this.month() - this.month() % 3, 1); 35051 break; 35052 case 'month': 35053 time = startOfDate(this.year(), this.month(), 1); 35054 break; 35055 case 'week': 35056 time = startOfDate(this.year(), this.month(), this.date() - this.weekday()); 35057 break; 35058 case 'isoWeek': 35059 time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1)); 35060 break; 35061 case 'day': 35062 case 'date': 35063 time = startOfDate(this.year(), this.month(), this.date()); 35064 break; 35065 case 'hour': 35066 time = this._d.valueOf(); 35067 time -= mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR); 35068 break; 35069 case 'minute': 35070 time = this._d.valueOf(); 35071 time -= mod$1(time, MS_PER_MINUTE); 35072 break; 35073 case 'second': 35074 time = this._d.valueOf(); 35075 time -= mod$1(time, MS_PER_SECOND); 35076 break; 35077 } 35078 35079 this._d.setTime(time); 35080 hooks.updateOffset(this, true); 35081 return this; 35082 } 35083 35084 function endOf (units) { 35085 var time; 35086 units = normalizeUnits(units); 35087 if (units === undefined || units === 'millisecond' || !this.isValid()) { 35088 return this; 35089 } 35090 35091 var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate; 35092 35093 switch (units) { 35094 case 'year': 35095 time = startOfDate(this.year() + 1, 0, 1) - 1; 35096 break; 35097 case 'quarter': 35098 time = startOfDate(this.year(), this.month() - this.month() % 3 + 3, 1) - 1; 35099 break; 35100 case 'month': 35101 time = startOfDate(this.year(), this.month() + 1, 1) - 1; 35102 break; 35103 case 'week': 35104 time = startOfDate(this.year(), this.month(), this.date() - this.weekday() + 7) - 1; 35105 break; 35106 case 'isoWeek': 35107 time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1; 35108 break; 35109 case 'day': 35110 case 'date': 35111 time = startOfDate(this.year(), this.month(), this.date() + 1) - 1; 35112 break; 35113 case 'hour': 35114 time = this._d.valueOf(); 35115 time += MS_PER_HOUR - mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR) - 1; 35116 break; 35117 case 'minute': 35118 time = this._d.valueOf(); 35119 time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1; 35120 break; 35121 case 'second': 35122 time = this._d.valueOf(); 35123 time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1; 35124 break; 35125 } 35126 35127 this._d.setTime(time); 35128 hooks.updateOffset(this, true); 35129 return this; 35130 } 35131 35132 function valueOf () { 35133 return this._d.valueOf() - ((this._offset || 0) * 60000); 35134 } 35135 35136 function unix () { 35137 return Math.floor(this.valueOf() / 1000); 35138 } 35139 35140 function toDate () { 35141 return new Date(this.valueOf()); 35142 } 35143 35144 function toArray () { 35145 var m = this; 35146 return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()]; 35147 } 35148 35149 function toObject () { 35150 var m = this; 35151 return { 35152 years: m.year(), 35153 months: m.month(), 35154 date: m.date(), 35155 hours: m.hours(), 35156 minutes: m.minutes(), 35157 seconds: m.seconds(), 35158 milliseconds: m.milliseconds() 35159 }; 35160 } 35161 35162 function toJSON () { 35163 // new Date(NaN).toJSON() === null 35164 return this.isValid() ? this.toISOString() : null; 35165 } 35166 35167 function isValid$2 () { 35168 return isValid(this); 35169 } 35170 35171 function parsingFlags () { 35172 return extend({}, getParsingFlags(this)); 35173 } 35174 35175 function invalidAt () { 35176 return getParsingFlags(this).overflow; 35177 } 35178 35179 function creationData() { 35180 return { 35181 input: this._i, 35182 format: this._f, 35183 locale: this._locale, 35184 isUTC: this._isUTC, 35185 strict: this._strict 35186 }; 35187 } 35188 35189 // FORMATTING 35190 35191 addFormatToken(0, ['gg', 2], 0, function () { 35192 return this.weekYear() % 100; 35193 }); 35194 35195 addFormatToken(0, ['GG', 2], 0, function () { 35196 return this.isoWeekYear() % 100; 35197 }); 35198 35199 function addWeekYearFormatToken (token, getter) { 35200 addFormatToken(0, [token, token.length], 0, getter); 35201 } 35202 35203 addWeekYearFormatToken('gggg', 'weekYear'); 35204 addWeekYearFormatToken('ggggg', 'weekYear'); 35205 addWeekYearFormatToken('GGGG', 'isoWeekYear'); 35206 addWeekYearFormatToken('GGGGG', 'isoWeekYear'); 35207 35208 // ALIASES 35209 35210 addUnitAlias('weekYear', 'gg'); 35211 addUnitAlias('isoWeekYear', 'GG'); 35212 35213 // PRIORITY 35214 35215 addUnitPriority('weekYear', 1); 35216 addUnitPriority('isoWeekYear', 1); 35217 35218 35219 // PARSING 35220 35221 addRegexToken('G', matchSigned); 35222 addRegexToken('g', matchSigned); 35223 addRegexToken('GG', match1to2, match2); 35224 addRegexToken('gg', match1to2, match2); 35225 addRegexToken('GGGG', match1to4, match4); 35226 addRegexToken('gggg', match1to4, match4); 35227 addRegexToken('GGGGG', match1to6, match6); 35228 addRegexToken('ggggg', match1to6, match6); 35229 35230 addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) { 35231 week[token.substr(0, 2)] = toInt(input); 35232 }); 35233 35234 addWeekParseToken(['gg', 'GG'], function (input, week, config, token) { 35235 week[token] = hooks.parseTwoDigitYear(input); 35236 }); 35237 35238 // MOMENTS 35239 35240 function getSetWeekYear (input) { 35241 return getSetWeekYearHelper.call(this, 35242 input, 35243 this.week(), 35244 this.weekday(), 35245 this.localeData()._week.dow, 35246 this.localeData()._week.doy); 35247 } 35248 35249 function getSetISOWeekYear (input) { 35250 return getSetWeekYearHelper.call(this, 35251 input, this.isoWeek(), this.isoWeekday(), 1, 4); 35252 } 35253 35254 function getISOWeeksInYear () { 35255 return weeksInYear(this.year(), 1, 4); 35256 } 35257 35258 function getWeeksInYear () { 35259 var weekInfo = this.localeData()._week; 35260 return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); 35261 } 35262 35263 function getSetWeekYearHelper(input, week, weekday, dow, doy) { 35264 var weeksTarget; 35265 if (input == null) { 35266 return weekOfYear(this, dow, doy).year; 35267 } else { 35268 weeksTarget = weeksInYear(input, dow, doy); 35269 if (week > weeksTarget) { 35270 week = weeksTarget; 35271 } 35272 return setWeekAll.call(this, input, week, weekday, dow, doy); 35273 } 35274 } 35275 35276 function setWeekAll(weekYear, week, weekday, dow, doy) { 35277 var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy), 35278 date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear); 35279 35280 this.year(date.getUTCFullYear()); 35281 this.month(date.getUTCMonth()); 35282 this.date(date.getUTCDate()); 35283 return this; 35284 } 35285 35286 // FORMATTING 35287 35288 addFormatToken('Q', 0, 'Qo', 'quarter'); 35289 35290 // ALIASES 35291 35292 addUnitAlias('quarter', 'Q'); 35293 35294 // PRIORITY 35295 35296 addUnitPriority('quarter', 7); 35297 35298 // PARSING 35299 35300 addRegexToken('Q', match1); 35301 addParseToken('Q', function (input, array) { 35302 array[MONTH] = (toInt(input) - 1) * 3; 35303 }); 35304 35305 // MOMENTS 35306 35307 function getSetQuarter (input) { 35308 return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); 35309 } 35310 35311 // FORMATTING 35312 35313 addFormatToken('D', ['DD', 2], 'Do', 'date'); 35314 35315 // ALIASES 35316 35317 addUnitAlias('date', 'D'); 35318 35319 // PRIORITY 35320 addUnitPriority('date', 9); 35321 35322 // PARSING 35323 35324 addRegexToken('D', match1to2); 35325 addRegexToken('DD', match1to2, match2); 35326 addRegexToken('Do', function (isStrict, locale) { 35327 // TODO: Remove "ordinalParse" fallback in next major release. 35328 return isStrict ? 35329 (locale._dayOfMonthOrdinalParse || locale._ordinalParse) : 35330 locale._dayOfMonthOrdinalParseLenient; 35331 }); 35332 35333 addParseToken(['D', 'DD'], DATE); 35334 addParseToken('Do', function (input, array) { 35335 array[DATE] = toInt(input.match(match1to2)[0]); 35336 }); 35337 35338 // MOMENTS 35339 35340 var getSetDayOfMonth = makeGetSet('Date', true); 35341 35342 // FORMATTING 35343 35344 addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); 35345 35346 // ALIASES 35347 35348 addUnitAlias('dayOfYear', 'DDD'); 35349 35350 // PRIORITY 35351 addUnitPriority('dayOfYear', 4); 35352 35353 // PARSING 35354 35355 addRegexToken('DDD', match1to3); 35356 addRegexToken('DDDD', match3); 35357 addParseToken(['DDD', 'DDDD'], function (input, array, config) { 35358 config._dayOfYear = toInt(input); 35359 }); 35360 35361 // HELPERS 35362 35363 // MOMENTS 35364 35365 function getSetDayOfYear (input) { 35366 var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1; 35367 return input == null ? dayOfYear : this.add((input - dayOfYear), 'd'); 35368 } 35369 35370 // FORMATTING 35371 35372 addFormatToken('m', ['mm', 2], 0, 'minute'); 35373 35374 // ALIASES 35375 35376 addUnitAlias('minute', 'm'); 35377 35378 // PRIORITY 35379 35380 addUnitPriority('minute', 14); 35381 35382 // PARSING 35383 35384 addRegexToken('m', match1to2); 35385 addRegexToken('mm', match1to2, match2); 35386 addParseToken(['m', 'mm'], MINUTE); 35387 35388 // MOMENTS 35389 35390 var getSetMinute = makeGetSet('Minutes', false); 35391 35392 // FORMATTING 35393 35394 addFormatToken('s', ['ss', 2], 0, 'second'); 35395 35396 // ALIASES 35397 35398 addUnitAlias('second', 's'); 35399 35400 // PRIORITY 35401 35402 addUnitPriority('second', 15); 35403 35404 // PARSING 35405 35406 addRegexToken('s', match1to2); 35407 addRegexToken('ss', match1to2, match2); 35408 addParseToken(['s', 'ss'], SECOND); 35409 35410 // MOMENTS 35411 35412 var getSetSecond = makeGetSet('Seconds', false); 35413 35414 // FORMATTING 35415 35416 addFormatToken('S', 0, 0, function () { 35417 return ~~(this.millisecond() / 100); 35418 }); 35419 35420 addFormatToken(0, ['SS', 2], 0, function () { 35421 return ~~(this.millisecond() / 10); 35422 }); 35423 35424 addFormatToken(0, ['SSS', 3], 0, 'millisecond'); 35425 addFormatToken(0, ['SSSS', 4], 0, function () { 35426 return this.millisecond() * 10; 35427 }); 35428 addFormatToken(0, ['SSSSS', 5], 0, function () { 35429 return this.millisecond() * 100; 35430 }); 35431 addFormatToken(0, ['SSSSSS', 6], 0, function () { 35432 return this.millisecond() * 1000; 35433 }); 35434 addFormatToken(0, ['SSSSSSS', 7], 0, function () { 35435 return this.millisecond() * 10000; 35436 }); 35437 addFormatToken(0, ['SSSSSSSS', 8], 0, function () { 35438 return this.millisecond() * 100000; 35439 }); 35440 addFormatToken(0, ['SSSSSSSSS', 9], 0, function () { 35441 return this.millisecond() * 1000000; 35442 }); 35443 35444 35445 // ALIASES 35446 35447 addUnitAlias('millisecond', 'ms'); 35448 35449 // PRIORITY 35450 35451 addUnitPriority('millisecond', 16); 35452 35453 // PARSING 35454 35455 addRegexToken('S', match1to3, match1); 35456 addRegexToken('SS', match1to3, match2); 35457 addRegexToken('SSS', match1to3, match3); 35458 35459 var token; 35460 for (token = 'SSSS'; token.length <= 9; token += 'S') { 35461 addRegexToken(token, matchUnsigned); 35462 } 35463 35464 function parseMs(input, array) { 35465 array[MILLISECOND] = toInt(('0.' + input) * 1000); 35466 } 35467 35468 for (token = 'S'; token.length <= 9; token += 'S') { 35469 addParseToken(token, parseMs); 35470 } 35471 // MOMENTS 35472 35473 var getSetMillisecond = makeGetSet('Milliseconds', false); 35474 35475 // FORMATTING 35476 35477 addFormatToken('z', 0, 0, 'zoneAbbr'); 35478 addFormatToken('zz', 0, 0, 'zoneName'); 35479 35480 // MOMENTS 35481 35482 function getZoneAbbr () { 35483 return this._isUTC ? 'UTC' : ''; 35484 } 35485 35486 function getZoneName () { 35487 return this._isUTC ? 'Coordinated Universal Time' : ''; 35488 } 35489 35490 var proto = Moment.prototype; 35491 35492 proto.add = add; 35493 proto.calendar = calendar$1; 35494 proto.clone = clone; 35495 proto.diff = diff; 35496 proto.endOf = endOf; 35497 proto.format = format; 35498 proto.from = from; 35499 proto.fromNow = fromNow; 35500 proto.to = to; 35501 proto.toNow = toNow; 35502 proto.get = stringGet; 35503 proto.invalidAt = invalidAt; 35504 proto.isAfter = isAfter; 35505 proto.isBefore = isBefore; 35506 proto.isBetween = isBetween; 35507 proto.isSame = isSame; 35508 proto.isSameOrAfter = isSameOrAfter; 35509 proto.isSameOrBefore = isSameOrBefore; 35510 proto.isValid = isValid$2; 35511 proto.lang = lang; 35512 proto.locale = locale; 35513 proto.localeData = localeData; 35514 proto.max = prototypeMax; 35515 proto.min = prototypeMin; 35516 proto.parsingFlags = parsingFlags; 35517 proto.set = stringSet; 35518 proto.startOf = startOf; 35519 proto.subtract = subtract; 35520 proto.toArray = toArray; 35521 proto.toObject = toObject; 35522 proto.toDate = toDate; 35523 proto.toISOString = toISOString; 35524 proto.inspect = inspect; 35525 proto.toJSON = toJSON; 35526 proto.toString = toString; 35527 proto.unix = unix; 35528 proto.valueOf = valueOf; 35529 proto.creationData = creationData; 35530 proto.year = getSetYear; 35531 proto.isLeapYear = getIsLeapYear; 35532 proto.weekYear = getSetWeekYear; 35533 proto.isoWeekYear = getSetISOWeekYear; 35534 proto.quarter = proto.quarters = getSetQuarter; 35535 proto.month = getSetMonth; 35536 proto.daysInMonth = getDaysInMonth; 35537 proto.week = proto.weeks = getSetWeek; 35538 proto.isoWeek = proto.isoWeeks = getSetISOWeek; 35539 proto.weeksInYear = getWeeksInYear; 35540 proto.isoWeeksInYear = getISOWeeksInYear; 35541 proto.date = getSetDayOfMonth; 35542 proto.day = proto.days = getSetDayOfWeek; 35543 proto.weekday = getSetLocaleDayOfWeek; 35544 proto.isoWeekday = getSetISODayOfWeek; 35545 proto.dayOfYear = getSetDayOfYear; 35546 proto.hour = proto.hours = getSetHour; 35547 proto.minute = proto.minutes = getSetMinute; 35548 proto.second = proto.seconds = getSetSecond; 35549 proto.millisecond = proto.milliseconds = getSetMillisecond; 35550 proto.utcOffset = getSetOffset; 35551 proto.utc = setOffsetToUTC; 35552 proto.local = setOffsetToLocal; 35553 proto.parseZone = setOffsetToParsedOffset; 35554 proto.hasAlignedHourOffset = hasAlignedHourOffset; 35555 proto.isDST = isDaylightSavingTime; 35556 proto.isLocal = isLocal; 35557 proto.isUtcOffset = isUtcOffset; 35558 proto.isUtc = isUtc; 35559 proto.isUTC = isUtc; 35560 proto.zoneAbbr = getZoneAbbr; 35561 proto.zoneName = getZoneName; 35562 proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth); 35563 proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth); 35564 proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear); 35565 proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone); 35566 proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted); 35567 35568 function createUnix (input) { 35569 return createLocal(input * 1000); 35570 } 35571 35572 function createInZone () { 35573 return createLocal.apply(null, arguments).parseZone(); 35574 } 35575 35576 function preParsePostFormat (string) { 35577 return string; 35578 } 35579 35580 var proto$1 = Locale.prototype; 35581 35582 proto$1.calendar = calendar; 35583 proto$1.longDateFormat = longDateFormat; 35584 proto$1.invalidDate = invalidDate; 35585 proto$1.ordinal = ordinal; 35586 proto$1.preparse = preParsePostFormat; 35587 proto$1.postformat = preParsePostFormat; 35588 proto$1.relativeTime = relativeTime; 35589 proto$1.pastFuture = pastFuture; 35590 proto$1.set = set; 35591 35592 proto$1.months = localeMonths; 35593 proto$1.monthsShort = localeMonthsShort; 35594 proto$1.monthsParse = localeMonthsParse; 35595 proto$1.monthsRegex = monthsRegex; 35596 proto$1.monthsShortRegex = monthsShortRegex; 35597 proto$1.week = localeWeek; 35598 proto$1.firstDayOfYear = localeFirstDayOfYear; 35599 proto$1.firstDayOfWeek = localeFirstDayOfWeek; 35600 35601 proto$1.weekdays = localeWeekdays; 35602 proto$1.weekdaysMin = localeWeekdaysMin; 35603 proto$1.weekdaysShort = localeWeekdaysShort; 35604 proto$1.weekdaysParse = localeWeekdaysParse; 35605 35606 proto$1.weekdaysRegex = weekdaysRegex; 35607 proto$1.weekdaysShortRegex = weekdaysShortRegex; 35608 proto$1.weekdaysMinRegex = weekdaysMinRegex; 35609 35610 proto$1.isPM = localeIsPM; 35611 proto$1.meridiem = localeMeridiem; 35612 35613 function get$1 (format, index, field, setter) { 35614 var locale = getLocale(); 35615 var utc = createUTC().set(setter, index); 35616 return locale[field](utc, format); 35617 } 35618 35619 function listMonthsImpl (format, index, field) { 35620 if (isNumber(format)) { 35621 index = format; 35622 format = undefined; 35623 } 35624 35625 format = format || ''; 35626 35627 if (index != null) { 35628 return get$1(format, index, field, 'month'); 35629 } 35630 35631 var i; 35632 var out = []; 35633 for (i = 0; i < 12; i++) { 35634 out[i] = get$1(format, i, field, 'month'); 35635 } 35636 return out; 35637 } 35638 35639 // () 35640 // (5) 35641 // (fmt, 5) 35642 // (fmt) 35643 // (true) 35644 // (true, 5) 35645 // (true, fmt, 5) 35646 // (true, fmt) 35647 function listWeekdaysImpl (localeSorted, format, index, field) { 35648 if (typeof localeSorted === 'boolean') { 35649 if (isNumber(format)) { 35650 index = format; 35651 format = undefined; 35652 } 35653 35654 format = format || ''; 35655 } else { 35656 format = localeSorted; 35657 index = format; 35658 localeSorted = false; 35659 35660 if (isNumber(format)) { 35661 index = format; 35662 format = undefined; 35663 } 35664 35665 format = format || ''; 35666 } 35667 35668 var locale = getLocale(), 35669 shift = localeSorted ? locale._week.dow : 0; 35670 35671 if (index != null) { 35672 return get$1(format, (index + shift) % 7, field, 'day'); 35673 } 35674 35675 var i; 35676 var out = []; 35677 for (i = 0; i < 7; i++) { 35678 out[i] = get$1(format, (i + shift) % 7, field, 'day'); 35679 } 35680 return out; 35681 } 35682 35683 function listMonths (format, index) { 35684 return listMonthsImpl(format, index, 'months'); 35685 } 35686 35687 function listMonthsShort (format, index) { 35688 return listMonthsImpl(format, index, 'monthsShort'); 35689 } 35690 35691 function listWeekdays (localeSorted, format, index) { 35692 return listWeekdaysImpl(localeSorted, format, index, 'weekdays'); 35693 } 35694 35695 function listWeekdaysShort (localeSorted, format, index) { 35696 return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort'); 35697 } 35698 35699 function listWeekdaysMin (localeSorted, format, index) { 35700 return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin'); 35701 } 35702 35703 getSetGlobalLocale('en', { 35704 dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, 35705 ordinal : function (number) { 35706 var b = number % 10, 35707 output = (toInt(number % 100 / 10) === 1) ? 'th' : 35708 (b === 1) ? 'st' : 35709 (b === 2) ? 'nd' : 35710 (b === 3) ? 'rd' : 'th'; 35711 return number + output; 35712 } 35713 }); 35714 35715 // Side effect imports 35716 35717 hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale); 35718 hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale); 35719 35720 var mathAbs = Math.abs; 35721 35722 function abs () { 35723 var data = this._data; 35724 35725 this._milliseconds = mathAbs(this._milliseconds); 35726 this._days = mathAbs(this._days); 35727 this._months = mathAbs(this._months); 35728 35729 data.milliseconds = mathAbs(data.milliseconds); 35730 data.seconds = mathAbs(data.seconds); 35731 data.minutes = mathAbs(data.minutes); 35732 data.hours = mathAbs(data.hours); 35733 data.months = mathAbs(data.months); 35734 data.years = mathAbs(data.years); 35735 35736 return this; 35737 } 35738 35739 function addSubtract$1 (duration, input, value, direction) { 35740 var other = createDuration(input, value); 35741 35742 duration._milliseconds += direction * other._milliseconds; 35743 duration._days += direction * other._days; 35744 duration._months += direction * other._months; 35745 35746 return duration._bubble(); 35747 } 35748 35749 // supports only 2.0-style add(1, 's') or add(duration) 35750 function add$1 (input, value) { 35751 return addSubtract$1(this, input, value, 1); 35752 } 35753 35754 // supports only 2.0-style subtract(1, 's') or subtract(duration) 35755 function subtract$1 (input, value) { 35756 return addSubtract$1(this, input, value, -1); 35757 } 35758 35759 function absCeil (number) { 35760 if (number < 0) { 35761 return Math.floor(number); 35762 } else { 35763 return Math.ceil(number); 35764 } 35765 } 35766 35767 function bubble () { 35768 var milliseconds = this._milliseconds; 35769 var days = this._days; 35770 var months = this._months; 35771 var data = this._data; 35772 var seconds, minutes, hours, years, monthsFromDays; 35773 35774 // if we have a mix of positive and negative values, bubble down first 35775 // check: https://github.com/moment/moment/issues/2166 35776 if (!((milliseconds >= 0 && days >= 0 && months >= 0) || 35777 (milliseconds <= 0 && days <= 0 && months <= 0))) { 35778 milliseconds += absCeil(monthsToDays(months) + days) * 864e5; 35779 days = 0; 35780 months = 0; 35781 } 35782 35783 // The following code bubbles up values, see the tests for 35784 // examples of what that means. 35785 data.milliseconds = milliseconds % 1000; 35786 35787 seconds = absFloor(milliseconds / 1000); 35788 data.seconds = seconds % 60; 35789 35790 minutes = absFloor(seconds / 60); 35791 data.minutes = minutes % 60; 35792 35793 hours = absFloor(minutes / 60); 35794 data.hours = hours % 24; 35795 35796 days += absFloor(hours / 24); 35797 35798 // convert days to months 35799 monthsFromDays = absFloor(daysToMonths(days)); 35800 months += monthsFromDays; 35801 days -= absCeil(monthsToDays(monthsFromDays)); 35802 35803 // 12 months -> 1 year 35804 years = absFloor(months / 12); 35805 months %= 12; 35806 35807 data.days = days; 35808 data.months = months; 35809 data.years = years; 35810 35811 return this; 35812 } 35813 35814 function daysToMonths (days) { 35815 // 400 years have 146097 days (taking into account leap year rules) 35816 // 400 years have 12 months === 4800 35817 return days * 4800 / 146097; 35818 } 35819 35820 function monthsToDays (months) { 35821 // the reverse of daysToMonths 35822 return months * 146097 / 4800; 35823 } 35824 35825 function as (units) { 35826 if (!this.isValid()) { 35827 return NaN; 35828 } 35829 var days; 35830 var months; 35831 var milliseconds = this._milliseconds; 35832 35833 units = normalizeUnits(units); 35834 35835 if (units === 'month' || units === 'quarter' || units === 'year') { 35836 days = this._days + milliseconds / 864e5; 35837 months = this._months + daysToMonths(days); 35838 switch (units) { 35839 case 'month': return months; 35840 case 'quarter': return months / 3; 35841 case 'year': return months / 12; 35842 } 35843 } else { 35844 // handle milliseconds separately because of floating point math errors (issue #1867) 35845 days = this._days + Math.round(monthsToDays(this._months)); 35846 switch (units) { 35847 case 'week' : return days / 7 + milliseconds / 6048e5; 35848 case 'day' : return days + milliseconds / 864e5; 35849 case 'hour' : return days * 24 + milliseconds / 36e5; 35850 case 'minute' : return days * 1440 + milliseconds / 6e4; 35851 case 'second' : return days * 86400 + milliseconds / 1000; 35852 // Math.floor prevents floating point math errors here 35853 case 'millisecond': return Math.floor(days * 864e5) + milliseconds; 35854 default: throw new Error('Unknown unit ' + units); 35855 } 35856 } 35857 } 35858 35859 // TODO: Use this.as('ms')? 35860 function valueOf$1 () { 35861 if (!this.isValid()) { 35862 return NaN; 35863 } 35864 return ( 35865 this._milliseconds + 35866 this._days * 864e5 + 35867 (this._months % 12) * 2592e6 + 35868 toInt(this._months / 12) * 31536e6 35869 ); 35870 } 35871 35872 function makeAs (alias) { 35873 return function () { 35874 return this.as(alias); 35875 }; 35876 } 35877 35878 var asMilliseconds = makeAs('ms'); 35879 var asSeconds = makeAs('s'); 35880 var asMinutes = makeAs('m'); 35881 var asHours = makeAs('h'); 35882 var asDays = makeAs('d'); 35883 var asWeeks = makeAs('w'); 35884 var asMonths = makeAs('M'); 35885 var asQuarters = makeAs('Q'); 35886 var asYears = makeAs('y'); 35887 35888 function clone$1 () { 35889 return createDuration(this); 35890 } 35891 35892 function get$2 (units) { 35893 units = normalizeUnits(units); 35894 return this.isValid() ? this[units + 's']() : NaN; 35895 } 35896 35897 function makeGetter(name) { 35898 return function () { 35899 return this.isValid() ? this._data[name] : NaN; 35900 }; 35901 } 35902 35903 var milliseconds = makeGetter('milliseconds'); 35904 var seconds = makeGetter('seconds'); 35905 var minutes = makeGetter('minutes'); 35906 var hours = makeGetter('hours'); 35907 var days = makeGetter('days'); 35908 var months = makeGetter('months'); 35909 var years = makeGetter('years'); 35910 35911 function weeks () { 35912 return absFloor(this.days() / 7); 35913 } 35914 35915 var round = Math.round; 35916 var thresholds = { 35917 ss: 44, // a few seconds to seconds 35918 s : 45, // seconds to minute 35919 m : 45, // minutes to hour 35920 h : 22, // hours to day 35921 d : 26, // days to month 35922 M : 11 // months to year 35923 }; 35924 35925 // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize 35926 function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) { 35927 return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); 35928 } 35929 35930 function relativeTime$1 (posNegDuration, withoutSuffix, locale) { 35931 var duration = createDuration(posNegDuration).abs(); 35932 var seconds = round(duration.as('s')); 35933 var minutes = round(duration.as('m')); 35934 var hours = round(duration.as('h')); 35935 var days = round(duration.as('d')); 35936 var months = round(duration.as('M')); 35937 var years = round(duration.as('y')); 35938 35939 var a = seconds <= thresholds.ss && ['s', seconds] || 35940 seconds < thresholds.s && ['ss', seconds] || 35941 minutes <= 1 && ['m'] || 35942 minutes < thresholds.m && ['mm', minutes] || 35943 hours <= 1 && ['h'] || 35944 hours < thresholds.h && ['hh', hours] || 35945 days <= 1 && ['d'] || 35946 days < thresholds.d && ['dd', days] || 35947 months <= 1 && ['M'] || 35948 months < thresholds.M && ['MM', months] || 35949 years <= 1 && ['y'] || ['yy', years]; 35950 35951 a[2] = withoutSuffix; 35952 a[3] = +posNegDuration > 0; 35953 a[4] = locale; 35954 return substituteTimeAgo.apply(null, a); 35955 } 35956 35957 // This function allows you to set the rounding function for relative time strings 35958 function getSetRelativeTimeRounding (roundingFunction) { 35959 if (roundingFunction === undefined) { 35960 return round; 35961 } 35962 if (typeof(roundingFunction) === 'function') { 35963 round = roundingFunction; 35964 return true; 35965 } 35966 return false; 35967 } 35968 35969 // This function allows you to set a threshold for relative time strings 35970 function getSetRelativeTimeThreshold (threshold, limit) { 35971 if (thresholds[threshold] === undefined) { 35972 return false; 35973 } 35974 if (limit === undefined) { 35975 return thresholds[threshold]; 35976 } 35977 thresholds[threshold] = limit; 35978 if (threshold === 's') { 35979 thresholds.ss = limit - 1; 35980 } 35981 return true; 35982 } 35983 35984 function humanize (withSuffix) { 35985 if (!this.isValid()) { 35986 return this.localeData().invalidDate(); 35987 } 35988 35989 var locale = this.localeData(); 35990 var output = relativeTime$1(this, !withSuffix, locale); 35991 35992 if (withSuffix) { 35993 output = locale.pastFuture(+this, output); 35994 } 35995 35996 return locale.postformat(output); 35997 } 35998 35999 var abs$1 = Math.abs; 36000 36001 function sign(x) { 36002 return ((x > 0) - (x < 0)) || +x; 36003 } 36004 36005 function toISOString$1() { 36006 // for ISO strings we do not use the normal bubbling rules: 36007 // * milliseconds bubble up until they become hours 36008 // * days do not bubble at all 36009 // * months bubble up until they become years 36010 // This is because there is no context-free conversion between hours and days 36011 // (think of clock changes) 36012 // and also not between days and months (28-31 days per month) 36013 if (!this.isValid()) { 36014 return this.localeData().invalidDate(); 36015 } 36016 36017 var seconds = abs$1(this._milliseconds) / 1000; 36018 var days = abs$1(this._days); 36019 var months = abs$1(this._months); 36020 var minutes, hours, years; 36021 36022 // 3600 seconds -> 60 minutes -> 1 hour 36023 minutes = absFloor(seconds / 60); 36024 hours = absFloor(minutes / 60); 36025 seconds %= 60; 36026 minutes %= 60; 36027 36028 // 12 months -> 1 year 36029 years = absFloor(months / 12); 36030 months %= 12; 36031 36032 36033 // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js 36034 var Y = years; 36035 var M = months; 36036 var D = days; 36037 var h = hours; 36038 var m = minutes; 36039 var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : ''; 36040 var total = this.asSeconds(); 36041 36042 if (!total) { 36043 // this is the same as C#'s (Noda) and python (isodate)... 36044 // but not other JS (goog.date) 36045 return 'P0D'; 36046 } 36047 36048 var totalSign = total < 0 ? '-' : ''; 36049 var ymSign = sign(this._months) !== sign(total) ? '-' : ''; 36050 var daysSign = sign(this._days) !== sign(total) ? '-' : ''; 36051 var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : ''; 36052 36053 return totalSign + 'P' + 36054 (Y ? ymSign + Y + 'Y' : '') + 36055 (M ? ymSign + M + 'M' : '') + 36056 (D ? daysSign + D + 'D' : '') + 36057 ((h || m || s) ? 'T' : '') + 36058 (h ? hmsSign + h + 'H' : '') + 36059 (m ? hmsSign + m + 'M' : '') + 36060 (s ? hmsSign + s + 'S' : ''); 36061 } 36062 36063 var proto$2 = Duration.prototype; 36064 36065 proto$2.isValid = isValid$1; 36066 proto$2.abs = abs; 36067 proto$2.add = add$1; 36068 proto$2.subtract = subtract$1; 36069 proto$2.as = as; 36070 proto$2.asMilliseconds = asMilliseconds; 36071 proto$2.asSeconds = asSeconds; 36072 proto$2.asMinutes = asMinutes; 36073 proto$2.asHours = asHours; 36074 proto$2.asDays = asDays; 36075 proto$2.asWeeks = asWeeks; 36076 proto$2.asMonths = asMonths; 36077 proto$2.asQuarters = asQuarters; 36078 proto$2.asYears = asYears; 36079 proto$2.valueOf = valueOf$1; 36080 proto$2._bubble = bubble; 36081 proto$2.clone = clone$1; 36082 proto$2.get = get$2; 36083 proto$2.milliseconds = milliseconds; 36084 proto$2.seconds = seconds; 36085 proto$2.minutes = minutes; 36086 proto$2.hours = hours; 36087 proto$2.days = days; 36088 proto$2.weeks = weeks; 36089 proto$2.months = months; 36090 proto$2.years = years; 36091 proto$2.humanize = humanize; 36092 proto$2.toISOString = toISOString$1; 36093 proto$2.toString = toISOString$1; 36094 proto$2.toJSON = toISOString$1; 36095 proto$2.locale = locale; 36096 proto$2.localeData = localeData; 36097 36098 proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1); 36099 proto$2.lang = lang; 36100 36101 // Side effect imports 36102 36103 // FORMATTING 36104 36105 addFormatToken('X', 0, 0, 'unix'); 36106 addFormatToken('x', 0, 0, 'valueOf'); 36107 36108 // PARSING 36109 36110 addRegexToken('x', matchSigned); 36111 addRegexToken('X', matchTimestamp); 36112 addParseToken('X', function (input, array, config) { 36113 config._d = new Date(parseFloat(input, 10) * 1000); 36114 }); 36115 addParseToken('x', function (input, array, config) { 36116 config._d = new Date(toInt(input)); 36117 }); 36118 36119 // Side effect imports 36120 36121 36122 hooks.version = '2.24.0'; 36123 36124 setHookCallback(createLocal); 36125 36126 hooks.fn = proto; 36127 hooks.min = min; 36128 hooks.max = max; 36129 hooks.now = now; 36130 hooks.utc = createUTC; 36131 hooks.unix = createUnix; 36132 hooks.months = listMonths; 36133 hooks.isDate = isDate; 36134 hooks.locale = getSetGlobalLocale; 36135 hooks.invalid = createInvalid; 36136 hooks.duration = createDuration; 36137 hooks.isMoment = isMoment; 36138 hooks.weekdays = listWeekdays; 36139 hooks.parseZone = createInZone; 36140 hooks.localeData = getLocale; 36141 hooks.isDuration = isDuration; 36142 hooks.monthsShort = listMonthsShort; 36143 hooks.weekdaysMin = listWeekdaysMin; 36144 hooks.defineLocale = defineLocale; 36145 hooks.updateLocale = updateLocale; 36146 hooks.locales = listLocales; 36147 hooks.weekdaysShort = listWeekdaysShort; 36148 hooks.normalizeUnits = normalizeUnits; 36149 hooks.relativeTimeRounding = getSetRelativeTimeRounding; 36150 hooks.relativeTimeThreshold = getSetRelativeTimeThreshold; 36151 hooks.calendarFormat = getCalendarFormat; 36152 hooks.prototype = proto; 36153 36154 // currently HTML5 input type only supports 24-hour formats 36155 hooks.HTML5_FMT = { 36156 DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm', // <input type="datetime-local" /> 36157 DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', // <input type="datetime-local" step="1" /> 36158 DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', // <input type="datetime-local" step="0.001" /> 36159 DATE: 'YYYY-MM-DD', // <input type="date" /> 36160 TIME: 'HH:mm', // <input type="time" /> 36161 TIME_SECONDS: 'HH:mm:ss', // <input type="time" step="1" /> 36162 TIME_MS: 'HH:mm:ss.SSS', // <input type="time" step="0.001" /> 36163 WEEK: 'GGGG-[W]WW', // <input type="week" /> 36164 MONTH: 'YYYY-MM' // <input type="month" /> 36165 }; 36166 36167 return hooks; 36168 36169}))); 36170
vendor: 2,042 bytes, lines 36171-36216
36171},{}],15:[function(require,module,exports){ 36172(function (global){ 36173/**! 36174 * @fileOverview Kickass library to create and place poppers near their reference elements. 36175 * @version 1.16.0 36176 * @license 36177 * Copyright (c) 2016 Federico Zivolo and contributors 36178 * 36179 * Permission is hereby granted, free of charge, to any person obtaining a copy 36180 * of this software and associated documentation files (the "Software"), to deal 36181 * in the Software without restriction, including without limitation the rights 36182 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 36183 * copies of the Software, and to permit persons to whom the Software is 36184 * furnished to do so, subject to the following conditions: 36185 * 36186 * The above copyright notice and this permission notice shall be included in all 36187 * copies or substantial portions of the Software. 36188 * 36189 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 36190 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 36191 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 36192 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 36193 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36194 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 36195 * SOFTWARE. 36196 */ 36197(function (global, factory) { 36198 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 36199 typeof define === 'function' && define.amd ? define(factory) : 36200 (global.Popper = factory()); 36201}(this, (function () { 'use strict'; 36202 36203var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && typeof navigator !== 'undefined'; 36204 36205var timeoutDuration = function () { 36206 var longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox']; 36207 for (var i = 0; i < longerTimeoutBrowsers.length; i += 1) { 36208 if (isBrowser && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) { 36209 return 1; 36210 } 36211 } 36212 return 0; 36213}(); 36214 36215function microtaskDebounce(fn) { 36216 var called = false;
vendor: 3,141 bytes, lines 36217-36342
36217 return function () { 36218 if (called) { 36219 return; 36220 } 36221 called = true; 36222 window.Promise.resolve().then(function () { 36223 called = false; 36224 fn(); 36225 }); 36226 }; 36227} 36228 36229function taskDebounce(fn) { 36230 var scheduled = false; 36231 return function () { 36232 if (!scheduled) { 36233 scheduled = true; 36234 setTimeout(function () { 36235 scheduled = false; 36236 fn(); 36237 }, timeoutDuration); 36238 } 36239 }; 36240} 36241 36242var supportsMicroTasks = isBrowser && window.Promise; 36243 36244/** 36245* Create a debounced version of a method, that's asynchronously deferred 36246* but called in the minimum time possible. 36247* 36248* @method 36249* @memberof Popper.Utils 36250* @argument {Function} fn 36251* @returns {Function} 36252*/ 36253var debounce = supportsMicroTasks ? microtaskDebounce : taskDebounce; 36254 36255/** 36256 * Check if the given variable is a function 36257 * @method 36258 * @memberof Popper.Utils 36259 * @argument {Any} functionToCheck - variable to check 36260 * @returns {Boolean} answer to: is a function? 36261 */ 36262function isFunction(functionToCheck) { 36263 var getType = {}; 36264 return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]'; 36265} 36266 36267/** 36268 * Get CSS computed property of the given element 36269 * @method 36270 * @memberof Popper.Utils 36271 * @argument {Eement} element 36272 * @argument {String} property 36273 */ 36274function getStyleComputedProperty(element, property) { 36275 if (element.nodeType !== 1) { 36276 return []; 36277 } 36278 // NOTE: 1 DOM access here 36279 var window = element.ownerDocument.defaultView; 36280 var css = window.getComputedStyle(element, null); 36281 return property ? css[property] : css; 36282} 36283 36284/** 36285 * Returns the parentNode or the host of the element 36286 * @method 36287 * @memberof Popper.Utils 36288 * @argument {Element} element 36289 * @returns {Element} parent 36290 */ 36291function getParentNode(element) { 36292 if (element.nodeName === 'HTML') { 36293 return element; 36294 } 36295 return element.parentNode || element.host; 36296} 36297 36298/** 36299 * Returns the scrolling parent of the given element 36300 * @method 36301 * @memberof Popper.Utils 36302 * @argument {Element} element 36303 * @returns {Element} scroll parent 36304 */ 36305function getScrollParent(element) { 36306 // Return body, `getScroll` will take care to get the correct `scrollTop` from it 36307 if (!element) { 36308 return document.body; 36309 } 36310 36311 switch (element.nodeName) { 36312 case 'HTML': 36313 case 'BODY': 36314 return element.ownerDocument.body; 36315 case '#document': 36316 return element.body; 36317 } 36318 36319 // Firefox want us to check `-x` and `-y` variations as well 36320 36321 var _getStyleComputedProp = getStyleComputedProperty(element), 36322 overflow = _getStyleComputedProp.overflow, 36323 overflowX = _getStyleComputedProp.overflowX, 36324 overflowY = _getStyleComputedProp.overflowY; 36325 36326 if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) { 36327 return element; 36328 } 36329 36330 return getScrollParent(getParentNode(element)); 36331} 36332 36333/** 36334 * Returns the reference node of the reference object, or the reference object itself. 36335 * @method 36336 * @memberof Popper.Utils 36337 * @param {Element|Object} reference - the reference element (the popper will be relative to this) 36338 * @returns {Element} parent 36339 */ 36340function getReferenceNode(reference) { 36341 return reference && reference.referenceNode ? reference.referenceNode : reference; 36342}
vendor: 3,047 bytes, lines 36342-36448
36342 36343 36344var isIE11 = isBrowser && !!(window.MSInputMethodContext && document.documentMode); 36345var isIE10 = isBrowser && /MSIE 10/.test(navigator.userAgent); 36346 36347/** 36348 * Determines if the browser is Internet Explorer 36349 * @method 36350 * @memberof Popper.Utils 36351 * @param {Number} version to check 36352 * @returns {Boolean} isIE 36353 */ 36354function isIE(version) { 36355 if (version === 11) { 36356 return isIE11; 36357 } 36358 if (version === 10) { 36359 return isIE10; 36360 } 36361 return isIE11 || isIE10; 36362} 36363 36364/** 36365 * Returns the offset parent of the given element 36366 * @method 36367 * @memberof Popper.Utils 36368 * @argument {Element} element 36369 * @returns {Element} offset parent 36370 */ 36371function getOffsetParent(element) { 36372 if (!element) { 36373 return document.documentElement; 36374 } 36375 36376 var noOffsetParent = isIE(10) ? document.body : null; 36377 36378 // NOTE: 1 DOM access here 36379 var offsetParent = element.offsetParent || null; 36380 // Skip hidden elements which don't have an offsetParent 36381 while (offsetParent === noOffsetParent && element.nextElementSibling) { 36382 offsetParent = (element = element.nextElementSibling).offsetParent; 36383 } 36384 36385 var nodeName = offsetParent && offsetParent.nodeName; 36386 36387 if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') { 36388 return element ? element.ownerDocument.documentElement : document.documentElement; 36389 } 36390 36391 // .offsetParent will return the closest TH, TD or TABLE in case 36392 // no offsetParent is present, I hate this job... 36393 if (['TH', 'TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && getStyleComputedProperty(offsetParent, 'position') === 'static') { 36394 return getOffsetParent(offsetParent); 36395 } 36396 36397 return offsetParent; 36398} 36399 36400function isOffsetContainer(element) { 36401 var nodeName = element.nodeName; 36402 36403 if (nodeName === 'BODY') { 36404 return false; 36405 } 36406 return nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element; 36407} 36408 36409/** 36410 * Finds the root node (document, shadowDOM root) of the given element 36411 * @method 36412 * @memberof Popper.Utils 36413 * @argument {Element} node 36414 * @returns {Element} root node 36415 */ 36416function getRoot(node) { 36417 if (node.parentNode !== null) { 36418 return getRoot(node.parentNode); 36419 } 36420 36421 return node; 36422} 36423 36424/** 36425 * Finds the offset parent common to the two provided nodes 36426 * @method 36427 * @memberof Popper.Utils 36428 * @argument {Element} element1 36429 * @argument {Element} element2 36430 * @returns {Element} common offset parent 36431 */ 36432function findCommonOffsetParent(element1, element2) { 36433 // This check is needed to avoid errors in case one of the elements isn't defined for any reason 36434 if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) { 36435 return document.documentElement; 36436 } 36437 36438 // Here we make sure to give as "start" the element that comes first in the DOM 36439 var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING; 36440 var start = order ? element1 : element2; 36441 var end = order ? element2 : element1; 36442 36443 // Get common ancestor container 36444 var range = document.createRange(); 36445 range.setStart(start, 0); 36446 range.setEnd(end, 0); 36447 var commonAncestorContainer = range.commonAncestorContainer; 36448
vendor: 6,175 bytes, lines 36449-36652
36449 // Both nodes are inside #document 36450 36451 if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) { 36452 if (isOffsetContainer(commonAncestorContainer)) { 36453 return commonAncestorContainer; 36454 } 36455 36456 return getOffsetParent(commonAncestorContainer); 36457 } 36458 36459 // one of the nodes is inside shadowDOM, find which one 36460 var element1root = getRoot(element1); 36461 if (element1root.host) { 36462 return findCommonOffsetParent(element1root.host, element2); 36463 } else { 36464 return findCommonOffsetParent(element1, getRoot(element2).host); 36465 } 36466} 36467 36468/** 36469 * Gets the scroll value of the given element in the given side (top and left) 36470 * @method 36471 * @memberof Popper.Utils 36472 * @argument {Element} element 36473 * @argument {String} side `top` or `left` 36474 * @returns {number} amount of scrolled pixels 36475 */ 36476function getScroll(element) { 36477 var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top'; 36478 36479 var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft'; 36480 var nodeName = element.nodeName; 36481 36482 if (nodeName === 'BODY' || nodeName === 'HTML') { 36483 var html = element.ownerDocument.documentElement; 36484 var scrollingElement = element.ownerDocument.scrollingElement || html; 36485 return scrollingElement[upperSide]; 36486 } 36487 36488 return element[upperSide]; 36489} 36490 36491/* 36492 * Sum or subtract the element scroll values (left and top) from a given rect object 36493 * @method 36494 * @memberof Popper.Utils 36495 * @param {Object} rect - Rect object you want to change 36496 * @param {HTMLElement} element - The element from the function reads the scroll values 36497 * @param {Boolean} subtract - set to true if you want to subtract the scroll values 36498 * @return {Object} rect - The modifier rect object 36499 */ 36500function includeScroll(rect, element) { 36501 var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; 36502 36503 var scrollTop = getScroll(element, 'top'); 36504 var scrollLeft = getScroll(element, 'left'); 36505 var modifier = subtract ? -1 : 1; 36506 rect.top += scrollTop * modifier; 36507 rect.bottom += scrollTop * modifier; 36508 rect.left += scrollLeft * modifier; 36509 rect.right += scrollLeft * modifier; 36510 return rect; 36511} 36512 36513/* 36514 * Helper to detect borders of a given element 36515 * @method 36516 * @memberof Popper.Utils 36517 * @param {CSSStyleDeclaration} styles 36518 * Result of `getStyleComputedProperty` on the given element 36519 * @param {String} axis - `x` or `y` 36520 * @return {number} borders - The borders size of the given axis 36521 */ 36522 36523function getBordersSize(styles, axis) { 36524 var sideA = axis === 'x' ? 'Left' : 'Top'; 36525 var sideB = sideA === 'Left' ? 'Right' : 'Bottom'; 36526 36527 return parseFloat(styles['border' + sideA + 'Width'], 10) + parseFloat(styles['border' + sideB + 'Width'], 10); 36528} 36529 36530function getSize(axis, body, html, computedStyle) { 36531 return Math.max(body['offset' + axis], body['scroll' + axis], html['client' + axis], html['offset' + axis], html['scroll' + axis], isIE(10) ? parseInt(html['offset' + axis]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Top' : 'Left')]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Bottom' : 'Right')]) : 0); 36532} 36533 36534function getWindowSizes(document) { 36535 var body = document.body; 36536 var html = document.documentElement; 36537 var computedStyle = isIE(10) && getComputedStyle(html); 36538 36539 return { 36540 height: getSize('Height', body, html, computedStyle), 36541 width: getSize('Width', body, html, computedStyle) 36542 }; 36543} 36544 36545var classCallCheck = function (instance, Constructor) { 36546 if (!(instance instanceof Constructor)) { 36547 throw new TypeError("Cannot call a class as a function"); 36548 } 36549}; 36550 36551var createClass = function () { 36552 function defineProperties(target, props) { 36553 for (var i = 0; i < props.length; i++) { 36554 var descriptor = props[i]; 36555 descriptor.enumerable = descriptor.enumerable || false; 36556 descriptor.configurable = true; 36557 if ("value" in descriptor) descriptor.writable = true; 36558 Object.defineProperty(target, descriptor.key, descriptor); 36559 } 36560 } 36561 36562 return function (Constructor, protoProps, staticProps) { 36563 if (protoProps) defineProperties(Constructor.prototype, protoProps); 36564 if (staticProps) defineProperties(Constructor, staticProps); 36565 return Constructor; 36566 }; 36567}(); 36568 36569 36570 36571 36572 36573var defineProperty = function (obj, key, value) { 36574 if (key in obj) { 36575 Object.defineProperty(obj, key, { 36576 value: value, 36577 enumerable: true, 36578 configurable: true, 36579 writable: true 36580 }); 36581 } else { 36582 obj[key] = value; 36583 } 36584 36585 return obj; 36586}; 36587 36588var _extends = Object.assign || function (target) { 36589 for (var i = 1; i < arguments.length; i++) { 36590 var source = arguments[i]; 36591 36592 for (var key in source) { 36593 if (Object.prototype.hasOwnProperty.call(source, key)) { 36594 target[key] = source[key]; 36595 } 36596 } 36597 } 36598 36599 return target; 36600}; 36601 36602/** 36603 * Given element offsets, generate an output similar to getBoundingClientRect 36604 * @method 36605 * @memberof Popper.Utils 36606 * @argument {Object} offsets 36607 * @returns {Object} ClientRect like output 36608 */ 36609function getClientRect(offsets) { 36610 return _extends({}, offsets, { 36611 right: offsets.left + offsets.width, 36612 bottom: offsets.top + offsets.height 36613 }); 36614} 36615 36616/** 36617 * Get bounding client rect of given element 36618 * @method 36619 * @memberof Popper.Utils 36620 * @param {HTMLElement} element 36621 * @return {Object} client rect 36622 */ 36623function getBoundingClientRect(element) { 36624 var rect = {}; 36625 36626 // IE10 10 FIX: Please, don't ask, the element isn't 36627 // considered in DOM in some circumstances... 36628 // This isn't reproducible in IE10 compatibility mode of IE11 36629 try { 36630 if (isIE(10)) { 36631 rect = element.getBoundingClientRect(); 36632 var scrollTop = getScroll(element, 'top'); 36633 var scrollLeft = getScroll(element, 'left'); 36634 rect.top += scrollTop; 36635 rect.left += scrollLeft; 36636 rect.bottom += scrollTop; 36637 rect.right += scrollLeft; 36638 } else { 36639 rect = element.getBoundingClientRect(); 36640 } 36641 } catch (e) {} 36642 36643 var result = { 36644 left: rect.left, 36645 top: rect.top, 36646 width: rect.right - rect.left, 36647 height: rect.bottom - rect.top 36648 }; 36649 36650 // subtract scrollbar size from sizes 36651 var sizes = element.nodeName === 'HTML' ? getWindowSizes(element.ownerDocument) : {}; 36652 var width = sizes.width || element.clientWidth || result.
vendor: 2,119 bytes, lines 36652-36705
36652width; 36653 var height = sizes.height || element.clientHeight || result.height; 36654 36655 var horizScrollbar = element.offsetWidth - width; 36656 var vertScrollbar = element.offsetHeight - height; 36657 36658 // if an hypothetical scrollbar is detected, we must be sure it's not a `border` 36659 // we make this check conditional for performance reasons 36660 if (horizScrollbar || vertScrollbar) { 36661 var styles = getStyleComputedProperty(element); 36662 horizScrollbar -= getBordersSize(styles, 'x'); 36663 vertScrollbar -= getBordersSize(styles, 'y'); 36664 36665 result.width -= horizScrollbar; 36666 result.height -= vertScrollbar; 36667 } 36668 36669 return getClientRect(result); 36670} 36671 36672function getOffsetRectRelativeToArbitraryNode(children, parent) { 36673 var fixedPosition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; 36674 36675 var isIE10 = isIE(10); 36676 var isHTML = parent.nodeName === 'HTML'; 36677 var childrenRect = getBoundingClientRect(children); 36678 var parentRect = getBoundingClientRect(parent); 36679 var scrollParent = getScrollParent(children); 36680 36681 var styles = getStyleComputedProperty(parent); 36682 var borderTopWidth = parseFloat(styles.borderTopWidth, 10); 36683 var borderLeftWidth = parseFloat(styles.borderLeftWidth, 10); 36684 36685 // In cases where the parent is fixed, we must ignore negative scroll in offset calc 36686 if (fixedPosition && isHTML) { 36687 parentRect.top = Math.max(parentRect.top, 0); 36688 parentRect.left = Math.max(parentRect.left, 0); 36689 } 36690 var offsets = getClientRect({ 36691 top: childrenRect.top - parentRect.top - borderTopWidth, 36692 left: childrenRect.left - parentRect.left - borderLeftWidth, 36693 width: childrenRect.width, 36694 height: childrenRect.height 36695 }); 36696 offsets.marginTop = 0; 36697 offsets.marginLeft = 0; 36698 36699 // Subtract margins of documentElement in case it's being used as parent 36700 // we do this only on HTML because it's the only element that behaves 36701 // differently when margins are applied to it. The margins are included in 36702 // the box of the documentElement, in the other cases not. 36703 if (!isIE10 && isHTML) { 36704 var marginTop = parseFloat(styles.marginTop, 10); 36705 var marginLeft = parseFloat(styles.marginLeft, 10
vendor: 17,895 bytes, lines 36705-37266
36705); 36706 36707 offsets.top -= borderTopWidth - marginTop; 36708 offsets.bottom -= borderTopWidth - marginTop; 36709 offsets.left -= borderLeftWidth - marginLeft; 36710 offsets.right -= borderLeftWidth - marginLeft; 36711 36712 // Attach marginTop and marginLeft because in some circumstances we may need them 36713 offsets.marginTop = marginTop; 36714 offsets.marginLeft = marginLeft; 36715 } 36716 36717 if (isIE10 && !fixedPosition ? parent.contains(scrollParent) : parent === scrollParent && scrollParent.nodeName !== 'BODY') { 36718 offsets = includeScroll(offsets, parent); 36719 } 36720 36721 return offsets; 36722} 36723 36724function getViewportOffsetRectRelativeToArtbitraryNode(element) { 36725 var excludeScroll = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; 36726 36727 var html = element.ownerDocument.documentElement; 36728 var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html); 36729 var width = Math.max(html.clientWidth, window.innerWidth || 0); 36730 var height = Math.max(html.clientHeight, window.innerHeight || 0); 36731 36732 var scrollTop = !excludeScroll ? getScroll(html) : 0; 36733 var scrollLeft = !excludeScroll ? getScroll(html, 'left') : 0; 36734 36735 var offset = { 36736 top: scrollTop - relativeOffset.top + relativeOffset.marginTop, 36737 left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft, 36738 width: width, 36739 height: height 36740 }; 36741 36742 return getClientRect(offset); 36743} 36744 36745/** 36746 * Check if the given element is fixed or is inside a fixed parent 36747 * @method 36748 * @memberof Popper.Utils 36749 * @argument {Element} element 36750 * @argument {Element} customContainer 36751 * @returns {Boolean} answer to "isFixed?" 36752 */ 36753function isFixed(element) { 36754 var nodeName = element.nodeName; 36755 if (nodeName === 'BODY' || nodeName === 'HTML') { 36756 return false; 36757 } 36758 if (getStyleComputedProperty(element, 'position') === 'fixed') { 36759 return true; 36760 } 36761 var parentNode = getParentNode(element); 36762 if (!parentNode) { 36763 return false; 36764 } 36765 return isFixed(parentNode); 36766} 36767 36768/** 36769 * Finds the first parent of an element that has a transformed property defined 36770 * @method 36771 * @memberof Popper.Utils 36772 * @argument {Element} element 36773 * @returns {Element} first transformed parent or documentElement 36774 */ 36775 36776function getFixedPositionOffsetParent(element) { 36777 // This check is needed to avoid errors in case one of the elements isn't defined for any reason 36778 if (!element || !element.parentElement || isIE()) { 36779 return document.documentElement; 36780 } 36781 var el = element.parentElement; 36782 while (el && getStyleComputedProperty(el, 'transform') === 'none') { 36783 el = el.parentElement; 36784 } 36785 return el || document.documentElement; 36786} 36787 36788/** 36789 * Computed the boundaries limits and return them 36790 * @method 36791 * @memberof Popper.Utils 36792 * @param {HTMLElement} popper 36793 * @param {HTMLElement} reference 36794 * @param {number} padding 36795 * @param {HTMLElement} boundariesElement - Element used to define the boundaries 36796 * @param {Boolean} fixedPosition - Is in fixed position mode 36797 * @returns {Object} Coordinates of the boundaries 36798 */ 36799function getBoundaries(popper, reference, padding, boundariesElement) { 36800 var fixedPosition = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; 36801 36802 // NOTE: 1 DOM access here 36803 36804 var boundaries = { top: 0, left: 0 }; 36805 var offsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference)); 36806 36807 // Handle viewport case 36808 if (boundariesElement === 'viewport') { 36809 boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent, fixedPosition); 36810 } else { 36811 // Handle other cases based on DOM element used as boundaries 36812 var boundariesNode = void 0; 36813 if (boundariesElement === 'scrollParent') { 36814 boundariesNode = getScrollParent(getParentNode(reference)); 36815 if (boundariesNode.nodeName === 'BODY') { 36816 boundariesNode = popper.ownerDocument.documentElement; 36817 } 36818 } else if (boundariesElement === 'window') { 36819 boundariesNode = popper.ownerDocument.documentElement; 36820 } else { 36821 boundariesNode = boundariesElement; 36822 } 36823 36824 var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent, fixedPosition); 36825 36826 // In case of HTML, we need a different computation 36827 if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) { 36828 var _getWindowSizes = getWindowSizes(popper.ownerDocument), 36829 height = _getWindowSizes.height, 36830 width = _getWindowSizes.width; 36831 36832 boundaries.top += offsets.top - offsets.marginTop; 36833 boundaries.bottom = height + offsets.top; 36834 boundaries.left += offsets.left - offsets.marginLeft; 36835 boundaries.right = width + offsets.left; 36836 } else { 36837 // for all the other DOM elements, this one is good 36838 boundaries = offsets; 36839 } 36840 } 36841 36842 // Add paddings 36843 padding = padding || 0; 36844 var isPaddingNumber = typeof padding === 'number'; 36845 boundaries.left += isPaddingNumber ? padding : padding.left || 0; 36846 boundaries.top += isPaddingNumber ? padding : padding.top || 0; 36847 boundaries.right -= isPaddingNumber ? padding : padding.right || 0; 36848 boundaries.bottom -= isPaddingNumber ? padding : padding.bottom || 0; 36849 36850 return boundaries; 36851} 36852 36853function getArea(_ref) { 36854 var width = _ref.width, 36855 height = _ref.height; 36856 36857 return width * height; 36858} 36859 36860/** 36861 * Utility used to transform the `auto` placement to the placement with more 36862 * available space. 36863 * @method 36864 * @memberof Popper.Utils 36865 * @argument {Object} data - The data object generated by update method 36866 * @argument {Object} options - Modifiers configuration and options 36867 * @returns {Object} The data object, properly modified 36868 */ 36869function computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) { 36870 var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0; 36871 36872 if (placement.indexOf('auto') === -1) { 36873 return placement; 36874 } 36875 36876 var boundaries = getBoundaries(popper, reference, padding, boundariesElement); 36877 36878 var rects = { 36879 top: { 36880 width: boundaries.width, 36881 height: refRect.top - boundaries.top 36882 }, 36883 right: { 36884 width: boundaries.right - refRect.right, 36885 height: boundaries.height 36886 }, 36887 bottom: { 36888 width: boundaries.width, 36889 height: boundaries.bottom - refRect.bottom 36890 }, 36891 left: { 36892 width: refRect.left - boundaries.left, 36893 height: boundaries.height 36894 } 36895 }; 36896 36897 var sortedAreas = Object.keys(rects).map(function (key) { 36898 return _extends({ 36899 key: key 36900 }, rects[key], { 36901 area: getArea(rects[key]) 36902 }); 36903 }).sort(function (a, b) { 36904 return b.area - a.area; 36905 }); 36906 36907 var filteredAreas = sortedAreas.filter(function (_ref2) { 36908 var width = _ref2.width, 36909 height = _ref2.height; 36910 return width >= popper.clientWidth && height >= popper.clientHeight; 36911 }); 36912 36913 var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key; 36914 36915 var variation = placement.split('-')[1]; 36916 36917 return computedPlacement + (variation ? '-' + variation : ''); 36918} 36919 36920/** 36921 * Get offsets to the reference element 36922 * @method 36923 * @memberof Popper.Utils 36924 * @param {Object} state 36925 * @param {Element} popper - the popper element 36926 * @param {Element} reference - the reference element (the popper will be relative to this) 36927 * @param {Element} fixedPosition - is in fixed position mode 36928 * @returns {Object} An object containing the offsets which will be applied to the popper 36929 */ 36930function getReferenceOffsets(state, popper, reference) { 36931 var fixedPosition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; 36932 36933 var commonOffsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference)); 36934 return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent, fixedPosition); 36935} 36936 36937/** 36938 * Get the outer sizes of the given element (offset size + margins) 36939 * @method 36940 * @memberof Popper.Utils 36941 * @argument {Element} element 36942 * @returns {Object} object containing width and height properties 36943 */ 36944function getOuterSizes(element) { 36945 var window = element.ownerDocument.defaultView; 36946 var styles = window.getComputedStyle(element); 36947 var x = parseFloat(styles.marginTop || 0) + parseFloat(styles.marginBottom || 0); 36948 var y = parseFloat(styles.marginLeft || 0) + parseFloat(styles.marginRight || 0); 36949 var result = { 36950 width: element.offsetWidth + y, 36951 height: element.offsetHeight + x 36952 }; 36953 return result; 36954} 36955 36956/** 36957 * Get the opposite placement of the given one 36958 * @method 36959 * @memberof Popper.Utils 36960 * @argument {String} placement 36961 * @returns {String} flipped placement 36962 */ 36963function getOppositePlacement(placement) { 36964 var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' }; 36965 return placement.replace(/left|right|bottom|top/g, function (matched) { 36966 return hash[matched]; 36967 }); 36968} 36969 36970/** 36971 * Get offsets to the popper 36972 * @method 36973 * @memberof Popper.Utils 36974 * @param {Object} position - CSS position the Popper will get applied 36975 * @param {HTMLElement} popper - the popper element 36976 * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this) 36977 * @param {String} placement - one of the valid placement options 36978 * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper 36979 */ 36980function getPopperOffsets(popper, referenceOffsets, placement) { 36981 placement = placement.split('-')[0]; 36982 36983 // Get popper node sizes 36984 var popperRect = getOuterSizes(popper); 36985 36986 // Add position, width and height to our offsets object 36987 var popperOffsets = { 36988 width: popperRect.width, 36989 height: popperRect.height 36990 }; 36991 36992 // depending by the popper placement we have to compute its offsets slightly differently 36993 var isHoriz = ['right', 'left'].indexOf(placement) !== -1; 36994 var mainSide = isHoriz ? 'top' : 'left'; 36995 var secondarySide = isHoriz ? 'left' : 'top'; 36996 var measurement = isHoriz ? 'height' : 'width'; 36997 var secondaryMeasurement = !isHoriz ? 'height' : 'width'; 36998 36999 popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2; 37000 if (placement === secondarySide) { 37001 popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement]; 37002 } else { 37003 popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)]; 37004 } 37005 37006 return popperOffsets; 37007} 37008 37009/** 37010 * Mimics the `find` method of Array 37011 * @method 37012 * @memberof Popper.Utils 37013 * @argument {Array} arr 37014 * @argument prop 37015 * @argument value 37016 * @returns index or -1 37017 */ 37018function find(arr, check) { 37019 // use native find if supported 37020 if (Array.prototype.find) { 37021 return arr.find(check); 37022 } 37023 37024 // use `filter` to obtain the same behavior of `find` 37025 return arr.filter(check)[0]; 37026} 37027 37028/** 37029 * Return the index of the matching object 37030 * @method 37031 * @memberof Popper.Utils 37032 * @argument {Array} arr 37033 * @argument prop 37034 * @argument value 37035 * @returns index or -1 37036 */ 37037function findIndex(arr, prop, value) { 37038 // use native findIndex if supported 37039 if (Array.prototype.findIndex) { 37040 return arr.findIndex(function (cur) { 37041 return cur[prop] === value; 37042 }); 37043 } 37044 37045 // use `find` + `indexOf` if `findIndex` isn't supported 37046 var match = find(arr, function (obj) { 37047 return obj[prop] === value; 37048 }); 37049 return arr.indexOf(match); 37050} 37051 37052/** 37053 * Loop trough the list of modifiers and run them in order, 37054 * each of them will then edit the data object. 37055 * @method 37056 * @memberof Popper.Utils 37057 * @param {dataObject} data 37058 * @param {Array} modifiers 37059 * @param {String} ends - Optional modifier name used as stopper 37060 * @returns {dataObject} 37061 */ 37062function runModifiers(modifiers, data, ends) { 37063 var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends)); 37064 37065 modifiersToRun.forEach(function (modifier) { 37066 if (modifier['function']) { 37067 // eslint-disable-line dot-notation 37068 console.warn('`modifier.function` is deprecated, use `modifier.fn`!'); 37069 } 37070 var fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation 37071 if (modifier.enabled && isFunction(fn)) { 37072 // Add properties to offsets to make them a complete clientRect object 37073 // we do this before each modifier to make sure the previous one doesn't 37074 // mess with these values 37075 data.offsets.popper = getClientRect(data.offsets.popper); 37076 data.offsets.reference = getClientRect(data.offsets.reference); 37077 37078 data = fn(data, modifier); 37079 } 37080 }); 37081 37082 return data; 37083} 37084 37085/** 37086 * Updates the position of the popper, computing the new offsets and applying 37087 * the new style.<br /> 37088 * Prefer `scheduleUpdate` over `update` because of performance reasons. 37089 * @method 37090 * @memberof Popper 37091 */ 37092function update() { 37093 // if popper is destroyed, don't perform any further update 37094 if (this.state.isDestroyed) { 37095 return; 37096 } 37097 37098 var data = { 37099 instance: this, 37100 styles: {}, 37101 arrowStyles: {}, 37102 attributes: {}, 37103 flipped: false, 37104 offsets: {} 37105 }; 37106 37107 // compute reference element offsets 37108 data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference, this.options.positionFixed); 37109 37110 // compute auto placement, store placement inside the data object, 37111 // modifiers will be able to edit `placement` if needed 37112 // and refer to originalPlacement to know the original value 37113 data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper, this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding); 37114 37115 // store the computed placement inside `originalPlacement` 37116 data.originalPlacement = data.placement; 37117 37118 data.positionFixed = this.options.positionFixed; 37119 37120 // compute the popper offsets 37121 data.offsets.popper = getPopperOffsets(this.popper, data.offsets.reference, data.placement); 37122 37123 data.offsets.popper.position = this.options.positionFixed ? 'fixed' : 'absolute'; 37124 37125 // run the modifiers 37126 data = runModifiers(this.modifiers, data); 37127 37128 // the first `update` will call `onCreate` callback 37129 // the other ones will call `onUpdate` callback 37130 if (!this.state.isCreated) { 37131 this.state.isCreated = true; 37132 this.options.onCreate(data); 37133 } else { 37134 this.options.onUpdate(data); 37135 } 37136} 37137 37138/** 37139 * Helper used to know if the given modifier is enabled. 37140 * @method 37141 * @memberof Popper.Utils 37142 * @returns {Boolean} 37143 */ 37144function isModifierEnabled(modifiers, modifierName) { 37145 return modifiers.some(function (_ref) { 37146 var name = _ref.name, 37147 enabled = _ref.enabled; 37148 return enabled && name === modifierName; 37149 }); 37150} 37151 37152/** 37153 * Get the prefixed supported property name 37154 * @method 37155 * @memberof Popper.Utils 37156 * @argument {String} property (camelCase) 37157 * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix) 37158 */ 37159function getSupportedPropertyName(property) { 37160 var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O']; 37161 var upperProp = property.charAt(0).toUpperCase() + property.slice(1); 37162 37163 for (var i = 0; i < prefixes.length; i++) { 37164 var prefix = prefixes[i]; 37165 var toCheck = prefix ? '' + prefix + upperProp : property; 37166 if (typeof document.body.style[toCheck] !== 'undefined') { 37167 return toCheck; 37168 } 37169 } 37170 return null; 37171} 37172 37173/** 37174 * Destroys the popper. 37175 * @method 37176 * @memberof Popper 37177 */ 37178function destroy() { 37179 this.state.isDestroyed = true; 37180 37181 // touch DOM only if `applyStyle` modifier is enabled 37182 if (isModifierEnabled(this.modifiers, 'applyStyle')) { 37183 this.popper.removeAttribute('x-placement'); 37184 this.popper.style.position = ''; 37185 this.popper.style.top = ''; 37186 this.popper.style.left = ''; 37187 this.popper.style.right = ''; 37188 this.popper.style.bottom = ''; 37189 this.popper.style.willChange = ''; 37190 this.popper.style[getSupportedPropertyName('transform')] = ''; 37191 } 37192 37193 this.disableEventListeners(); 37194 37195 // remove the popper if user explicitly asked for the deletion on destroy 37196 // do not use `remove` because IE11 doesn't support it 37197 if (this.options.removeOnDestroy) { 37198 this.popper.parentNode.removeChild(this.popper); 37199 } 37200 return this; 37201} 37202 37203/** 37204 * Get the window associated with the element 37205 * @argument {Element} element 37206 * @returns {Window} 37207 */ 37208function getWindow(element) { 37209 var ownerDocument = element.ownerDocument; 37210 return ownerDocument ? ownerDocument.defaultView : window; 37211} 37212 37213function attachToScrollParents(scrollParent, event, callback, scrollParents) { 37214 var isBody = scrollParent.nodeName === 'BODY'; 37215 var target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent; 37216 target.addEventListener(event, callback, { passive: true }); 37217 37218 if (!isBody) { 37219 attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents); 37220 } 37221 scrollParents.push(target); 37222} 37223 37224/** 37225 * Setup needed event listeners used to update the popper position 37226 * @method 37227 * @memberof Popper.Utils 37228 * @private 37229 */ 37230function setupEventListeners(reference, options, state, updateBound) { 37231 // Resize event listener on window 37232 state.updateBound = updateBound; 37233 getWindow(reference).addEventListener('resize', state.updateBound, { passive: true }); 37234 37235 // Scroll event listener on scroll parents 37236 var scrollElement = getScrollParent(reference); 37237 attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents); 37238 state.scrollElement = scrollElement; 37239 state.eventsEnabled = true; 37240 37241 return state; 37242} 37243 37244/** 37245 * It will add resize/scroll events and start recalculating 37246 * position of the popper element when they are triggered. 37247 * @method 37248 * @memberof Popper 37249 */ 37250function enableEventListeners() { 37251 if (!this.state.eventsEnabled) { 37252 this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate); 37253 } 37254} 37255 37256/** 37257 * Remove event listeners used to update the popper position 37258 * @method 37259 * @memberof Popper.Utils 37260 * @private 37261 */ 37262function removeEventListeners(reference, state) { 37263 // Remove resize event listener on window 37264 getWindow(reference).removeEventListener('resize', state.updateBound); 37265 37266 // Remove scroll event listener on scroll parents
vendor: 54,378 bytes, lines 37267-38795
37267 state.scrollParents.forEach(function (target) { 37268 target.removeEventListener('scroll', state.updateBound); 37269 }); 37270 37271 // Reset state 37272 state.updateBound = null; 37273 state.scrollParents = []; 37274 state.scrollElement = null; 37275 state.eventsEnabled = false; 37276 return state; 37277} 37278 37279/** 37280 * It will remove resize/scroll events and won't recalculate popper position 37281 * when they are triggered. It also won't trigger `onUpdate` callback anymore, 37282 * unless you call `update` method manually. 37283 * @method 37284 * @memberof Popper 37285 */ 37286function disableEventListeners() { 37287 if (this.state.eventsEnabled) { 37288 cancelAnimationFrame(this.scheduleUpdate); 37289 this.state = removeEventListeners(this.reference, this.state); 37290 } 37291} 37292 37293/** 37294 * Tells if a given input is a number 37295 * @method 37296 * @memberof Popper.Utils 37297 * @param {*} input to check 37298 * @return {Boolean} 37299 */ 37300function isNumeric(n) { 37301 return n !== '' && !isNaN(parseFloat(n)) && isFinite(n); 37302} 37303 37304/** 37305 * Set the style to the given popper 37306 * @method 37307 * @memberof Popper.Utils 37308 * @argument {Element} element - Element to apply the style to 37309 * @argument {Object} styles 37310 * Object with a list of properties and values which will be applied to the element 37311 */ 37312function setStyles(element, styles) { 37313 Object.keys(styles).forEach(function (prop) { 37314 var unit = ''; 37315 // add unit if the value is numeric and is one of the following 37316 if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) { 37317 unit = 'px'; 37318 } 37319 element.style[prop] = styles[prop] + unit; 37320 }); 37321} 37322 37323/** 37324 * Set the attributes to the given popper 37325 * @method 37326 * @memberof Popper.Utils 37327 * @argument {Element} element - Element to apply the attributes to 37328 * @argument {Object} styles 37329 * Object with a list of properties and values which will be applied to the element 37330 */ 37331function setAttributes(element, attributes) { 37332 Object.keys(attributes).forEach(function (prop) { 37333 var value = attributes[prop]; 37334 if (value !== false) { 37335 element.setAttribute(prop, attributes[prop]); 37336 } else { 37337 element.removeAttribute(prop); 37338 } 37339 }); 37340} 37341 37342/** 37343 * @function 37344 * @memberof Modifiers 37345 * @argument {Object} data - The data object generated by `update` method 37346 * @argument {Object} data.styles - List of style properties - values to apply to popper element 37347 * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element 37348 * @argument {Object} options - Modifiers configuration and options 37349 * @returns {Object} The same data object 37350 */ 37351function applyStyle(data) { 37352 // any property present in `data.styles` will be applied to the popper, 37353 // in this way we can make the 3rd party modifiers add custom styles to it 37354 // Be aware, modifiers could override the properties defined in the previous 37355 // lines of this modifier! 37356 setStyles(data.instance.popper, data.styles); 37357 37358 // any property present in `data.attributes` will be applied to the popper, 37359 // they will be set as HTML attributes of the element 37360 setAttributes(data.instance.popper, data.attributes); 37361 37362 // if arrowElement is defined and arrowStyles has some properties 37363 if (data.arrowElement && Object.keys(data.arrowStyles).length) { 37364 setStyles(data.arrowElement, data.arrowStyles); 37365 } 37366 37367 return data; 37368} 37369 37370/** 37371 * Set the x-placement attribute before everything else because it could be used 37372 * to add margins to the popper margins needs to be calculated to get the 37373 * correct popper offsets. 37374 * @method 37375 * @memberof Popper.modifiers 37376 * @param {HTMLElement} reference - The reference element used to position the popper 37377 * @param {HTMLElement} popper - The HTML element used as popper 37378 * @param {Object} options - Popper.js options 37379 */ 37380function applyStyleOnLoad(reference, popper, options, modifierOptions, state) { 37381 // compute reference element offsets 37382 var referenceOffsets = getReferenceOffsets(state, popper, reference, options.positionFixed); 37383 37384 // compute auto placement, store placement inside the data object, 37385 // modifiers will be able to edit `placement` if needed 37386 // and refer to originalPlacement to know the original value 37387 var placement = computeAutoPlacement(options.placement, referenceOffsets, popper, reference, options.modifiers.flip.boundariesElement, options.modifiers.flip.padding); 37388 37389 popper.setAttribute('x-placement', placement); 37390 37391 // Apply `position` to popper before anything else because 37392 // without the position applied we can't guarantee correct computations 37393 setStyles(popper, { position: options.positionFixed ? 'fixed' : 'absolute' }); 37394 37395 return options; 37396} 37397 37398/** 37399 * @function 37400 * @memberof Popper.Utils 37401 * @argument {Object} data - The data object generated by `update` method 37402 * @argument {Boolean} shouldRound - If the offsets should be rounded at all 37403 * @returns {Object} The popper's position offsets rounded 37404 * 37405 * The tale of pixel-perfect positioning. It's still not 100% perfect, but as 37406 * good as it can be within reason. 37407 * Discussion here: https://github.com/FezVrasta/popper.js/pull/715 37408 * 37409 * Low DPI screens cause a popper to be blurry if not using full pixels (Safari 37410 * as well on High DPI screens). 37411 * 37412 * Firefox prefers no rounding for positioning and does not have blurriness on 37413 * high DPI screens. 37414 * 37415 * Only horizontal placement and left/right values need to be considered. 37416 */ 37417function getRoundedOffsets(data, shouldRound) { 37418 var _data$offsets = data.offsets, 37419 popper = _data$offsets.popper, 37420 reference = _data$offsets.reference; 37421 var round = Math.round, 37422 floor = Math.floor; 37423 37424 var noRound = function noRound(v) { 37425 return v; 37426 }; 37427 37428 var referenceWidth = round(reference.width); 37429 var popperWidth = round(popper.width); 37430 37431 var isVertical = ['left', 'right'].indexOf(data.placement) !== -1; 37432 var isVariation = data.placement.indexOf('-') !== -1; 37433 var sameWidthParity = referenceWidth % 2 === popperWidth % 2; 37434 var bothOddWidth = referenceWidth % 2 === 1 && popperWidth % 2 === 1; 37435 37436 var horizontalToInteger = !shouldRound ? noRound : isVertical || isVariation || sameWidthParity ? round : floor; 37437 var verticalToInteger = !shouldRound ? noRound : round; 37438 37439 return { 37440 left: horizontalToInteger(bothOddWidth && !isVariation && shouldRound ? popper.left - 1 : popper.left), 37441 top: verticalToInteger(popper.top), 37442 bottom: verticalToInteger(popper.bottom), 37443 right: horizontalToInteger(popper.right) 37444 }; 37445} 37446 37447var isFirefox = isBrowser && /Firefox/i.test(navigator.userAgent); 37448 37449/** 37450 * @function 37451 * @memberof Modifiers 37452 * @argument {Object} data - The data object generated by `update` method 37453 * @argument {Object} options - Modifiers configuration and options 37454 * @returns {Object} The data object, properly modified 37455 */ 37456function computeStyle(data, options) { 37457 var x = options.x, 37458 y = options.y; 37459 var popper = data.offsets.popper; 37460 37461 // Remove this legacy support in Popper.js v2 37462 37463 var legacyGpuAccelerationOption = find(data.instance.modifiers, function (modifier) { 37464 return modifier.name === 'applyStyle'; 37465 }).gpuAcceleration; 37466 if (legacyGpuAccelerationOption !== undefined) { 37467 console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!'); 37468 } 37469 var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : options.gpuAcceleration; 37470 37471 var offsetParent = getOffsetParent(data.instance.popper); 37472 var offsetParentRect = getBoundingClientRect(offsetParent); 37473 37474 // Styles 37475 var styles = { 37476 position: popper.position 37477 }; 37478 37479 var offsets = getRoundedOffsets(data, window.devicePixelRatio < 2 || !isFirefox); 37480 37481 var sideA = x === 'bottom' ? 'top' : 'bottom'; 37482 var sideB = y === 'right' ? 'left' : 'right'; 37483 37484 // if gpuAcceleration is set to `true` and transform is supported, 37485 // we use `translate3d` to apply the position to the popper we 37486 // automatically use the supported prefixed version if needed 37487 var prefixedProperty = getSupportedPropertyName('transform'); 37488 37489 // now, let's make a step back and look at this code closely (wtf?) 37490 // If the content of the popper grows once it's been positioned, it 37491 // may happen that the popper gets misplaced because of the new content 37492 // overflowing its reference element 37493 // To avoid this problem, we provide two options (x and y), which allow 37494 // the consumer to define the offset origin. 37495 // If we position a popper on top of a reference element, we can set 37496 // `x` to `top` to make the popper grow towards its top instead of 37497 // its bottom. 37498 var left = void 0, 37499 top = void 0; 37500 if (sideA === 'bottom') { 37501 // when offsetParent is <html> the positioning is relative to the bottom of the screen (excluding the scrollbar) 37502 // and not the bottom of the html element 37503 if (offsetParent.nodeName === 'HTML') { 37504 top = -offsetParent.clientHeight + offsets.bottom; 37505 } else { 37506 top = -offsetParentRect.height + offsets.bottom; 37507 } 37508 } else { 37509 top = offsets.top; 37510 } 37511 if (sideB === 'right') { 37512 if (offsetParent.nodeName === 'HTML') { 37513 left = -offsetParent.clientWidth + offsets.right; 37514 } else { 37515 left = -offsetParentRect.width + offsets.right; 37516 } 37517 } else { 37518 left = offsets.left; 37519 } 37520 if (gpuAcceleration && prefixedProperty) { 37521 styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)'; 37522 styles[sideA] = 0; 37523 styles[sideB] = 0; 37524 styles.willChange = 'transform'; 37525 } else { 37526 // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties 37527 var invertTop = sideA === 'bottom' ? -1 : 1; 37528 var invertLeft = sideB === 'right' ? -1 : 1; 37529 styles[sideA] = top * invertTop; 37530 styles[sideB] = left * invertLeft; 37531 styles.willChange = sideA + ', ' + sideB; 37532 } 37533 37534 // Attributes 37535 var attributes = { 37536 'x-placement': data.placement 37537 }; 37538 37539 // Update `data` attributes, styles and arrowStyles 37540 data.attributes = _extends({}, attributes, data.attributes); 37541 data.styles = _extends({}, styles, data.styles); 37542 data.arrowStyles = _extends({}, data.offsets.arrow, data.arrowStyles); 37543 37544 return data; 37545} 37546 37547/** 37548 * Helper used to know if the given modifier depends from another one.<br /> 37549 * It checks if the needed modifier is listed and enabled. 37550 * @method 37551 * @memberof Popper.Utils 37552 * @param {Array} modifiers - list of modifiers 37553 * @param {String} requestingName - name of requesting modifier 37554 * @param {String} requestedName - name of requested modifier 37555 * @returns {Boolean} 37556 */ 37557function isModifierRequired(modifiers, requestingName, requestedName) { 37558 var requesting = find(modifiers, function (_ref) { 37559 var name = _ref.name; 37560 return name === requestingName; 37561 }); 37562 37563 var isRequired = !!requesting && modifiers.some(function (modifier) { 37564 return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order; 37565 }); 37566 37567 if (!isRequired) { 37568 var _requesting = '`' + requestingName + '`'; 37569 var requested = '`' + requestedName + '`'; 37570 console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!'); 37571 } 37572 return isRequired; 37573} 37574 37575/** 37576 * @function 37577 * @memberof Modifiers 37578 * @argument {Object} data - The data object generated by update method 37579 * @argument {Object} options - Modifiers configuration and options 37580 * @returns {Object} The data object, properly modified 37581 */ 37582function arrow(data, options) { 37583 var _data$offsets$arrow; 37584 37585 // arrow depends on keepTogether in order to work 37586 if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) { 37587 return data; 37588 } 37589 37590 var arrowElement = options.element; 37591 37592 // if arrowElement is a string, suppose it's a CSS selector 37593 if (typeof arrowElement === 'string') { 37594 arrowElement = data.instance.popper.querySelector(arrowElement); 37595 37596 // if arrowElement is not found, don't run the modifier 37597 if (!arrowElement) { 37598 return data; 37599 } 37600 } else { 37601 // if the arrowElement isn't a query selector we must check that the 37602 // provided DOM node is child of its popper node 37603 if (!data.instance.popper.contains(arrowElement)) { 37604 console.warn('WARNING: `arrow.element` must be child of its popper element!'); 37605 return data; 37606 } 37607 } 37608 37609 var placement = data.placement.split('-')[0]; 37610 var _data$offsets = data.offsets, 37611 popper = _data$offsets.popper, 37612 reference = _data$offsets.reference; 37613 37614 var isVertical = ['left', 'right'].indexOf(placement) !== -1; 37615 37616 var len = isVertical ? 'height' : 'width'; 37617 var sideCapitalized = isVertical ? 'Top' : 'Left'; 37618 var side = sideCapitalized.toLowerCase(); 37619 var altSide = isVertical ? 'left' : 'top'; 37620 var opSide = isVertical ? 'bottom' : 'right'; 37621 var arrowElementSize = getOuterSizes(arrowElement)[len]; 37622 37623 // 37624 // extends keepTogether behavior making sure the popper and its 37625 // reference have enough pixels in conjunction 37626 // 37627 37628 // top/left side 37629 if (reference[opSide] - arrowElementSize < popper[side]) { 37630 data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize); 37631 } 37632 // bottom/right side 37633 if (reference[side] + arrowElementSize > popper[opSide]) { 37634 data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide]; 37635 } 37636 data.offsets.popper = getClientRect(data.offsets.popper); 37637 37638 // compute center of the popper 37639 var center = reference[side] + reference[len] / 2 - arrowElementSize / 2; 37640 37641 // Compute the sideValue using the updated popper offsets 37642 // take popper margin in account because we don't have this info available 37643 var css = getStyleComputedProperty(data.instance.popper); 37644 var popperMarginSide = parseFloat(css['margin' + sideCapitalized], 10); 37645 var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width'], 10); 37646 var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide; 37647 37648 // prevent arrowElement from being placed not contiguously to its popper 37649 sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0); 37650 37651 data.arrowElement = arrowElement; 37652 data.offsets.arrow = (_data$offsets$arrow = {}, defineProperty(_data$offsets$arrow, side, Math.round(sideValue)), defineProperty(_data$offsets$arrow, altSide, ''), _data$offsets$arrow); 37653 37654 return data; 37655} 37656 37657/** 37658 * Get the opposite placement variation of the given one 37659 * @method 37660 * @memberof Popper.Utils 37661 * @argument {String} placement variation 37662 * @returns {String} flipped placement variation 37663 */ 37664function getOppositeVariation(variation) { 37665 if (variation === 'end') { 37666 return 'start'; 37667 } else if (variation === 'start') { 37668 return 'end'; 37669 } 37670 return variation; 37671} 37672 37673/** 37674 * List of accepted placements to use as values of the `placement` option.<br /> 37675 * Valid placements are: 37676 * - `auto` 37677 * - `top` 37678 * - `right` 37679 * - `bottom` 37680 * - `left` 37681 * 37682 * Each placement can have a variation from this list: 37683 * - `-start` 37684 * - `-end` 37685 * 37686 * Variations are interpreted easily if you think of them as the left to right 37687 * written languages. Horizontally (`top` and `bottom`), `start` is left and `end` 37688 * is right.<br /> 37689 * Vertically (`left` and `right`), `start` is top and `end` is bottom. 37690 * 37691 * Some valid examples are: 37692 * - `top-end` (on top of reference, right aligned) 37693 * - `right-start` (on right of reference, top aligned) 37694 * - `bottom` (on bottom, centered) 37695 * - `auto-end` (on the side with more space available, alignment depends by placement) 37696 * 37697 * @static 37698 * @type {Array} 37699 * @enum {String} 37700 * @readonly 37701 * @method placements 37702 * @memberof Popper 37703 */ 37704var placements = ['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start']; 37705 37706// Get rid of `auto` `auto-start` and `auto-end` 37707var validPlacements = placements.slice(3); 37708 37709/** 37710 * Given an initial placement, returns all the subsequent placements 37711 * clockwise (or counter-clockwise). 37712 * 37713 * @method 37714 * @memberof Popper.Utils 37715 * @argument {String} placement - A valid placement (it accepts variations) 37716 * @argument {Boolean} counter - Set to true to walk the placements counterclockwise 37717 * @returns {Array} placements including their variations 37718 */ 37719function clockwise(placement) { 37720 var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; 37721 37722 var index = validPlacements.indexOf(placement); 37723 var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index)); 37724 return counter ? arr.reverse() : arr; 37725} 37726 37727var BEHAVIORS = { 37728 FLIP: 'flip', 37729 CLOCKWISE: 'clockwise', 37730 COUNTERCLOCKWISE: 'counterclockwise' 37731}; 37732 37733/** 37734 * @function 37735 * @memberof Modifiers 37736 * @argument {Object} data - The data object generated by update method 37737 * @argument {Object} options - Modifiers configuration and options 37738 * @returns {Object} The data object, properly modified 37739 */ 37740function flip(data, options) { 37741 // if `inner` modifier is enabled, we can't use the `flip` modifier 37742 if (isModifierEnabled(data.instance.modifiers, 'inner')) { 37743 return data; 37744 } 37745 37746 if (data.flipped && data.placement === data.originalPlacement) { 37747 // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides 37748 return data; 37749 } 37750 37751 var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, options.boundariesElement, data.positionFixed); 37752 37753 var placement = data.placement.split('-')[0]; 37754 var placementOpposite = getOppositePlacement(placement); 37755 var variation = data.placement.split('-')[1] || ''; 37756 37757 var flipOrder = []; 37758 37759 switch (options.behavior) { 37760 case BEHAVIORS.FLIP: 37761 flipOrder = [placement, placementOpposite]; 37762 break; 37763 case BEHAVIORS.CLOCKWISE: 37764 flipOrder = clockwise(placement); 37765 break; 37766 case BEHAVIORS.COUNTERCLOCKWISE: 37767 flipOrder = clockwise(placement, true); 37768 break; 37769 default: 37770 flipOrder = options.behavior; 37771 } 37772 37773 flipOrder.forEach(function (step, index) { 37774 if (placement !== step || flipOrder.length === index + 1) { 37775 return data; 37776 } 37777 37778 placement = data.placement.split('-')[0]; 37779 placementOpposite = getOppositePlacement(placement); 37780 37781 var popperOffsets = data.offsets.popper; 37782 var refOffsets = data.offsets.reference; 37783 37784 // using floor because the reference offsets may contain decimals we are not going to consider here 37785 var floor = Math.floor; 37786 var overlapsRef = placement === 'left' && floor(popperOffsets.right) > floor(refOffsets.left) || placement === 'right' && floor(popperOffsets.left) < floor(refOffsets.right) || placement === 'top' && floor(popperOffsets.bottom) > floor(refOffsets.top) || placement === 'bottom' && floor(popperOffsets.top) < floor(refOffsets.bottom); 37787 37788 var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left); 37789 var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right); 37790 var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top); 37791 var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom); 37792 37793 var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom; 37794 37795 // flip the variation if required 37796 var isVertical = ['top', 'bottom'].indexOf(placement) !== -1; 37797 37798 // flips variation if reference element overflows boundaries 37799 var flippedVariationByRef = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom); 37800 37801 // flips variation if popper content overflows boundaries 37802 var flippedVariationByContent = !!options.flipVariationsByContent && (isVertical && variation === 'start' && overflowsRight || isVertical && variation === 'end' && overflowsLeft || !isVertical && variation === 'start' && overflowsBottom || !isVertical && variation === 'end' && overflowsTop); 37803 37804 var flippedVariation = flippedVariationByRef || flippedVariationByContent; 37805 37806 if (overlapsRef || overflowsBoundaries || flippedVariation) { 37807 // this boolean to detect any flip loop 37808 data.flipped = true; 37809 37810 if (overlapsRef || overflowsBoundaries) { 37811 placement = flipOrder[index + 1]; 37812 } 37813 37814 if (flippedVariation) { 37815 variation = getOppositeVariation(variation); 37816 } 37817 37818 data.placement = placement + (variation ? '-' + variation : ''); 37819 37820 // this object contains `position`, we want to preserve it along with 37821 // any additional property we may add in the future 37822 data.offsets.popper = _extends({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement)); 37823 37824 data = runModifiers(data.instance.modifiers, data, 'flip'); 37825 } 37826 }); 37827 return data; 37828} 37829 37830/** 37831 * @function 37832 * @memberof Modifiers 37833 * @argument {Object} data - The data object generated by update method 37834 * @argument {Object} options - Modifiers configuration and options 37835 * @returns {Object} The data object, properly modified 37836 */ 37837function keepTogether(data) { 37838 var _data$offsets = data.offsets, 37839 popper = _data$offsets.popper, 37840 reference = _data$offsets.reference; 37841 37842 var placement = data.placement.split('-')[0]; 37843 var floor = Math.floor; 37844 var isVertical = ['top', 'bottom'].indexOf(placement) !== -1; 37845 var side = isVertical ? 'right' : 'bottom'; 37846 var opSide = isVertical ? 'left' : 'top'; 37847 var measurement = isVertical ? 'width' : 'height'; 37848 37849 if (popper[side] < floor(reference[opSide])) { 37850 data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement]; 37851 } 37852 if (popper[opSide] > floor(reference[side])) { 37853 data.offsets.popper[opSide] = floor(reference[side]); 37854 } 37855 37856 return data; 37857} 37858 37859/** 37860 * Converts a string containing value + unit into a px value number 37861 * @function 37862 * @memberof {modifiers~offset} 37863 * @private 37864 * @argument {String} str - Value + unit string 37865 * @argument {String} measurement - `height` or `width` 37866 * @argument {Object} popperOffsets 37867 * @argument {Object} referenceOffsets 37868 * @returns {Number|String} 37869 * Value in pixels, or original string if no values were extracted 37870 */ 37871function toValue(str, measurement, popperOffsets, referenceOffsets) { 37872 // separate value from unit 37873 var split = str.match(/((?:\-|\+)?\d*\.?\d*)(.*)/); 37874 var value = +split[1]; 37875 var unit = split[2]; 37876 37877 // If it's not a number it's an operator, I guess 37878 if (!value) { 37879 return str; 37880 } 37881 37882 if (unit.indexOf('%') === 0) { 37883 var element = void 0; 37884 switch (unit) { 37885 case '%p': 37886 element = popperOffsets; 37887 break; 37888 case '%': 37889 case '%r': 37890 default: 37891 element = referenceOffsets; 37892 } 37893 37894 var rect = getClientRect(element); 37895 return rect[measurement] / 100 * value; 37896 } else if (unit === 'vh' || unit === 'vw') { 37897 // if is a vh or vw, we calculate the size based on the viewport 37898 var size = void 0; 37899 if (unit === 'vh') { 37900 size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); 37901 } else { 37902 size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); 37903 } 37904 return size / 100 * value; 37905 } else { 37906 // if is an explicit pixel unit, we get rid of the unit and keep the value 37907 // if is an implicit unit, it's px, and we return just the value 37908 return value; 37909 } 37910} 37911 37912/** 37913 * Parse an `offset` string to extrapolate `x` and `y` numeric offsets. 37914 * @function 37915 * @memberof {modifiers~offset} 37916 * @private 37917 * @argument {String} offset 37918 * @argument {Object} popperOffsets 37919 * @argument {Object} referenceOffsets 37920 * @argument {String} basePlacement 37921 * @returns {Array} a two cells array with x and y offsets in numbers 37922 */ 37923function parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) { 37924 var offsets = [0, 0]; 37925 37926 // Use height if placement is left or right and index is 0 otherwise use width 37927 // in this way the first offset will use an axis and the second one 37928 // will use the other one 37929 var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1; 37930 37931 // Split the offset string to obtain a list of values and operands 37932 // The regex addresses values with the plus or minus sign in front (+10, -20, etc) 37933 var fragments = offset.split(/(\+|\-)/).map(function (frag) { 37934 return frag.trim(); 37935 }); 37936 37937 // Detect if the offset string contains a pair of values or a single one 37938 // they could be separated by comma or space 37939 var divider = fragments.indexOf(find(fragments, function (frag) { 37940 return frag.search(/,|\s/) !== -1; 37941 })); 37942 37943 if (fragments[divider] && fragments[divider].indexOf(',') === -1) { 37944 console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.'); 37945 } 37946 37947 // If divider is found, we divide the list of values and operands to divide 37948 // them by ofset X and Y. 37949 var splitRegex = /\s*,\s*|\s+/; 37950 var ops = divider !== -1 ? [fragments.slice(0, divider).concat([fragments[divider].split(splitRegex)[0]]), [fragments[divider].split(splitRegex)[1]].concat(fragments.slice(divider + 1))] : [fragments]; 37951 37952 // Convert the values with units to absolute pixels to allow our computations 37953 ops = ops.map(function (op, index) { 37954 // Most of the units rely on the orientation of the popper 37955 var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width'; 37956 var mergeWithPrevious = false; 37957 return op 37958 // This aggregates any `+` or `-` sign that aren't considered operators 37959 // e.g.: 10 + +5 => [10, +, +5] 37960 .reduce(function (a, b) { 37961 if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) { 37962 a[a.length - 1] = b; 37963 mergeWithPrevious = true; 37964 return a; 37965 } else if (mergeWithPrevious) { 37966 a[a.length - 1] += b; 37967 mergeWithPrevious = false; 37968 return a; 37969 } else { 37970 return a.concat(b); 37971 } 37972 }, []) 37973 // Here we convert the string values into number values (in px) 37974 .map(function (str) { 37975 return toValue(str, measurement, popperOffsets, referenceOffsets); 37976 }); 37977 }); 37978 37979 // Loop trough the offsets arrays and execute the operations 37980 ops.forEach(function (op, index) { 37981 op.forEach(function (frag, index2) { 37982 if (isNumeric(frag)) { 37983 offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1); 37984 } 37985 }); 37986 }); 37987 return offsets; 37988} 37989 37990/** 37991 * @function 37992 * @memberof Modifiers 37993 * @argument {Object} data - The data object generated by update method 37994 * @argument {Object} options - Modifiers configuration and options 37995 * @argument {Number|String} options.offset=0 37996 * The offset value as described in the modifier description 37997 * @returns {Object} The data object, properly modified 37998 */ 37999function offset(data, _ref) { 38000 var offset = _ref.offset; 38001 var placement = data.placement, 38002 _data$offsets = data.offsets, 38003 popper = _data$offsets.popper, 38004 reference = _data$offsets.reference; 38005 38006 var basePlacement = placement.split('-')[0]; 38007 38008 var offsets = void 0; 38009 if (isNumeric(+offset)) { 38010 offsets = [+offset, 0]; 38011 } else { 38012 offsets = parseOffset(offset, popper, reference, basePlacement); 38013 } 38014 38015 if (basePlacement === 'left') { 38016 popper.top += offsets[0]; 38017 popper.left -= offsets[1]; 38018 } else if (basePlacement === 'right') { 38019 popper.top += offsets[0]; 38020 popper.left += offsets[1]; 38021 } else if (basePlacement === 'top') { 38022 popper.left += offsets[0]; 38023 popper.top -= offsets[1]; 38024 } else if (basePlacement === 'bottom') { 38025 popper.left += offsets[0]; 38026 popper.top += offsets[1]; 38027 } 38028 38029 data.popper = popper; 38030 return data; 38031} 38032 38033/** 38034 * @function 38035 * @memberof Modifiers 38036 * @argument {Object} data - The data object generated by `update` method 38037 * @argument {Object} options - Modifiers configuration and options 38038 * @returns {Object} The data object, properly modified 38039 */ 38040function preventOverflow(data, options) { 38041 var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper); 38042 38043 // If offsetParent is the reference element, we really want to 38044 // go one step up and use the next offsetParent as reference to 38045 // avoid to make this modifier completely useless and look like broken 38046 if (data.instance.reference === boundariesElement) { 38047 boundariesElement = getOffsetParent(boundariesElement); 38048 } 38049 38050 // NOTE: DOM access here 38051 // resets the popper's position so that the document size can be calculated excluding 38052 // the size of the popper element itself 38053 var transformProp = getSupportedPropertyName('transform'); 38054 var popperStyles = data.instance.popper.style; // assignment to help minification 38055 var top = popperStyles.top, 38056 left = popperStyles.left, 38057 transform = popperStyles[transformProp]; 38058 38059 popperStyles.top = ''; 38060 popperStyles.left = ''; 38061 popperStyles[transformProp] = ''; 38062 38063 var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, boundariesElement, data.positionFixed); 38064 38065 // NOTE: DOM access here 38066 // restores the original style properties after the offsets have been computed 38067 popperStyles.top = top; 38068 popperStyles.left = left; 38069 popperStyles[transformProp] = transform; 38070 38071 options.boundaries = boundaries; 38072 38073 var order = options.priority; 38074 var popper = data.offsets.popper; 38075 38076 var check = { 38077 primary: function primary(placement) { 38078 var value = popper[placement]; 38079 if (popper[placement] < boundaries[placement] && !options.escapeWithReference) { 38080 value = Math.max(popper[placement], boundaries[placement]); 38081 } 38082 return defineProperty({}, placement, value); 38083 }, 38084 secondary: function secondary(placement) { 38085 var mainSide = placement === 'right' ? 'left' : 'top'; 38086 var value = popper[mainSide]; 38087 if (popper[placement] > boundaries[placement] && !options.escapeWithReference) { 38088 value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height)); 38089 } 38090 return defineProperty({}, mainSide, value); 38091 } 38092 }; 38093 38094 order.forEach(function (placement) { 38095 var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary'; 38096 popper = _extends({}, popper, check[side](placement)); 38097 }); 38098 38099 data.offsets.popper = popper; 38100 38101 return data; 38102} 38103 38104/** 38105 * @function 38106 * @memberof Modifiers 38107 * @argument {Object} data - The data object generated by `update` method 38108 * @argument {Object} options - Modifiers configuration and options 38109 * @returns {Object} The data object, properly modified 38110 */ 38111function shift(data) { 38112 var placement = data.placement; 38113 var basePlacement = placement.split('-')[0]; 38114 var shiftvariation = placement.split('-')[1]; 38115 38116 // if shift shiftvariation is specified, run the modifier 38117 if (shiftvariation) { 38118 var _data$offsets = data.offsets, 38119 reference = _data$offsets.reference, 38120 popper = _data$offsets.popper; 38121 38122 var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1; 38123 var side = isVertical ? 'left' : 'top'; 38124 var measurement = isVertical ? 'width' : 'height'; 38125 38126 var shiftOffsets = { 38127 start: defineProperty({}, side, reference[side]), 38128 end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement]) 38129 }; 38130 38131 data.offsets.popper = _extends({}, popper, shiftOffsets[shiftvariation]); 38132 } 38133 38134 return data; 38135} 38136 38137/** 38138 * @function 38139 * @memberof Modifiers 38140 * @argument {Object} data - The data object generated by update method 38141 * @argument {Object} options - Modifiers configuration and options 38142 * @returns {Object} The data object, properly modified 38143 */ 38144function hide(data) { 38145 if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) { 38146 return data; 38147 } 38148 38149 var refRect = data.offsets.reference; 38150 var bound = find(data.instance.modifiers, function (modifier) { 38151 return modifier.name === 'preventOverflow'; 38152 }).boundaries; 38153 38154 if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) { 38155 // Avoid unnecessary DOM access if visibility hasn't changed 38156 if (data.hide === true) { 38157 return data; 38158 } 38159 38160 data.hide = true; 38161 data.attributes['x-out-of-boundaries'] = ''; 38162 } else { 38163 // Avoid unnecessary DOM access if visibility hasn't changed 38164 if (data.hide === false) { 38165 return data; 38166 } 38167 38168 data.hide = false; 38169 data.attributes['x-out-of-boundaries'] = false; 38170 } 38171 38172 return data; 38173} 38174 38175/** 38176 * @function 38177 * @memberof Modifiers 38178 * @argument {Object} data - The data object generated by `update` method 38179 * @argument {Object} options - Modifiers configuration and options 38180 * @returns {Object} The data object, properly modified 38181 */ 38182function inner(data) { 38183 var placement = data.placement; 38184 var basePlacement = placement.split('-')[0]; 38185 var _data$offsets = data.offsets, 38186 popper = _data$offsets.popper, 38187 reference = _data$offsets.reference; 38188 38189 var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1; 38190 38191 var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1; 38192 38193 popper[isHoriz ? 'left' : 'top'] = reference[basePlacement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0); 38194 38195 data.placement = getOppositePlacement(placement); 38196 data.offsets.popper = getClientRect(popper); 38197 38198 return data; 38199} 38200 38201/** 38202 * Modifier function, each modifier can have a function of this type assigned 38203 * to its `fn` property.<br /> 38204 * These functions will be called on each update, this means that you must 38205 * make sure they are performant enough to avoid performance bottlenecks. 38206 * 38207 * @function ModifierFn 38208 * @argument {dataObject} data - The data object generated by `update` method 38209 * @argument {Object} options - Modifiers configuration and options 38210 * @returns {dataObject} The data object, properly modified 38211 */ 38212 38213/** 38214 * Modifiers are plugins used to alter the behavior of your poppers.<br /> 38215 * Popper.js uses a set of 9 modifiers to provide all the basic functionalities 38216 * needed by the library. 38217 * 38218 * Usually you don't want to override the `order`, `fn` and `onLoad` props. 38219 * All the other properties are configurations that could be tweaked. 38220 * @namespace modifiers 38221 */ 38222var modifiers = { 38223 /** 38224 * Modifier used to shift the popper on the start or end of its reference 38225 * element.<br /> 38226 * It will read the variation of the `placement` property.<br /> 38227 * It can be one either `-end` or `-start`. 38228 * @memberof modifiers 38229 * @inner 38230 */ 38231 shift: { 38232 /** @prop {number} order=100 - Index used to define the order of execution */ 38233 order: 100, 38234 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 38235 enabled: true, 38236 /** @prop {ModifierFn} */ 38237 fn: shift 38238 }, 38239 38240 /** 38241 * The `offset` modifier can shift your popper on both its axis. 38242 * 38243 * It accepts the following units: 38244 * - `px` or unit-less, interpreted as pixels 38245 * - `%` or `%r`, percentage relative to the length of the reference element 38246 * - `%p`, percentage relative to the length of the popper element 38247 * - `vw`, CSS viewport width unit 38248 * - `vh`, CSS viewport height unit 38249 * 38250 * For length is intended the main axis relative to the placement of the popper.<br /> 38251 * This means that if the placement is `top` or `bottom`, the length will be the 38252 * `width`. In case of `left` or `right`, it will be the `height`. 38253 * 38254 * You can provide a single value (as `Number` or `String`), or a pair of values 38255 * as `String` divided by a comma or one (or more) white spaces.<br /> 38256 * The latter is a deprecated method because it leads to confusion and will be 38257 * removed in v2.<br /> 38258 * Additionally, it accepts additions and subtractions between different units. 38259 * Note that multiplications and divisions aren't supported. 38260 * 38261 * Valid examples are: 38262 * ``` 38263 * 10 38264 * '10%' 38265 * '10, 10' 38266 * '10%, 10' 38267 * '10 + 10%' 38268 * '10 - 5vh + 3%' 38269 * '-10px + 5vh, 5px - 6%' 38270 * ``` 38271 * > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap 38272 * > with their reference element, unfortunately, you will have to disable the `flip` modifier. 38273 * > You can read more on this at this [issue](https://github.com/FezVrasta/popper.js/issues/373). 38274 * 38275 * @memberof modifiers 38276 * @inner 38277 */ 38278 offset: { 38279 /** @prop {number} order=200 - Index used to define the order of execution */ 38280 order: 200, 38281 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 38282 enabled: true, 38283 /** @prop {ModifierFn} */ 38284 fn: offset, 38285 /** @prop {Number|String} offset=0 38286 * The offset value as described in the modifier description 38287 */ 38288 offset: 0 38289 }, 38290 38291 /** 38292 * Modifier used to prevent the popper from being positioned outside the boundary. 38293 * 38294 * A scenario exists where the reference itself is not within the boundaries.<br /> 38295 * We can say it has "escaped the boundaries" — or just "escaped".<br /> 38296 * In this case we need to decide whether the popper should either: 38297 * 38298 * - detach from the reference and remain "trapped" in the boundaries, or 38299 * - if it should ignore the boundary and "escape with its reference" 38300 * 38301 * When `escapeWithReference` is set to`true` and reference is completely 38302 * outside its boundaries, the popper will overflow (or completely leave) 38303 * the boundaries in order to remain attached to the edge of the reference. 38304 * 38305 * @memberof modifiers 38306 * @inner 38307 */ 38308 preventOverflow: { 38309 /** @prop {number} order=300 - Index used to define the order of execution */ 38310 order: 300, 38311 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 38312 enabled: true, 38313 /** @prop {ModifierFn} */ 38314 fn: preventOverflow, 38315 /** 38316 * @prop {Array} [priority=['left','right','top','bottom']] 38317 * Popper will try to prevent overflow following these priorities by default, 38318 * then, it could overflow on the left and on top of the `boundariesElement` 38319 */ 38320 priority: ['left', 'right', 'top', 'bottom'], 38321 /** 38322 * @prop {number} padding=5 38323 * Amount of pixel used to define a minimum distance between the boundaries 38324 * and the popper. This makes sure the popper always has a little padding 38325 * between the edges of its container 38326 */ 38327 padding: 5, 38328 /** 38329 * @prop {String|HTMLElement} boundariesElement='scrollParent' 38330 * Boundaries used by the modifier. Can be `scrollParent`, `window`, 38331 * `viewport` or any DOM element. 38332 */ 38333 boundariesElement: 'scrollParent' 38334 }, 38335 38336 /** 38337 * Modifier used to make sure the reference and its popper stay near each other 38338 * without leaving any gap between the two. Especially useful when the arrow is 38339 * enabled and you want to ensure that it points to its reference element. 38340 * It cares only about the first axis. You can still have poppers with margin 38341 * between the popper and its reference element. 38342 * @memberof modifiers 38343 * @inner 38344 */ 38345 keepTogether: { 38346 /** @prop {number} order=400 - Index used to define the order of execution */ 38347 order: 400, 38348 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 38349 enabled: true, 38350 /** @prop {ModifierFn} */ 38351 fn: keepTogether 38352 }, 38353 38354 /** 38355 * This modifier is used to move the `arrowElement` of the popper to make 38356 * sure it is positioned between the reference element and its popper element. 38357 * It will read the outer size of the `arrowElement` node to detect how many 38358 * pixels of conjunction are needed. 38359 * 38360 * It has no effect if no `arrowElement` is provided. 38361 * @memberof modifiers 38362 * @inner 38363 */ 38364 arrow: { 38365 /** @prop {number} order=500 - Index used to define the order of execution */ 38366 order: 500, 38367 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 38368 enabled: true, 38369 /** @prop {ModifierFn} */ 38370 fn: arrow, 38371 /** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */ 38372 element: '[x-arrow]' 38373 }, 38374 38375 /** 38376 * Modifier used to flip the popper's placement when it starts to overlap its 38377 * reference element. 38378 * 38379 * Requires the `preventOverflow` modifier before it in order to work. 38380 * 38381 * **NOTE:** this modifier will interrupt the current update cycle and will 38382 * restart it if it detects the need to flip the placement. 38383 * @memberof modifiers 38384 * @inner 38385 */ 38386 flip: { 38387 /** @prop {number} order=600 - Index used to define the order of execution */ 38388 order: 600, 38389 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 38390 enabled: true, 38391 /** @prop {ModifierFn} */ 38392 fn: flip, 38393 /** 38394 * @prop {String|Array} behavior='flip' 38395 * The behavior used to change the popper's placement. It can be one of 38396 * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid 38397 * placements (with optional variations) 38398 */ 38399 behavior: 'flip', 38400 /** 38401 * @prop {number} padding=5 38402 * The popper will flip if it hits the edges of the `boundariesElement` 38403 */ 38404 padding: 5, 38405 /** 38406 * @prop {String|HTMLElement} boundariesElement='viewport' 38407 * The element which will define the boundaries of the popper position. 38408 * The popper will never be placed outside of the defined boundaries 38409 * (except if `keepTogether` is enabled) 38410 */ 38411 boundariesElement: 'viewport', 38412 /** 38413 * @prop {Boolean} flipVariations=false 38414 * The popper will switch placement variation between `-start` and `-end` when 38415 * the reference element overlaps its boundaries. 38416 * 38417 * The original placement should have a set variation. 38418 */ 38419 flipVariations: false, 38420 /** 38421 * @prop {Boolean} flipVariationsByContent=false 38422 * The popper will switch placement variation between `-start` and `-end` when 38423 * the popper element overlaps its reference boundaries. 38424 * 38425 * The original placement should have a set variation. 38426 */ 38427 flipVariationsByContent: false 38428 }, 38429 38430 /** 38431 * Modifier used to make the popper flow toward the inner of the reference element. 38432 * By default, when this modifier is disabled, the popper will be placed outside 38433 * the reference element. 38434 * @memberof modifiers 38435 * @inner 38436 */ 38437 inner: { 38438 /** @prop {number} order=700 - Index used to define the order of execution */ 38439 order: 700, 38440 /** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */ 38441 enabled: false, 38442 /** @prop {ModifierFn} */ 38443 fn: inner 38444 }, 38445 38446 /** 38447 * Modifier used to hide the popper when its reference element is outside of the 38448 * popper boundaries. It will set a `x-out-of-boundaries` attribute which can 38449 * be used to hide with a CSS selector the popper when its reference is 38450 * out of boundaries. 38451 * 38452 * Requires the `preventOverflow` modifier before it in order to work. 38453 * @memberof modifiers 38454 * @inner 38455 */ 38456 hide: { 38457 /** @prop {number} order=800 - Index used to define the order of execution */ 38458 order: 800, 38459 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 38460 enabled: true, 38461 /** @prop {ModifierFn} */ 38462 fn: hide 38463 }, 38464 38465 /** 38466 * Computes the style that will be applied to the popper element to gets 38467 * properly positioned. 38468 * 38469 * Note that this modifier will not touch the DOM, it just prepares the styles 38470 * so that `applyStyle` modifier can apply it. This separation is useful 38471 * in case you need to replace `applyStyle` with a custom implementation. 38472 * 38473 * This modifier has `850` as `order` value to maintain backward compatibility 38474 * with previous versions of Popper.js. Expect the modifiers ordering method 38475 * to change in future major versions of the library. 38476 * 38477 * @memberof modifiers 38478 * @inner 38479 */ 38480 computeStyle: { 38481 /** @prop {number} order=850 - Index used to define the order of execution */ 38482 order: 850, 38483 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 38484 enabled: true, 38485 /** @prop {ModifierFn} */ 38486 fn: computeStyle, 38487 /** 38488 * @prop {Boolean} gpuAcceleration=true 38489 * If true, it uses the CSS 3D transformation to position the popper. 38490 * Otherwise, it will use the `top` and `left` properties 38491 */ 38492 gpuAcceleration: true, 38493 /** 38494 * @prop {string} [x='bottom'] 38495 * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin. 38496 * Change this if your popper should grow in a direction different from `bottom` 38497 */ 38498 x: 'bottom', 38499 /** 38500 * @prop {string} [x='left'] 38501 * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin. 38502 * Change this if your popper should grow in a direction different from `right` 38503 */ 38504 y: 'right' 38505 }, 38506 38507 /** 38508 * Applies the computed styles to the popper element. 38509 * 38510 * All the DOM manipulations are limited to this modifier. This is useful in case 38511 * you want to integrate Popper.js inside a framework or view library and you 38512 * want to delegate all the DOM manipulations to it. 38513 * 38514 * Note that if you disable this modifier, you must make sure the popper element 38515 * has its position set to `absolute` before Popper.js can do its work! 38516 * 38517 * Just disable this modifier and define your own to achieve the desired effect. 38518 * 38519 * @memberof modifiers 38520 * @inner 38521 */ 38522 applyStyle: { 38523 /** @prop {number} order=900 - Index used to define the order of execution */ 38524 order: 900, 38525 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 38526 enabled: true, 38527 /** @prop {ModifierFn} */ 38528 fn: applyStyle, 38529 /** @prop {Function} */ 38530 onLoad: applyStyleOnLoad, 38531 /** 38532 * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier 38533 * @prop {Boolean} gpuAcceleration=true 38534 * If true, it uses the CSS 3D transformation to position the popper. 38535 * Otherwise, it will use the `top` and `left` properties 38536 */ 38537 gpuAcceleration: undefined 38538 } 38539}; 38540 38541/** 38542 * The `dataObject` is an object containing all the information used by Popper.js. 38543 * This object is passed to modifiers and to the `onCreate` and `onUpdate` callbacks. 38544 * @name dataObject 38545 * @property {Object} data.instance The Popper.js instance 38546 * @property {String} data.placement Placement applied to popper 38547 * @property {String} data.originalPlacement Placement originally defined on init 38548 * @property {Boolean} data.flipped True if popper has been flipped by flip modifier 38549 * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper 38550 * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier 38551 * @property {Object} data.styles Any CSS property defined here will be applied to the popper. It expects the JavaScript nomenclature (eg. `marginBottom`) 38552 * @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow. It expects the JavaScript nomenclature (eg. `marginBottom`) 38553 * @property {Object} data.boundaries Offsets of the popper boundaries 38554 * @property {Object} data.offsets The measurements of popper, reference and arrow elements 38555 * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values 38556 * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values 38557 * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0 38558 */ 38559 38560/** 38561 * Default options provided to Popper.js constructor.<br /> 38562 * These can be overridden using the `options` argument of Popper.js.<br /> 38563 * To override an option, simply pass an object with the same 38564 * structure of the `options` object, as the 3rd argument. For example: 38565 * ``` 38566 * new Popper(ref, pop, { 38567 * modifiers: { 38568 * preventOverflow: { enabled: false } 38569 * } 38570 * }) 38571 * ``` 38572 * @type {Object} 38573 * @static 38574 * @memberof Popper 38575 */ 38576var Defaults = { 38577 /** 38578 * Popper's placement. 38579 * @prop {Popper.placements} placement='bottom' 38580 */ 38581 placement: 'bottom', 38582 38583 /** 38584 * Set this to true if you want popper to position it self in 'fixed' mode 38585 * @prop {Boolean} positionFixed=false 38586 */ 38587 positionFixed: false, 38588 38589 /** 38590 * Whether events (resize, scroll) are initially enabled. 38591 * @prop {Boolean} eventsEnabled=true 38592 */ 38593 eventsEnabled: true, 38594 38595 /** 38596 * Set to true if you want to automatically remove the popper when 38597 * you call the `destroy` method. 38598 * @prop {Boolean} removeOnDestroy=false 38599 */ 38600 removeOnDestroy: false, 38601 38602 /** 38603 * Callback called when the popper is created.<br /> 38604 * By default, it is set to no-op.<br /> 38605 * Access Popper.js instance with `data.instance`. 38606 * @prop {onCreate} 38607 */ 38608 onCreate: function onCreate() {}, 38609 38610 /** 38611 * Callback called when the popper is updated. This callback is not called 38612 * on the initialization/creation of the popper, but only on subsequent 38613 * updates.<br /> 38614 * By default, it is set to no-op.<br /> 38615 * Access Popper.js instance with `data.instance`. 38616 * @prop {onUpdate} 38617 */ 38618 onUpdate: function onUpdate() {}, 38619 38620 /** 38621 * List of modifiers used to modify the offsets before they are applied to the popper. 38622 * They provide most of the functionalities of Popper.js. 38623 * @prop {modifiers} 38624 */ 38625 modifiers: modifiers 38626}; 38627 38628/** 38629 * @callback onCreate 38630 * @param {dataObject} data 38631 */ 38632 38633/** 38634 * @callback onUpdate 38635 * @param {dataObject} data 38636 */ 38637 38638// Utils 38639// Methods 38640var Popper = function () { 38641 /** 38642 * Creates a new Popper.js instance. 38643 * @class Popper 38644 * @param {Element|referenceObject} reference - The reference element used to position the popper 38645 * @param {Element} popper - The HTML / XML element used as the popper 38646 * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults) 38647 * @return {Object} instance - The generated Popper.js instance 38648 */ 38649 function Popper(reference, popper) { 38650 var _this = this; 38651 38652 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 38653 classCallCheck(this, Popper); 38654 38655 this.scheduleUpdate = function () { 38656 return requestAnimationFrame(_this.update); 38657 }; 38658 38659 // make update() debounced, so that it only runs at most once-per-tick 38660 this.update = debounce(this.update.bind(this)); 38661 38662 // with {} we create a new object with the options inside it 38663 this.options = _extends({}, Popper.Defaults, options); 38664 38665 // init state 38666 this.state = { 38667 isDestroyed: false, 38668 isCreated: false, 38669 scrollParents: [] 38670 }; 38671 38672 // get reference and popper elements (allow jQuery wrappers) 38673 this.reference = reference && reference.jquery ? reference[0] : reference; 38674 this.popper = popper && popper.jquery ? popper[0] : popper; 38675 38676 // Deep merge modifiers options 38677 this.options.modifiers = {}; 38678 Object.keys(_extends({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) { 38679 _this.options.modifiers[name] = _extends({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {}); 38680 }); 38681 38682 // Refactoring modifiers' list (Object => Array) 38683 this.modifiers = Object.keys(this.options.modifiers).map(function (name) { 38684 return _extends({ 38685 name: name 38686 }, _this.options.modifiers[name]); 38687 }) 38688 // sort the modifiers by order 38689 .sort(function (a, b) { 38690 return a.order - b.order; 38691 }); 38692 38693 // modifiers have the ability to execute arbitrary code when Popper.js get inited 38694 // such code is executed in the same order of its modifier 38695 // they could add new properties to their options configuration 38696 // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`! 38697 this.modifiers.forEach(function (modifierOptions) { 38698 if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) { 38699 modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state); 38700 } 38701 }); 38702 38703 // fire the first update to position the popper in the right place 38704 this.update(); 38705 38706 var eventsEnabled = this.options.eventsEnabled; 38707 if (eventsEnabled) { 38708 // setup event listeners, they will take care of update the position in specific situations 38709 this.enableEventListeners(); 38710 } 38711 38712 this.state.eventsEnabled = eventsEnabled; 38713 } 38714 38715 // We can't use class properties because they don't get listed in the 38716 // class prototype and break stuff like Sinon stubs 38717 38718 38719 createClass(Popper, [{ 38720 key: 'update', 38721 value: function update$$1() { 38722 return update.call(this); 38723 } 38724 }, { 38725 key: 'destroy', 38726 value: function destroy$$1() { 38727 return destroy.call(this); 38728 } 38729 }, { 38730 key: 'enableEventListeners', 38731 value: function enableEventListeners$$1() { 38732 return enableEventListeners.call(this); 38733 } 38734 }, { 38735 key: 'disableEventListeners', 38736 value: function disableEventListeners$$1() { 38737 return disableEventListeners.call(this); 38738 } 38739 38740 /** 38741 * Schedules an update. It will run on the next UI update available. 38742 * @method scheduleUpdate 38743 * @memberof Popper 38744 */ 38745 38746 38747 /** 38748 * Collection of utilities useful when writing custom modifiers. 38749 * Starting from version 1.7, this method is available only if you 38750 * include `popper-utils.js` before `popper.js`. 38751 * 38752 * **DEPRECATION**: This way to access PopperUtils is deprecated 38753 * and will be removed in v2! Use the PopperUtils module directly instead. 38754 * Due to the high instability of the methods contained in Utils, we can't 38755 * guarantee them to follow semver. Use them at your own risk! 38756 * @static 38757 * @private 38758 * @type {Object} 38759 * @deprecated since version 1.8 38760 * @member Utils 38761 * @memberof Popper 38762 */ 38763 38764 }]); 38765 return Popper; 38766}(); 38767 38768/** 38769 * The `referenceObject` is an object that provides an interface compatible with Popper.js 38770 * and lets you use it as replacement of a real DOM node.<br /> 38771 * You can use this method to position a popper relatively to a set of coordinates 38772 * in case you don't have a DOM node to use as reference. 38773 * 38774 * ``` 38775 * new Popper(referenceObject, popperNode); 38776 * ``` 38777 * 38778 * NB: This feature isn't supported in Internet Explorer 10. 38779 * @name referenceObject 38780 * @property {Function} data.getBoundingClientRect 38781 * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method. 38782 * @property {number} data.clientWidth 38783 * An ES6 getter that will return the width of the virtual reference element. 38784 * @property {number} data.clientHeight 38785 * An ES6 getter that will return the height of the virtual reference element. 38786 */ 38787 38788 38789Popper.Utils = (typeof window !== 'undefined' ? window : global).PopperUtils; 38790Popper.placements = placements; 38791Popper.Defaults = Defaults; 38792 38793return Popper; 38794 38795})));
38796 38797 38798}
vendor: 6,571 bytes, lines 38798-39017
38798).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 38799},{}],16:[function(require,module,exports){ 38800// shim for using process in browser 38801var process = module.exports = {}; 38802 38803// cached from whatever global is present so that test runners that stub it 38804// don't break things. But we need to wrap it in a try catch in case it is 38805// wrapped in strict mode code which doesn't define any globals. It's inside a 38806// function because try/catches deoptimize in certain engines. 38807 38808var cachedSetTimeout; 38809var cachedClearTimeout; 38810 38811function defaultSetTimout() { 38812 throw new Error('setTimeout has not been defined'); 38813} 38814function defaultClearTimeout () { 38815 throw new Error('clearTimeout has not been defined'); 38816} 38817(function () { 38818 try { 38819 if (typeof setTimeout === 'function') { 38820 cachedSetTimeout = setTimeout; 38821 } else { 38822 cachedSetTimeout = defaultSetTimout; 38823 } 38824 } catch (e) { 38825 cachedSetTimeout = defaultSetTimout; 38826 } 38827 try { 38828 if (typeof clearTimeout === 'function') { 38829 cachedClearTimeout = clearTimeout; 38830 } else { 38831 cachedClearTimeout = defaultClearTimeout; 38832 } 38833 } catch (e) { 38834 cachedClearTimeout = defaultClearTimeout; 38835 } 38836} ()) 38837function runTimeout(fun) { 38838 if (cachedSetTimeout === setTimeout) { 38839 //normal enviroments in sane situations 38840 return setTimeout(fun, 0); 38841 } 38842 // if setTimeout wasn't available but was latter defined 38843 if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { 38844 cachedSetTimeout = setTimeout; 38845 return setTimeout(fun, 0); 38846 } 38847 try { 38848 // when when somebody has screwed with setTimeout but no I.E. maddness 38849 return cachedSetTimeout(fun, 0); 38850 } catch(e){ 38851 try { 38852 // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally 38853 return cachedSetTimeout.call(null, fun, 0); 38854 } catch(e){ 38855 // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error 38856 return cachedSetTimeout.call(this, fun, 0); 38857 } 38858 } 38859 38860 38861} 38862function runClearTimeout(marker) { 38863 if (cachedClearTimeout === clearTimeout) { 38864 //normal enviroments in sane situations 38865 return clearTimeout(marker); 38866 } 38867 // if clearTimeout wasn't available but was latter defined 38868 if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { 38869 cachedClearTimeout = clearTimeout; 38870 return clearTimeout(marker); 38871 } 38872 try { 38873 // when when somebody has screwed with setTimeout but no I.E. maddness 38874 return cachedClearTimeout(marker); 38875 } catch (e){ 38876 try { 38877 // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally 38878 return cachedClearTimeout.call(null, marker); 38879 } catch (e){ 38880 // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. 38881 // Some versions of I.E. have different rules for clearTimeout vs setTimeout 38882 return cachedClearTimeout.call(this, marker); 38883 } 38884 } 38885 38886 38887 38888} 38889var queue = []; 38890var draining = false; 38891var currentQueue; 38892var queueIndex = -1; 38893 38894function cleanUpNextTick() { 38895 if (!draining || !currentQueue) { 38896 return; 38897 } 38898 draining = false; 38899 if (currentQueue.length) { 38900 queue = currentQueue.concat(queue); 38901 } else { 38902 queueIndex = -1; 38903 } 38904 if (queue.length) { 38905 drainQueue(); 38906 } 38907} 38908 38909function drainQueue() { 38910 if (draining) { 38911 return; 38912 } 38913 var timeout = runTimeout(cleanUpNextTick); 38914 draining = true; 38915 38916 var len = queue.length; 38917 while(len) { 38918 currentQueue = queue; 38919 queue = []; 38920 while (++queueIndex < len) { 38921 if (currentQueue) { 38922 currentQueue[queueIndex].run(); 38923 } 38924 } 38925 queueIndex = -1; 38926 len = queue.length; 38927 } 38928 currentQueue = null; 38929 draining = false; 38930 runClearTimeout(timeout); 38931} 38932 38933process.nextTick = function (fun) { 38934 var args = new Array(arguments.length - 1); 38935 if (arguments.length > 1) { 38936 for (var i = 1; i < arguments.length; i++) { 38937 args[i - 1] = arguments[i]; 38938 } 38939 } 38940 queue.push(new Item(fun, args)); 38941 if (queue.length === 1 && !draining) { 38942 runTimeout(drainQueue); 38943 } 38944}; 38945 38946// v8 likes predictible objects 38947function Item(fun, array) { 38948 this.fun = fun; 38949 this.array = array; 38950} 38951Item.prototype.run = function () { 38952 this.fun.apply(null, this.array); 38953}; 38954process.title = 'browser'; 38955process.browser = true; 38956process.env = {}; 38957process.argv = []; 38958process.version = ''; // empty string to avoid regexp issues 38959process.versions = {}; 38960 38961function noop() {} 38962 38963process.on = noop; 38964process.addListener = noop; 38965process.once = noop; 38966process.off = noop; 38967process.removeListener = noop; 38968process.removeAllListeners = noop; 38969process.emit = noop; 38970process.prependListener = noop; 38971process.prependOnceListener = noop; 38972 38973process.listeners = function (name) { return [] } 38974 38975process.binding = function (name) { 38976 throw new Error('process.binding is not supported'); 38977}; 38978 38979process.cwd = function () { return '/' }; 38980process.chdir = function (dir) { 38981 throw new Error('process.chdir is not supported'); 38982}; 38983process.umask = function() { return 0; }; 38984 38985},{}],17:[function(require,module,exports){ 38986if (typeof Object.create === 'function') { 38987 // implementation from standard node.js 'util' module 38988 module.exports = function inherits(ctor, superCtor) { 38989 ctor.super_ = superCtor 38990 ctor.prototype = Object.create(superCtor.prototype, { 38991 constructor: { 38992 value: ctor, 38993 enumerable: false, 38994 writable: true, 38995 configurable: true 38996 } 38997 }); 38998 }; 38999} else { 39000 // old school shim for old browsers 39001 module.exports = function inherits(ctor, superCtor) { 39002 ctor.super_ = superCtor 39003 var TempCtor = function () {} 39004 TempCtor.prototype = superCtor.prototype 39005 ctor.prototype = new TempCtor() 39006 ctor.prototype.constructor = ctor 39007 } 39008} 39009 39010},{}],18:[function(require,module,exports){ 39011module.exports = function isBuffer(arg) { 39012 return arg && typeof arg === 'object' 39013 && typeof arg.copy === 'function' 39014 && typeof arg.fill === 'function' 39015 && typeof arg.readUInt8 === 'function'; 39016} 39017},{}],19
vendor: 15,808 bytes, lines 39017-39607
39017:[function(require,module,exports){ 39018(function (process,global){ 39019// Copyright Joyent, Inc. and other Node contributors. 39020// 39021// Permission is hereby granted, free of charge, to any person obtaining a 39022// copy of this software and associated documentation files (the 39023// "Software"), to deal in the Software without restriction, including 39024// without limitation the rights to use, copy, modify, merge, publish, 39025// distribute, sublicense, and/or sell copies of the Software, and to permit 39026// persons to whom the Software is furnished to do so, subject to the 39027// following conditions: 39028// 39029// The above copyright notice and this permission notice shall be included 39030// in all copies or substantial portions of the Software. 39031// 39032// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 39033// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 39034// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 39035// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 39036// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 39037// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 39038// USE OR OTHER DEALINGS IN THE SOFTWARE. 39039 39040var formatRegExp = /%[sdj%]/g; 39041exports.format = function(f) { 39042 if (!isString(f)) { 39043 var objects = []; 39044 for (var i = 0; i < arguments.length; i++) { 39045 objects.push(inspect(arguments[i])); 39046 } 39047 return objects.join(' '); 39048 } 39049 39050 var i = 1; 39051 var args = arguments; 39052 var len = args.length; 39053 var str = String(f).replace(formatRegExp, function(x) { 39054 if (x === '%%') return '%'; 39055 if (i >= len) return x; 39056 switch (x) { 39057 case '%s': return String(args[i++]); 39058 case '%d': return Number(args[i++]); 39059 case '%j': 39060 try { 39061 return JSON.stringify(args[i++]); 39062 } catch (_) { 39063 return '[Circular]'; 39064 } 39065 default: 39066 return x; 39067 } 39068 }); 39069 for (var x = args[i]; i < len; x = args[++i]) { 39070 if (isNull(x) || !isObject(x)) { 39071 str += ' ' + x; 39072 } else { 39073 str += ' ' + inspect(x); 39074 } 39075 } 39076 return str; 39077}; 39078 39079 39080// Mark that a method should not be used. 39081// Returns a modified function which warns once by default. 39082// If --no-deprecation is set, then it is a no-op. 39083exports.deprecate = function(fn, msg) { 39084 // Allow for deprecating things in the process of starting up. 39085 if (isUndefined(global.process)) { 39086 return function() { 39087 return exports.deprecate(fn, msg).apply(this, arguments); 39088 }; 39089 } 39090 39091 if (process.noDeprecation === true) { 39092 return fn; 39093 } 39094 39095 var warned = false; 39096 function deprecated() { 39097 if (!warned) { 39098 if (process.throwDeprecation) { 39099 throw new Error(msg); 39100 } else if (process.traceDeprecation) { 39101 console.trace(msg); 39102 } else { 39103 console.error(msg); 39104 } 39105 warned = true; 39106 } 39107 return fn.apply(this, arguments); 39108 } 39109 39110 return deprecated; 39111}; 39112 39113 39114var debugs = {}; 39115var debugEnviron; 39116exports.debuglog = function(set) { 39117 if (isUndefined(debugEnviron)) 39118 debugEnviron = process.env.NODE_DEBUG || ''; 39119 set = set.toUpperCase(); 39120 if (!debugs[set]) { 39121 if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { 39122 var pid = process.pid; 39123 debugs[set] = function() { 39124 var msg = exports.format.apply(exports, arguments); 39125 console.error('%s %d: %s', set, pid, msg); 39126 }; 39127 } else { 39128 debugs[set] = function() {}; 39129 } 39130 } 39131 return debugs[set]; 39132}; 39133 39134 39135/** 39136 * Echos the value of a value. Trys to print the value out 39137 * in the best way possible given the different types. 39138 * 39139 * @param {Object} obj The object to print out. 39140 * @param {Object} opts Optional options object that alters the output. 39141 */ 39142/* legacy: obj, showHidden, depth, colors*/ 39143function inspect(obj, opts) { 39144 // default options 39145 var ctx = { 39146 seen: [], 39147 stylize: stylizeNoColor 39148 }; 39149 // legacy... 39150 if (arguments.length >= 3) ctx.depth = arguments[2]; 39151 if (arguments.length >= 4) ctx.colors = arguments[3]; 39152 if (isBoolean(opts)) { 39153 // legacy... 39154 ctx.showHidden = opts; 39155 } else if (opts) { 39156 // got an "options" object 39157 exports._extend(ctx, opts); 39158 } 39159 // set default options 39160 if (isUndefined(ctx.showHidden)) ctx.showHidden = false; 39161 if (isUndefined(ctx.depth)) ctx.depth = 2; 39162 if (isUndefined(ctx.colors)) ctx.colors = false; 39163 if (isUndefined(ctx.customInspect)) ctx.customInspect = true; 39164 if (ctx.colors) ctx.stylize = stylizeWithColor; 39165 return formatValue(ctx, obj, ctx.depth); 39166} 39167exports.inspect = inspect; 39168 39169 39170// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics 39171inspect.colors = { 39172 'bold' : [1, 22], 39173 'italic' : [3, 23], 39174 'underline' : [4, 24], 39175 'inverse' : [7, 27], 39176 'white' : [37, 39], 39177 'grey' : [90, 39], 39178 'black' : [30, 39], 39179 'blue' : [34, 39], 39180 'cyan' : [36, 39], 39181 'green' : [32, 39], 39182 'magenta' : [35, 39], 39183 'red' : [31, 39], 39184 'yellow' : [33, 39] 39185}; 39186 39187// Don't use 'blue' not visible on cmd.exe 39188inspect.styles = { 39189 'special': 'cyan', 39190 'number': 'yellow', 39191 'boolean': 'yellow', 39192 'undefined': 'grey', 39193 'null': 'bold', 39194 'string': 'green', 39195 'date': 'magenta', 39196 // "name": intentionally not styling 39197 'regexp': 'red' 39198}; 39199 39200 39201function stylizeWithColor(str, styleType) { 39202 var style = inspect.styles[styleType]; 39203 39204 if (style) { 39205 return '\u001b[' + inspect.colors[style][0] + 'm' + str + 39206 '\u001b[' + inspect.colors[style][1] + 'm'; 39207 } else { 39208 return str; 39209 } 39210} 39211 39212 39213function stylizeNoColor(str, styleType) { 39214 return str; 39215} 39216 39217 39218function arrayToHash(array) { 39219 var hash = {}; 39220 39221 array.forEach(function(val, idx) { 39222 hash[val] = true; 39223 }); 39224 39225 return hash; 39226} 39227 39228 39229function formatValue(ctx, value, recurseTimes) { 39230 // Provide a hook for user-specified inspect functions. 39231 // Check that value is an object with an inspect function on it 39232 if (ctx.customInspect && 39233 value && 39234 isFunction(value.inspect) && 39235 // Filter out the util module, it's inspect function is special 39236 value.inspect !== exports.inspect && 39237 // Also filter out any prototype objects using the circular check. 39238 !(value.constructor && value.constructor.prototype === value)) { 39239 var ret = value.inspect(recurseTimes, ctx); 39240 if (!isString(ret)) { 39241 ret = formatValue(ctx, ret, recurseTimes); 39242 } 39243 return ret; 39244 } 39245 39246 // Primitive types cannot have properties 39247 var primitive = formatPrimitive(ctx, value); 39248 if (primitive) { 39249 return primitive; 39250 } 39251 39252 // Look up the keys of the object. 39253 var keys = Object.keys(value); 39254 var visibleKeys = arrayToHash(keys); 39255 39256 if (ctx.showHidden) { 39257 keys = Object.getOwnPropertyNames(value); 39258 } 39259 39260 // IE doesn't make error fields non-enumerable 39261 // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx 39262 if (isError(value) 39263 && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { 39264 return formatError(value); 39265 } 39266 39267 // Some type of object without properties can be shortcutted. 39268 if (keys.length === 0) { 39269 if (isFunction(value)) { 39270 var name = value.name ? ': ' + value.name : ''; 39271 return ctx.stylize('[Function' + name + ']', 'special'); 39272 } 39273 if (isRegExp(value)) { 39274 return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); 39275 } 39276 if (isDate(value)) { 39277 return ctx.stylize(Date.prototype.toString.call(value), 'date'); 39278 } 39279 if (isError(value)) { 39280 return formatError(value); 39281 } 39282 } 39283 39284 var base = '', array = false, braces = ['{', '}']; 39285 39286 // Make Array say that they are Array 39287 if (isArray(value)) { 39288 array = true; 39289 braces = ['[', ']']; 39290 } 39291 39292 // Make functions say that they are functions 39293 if (isFunction(value)) { 39294 var n = value.name ? ': ' + value.name : ''; 39295 base = ' [Function' + n + ']'; 39296 } 39297 39298 // Make RegExps say that they are RegExps 39299 if (isRegExp(value)) { 39300 base = ' ' + RegExp.prototype.toString.call(value); 39301 } 39302 39303 // Make dates with properties first say the date 39304 if (isDate(value)) { 39305 base = ' ' + Date.prototype.toUTCString.call(value); 39306 } 39307 39308 // Make error with message first say the error 39309 if (isError(value)) { 39310 base = ' ' + formatError(value); 39311 } 39312 39313 if (keys.length === 0 && (!array || value.length == 0)) { 39314 return braces[0] + base + braces[1]; 39315 } 39316 39317 if (recurseTimes < 0) { 39318 if (isRegExp(value)) { 39319 return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); 39320 } else { 39321 return ctx.stylize('[Object]', 'special'); 39322 } 39323 } 39324 39325 ctx.seen.push(value); 39326 39327 var output; 39328 if (array) { 39329 output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); 39330 } else { 39331 output = keys.map(function(key) { 39332 return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); 39333 }); 39334 } 39335 39336 ctx.seen.pop(); 39337 39338 return reduceToSingleString(output, base, braces); 39339} 39340 39341 39342function formatPrimitive(ctx, value) { 39343 if (isUndefined(value)) 39344 return ctx.stylize('undefined', 'undefined'); 39345 if (isString(value)) { 39346 var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') 39347 .replace(/'/g, "\\'") 39348 .replace(/\\"/g, '"') + '\''; 39349 return ctx.stylize(simple, 'string'); 39350 } 39351 if (isNumber(value)) 39352 return ctx.stylize('' + value, 'number'); 39353 if (isBoolean(value)) 39354 return ctx.stylize('' + value, 'boolean'); 39355 // For some reason typeof null is "object", so special case here. 39356 if (isNull(value)) 39357 return ctx.stylize('null', 'null'); 39358} 39359 39360 39361function formatError(value) { 39362 return '[' + Error.prototype.toString.call(value) + ']'; 39363} 39364 39365 39366function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { 39367 var output = []; 39368 for (var i = 0, l = value.length; i < l; ++i) { 39369 if (hasOwnProperty(value, String(i))) { 39370 output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, 39371 String(i), true)); 39372 } else { 39373 output.push(''); 39374 } 39375 } 39376 keys.forEach(function(key) { 39377 if (!key.match(/^\d+$/)) { 39378 output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, 39379 key, true)); 39380 } 39381 }); 39382 return output; 39383} 39384 39385 39386function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { 39387 var name, str, desc; 39388 desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; 39389 if (desc.get) { 39390 if (desc.set) { 39391 str = ctx.stylize('[Getter/Setter]', 'special'); 39392 } else { 39393 str = ctx.stylize('[Getter]', 'special'); 39394 } 39395 } else { 39396 if (desc.set) { 39397 str = ctx.stylize('[Setter]', 'special'); 39398 } 39399 } 39400 if (!hasOwnProperty(visibleKeys, key)) { 39401 name = '[' + key + ']'; 39402 } 39403 if (!str) { 39404 if (ctx.seen.indexOf(desc.value) < 0) { 39405 if (isNull(recurseTimes)) { 39406 str = formatValue(ctx, desc.value, null); 39407 } else { 39408 str = formatValue(ctx, desc.value, recurseTimes - 1); 39409 } 39410 if (str.indexOf('\n') > -1) { 39411 if (array) { 39412 str = str.split('\n').map(function(line) { 39413 return ' ' + line; 39414 }).join('\n').substr(2); 39415 } else { 39416 str = '\n' + str.split('\n').map(function(line) { 39417 return ' ' + line; 39418 }).join('\n'); 39419 } 39420 } 39421 } else { 39422 str = ctx.stylize('[Circular]', 'special'); 39423 } 39424 } 39425 if (isUndefined(name)) { 39426 if (array && key.match(/^\d+$/)) { 39427 return str; 39428 } 39429 name = JSON.stringify('' + key); 39430 if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { 39431 name = name.substr(1, name.length - 2); 39432 name = ctx.stylize(name, 'name'); 39433 } else { 39434 name = name.replace(/'/g, "\\'") 39435 .replace(/\\"/g, '"') 39436 .replace(/(^"|"$)/g, "'"); 39437 name = ctx.stylize(name, 'string'); 39438 } 39439 } 39440 39441 return name + ': ' + str; 39442} 39443 39444 39445function reduceToSingleString(output, base, braces) { 39446 var numLinesEst = 0; 39447 var length = output.reduce(function(prev, cur) { 39448 numLinesEst++; 39449 if (cur.indexOf('\n') >= 0) numLinesEst++; 39450 return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; 39451 }, 0); 39452 39453 if (length > 60) { 39454 return braces[0] + 39455 (base === '' ? '' : base + '\n ') + 39456 ' ' + 39457 output.join(',\n ') + 39458 ' ' + 39459 braces[1]; 39460 } 39461 39462 return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; 39463} 39464 39465 39466// NOTE: These type checking functions intentionally don't use `instanceof` 39467// because it is fragile and can be easily faked with `Object.create()`. 39468function isArray(ar) { 39469 return Array.isArray(ar); 39470} 39471exports.isArray = isArray; 39472 39473function isBoolean(arg) { 39474 return typeof arg === 'boolean'; 39475} 39476exports.isBoolean = isBoolean; 39477 39478function isNull(arg) { 39479 return arg === null; 39480} 39481exports.isNull = isNull; 39482 39483function isNullOrUndefined(arg) { 39484 return arg == null; 39485} 39486exports.isNullOrUndefined = isNullOrUndefined; 39487 39488function isNumber(arg) { 39489 return typeof arg === 'number'; 39490} 39491exports.isNumber = isNumber; 39492 39493function isString(arg) { 39494 return typeof arg === 'string'; 39495} 39496exports.isString = isString; 39497 39498function isSymbol(arg) { 39499 return typeof arg === 'symbol'; 39500} 39501exports.isSymbol = isSymbol; 39502 39503function isUndefined(arg) { 39504 return arg === void 0; 39505} 39506exports.isUndefined = isUndefined; 39507 39508function isRegExp(re) { 39509 return isObject(re) && objectToString(re) === '[object RegExp]'; 39510} 39511exports.isRegExp = isRegExp; 39512 39513function isObject(arg) { 39514 return typeof arg === 'object' && arg !== null; 39515} 39516exports.isObject = isObject; 39517 39518function isDate(d) { 39519 return isObject(d) && objectToString(d) === '[object Date]'; 39520} 39521exports.isDate = isDate; 39522 39523function isError(e) { 39524 return isObject(e) && 39525 (objectToString(e) === '[object Error]' || e instanceof Error); 39526} 39527exports.isError = isError; 39528 39529function isFunction(arg) { 39530 return typeof arg === 'function'; 39531} 39532exports.isFunction = isFunction; 39533 39534function isPrimitive(arg) { 39535 return arg === null || 39536 typeof arg === 'boolean' || 39537 typeof arg === 'number' || 39538 typeof arg === 'string' || 39539 typeof arg === 'symbol' || // ES6 symbol 39540 typeof arg === 'undefined'; 39541} 39542exports.isPrimitive = isPrimitive; 39543 39544exports.isBuffer = require('./support/isBuffer'); 39545 39546function objectToString(o) { 39547 return Object.prototype.toString.call(o); 39548} 39549 39550 39551function pad(n) { 39552 return n < 10 ? '0' + n.toString(10) : n.toString(10); 39553} 39554 39555 39556var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 39557 'Oct', 'Nov', 'Dec']; 39558 39559// 26 Feb 16:19:34 39560function timestamp() { 39561 var d = new Date(); 39562 var time = [pad(d.getHours()), 39563 pad(d.getMinutes()), 39564 pad(d.getSeconds())].join(':'); 39565 return [d.getDate(), months[d.getMonth()], time].join(' '); 39566} 39567 39568 39569// log is just a thin wrapper to console.log that prepends a timestamp 39570exports.log = function() { 39571 console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); 39572}; 39573 39574 39575/** 39576 * Inherit the prototype methods from one constructor into another. 39577 * 39578 * The Function.prototype.inherits from lang.js rewritten as a standalone 39579 * function (not on Function.prototype). NOTE: If this file is to be loaded 39580 * during bootstrapping this function needs to be rewritten using some native 39581 * functions as prototype setup using normal JavaScript does not work as 39582 * expected during bootstrapping (see mirror.js in r114903). 39583 * 39584 * @param {function} ctor Constructor function which needs to inherit the 39585 * prototype. 39586 * @param {function} superCtor Constructor function to inherit prototype from. 39587 */ 39588exports.inherits = require('inherits'); 39589 39590exports._extend = function(origin, add) { 39591 // Don't do anything if add isn't an object 39592 if (!add || !isObject(add)) return origin; 39593 39594 var keys = Object.keys(add); 39595 var i = keys.length; 39596 while (i--) { 39597 origin[keys[i]] = add[keys[i]]; 39598 } 39599 return origin; 39600}; 39601 39602function hasOwnProperty(obj, prop) { 39603 return Object.prototype.hasOwnProperty.call(obj, prop); 39604} 39605 39606}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 39607},{"./support/isBuffer":
3960718,"_process":16,"inherits":17}],20:[function(require,module,exports){ 39608"use strict"; 39609Object.defineProperty(exports, "__esModule", { value: true }); 39610const util_1 = require("util"); 39611window.addEventListener("DOMContentLoaded", function () { 39612 const deleting = (el) => { 39613 // return function since this is a callback 39614 return function () { 39615 if (document.getElementsByName(document.getElementById(el.getAttribute("id").replace(/(delButton)/, "div")).getAttribute("name")).length !== 1) { 39616 const form = document.getElementById("update"); 39617 const div = document.getElementById(el.getAttribute("id").replace(/(delButton)/, "div")); 39618 form.removeChild(div); 39619 } 39620 }; 39621 }; 39622 const adding = (el) => { 39623 // return function since this is a callback 39624 return function () { 39625 const idOfDiv = el.getAttribute("id").replace(/(addButton)/, "div"); 39626 const div = document.getElementById(idOfDiv); 39627 const newDiv = div.cloneNode(true); 39628 // Find the number in the id and cast to number 39629 let stringNumbers = ""; 39630 idOfDiv.match(/([0-9]+)/g).forEach((element) => { 39631 stringNumbers += element; 39632 }); 39633 let number = Number(stringNumbers); 39634 // Create a unique id. Must check if the number is occupied by anyone else. If it is then increment until an unoccupied id is found. 39635 while (!util_1.isNullOrUndefined(document.getElementById(idOfDiv.replace(stringNumbers, String(number))))) { 39636 number = number + 1; 39637 } 39638 // Replace ids for the elements 39639 // Unfortunately div is a node and children of elements are nodes. A workaround is to find any of their children and go back to the parentElement since this is an element. Very messy 39640 newDiv.firstChild.parentElement.setAttribute("id", idOfDiv.replace(stringNumbers, String(number))); 39641 newDiv.childNodes[1].childNodes[0].firstChild.parentElement.setAttribute("id", idOfDiv.replace(stringNumbers + "div", String(number))); 39642 newDiv.childNodes[2].childNodes[0].firstChild.parentElement.setAttribute("id", idOfDiv.replace(stringNumbers + "div", String(number) + "addButton")); 39643 newDiv.childNodes[2].childNodes[0].firstChild.parentElement.addEventListener("click", adding(newDiv.childNodes[2].childNodes[0].firstChild.parentElement)); 39644 newDiv.childNodes[2].childNodes[2].firstChild.parentElement.setAttribute("id", idOfDiv.replace(stringNumbers + "div", String(number) + "delButton")); 39645 newDiv.childNodes[2].childNodes[2].firstChild.parentElement.addEventListener("click", deleting(newDiv.childNodes[2].childNodes[2].firstChild.parentElement)); 39646 div.parentNode.insertBefore(newDiv, div.nextSibling); 39647 }; 39648 }; 39649 // const removeUser = (el: HTMLElement) => { 39650 // console.log("Setup: " + el.id); 39651 // return function() { 39652 // console.log("Cicked: " + el.id); 39653 // }; 39654 // }; 39655 const addElements = document.getElementsByName("addButton"); 39656 Array.prototype.forEach.call(addElements, function (el) { 39657 el.addEventListener("click", adding(el)); 39658 }); 39659 const delElements = document.getElementsByName("delButton"); 39660 Array.prototype.forEach.call(delElements, function (el) { 39661 el.addEventListener("click", deleting(el)); 39662 }); 39663 // const removeUserButtons = document.getElementsByName("removeButton"); 39664 // Array.prototype.forEach.call(removeUserButtons, function(el: HTMLElement) { 39665 // el.addEventListener("click", removeUser(el)); 39666 // }); 39667}); 39668 39669},{"util":19}],21:[function(require,module,exports){ 39670"use strict"; 39671var __importDefault = (this && this.__importDefault) || function (mod) { 39672 return (mod && mod.__esModule) ? mod : { "default": mod }; 39673}; 39674Object.defineProperty(exports, "__esModule", { value: true }); 39675const aos_1 = __importDefault(require("aos")); 39676// Animate elements on your page as you scroll 39677aos_1.default.init(); 39678 39679},{"aos":9}],22:[function(require,module,exports){ 39680"use strict"; 39681var __importDefault = (this && this.__importDefault) || function (mod) { 39682 return (mod && mod.__esModule) ? mod : { "default": mod }; 39683}; 39684Object.defineProperty(exports, "__esModule", { value: true }); 39685const blazy_1 = __importDefault(require("blazy")); 39686// Lazy loading and multi-serving images 39687new blazy_1.default({ 39688 breakpoints: [{ 39689 width: 420 // Max-width 39690 , 39691 src: "data-src-small" 39692 }], 39693 success: (element) => { 39694 setTimeout(function () { 39695 // We want to remove the loader gif now. 39696 // First we find the parent container 39697 // then we remove the "loading" class which holds the loader image 39698 const parent = element.parentNode; 39699 parent.className = parent.className.replace(/\bloading\b/, ""); 39700 }, 200); 39701 } 39702}); 39703 39704},{"blazy":10}],23:[function(require,module,exports){ 39705"use strict"; 39706var __importDefault = (this && this.__importDefault) || function (mod) { 39707 return (mod && mod.__esModule) ? mod : { "default": mod }; 39708}; 39709Object.defineProperty(exports, "__esModule", { value: true }); 39710const moment_1 = require("moment"); 39711const core_1 = require("@fullcalendar/core"); 39712const interaction_1 = __importDefault(require("@fullcalendar/interaction"));
39713const daygrid_1 = __importDefault(require("@fullcalendar/daygrid")); 39714const timegrid_1 = __importDefault(require("@fullcalendar/timegrid")); 39715const list_1 = __importDefault(require("@fullcalendar/list")); 39716const bootstrap_1 = __importDefault(require("@fullcalendar/bootstrap")); 39717const moment_2 = __importDefault(require("@fullcalendar/moment")); 39718const google_calendar_1 = __importDefault(require("@fullcalendar/google-calendar")); 39719const util_1 = require("util"); 39720const jquery_1 = __importDefault(require("jquery")); 39721require("daterangepicker"); 39722require("bootstrap"); 39723document.addEventListener("DOMContentLoaded", function () { 39724 if (!util_1.isNullOrUndefined(document.getElementById("calendar"))) { 39725 const calendarEl = document.getElementById("calendar"); 39726 const calendar = new core_1.Calendar(calendarEl, { 39727 plugins: [interaction_1.default, daygrid_1.default, timegrid_1.default, list_1.default, bootstrap_1.default, moment_2.default, google_calendar_1.default], 39728 themeSystem: "bootstrap", 39729 locale: document.getElementById("language").getAttribute("value").toString() === "da" ? "da" : "en", 39730 timeZone: "Europe/Copenhagen", 39731 googleCalendarApiKey: "AIzaSyD8flgO6cGM0jTra1m21Fk06ryIzF1lqg8", 39732 header: { 39733 left: "prev,next today", 39734 center: "title", 39735 right: "dayGridMonth,timeGridWeek,listWeek" 39736 }, 39737 firstDay: 1, 39738 navLinks: true, 39739 selectable: true, 39740 eventLimit: true, 39741 eventSources: [ 39742 JSON.parse(document.getElementById("variableName").getAttribute("value").toString()), 39743 (document.getElementById("googleCalID").getAttribute("value") ? { 39744 googleCalendarId: document.getElementById("googleCalID").getAttribute("value") 39745 } : {}) 39746 ], 39747 eventRender: (info) => { 39748 info.el.setAttribute("data-toggle", "modal"); 39749 info.el.setAttribute("data-target", "#fullCalModal"); 39750 }, 39751 select: (info) => { 39752 jquery_1.default("#createEventModal").modal("show"); 39753 document.getElementById("eventStartDate").setAttribute("value", moment_1.utc(info.start).format("DD/MM/YYYY, HH:mm")); 39754 document.getElementById("eventEndDate").setAttribute("value", moment_1.utc(info.end).format("DD/MM/YYYY, HH:mm")); 39755 document.getElementById("eventPlace").setAttribute("value", document.getElementById("placeDisplay").getAttribute("value").toString()); 39756 jquery_1.default("input[name='eventStartDate']").daterangepicker({ 39757 singleDatePicker: true, 39758 timePicker: true, 39759 timePicker24Hour: true, 39760 locale: { 39761 format: "DD/MM/YYYY, HH:mm" 39762 }, 39763 startDate: info.start 39764 }); 39765 jquery_1.default("input[name='eventEndDate']").daterangepicker({ 39766 singleDatePicker: true, 39767 timePicker: true, 39768 timePicker24Hour: true, 39769 locale: { 39770 format: "DD/MM/YYYY, HH:mm" 39771 }, 39772 startDate: info.end 39773 }); 39774 jquery_1.default("input[name='eventStartDate'],input[name='eventEndDate']").on("apply.daterangepicker", (ev, picker) => { 39775 jquery_1.default(this).val(picker.startDate.format("DD/MM/YYYY, HH:mm")); 39776 }); 39777 }, 39778 eventClick: (info) => { 39779 console.log(info.event); 39780 document.getElementById("modalTitle").innerHTML = info.event.title; 39781 document.getElementById("showId").setAttribute("value", info.event.id); 39782 info.event.extendedProps.description ? document.getElementById("showDescription").setAttribute("value", info.event.extendedProps.description) : document.getElementById("showDescription").setAttribute("value", info.event.url); 39783 document.getElementById("showStartDate").setAttribute("value", moment_1.utc(info.event.start, "DD/MM/YYYY, HH:mm").format("DD/MM/YYYY, HH:mm")); 39784 document.getElementById("showEndDate").setAttribute("value", moment_1.utc(info.event.end, "DD/MM/YYYY, HH:mm").format("DD/MM/YYYY, HH:mm")); 39785 info.event.extendedProps.name ? document.getElementById("showUser").setAttribute("value", info.event.extendedProps.name) : document.getElementById("showUser").setAttribute("value", ""); 39786 } 39787 }); 39788 jquery_1.default("#removeEventButton").click(function () { 39789 jquery_1.default("#removeEvent").submit(); 39790 }); 39791 jquery_1.default("#addEventButton").click(function () { 39792 jquery_1.default("#addEvent").submit(); 39793 }); 39794 calendar.render(); 39795 } 39796}); 39797 39798},{"@fullcalendar/bootstrap":1,"@fullcalendar/core":2,"@fullcalendar/daygri
39798d":3,"@fullcalendar/google-calendar":4,"@fullcalendar/interaction":5,"@fullcalendar/list":6,"@fullcalendar/moment":7,"@fullcalendar/timegrid":8,"bootstrap":11,"daterangepicker":12,"jquery":13,"moment":14,"util":19}],24:[function(require,module,exports){ 39799"use strict"; 39800var __importDefault = (this && this.__importDefault) || function (mod) { 39801 return (mod && mod.__esModule) ? mod : { "default": mod }; 39802}; 39803Object.defineProperty(exports, "__esModule", { value: true }); 39804const moment_1 = __importDefault(require("moment")); 39805const jquery_1 = __importDefault(require("jquery")); 39806require("daterangepicker"); 39807moment_1.default.locale(window.navigator.language); 39808jquery_1.default("input[name='birthDay'],input[name='movedInDate']").daterangepicker({ 39809 singleDatePicker: true, 39810 locale: { 39811 format: "DD/MM/YYYY" 39812 } 39813}); 39814jquery_1.default("input[name='birthDay'],input[name='movedInDate']").on("apply.daterangepicker", (ev, picker) => { 39815 picker.startDate.locale(window.navigator.language); 39816 jquery_1.default(this).val(picker.startDate.format("DD/MM/YYYY")); 39817}); 39818jquery_1.default("input[name='birthDay'],input[name='movedInDate']").on("cancel.daterangepicker", (ev, picker) => { 39819 jquery_1.default(this).val(""); 39820}); 39821 39822},{"daterangepicker":12,"jquery":13,"moment":14}],25:[function(require,module,exports){ 39823"use strict"; 39824Object.defineProperty(exports, "__esModule", { value: true }); 39825const util_1 = require("util"); 39826window.onload = function () { 39827 if (!util_1.isNullOrUndefined(document.getElementById("googleMap"))) { 39828 const styledMapType = new google.maps.StyledMapType([ 39829 { 39830 elementType: "geometry", stylers: [{ color: "#ebe3cd" }] 39831 }, 39832 { 39833 elementType: "labels.text.fill", stylers: [{ color: "#523735" }] 39834 }, 39835 { 39836 elementType: "labels.text.stroke", stylers: [{ color: "#f5f1e6" }] 39837 }, 39838 { 39839 featureType: "administrative", 39840 elementType: "geometry.stroke", 39841 stylers: [{ color: "#c9b2a6" }] 39842 }, 39843 { 39844 featureType: "administrative.land_parcel", 39845 elementType: "geometry.stroke", 39846 stylers: [{ color: "#dcd2be" }] 39847 }, 39848 { 39849 featureType: "administrative.land_parcel", 39850 elementType: "labels.text.fill", 39851 stylers: [{ color: "#ae9e90" }] 39852 }, 39853 { 39854 featureType: "landscape.natural", 39855 elementType: "geometry", 39856 stylers: [{ color: "#dfd2ae" }] 39857 }, 39858 { 39859 featureType: "poi", 39860 elementType: "geometry", 39861 stylers: [{ color: "#dfd2ae" }] 39862 }, 39863 { 39864 featureType: "poi", 39865 elementType: "labels.text.fill", 39866 stylers: [{ color: "#93817c" }] 39867 }, 39868 { 39869 featureType: "poi.park", 39870 elementType: "geometry.fill", 39871 stylers: [{ color: "#a5b076" }] 39872 }, 39873 { 39874 featureType: "poi.park", 39875 elementType: "labels.text.fill", 39876 stylers: [{ color: "#447530" }] 39877 }, 39878 { 39879 featureType: "road", 39880 elementType: "geometry", 39881 stylers: [{ color: "#f5f1e6" }] 39882 }, 39883 { 39884 featureType: "road.arterial", 39885 elementType: "geometry", 39886 stylers: [{ color: "#fdfcf8" }] 39887 }, 39888 { 39889 featureType: "road.highway", 39890 elementType: "geometry", 39891 stylers: [{ color: "#f8c967" }] 39892 }, 39893 { 39894 featureType: "road.highway", 39895 elementType: "geometry.stroke", 39896 stylers: [{ color: "#e9bc62" }] 39897 }, 39898 { 39899 featureType: "road.highway.controlled_access", 39900 elementType: "geometry", 39901 stylers: [{ color: "#e98d58" }] 39902 }, 39903 { 39904 featureType: "road.highway.controlled_access", 39905 elementType: "geometry.stroke", 39906 stylers: [{ color: "#db8555" }] 39907 }, 39908 { 39909 featureType: "road.local", 39910 elementType: "labels.text.fill", 39911 stylers: [{ color: "#806b63" }] 39912 }, 39913 { 39914 featureType: "transit.line", 39915 elementType: "geometry", 39916 stylers: [{ color: "#dfd2ae" }] 39917 }, 39918 { 39919 featureType: "transit.line", 39920 elementType: "labels.text.fill", 39921 stylers: [{ color: "#8f7d77" }] 39922 }, 39923 { 39924 featureType: "transit.line", 39925 elementType: "labels.text.stroke", 39926 stylers: [{ color: "#ebe3cd" }] 39927 }, 39928 { 39929 featureType: "transit.station", 39930 elementType: "geometry", 39931 stylers: [{ color: "#dfd2ae" }] 39932 }, 39933 { 39934 featureType: "water", 39935 elementType: "geometry.fill", 39936 stylers: [{ color: "#b9d3c2" }] 39937 }, 39938 { 39939 featureType: "water", 39940 elementType: "labels.text.fill", 39941 stylers: [{ color: "#92998d" }] 39942 } 39943 ], { name: "Styled Map" }); 39944 const map = new google.maps.Map(document.getElementById("googleMap"), { 39945 center: new google.maps.LatLng(55.682376, 12.5736143), 39946 zoom: 16, 39947 tilt: 45, 39948 disableDefaultUI: true, 39949 scrollwheel: false, 39950 draggable: false, 39951 mapTypeControlOptions: { 39952 mapTypeIds: ["roadmap", "satellite", "hybrid", "terrain", "styled_map"] 39953 } 39954 }); 39955 const marker = new google.maps.Marker({ 39956 position: { lat: 55.681112, lng: 12.575585 }, 39957 animation: google.maps.Animation.DROP, 39958 title: "Regensen" 39959 }); 39960 // Associate the styled map with the MapTypeId and set it to display. 39961 map.mapTypes.set("styled_map", styledMapType);
39962 marker.setMap(map); 39963 map.setMapTypeId("styled_map"); 39964 } 39965}; 39966 39967},{"util":19}]},{},[20,21,22,23,24,25]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.