PageSourceSearch

https://skillhub.jp/assets/application-a81d0f7350f6888c876a5acb6a4847adce3c63a3e790d0584c3aaddd2d01df7a.js

js skillhub.jp collected 2026-09-24 18:10:53 UTC 3,939,174 bytes, 85,109 lines download raw bytes

1/*
2* jQuery UI Tag-it!
3*
4* @version v2.0 (06/2011)
5*
6* Copyright 2011, Levy Carneiro Jr.
7* Released under the MIT license.
8* http://aehlke.github.com/tag-it/LICENSE
9*
10* Homepage:
11*   http://aehlke.github.com/tag-it/
12*
13* Authors:
14*   Levy Carneiro Jr.
15*   Martin Rehfeld
16*   Tobias Schmidt
17*   Skylar Challand
18*   Alex Ehlke
19*
20* Maintainer:
21*   Alex Ehlke - Twitter: @aehlke
22*
23* Dependencies:
24*   jQuery v1.4+
25*   jQuery UI v1.8+
26*/
27(function($) {
28
29    $.widget('ui.tagit', {
30        options: {
31            allowDuplicates   : false,
32            caseSensitive     : true,
33            fieldName         : 'tags',
34            placeholderText   : null,   // Sets `placeholder` attr on input field.
35            readOnly          : false,  // Disables editing.
36            removeConfirmation: false,  // Require confirmation to remove tags.
37            tagLimit          : null,   // Max number of tags allowed (null for unlimited).
38
39            // Used for autocomplete, unless you override `autocomplete.source`.
40            availableTags     : [],
41
42            // Use to override or add any options to the autocomplete widget.
43            //
44            // By default, autocomplete.source will map to availableTags,
45            // unless overridden.
46            autocomplete: {},
47
48            // Shows autocomplete before the user even types anything.
49            showAutocompleteOnFocus: false,
50
51            // When enabled, quotes are unneccesary for inputting multi-word tags.
52            allowSpaces: false,
53
54            // The below options are for using a single field instead of several
55            // for our form values.
56            //
57            // When enabled, will use a single hidden field for the form,
58            // rather than one per tag. It will delimit tags in the field
59            // with singleFieldDelimiter.
60            //
61            // The easiest way to use singleField is to just instantiate tag-it
62            // on an INPUT element, in which case singleField is automatically
63            // set to true, and singleFieldNode is set to that element. This
64            // way, you don't need to fiddle with these options.
65            singleField: false,
66
67            // This is just used when preloading data from the field, and for
68            // populating the field with delimited tags as the user adds them.
69            singleFieldDelimiter: ',',
70
71            // Set this to an input DOM node to use an existing form field.
72            // Any text in it will be erased on init. But it will be
73            // populated with the text of tags as they are created,
74            // delimited by singleFieldDelimiter.
75            //
76            // If this is not set, we create an input node for it,
77            // with the name given in settings.fieldName.
78            singleFieldNode: null,
79
80            // Whether to animate tag removals or not.
81            animate: true,
82
83            // Optionally set a tabindex attribute on the input that gets
84            // created for tag-it.
85            tabIndex: null,
86
87            // Event callbacks.
88            beforeTagAdded      : null,
89            afterTagAdded       : null,
90
91            beforeTagRemoved    : null,
92            afterTagRemoved     : null,
93
94            onTagClicked        : null,
95            onTagLimitExceeded  : null,
96
97
98            // DEPRECATED:
99            //
100            // /!\ These event callbacks are deprecated and WILL BE REMOVED at some
101            // point in the future. They're here for backwards-compatibility.
102            // Use the above before/after event callbacks instead.
103            onTagAdded  : null,
104            onTagRemoved: null,
105            // `autocomplete.source` is the replacement for tagSource.
106            tagSource: null
107            // Do not use the above deprecated options.
108        },
109
110        _create: function() {
111            // for handling static scoping inside callbacks
112            var that = this;
113
114            // There are 2 kinds of DOM nodes this widget can be instantiated on:
115            //     1. UL, OL, or some element containing either of these.
116            //     2. INPUT, in which case 'singleField' is overridden to true,
117            //        a UL is created and the INPUT is hidden.
118            if (this.element.is('input')) {
119                this.tagList = $('<ul></ul>').insertAfter(this.element);
120                this.options.singleField = true;
121                this.options.singleFieldNode = this.element;
122                this.element.addClass('tagit-hidden-field');
123            } else {
124                this.tagList = this.element.find('ul, ol').andSelf().last();
125            }
126
127            this.tagInput = $('<input type="text" />').addClass('ui-widget-content');
128
129            if (this.options.readOnly) this.tagInput.attr('disabled', 'disabled');
130
131            if (this.options.tabIndex) {
132                this.tagInput.attr('tabindex', this.options.tabIndex);
133            }
134
135            if (this.options.placeholderText) {
136                this.tagInput.attr('placeholder', this.options.placeholderText);
137            }
138
139            if (!this.options.autocomplete.source) {
140                this.options.autocomplete.source = function(search, showChoices) {
141                    var filter = search.term.toLowerCase();
142                    var choices = $.grep(this.options.availableTags, function(element) {
143                        // Only match autocomplete options that begin with the search term.
144                        // (Case insensitive.)
145                        return (element.toLowerCase().indexOf(filter) === 0);
146                    });
147                    if (!this.options.allowDuplicates) {
148                        choices = this._subtractArray(choices, this.assignedTags());
149                    }
150                    showChoices(choices);
151                };
152            }
153
154            if (this.options.showAutocompleteOnFocus) {
155                this.tagInput.focus(function(event, ui) {
156                    that._showAutocomplete();
157                });
158
159                if (typeof this.options.autocomplete.minLength === 'undefined') {
160                    this.options.autocomplete.minLength = 0;
161                }
162            }
163
164            // Bind autocomplete.source callback functions to this context.
165            if ($.isFunction(this.options.autocomplete.source)) {
166                this.options.autocomplete.source = $.proxy(this.options.autocomplete.source, this);
167            }
168
169            // DEPRECATED.
170            if ($.isFunction(this.options.tagSource)) {
171                this.options.tagSource = $.proxy(this.options.tagSource, this);
172            }
173
174            this.tagList
175                .addClass('tagit')
176                .addClass('ui-widget ui-widget-content ui-corner-all')
177                // Create the input field.
178                .append($('<li class="tagit-new"></li>').append(this.tagInput))
179                .click(function(e) {
180                    var target = $(e.target);
181                    if (target.hasClass('tagit-label')) {
182                        var tag = target.closest('.tagit-choice');
183                        if (!tag.hasClass('removed')) {
184                            that._trigger('onTagClicked', e, {tag: tag, tagLabel: that.tagLabel(tag)});
185                        }
186                    } else {
187                        // Sets the focus() to the input field, if the user
188                        // clicks anywhere inside the UL. This is needed
189                        // because the input field needs to be of a small size.
190                        that.tagInput.focus();
191                    }
192                });
193
194            // Single field support.
195            var addedExistingFromSingleFieldNode = false;
196            if (this.options.singleField) {
197                if (this.options.singleFieldNode) {
198                    // Add existing tags from the input field.
199                    var node = $(this.options.singleFieldNode);
200                    var tags = node.val().split(this.options.singleFieldDelimiter);
201                    node.val('');
202                    $.each(tags, function(index, tag) {
203                        that.createTag(tag, null, true);
204                        addedExistingFromSingleFieldNode = true;
205                    });
206                } else {
207                    // Create our single field input after our list.
208                    this.options.singleFieldNode = $('<input type="hidden" style="display:none;" value="" name="' + this.options.fieldName + '" />');
209                    this.tagList.after(this.options.singleFieldNode);
210                }
211            }
212
213            // Add existing tags from the list, if any.
214            if (!addedExistingFromSingleFieldNode) {
215                this.tagList.children('li').each(function() {
216                    if (!$(this).hasClass('tagit-new')) {
217                        that.createTag($(this).text(), $(this).attr('class'), true);
218                        $(this).remove();
219                    }
220                });
221            }
222
223            // Events.
224            this.tagInput
225                .keydown(function(event) {
226                    // Backspace is not detected within a keypress, so it must use keydown.
227                    if (event.which == $.ui.keyCode.BACKSPACE && that.tagInput.val() === '') {
228                        var tag = that._lastTag();
229                        if (!that.options.removeConfirmation || tag.hasClass('remove')) {
230                            // When backspace is pressed, the last tag is deleted.
231                            that.removeTag(tag);
232                        } else if (that.options.removeConfirmation) {
233                            tag.addClass('remove ui-state-highlight');
234                        }
235                    } else if (that.options.removeConfirmation) {
236                        that._lastTag().removeClass('remove ui-state-highlight');
237                    }
238
239                    // Comma/Space/Enter are all valid delimiters for new tags,
240                    // except when there is an open quote or if setting allowSpaces = true.
241                    // Tab will also create a tag, unless the tag input is empty,
242                    // in which case it isn't caught.
243                    if (
244                        (event.which === $.ui.keyCode.COMMA && event.shiftKey === false) ||
245                        event.which === $.ui.keyCode.ENTER ||
246                        (
247                            event.which == $.ui.keyCode.TAB &&
248                            that.tagInput.val() !== ''
249                        ) ||
250                        (
251                            event.which == $.ui.keyCode.SPACE &&
252                            that.options.allowSpaces !== true &&
253                            (
254                                $.trim(that.tagInput.val()).replace( /^s*/, '' ).charAt(0) != '"' ||
255                                (
256                                    $.trim(that.tagInput.val()).charAt(0) == '"' &&
257                                    $.trim(that.tagInput.val()).charAt($.trim(that.tagInput.val()).length - 1) == '"' &&
258                                    $.trim(that.tagInput.val()).length - 1 !== 0
259                                )
260                            )
261                        )
262                    ) {
263                        // Enter submits the form if there's no text in the input.
264                        if (!(event.which === $.ui.keyCode.ENTER && that.tagInput.val() === '')) {
265                            event.preventDefault();
266                        }
267
268                        // Autocomplete will create its own tag from a selection and close automatically.
269                        if (!(that.options.autocomplete.autoFocus && that.tagInput.data('autocomplete-open'))) {
270                            that.tagInput.autocomplete('close');
271                            that.createTag(that._cleanedInput());
272                        }
273                    }
274                }).blur(function(e){
275                    // Create a tag when the element loses focus.
276                    // If autocomplete is enabled and suggestion was clicked, don't add it.
277                    if (!that.tagInput.data('autocomplete-open')) {
278                        that.createTag(that._cleanedInput());
279                    }
280                });
281
282            // Autocomplete.
283            if (this.options.availableTags || this.options.tagSource || this.options.autocomplete.source) {
284                var autocompleteOptions = {
285                    select: function(event, ui) {
286                        that.createTag(ui.item.value);
287                        // Preventing the tag input to be updated with the chosen value.
288                        return false;
289                    }
290                };
291                $.extend(autocompleteOptions, this.options.autocomplete);
292
293                // tagSource is deprecated, but takes precedence here since autocomplete.source is set by default,
294                // while tagSource is left null by default.
295                autocompleteOptions.source = this.options.tagSource || autocompleteOptions.source;
296
297                this.tagInput.autocomplete(autocompleteOptions).bind('autocompleteopen.tagit', function(event, ui) {
298                    that.tagInput.data('autocomplete-open', true);
299                }).bind('autocompleteclose.tagit', function(event, ui) {
300                    that.tagInput.data('autocomplete-open', false);
301                });
302
303                this.tagInput.autocomplete('widget').addClass('tagit-autocomplete');
304            }
305        },
306
307        destroy: function() {
308            $.Widget.prototype.destroy.call(this);
309
310            this.element.unbind('.tagit');
311            this.tagList.unbind('.tagit');
312
313            this.tagInput.removeData('autocomplete-open');
314
315            this.tagList.removeClass([
316                'tagit',
317                'ui-widget',
318                'ui-widget-content',
319                'ui-corner-all',
320                'tagit-hidden-field'
321            ].join(' '));
322
323            if (this.element.is('input')) {
324                this.element.removeClass('tagit-hidden-field');
325                this.tagList.remove();
326            } else {
327                this.element.children('li').each(function() {
328                    if ($(this).hasClass('tagit-new')) {
329                        $(this).remove();
330                    } else {
331                        $(this).removeClass([
332                            'tagit-choice',
333                            'ui-widget-content',
334                            'ui-state-default',
335                            'ui-state-highlight',
336                            'ui-corner-all',
337                            'remove',
338                            'tagit-choice-editable',
339                            'tagit-choice-read-only'
340                        ].join(' '));
341
342                        $(this).text($(this).children('.tagit-label').text());
343                    }
344                });
345
346                if (this.singleFieldNode) {
347                    this.singleFieldNode.remove();
348                }
349            }
350
351            return this;
352        },
353
354        _cleanedInput: function() {
355            // Returns the contents of the tag input, cleaned and ready to be passed to createTag
356            return $.trim(this.tagInput.val().replace(/^"(.*)"$/, '$1'));
357        },
358
359        _lastTag: function() {
360            return this.tagList.find('.tagit-choice:last:not(.removed)');
361        },
362
363        _tags: function() {
364            return this.tagList.find('.tagit-choice:not(.removed)');
365        },
366
367        assignedTags: function() {
368            // Returns an array of tag string values
369            var that = this;
370            var tags = [];
371            if (this.options.singleField) {
372                tags = $(this.options.singleFieldNode).val().split(this.options.singleFieldDelimiter);
373                if (tags[0] === '') {
374                    tags = [];
375                }
376            } else {
377                this._tags().each(function() {
378                    tags.push(that.tagLabel(this));
379                });
380            }
381            return tags;
382        },
383
384        _updateSingleTagsField: function(tags) {
385            // Takes a list of tag string values, updates this.options.singleFieldNode.val to the tags delimited by this.options.singleFieldDelimiter
386            $(this.options.singleFieldNode).val(tags.join(this.options.singleFieldDelimiter)).trigger('change');
387        },
388
389        _subtractArray: function(a1, a2) {
390            var result = [];
391            for (var i = 0; i < a1.length; i++) {
392                if ($.inArray(a1[i], a2) == -1) {
393                    result.push(a1[i]);
394                }
395            }
396            return result;
397        },
398
399        tagLabel: function(tag) {
400            // Returns the tag's string label.
401            if (this.options.singleField) {
402                return $(tag).find('.tagit-label:first').text();
403            } else {
404                return $(tag).find('input:first').val();
405            }
406        },
407
408        _showAutocomplete: function() {
409            this.tagInput.autocomplete('search', '');
410        },
411
412        _findTagByLabel: function(name) {
413            var that = this;
414            var tag = null;
415            this._tags().each(function(i) {
416                if (that._formatStr(name) == that._formatStr(that.tagLabel(this))) {
417                    tag = $(this);
418                    return false;
419                }
420            });
421            return tag;
422        },
423
424        _isNew: function(name) {
425            return !this._findTagByLabel(name);
426        },
427
428        _formatStr: function(str) {
429            if (this.options.caseSensitive) {
430                return str;
431            }
432            return $.trim(str.toLowerCase());
433        },
434
435        _effectExists: function(name) {
436            return Boolean($.effects && ($.effects[name] || ($.effects.effect && $.effects.effect[name])));
437        },
438
439        createTag: function(value, additionalClass, duringInitialization) {
440            var that = this;
441
442            value = $.trim(value);
443
444            if(this.options.preprocessTag) {
445                value = this.options.preprocessTag(value);
446            }
447
448            if (value === '') {
449                return false;
450            }
451
452            if (!this.options.allowDuplicates && !this._isNew(value)) {
453                var existingTag = this._findTagByLabel(value);
454                if (this._trigger('onTagExists', null, {
455                    existingTag: existingTag,
456                    duringInitialization: duringInitialization
457                }) !== false) {
458                    if (this._effectExists('highlight')) {
459                        existingTag.effect('highlight');
460                    }
461                }
462                return false;
463            }
464
465            if (this.options.tagLimit && this._tags().length >= this.options.tagLimit) {
466                this._trigger('onTagLimitExceeded', null, {duringInitialization: duringInitialization});
467                return false;
468            }
469
470            var label = $(this.options.onTagClicked ? '<a class="tagit-label"></a>' : '<span class="tagit-label"></span>').text(value);
471
472            // Create tag.
473            var tag = $('<li></li>')
474                .addClass('tagit-choice ui-widget-content ui-state-default ui-corner-all')
475                .addClass(additionalClass)
476                .append(label);
477
478            if (this.options.readOnly){
479                tag.addClass('tagit-choice-read-only');
480            } else {
481                tag.addClass('tagit-choice-editable');
482                // Button for removing the tag.
483                var removeTagIcon = $('<span></span>')
484                    .addClass('ui-icon ui-icon-close');
485                var removeTag = $('<a><span class="text-icon">\xd7</span></a>') // \xd7 is an X
486                    .addClass('tagit-close')
487                    .append(removeTagIcon)
488                    .click(function(e) {
489                        // Removes a tag when the little 'x' is clicked.
490                        that.removeTag(tag);
491                    });
492                tag.append(removeTag);
493            }
494
495            // Unless options.singleField is set, each tag has a hidden input field inline.
496            if (!this.options.singleField) {
497                var escapedValue = label.html();
498                tag.append('<input type="hidden" value="' + escapedValue + '" name="' + this.options.fieldName + '" class="tagit-hidden-field" />');
499            }
500
501            if (this._trigger('beforeTagAdded', null, {
502                tag: tag,
503                tagLabel: this.tagLabel(tag),
504                duringInitialization: duringInitialization
505            }) === false) {
506                return;
507            }
508
509            if (this.options.singleField) {
510                var tags = this.assignedTags();
511                tags.push(value);
512                this._updateSingleTagsField(tags);
513            }
514
515            // DEPRECATED.
516            this._trigger('onTagAdded', null, tag);
517
518            this.tagInput.val('');
519
520            // Insert tag.
521            this.tagInput.parent().before(tag);
522
523            this._trigger('afterTagAdded', null, {
524                tag: tag,
525                tagLabel: this.tagLabel(tag),
526                duringInitialization: duringInitialization
527            });
528
529            if (this.options.showAutocompleteOnFocus && !duringInitialization) {
530                setTimeout(function () { that._showAutocomplete(); }, 0);
531            }
532        },
533
534        removeTag: function(tag, animate) {
535            animate = typeof animate === 'undefined' ? this.options.animate : animate;
536
537            tag = $(tag);
538
539            // DEPRECATED.
540            this._trigger('onTagRemoved', null, tag);
541
542            if (this._trigger('beforeTagRemoved', null, {tag: tag, tagLabel: this.tagLabel(tag)}) === false) {
543                return;
544            }
545
546            if (this.options.singleField) {
547                var tags = this.assignedTags();
548                var removedTagLabel = this.tagLabel(tag);
549                tags = $.grep(tags, function(el){
550                    return el != removedTagLabel;
551                });
552                this._updateSingleTagsField(tags);
553            }
554
555            if (animate) {
556                tag.addClass('removed'); // Excludes this tag from _tags.
557                var hide_args = this._effectExists('blind') ? ['blind', {direction: 'horizontal'}, 'fast'] : ['fast'];
558
559                var thisTag = this;
560                hide_args.push(function() {
561                    tag.remove();
562                    thisTag._trigger('afterTagRemoved', null, {tag: tag, tagLabel: thisTag.tagLabel(tag)});
563                });
564
565                tag.fadeOut('fast').hide.apply(tag, hide_args).dequeue();
566            } else {
567                tag.remove();
568                this._trigger('afterTagRemoved', null, {tag: tag, tagLabel: this.tagLabel(tag)});
569            }
570
571        },
572
573        removeTagByLabel: function(tagLabel, animate) {
574            var toRemove = this._findTagByLabel(tagLabel);
575            if (!toRemove) {
576                throw "No such tag exists with the name '" + tagLabel + "'";
577            }
578            this.removeTag(toRemove, animate);
579        },
580
581        removeAll: function() {
582            // Removes all tags.
583            var that = this;
584            this._tags().each(function(index, tag) {
585                that.removeTag(tag, false);
586            });
587        }
588
589    });
590})(jQuery);
591
592/*
593 * jQuery Templates Plugin 1.0.0pre
594 * http://github.com/jquery/jquery-tmpl
595 * Requires jQuery 1.4.2
596 *
597 * Copyright Software Freedom Conservancy, Inc.
598 * Dual licensed under the MIT or GPL Version 2 licenses.
599 * http://jquery.org/license
600 */
601(function(a){var r=a.fn.domManip,d="_tmplitem",q=/^[^<]*(<[\w\W]+>)[^>]*$|\{\{\! /,b={},f={},e,p={key:0,data:{}},i=0,c=0,l=[];function g(g,d,h,e){var c={data:e||(e===0||e===false)?e:d?d.data:{},_wrap:d?d._wrap:null,tmpl:null,parent:d||null,nodes:[],calls:u,nest:w,wrap:x,html:v,update:t};g&&a.extend(c,g,{nodes:[],parent:d});if(h){c.tmpl=h;c._ctnt=c._ctnt||c.tmpl(a,c);c.key=++i;(l.length?f:b)[i]=c}return c}a.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(f,d){a.fn[f]=function(n){var g=[],i=a(n),k,h,m,l,j=this.length===1&&this[0].parentNode;e=b||{};if(j&&j.nodeType===11&&j.childNodes.length===1&&i.length===1){i[d](this[0]);g=this}else{for(h=0,m=i.length;h<m;h++){c=h;k=(h>0?this.clone(true):this).get();a(i[h])[d](k);g=g.concat(k)}c=0;g=this.pushStack(g,f,i.selector)}l=e;e=null;a.tmpl.complete(l);return g}});a.fn.extend({tmpl:function(d,c,b){return a.tmpl(this[0],d,c,b)},tmplItem:function(){return a.tmplItem(this[0])},template:function(b){return a.template(b,this[0])},domManip:function(d,m,k){if(d[0]&&a.isArray(d[0])){var g=a.makeArray(arguments),h=d[0],j=h.length,i=0,f;while(i<j&&!(f=a.data(h[i++],"tmplItem")));if(f&&c)g[2]=function(b){a.tmpl.afterManip(this,b,k)};r.apply(this,g)}else r.apply(this,arguments);c=0;!e&&a.tmpl.complete(b);return this}});a.extend({tmpl:function(d,h,e,c){var i,k=!c;if(k){c=p;d=a.template[d]||a.template(null,d);f={}}else if(!d){d=c.tmpl;b[c.key]=c;c.nodes=[];c.wrapped&&n(c,c.wrapped);return a(j(c,null,c.tmpl(a,c)))}if(!d)return[];if(typeof h==="function")h=h.call(c||{});e&&e.wrapped&&n(e,e.wrapped);i=a.isArray(h)?a.map(h,function(a){return a?g(e,c,d,a):null}):[g(e,c,d,h)];return k?a(j(c,null,i)):i},tmplItem:function(b){var c;if(b instanceof a)b=b[0];while(b&&b.nodeType===1&&!(c=a.data(b,"tmplItem"))&&(b=b.parentNode));return c||p},template:function(c,b){if(b){if(typeof b==="string")b=o(b);else if(b instanceof a)b=b[0]||{};if(b.nodeType)b=a.data(b,"tmpl")||a.data(b,"tmpl",o(b.innerHTML));
601return typeof c==="string"?(a.template[c]=b):b}return c?typeof c!=="string"?a.template(null,c):a.template[c]||a.template(null,q.test(c)?c:a(c)):null},encode:function(a){return(""+a).split("<").join("&lt;").split(">").join("&gt;").split('"').join("&#34;").split("'").join("&#39;")}});a.extend(a.tmpl,{tag:{tmpl:{_default:{$2:"null"},open:"if($notnull_1){__=__.concat($item.nest($1,$2));}"},wrap:{_default:{$2:"null"},open:"$item.calls(__,$1,$2);__=[];",close:"call=$item.calls();__=call._.concat($item.wrap(call,__));"},each:{_default:{$2:"$index, $value"},open:"if($notnull_1){$.each($1a,function($2){with(this){",close:"}});}"},"if":{open:"if(($notnull_1) && $1a){",close:"}"},"else":{_default:{$1:"true"},open:"}else if(($notnull_1) && $1a){"},html:{open:"if($notnull_1){__.push($1a);}"},"=":{_default:{$1:"$data"},open:"if($notnull_1){__.push($.encode($1a));}"},"!":{open:""}},complete:function(){b={}},afterManip:function(f,b,d){var e=b.nodeType===11?a.makeArray(b.childNodes):b.nodeType===1?[b]:[];d.call(f,b);m(e);c++}});function j(e,g,f){var b,c=f?a.map(f,function(a){return typeof a==="string"?e.key?a.replace(/(<\w+)(?=[\s>])(?![^>]*_tmplitem)([^>]*)/g,"$1 "+d+'="'+e.key+'" $2'):a:j(a,e,a._ctnt)}):e;if(g)return c;c=c.join("");c.replace(/^\s*([^<\s][^<]*)?(<[\w\W]+>)([^>]*[^>\s])?\s*$/,function(f,c,e,d){b=a(e).get();m(b);if(c)b=k(c).concat(b);if(d)b=b.concat(k(d))});return b?b:k(c)}function k(c){var b=document.createElement("div");b.innerHTML=c;return a.makeArray(b.childNodes)}function o(b){return new Function("jQuery","$item","var $=jQuery,call,__=[],$data=$item.data;with($data){__.push('"+a.trim(b).replace(/([\\'])/g,"\\$1").replace(/[\r\t\n]/g," ").replace(/\$\{([^\}]*)\}/g,"{{= $1}}").replace(/\{\{(\/?)(\w+|.)(?:\(((?:[^\}]|\}(?!\}))*?)?\))?(?:\s+(.*?)?)?(\(((?:[^\}]|\}(?!\}))*?)\))?\s*\}\}/g,function(m,l,k,g,b,c,d){var j=a.tmpl.tag[k],i,e,f;if(!j)throw"Unknown template tag: "+k;i=j._default||[];if(c&&!/\w$/.test(b)){b+=c;c=""}if(b){b=h(b);d=d?","+h(d)+")":c?")":"";e=c?b.indexOf(".")>-1?b+h(c):"("+b+").call($item"+d:b;f=c?e:"(typeof("+b+")==='function'?("+b+").call($item):("+b+"))"}else f=e=i.$1||"null";g=h(g);return"');"+j[l?"close":"open"].split("$notnull_1").join(b?"typeof("+b+")!=='undefined' && ("+b+")!=null":"true").split("$1a").join(f).split("$1").join(e).split("$2").join(g||i.$2||"")+"__.push('"})+"');}return __;")}function n(c,b){c._wrap=j(c,true,a.isArray(b)?b:[q.test(b)?b:a(b).html()]).join("")}function h(a){return a?a.replace(/\\'/g,"'").replace(/\\\\/g,"\\"):null}function s(b){var a=document.createElement("div");a.appendChild(b.cloneNode(true));return a.innerHTML}function m(o){var n="_"+c,k,j,l={},e,p,h;for(e=0,p=o.length;e<p;e++){if((k=o[e]).nodeType!==1)continue;j=k.getElementsByTagName("*");for(h=j.length-1;h>=0;h--)m(j[h]);m(k)}function m(j){var p,h=j,k,e,m;if(m=j.getAttribute(d)){while(h.parentNode&&(h=h.parentNode).nodeType===1&&!(p=h.getAttribute(d)));if(p!==m){h=h.parentNode?h.nodeType===11?0:h.getAttribute(d)||0:0;if(!(e=b[m])){e=f[m];e=g(e,b[h]||f[h]);e.key=++i;b[i]=e}c&&o(m)}j.removeAttribute(d)}else if(c&&(e=a.data(j,"tmplItem"))){o(e.key);b[e.key]=e;h=a.data(j.parentNode,"tmplItem");h=h?h.key:0}if(e){k=e;while(k&&k.key!=h){k.nodes.push(j);k=k.parent}delete e._ctnt;delete e._wrap;a.data(j,"tmplItem",e)}function o(a){a=a+n;e=l[a]=l[a]||g(e,b[e.parent.key+n]||e.parent)}}}function u(a,d,c,b){if(!a)return l.pop();l.push({_:a,tmpl:d,item:this,data:c,options:b})}function w(d,c,b){return a.tmpl(a.template(d),c,b,this)}function x(b,d){var c=b.options||{};c.wrapped=d;return a.tmpl(a.template(b.tmpl),b.data,c,b.item)}function v(d,c){var b=this._wrap;return a.map(a(a.isArray(b)?b.join(""):b).filter(d||"*"),function(a){return c?a.innerText||a.textContent:a.outerHTML||s(a)})}function t(){var b=this.nodes;a.tmpl(null,null,null,this).insertBefore(b[0]);a(b).remove()}})(jQuery);
602/**
603 * http://github.com/valums/file-uploader
604 * 
605 * Multiple file upload component with progress-bar, drag-and-drop. 
606 * © 2010 Andrew Valums ( andrew(at)valums.com ) 
607 * 
608 * Licensed under GNU GPL 2 or later, see license.txt.
609 */    
610
611//
612// Helper functions
613//
614
615var qq = qq || {};
616
617/**
618 * Adds all missing properties from second obj to first obj
619 */ 
620qq.extend = function(first, second){
621    for (var prop in second){
622        first[prop] = second[prop];
623    }
624};  
625
626/**
627 * Searches for a given element in the array, returns -1 if it is not present.
628 * @param {Number} [from] The index at which to begin the search
629 */
630qq.indexOf = function(arr, elt, from){
631    if (arr.indexOf) return arr.indexOf(elt, from);
632    
633    from = from || 0;
634    var len = arr.length;    
635    
636    if (from < 0) from += len;  
637
638    for (; from < len; from++){  
639        if (from in arr && arr[from] === elt){  
640            return from;
641        }
642    }  
643    return -1;  
644}; 
645    
646qq.getUniqueId = (function(){
647    var id = 0;
648    return function(){ return id++; };
649})();
650
651//
652// Events
653
654qq.attach = function(element, type, fn){
655    if (element.addEventListener){
656        element.addEventListener(type, fn, false);
657    } else if (element.attachEvent){
658        element.attachEvent('on' + type, fn);
659    }
660};
661qq.detach = function(element, type, fn){
662    if (element.removeEventListener){
663        element.removeEventListener(type, fn, false);
664    } else if (element.attachEvent){
665        element.detachEvent('on' + type, fn);
666    }
667};
668
669qq.preventDefault = function(e){
670    if (e.preventDefault){
671        e.preventDefault();
672    } else{
673        e.returnValue = false;
674    }
675};
676
677//
678// Node manipulations
679
680/**
681 * Insert node a before node b.
682 */
683qq.insertBefore = function(a, b){
684    b.parentNode.insertBefore(a, b);
685};
686qq.remove = function(element){
687    element.parentNode.removeChild(element);
688};
689
690qq.contains = function(parent, descendant){       
691    // compareposition returns false in this case
692    if (parent == descendant) return true;
693    
694    if (parent.contains){
695        return parent.contains(descendant);
696    } else {
697        return !!(descendant.compareDocumentPosition(parent) & 8);
698    }
699};
700
701/**
702 * Creates and returns element from html string
703 * Uses innerHTML to create an element
704 */
705qq.toElement = (function(){
706    var div = document.createElement('div');
707    return function(html){
708        div.innerHTML = html;
709        var element = div.firstChild;
710        div.removeChild(element);
711        return element;
712    };
713})();
714
715//
716// Node properties and attributes
717
718/**
719 * Sets styles for an element.
720 * Fixes opacity in IE6-8.
721 */
722qq.css = function(element, styles){
723    if (styles.opacity != null){
724        if (typeof element.style.opacity != 'string' && typeof(element.filters) != 'undefined'){
725            styles.filter = 'alpha(opacity=' + Math.round(100 * styles.opacity) + ')';
726        }
727    }
728    qq.extend(element.style, styles);
729};
730qq.hasClass = function(element, name){
731    var re = new RegExp('(^| )' + name + '( |$)');
732    return re.test(element.className);
733};
734qq.addClass = function(element, name){
735    if (!qq.hasClass(element, name)){
736        element.className += ' ' + name;
737    }
738};
739qq.removeClass = function(element, name){
740    var re = new RegExp('(^| )' + name + '( |$)');
741    element.className = element.className.replace(re, ' ').replace(/^\s+|\s+$/g, "");
742};
743qq.setText = function(element, text){
744    element.innerText = text;
745    element.textContent = text;
746};
747
748//
749// Selecting elements
750
751qq.children = function(element){
752    var children = [],
753    child = element.firstChild;
754
755    while (child){
756        if (child.nodeType == 1){
757            children.push(child);
758        }
759        child = child.nextSibling;
760    }
761
762    return children;
763};
764
765qq.getByClass = function(element, className){
766    if (element.querySelectorAll){
767        return element.querySelectorAll('.' + className);
768    }
769
770    var result = [];
771    var candidates = element.getElementsByTagName("*");
772    var len = candidates.length;
773
774    for (var i = 0; i < len; i++){
775        if (qq.hasClass(candidates[i], className)){
776            result.push(candidates[i]);
777        }
778    }
779    return result;
780};
781
782/**
783 * obj2url() takes a json-object as argument and generates
784 * a querystring. pretty much like jQuery.param()
785 * 
786 * how to use:
787 *
788 *    `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`
789 *
790 * will result in:
791 *
792 *    `http://any.url/upload?otherParam=value&a=b&c=d`
793 *
794 * @param  Object JSON-Object
795 * @param  String current querystring-part
796 * @return String encoded querystring
797 */
798qq.obj2url = function(obj, temp, prefixDone){
799    var uristrings = [],
800        prefix = '&',
801        add = function(nextObj, i){
802            var nextTemp = temp 
803                ? (/\[\]$/.test(temp)) // prevent double-encoding
804                   ? temp
805                   : temp+'['+i+']'
806                : i;
807            if ((nextTemp != 'undefined') && (i != 'undefined')) {  
808                uristrings.push(
809                    (typeof nextObj === 'object') 
810                        ? qq.obj2url(nextObj, nextTemp, true)
811                        : (Object.prototype.toString.call(nextObj) === '[object Function]')
812                            ? encodeURIComponent(nextTemp) + '=' + encodeURIComponent(nextObj())
813                            : encodeURIComponent(nextTemp) + '=' + encodeURIComponent(nextObj)                                                          
814                );
815            }
816        }; 
817
818    if (!prefixDone && temp) {
819      prefix = (/\?/.test(temp)) ? (/\?$/.test(temp)) ? '' : '&' : '?';
820      uristrings.push(temp);
821      uristrings.push(qq.obj2url(obj));
822    } else if ((Object.prototype.toString.call(obj) === '[object Array]') && (typeof obj != 'undefined') ) {
823        // we wont use a for-in-loop on an array (performance)
824        for (var i = 0, len = obj.length; i < len; ++i){
825            add(obj[i], i);
826        }
827    } else if ((typeof obj != 'undefined') && (obj !== null) && (typeof obj === "object")){
828        // for anything else but a scalar, we will use for-in-loop
829        for (var i in obj){
830            add(obj[i], i);
831        }
832    } else {
833        uristrings.push(encodeURIComponent(temp) + '=' + encodeURIComponent(obj));
834    }
835
836    return uristrings.join(prefix)
837                     .replace(/^&/, '')
838                     .replace(/%20/g, '+'); 
839};
840
841//
842//
843// Uploader Classes
844//
845//
846
847var qq = qq || {};
848    
849/**
850 * Creates upload button, validates upload, but doesn't create file list or dd. 
851 */
852qq.FileUploaderBasic = function(o){
853    this._options = {
854        // set to true to see the server response
855        debug: false,
856        action: '/server/upload',
857        params: {},
858        button: null,
859        multiple: true,
860        maxConnections: 3,
861        method: 'POST',
862        fieldName: 'qqfile',
863        // validation        
864        allowedExtensions: [],               
865        sizeLimit: 0,   
866        minSizeLimit: 0,
867        maxFilesCount: 0, // 0 - no limit, works only in multiple mode
868        minFilesCount: 0, // 0 - no limit, works only in multiple mode
869        // events
870        // return false to cancel submit
871        onSubmit: function(id, fileName){},
872        onProgress: function(id, fileName, loaded, total){},
873        onComplete: function(id, fileName, responseJSON){},
874        onCancel: function(id, fileName){},
875        // messages                
876        messages: {
877            typeError: "{file} has invalid extension. Only {extensions} are allowed.",
878            sizeError: "{file} is too large, maximum file size is {sizeLimit}.",
879            minSizeError: "{file} is too small, minimum file size is {minSizeLimit}.",
880            emptyError: "{file} is empty, please select files again without it.",
881            onLeave: "The files are being uploaded, if you leave now the upload will be cancelled.",
882            maxFilesError: "You must select less then {maxFilesCount} files.",
883            minFilesError: "You must select more then {minFilesCount} files."
884        },
885        showMessage: function(message){
886            alert(message);
887        }               
888    };
889    qq.extend(this._options, o);
890        
891    // number of files being uploaded
892    this._filesInProgress = 0;
893    // number of files was processed
894    this._filesUploaded = 0;
895    this._handler = this._createUploadHandler(); 
896    
897    if (this._options.button){ 
898        this._button = this._createUploadButton(this._options.button);
899    }
900                        
901    this._preventLeaveInProgress();         
902};
903   
904qq.FileUploaderBasic.prototype = {
905    setParams: function(params){
906        this._options.params = params;
907    },
908    getInProgress: function(){
909        return this._filesInProgress;         
910    },
911    _createUploadButton: function(element){
912        var self = this;
913        
914        return new qq.UploadButton({
915            element: element,
916            multiple: this._options.multiple && qq.UploadHandlerXhr.isSupported(),
917            onChange: function(input){
918                self._onInputChange(input);
919            }        
920        });           
921    },    
922    _createUploadHandler: function(){
923        var self = this,
924            handlerClass;        
925        
926        if(qq.UploadHandlerXhr.isSupported()){           
927            handlerClass = 'UploadHandlerXhr';                        
928        } else {
929            handlerClass = 'UploadHandlerForm';
930        }
931
932        var handler = new qq[handlerClass]({
933            debug: this._options.debug,
934            action: this._options.action,         
935            maxConnections: this._options.maxConnections,
936            fieldName: this._options.fieldName,
937            method: this._options.method,   
938            onProgress: function(id, fileName, loaded, total){                
939                self._onProgress(id, fileName, loaded, total);
940                self._options.onProgress(id, fileName, loaded, total);                    
941            },            
942            onComplete: function(id, fileName, result){
943                self._onComplete(id, fileName, result);
944                self._options.onComplete(id, fileName, result);
945            },
946            onCancel: function(id, fileName){
947                self._onCancel(id, fileName);
948                self._options.onCancel(id, fileName);
949            }
950        });
951
952        return handler;
953    },    
954    _preventLeaveInProgress: function(){
955        var self = this;
956        
957        qq.attach(window, 'beforeunload', function(e){
958            if (!self._filesInProgress){return;}
959            
960            var e = e || window.event;
961            // for ie, ff
962            e.returnValue = self._options.messages.onLeave;
963            // for webkit
964            return self._options.messages.onLeave;             
965        });        
966    },    
967    _onSubmit: function(id, fileName){
968        this._filesInProgress++;  
969    },
970    _onProgress: function(id, fileName, loaded, total){        
971    },
972    _onComplete: function(id, fileName, result){
973        this._filesInProgress--;                 
974        if (result.error){
975            this._options.showMessage(result.error);
976        } else {
977          this._filesUploaded++;
978        }             
979    },
980    _onCancel: function(id, fileName){
981        this._filesInProgress--;        
982    },
983    _onInputChange: function(input){
984        if (this._handler instanceof qq.UploadHandlerXhr){                
985            this._uploadFileList(input.files);                   
986        } else {             
987            if (this._validateFile(input)){                
988                this._uploadFile(input);                                    
989            }                      
990        }               
991        this._button.reset();   
992    },  
993    _uploadFileList: function(files){
994        if ( this._validateFiles(files) ) {
995          for (var i=0; i<files.length; i++){
996              this._uploadFile(files[i]);        
997          }
998        }
999    },       
1000    _uploadFile: function(fileContainer){      
1001        var id = this._handler.add(fileContainer);
1002        var fileName = this._handler.getName(id);
1003        
1004        if (this._options.onSubmit(id, fileName) !== false){
1005            this._onSubmit(id, fileName);
1006            this._handler.upload(id, this._options.params);
1007        }
1008    },
1009    _validateFiles: function(files){
1010        var uploadedCount = this._filesUploaded + files.length;
1011        
1012        if (this._options.maxFilesCount > 0) {
1013          if ( uploadedCount > this._options.maxFilesCount) { 
1014            this._error('maxFilesError', 'name');
1015            return false;
1016          }
1017        }
1018        
1019        if (this._options.minFilesCount > 0) {
1020          if ( uploadedCount < this._options.minFilesCount) {
1021            this._error('minFilesError', 'name');
1022            return false;
1023          }
1024        }
1025        
1026        for (var i=0; i<files.length; i++){
1027            if ( !this._validateFile(files[i])){
1028                return false;
1029            }            
1030        }
1031        
1032        return true;
1033    },      
1034    _validateFile: function(file){
1035        var name, size;
1036        
1037        if (file.value){
1038            // it is a file input            
1039            // get input value and remove path to normalize
1040            name = file.value.replace(/.*(\/|\\)/, "");
1041        } else {
1042            // fix missing properties in Safari
1043            name = file.fileName != null ? file.fileName : file.name;
1044            size = file.fileSize != null ? file.fileSize : file.size;
1045        }
1046                    
1047        if (! this._isAllowedExtension(name)){            
1048            this._error('typeError', name);
1049            return false;
1050            
1051        } else if (size === 0){            
1052            this._error('emptyError', name);
1053            return false;
1054                                                     
1055        } else if (size && this._options.sizeLimit && size > this._options.sizeLimit){            
1056            this._error('sizeError', name);
1057            return false;
1058                        
1059        } else if (size && size < this._options.minSizeLimit){
1060            this._error('minSizeError', name);
1061            return false;            
1062        }
1063        
1064        return true;                
1065    },
1066    _error: function(code, fileName){
1067        var message = this._options.messages[code];        
1068        function r(name, replacement){ message = message.replace(name, replacement); }
1069        
1070        r('{file}', this._formatFileName(fileName));        
1071        r('{extensions}', this._options.allowedExtensions.join(', '));
1072        r('{sizeLimit}', this._formatSize(this._options.sizeLimit));
1073        r('{minSizeLimit}', this._formatSize(this._options.minSizeLimit));
1074        r('{maxFilesCount}', this._options.maxFilesCount);
1075        r('{minFilesCount}', this._options.minFilesCount);
1076        
1077        this._options.showMessage(message);                
1078    },
1079    _formatFileName: function(name){
1080        if (name.length > 33){
1081            name = name.slice(0, 19) + '...' + name.slice(-13);    
1082        }
1083        return name;
1084    },
1085    _isAllowedExtension: function(fileName){
1086        var ext = (-1 !== fileName.indexOf('.')) ? fileName.replace(/.*[.]/, '').toLowerCase() : '';
1087        var allowed = this._options.allowedExtensions;
1088        
1089        if (!allowed.length){return true;}        
1090        
1091        for (var i=0; i<allowed.length; i++){
1092            if (allowed[i].toLowerCase() == ext){ return true;}    
1093        }
1094        
1095        return false;
1096    },    
1097    _formatSize: function(bytes){
1098        var i = -1;                                    
1099        do {
1100            bytes = bytes / 1024;
1101            i++;  
1102        } while (bytes > 99);
1103        
1104        return Math.max(bytes, 0.1).toFixed(1) + ['kB', 'MB', 'GB', 'TB', 'PB', 'EB'][i];          
1105    }
1106};
1107    
1108       
1109/**
1110 * Class that creates upload widget with drag-and-drop and file list
1111 * @inherits qq.FileUploaderBasic
1112 */
1113qq.FileUploader = function(o){
1114    // call parent constructor
1115    qq.FileUploaderBasic.apply(this, arguments);
1116    
1117    // additional options    
1118    qq.extend(this._options, {
1119        element: null,
1120        // if set, will be used instead of qq-upload-list in template
1121        listElement: null,
1122                
1123        template: '<div class="qq-uploader">' + 
1124                '<div class="qq-upload-drop-area"><span>Drop files here to upload</span></div>' +
1125                '<div class="qq-upload-button">Upload a file</div>' +
1126                '<ul class="qq-upload-list"></ul>' + 
1127             '</div>',
1128
1129        // template for one item in file list
1130        fileTemplate: '<li>' +
1131                '<span class="qq-upload-file"></span>' +
1132                '<span class="qq-upload-spinner"></span>' +
1133                '<span class="qq-upload-size"></span>' +
1134                '<a class="qq-upload-cancel" href="#">Cancel</a>' +
1135                '<span class="qq-upload-failed-text">Failed</span>' +
1136            '</li>',        
1137        
1138        classes: {
1139            // used to get elements from templates
1140            button: 'qq-upload-button',
1141            drop: 'qq-upload-drop-area',
1142            dropActive: 'qq-upload-drop-area-active',
1143            list: 'qq-upload-list',
1144                        
1145            file: 'qq-upload-file',
1146            spinner: 'qq-upload-spinner',
1147            size: 'qq-upload-size',
1148            cancel: 'qq-upload-cancel',
1149
1150            // added to list item when upload completes
1151            // used in css to hide progress spinner
1152            success: 'qq-upload-success',
1153            fail: 'qq-upload-fail'
1154        }
1155    });
1156    // overwrite options with user supplied    
1157    qq.extend(this._options, o);       
1158
1159    this._element = this._options.element;
1160    this._element.innerHTML = this._options.template;        
1161    this._listElement = this._options.listElement || this._find(this._element, 'list');
1162    
1163    this._classes = this._options.classes;
1164        
1165    this._button = this._createUploadButton(this._find(this._element, 'button'));        
1166    
1167    this._bindCancelEvent();
1168    this._setupDragDrop();
1169};
1170
1171// inherit from Basic Uploader
1172qq.extend(qq.FileUploader.prototype, qq.FileUploaderBasic.prototype);
1173
1174qq.extend(qq.FileUploader.prototype, {
1175    /**
1176     * Gets one of the elements listed in this._options.classes
1177     **/
1178    _find: function(parent, type){                                
1179        var element = qq.getByClass(parent, this._options.classes[type])[0];        
1180        if (!element){
1181            throw new Error('element not found ' + type);
1182        }
1183        
1184        return element;
1185    },
1186    _setupDragDrop: function(){
1187        var self = this,
1188            dropArea = this._find(this._element, 'drop');                        
1189
1190        var dz = new qq.UploadDropZone({
1191            element: dropArea,
1192            onEnter: function(e){
1193                qq.addClass(dropArea, self._classes.dropActive);
1194                e.stopPropagation();
1195            },
1196            onLeave: function(e){
1197                e.stopPropagation();
1198            },
1199            onLeaveNotDescendants: function(e){
1200                qq.removeClass(dropArea, self._classes.dropActive);  
1201            },
1202            onDrop: function(e){
1203                dropArea.style.display = 'none';
1204                qq.removeClass(dropArea, self._classes.dropActive);
1205                self._uploadFileList(e.dataTransfer.files);    
1206            }
1207        });
1208                
1209        dropArea.style.display = 'none';
1210
1211        qq.attach(document, 'dragenter', function(e){     
1212            if (!dz._isValidFileDrag(e)) return; 
1213            
1214            dropArea.style.display = 'block';            
1215        });                 
1216        qq.attach(document, 'dragleave', function(e){
1217            if (!dz._isValidFileDrag(e)) return;            
1218            
1219            var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);
1220            // only fire when leaving document out
1221            if ( ! relatedTarget || relatedTarget.nodeName == "HTML"){               
1222                dropArea.style.display = 'none';                                            
1223            }
1224        });                
1225    },
1226    _onSubmit: function(id, fileName){
1227        qq.FileUploaderBasic.prototype._onSubmit.apply(this, arguments);
1228        this._addToList(id, fileName);  
1229    },
1230    _onProgress: function(id, fileName, loaded, total){
1231        qq.FileUploaderBasic.prototype._onProgress.apply(this, arguments);
1232
1233        var item = this._getItemByFileId(id);
1234        var size = this._find(item, 'size');
1235        size.style.display = 'inline';
1236        
1237        var text; 
1238        if (loaded != total){
1239            text = Math.round(loaded / total * 100) + '% from ' + this._formatSize(total);
1240        } else {                                   
1241            text = this._formatSize(total);
1242        }          
1243        
1244        qq.setText(size, text);         
1245    },
1246    _onComplete: function(id, fileName, result){
1247        qq.FileUploaderBasic.prototype._onComplete.apply(this, arguments);
1248
1249        // mark completed
1250        var item = this._getItemByFileId(id);                
1251        qq.remove(this._find(item, 'cancel'));
1252        qq.remove(this._find(item, 'spinner'));
1253        
1254        if (result.success){
1255            qq.addClass(item, this._classes.success);    
1256        } else {
1257            qq.addClass(item, this._classes.fail);
1258        }         
1259    },
1260    _addToList: function(id, fileName){
1261        var item = qq.toElement(this._options.fileTemplate);                
1262        item.qqFileId = id;
1263
1264        var fileElement = this._find(item, 'file');        
1265        qq.setText(fileElement, this._formatFileName(fileName));
1266        this._find(item, 'size').style.display = 'none';        
1267
1268        this._listElement.appendChild(item);
1269    },
1270    _getItemByFileId: function(id){
1271        var item = this._listElement.firstChild;        
1272        
1273        // there can't be txt nodes in dynamically created list
1274        // and we can  use nextSibling
1275        while (item){            
1276            if (item.qqFileId == id) return item;            
1277            item = item.nextSibling;
1278        }          
1279    },
1280    /**
1281     * delegate click event for cancel link 
1282     **/
1283    _bindCancelEvent: function(){
1284        var self = this,
1285            list = this._listElement;            
1286        
1287        qq.attach(list, 'click', function(e){            
1288            e = e || window.event;
1289            var target = e.target || e.srcElement;
1290            
1291            if (qq.hasClass(target, self._classes.cancel)){                
1292                qq.preventDefault(e);
1293               
1294                var item = target.parentNode;
1295                self._handler.cancel(item.qqFileId);
1296                qq.remove(item);
1297            }
1298        });
1299    }    
1300});
1301    
1302qq.UploadDropZone = function(o){
1303    this._options = {
1304        element: null,  
1305        onEnter: function(e){},
1306        onLeave: function(e){},  
1307        // is not fired when leaving element by hovering descendants   
1308        onLeaveNotDescendants: function(e){},   
1309        onDrop: function(e){}                       
1310    };
1311    qq.extend(this._options, o); 
1312    
1313    this._element = this._options.element;
1314    
1315    this._disableDropOutside();
1316    this._attachEvents();   
1317};
1318
1319qq.UploadDropZone.prototype = {
1320    _disableDropOutside: function(e){
1321        // run only once for all instances
1322        if (!qq.UploadDropZone.dropOutsideDisabled ){
1323
1324            qq.attach(document, 'dragover', function(e){
1325                if (e.dataTransfer){
1326                    e.dataTransfer.dropEffect = 'none';
1327                    e.preventDefault(); 
1328                }           
1329            });
1330            
1331            qq.UploadDropZone.dropOutsideDisabled = true; 
1332        }        
1333    },
1334    _attachEvents: function(){
1335        var self = this;              
1336                  
1337        qq.attach(self._element, 'dragover', function(e){
1338            if (!self._isValidFileDrag(e)) return;
1339            
1340            var effect = e.dataTransfer.effectAllowed;
1341            if (effect == 'move' || effect == 'linkMove'){
1342                e.dataTransfer.dropEffect = 'move'; // for FF (only move allowed)    
1343            } else {                    
1344                e.dataTransfer.dropEffect = 'copy'; // for Chrome
1345            }
1346                                                     
1347            e.stopPropagation();
1348            e.preventDefault();                                                                    
1349        });
1350        
1351        qq.attach(self._element, 'dragenter', function(e){
1352            if (!self._isValidFileDrag(e)) return;
1353                        
1354            self._options.onEnter(e);
1355        });
1356        
1357        qq.attach(self._element, 'dragleave', function(e){
1358            if (!self._isValidFileDrag(e)) return;
1359            
1360            self._options.onLeave(e);
1361            
1362            var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);                      
1363            // do not fire when moving a mouse over a descendant
1364            if (qq.contains(this, relatedTarget)) return;
1365                        
1366            self._options.onLeaveNotDescendants(e); 
1367        });
1368                
1369        qq.attach(self._element, 'drop', function(e){
1370            if (!self._isValidFileDrag(e)) return;
1371            
1372            e.preventDefault();
1373            self._options.onDrop(e);
1374        });          
1375    },
1376    _isValidFileDrag: function(e){
1377        var dt = e.dataTransfer,
1378            // do not check dt.types.contains in webkit, because it crashes safari 4            
1379            isWebkit = navigator.userAgent.indexOf("AppleWebKit") > -1;                        
1380
1381        // dt.effectAllowed is none in Safari 5
1382        // dt.types.contains check is for firefox            
1383        return dt && dt.effectAllowed != 'none' && 
1384            (dt.files || (!isWebkit && dt.types.contains && dt.types.contains('Files')));
1385        
1386    }        
1387}; 
1388
1389qq.UploadButton = function(o){
1390    this._options = {
1391        element: null,  
1392        // if set to true adds multiple attribute to file input      
1393        multiple: false,
1394        // name attribute of file input
1395        name: 'file',
1396        onChange: function(input){},
1397        hoverClass: 'qq-upload-button-hover',
1398        focusClass: 'qq-upload-button-focus'                       
1399    };
1400    
1401    qq.extend(this._options, o);
1402        
1403    this._element = this._options.element;
1404    
1405    // make button suitable container for input
1406    qq.css(this._element, {
1407        position: 'relative',
1408        overflow: 'hidden',
1409        // Make sure browse button is in the right side
1410        // in Internet Explorer
1411        direction: 'ltr'
1412    });   
1413    
1414    this._input = this._createInput();
1415};
1416
1417qq.UploadButton.prototype = {
1418    /* returns file input element */    
1419    getInput: function(){
1420        return this._input;
1421    },
1422    /* cleans/recreates the file input */
1423    reset: function(){
1424        if (this._input.parentNode){
1425            qq.remove(this._input);    
1426        }                
1427        
1428        qq.removeClass(this._element, this._options.focusClass);
1429        this._input = this._createInput();
1430    },    
1431    _createInput: function(){                
1432        var input = document.createElement("input");
1433        
1434        if (this._options.multiple){
1435            input.setAttribute("multiple", "multiple");
1436        }
1437                
1438        input.setAttribute("type", "file");
1439        input.setAttribute("name", this._options.name);
1440        
1441        qq.css(input, {
1442            position: 'absolute',
1443            // in Opera only 'browse' button
1444            // is clickable and it is located at
1445            // the right side of the input
1446            right: 0,
1447            top: 0,
1448            fontFamily: 'Arial',
1449            // 4 persons reported this, the max value
1449s that worked for them were 243, 236, 236, 118
1450            fontSize: '118px',
1451            margin: 0,
1452            padding: 0,
1453            cursor: 'pointer',
1454            opacity: 0
1455        });
1456        
1457        this._element.appendChild(input);
1458
1459        var self = this;
1460        qq.attach(input, 'change', function(){
1461            self._options.onChange(input);
1462        });
1463                
1464        qq.attach(input, 'mouseover', function(){
1465            qq.addClass(self._element, self._options.hoverClass);
1466        });
1467        qq.attach(input, 'mouseout', function(){
1468            qq.removeClass(self._element, self._options.hoverClass);
1469        });
1470        qq.attach(input, 'focus', function(){
1471            qq.addClass(self._element, self._options.focusClass);
1472        });
1473        qq.attach(input, 'blur', function(){
1474            qq.removeClass(self._element, self._options.focusClass);
1475        });
1476
1477        // IE and Opera, unfortunately have 2 tab stops on file input
1478        // which is unacceptable in our case, disable keyboard access
1479        if (window.attachEvent){
1480            // it is IE or Opera
1481            input.setAttribute('tabIndex', "-1");
1482        }
1483
1484        return input;            
1485    }        
1486};
1487
1488/**
1489 * Class for uploading files, uploading itself is handled by child classes
1490 */
1491qq.UploadHandlerAbstract = function(o){
1492    this._options = {
1493        debug: false,
1494        action: '/upload.php',
1495        method: 'POST',
1496        fieldName: 'qqfile',
1497        // maximum number of concurrent uploads        
1498        maxConnections: 999,
1499        onProgress: function(id, fileName, loaded, total){},
1500        onComplete: function(id, fileName, response){},
1501        onCancel: function(id, fileName){}
1502    };
1503    qq.extend(this._options, o);    
1504    
1505    this._queue = [];
1506    // params for files in queue
1507    this._params = [];
1508};
1509qq.UploadHandlerAbstract.prototype = {
1510    log: function(str){
1511        if (this._options.debug && window.console) console.log('[uploader] ' + str);        
1512    },
1513    /**
1514     * Adds file or file input to the queue
1515     * @returns id
1516     **/    
1517    add: function(file){},
1518    /**
1519     * Sends the file identified by id and additional query params to the server
1520     */
1521    upload: function(id, params){
1522        var len = this._queue.push(id);
1523
1524        var copy = {};        
1525        qq.extend(copy, params);
1526        this._params[id] = copy;        
1527                
1528        // if too many active uploads, wait...
1529        if (len <= this._options.maxConnections){               
1530            this._upload(id, this._params[id]);
1531        }
1532    },
1533    /**
1534     * Cancels file upload by id
1535     */
1536    cancel: function(id){
1537        this._cancel(id);
1538        this._dequeue(id);
1539    },
1540    /**
1541     * Cancells all uploads
1542     */
1543    cancelAll: function(){
1544        for (var i=0; i<this._queue.length; i++){
1545            this._cancel(this._queue[i]);
1546        }
1547        this._queue = [];
1548    },
1549    /**
1550     * Returns name of the file identified by id
1551     */
1552    getName: function(id){},
1553    /**
1554     * Returns size of the file identified by id
1555     */          
1556    getSize: function(id){},
1557    /**
1558     * Returns id of files being uploaded or
1559     * waiting for their turn
1560     */
1561    getQueue: function(){
1562        return this._queue;
1563    },
1564    /**
1565     * Actual upload method
1566     */
1567    _upload: function(id){},
1568    /**
1569     * Actual cancel method
1570     */
1571    _cancel: function(id){},     
1572    /**
1573     * Removes element from queue, starts upload of next
1574     */
1575    _dequeue: function(id){
1576        var i = qq.indexOf(this._queue, id);
1577        this._queue.splice(i, 1);
1578                
1579        var max = this._options.maxConnections;
1580        
1581        if (this._queue.length >= max && i < max){
1582            var nextId = this._queue[max-1];
1583            this._upload(nextId, this._params[nextId]);
1584        }
1585    }        
1586};
1587
1588/**
1589 * Class for uploading files using form and iframe
1590 * @inherits qq.UploadHandlerAbstract
1591 */
1592qq.UploadHandlerForm = function(o){
1593    qq.UploadHandlerAbstract.apply(this, arguments);
1594       
1595    this._inputs = {};
1596};
1597// @inherits qq.UploadHandlerAbstract
1598qq.extend(qq.UploadHandlerForm.prototype, qq.UploadHandlerAbstract.prototype);
1599
1600qq.extend(qq.UploadHandlerForm.prototype, {
1601    add: function(fileInput){
1602        fileInput.setAttribute('name', this._options.fieldName);
1603        var id = 'qq-upload-handler-iframe' + qq.getUniqueId();       
1604        
1605        this._inputs[id] = fileInput;
1606        
1607        // remove file input from DOM
1608        if (fileInput.parentNode){
1609            qq.remove(fileInput);
1610        }
1611                
1612        return id;
1613    },
1614    getName: function(id){
1615        // get input value and remove path to normalize
1616        return this._inputs[id].value.replace(/.*(\/|\\)/, "");
1617    },    
1618    _cancel: function(id){
1619        this._options.onCancel(id, this.getName(id));
1620        
1621        delete this._inputs[id];        
1622
1623        var iframe = document.getElementById(id);
1624        if (iframe){
1625            // to cancel request set src to something else
1626            // we use src="javascript:false;" because it doesn't
1627            // trigger ie6 prompt on https
1628            iframe.setAttribute('src', 'javascript:false;');
1629
1630            qq.remove(iframe);
1631        }
1632    },     
1633    _upload: function(id, params){                        
1634        var input = this._inputs[id];
1635        
1636        if (!input){
1637            throw new Error('file with passed id was not added, or already uploaded or cancelled');
1638        }                
1639
1640        var fileName = this.getName(id);
1641                
1642        var iframe = this._createIframe(id);
1643        var form = this._createForm(iframe, params);
1644        form.appendChild(input);
1645
1646        var self = this;
1647        this._attachLoadEvent(iframe, function(){                                 
1648            self.log('iframe loaded');
1649            
1650            var response = self._getIframeContentJSON(iframe);
1651
1652            self._options.onComplete(id, fileName, response);
1653            self._dequeue(id);
1654            
1655            delete self._inputs[id];
1656            // timeout added to fix busy state in FF3.6
1657            setTimeout(function(){
1658                qq.remove(iframe);
1659            }, 1);
1660        });
1661
1662        form.submit();        
1663        qq.remove(form);        
1664        
1665        return id;
1666    }, 
1667    _attachLoadEvent: function(iframe, callback){
1668        qq.attach(iframe, 'load', function(){
1669            // when we remove iframe from dom
1670            // the request stops, but in IE load
1671            // event fires
1672            if (!iframe.parentNode){
1673                return;
1674            }
1675
1676            // fixing Opera 10.53
1677            if (iframe.contentDocument &&
1678                iframe.contentDocument.body &&
1679                iframe.contentDocument.body.innerHTML == "false"){
1680                // In Opera event is fired second time
1681                // when body.innerHTML changed from false
1682                // to server response approx. after 1 sec
1683                // when we upload file with iframe
1684                return;
1685            }
1686
1687            callback();
1688        });
1689    },
1690    /**
1691     * Returns json object received by iframe from server.
1692     */
1693    _getIframeContentJSON: function(iframe){
1694        // iframe.contentWindow.document - for IE<7
1695        var doc = iframe.contentDocument ? iframe.contentDocument: iframe.contentWindow.document,
1696            response;
1697        
1698        this.log("converting iframe's innerHTML to JSON");
1699        this.log("innerHTML = " + doc.body.innerHTML);
1700                        
1701        try {
1702            response = eval("(" + doc.body.innerHTML + ")");
1703        } catch(err){
1704            response = {};
1705        }        
1706
1707        return response;
1708    },
1709    /**
1710     * Creates iframe with unique name
1711     */
1712    _createIframe: function(id){
1713        // We can't use following code as the name attribute
1714        // won't be properly registered in IE6, and new window
1715        // on form submit will open
1716        // var iframe = document.createElement('iframe');
1717        // iframe.setAttribute('name', id);
1718
1719        var iframe = qq.toElement('<iframe src="javascript:false;" name="' + id + '" />');
1720        // src="javascript:false;" removes ie6 prompt on https
1721
1722        iframe.setAttribute('id', id);
1723
1724        iframe.style.display = 'none';
1725        document.body.appendChild(iframe);
1726
1727        return iframe;
1728    },
1729    /**
1730     * Creates form, that will be submitted to iframe
1731     */
1732    _createForm: function(iframe, params){
1733        // We can't use the following code in IE6
1734        // var form = document.createElement('form');
1735        // form.setAttribute('method', 'post');
1736        // form.setAttribute('enctype', 'multipart/form-data');
1737        // Because in this case file won't be attached to request
1738        var form = qq.toElement('<form enctype="multipart/form-data"></form>');
1739
1740        var queryString = qq.obj2url(params, this._options.action);
1741        
1742        form.setAttribute('method', this._options.method);
1743        form.setAttribute('action', queryString);
1744        form.setAttribute('target', iframe.name);
1745        form.style.display = 'none';
1746
1747        // Rails CSRFProtection
1748        var token = $('meta[name="csrf-token"]').attr('content');
1749        var param = $('meta[name="csrf-param"]').attr('content');
1750        var input = qq.toElement('<input type="hidden" />');
1751        
1752        input.setAttribute('name', param);
1753        input.setAttribute('value', token);
1754        
1755        form.appendChild(input);
1756        document.body.appendChild(form);
1757
1758        return form;
1759    }
1760});
1761
1762/**
1763 * Class for uploading files using xhr
1764 * @inherits qq.UploadHandlerAbstract
1765 */
1766qq.UploadHandlerXhr = function(o){
1767    qq.UploadHandlerAbstract.apply(this, arguments);
1768
1769    this._files = [];
1770    this._xhrs = [];
1771    
1772    // current loaded size in bytes for each file 
1773    this._loaded = [];
1774};
1775
1776// static method
1777qq.UploadHandlerXhr.isSupported = function(){
1778    var input = document.createElement('input');
1779    input.type = 'file';        
1780    
1781    return (
1782        'multiple' in input &&
1783        typeof File != "undefined" &&
1784        typeof (new XMLHttpRequest()).upload != "undefined" );       
1785};
1786
1787// @inherits qq.UploadHandlerAbstract
1788qq.extend(qq.UploadHandlerXhr.prototype, qq.UploadHandlerAbstract.prototype)
1789
1790qq.extend(qq.UploadHandlerXhr.prototype, {
1791    /**
1792     * Adds file to the queue
1793     * Returns id to use with upload, cancel
1794     **/    
1795    add: function(file){
1796        if (!(file instanceof File)){
1797            throw new Error('Passed obj in not a File (in qq.UploadHandlerXhr)');
1798        }
1799                
1800        return this._files.push(file) - 1;        
1801    },
1802    getName: function(id){        
1803        var file = this._files[id];
1804        // fix missing name in Safari 4
1805        return file.fileName != null ? file.fileName : file.name;       
1806    },
1807    getSize: function(id){
1808        var file = this._files[id];
1809        return file.fileSize != null ? file.fileSize : file.size;
1810    },    
1811    /**
1812     * Returns uploaded bytes for file identified by id 
1813     */    
1814    getLoaded: function(id){
1815        return this._loaded[id] || 0; 
1816    },
1817    /**
1818     * Sends the file identified by id and additional query params to the server
1819     * @param {Object} params name-value string pairs
1820     */    
1821    _upload: function(id, params){
1822        var file = this._files[id],
1823            name = this.getName(id),
1824            size = this.getSize(id);
1825                
1826        this._loaded[id] = 0;
1827                                
1828        var xhr = this._xhrs[id] = new XMLHttpRequest();
1829        var self = this;
1830                                        
1831        xhr.upload.onprogress = function(e){
1832            if (e.lengthComputable){
1833                self._loaded[id] = e.loaded;
1834                self._options.onProgress(id, name, e.loaded, e.total);
1835            }
1836        };
1837
1838        xhr.onreadystatechange = function(){            
1839            if (xhr.readyState == 4){
1840                self._onComplete(id, xhr);                    
1841            }
1842        };
1843
1844        // build query string
1845        params = params || {};
1846        params[this._options.fieldName] = name;
1847        var queryString = qq.obj2url(params, this._options.action);
1848
1849        xhr.open(this._options.method, queryString, true);
1850        xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
1851        xhr.setRequestHeader("X-File-Name", encodeURIComponent(name));
1852        xhr.setRequestHeader('X-File-Size', size);
1853        xhr.setRequestHeader('X-File-Type', file.type);
1854        xhr.setRequestHeader("Content-Type", "application/octet-stream");
1855
1856        // Rails CSRFProtection
1857        if ($.rails) $.rails.CSRFProtection(xhr);        
1858
1859        xhr.send(file);
1860    },
1861    _onComplete: function(id, xhr){
1862        // the request was aborted/cancelled
1863        if (!this._files[id]) return;
1864        
1865        var name = this.getName(id);
1866        var size = this.getSize(id);
1867        
1868        this._options.onProgress(id, name, size, size);
1869                
1870        if ([200, 201].indexOf( xhr.status ) > -1){
1871            this.log("xhr - server response received");
1872            this.log("responseText = " + xhr.responseText);
1873                        
1874            var response;
1875                    
1876            try {
1877                response = eval("(" + xhr.responseText + ")");
1878            } catch(err){
1879                response = {};
1880            }
1881            
1882            this._options.onComplete(id, name, response);
1883                        
1884        } else {                   
1885            this._options.onComplete(id, name, {});
1886        }
1887                
1888        this._files[id] = null;
1889        this._xhrs[id] = null;    
1890        this._dequeue(id);                    
1891    },
1892    _cancel: function(id){
1893        this._options.onCancel(id, this.getName(id));
1894        
1895        this._files[id] = null;
1896        
1897        if (this._xhrs[id]){
1898            this._xhrs[id].abort();
1899            this._xhrs[id] = null;                                   
1900        }
1901    }
1902});
1903/**
1904 * Author: Sergey Kukunin
1905 * See: https://github.com/Kukunin/jquery-endless-scroll
1906 */
1907(function($) {
1908	'use strict';
1909
1910	// Is pushState supported by this browser?
1911	$.support.pushState =
1912		window.history && window.history.pushState && window.history.replaceState &&
1913		// pushState isn't reliable on iOS until 5.
1914		!navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]|WebApps\/.+CFNetwork)/)
1915
1916	//Declaration of modules
1917	var scrollModule = {
1918		init: function(options, obj) {
1919			obj.options = $.extend({
1920				scrollContainer: window,
1921				scrollPadding: 100,
1922				scrollEventDelay: 300
1923			}, options);
1924			this.options = obj.options;
1925			this.container = obj.container;
1926			obj.scrollModule = this;
1927
1928			this._toplock = true;
1929			this._bottomlock = true;
1930
1931			this.scrollContainer = $(this.options.scrollContainer);
1932
1933			this.updateEntities();
1934			this.sortMarkers();
1935
1936			this.currentPage = null;
1937
1938			this.container.on("jes:afterPageLoad", $.proxy(function(event, url, placement) {
1939				this.updateEntities();
1940				this.sortMarkers();
1941				this.checkMarker();
1942
1943				if ( placement == "top" ) {
1944					//Get offset between first and second pages
1945					var offset = this.markers[1].top,
1946						scrollTop = this.scrollContainer.scrollTop();
1947
1948					this.scrollContainer.scrollTop(scrollTop + offset);
1949				}
1950			}, this));
1951
1952			this.bind();
1953		},
1954		updateEntities: function() {
1955			this.entities = $(this.options.entity, this.container);
1956		},
1957		sortMarkers: function() {
1958			var markers = [];
1959			$(".jes-marker", this.container).each(function() {
1960				markers.push({ top: $(this).position().top, url: $(this).data("jesUrl") });
1961			});
1962			this.markers = markers;
1963		},
1964		//Check, whether user scrolled to another page
1965		checkMarker: function() {
1966			var newPage = this.markers[0],
1967				scrollTop = this.scrollContainer.scrollTop();
1968
1969			//Determine, what is current page
1970			for ( var i = 1; i < this.markers.length; i++ ) {
1971				if ( scrollTop > this.markers[i].top ) {
1972					newPage = this.markers[i];
1973				} else {
1974					break;
1975				}
1976			}
1977			if ( newPage.url != this.currentPage ) {
1978				this.currentPage = newPage.url;
1979				$(this.container).trigger("jes:scrollToPage", newPage.url);
1980			}
1981		},
1982		bind: function() {
1983			this.scrollContainer.on("scroll.jes", $.proxy(function(event) {
1984				if ( this._tId ) { return; }
1985
1986				this.scrollHandler(event);
1987				//Clean up mark
1988				this._tId= setTimeout($.proxy(function(){
1989					this._tId = null;
1990				},this), this.options.scrollEventDelay);
1991
1992			}, this));
1993		},
1994		unbind: function() {
1995			$(this.options.scrollContainer).off("scroll.jes");
1996		},
1997		scrollHandler: function(ev) {
1998			var $scrollable = this.scrollContainer,
1999				$entities = this.entities,
2000				$firstEntity = $entities.first(),
2001				$lastEntity = $entities.last();
2002
2003			var scrollTop = $scrollable.scrollTop(),
2004				height = $scrollable.height(),
2005				scrollBottom = scrollTop + height;
2006
2007			var topEntityPosition = $firstEntity.position().top,
2008				topTarget = topEntityPosition + this.options.scrollPadding,
2009				bottomEntityPosition = $lastEntity.outerHeight() + $lastEntity.position().top,
2010				bottomTarget = bottomEntityPosition - this.options.scrollPadding;
2011
2012			//Don't trigger event again, if already fired
2013			//Visitor have to leave the area and get back to fire event again
2014			//Process top threshold
2015			if ( scrollTop < topTarget ) {
2016				if ( !this._toplock ) {
2017					$(this.container).trigger("jes:topThreshold");
2018					this._toplock = true;
2019				}
2020			} else {
2021				this._toplock = false;
2022			}
2023
2024			//Process bottom threshold
2025			if ( scrollBottom > bottomTarget ) {
2026				if ( !this._bottomlock ) {
2027					$(this.container).trigger("jes:bottomThreshold");
2028					this._bottomlock = true;
2029				}
2030			} else {
2031				this._bottomlock = false;
2032			}
2033
2034			this.checkMarker();
2035		}
2036	}
2037
2038	var ajaxModule = {
2039		init: function(options, obj) {
2040			obj.options = $.extend({
2041			}, options);
2042
2043			this.options = obj.options;
2044			this.container = obj.container;
2045
2046			//markers
2047			this.setMarker($(this.options.entity, this.container).first(), location.href);
2048
2049			obj.ajaxModule = this;
2050		},
2051		loadPage: function(url, placement, callback) {
2052			//The hash with methods list
2053			//depends from placement
2054			var actions = {
2055					top: {
2056						find: 'first',
2057						inject: 'insertBefore'
2058					},
2059					bottom: {
2060						find: 'last',
2061						inject: 'insertAfter'
2062					}
2063				},
2064				action = actions[placement];
2065
2066			this.container.trigger("jes:beforePageLoad", [url, placement]);
2067
2068			//Make AJAX query
2069			$.get(url, null, $.proxy(function (_data) {
2070				var data = $("<div>").html(_data),
2071				containerSelector = this.options.container,
2072				container = $(containerSelector, data).first();
2073
2074				if ( container.length ) {
2075					//Find entities
2076					var entities = container.find(this.options.entity);
2077
2078					if ( placement == "bottom" ) {
2079						//Remove duplicated (staled) entities from page
2080						entities.each(function(i) {
2081							var id = $(this).attr("id");
2082							if ( id ) {
2083								$('#' + id, this.container).remove();
2084							}
2085						});
2086					}
2087
2088					//Find the cursor
2089					var cursor = $(this.options.entity, containerSelector)[action.find]();
2090
2091					//Find and insert entities
2092					entities[action.inject](cursor);
2093					this.setMarker(entities.first(), url);
2094				}
2095
2096				if ( $.isFunction(callback) ) {
2097					callback(data);
2098				}
2099				this.container.trigger("jes:afterPageLoad", [url, placement, data, entities]);
2100			}, this), 'html');
2101		},
2102		setMarker: function(entity, url) {
2103			entity.addClass("jes-marker").data("jesUrl", url);
2104		}
2105	}
2106
2107	var navigationModule = {
2108		init: function(options, obj) {
2109			obj.options = $.extend({
2110				nextPage: ".pagination a[rel=next]",
2111				previousPage: ".pagination a[rel=previous]"
2112			}, options);
2113
2114			this.options = obj.options;
2115			this.container = obj.container;
2116
2117			$.each([{
2118				selector: this.options.nextPage,
2119				event: "jes:bottomThreshold.navigation",
2120				placement: 'bottom'
2121			}, {
2122				selector: this.options.previousPage,
2123				event: "jes:topThreshold.navigation",
2124				placement: 'top'
2125			}], $.proxy(function(i, v) {
2126				v.element = $(v.selector);
2127				if ( v.element.length ) {
2128					var url = v.element.prop("href"),
2129					lock = false;
2130
2131					var handler = function() {
2132						//this object is container
2133						if ( lock || !url ) return;
2134
2135						lock = true;
2136						obj.ajaxModule.loadPage(url, v.placement, $.proxy(function( data ) {
2137							//Search new next link
2138							var newElement = $(v.selector, $(data));
2139							if ( newElement.length ) {
2140								//Update URL and remove lock
2141								lock = false;
2142								url = newElement.prop("href");
2143								v.element.attr("href", url);
2144							} else {
2145								//Remove event at all
2146								$(this).off(v.event);
2147								v.element.remove();
2148							}
2149						}, this));
2150					};
2151
2152					$(this.container).on(v.event, handler);
2153					$(v.element).on("click", $.proxy(function(ev) {
2154						ev.preventDefault();
2155						handler.apply(this.container)
2156					}, this));
2157				}
2158			},this));
2159		}
2160	}
2161
2162	var pushStateHistory = {
2163		init: function(options, obj) {
2164			if ( !$.support.pushState ) {
2165				return;
2166			}
2167
2168			obj.container.on("jes:scrollToPage", function(event, url) {
2169				history.replaceState({}, null, url);
2170			});
2171		}
2172	}
2173
2174	$.endlessScroll = function(options) {
2175
2176		//Initialize modules
2177		this.options = $.extend(true, {
2178			container: "#container",
2179			entity: ".entity",
2180			_modules: [ ajaxModule, scrollModule, navigationModule, pushStateHistory ],
2181			modules: []
2182		}, options);
2183
2184		this.container = $(this.options.container);
2185		if ( !this.container.length ) {
2186			throw "Container for endless scroll isn't available on the page";
2187			return;
2188		}
2189
2190
2191		//Merge custom options with default
2192		$.merge(this.options.modules, this.options._modules);
2193		//Init modules
2194		this.options.modules.forEach($.proxy(function(module) {
2195			module.init(this.options, this);
2196		},this));
2197
2198
2199		return this;
2200	}
2201
2202})(jQuery);
2203(function($, undefined) {
2204
2205/**
2206 * Unobtrusive scripting adapter for jQuery
2207 *
2208 * Requires jQuery 1.6.0 or later.
2209 * https://github.com/rails/jquery-ujs
2210
2211 * Uploading file using rails.js
2212 * =============================
2213 *
2214 * By default, browsers do not allow files to be uploaded via AJAX. As a result, if there are any non-blank file fields
2215 * in the remote form, this adapter aborts the AJAX submission and allows the form to submit through standard means.
2216 *
2217 * The `ajax:aborted:file` event allows you to bind your own handler to process the form submission however you wish.
2218 *
2219 * Ex:
2220 *     $('form').live('ajax:aborted:file', function(event, elements){
2221 *       // Implement own remote file-transfer handler here for non-blank file inputs passed in `elements`.
2222 *       // Returning false in this handler tells rails.js to disallow standard form submission
2223 *       return false;
2224 *     });
2225 *
2226 * The `ajax:aborted:file` event is fired when a file-type input is detected with a non-blank value.
2227 *
2228 * Third-party tools can use this hook to detect when an AJAX file upload is attempted, and then use
2229 * techniques like the iframe method to upload the file instead.
2230 *
2231 * Required fields in rails.js
2232 * ===========================
2233 *
2234 * If any blank required inputs (required="required") are detected in the remote form, the whole form submission
2235 * is canceled. Note that this is unlike file inputs, which still allow standard (non-AJAX) form submission.
2236 *
2237 * The `ajax:aborted:required` event allows you to bind your own handler to inform the user of blank required inputs.
2238 *
2239 * !! Note that Opera does not fire the form's submit event if there are blank required inputs, so this event may never
2240 *    get fired in Opera. This event is what causes other browsers to exhibit the same submit-aborting behavior.
2241 *
2242 * Ex:
2243 *     $('form').live('ajax:aborted:required', function(event, elements){
2244 *       // Returning false in this handler tells rails.js to submit the form anyway.
2245 *       // The blank required inputs are passed to this function in `elements`.
2246 *       return ! confirm("Would you like to submit the form with missing info?");
2247 *     });
2248 */
2249
2250  // Shorthand to make it a little easier to call public rails functions from within rails.js
2251  var rails;
2252
2253  $.rails = rails = {
2254    // Link elements bound by jquery-ujs
2255    linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote], a[data-disable-with]',
2256
2257    // Select elements bound by jquery-ujs
2258    inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]',
2259
2260    // Form elements bound by jquery-ujs
2261    formSubmitSelector: 'form',
2262
2263    // Form input elements bound by jquery-ujs
2264    formInputClickSelector: 'form input[type=submit], form input[type=image], form button[type=submit], form button:not(button[type])',
2265
2266    // Form input elements disabled during form submission
2267    disableSelector: 'input[data-disable-with], button[data-disable-with], textarea[data-disable-with]',
2268
2269    // Form input elements re-enabled after form submission
2270    enableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled',
2271
2272    // Form required input elements
2273    requiredInputSelector: 'input[name][required]:not([disabled]),textarea[name][required]:not([disabled])',
2274
2275    // Form file input elements
2276    fileInputSelector: 'input:file',
2277
2278    // Link onClick disable selector with possible reenable after remote submission
2279    linkDisableSelector: 'a[data-disable-with]',
2280
2281    // Make sure that every Ajax request sends the CSRF token
2282    CSRFProtection: function(xhr) {
2283      var token = $('meta[name="csrf-token"]').attr('content');
2284      if (token) xhr.setRequestHeader('X-CSRF-Token', token);
2285    },
2286
2287    // Triggers an event on an element and returns false if the event result is false
2288    fire: function(obj, name, data) {
2289      var event = $.Event(name);
2290      obj.trigger(event, data);
2291      return event.result !== false;
2292    },
2293
2294    // Default confirm dialog, may be overridden with custom confirm dialog in $.rails.confirm
2295    confirm: function(message) {
2296      return confirm(message);
2297    },
2298
2299    // Default ajax function, may be overridden with custom function in $.rails.ajax
2300    ajax: function(options) {
2301      return $.ajax(options);
2302    },
2303
2304    // Submits "remote" forms and links with ajax
2305    handleRemote: function(element) {
2306      var method, url, data,
2307        crossDomain = element.data('cross-domain') || null,
2308        dataType = element.data('type') || ($.ajaxSettings && $.ajaxSettings.dataType),
2309        options;
2310
2311      if (rails.fire(element, 'ajax:before')) {
2312
2313        if (element.is('form')) {
2314          method = element.attr('method');
2315          url = element.attr('action');
2316          data = element.serializeArray();
2317          // memoized value from clicked submit button
2318          var button = element.data('ujs:submit-button');
2319          if (button) {
2320            data.push(button);
2321            element.data('ujs:submit-button', null);
2322          }
2323        } else if (element.is(rails.inputChangeSelector)) {
2324          method = element.data('method');
2325          url = element.data('url');
2326          data = element.serialize();
2327          if (element.data('params')) data = data + "&" + element.data('params');
2328        } else {
2329          method = element.data('method');
2330          url = element.attr('href');
2331          data = element.data('params') || null;
2332        }
2333
2334        options = {
2335          type: method || 'GET', data: data, dataType: dataType, crossDomain: crossDomain,
2336          // stopping the "ajax:beforeSend" event will cancel the ajax request
2337          beforeSend: function(xhr, settings) {
2338            if (settings.dataType === undefined) {
2339              xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script);
2340            }
2341            return rails.fire(element, 'ajax:beforeSend', [xhr, settings]);
2342          },
2343          success: function(data, status, xhr) {
2344            element.trigger('ajax:success', [data, status, xhr]);
2345          },
2346          complete: function(xhr, status) {
2347            element.trigger('ajax:complete', [xhr, status]);
2348          },
2349          error: function(xhr, status, error) {
2350            element.trigger('ajax:error', [xhr, status, error]);
2351          }
2352        };
2353        // Only pass url to `ajax` options if not blank
2354        if (url) { options.url = url; }
2355
2356        return rails.ajax(options);
2357      } else {
2358        return false;
2359      }
2360    },
2361
2362    // Handles "data-method" on links such as:
2363    // <a href="/users/5" data-method="delete" rel="nofollow" data-confirm="Are you sure?">Delete</a>
2364    handleMethod: function(link) {
2365      var href = link.attr('href'),
2366        method = link.data('method'),
2367        target = link.attr('target'),
2368        csrf_token = $('meta[name=csrf-token]').attr('content'),
2369        csrf_param = $('meta[name=csrf-param]').attr('content'),
2370        form = $('<form method="post" action="' + href + '"></form>'),
2371        metadata_input = '<input name="_method" value="' + method + '" type="hidden" />';
2372
2373      if (csrf_param !== undefined && csrf_token !== undefined) {
2374        metadata_input += '<input name="' + csrf_param + '" value="' + csrf_token + '" type="hidden" />';
2375      }
2376
2377      if (target) { form.attr('target', target); }
2378
2379      form.hide().append(metadata_input).appendTo('body');
2380      form.submit();
2381    },
2382
2383    /* Disables form elements:
2384      - Caches element value in 'ujs:enable-with' data store
2385      - Replaces element text with value of 'data-disable-with' attribute
2386      - Sets disabled property to true
2387    */
2388    disableFormElements: function(form) {
2389      form.find(rails.disableSelector).each(function() {
2390        var element = $(this), method = element.is('button') ? 'html' : 'val';
2391        element.data('ujs:enable-with', element[method]());
2392        element[method](element.data('disable-with'));
2393        element.prop('disabled', true);
2394      });
2395    },
2396
2397    /* Re-enables disabled form elements:
2398      - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`)
2399      - Sets disabled property to false
2400    */
2401    enableFormElements: function(form) {
2402      form.find(rails.enableSelector).each(function() {
2403        var element = $(this), method = element.is('button') ? 'html' : 'val';
2404        if (element.data('ujs:enable-with')) element[method](element.data('ujs:enable-with'));
2405        element.prop('disabled', false);
2406      });
2407    },
2408
2409   /* For 'data-confirm' attribute:
2410      - Fires `confirm` event
2411      - Shows the confirmation dialog
2412      - Fires the `confirm:complete` event
2413
2414      Returns `true` if no function stops the chain and user chose yes; `false` otherwise.
2415      Attaching a handler to the element's `confirm` event that returns a `falsy` value cancels the confirmation dialog.
2416      Attaching a handler to the element's `confirm:complete` event that returns a `falsy` value makes this function
2417      return false. The `confirm:complete` event is fired whether or not the user answered true or false to the dialog.
2418   */
2419    allowAction: function(element) {
2420      var message = element.data('confirm'),
2421          answer = false, callback;
2422      if (!message) { return true; }
2423
2424      if (rails.fire(element, 'confirm')) {
2425        answer = rails.confirm(message);
2426        callback = rails.fire(element, 'confirm:complete', [answer]);
2427      }
2428      return answer && callback;
2429    },
2430
2431    // Helper function which checks for blank inputs in a form that match the specified CSS selector
2432    blankInputs: function(form, specifiedSelector, nonBlank) {
2433      var inputs = $(), input,
2434        selector = specifiedSelector || 'input,textarea';
2435      form.find(selector).each(function() {
2436        input = $(this);
2437        // Collect non-blank inputs if nonBlank option is true, otherwise, collect blank inputs
2438        if (nonBlank ? input.val() : !input.val()) {
2439          inputs = inputs.add(input);
2440        }
2441      });
2442      return inputs.length ? inputs : false;
2443    },
2444
2445    // Helper function which checks for non-blank inputs in a form that match the specified CSS 
2445selector
2446    nonBlankInputs: function(form, specifiedSelector) {
2447      return rails.blankInputs(form, specifiedSelector, true); // true specifies nonBlank
2448    },
2449
2450    // Helper function, needed to provide consistent behavior in IE
2451    stopEverything: function(e) {
2452      $(e.target).trigger('ujs:everythingStopped');
2453      e.stopImmediatePropagation();
2454      return false;
2455    },
2456
2457    // find all the submit events directly bound to the form and
2458    // manually invoke them. If anyone returns false then stop the loop
2459    callFormSubmitBindings: function(form, event) {
2460      var events = form.data('events'), continuePropagation = true;
2461      if (events !== undefined && events['submit'] !== undefined) {
2462        $.each(events['submit'], function(i, obj){
2463          if (typeof obj.handler === 'function') return continuePropagation = obj.handler(event);
2464        });
2465      }
2466      return continuePropagation;
2467    },
2468
2469    //  replace element's html with the 'data-disable-with' after storing original html
2470    //  and prevent clicking on it
2471    disableElement: function(element) {
2472      element.data('ujs:enable-with', element.html()); // store enabled state
2473      element.html(element.data('disable-with')); // set to disabled state
2474      element.bind('click.railsDisable', function(e) { // prevent further clicking
2475        return rails.stopEverything(e)
2476      });
2477    },
2478
2479    // restore element to its original state which was disabled by 'disableElement' above
2480    enableElement: function(element) {
2481      if (element.data('ujs:enable-with') !== undefined) {
2482        element.html(element.data('ujs:enable-with')); // set to old enabled state
2483        // this should be element.removeData('ujs:enable-with')
2484        // but, there is currently a bug in jquery which makes hyphenated data attributes not get removed
2485        element.data('ujs:enable-with', false); // clean up cache
2486      }
2487      element.unbind('click.railsDisable'); // enable element
2488    }
2489
2490  };
2491
2492  $.ajaxPrefilter(function(options, originalOptions, xhr){ if ( !options.crossDomain ) { rails.CSRFProtection(xhr); }});
2493
2494  $(document).delegate(rails.linkDisableSelector, 'ajax:complete', function() {
2495      rails.enableElement($(this));
2496  });
2497
2498  $(document).delegate(rails.linkClickSelector, 'click.rails', function(e) {
2499    var link = $(this), method = link.data('method'), data = link.data('params');
2500    if (!rails.allowAction(link)) return rails.stopEverything(e);
2501
2502    if (link.is(rails.linkDisableSelector)) rails.disableElement(link);
2503
2504    if (link.data('remote') !== undefined) {
2505      if ( (e.metaKey || e.ctrlKey) && (!method || method === 'GET') && !data ) { return true; }
2506
2507      if (rails.handleRemote(link) === false) { rails.enableElement(link); }
2508      return false;
2509
2510    } else if (link.data('method')) {
2511      rails.handleMethod(link);
2512      return false;
2513    }
2514  });
2515
2516  $(document).delegate(rails.inputChangeSelector, 'change.rails', function(e) {
2517    var link = $(this);
2518    if (!rails.allowAction(link)) return rails.stopEverything(e);
2519
2520    rails.handleRemote(link);
2521    return false;
2522  });
2523
2524  $(document).delegate(rails.formSubmitSelector, 'submit.rails', function(e) {
2525    var form = $(this),
2526      remote = form.data('remote') !== undefined,
2527      blankRequiredInputs = rails.blankInputs(form, rails.requiredInputSelector),
2528      nonBlankFileInputs = rails.nonBlankInputs(form, rails.fileInputSelector);
2529
2530    if (!rails.allowAction(form)) return rails.stopEverything(e);
2531
2532    // skip other logic when required values are missing or file upload is present
2533    if (blankRequiredInputs && form.attr("novalidate") == undefined && rails.fire(form, 'ajax:aborted:required', [blankRequiredInputs])) {
2534      return rails.stopEverything(e);
2535    }
2536
2537    if (remote) {
2538      if (nonBlankFileInputs) {
2539        return rails.fire(form, 'ajax:aborted:file', [nonBlankFileInputs]);
2540      }
2541
2542      // If browser does not support submit bubbling, then this live-binding will be called before direct
2543      // bindings. Therefore, we should directly call any direct bindings before remotely submitting form.
2544      if (!$.support.submitBubbles && $().jquery < '1.7' && rails.callFormSubmitBindings(form, e) === false) return rails.stopEverything(e);
2545
2546      rails.handleRemote(form);
2547      return false;
2548
2549    } else {
2550      // slight timeout so that the submit button gets properly serialized
2551      setTimeout(function(){ rails.disableFormElements(form); }, 13);
2552    }
2553  });
2554
2555  $(document).delegate(rails.formInputClickSelector, 'click.rails', function(event) {
2556    var button = $(this);
2557
2558    if (!rails.allowAction(button)) return rails.stopEverything(event);
2559
2560    // register the pressed submit button
2561    var name = button.attr('name'),
2562      data = name ? {name:name, value:button.val()} : null;
2563
2564    button.closest('form').data('ujs:submit-button', data);
2565  });
2566
2567  $(document).delegate(rails.formSubmitSelector, 'ajax:beforeSend.rails', function(event) {
2568    if (this == event.target) rails.disableFormElements($(this));
2569  });
2570
2571  $(document).delegate(rails.formSubmitSelector, 'ajax:complete.rails', function(event) {
2572    if (this == event.target) rails.enableFormElements($(this));
2573  });
2574
2575})( jQuery );
2576$.QueryString = (function(a) {
2577  if (a == "") return {};
2578  var b = {};
2579  for (var i = 0; i < a.length; ++i)
2580  {
2581    var p=a[i].split('=');
2582    if (p.length != 2) continue;
2583    b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
2584  }
2585  return b;
2586})(window.location.search.substr(1).split('&'))
2587
2588$(document).ready(function(){
2589  var selector = "div.gal-item div.gal-inner-holder";
2590
2591  $(document)
2592    .on('mouseover', selector, function(e){
2593      $(this).addClass('hover');
2594    })
2595    .on('mouseout', selector, function(e){
2596      $(this).removeClass('hover');
2597    })
2598    .on('click', selector, function(e){
2599      var url = $(this).parents('div.gal-item').data('url');
2600      CKEDITOR.tools.callFunction(CKEditorFuncNum, url);
2601      window.close();
2602    });
2603
2604  $(document).on('ajax:complete', "div.gal-item a.gal-del", function(xhr, status){
2605    $(this).parents('div.gal-item').remove();
2606  });
2607
2608  var endlessScroll = $.endlessScroll({
2609    container: ".fileupload-list",
2610    entity: ".gal-item",
2611    scrollPadding: 100
2612  });
2613
2614  // Don't listen events first second
2615  endlessScroll.scrollModule.unbind();
2616  window.setTimeout(function() { endlessScroll.scrollModule.bind();}, 1000);
2617});
2618
2619// Collection of all instances on page
2620qq.FileUploader.instances = new Object();
2621
2622/**
2623 * Class that creates upload widget with drag-and-drop and file list
2624 * @inherits qq.FileUploaderBasic
2625 */
2626qq.FileUploaderInput = function(o){
2627    // call parent constructor
2628    qq.FileUploaderBasic.apply(this, arguments);
2629
2630    // additional options
2631    qq.extend(this._options, {
2632        element: null,
2633        // if set, will be used instead of qq-upload-list in template
2634        listElement: null,
2635
2636        template_id: '#fileupload_tmpl',
2637
2638        classes: {
2639            // used to get elements from templates
2640            button: 'fileupload-button',
2641            drop: 'fileupload-drop-area',
2642            dropActive: 'fileupload-drop-area-active',
2643            list: 'fileupload-list',
2644            preview: 'fileupload-preview',
2645
2646            file: 'fileupload-file',
2647            spinner: 'fileupload-spinner',
2648            size: 'fileupload-size',
2649            cancel: 'fileupload-cancel',
2650
2651            // added to list item when upload completes
2652            // used in css to hide progress spinner
2653            success: 'fileupload-success',
2654            fail: 'fileupload-fail'
2655        }
2656    });
2657    // overwrite options with user supplied
2658    qq.extend(this._options, o);
2659
2660    this._element = document.getElementById(this._options.element);
2661    this._listElement = this._options.listElement || this._find(this._element, 'list');
2662
2663    this._classes = this._options.classes;
2664
2665    this._button = this._createUploadButton(this._find(this._element, 'button'));
2666
2667    //this._setupDragDrop();
2668
2669    qq.FileUploader.instances[this._element.id] = this;
2670};
2671
2672// inherit from Basic Uploader
2673qq.extend(qq.FileUploaderInput.prototype, qq.FileUploaderBasic.prototype);
2674
2675qq.extend(qq.FileUploaderInput.prototype, {
2676    /**
2677     * Gets one of the elements listed in this._options.classes
2678     **/
2679    _find: function(parent, type){
2680        var element = qq.getByClass(parent, this._options.classes[type])[0];
2681        if (!element){
2682          alert(type);
2683            throw new Error('element not found ' + type);
2684        }
2685
2686        return element;
2687    },
2688    _setupDragDrop: function(){
2689        var self = this,
2690            dropArea = this._find(this._element, 'drop');
2691
2692        var dz = new qq.UploadDropZone({
2693            element: dropArea,
2694            onEnter: function(e){
2695                qq.addClass(dropArea, self._classes.dropActive);
2696                e.stopPropagation();
2697            },
2698            onLeave: function(e){
2699                e.stopPropagation();
2700            },
2701            onLeaveNotDescendants: function(e){
2702                qq.removeClass(dropArea, self._classes.dropActive);
2703            },
2704            onDrop: function(e){
2705                dropArea.style.display = 'none';
2706                qq.removeClass(dropArea, self._classes.dropActive);
2707                self._uploadFileList(e.dataTransfer.files);
2708            }
2709        });
2710
2711        dropArea.style.display = 'none';
2712
2713        qq.attach(document, 'dragenter', function(e){
2714            if (!dz._isValidFileDrag(e)) return;
2715
2716            dropArea.style.display = 'block';
2717        });
2718        qq.attach(document, 'dragleave', function(e){
2719            if (!dz._isValidFileDrag(e)) return;
2720
2721            var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);
2722            // only fire when leaving document out
2723            if ( ! relatedTarget || relatedTarget.nodeName == "HTML"){
2724                dropArea.style.display = 'none';
2725            }
2726        });
2727    },
2728    _onSubmit: function(id, fileName){
2729        qq.FileUploaderBasic.prototype._onSubmit.apply(this, arguments);
2730        this._addToList(id, fileName);
2731    },
2732    _onProgress: function(id, fileName, loaded, total){
2733        qq.FileUploaderBasic.prototype._onProgress.apply(this, arguments);
2734
2735        var item = this._getItemByFileId(id);
2736        var size = this._find(item, 'size');
2737
2738        var text;
2739        if (loaded != total){
2740            text = Math.round(loaded / total * 100) + '% from ' + this._formatSize(total);
2741        } else {
2742            text = this._formatSize(total);
2743        }
2744
2745        qq.setText(size, text);
2746    },
2747    _onComplete: function(id, fileName, result){
2748        qq.FileUploaderBasic.prototype._onComplete.apply(this, arguments);
2749
2750        var item = this._getItemByFileId(id);
2751        var asset = result.asset ? result.asset : result;
2752
2753        if (asset && asset.id){
2754            qq.addClass(item, this._classes.success);
2755
2756            asset.size = this._formatSize(asset.size);
2757            asset.controller = (asset.type !== undefined && asset.type.toLowerCase() == "ckeditor::picture" ? "pictures" : "attachment_files");
2758
2759            $(item).replaceWith($(this._options.template_id).tmpl(asset));
2760        } else {
2761            qq.addClass(item, this._classes.fail);
2762        }
2763    },
2764    _addToList: function(id, fileName){
2765        if (this._listElement) {
2766          if (this._options.multiple === false) {
2767            $(this._listElement).empty();
2768          }
2769
2770          var asset = {
2771            id: 0,
2772            filename: this._formatFileName(fileName),
2773            size: 0,
2774            format_created_at: '',
2775            url_content: "#",
2776            controller: "assets",
2777            url_thumb: ""
2778          };
2779
2780          var item = $(this._options.template_id).tmpl(asset).attr('qqfileid', id)
2781
2782          item.find('div.img').html('').addClass('preloader');
2783          item.prependTo( this._listElement );
2784
2785          this._bindCancelEvent(item);
2786        }
2787    },
2788    _getItemByFileId: function(id){
2789        return $(this._listElement).find('div[qqfileid=' + id  +']').get(0);
2790    },
2791    /**
2792     * delegate click event for cancel link
2793     **/
2794    _bindCancelEvent: function(element){
2795        var self = this,
2796            item = $(element);
2797
2798        item.find('a.' + this._classes.cancel).bind('click', function(e){
2799          self._handler.cancel( item.attr('qqfileid') );
2800          item.remove();
2801          qq.preventDefault(e);
2802          return false;
2803        });
2804    }
2805});
2806
2807
2808
2809
2810
2811// COPY FROM https://cdnjs.cloudflare.com/ajax/libs/ace/1.3.3/ace.js
2812// フロントエンドにもaceを使っていますので、window.aceをwindow.ace_railsに変える
2813
2814;(function() {
2815  function o(n) {
2816    var i = e
2817    n && (e[n] || (e[n] = {}), (i = e[n]))
2818    if (!i.define || !i.define.packaged) (t.original = i.define), (i.define = t), (i.define.packaged = !0)
2819    if (!i.require || !i.require.packaged) (r.original = i.require), (i.require = r), (i.require.packaged = !0)
2820  }
2821  var ACE_NAMESPACE = '',
2822    e = (function() {
2823      return this
2824    })()
2825  !e && typeof window != 'undefined' && (e = window)
2826  if (!ACE_NAMESPACE && typeof requirejs != 'undefined') return
2827  var t = function(e, n, r) {
2828    if (typeof e != 'string') {
2829      t.original
2830        ? t.original.apply(this, arguments)
2831        : (console.error("dropping module because define wasn't a string."), console.trace())
2832      return
2833    }
2834    arguments.length == 2 && (r = n), t.modules[e] || ((t.payloads[e] = r), (t.modules[e] = null))
2835  }
2836  ;(t.modules = {}), (t.payloads = {})
2837  var n = function(e, t, n) {
2838      if (typeof t == 'string') {
2839        var i = s(e, t)
2840        if (i != undefined) return n && n(), i
2841      } else if (Object.prototype.toString.call(t) === '[object Array]') {
2842        var o = []
2843        for (var u = 0, a = t.length; u < a; ++u) {
2844          var f = s(e, t[u])
2845          if (f == undefined && r.original) return
2846          o.push(f)
2847        }
2848        return (n && n.apply(null, o)) || !0
2849      }
2850    },
2851    r = function(e, t) {
2852      var i = n('', e, t)
2853      return i == undefined && r.original ? r.original.apply(this, arguments) : i
2854    },
2855    i = function(e, t) {
2856      if (t.indexOf('!') !== -1) {
2857        var n = t.split('!')
2858        return i(e, n[0]) + '!' + i(e, n[1])
2859      }
2860      if (t.charAt(0) == '.') {
2861        var r = e
2862          .split('/')
2863          .slice(0, -1)
2864          .join('/')
2865        t = r + '/' + t
2866        while (t.indexOf('.') !== -1 && s != t) {
2867          var s = t
2868          t = t.replace(/\/\.\//, '/').replace(/[^\/]+\/\.\.\//, '')
2869        }
2870      }
2871      return t
2872    },
2873    s = function(e, r) {
2874      r = i(e, r)
2875      var s = t.modules[r]
2876      if (!s) {
2877        s = t.payloads[r]
2878        if (typeof s == 'function') {
2879          var o = {},
2880            u = { id: r, uri: '', exports: o, packaged: !0 },
2881            a = function(e, t) {
2882              return n(r, e, t)
2883            },
2884            f = s(a, o, u)
2885          ;(o = f || u.exports), (t.modules[r] = o), delete t.payloads[r]
2886        }
2887        s = t.modules[r] = o || s
2888      }
2889      return s
2890    }
2891  o(ACE_NAMESPACE)
2892})(),
2893  define('ace/lib/regexp', ['require', 'exports', 'module'], function(e, t, n) {
2894    'use strict'
2895    function o(e) {
2896      return (
2897        (e.global ? 'g' : '') +
2898        (e.ignoreCase ? 'i' : '') +
2899        (e.multiline ? 'm' : '') +
2900        (e.extended ? 'x' : '') +
2901        (e.sticky ? 'y' : '')
2902      )
2903    }
2904    function u(e, t, n) {
2905      if (Array.prototype.indexOf) return e.indexOf(t, n)
2906      for (var r = n || 0; r < e.length; r++) if (e[r] === t) return r
2907      return -1
2908    }
2909    var r = {
2910        exec: RegExp.prototype.exec,
2911        test: RegExp.prototype.test,
2912        match: String.prototype.match,
2913        replace: String.prototype.replace,
2914        split: String.prototype.split
2915      },
2916      i = r.exec.call(/()??/, '')[1] === undefined,
2917      s = (function() {
2918        var e = /^/g
2919        return r.test.call(e, ''), !e.lastIndex
2920      })()
2921    if (s && i) return
2922    ;(RegExp.prototype.exec = function(e) {
2923      var t = r.exec.apply(this, arguments),
2924        n,
2925        a
2926      if (typeof e == 'string' && t) {
2927        !i &&
2928          t.length > 1 &&
2929          u(t, '') > -1 &&
2930          ((a = RegExp(this.source, r.replace.call(o(this), 'g', ''))),
2931          r.replace.call(e.slice(t.index), a, function() {
2932            for (var e = 1; e < arguments.length - 2; e++) arguments[e] === undefined && (t[e] = undefined)
2933          }))
2934        if (this._xregexp && this._xregexp.captureNames)
2935          for (var f = 1; f < t.length; f++) (n = this._xregexp.captureNames[f - 1]), n && (t[n] = t[f])
2936        !s && this.global && !t[0].length && this.lastIndex > t.index && this.lastIndex--
2937      }
2938      return t
2939    }),
2940      s ||
2941        (RegExp.prototype.test = function(e) {
2942          var t = r.exec.call(this, e)
2943          return t && this.global && !t[0].length && this.lastIndex > t.index && this.lastIndex--, !!t
2944        })
2945  }),
2946  define('ace/lib/es5-shim', ['require', 'exports', 'module'], function(e, t, n) {
2947    function r() {}
2948    function w(e) {
2949      try {
2950        return Object.defineProperty(e, 'sentinel', {}), 'sentinel' in e
2951      } catch (t) {}
2952    }
2953    function H(e) {
2954      return (
2955        (e = +e),
2956        e !== e ? (e = 0) : e !== 0 && e !== 1 / 0 && e !== -1 / 0 && (e = (e > 0 || -1) * Math.floor(Math.abs(e))),
2957        e
2958      )
2959    }
2960    function B(e) {
2961      var t = typeof e
2962      return e === null || t === 'undefined' || t === 'boolean' || t === 'number' || t === 'string'
2963    }
2964    function j(e) {
2965      var t, n, r
2966      if (B(e)) return e
2967      n = e.valueOf
2968      if (typeof n == 'function') {
2969        t = n.call(e)
2970        if (B(t)) return t
2971      }
2972      r = e.toString
2973      if (typeof r == 'function') {
2974        t = r.call(e)
2975        if (B(t)) return t
2976      }
2977      throw new TypeError()
2978    }
2979    Function.prototype.bind ||
2980      (Function.prototype.bind = function(t) {
2981        var n = this
2982        if (typeof n != 'function') throw new TypeError('Function.prototype.bind called on incompatible ' + n)
2983        var i = u.call(arguments, 1),
2984          s = function() {
2985            if (this instanceof s) {
2986              var e = n.apply(this, i.concat(u.call(arguments)))
2987              return Object(e) === e ? e : this
2988            }
2989            return n.apply(t, i.concat(u.call(arguments)))
2990          }
2991        return n.prototype && ((r.prototype = n.prototype), (s.prototype = new r()), (r.prototype = null)), s
2992      })
2993    var i = Function.prototype.call,
2994      s = Array.prototype,
2995      o = Object.prototype,
2996      u = s.slice,
2997      a = i.bind(o.toString),
2998      f = i.bind(o.hasOwnProperty),
2999      l,
3000      c,
3001      h,
3002      p,
3003      d
3004    if ((d = f(o, '__defineGetter__')))
3005      (l = i.bind(o.__defineGetter__)),
3006        (c = i.bind(o.__defineSetter__)),
3007        (h = i.bind(o.__lookupGetter__)),
3008        (p = i.bind(o.__lookupSetter__))
3009    if ([1, 2].splice(0).length != 2)
3010      if (
3011        !(function() {
3012          function e(e) {
3013            var t = new Array(e + 2)
3014            return (t[0] = t[1] = 0), t
3015          }
3016          var t = [],
3017            n
3018          t.splice.apply(t, e(20)), t.splice.apply(t, e(26)), (n = t.length), t.splice(5, 0, 'XXX'), n + 1 == t.length
3019          if (n + 1 == t.length) return !0
3020        })()
3021      )
3022        Array.prototype.splice = function(e, t) {
3023          var n = this.length
3024          e > 0 ? e > n && (e = n) : e == void 0 ? (e = 0) : e < 0 && (e = Math.max(n + e, 0)), e + t < n || (t = n - e)
3025          var r = this.slice(e, e + t),
3026            i = u.call(arguments, 2),
3027            s = i.length
3028          if (e === n) s && this.push.apply(this, i)
3029          else {
3030            var o = Math.min(t, n - e),
3031              a = e + o,
3032              f = a + s - o,
3033              l = n - a,
3034              c = n - o
3035            if (f < a) for (var h = 0; h < l; ++h) this[f + h] = this[a + h]
3036            else if (f > a) for (h = l; h--; ) this[f + h] = this[a + h]
3037            if (s && e === c) (this.length = c), this.push.apply(this, i)
3038            else {
3039              this.length = c + s
3040              for (h = 0; h < s; ++h) this[e + h] = i[h]
3041            }
3042          }
3043          return r
3044        }
3045      else {
3046        var v = Array.prototype.splice
3047        Array.prototype.splice = function(e, t) {
3048          return arguments.length
3049            ? v.apply(this, [e === void 0 ? 0 : e, t === void 0 ? this.length - e : t].concat(u.call(arguments, 2)))
3050            : []
3051        }
3052      }
3053    Array.isArray ||
3054      (Array.isArray = function(t) {
3055        return a(t) == '[object Array]'
3056      })
3057    var m = Object('a'),
3058      g = m[0] != 'a' || !(0 in m)
3059    Array.prototype.forEach ||
3060      (Array.prototype.forEach = function(t) {
3061        var n = F(this),
3062          r = g && a(this) == '[object String]' ? this.split('') : n,
3063          i = arguments[1],
3064          s = -1,
3065          o = r.length >>> 0
3066        if (a(t) != '[object Function]') throw new TypeError()
3067        while (++s < o) s in r && t.call(i, r[s], s, n)
3068      }),
3069      Array.prototype.map ||
3070        (Array.prototype.map = function(t) {
3071          var n = F(this),
3072            r = g && a(this) == '[object String]' ? this.split('') : n,
3073            i = r.length >>> 0,
3074            s = Array(i),
3075            o = arguments[1]
3076          if (a(t) != '[object Function]') throw new TypeError(t + ' is not a function')
3077          for (var u = 0; u < i; u++) u in r && (s[u] = t.call(o, r[u], u, n))
3078          return s
3079        }),
3080      Array.prototype.filter ||
3081        (Array.prototype.filter = function(t) {
3082          var n = F(this),
3083            r = g && a(this) == '[object String]' ? this.split('') : n,
3084            i = r.length >>> 0,
3085            s = [],
3086            o,
3087            u = arguments[1]
3088          if (a(t) != '[object Function]') throw new TypeError(t + ' is not a function')
3089          for (var f = 0; f < i; f++) f in r && ((o = r[f]), t.call(u, o, f, n) && s.push(o))
3090          return s
3091        }),
3092      Array.prototype.every ||
3093        (Array.prototype.every = function(t) {
3094          var n = F(this),
3095            r = g && a(this) == '[object String]' ? this.split('') : n,
3096            i = r.length >>> 0,
3097            s = arguments[1]
3098          if (a(t) != '[object Function]') throw new TypeError(t + ' is not a function')
3099          for (var o = 0; o < i; o++) if (o in r && !t.call(s, r[o], o, n)) return !1
3100          return !0
3101        }),
3102      Array.prototype.some ||
3103        (Array.prototype.some = function(t) {
3104          var n = F(this),
3105            r = g && a(this) == '[object String]' ? this.split('') : n,
3106            i = r.length >>> 0,
3107            s = arguments[1]
3108          if (a(t) != '[object Function]') throw new TypeError(t + ' is not a function')
3109          for (var o = 0; o < i; o++) if (o in r && t.call(s, r[o], o, n)) return !0
3110          return !1
3111        }),
3112      Array.prototype.reduce ||
3113        (Array.prototype.reduce = function(t) {
3114          var n = F(this),
3115            r = g && a(this) == '[object String]' ? this.split('') : n,
3116            i = r.length >>> 0
3117          if (a(t) != '[object Function]') throw new TypeError(t + ' is not a function')
3118          if (!i && arguments.length == 1) throw new TypeError('reduce of empty array with 
3118no initial value')
3119          var s = 0,
3120            o
3121          if (arguments.length >= 2) o = arguments[1]
3122          else
3123            do {
3124              if (s in r) {
3125                o = r[s++]
3126                break
3127              }
3128              if (++s >= i) throw new TypeError('reduce of empty array with no initial value')
3129            } while (!0)
3130          for (; s < i; s++) s in r && (o = t.call(void 0, o, r[s], s, n))
3131          return o
3132        }),
3133      Array.prototype.reduceRight ||
3134        (Array.prototype.reduceRight = function(t) {
3135          var n = F(this),
3136            r = g && a(this) == '[object String]' ? this.split('') : n,
3137            i = r.length >>> 0
3138          if (a(t) != '[object Function]') throw new TypeError(t + ' is not a function')
3139          if (!i && arguments.length == 1) throw new TypeError('reduceRight of empty array with no initial value')
3140          var s,
3141            o = i - 1
3142          if (arguments.length >= 2) s = arguments[1]
3143          else
3144            do {
3145              if (o in r) {
3146                s = r[o--]
3147                break
3148              }
3149              if (--o < 0) throw new TypeError('reduceRight of empty array with no initial value')
3150            } while (!0)
3151          do o in this && (s = t.call(void 0, s, r[o], o, n))
3152          while (o--)
3153          return s
3154        })
3155    if (!Array.prototype.indexOf || [0, 1].indexOf(1, 2) != -1)
3156      Array.prototype.indexOf = function(t) {
3157        var n = g && a(this) == '[object String]' ? this.split('') : F(this),
3158          r = n.length >>> 0
3159        if (!r) return -1
3160        var i = 0
3161        arguments.length > 1 && (i = H(arguments[1])), (i = i >= 0 ? i : Math.max(0, r + i))
3162        for (; i < r; i++) if (i in n && n[i] === t) return i
3163        return -1
3164      }
3165    if (!Array.prototype.lastIndexOf || [0, 1].lastIndexOf(0, -3) != -1)
3166      Array.prototype.lastIndexOf = function(t) {
3167        var n = g && a(this) == '[object String]' ? this.split('') : F(this),
3168          r = n.length >>> 0
3169        if (!r) return -1
3170        var i = r - 1
3171        arguments.length > 1 && (i = Math.min(i, H(arguments[1]))), (i = i >= 0 ? i : r - Math.abs(i))
3172        for (; i >= 0; i--) if (i in n && t === n[i]) return i
3173        return -1
3174      }
3175    Object.getPrototypeOf ||
3176      (Object.getPrototypeOf = function(t) {
3177        return t.__proto__ || (t.constructor ? t.constructor.prototype : o)
3178      })
3179    if (!Object.getOwnPropertyDescriptor) {
3180      var y = 'Object.getOwnPropertyDescriptor called on a non-object: '
3181      Object.getOwnPropertyDescriptor = function(t, n) {
3182        if ((typeof t != 'object' && typeof t != 'function') || t === null) throw new TypeError(y + t)
3183        if (!f(t, n)) return
3184        var r, i, s
3185        r = { enumerable: !0, configurable: !0 }
3186        if (d) {
3187          var u = t.__proto__
3188          t.__proto__ = o
3189          var i = h(t, n),
3190            s = p(t, n)
3191          t.__proto__ = u
3192          if (i || s) return i && (r.get = i), s && (r.set = s), r
3193        }
3194        return (r.value = t[n]), r
3195      }
3196    }
3197    Object.getOwnPropertyNames ||
3198      (Object.getOwnPropertyNames = function(t) {
3199        return Object.keys(t)
3200      })
3201    if (!Object.create) {
3202      var b
3203      Object.prototype.__proto__ === null
3204        ? (b = function() {
3205            return { __proto__: null }
3206          })
3207        : (b = function() {
3208            var e = {}
3209            for (var t in e) e[t] = null
3210            return (
3211              (e.constructor = e.hasOwnProperty = e.propertyIsEnumerable = e.isPrototypeOf = e.toLocaleString = e.toString = e.valueOf = e.__proto__ = null),
3212              e
3213            )
3214          }),
3215        (Object.create = function(t, n) {
3216          var r
3217          if (t === null) r = b()
3218          else {
3219            if (typeof t != 'object') throw new TypeError('typeof prototype[' + typeof t + "] != 'object'")
3220            var i = function() {}
3221            ;(i.prototype = t), (r = new i()), (r.__proto__ = t)
3222          }
3223          return n !== void 0 && Object.defineProperties(r, n), r
3224        })
3225    }
3226    if (Object.defineProperty) {
3227      var E = w({}),
3228        S = typeof document == 'undefined' || w(document.createElement('div'))
3229      if (!E || !S) var x = Object.defineProperty
3230    }
3231    if (!Object.defineProperty || x) {
3232      var T = 'Property description must be an object: ',
3233        N = 'Object.defineProperty called on non-object: ',
3234        C = 'getters & setters can not be defined on this javascript engine'
3235      Object.defineProperty = function(t, n, r) {
3236        if ((typeof t != 'object' && typeof t != 'function') || t === null) throw new TypeError(N + t)
3237        if ((typeof r != 'object' && typeof r != 'function') || r === null) throw new TypeError(T + r)
3238        if (x)
3239          try {
3240            return x.call(Object, t, n, r)
3241          } catch (i) {}
3242        if (f(r, 'value'))
3243          if (d && (h(t, n) || p(t, n))) {
3244            var s = t.__proto__
3245            ;(t.__proto__ = o), delete t[n], (t[n] = r.value), (t.__proto__ = s)
3246          } else t[n] = r.value
3247        else {
3248          if (!d) throw new TypeError(C)
3249          f(r, 'get') && l(t, n, r.get), f(r, 'set') && c(t, n, r.set)
3250        }
3251        return t
3252      }
3253    }
3254    Object.defineProperties ||
3255      (Object.defineProperties = function(t, n) {
3256        for (var r in n) f(n, r) && Object.defineProperty(t, r, n[r])
3257        return t
3258      }),
3259      Object.seal ||
3260        (Object.seal = function(t) {
3261          return t
3262        }),
3263      Object.freeze ||
3264        (Object.freeze = function(t) {
3265          return t
3266        })
3267    try {
3268      Object.freeze(function() {})
3269    } catch (k) {
3270      Object.freeze = (function(t) {
3271        return function(n) {
3272          return typeof n == 'function' ? n : t(n)
3273        }
3274      })(Object.freeze)
3275    }
3276    Object.preventExtensions ||
3277      (Object.preventExtensions = function(t) {
3278        return t
3279      }),
3280      Object.isSealed ||
3281        (Object.isSealed = function(t) {
3282          return !1
3283        }),
3284      Object.isFrozen ||
3285        (Object.isFrozen = function(t) {
3286          return !1
3287        }),
3288      Object.isExtensible ||
3289        (Object.isExtensible = function(t) {
3290          if (Object(t) === t) throw new TypeError()
3291          var n = ''
3292          while (f(t, n)) n += '?'
3293          t[n] = !0
3294          var r = f(t, n)
3295          return delete t[n], r
3296        })
3297    if (!Object.keys) {
3298      var L = !0,
3299        A = [
3300          'toString',
3301          'toLocaleString',
3302          'valueOf',
3303          'hasOwnProperty',
3304          'isPrototypeOf',
3305          'propertyIsEnumerable',
3306          'constructor'
3307        ],
3308        O = A.length
3309      for (var M in { toString: null }) L = !1
3310      Object.keys = function I(e) {
3311        if ((typeof e != 'object' && typeof e != 'function') || e === null)
3312          throw new TypeError('Object.keys called on a non-object')
3313        var I = []
3314        for (var t in e) f(e, t) && I.push(t)
3315        if (L)
3316          for (var n = 0, r = O; n < r; n++) {
3317            var i = A[n]
3318            f(e, i) && I.push(i)
3319          }
3320        return I
3321      }
3322    }
3323    Date.now ||
3324      (Date.now = function() {
3325        return new Date().getTime()
3326      })
3327    var _ =
3328      '	\n\x0b\f\r \u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\ufeff'
3329    if (!String.prototype.trim || _.trim()) {
3330      _ = '[' + _ + ']'
3331      var D = new RegExp('^' + _ + _ + '*'),
3332        P = new RegExp(_ + _ + '*$')
3333      String.prototype.trim = function() {
3334        return String(this)
3335          .replace(D, '')
3336          .replace(P, '')
3337      }
3338    }
3339    var F = function(e) {
3340      if (e == null) throw new TypeError("can't convert " + e + ' to object')
3341      return Object(e)
3342    }
3343  }),
3344  define('ace/lib/fixoldbrowsers', ['require', 'exports', 'module', 'ace/lib/regexp', 'ace/lib/es5-shim'], function(
3345    e,
3346    t,
3347    n
3348  ) {
3349    'use strict'
3350    e('./regexp'), e('./es5-shim')
3351  }),
3352  define('ace/lib/dom', ['require', 'exports', 'module'], function(e, t, n) {
3353    'use strict'
3354    var r = 'http://www.w3.org/1999/xhtml'
3355    ;(t.buildDom = function s(e, t, n) {
3356      if (typeof e == 'string' && e) {
3357        var r = document.createTextNode(e)
3358        return t && t.appendChild(r), r
3359      }
3360      if (!Array.isArray(e)) return e
3361      if (typeof e[0] != 'string' || !e[0]) {
3362        var i = []
3363        for (var o = 0; o < e.length; o++) {
3364          var u = s(e[o], t, n)
3365          u && i.push(u)
3366        }
3367        return i
3368      }
3369      var a = document.createElement(e[0]),
3370        f = e[1],
3371        l = 1
3372      f && typeof f == 'object' && !Array.isArray(f) && (l = 2)
3373      for (var o = l; o < e.length; o++) s(e[o], a, n)
3374      return (
3375        l == 2 &&
3376          Object.keys(f).forEach(function(e) {
3377            var t = f[e]
3378            e === 'class'
3379              ? (a.className = Array.isArray(t) ? t.join(' ') : t)
3380              : typeof t == 'function' || e == 'value'
3381              ? (a[e] = t)
3382              : e === 'ref'
3383              ? n && (n[t] = a)
3384              : t != null && a.setAttribute(e, t)
3385          }),
3386        t && t.appendChild(a),
3387        a
3388      )
3389    }),
3390      (t.getDocumentHead = function(e) {
3391        return e || (e = document), e.head || e.getElementsByTagName('head')[0] || e.documentElement
3392      }),
3393      (t.createElement = function(e, t) {
3394        return document.createElementNS ? document.createElementNS(t || r, e) : document.createElement(e)
3395      }),
3396      (t.hasCssClass = function(e, t) {
3397        var n = (e.className + '').split(/\s+/g)
3398        return n.indexOf(t) !== -1
3399      }),
3400      (t.addCssClass = function(e, n) {
3401        t.hasCssClass(e, n) || (e.className += ' ' + n)
3402      }),
3403      (t.removeCssClass = function(e, t) {
3404        var n = e.className.split(/\s+/g)
3405        for (;;) {
3406          var r = n.indexOf(t)
3407          if (r == -1) break
3408          n.splice(r, 1)
3409        }
3410        e.className = n.join(' ')
3411      }),
3412      (t.toggleCssClass = function(e, t) {
3413        var n = e.className.split(/\s+/g),
3414          r = !0
3415        for (;;) {
3416          var i = n.indexOf(t)
3417          if (i == -1) break
3418          ;(r = !1), n.splice(i, 1)
3419        }
3420        return r && n.push(t), (e.className = n.join(' ')), r
3421      }),
3422      (t.setCssClass = function(e, n, r) {
3423        r ? t.addCssClass(e, n) : t.removeCssClass(e, n)
3424      }),
3425      (t.hasCssString = function(e, t) {
3426        var n = 0,
3427          r
3428        t = t || document
3429        if ((r = t.querySelectorAll('style'))) while (n < r.length) if (r[n++].id === e) return !0
3430      }),
3431      (t.importCssString = function(n, r, i) {
3432        var s = i && i.getRootNode ? i.getRootNode() : i || document,
3433          o = s.ownerDocument || s
3434        if (r && t.hasCssString(r, s)) return null
3435        r && (n += '\n/*# sourceURL=ace/css/' + r + ' */')
3436        var u = t.createElement('style')
3437        u.appendChild(o.createTextNode(n)), r && (u.id = r), s == o && (s = t.getDocumentHead(o)), s.appendChild(u)
3438      }),
3439      (t.importCssStylsheet = function(e, n) {
3440        t.buildDom('link', { rel: 'stylesheet', href: e }, t.getDocumentHead(n))
3441      }),
3442      (t.scrollbarWidth = function(e) {
3443        var n = t.createElement('ace_inner')
3444        ;(n.style.width = '100%'), (n.style.minWidth = '0px'), (n.style.height = '200px'), (n.style.display = 'block')
3445        var r = t.createElement('ace_outer'),
3446          i = r.style
3447        ;(i.position = 'absolute'),
3448          (i.left = '-10000px'),
3449          (i.overflow = 'hidden'),
3450          (i.width = '200px'),
3451          (i.minWidth = '0px'),
3452          (i.height = '150px'),
3453          (i.display = 'block'),
3454          r.appendChild(n)
3455        var s = e.documentElement
3456        s.appendChild(r)
3457        var o = n.offsetWidth
3458        i.overflow = 'scroll'
3459        var u = n.offsetWidth
3460        return o == u && (u = r.clientWidth), s.removeChild(r), o - u
3461      }),
3462      typeof document == 'undefined' && (t.importCssString = function() {}),
3463      (t.computedStyle = function(e, t) {
3464        return window.getComputedStyle(e, '') || {}
3465      }),
3466      (t.HAS_CSS_ANIMATION = !1)
3467    if (typeof document != 'undefined') {
3468      var i = document.createElement('div')
3469      typeof i.style.animationName != 'undefined' && (t.HAS_CSS_ANIMATION = !0)
3470    }
3471  }),
3472  define('ace/lib/oop', ['require', 'exports', 'module'], function(e, t, n) {
3473    'use strict'
3474    ;(t.inherits = function(e, t) {
3475      ;(e.super_ = t),
3476        (e.prototype = Object.create(t.prototype, {
3477          constructor: { value: e, enumerable: !1, writable: !0, configurable: !0 }
3478        }))
3479    }),
3480      (t.mixin = function(e, t) {
3481        for (var n in t) e[n] = t[n]
3482        return e
3483      }),
3484      (t.implement = function(e, n) {
3485        t.mixin(e, n)
3486      })
3487  }),
3488  define('ace/lib/keys', ['require', 'exports', 'module', 'ace/lib/fixoldbrowsers', 'ace/lib/oop'], function(e, t, n) {
3489    'use strict'
3490    e('./fixoldbrowsers')
3491    var r = e('./oop'),
3492      i = (function() {
3493        var e = {
3494            MODIFIER_KEYS: { 16: 'Shift', 17: 'Ctrl', 18: 'Alt', 224: 'Meta' },
3495            KEY_MODS: { ctrl: 1, alt: 2, option: 2, shift: 4, super: 8, meta: 8, command: 8, cmd: 8 },
3496            FUNCTION_KEYS: {
3497              8: 'Backspace',
3498              9: 'Tab',
3499              13: 'Return',
3500              19: 'Pause',
3501              27: 'Esc',
3502              32: 'Space',
3503              33: 'PageUp',
3504              34: 'PageDown',
3505              35: 'End',
3506              36: 'Home',
3507              37: 'Left',
3508              38: 'Up',
3509              39: 'Right',
3510              40: 'Down',
3511              44: 'Print',
3512              45: 'Insert',
3513              46: 'Delete',
3514              96: 'Numpad0',
3515              97: 'Numpad1',
3516              98: 'Numpad2',
3517              99: 'Numpad3',
3518              100: 'Numpad4',
3519              101: 'Numpad5',
3520              102: 'Numpad6',
3521              103: 'Numpad7',
3522              104: 'Numpad8',
3523              105: 'Numpad9',
3524              '-13': 'NumpadEnter',
3525              112: 'F1',
3526              113: 'F2',
3527              114: 'F3',
3528              115: 'F4',
3529              116: 'F5',
3530              117: 'F6',
3531              118: 'F7',
3532              119: 'F8',
3533              120: 'F9',
3534              121: 'F10',
3535              122: 'F11',
3536              123: 'F12',
3537              144: 'Numlock',
3538              145: 'Scrolllock'
3539            },
3540            PRINTABLE_KEYS: {
3541              32: ' ',
3542              48: '0',
3543              49: '1',
3544              50: '2',
3545              51: '3',
3546              52: '4',
3547              53: '5',
3548              54: '6',
3549              55: '7',
3550              56: '8',
3551              57: '9',
3552              59: ';',
3553              61: '=',
3554              65: 'a',
3555              66: 'b',
3556              67: 'c',
3557              68: 'd',
3558              69: 'e',
3559              70: 'f',
3560              71: 'g',
3561              72: 'h',
3562              73: 'i',
3563              74: 'j',
3564              75: 'k',
3565              76: 'l',
3566              77: 'm',
3567              78: 'n',
3568              79: 'o',
3569              80: 'p',
3570              81: 'q',
3571              82: 'r',
3572              83: 's',
3573              84: 't',
3574              85: 'u',
3575              86: 'v',
3576              87: 'w',
3577              88: 'x',
3578              89: 'y',
3579              90: 'z',
3580              107: '+',
3581              109: '-',
3582              110: '.',
3583              186: ';',
3584              187: '=',
3585              188: ',',
3586              189: '-',
3587              190: '.',
3588              191: '/',
3589              192: '`',
3590              219: '[',
3591              220: '\\',
3592              221: ']',
3593              222: "'",
3594              111: '/',
3595              106: '*'
3596            }
3597          },
3598          t,
3599          n
3600        for (n in e.FUNCTION_KEYS) (t = e.FUNCTION_KEYS[n].toLowerCase()), (e[t] = parseInt(n, 10))
3601        for (n in e.PRINTABLE_KEYS) (t = e.PRINTABLE_KEYS[n].toLowerCase()), (e[t] = parseInt(n, 10))
3602        return (
3603          r.mixin(e, e.MODIFIER_KEYS),
3604          r.mixin(e, e.PRINTABLE_KEYS),
3605          r.mixin(e, e.FUNCTION_KEYS),
3606          (e.enter = e['return']),
3607          (e.escape = e.esc),
3608          (e.del = e['delete']),
3609          (e[173] = '-'),
3610          (function() {
3611            var t = ['cmd', 'ctrl', 'alt', 'shift']
3612            for (var n = Math.pow(2, t.length); n--; )
3613              e.KEY_MODS[n] =
3614                t
3615                  .filter(function(t) {
3616                    return n & e.KEY_MODS[t]
3617                  })
3618                  .join('-') + '-'
3619          })(),
3620          (e.KEY_MODS[0] = ''),
3621          (e.KEY_MODS[-1] = 'input-'),
3622          e
3623        )
3624      })()
3625    r.mixin(t, i),
3626      (t.keyCodeToString = function(e) {
3627        var t = i[e]
3628        return typeof t != 'string' && (t = String.fromCharCode(e)), t.toLowerCase()
3629      })
3630  }),
3631  define('ace/lib/useragent', ['require', 'exports', 'module'], function(e, t, n) {
3632    'use strict'
3633    ;(t.OS = { LINUX: 'LINUX', MAC: 'MAC', WINDOWS: 'WINDOWS' }),
3634      (t.getOS = function() {
3635        return t.isMac ? t.OS.MAC : t.isLinux ? t.OS.LINUX : t.OS.WINDOWS
3636      })
3637    if (typeof navigator != 'object') return
3638    var r = (navigator.platform.match(/mac|win|linux/i) || ['other'])[0].toLowerCase(),
3639      i = navigator.userAgent
3640    ;(t.isWin = r == 'win'),
3641      (t.isMac = r == 'mac'),
3642      (t.isLinux = r == 'linux'),
3643      (t.isIE =
3644        navigator.appName == 'Microsoft Internet Explorer' || navigator.appName.indexOf('MSAppHost') >= 0
3645          ? parseFloat((i.match(/(?:MSIE |Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/) || [])[1])
3646          : parseFloat((i.match(/(?:Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/) || [])[1])),
3647      (t.isOldIE = t.isIE && t.isIE < 9),
3648      (t.isGecko = t.isMozilla = i.match(/ Gecko\/\d+/)),
3649      (t.isOpera = window.opera && Object.prototype.toString.call(window.opera) == '[object Opera]'),
3650      (t.isWebKit = parseFloat(i.split('WebKit/')[1]) || undefined),
3651      (t.isChrome = parseFloat(i.split(' Chrome/')[1]) || undefined),
3652      (t.isAIR = i.indexOf('AdobeAIR') >= 0),
3653      (t.isIPad = i.indexOf('iPad') >= 0),
3654      (t.isChromeOS = i.indexOf(' CrOS ') >= 0),
3655      (t.isIOS = /iPad|iPhone|iPod/.test(i) && !window.MSStream),
3656      t.isIOS && (t.isMac = !0)
3657  }),
3658  define('ace/lib/event', ['require', 'exports', 'module', 'ace/lib/keys', 'ace/lib/useragent'], function(e, t, n) {
3659    'use strict'
3660    function a(e, t, n) {
3661      var a = u(t)
3662      if (!i.isMac && s) {
3663        t.getModifierState && (t.getModifierState('OS') || t.getModifierState('Win')) && (a |= 8)
3664        if (s.altGr) {
3665          if ((3 & a) == 3) return
3666          s.altGr = 0
3667        }
3668        if (n === 18 || n === 17) {
3669          var f = 'location' in t ? t.location : t.keyLocation
3670          if (n === 17 && f === 1) s[n] == 1 && (o = t.timeStamp)
3671          else if (n === 18 && a === 3 && f === 2) {
3672            var l = t.timeStamp - o
3673            l < 50 && (s.altGr = !0)
3674          }
3675        }
3676      }
3677      n in r.MODIFIER_KEYS && (n = -1), a & 8 && n >= 91 && n <= 93 && (n = -1)
3678      if (!a && n === 13) {
3679        var f = 'location' in t ? t.location : t.keyLocation
3680        if (f === 3) {
3681          e(t, a, -n)
3682          if (t.defaultPrevented) return
3683        }
3684      }
3685      if (i.isChromeOS && a & 8) {
3686        e(t, a, n)
3687        if (t.defaultPrevented) return
3688        a &= -9
3689      }
3690      return !!a || n in r.FUNCTION_KEYS || n in r.PRINTABLE_KEYS ? e(t, a, n) : !1
3691    }
3692    function f() {
3693      s = Object.create(null)
3694    }
3695    var r = e('./keys'),
3696      i = e('./useragent'),
3697      s = null,
3698      o = 0
3699    ;(t.addListener = function(e, t, n) {
3700      if (e.addEventListener) return e.addEventListener(t, n, !1)
3701      if (e.attachEvent) {
3702        var r = function() {
3703          n.call(e, window.event)
3704        }
3705        ;(n._wrapper = r), e.attachEvent('on' + t, r)
3706      }
3707    }),
3708      (t.removeListener = function(e, t, n) {
3709        if (e.removeEventListener) return e.removeEventListener(t, n, !1)
3710        e.detachEvent && e.detachEvent('on' + t, n._wrapper || n)
3711      }),
3712      (t.stopEvent = function(e) {
3713        return t.stopPropagation(e), t.preventDefault(e), !1
3714      }),
3715      (t.stopPropagation = function(e) {
3716        e.stopPropagation ? e.stopPropagation() : (e.cancelBubble = !0)
3717      }),
3718      (t.preventDefault = function(e) {
3719        e.preventDefault ? e.preventDefault() : (e.returnValue = !1)
3720      }),
3721      (t.getButton = function(e) {
3722        return e.type == 'dblclick'
3723          ? 0
3724          : e.type == 'contextmenu' || (i.isMac && e.ctrlKey && !e.altKey && !e.shiftKey)
3725          ? 2
3726          : e.preventDefault
3727          ? e.button
3728          : { 1: 0, 2: 2, 4: 1 }[e.button]
3729      }),
3730      (t.capture = function(e, n, r) {
3731        function i(e) {
3732          n && n(e),
3733            r && r(e),
3734            t.removeListener(document, 'mousemove', n, !0),
3735            t.removeListener(document, 'mouseup', i, !0),
3736            t.removeListener(document, 'dragstart', i, !0)
3737        }
3738        return (
3739          t.addListener(document, 'mousemove', n, !0),
3740          t.addListener(document, 'mouseup', i, !0),
3741          t.addListener(document, 'dragstart', i, !0),
3742          i
3743        )
3744      }),
3745      (t.addTouchMoveListener = function(e, n) {
3746        var r, i
3747        t.addListener(e, 'touchstart', function(e) {
3748          var t = e.touches,
3749            n = t[0]
3750          ;(r = n.clientX), (i = n.clientY)
3751        }),
3752          t.addListener(e, 'touchmove', function(e) {
3753            var t = e.touches
3754            if (t.length > 1) return
3755            var s = t[0]
3756            ;(e.wheelX = r - s.clientX), (e.wheelY = i - s.clientY), (r = s.clientX), (i = s.clientY), n(e)
3757          })
3758      }),
3759      (t.addMouseWheelListener = function(e, n) {
3760        'onmousewheel' in e
3761          ? t.addListener(e, 'mousewheel', function(e) {
3762              var t = 8
3763              e.wheelDeltaX !== undefined
3764                ? ((e.wheelX = -e.wheelDeltaX / t), (e.wheelY = -e.wheelDeltaY / t))
3765                : ((e.wheelX = 0), (e.wheelY = -e.wheelDelta / t)),
3766                n(e)
3767            })
3768          : 'onwheel' in e
3769          ? t.addListener(e, 'wheel', function(e) {
3770              var t = 0.35
3771              switch (e.deltaMode) {
3772                case e.DOM_DELTA_PIXEL:
3773                  ;(e.wheelX = e.deltaX * t || 0), (e.wheelY = e.deltaY * t || 0)
3774                  break
3775                case e.DOM_DELTA_LINE:
3776                case e.DOM_DELTA_PAGE:
3777                  ;(e.wheelX = (e.deltaX || 0) * 5), (e.wheelY = (e.deltaY || 0) * 5)
3778              }
3779              n(e)
3780            })
3781          : t.addListener(e, 'DOMMouseScroll', function(e) {
3782              e.axis && e.axis == e.HORIZONTAL_AXIS
3783                ? ((e.wheelX = (e.detail || 0) * 5), (e.wheelY = 0))
3784                : ((e.wheelX = 0), (e.wheelY = (e.detail || 0) * 5)),
3785                n(e)
3786            })
3787      }),
3788      (t.addMultiMouseDownListener = function(e, n, r, s) {
3789        function c(e) {
3790          t.getButton(e) !== 0 ? (o = 0) : e.detail > 1 ? (o++, o > 4 && (o = 1)) : (o = 1)
3791          if (i.isIE) {
3792            var c = Math.abs(e.clientX - u) > 5 || Math.abs(e.clientY - a) > 5
3793            if (!f || c) o = 1
3794            f && clearTimeout(f),
3795              (f = setTimeout(function() {
3796                f = null
3797              }, n[o - 1] || 600)),
3798              o == 1 && ((u = e.clientX), (a = e.clientY))
3799          }
3800          ;(e._clicks = o), r[s]('mousedown', e)
3801          if (o > 4) o = 0
3802          else if (o > 1) return r[s](l[o], e)
3803        }
3804        function h(e) {
3805          ;
3805(o = 2),
3806            f && clearTimeout(f),
3807            (f = setTimeout(function() {
3808              f = null
3809            }, n[o - 1] || 600)),
3810            r[s]('mousedown', e),
3811            r[s](l[o], e)
3812        }
3813        var o = 0,
3814          u,
3815          a,
3816          f,
3817          l = { 2: 'dblclick', 3: 'tripleclick', 4: 'quadclick' }
3818        Array.isArray(e) || (e = [e]),
3819          e.forEach(function(e) {
3820            t.addListener(e, 'mousedown', c), i.isOldIE && t.addListener(e, 'dblclick', h)
3821          })
3822      })
3823    var u =
3824      !i.isMac || !i.isOpera || 'KeyboardEvent' in window
3825        ? function(e) {
3826            return 0 | (e.ctrlKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.metaKey ? 8 : 0)
3827          }
3828        : function(e) {
3829            return 0 | (e.metaKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.ctrlKey ? 8 : 0)
3830          }
3831    ;(t.getModifierString = function(e) {
3832      return r.KEY_MODS[u(e)]
3833    }),
3834      (t.addCommandKeyListener = function(e, n) {
3835        var r = t.addListener
3836        if (i.isOldGecko || (i.isOpera && !('KeyboardEvent' in window))) {
3837          var o = null
3838          r(e, 'keydown', function(e) {
3839            o = e.keyCode
3840          }),
3841            r(e, 'keypress', function(e) {
3842              return a(n, e, o)
3843            })
3844        } else {
3845          var u = null
3846          r(e, 'keydown', function(e) {
3847            s[e.keyCode] = (s[e.keyCode] || 0) + 1
3848            var t = a(n, e, e.keyCode)
3849            return (u = e.defaultPrevented), t
3850          }),
3851            r(e, 'keypress', function(e) {
3852              u && (e.ctrlKey || e.altKey || e.shiftKey || e.metaKey) && (t.stopEvent(e), (u = null))
3853            }),
3854            r(e, 'keyup', function(e) {
3855              s[e.keyCode] = null
3856            }),
3857            s || (f(), r(window, 'focus', f))
3858        }
3859      })
3860    if (typeof window == 'object' && window.postMessage && !i.isOldIE) {
3861      var l = 1
3862      t.nextTick = function(e, n) {
3863        n = n || window
3864        var r = 'zero-timeout-message-' + l
3865        t.addListener(n, 'message', function i(s) {
3866          s.data == r && (t.stopPropagation(s), t.removeListener(n, 'message', i), e())
3867        }),
3868          n.postMessage(r, '*')
3869      }
3870    }
3871    ;(t.$idleBlocked = !1),
3872      (t.onIdle = function(e, n) {
3873        return setTimeout(function r() {
3874          t.$idleBlocked ? setTimeout(r, 100) : e()
3875        }, n)
3876      }),
3877      (t.$idleBlockId = null),
3878      (t.blockIdle = function(e) {
3879        t.$idleBlockId && clearTimeout(t.$idleBlockId),
3880          (t.$idleBlocked = !0),
3881          (t.$idleBlockId = setTimeout(function() {
3882            t.$idleBlocked = !1
3883          }, e || 100))
3884      }),
3885      (t.nextFrame =
3886        typeof window == 'object' &&
3887        (window.requestAnimationFrame ||
3888          window.mozRequestAnimationFrame ||
3889          window.webkitRequestAnimationFrame ||
3890          window.msRequestAnimationFrame ||
3891          window.oRequestAnimationFrame)),
3892      t.nextFrame
3893        ? (t.nextFrame = t.nextFrame.bind(window))
3894        : (t.nextFrame = function(e) {
3895            setTimeout(e, 17)
3896          })
3897  }),
3898  define('ace/range', ['require', 'exports', 'module'], function(e, t, n) {
3899    'use strict'
3900    var r = function(e, t) {
3901        return e.row - t.row || e.column - t.column
3902      },
3903      i = function(e, t, n, r) {
3904        ;(this.start = { row: e, column: t }), (this.end = { row: n, column: r })
3905      }
3906    ;(function() {
3907      ;(this.isEqual = function(e) {
3908        return (
3909          this.start.row === e.start.row &&
3910          this.end.row === e.end.row &&
3911          this.start.column === e.start.column &&
3912          this.end.column === e.end.column
3913        )
3914      }),
3915        (this.toString = function() {
3916          return (
3917            'Range: [' +
3918            this.start.row +
3919            '/' +
3920            this.start.column +
3921            '] -> [' +
3922            this.end.row +
3923            '/' +
3924            this.end.column +
3925            ']'
3926          )
3927        }),
3928        (this.contains = function(e, t) {
3929          return this.compare(e, t) == 0
3930        }),
3931        (this.compareRange = function(e) {
3932          var t,
3933            n = e.end,
3934            r = e.start
3935          return (
3936            (t = this.compare(n.row, n.column)),
3937            t == 1
3938              ? ((t = this.compare(r.row, r.column)), t == 1 ? 2 : t == 0 ? 1 : 0)
3939              : t == -1
3940              ? -2
3941              : ((t = this.compare(r.row, r.column)), t == -1 ? -1 : t == 1 ? 42 : 0)
3942          )
3943        }),
3944        (this.comparePoint = function(e) {
3945          return this.compare(e.row, e.column)
3946        }),
3947        (this.containsRange = function(e) {
3948          return this.comparePoint(e.start) == 0 && this.comparePoint(e.end) == 0
3949        }),
3950        (this.intersects = function(e) {
3951          var t = this.compareRange(e)
3952          return t == -1 || t == 0 || t == 1
3953        }),
3954        (this.isEnd = function(e, t) {
3955          return this.end.row == e && this.end.column == t
3956        }),
3957        (this.isStart = function(e, t) {
3958          return this.start.row == e && this.start.column == t
3959        }),
3960        (this.setStart = function(e, t) {
3961          typeof e == 'object'
3962            ? ((this.start.column = e.column), (this.start.row = e.row))
3963            : ((this.start.row = e), (this.start.column = t))
3964        }),
3965        (this.setEnd = function(e, t) {
3966          typeof e == 'object'
3967            ? ((this.end.column = e.column), (this.end.row = e.row))
3968            : ((this.end.row = e), (this.end.column = t))
3969        }),
3970        (this.inside = function(e, t) {
3971          return this.compare(e, t) == 0 ? (this.isEnd(e, t) || this.isStart(e, t) ? !1 : !0) : !1
3972        }),
3973        (this.insideStart = function(e, t) {
3974          return this.compare(e, t) == 0 ? (this.isEnd(e, t) ? !1 : !0) : !1
3975        }),
3976        (this.insideEnd = function(e, t) {
3977          return this.compare(e, t) == 0 ? (this.isStart(e, t) ? !1 : !0) : !1
3978        }),
3979        (this.compare = function(e, t) {
3980          return !this.isMultiLine() && e === this.start.row
3981            ? t < this.start.column
3982              ? -1
3983              : t > this.end.column
3984              ? 1
3985              : 0
3986            : e < this.start.row
3987            ? -1
3988            : e > this.end.row
3989            ? 1
3990            : this.start.row === e
3991            ? t >= this.start.column
3992              ? 0
3993              : -1
3994            : this.end.row === e
3995            ? t <= this.end.column
3996              ? 0
3997              : 1
3998            : 0
3999        }),
4000        (this.compareStart = function(e, t) {
4001          return this.start.row == e && this.start.column == t ? -1 : this.compare(e, t)
4002        }),
4003        (this.compareEnd = function(e, t) {
4004          return this.end.row == e && this.end.column == t ? 1 : this.compare(e, t)
4005        }),
4006        (this.compareInside = function(e, t) {
4007          return this.end.row == e && this.end.column == t
4008            ? 1
4009            : this.start.row == e && this.start.column == t
4010            ? -1
4011            : this.compare(e, t)
4012        }),
4013        (this.clipRows = function(e, t) {
4014          if (this.end.row > t) var n = { row: t + 1, column: 0 }
4015          else if (this.end.row < e) var n = { row: e, column: 0 }
4016          if (this.start.row > t) var r = { row: t + 1, column: 0 }
4017          else if (this.start.row < e) var r = { row: e, column: 0 }
4018          return i.fromPoints(r || this.start, n || this.end)
4019        }),
4020        (this.extend = function(e, t) {
4021          var n = this.compare(e, t)
4022          if (n == 0) return this
4023          if (n == -1) var r = { row: e, column: t }
4024          else var s = { row: e, column: t }
4025          return i.fromPoints(r || this.start, s || this.end)
4026        }),
4027        (this.isEmpty = function() {
4028          return this.start.row === this.end.row && this.start.column === this.end.column
4029        }),
4030        (this.isMultiLine = function() {
4031          return this.start.row !== this.end.row
4032        }),
4033        (this.clone = function() {
4034          return i.fromPoints(this.start, this.end)
4035        }),
4036        (this.collapseRows = function() {
4037          return this.end.column == 0
4038            ? new i(this.start.row, 0, Math.max(this.start.row, this.end.row - 1), 0)
4039            : new i(this.start.row, 0, this.end.row, 0)
4040        }),
4041        (this.toScreenRange = function(e) {
4042          var t = e.documentToScreenPosition(this.start),
4043            n = e.documentToScreenPosition(this.end)
4044          return new i(t.row, t.column, n.row, n.column)
4045        }),
4046        (this.moveBy = function(e, t) {
4047          ;(this.start.row += e), (this.start.column += t), (this.end.row += e), (this.end.column += t)
4048        })
4049    }.call(i.prototype),
4050      (i.fromPoints = function(e, t) {
4051        return new i(e.row, e.column, t.row, t.column)
4052      }),
4053      (i.comparePoints = r),
4054      (i.comparePoints = function(e, t) {
4055        return e.row - t.row || e.column - t.column
4056      }),
4057      (t.Range = i))
4058  }),
4059  define('ace/lib/lang', ['require', 'exports', 'module'], function(e, t, n) {
4060    'use strict'
4061    ;(t.last = function(e) {
4062      return e[e.length - 1]
4063    }),
4064      (t.stringReverse = function(e) {
4065        return e
4066          .split('')
4067          .reverse()
4068          .join('')
4069      }),
4070      (t.stringRepeat = function(e, t) {
4071        var n = ''
4072        while (t > 0) {
4073          t & 1 && (n += e)
4074          if ((t >>= 1)) e += e
4075        }
4076        return n
4077      })
4078    var r = /^\s\s*/,
4079      i = /\s\s*$/
4080    ;(t.stringTrimLeft = function(e) {
4081      return e.replace(r, '')
4082    }),
4083      (t.stringTrimRight = function(e) {
4084        return e.replace(i, '')
4085      }),
4086      (t.copyObject = function(e) {
4087        var t = {}
4088        for (var n in e) t[n] = e[n]
4089        return t
4090      }),
4091      (t.copyArray = function(e) {
4092        var t = []
4093        for (var n = 0, r = e.length; n < r; n++)
4094          e[n] && typeof e[n] == 'object' ? (t[n] = this.copyObject(e[n])) : (t[n] = e[n])
4095        return t
4096      }),
4097      (t.deepCopy = function s(e) {
4098        if (typeof e != 'object' || !e) return e
4099        var t
4100        if (Array.isArray(e)) {
4101          t = []
4102          for (var n = 0; n < e.length; n++) t[n] = s(e[n])
4103          return t
4104        }
4105        if (Object.prototype.toString.call(e) !== '[object Object]') return e
4106        t = {}
4107        for (var n in e) t[n] = s(e[n])
4108        return t
4109      }),
4110      (t.arrayToMap = function(e) {
4111        var t = {}
4112        for (var n = 0; n < e.length; n++) t[e[n]] = 1
4113        return t
4114      }),
4115      (t.createMap = function(e) {
4116        var t = Object.create(null)
4117        for (var n in e) t[n] = e[n]
4118        return t
4119      }),
4120      (t.arrayRemove = function(e, t) {
4121        for (var n = 0; n <= e.length; n++) t === e[n] && e.splice(n, 1)
4122      }),
4123      (t.escapeRegExp = function(e) {
4124        return e.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1')
4125      }),
4126      (t.escapeHTML = function(e) {
4127        return e
4128          .replace(/&/g, '&#38;')
4129          .replace(/"/g, '&#34;')
4130          .replace(/'/g, '&#39;')
4131          .replace(/</g, '&#60;')
4132      }),
4133      (t.getMatchOffsets = function(e, t) {
4134        var n = []
4135        return (
4136          e.replace(t, function(e) {
4137            n.push({ offset: arguments[arguments.length - 2], length: e.length })
4138          }),
4139          n
4140        )
4141      }),
4142      (t.deferredCall = function(e) {
4143        var t = null,
4144          n = function() {
4145            ;(t = null), e()
4146          },
4147          r = function(e) {
4148            return r.cancel(), (t = setTimeout(n, e || 0)), r
4149          }
4150        return (
4151          (r.schedule = r),
4152          (r.call = function() {
4153            return this.cancel(), e(), r
4154          }),
4155          (r.cancel = function() {
4156            return clearTimeout(t), (t = null), r
4157          }),
4158          (r.isPending = function() {
4159            return t
4160          }),
4161          r
4162        )
4163      }),
4164      (t.delayedCall = function(e, t) {
4165        var n = null,
4166          r = function() {
4167            ;(n = null), e()
4168          },
4169          i = function(e) {
4170            n == null && (n = setTimeout(r, e || t))
4171          }
4172        return (
4173          (i.delay = function(e) {
4174            n && clearTimeout(n), (n = setTimeout(r, e || t))
4175          }),
4176          (i.schedule = i),
4177          (i.call = function() {
4178            this.cancel(), e()
4179          }),
4180          (i.cancel = function() {
4181            n && clearTimeout(n), (n = null)
4182          }),
4183          (i.isPending = function() {
4184            return n
4185          }),
4186          i
4187        )
4188      })
4189  }),
4190  define('ace/keyboard/textinput_ios', [
4191    'require',
4192    'exports',
4193    'module',
4194    'ace/lib/event',
4195    'ace/lib/useragent',
4196    'ace/lib/dom',
4197    'ace/lib/lang',
4198    'ace/lib/keys'
4199  ], function(e, t, n) {
4200    'use strict'
4201    var r = e('../lib/event'),
4202      i = e('../lib/useragent'),
4203      s = e('../lib/dom'),
4204      o = e('../lib/lang'),
4205      u = e('../lib/keys'),
4206      a = u.KEY_MODS,
4207      f = i.isChrome < 18,
4208      l = i.isIE,
4209      c = function(e, t) {
4210        function x(e) {
4211          if (m) return
4212          m = !0
4213          if (k) (t = 0), (n = e ? 0 : c.value.length - 1)
4214          else
4215            var t = 4,
4216              n = 5
4217          try {
4218            c.setSelectionRange(t, n)
4219          } catch (r) {}
4220          m = !1
4221        }
4222        function T() {
4223          if (m) return
4224          ;(c.value = h), i.isWebKit && S.schedule()
4225        }
4226        function R() {
4227          clearTimeout(q),
4228            (q = setTimeout(function() {
4229              g && ((c.style.cssText = g), (g = '')),
4230                t.renderer.$keepTextAreaAtCursor == null &&
4231                  ((t.renderer.$keepTextAreaAtCursor = !0), t.renderer.$moveTextAreaToCursor())
4232            }, 0))
4233        }
4234        var n = this,
4235          c = s.createElement('textarea')
4236        ;(c.className = i.isIOS ? 'ace_text-input ace_text-input-ios' : 'ace_text-input'),
4237          i.isTouchPad && c.setAttribute('x-palm-disable-auto-cap', !0),
4238          c.setAttribute('wrap', 'off'),
4239          c.setAttribute('autocorrect', 'off'),
4240          c.setAttribute('autocapitalize', 'off'),
4241          c.setAttribute('spellcheck', !1),
4242          (c.style.opacity = '0'),
4243          e.insertBefore(c, e.firstChild)
4244        var h = '\n aaaa a\n',
4245          p = !1,
4246          d = !1,
4247          v = !1,
4248          m = !1,
4249          g = '',
4250          y = !0
4251        try {
4252          var b = document.activeElement === c
4253        } catch (w) {}
4254        r.addListener(c, 'blur', function(e) {
4255          t.onBlur(e), (b = !1)
4256        }),
4257          r.addListener(c, 'focus', function(e) {
4258            ;(b = !0), t.onFocus(e), x()
4259          }),
4260          (this.focus = function() {
4261            if (g) return c.focus()
4262            ;(c.style.position = 'fixed'), c.focus()
4263          }),
4264          (this.blur = function() {
4265            c.blur()
4266          }),
4267          (this.isFocused = function() {
4268            return b
4269          })
4270        var E = o.delayedCall(function() {
4271            b && x(y)
4272          }),
4273          S = o.delayedCall(function() {
4274            m || ((c.value = h), b && x())
4275          })
4276        i.isWebKit ||
4277          t.addEventListener('changeSelection', function() {
4278            t.selection.isEmpty() != y && ((y = !y), E.schedule())
4279          }),
4280          T(),
4281          b && t.onFocus()
4282        var N = function(e) {
4283            return e.selectionStart === 0 && e.selectionEnd === e.value.length
4284          },
4285          C = function(e) {
4286            N(c) ? (t.selectAll(), x()) : k && x(t.selection.isEmpty())
4287          },
4288          k = null
4289        ;(this.setInputHandler = function(e) {
4290          k = e
4291        }),
4292          (this.getInputHandler = function() {
4293            return k
4294          })
4295        var L = !1,
4296          A = function(e) {
4297            if (c.selectionStart === 4 && c.selectionEnd === 5) return
4298            k && ((e = k(e)), (k = null)),
4299              v
4300                ? (x(), e && t.onPaste(e), (v = !1))
4301                : e == h.substr(0) && c.selectionStart === 4
4302                ? L
4303                  ? t.execCommand('del', { source: 'ace' })
4304                  : t.execCommand('backspace', { source: 'ace' })
4305                : p ||
4306                  (e.substring(0, 9) == h && e.length > h.length
4307                    ? (e = e.substr(9))
4308                    : e.substr(0, 4) == h.substr(0, 4)
4309                    ? (e = e.substr(4, e.length - h.length + 1))
4310                    : e.charAt(e.length - 1) == h.charAt(0) && (e = e.slice(0, -1)),
4311                  e != h.charAt(0) && e.charAt(e.length - 1) == h.charAt(0) && (e = e.slice(0, -1)),
4312                  e && t.onTextInput(e)),
4313              p && (p = !1),
4314              L && (L = !1)
4315          },
4316          O = function(e) {
4317            if (m) return
4318            var t = c.value
4319            A(t), T()
4320          },
4321          M = function(e, t, n) {
4322            var r = e.clipboardData || window.clipboardData
4323            if (!r || f) return
4324            var i = l || n ? 'Text' : 'text/plain'
4325            try {
4326              return t ? r.setData(i, t) !== !1 : r.getData(i)
4327            } catch (e) {
4328              if (!n) return M(e, t, !0)
4329            }
4330          },
4331          _ = function(e, n) {
4332            var s = t.getCopyText()
4333            if (!s) return r.preventDefault(e)
4334            M(e, s)
4335              ? (i.isIOS &&
4336                  ((d = n),
4337                  (c.value = '\n aa' + s + 'a a\n'),
4338                  c.setSelectionRange(4, 4 + s.length),
4339                  (p = { value: s })),
4340                n ? t.onCut() : t.onCopy(),
4341                i.isIOS || r.preventDefault(e))
4342              : ((p = !0),
4343                (c.value = s),
4344                c.select(),
4345                setTimeout(function() {
4346                  ;(p = !1), T(), x(), n ? t.onCut() : t.onCopy()
4347                }))
4348          },
4349          D = function(e) {
4350            _(e, !0)
4351          },
4352          P = function(e) {
4353            _(e, !1)
4354          },
4355          H = function(e) {
4356            var n = M(e)
4357            typeof n == 'string'
4358              ? (n && t.onPaste(n, e), i.isIE && setTimeout(x), r.preventDefault(e))
4359              : ((c.value = ''), (v = !0))
4360          }
4361        r.addCommandKeyListener(c, t.onCommandKey.bind(t)),
4362          r.addListener(c, 'select', C),
4363          r.addListener(c, 'input', O),
4364          r.addListener(c, 'cut', D),
4365          r.addListener(c, 'copy', P),
4366          r.addListener(c, 'paste', H)
4367        var B = function(e) {
4368            if (m || !t.onCompositionStart || t.$readOnly) return
4369            ;(m = {}),
4370              (m.canUndo = t.session.$undoManager),
4371              t.onCompositionStart(),
4372              setTimeout(j, 0),
4373              t.on('mousedown', F),
4374              m.canUndo &&
4375                !t.selection.isEmpty() &&
4376                (t.insert(''), t.session.markUndoGroup(), t.selection.clearSelection()),
4377              t.session.markUndoGroup()
4378          },
4379          j = function() {
4380            if (!m || !t.onCompositionUpdate || t.$readOnly) return
4381            var e = c.value.replace(/\x01/g, '')
4382            if (m.lastValue === e) return
4383            t.onCompositionUpdate(e), m.lastValue && t.undo(), m.canUndo && (m.lastValue = e)
4384            if (m.lastValue) {
4385              var n = t.selection.getRange()
4386              t.insert(m.lastValue),
4387                t.session.markUndoGroup(),
4388                (m.range = t.selection.getRange()),
4389                t.selection.setRange(n),
4390                t.selection.clearSelection()
4391            }
4392          },
4393          F = function(e) {
4394            if (!t.onCompositionEnd || t.$readOnly) return
4395            var n = m
4396            m = !1
4397            var r = setTimeout(function() {
4398              r = null
4399              var e = c.value.replace(/\x01/g, '')
4400              if (m) return
4401              e == n.lastValue ? T() : !n.lastValue && e && (T(), A(e))
4402            })
4403            ;(k = function(i) {
4404              return (
4405                r && clearTimeout(r),
4406                (i = i.replace(/\x01/g, '')),
4407                i == n.lastValue ? '' : (n.lastValue && r && t.undo(), i)
4408              )
4409            }),
4410              t.onCompositionEnd(),
4411              t.removeListener('mousedown', F),
4412              e.type == 'compositionend' && n.range && t.selection.setRange(n.range)
4413            var s = (!!i.isChrome && i.isChrome >= 53) || (!!i.isWebKit && i.isWebKit >= 603)
4414            s && O()
4415          },
4416          I = o.delayedCall(j, 50)
4417        r.addListener(c, 'compositionstart', B),
4418          r.addListener(c, 'compositionupdate', function() {
4419            I.schedule()
4420          }),
4421          r.addListener(c, 'keyup', function() {
4422            I.schedule()
4423          }),
4424          r.addListener(c, 'keydown', function() {
4425            I.schedule()
4426          }),
4427          r.addListener(c, 'compositionend', F),
4428          (this.getElement = function() {
4429            return c
4430          }),
4431          (this.setReadOnly = function(e) {
4432            c.readOnly = e
4433          }),
4434          (this.onContextMenu = function(e) {
4435            ;(L = !0),
4436              x(t.selection.isEmpty()),
4437              t._emit('nativecontextmenu', { target: t, domEvent: e }),
4438              this.moveToMouse(e, !0)
4439          }),
4440          (this.moveToMouse = function(e, n) {
4441            g || (g = c.style.cssText),
4442              (c.style.cssText =
4443                (n ? 'z-index:100000;' : '') + 'height:' + c.style.height + ';' + (i.isIE ? 'opacity:0.1;' : ''))
4444            var o = t.container.getBoundingClientRect(),
4445              u = s.computedStyle(t.container),
4446              a = o.top + (parseInt(u.borderTopWidth) || 0),
4447              f = o.left + (parseInt(o.borderLeftWidth) || 0),
4448              l = o.bottom - a - c.clientHeight - 2,
4449              h = function(e) {
4450                ;(c.style.left = e.clientX - f - 2 + 'px'), (c.style.top = Math.min(e.clientY - a - 2, l) + 'px')
4451              }
4452            h(e)
4453            if (e.type != 'mousedown') return
4454            t.renderer.$keepTextAreaAtCursor && (t.renderer.$keepTextAreaAtCursor = null),
4455              clearTimeout(q),
4456              i.isWin && r.capture(t.container, h, R)
4457          }),
4458          (this.onContextMenuClose = R)
4459        var q,
4460          U = function(e) {
4461            t.textInput.onContextMenu(e), R()
4462          }
4463        r.addListener(c, 'mouseup', U),
4464          r.addListener(c, 'mousedown', function(e) {
4465            e.preventDefault(), R()
4466          }),
4467          r.addListener(t.renderer.scroller, 'contextmenu', U),
4468          r.addListener(c, 'contextmenu', U)
4469        if (i.isIOS) {
4470          var z = null,
4471            W = !1
4472          e.addEventListener('keydown', function(e) {
4473            z && clearTimeout(z), (W = !0)
4474          }),
4475            e.addEventListener('keyup', function(e) {
4476              z = setTimeout(function() {
4477                W = !1
4478              }, 100)
4479            })
4480          var X = function(e) {
4481            if (document.activeElement !== c) return
4482            if (W) return
4483            if (d)
4484              return setTimeout(function() {
4485                d = !1
4486              }, 100)
4487            var n = c.selectionStart,
4488              r = c.selectionEnd
4489            c.setSelectionRange(4, 5)
4490            if (n == r)
4491              switch (n) {
4492                case 0:
4493                  t.onCommandKey(null, 0, u.up)
4494                  break
4495                case 1:
4496                  t.onCommandKey(null, 0, u.home)
4497                  break
4498                case 2:
4499                  t.onCommandKey(null, a.option, u.left)
4500                  break
4501                case 4:
4502                  t.onCommandKey(null, 0, u.left)
4503                  break
4504                case 5:
4505                  t.onCommandKey(null, 0, u.right)
4506                  break
4507                case 7:
4508                  t.onCommandKey(null, a.option, u.right)
4509                  break
4510                case 8:
4511                  t.onCommandKey(null, 0, u.end)
4512                  break
4513                case 9:
4514                  t.onCommandKey(null, 0, u.down)
4515              }
4516            else {
4517              switch (r) {
4518                case 6:
4519                  t.onCommandKey(null, a.shift, u.right)
4520                  break
4521                case 7:
4522                  t.onCommandKey(null, a.shift | a.option, u.right)
4523                  break
4524                case 8:
4525                  t.onCommandKey(null, a.shift, u.end)
4526                  break
4527                case 9:
4528                  t.onCommandKey(null, a.shift, u.down)
4529              }
4530              switch (n) {
4531                case 0:
4532                  t.onCommandKey(null, a.shift, u.up)
4533                  break
4534                case 1:
4535                  t.onCommandKey(null, a.shift, u.home)
4536                  break
4537                case 2:
4538                  t.onCommandKey(null, a.shift | a.option, u.left)
4539                  break
4540                case 3:
4541                  t.onCommandKey(null, a.shift, u.left)
4542              }
4543            }
4544          }
4545          document.addEventListener('selectionchange', X),
4546            t.on('destroy', function() {
4547              document.removeEventListener('selectionchange', X)
4548            })
4549        }
4550      }
4551    t.TextInput = c
4552  }),
4553  define('ace/keyboard/textinput', [
4554    'require',
4555    'exports',
4556    'module',
4557    'ace/lib/event',
4558    'ace/lib/useragent',
4559    'ace/lib/dom',
4560    'ace/lib/lang',
4561    'ace/keyboard/textinput_ios'
4562  ], function(e, t, n) {
4563    'use strict'
4564    var r = e('../lib/event'),
4565      i = e('../lib/useragent'),
4566      s = e('../lib/dom'),
4567      o = e('../lib/lang'),
4568      u = i.isChrome < 18,
4569      a = i.isIE,
4570      f = i.isChrome > 63,
4571      l = e('./textinput_ios').TextInput,
4572      c = function(e, t) {
4573        function T(e) {
4574          e = y ? !1 : e
4575          if (v) return
4576          v = !0
4577          if (L)
4578            var t = 0,
4579              r = e ? 0 : n.value.length - 1
4580          else
4581            var t = e ? 2 : 1,
4582              r = 2
4583          try {
4584            n.setSelectionRange(t, r)
4585          } catch (i) {}
4586          v = !1
4587        }
4588        function N() {
4589          if (v) return
4590          ;(n.value = c), i.isWebKit && x.schedule()
4591        }
4592        function U() {
4593          clearTimeout(R),
4594            (R = setTimeout(function() {
4595              m && ((n.style.cssText = m), (m = '')),
4596                t.renderer.$keepTextAreaAtCursor == null &&
4597                  ((t.renderer.$keepTextAreaAtCursor = !0), t.renderer.$moveTextAreaToCursor())
4598            }, 0))
4599        }
4600        if (i.isIOS) return l.call(this, e, t)
4601        var n = s.createElement('textarea')
4602        ;(n.className = 'ace_text-input'),
4603          n.setAttribute('wrap', 'off'),
4604          n.setAttribute('autocorrect', 'off'),
4605          n.setAttribute('autocapitalize', 'off'),
4606          n.setAttribute('spellcheck', !1),
4607          (n.style.opacity = '0'),
4608          e.insertBefore(n, e.firstChild)
4609        var c = i.isIE ? '\x01\x01' : '\u2028\u2028',
4610          h = i.isIE ? /\x01/g : /\u2028/g,
4611          p = !1,
4612          d = !1,
4613          v = !1,
4614          m = '',
4615          g = !0,
4616          y = !1,
4617          b = !1
4618        try {
4619          var w = document.activeElement === n
4620        } catch (E) {}
4621        r.addListener(n, 'blur', function(e) {
4622          t.onBlur(e), (w = !1)
4623        }),
4624          r.addListener(n, 'focus', function(e) {
4625            ;(w = !0), t.onFocus(e), T()
4626          }),
4627          (this.$focusScroll = !1),
4628          (this.focus = function() {
4629            if (m || f || this.$focusScroll == 'browser') return n.focus({ preventScroll: !0 })
4630            var e = n.style.top
4631            ;(n.style.position = 'fixed'), (n.style.top = '0px')
4632            var t = n.getBoundingClientRect().top != 0,
4633              r = []
4634            if (t) {
4635              var i = n.parentElement
4636              while (i && i.nodeType == 1)
4637                r.push(i),
4638                  i.setAttribute('ace_nocontext', !0),
4639                  !i.parentElement && i.getRootNode ? (i = i.getRootNode().host) : (i = i.parentElement)
4640            }
4641            n.focus({ preventScroll: !0 }),
4642              t &&
4643                r.forEach(function(e) {
4644                  e.removeAttribute('ace_nocontext')
4645                }),
4646              setTimeout(function() {
4647                ;(n.style.position = ''), n.style.top == '0px' && (n.style.top = e)
4648              }, 0)
4649          }),
4650          (this.blur = function() {
4651            n.blur()
4652          }),
4653          (this.isFocused = function() {
4654            return w
4655          })
4656        var S = o.delayedCall(function() {
4657            w && T(g)
4658          }),
4659          x = o.delayedCall(function() {
4660            v || ((n.value = c), w && T())
4661          })
4662        i.isWebKit ||
4663          t.addEventListener('changeSelection', function() {
4664            t.selection.isEmpty() != g && ((g = !g), S.schedule())
4665          }),
4666          N(),
4667          w && t.onFocus()
4668        var C = function(e) {
4669            return e.selectionStart === 0 && e.selectionEnd === e.value.length
4670          },
4671          k = function(e) {
4672            p ? (p = !1) : C(n) ? (t.selectAll(), T()) : L && T(t.selection.isEmpty())
4673          },
4674          L = null
4675        ;(this.setInputHandler = function(e) {
4676          L = e
4677        }),
4678          (this.getInputHandler = function() {
4679            return L
4680          })
4681        var A = !1,
4682          O = function(e) {
4683            L && ((e = L(e)), (L = null)),
4684              d
4685                ? (T(), e && t.onPaste(e), (d = !1))
4686                : e == c.charAt(0)
4687                ? A
4688                  ? t.execCommand('del', { source: 'ace' })
4689                  : t.execCommand('backspace', { source: 'ace' })
4690                : (e.substring(0, 2) == c
4691                    ? (e = e.substr(2))
4692                    : e.charAt(0) == c.charAt(0)
4693                    ? (e = e.substr(1))
4694                    : e.charAt(e.length - 1) == c.charAt(0) && (e = e.slice(0, -1)),
4695                  e.charAt(e.length - 1) == c.charAt(0) && (e = e.slice(0, -1)),
4696                  e && t.onTextInput(e)),
4697              A && (A = !1)
4698          },
4699          M = function(e) {
4700            if (v) return
4701            var t = n.value
4702            O(t), N()
4703          },
4704          _ = function(e, t, n) {
4705            var r = e.clipboardData || window.clipboardData
4706            if (!r || u) return
4707            var i = a || n ? 'Text' : 'text/plain'
4708            try {
4709              return t ? r.setData(i, t) !== !1 : r.getData(i)
4710            } catch (e) {
4711              if (!n) return _(e, t, !0)
4712            }
4713          },
4714          D = function(e, i) {
4715            var s = t.getCopyText()
4716            if (!s) return r.preventDefault(e)
4717            _(e, s)
4718              ? (i ? t.onCut() : t.onCopy(), r.preventDefault(e))
4719              : ((p = !0),
4720                (n.value = s),
4721                n.select(),
4722                setTimeout(function() {
4723                  ;(p = !1), N(), T(), i ? t.onCut() : t.onCopy()
4724                }))
4725          },
4726          P = function(e) {
4727            D(e, !0)
4728          },
4729          H = function(e) {
4730            D(e, !1)
4731          },
4732          B = function(e) {
4733            var s = _(e)
4734            typeof s == 'string'
4735              ? (s && t.onPaste(s, e), i.isIE && setTimeout(T), r.preventDefault(e))
4736              : ((n.value = ''), (d = !0))
4737          }
4738        r.addCommandKeyListener(n, t.onCommandKey.bind(t)),
4739          r.addListener(n, 'select', k),
4740          r.addListener(n, 'input', M),
4741          r.addListener(n, 'cut', P),
4742          r.addListener(n, 'copy', H),
4743          r.addListener(n, 'paste', B),
4744          (!('oncut' in n) || !('oncopy' in n) || !('onpaste' in n)) &&
4745            r.addListener(e, 'keydown', function(e) {
4746              if ((i.isMac && !e.metaKey) || !e.ctrlKey) return
4747              switch (e.keyCode) {
4748                case 67:
4749                  H(e)
4750                  break
4751                case 86:
4752                  B(e)
4753                  break
4754                case 88:
4755                  P(e)
4756              }
4757            })
4758        var j = function(e) {
4759            if (v || !t.onCompositionStart || t.$readOnly) return
4760            ;(v = {}),
4761              (v.canUndo = t.session.$undoManager),
4762              t.onCompositionStart(),
4763              setTimeout(F, 0),
4764              t.on('mousedown', I),
4765              v.canUndo &&
4766                !t.selection.isEmpty() &&
4767                (t.insert(''), t.session.markUndoGroup(), t.selection.clearSelection()),
4768              t.session.markUndoGroup()
4769          },
4770          F = function() {
4771            if (!v || !t.onCompositionUpdate || t.$readOnly) return
4772            var e = n.value.replace(h, '')
4773            if (v.lastValue === e) return
4774            t.onCompositionUpdate(e), v.lastValue && t.undo(), v.canUndo && (v.lastValue = e)
4775            if (v.lastValue) {
4776              var r = t.selection.getRange()
4777              t.insert(v.lastValue),
4778                t.session.markUndoGroup(),
4779                (v.range = t.selection.getRange()),
4780                t.selection.setRange(r),
4781                t.selection.clearSelection()
4782            }
4783          },
4784          I = function(e) {
4785            if (!t.onCompositionEnd || t.$readOnly) return
4786            var r = v
4787            v = !1
4788            var s = setTimeout(function() {
4789              s = null
4790              var e = n.value.replace(h, '')
4791              if (v) return
4792              e == r.lastValue ? N() : !r.lastValue && e && (N(), O(e))
4793            })
4794            ;(L = function(n) {
4795              return (
4796                s && clearTimeout(s), (n = n.replace(h, '')), n == r.lastValue ? '' : (r.lastValue && s && t.undo(), n)
4797              )
4798            }),
4799              t.onCompositionEnd(),
4800              t.removeListener('mousedown', I),
4801              e.type == 'compositionend' && r.range && t.selection.setRange(r.range)
4802            var o = i.isIE || (i.isChrome && i.isChrome >= 53) || (i.isWebKit && i.isWebKit >= 603)
4803            o && M()
4804          },
4805          q = o.delayedCall(F, 50)
4806        r.addListener(n, 'compositionstart', j),
4807          r.addListener(n, 'compositionupdate', function() {
4808            q.schedule()
4809          }),
4810          r.addListener(n, 'keyup', function() {
4811            q.schedule()
4812          }),
4813          r.addListener(n, 'keydown', function() {
4814            q.schedule()
4815          }),
4816          r.addListener(n, 'compositionend', I),
4817          (this.getElement = function() {
4818            return n
4819          }),
4820          (this.setCommandMode = function(e) {
4821            ;(b = e), (n.readOnly = !1)
4822          }),
4823          (this.setReadOnly = function(e) {
4824            b || (n.readOnly = e)
4825          }),
4826          (this.setCopyWithEmptySelection = function(e) {
4827            y = e
4828          }),
4829          (this.onContextMenu = function(e) {
4830            ;(A = !0),
4831              T(t.selection.isEmpty()),
4832              t._emit('nativecontextmenu', { target: t, domEvent: e }),
4833              this.moveToMouse(e, !0)
4834          }),
4835          (this.moveToMouse = function(e, o) {
4836            m || (m = n.style.cssText),
4837              (n.style.cssText =
4838                (o ? 'z-index:100000;' : '') + 'height:' + n.style.height + ';' + (i.isIE ? 'opacity:0.1;' : ''))
4839            var u = t.container.getBoundingClientRect(),
4840              a = s.computedStyle(t.container),
4841              f = u.top + (parseInt(a.borderTopWidth) || 0),
4842              l = u.left + (parseInt(u.borderLeftWidth) || 0),
4843              c = u.bottom - f - n.clientHeight - 2,
4844              h = function(e) {
4845                ;(n.style.left = e.clientX - l - 2 + 'px'), (n.style.top = Math.min(e.clientY - f - 2, c) + 'px')
4846              }
4847            h(e)
4848            if (e.type != 'mousedown') return
4849            t.renderer.$keepTextAreaAtCursor && (t.renderer.$keepTextAreaAtCursor = null),
4850              clearTimeout(R),
4851              i.isWin && r.capture(t.container, h, U)
4852          }),
4853          (this.onContextMenuClose = U)
4854        var R,
4855          z = function(e) {
4856            t.textInput.onContextMenu(e), U()
4857          }
4858        r.addListener(n, 'mouseup', z),
4859          r.addListener(n, 'mousedown', function(e) {
4860            e.preventDefault(), U()
4861          }),
4862          r.addListener(t.renderer.scroller, 'contextmenu', z),
4863          r.addListener(n, 'contextmenu', z)
4864      }
4865    t.TextInput = c
4866  }),
4867  define('ace/mouse/default_handlers', [
4868    'require',
4869    'exports',
4870    'module',
4871    'ace/lib/dom',
4872    'ace/lib/event',
4873    'ace/lib/useragent'
4874  ], function(e, t, n) {
4875    'use strict'
4876    function a(e) {
4877      e.$clickSelection = null
4878      var t = e.editor
4879      t.setDefaultHandler('mousedown', this.onMouseDown.bind(e)),
4880        t.setDefaultHandler('dblclick', this.onDoubleClick.bind(e)),
4881        t.setDefaultHandler('tripleclick', this.onTripleClick.bind(e)),
4882        t.setDefaultHandler('quadclick', this.onQuadClick.bind(e)),
4883        t.setDefaultHandler('mousewheel', this.onMouseWheel.bind(e)),
4884        t.setDefaultHandler('touchmove', this.onTouchMove.bind(e))
4885      var n = [
4886        'select',
4887        'startSelect',
4888        'selectEnd',
4889        'selectAllEnd',
4890        'selectByWordsEnd',
4891        'selectByLinesEnd',
4892        'dragWait',
4893        'dragWaitEnd',
4894        'focusWait'
4895      ]
4896      n.forEach(function(t) {
4897        e[t] = this[t]
4898      }, this),
4899        (e.selectByLines = this.extendSelectionBy.bind(e, 'getLineRange')),
4900        (e.selectByWords = this.extendSelectionBy.bind(e, 'getWordRange'))
4901    }
4902    function f(e, t, n, r) {
4903      return Math.sqrt(Math.pow(n - e, 2) + Math.pow(r - t, 2))
4904    }
4905    function l(e, t) {
4906      if (e.start.row == e.end.row) var n = 2 * t.column - e.start.column - e.end.column
4907      else if (e.start.row == e.end.row - 1 && !e.start.column && !e.end.column) var n = t.column - 4
4908      else var n = 2 * t.row - e.start.row - e.end.row
4909      return n < 0 ? { cursor: e.start, anchor: e.end } : { cursor: e.end, anchor: e.start }
4910    }
4911    var r = e('../lib/dom'),
4912      i = e('../lib/event'),
4913      s = e('../lib/useragent'),
4914      o = 0,
4915      u = 250
4916    ;(function() {
4917      ;(this.onMouseDown = function(e) {
4918        var t = e.inSelection(),
4919          n = e.getDocumentPosition()
4920        this.mousedownEvent = e
4921        var r = this.editor,
4922          i = e.getButton()
4923        if (i !== 0) {
4924          var o = r.getSelectionRange(),
4925            u = o.isEmpty()
4926          ;(u || i == 1) && r.selection.moveToPosition(n),
4927            i == 2 && (r.textInput.onContextMenu(e.domEvent), s.isMozilla || e.preventDefault())
4928          return
4929        }
4930        this.mousedownEvent.time = Date.now()
4931        if (t && !r.isFocused()) {
4932          r.focus()
4933          if (this.$focusTimeout && !this.$clickSelection && !r.inMultiSelectMode) {
4934            this.setState('focusWait'), this.captureMouse(e)
4935            return
4936          }
4937        }
4938        return this.captureMouse(e), this.startSelect(n, e.domEvent._clicks > 1), e.preventDefault()
4939      }),
4940        (this.startSelect = function(e, t) {
4941          e = e || this.editor.renderer.screenToTextCoordinates(this.x, this.y)
4942          var n = this.editor
4943          this.mousedownEvent.getShiftKey() ? n.selection.selectToPosition(e) : t || n.selection.moveToPosition(e),
4944            t || this.select(),
4945            n.renderer.scroller.setCapture && n.renderer.scroller.setCapture(),
4946            n.setStyle('ace_selecting'),
4947            this.setState('select')
4948        }),
4949        (this.select = function() {
4950          var e,
4951            t = this.editor,
4952            n = t.renderer.screenToTextCoordinates(this.x, this.y)
4953          if (this.$clickSelection) {
4954            var r = this.$clickSelection.comparePoint(n)
4955            if (r == -1) e = this.$clickSelection.end
4956            else if (r == 1) e = this.$clickSelection.start
4957            else {
4958              var i = l(this.$clickSelection, n)
4959              ;(n = i.cursor), (e = i.anchor)
4960            }
4961            t.selection.setSelectionAnchor(e.row, e.column)
4962          }
4963          t.selection.selectToPosition(n), t.renderer.scrollCursorIntoView()
4964        }),
4965        (this.extendSelectionBy = function(e) {
4966          var t,
4967            n = this.editor,
4968            r = n.renderer.screenToTextCoordinates(this.x, this.y),
4969            i = n.selection[e](r.row, r.column)
4970          if (this.$clickSelection) {
4971            var s = this.$clickSelection.comparePoint(i.start),
4972              o = this.$clickSelection.comparePoint(i.end)
4973            if (s == -1 && o <= 0) {
4974              t = this.$clickSelection.end
4975              if (i.end.row != r.row || i.end.column != r.column) r = i.start
4976            } else if (o == 1 && s >= 0) {
4977              t = this.$clickSelection.start
4978              if (i.start.row != r.row || i.start.column != r.column) r = i.end
4979            } else if (s == -1 && o == 1) (r = i.end), (t = i.start)
4980            else {
4981              var u = l(this.$clickSelection, r)
4982              ;(r = u.cursor), (t = u.anchor)
4983            }
4984            n.selection.setSelectionAnchor(t.row, t.column)
4985          }
4986          n.selection.selectToPosition(r), n.renderer.scrollCursorIntoView()
4987        }),
4988        (this.selectEnd = this.selectAllEnd = this.selectByWordsEnd = this.selectByLinesEnd = function() {
4989          ;(this.$clickSelection = null),
4990            this.editor.unsetStyle('ace_selecting'),
4991            this.editor.renderer.scroller.releaseCapture && this.editor.renderer.scroller.releaseCapture()
4992        }),
4993        (this.focusWait = function() {
4994          var e = f(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y),
4995            t = Date.now()
4996          ;(e > o || t - this.mousedownEvent.time > this.$focusTimeout) &&
4997            this.startSelect(this.mousedownEvent.getDocumentPosition())
4998        }),
4999        (this.onDoubleClick = function(e) {
5000          var t = e.getDocumentPosition(),
5001            n = this.editor,
5002            r = n.session,
5003            i = r.getBracketRange(t)
5004          i
5005            ? (i.isEmpty() && (i.start.column--, i.end.column++), this.setState('select'))
5006            : ((i = n.selection.getWordRange(t.row, t.column)), this.setState('selectByWords')),
5007            (this.$clickSelection = i),
5008            this.select()
5009        }),
5010        (this.onTripleClick = function(e) {
5011          var t = e.getDocumentPosition(),
5012            n = this.editor
5013          this.setState('selectByLines')
5014          var r = n.getSelectionRange()
5015          r.isMultiLine() && r.contains(t.row, t.column)
5016            ? ((this.$clickSelection = n.selection.getLineRange(r.start.row)),
5017              (this.$clickSelection.end = n.selection.getLineRange(r.end.row).end))
5018            : (this.$clickSelection = n.selection.getLineRange(t.row)),
5019            this.select()
5020        }),
5021        (this.onQuadClick = function(e) {
5022          var t = this.editor
5023          t.selectAll(), (this.$clickSelection = t.getSelectionRange()), this.setState('selectAll')
5024        }),
5025        (this.onMouseWheel = function(e) {
5026          if (e.getAccelKey()) return
5027          e.getShiftKey() && e.wheelY && !e.wheelX && ((e.wheelX = e.wheelY), (e.wheelY = 0))
5028          var t = this.editor
5029          this.$lastScroll || (this.$lastScroll = { t: 0, vx: 0, vy: 0, allowed: 0 })
5030          var n = this.$lastScroll,
5031            r = e.domEvent.timeStamp,
5032            i = r - n.t,
5033            s = i ? e.wheelX / i : n.vx,
5034            o = i ? e.wheelY / i : n.vy
5035          i < u && ((s = (s + n.vx) / 2), (o = (o + n.vy) / 2))
5036          var a = Math.abs(s / o),
5037            f = !1
5038          a >= 1 && t.renderer.isScrollableBy(e.wheelX * e.speed, 0) && (f = !0),
5039            a <= 1 && t.renderer.isScrollableBy(0, e.wheelY * e.speed) && (f = !0)
5040          if (f) n.allowed = r
5041          else if (r - n.allowed < u) {
5042            var l = Math.abs(s) <= 1.1 * Math.abs(n.vx) && Math.abs(o) <= 1.1 * Math.abs(n.vy)
5043            l ? ((f = !0), (n.allowed = r)) : (n.allowed = 0)
5044          }
5045          ;(n.t = r), (n.vx = s), (n.vy = o)
5046          if (f) return t.renderer.scrollBy(e.wheelX * e.speed, e.wheelY * e.speed), e.stop()
5047        }),
5048        (this.onTouchMove = function(e) {
5049          this.editor._emit('mousewheel', e)
5050        })
5051    }.call(a.prototype),
5052      (t.DefaultHandlers = a))
5053  }),
5054  define('ace/tooltip', ['require', 'exports', 'module', 'ace/lib/oop', 'ace/lib/dom'], function(e, t, n) {
5055    'use strict'
5056    function s(e) {
5057      ;(this.isOpen = !1), (this.$element = null), (this.$parentNode = e)
5058    }
5059    var r = e('./lib/oop'),
5060      i = e('./lib/dom')
5061    ;(function() {
5062      ;(this.$init = function() {
5063        return (
5064          (this.$element = i.createElement('div')),
5065          (this.$element.className = 'ace_tooltip'),
5066          (this.$element.style.display = 'none'),
5067          this.$parentNode.appendChild(this.$element),
5068          this.$element
5069        )
5070      }),
5071        (this.getElement = function() {
5072          return this.$element || this.$init()
5073        }),
5074        (this.setText = function(e) {
5075          this.getElement().textContent = e
5076        }),
5077        (this.setHtml = function(e) {
5078          this.getElement().innerHTML = e
5079        }),
5080        (this.setPosition = function(e, t) {
5081          ;(this.getElement().style.left = e + 'px'), (this.getElement().style.top = t + 'px')
5082        }),
5083        (this.setClassName = function(e) {
5084          i.addCssClass(this.getElement(), e)
5085        }),
5086        (this.show = function(e, t, n) {
5087          e != null && this.setText(e),
5088            t != null && n != null && this.setPosition(t, n),
5089            this.isOpen || ((this.getElement().style.display = 'block'), (this.isOpen = !0))
5090        }),
5091        (this.hide = function() {
5092          this.isOpen && ((this.getElement().style.display = 'none'), (this.isOpen = !1))
5093        }),
5094        (this.getHeight = function() {
5095          return this.getElement().offsetHeight
5096        }),
5097        (this.getWidth = function() {
5098          return this.getElement().offsetWidth
5099        }),
5100        (this.destroy = function() {
5101          ;(this.isOpen = !1),
5102            this.$element && this.$element.parentNode && this.$element.parentNode.removeChild(this.$element)
5103        })
5104    }.call(s.prototype),
5105      (t.Tooltip = s))
5106  }),
5107  define('ace/mouse/default_gutter_handler', [
5108    'require',
5109    'exports',
5110    'module',
5111    'ace/lib/dom',
5112    'ace/lib/oop',
5113    'ace/lib/event',
5114    'ace/tooltip'
5115  ], function(e, t, n) {
5116    'use strict'
5117    function u(e) {
5118      function l() {
5119        var r = u.getDocumentPosition().row,
5120          s = n.$annotations[r]
5121        if (!s) return c()
5122        var o = t.session.getLength()
5123        if (r == o) {
5124          var a = t.renderer.pixelToScreenCoordinates(0, u.y).row,
5125            l = u.$pos
5126          if (a > t.session.documentToScreenRow(l.row, l.column)) return c()
5127        }
5128        if (f == s) return
5129        ;(f = s.text.join('<br/>')), i.setHtml(f), i.show(), t._signal('showGutterTooltip', i), t.on('mousewheel', c)
5130        if (e.$tooltipFollowsMouse) h(u)
5131        else {
5132          var p = u.domEvent.target,
5133            d = p.getBoundingClientRect(),
5134            v = i.getElement().style
5135          ;(v.left = d.right + 'px'), (v.top = d.bottom + 'px')
5136        }
5137      }
5138      function c() {
5139        o && (o = clearTimeout(o)),
5140          f && (i.hide(), (f = null), t._signal('hideGutterTooltip', i), t.removeEventListener('mousewheel', c))
5141      }
5142      function h(e) {
5143        i.setPosition(e.x, e.y)
5144      }
5145      var t = e.editor,
5146        n = t.renderer.$gutterLayer,
5147        i = new a(t.container)
5148      e.editor.setDefaultHandler('guttermousedown', function(r) {
5149        if (!t.isFocused() || r.getButton() != 0) return
5150        var i = n.getRegion(r)
5151        if (i == 'foldWidgets') return
5152        var s = r.getDocumentPosition().row,
5153          o = t.session.selection
5154        if (r.getShiftKey()) o.selectTo(s, 0)
5155        else {
5156          if (r.domEvent.detail == 2) return t.selectAll(), r.preventDefault()
5157          e.$clickSelection = t.selection.getLineRange(s)
5158        }
5159        return e.setState('selectByLines'), e.captureMouse(r), r.preventDefault()
5160      })
5161      var o, u, f
5162      e.editor.setDefaultHandler('guttermousemove', function(t) {
5163        var n = t.domEvent.target || t.domEvent.srcElement
5164        if (r.hasCssClass(n, 'ace_fold-widget')) return c()
5165        f && e.$tooltipFollowsMouse && h(t), (u = t)
5166        if (o) return
5167        o = setTimeout(function() {
5168          ;
5168(o = null), u && !e.isMousePressed ? l() : c()
5169        }, 50)
5170      }),
5171        s.addListener(t.renderer.$gutter, 'mouseout', function(e) {
5172          u = null
5173          if (!f || o) return
5174          o = setTimeout(function() {
5175            ;(o = null), c()
5176          }, 50)
5177        }),
5178        t.on('changeSession', c)
5179    }
5180    function a(e) {
5181      o.call(this, e)
5182    }
5183    var r = e('../lib/dom'),
5184      i = e('../lib/oop'),
5185      s = e('../lib/event'),
5186      o = e('../tooltip').Tooltip
5187    i.inherits(a, o),
5188      function() {
5189        this.setPosition = function(e, t) {
5190          var n = window.innerWidth || document.documentElement.clientWidth,
5191            r = window.innerHeight || document.documentElement.clientHeight,
5192            i = this.getWidth(),
5193            s = this.getHeight()
5194          ;(e += 15),
5195            (t += 15),
5196            e + i > n && (e -= e + i - n),
5197            t + s > r && (t -= 20 + s),
5198            o.prototype.setPosition.call(this, e, t)
5199        }
5200      }.call(a.prototype),
5201      (t.GutterHandler = u)
5202  }),
5203  define('ace/mouse/mouse_event', ['require', 'exports', 'module', 'ace/lib/event', 'ace/lib/useragent'], function(
5204    e,
5205    t,
5206    n
5207  ) {
5208    'use strict'
5209    var r = e('../lib/event'),
5210      i = e('../lib/useragent'),
5211      s = (t.MouseEvent = function(e, t) {
5212        ;(this.domEvent = e),
5213          (this.editor = t),
5214          (this.x = this.clientX = e.clientX),
5215          (this.y = this.clientY = e.clientY),
5216          (this.$pos = null),
5217          (this.$inSelection = null),
5218          (this.propagationStopped = !1),
5219          (this.defaultPrevented = !1)
5220      })
5221    ;(function() {
5222      ;(this.stopPropagation = function() {
5223        r.stopPropagation(this.domEvent), (this.propagationStopped = !0)
5224      }),
5225        (this.preventDefault = function() {
5226          r.preventDefault(this.domEvent), (this.defaultPrevented = !0)
5227        }),
5228        (this.stop = function() {
5229          this.stopPropagation(), this.preventDefault()
5230        }),
5231        (this.getDocumentPosition = function() {
5232          return this.$pos
5233            ? this.$pos
5234            : ((this.$pos = this.editor.renderer.screenToTextCoordinates(this.clientX, this.clientY)), this.$pos)
5235        }),
5236        (this.inSelection = function() {
5237          if (this.$inSelection !== null) return this.$inSelection
5238          var e = this.editor,
5239            t = e.getSelectionRange()
5240          if (t.isEmpty()) this.$inSelection = !1
5241          else {
5242            var n = this.getDocumentPosition()
5243            this.$inSelection = t.contains(n.row, n.column)
5244          }
5245          return this.$inSelection
5246        }),
5247        (this.getButton = function() {
5248          return r.getButton(this.domEvent)
5249        }),
5250        (this.getShiftKey = function() {
5251          return this.domEvent.shiftKey
5252        }),
5253        (this.getAccelKey = i.isMac
5254          ? function() {
5255              return this.domEvent.metaKey
5256            }
5257          : function() {
5258              return this.domEvent.ctrlKey
5259            })
5260    }.call(s.prototype))
5261  }),
5262  define('ace/mouse/dragdrop_handler', [
5263    'require',
5264    'exports',
5265    'module',
5266    'ace/lib/dom',
5267    'ace/lib/event',
5268    'ace/lib/useragent'
5269  ], function(e, t, n) {
5270    'use strict'
5271    function f(e) {
5272      function T(e, n) {
5273        var r = Date.now(),
5274          i = !n || e.row != n.row,
5275          s = !n || e.column != n.column
5276        if (!S || i || s) t.moveCursorToPosition(e), (S = r), (x = { x: p, y: d })
5277        else {
5278          var o = l(x.x, x.y, p, d)
5279          o > a ? (S = null) : r - S >= u && (t.renderer.scrollCursorIntoView(), (S = null))
5280        }
5281      }
5282      function N(e, n) {
5283        var r = Date.now(),
5284          i = t.renderer.layerConfig.lineHeight,
5285          s = t.renderer.layerConfig.characterWidth,
5286          u = t.renderer.scroller.getBoundingClientRect(),
5287          a = { x: { left: p - u.left, right: u.right - p }, y: { top: d - u.top, bottom: u.bottom - d } },
5288          f = Math.min(a.x.left, a.x.right),
5289          l = Math.min(a.y.top, a.y.bottom),
5290          c = { row: e.row, column: e.column }
5291        f / s <= 2 && (c.column += a.x.left < a.x.right ? -3 : 2),
5292          l / i <= 1 && (c.row += a.y.top < a.y.bottom ? -1 : 1)
5293        var h = e.row != c.row,
5294          v = e.column != c.column,
5295          m = !n || e.row != n.row
5296        h || (v && !m) ? (E ? r - E >= o && t.renderer.scrollCursorIntoView(c) : (E = r)) : (E = null)
5297      }
5298      function C() {
5299        var e = g
5300        ;(g = t.renderer.screenToTextCoordinates(p, d)), T(g, e), N(g, e)
5301      }
5302      function k() {
5303        ;(m = t.selection.toOrientedRange()),
5304          (h = t.session.addMarker(m, 'ace_selection', t.getSelectionStyle())),
5305          t.clearSelection(),
5306          t.isFocused() && t.renderer.$cursorLayer.setBlinking(!1),
5307          clearInterval(v),
5308          C(),
5309          (v = setInterval(C, 20)),
5310          (y = 0),
5311          i.addListener(document, 'mousemove', O)
5312      }
5313      function L() {
5314        clearInterval(v),
5315          t.session.removeMarker(h),
5316          (h = null),
5317          t.selection.fromOrientedRange(m),
5318          t.isFocused() && !w && t.renderer.$cursorLayer.setBlinking(!t.getReadOnly()),
5319          (m = null),
5320          (g = null),
5321          (y = 0),
5322          (E = null),
5323          (S = null),
5324          i.removeListener(document, 'mousemove', O)
5325      }
5326      function O() {
5327        A == null &&
5328          (A = setTimeout(function() {
5329            A != null && h && L()
5330          }, 20))
5331      }
5332      function M(e) {
5333        var t = e.types
5334        return (
5335          !t ||
5336          Array.prototype.some.call(t, function(e) {
5337            return e == 'text/plain' || e == 'Text'
5338          })
5339        )
5340      }
5341      function _(e) {
5342        var t = ['copy', 'copymove', 'all', 'uninitialized'],
5343          n = ['move', 'copymove', 'linkmove', 'all', 'uninitialized'],
5344          r = s.isMac ? e.altKey : e.ctrlKey,
5345          i = 'uninitialized'
5346        try {
5347          i = e.dataTransfer.effectAllowed.toLowerCase()
5348        } catch (e) {}
5349        var o = 'none'
5350        return (
5351          r && t.indexOf(i) >= 0 ? (o = 'copy') : n.indexOf(i) >= 0 ? (o = 'move') : t.indexOf(i) >= 0 && (o = 'copy'),
5352          o
5353        )
5354      }
5355      var t = e.editor,
5356        n = r.createElement('img')
5357      ;(n.src = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=='),
5358        s.isOpera &&
5359          (n.style.cssText = 'width:1px;height:1px;position:fixed;top:0;left:0;z-index:2147483647;opacity:0;')
5360      var f = ['dragWait', 'dragWaitEnd', 'startDrag', 'dragReadyEnd', 'onMouseDrag']
5361      f.forEach(function(t) {
5362        e[t] = this[t]
5363      }, this),
5364        t.addEventListener('mousedown', this.onMouseDown.bind(e))
5365      var c = t.container,
5366        h,
5367        p,
5368        d,
5369        v,
5370        m,
5371        g,
5372        y = 0,
5373        b,
5374        w,
5375        E,
5376        S,
5377        x
5378      ;(this.onDragStart = function(e) {
5379        if (this.cancelDrag || !c.draggable) {
5380          var r = this
5381          return (
5382            setTimeout(function() {
5383              r.startSelect(), r.captureMouse(e)
5384            }, 0),
5385            e.preventDefault()
5386          )
5387        }
5388        m = t.getSelectionRange()
5389        var i = e.dataTransfer
5390        ;(i.effectAllowed = t.getReadOnly() ? 'copy' : 'copyMove'),
5391          s.isOpera && (t.container.appendChild(n), (n.scrollTop = 0)),
5392          i.setDragImage && i.setDragImage(n, 0, 0),
5393          s.isOpera && t.container.removeChild(n),
5394          i.clearData(),
5395          i.setData('Text', t.session.getTextRange()),
5396          (w = !0),
5397          this.setState('drag')
5398      }),
5399        (this.onDragEnd = function(e) {
5400          ;(c.draggable = !1), (w = !1), this.setState(null)
5401          if (!t.getReadOnly()) {
5402            var n = e.dataTransfer.dropEffect
5403            !b && n == 'move' && t.session.remove(t.getSelectionRange()), t.renderer.$cursorLayer.setBlinking(!0)
5404          }
5405          this.editor.unsetStyle('ace_dragging'), this.editor.renderer.setCursorStyle('')
5406        }),
5407        (this.onDragEnter = function(e) {
5408          if (t.getReadOnly() || !M(e.dataTransfer)) return
5409          return (
5410            (p = e.clientX), (d = e.clientY), h || k(), y++, (e.dataTransfer.dropEffect = b = _(e)), i.preventDefault(e)
5411          )
5412        }),
5413        (this.onDragOver = function(e) {
5414          if (t.getReadOnly() || !M(e.dataTransfer)) return
5415          return (
5416            (p = e.clientX),
5417            (d = e.clientY),
5418            h || (k(), y++),
5419            A !== null && (A = null),
5420            (e.dataTransfer.dropEffect = b = _(e)),
5421            i.preventDefault(e)
5422          )
5423        }),
5424        (this.onDragLeave = function(e) {
5425          y--
5426          if (y <= 0 && h) return L(), (b = null), i.preventDefault(e)
5427        }),
5428        (this.onDrop = function(e) {
5429          if (!g) return
5430          var n = e.dataTransfer
5431          if (w)
5432            switch (b) {
5433              case 'move':
5434                m.contains(g.row, g.column) ? (m = { start: g, end: g }) : (m = t.moveText(m, g))
5435                break
5436              case 'copy':
5437                m = t.moveText(m, g, !0)
5438            }
5439          else {
5440            var r = n.getData('Text')
5441            ;(m = { start: g, end: t.session.insert(g, r) }), t.focus(), (b = null)
5442          }
5443          return L(), i.preventDefault(e)
5444        }),
5445        i.addListener(c, 'dragstart', this.onDragStart.bind(e)),
5446        i.addListener(c, 'dragend', this.onDragEnd.bind(e)),
5447        i.addListener(c, 'dragenter', this.onDragEnter.bind(e)),
5448        i.addListener(c, 'dragover', this.onDragOver.bind(e)),
5449        i.addListener(c, 'dragleave', this.onDragLeave.bind(e)),
5450        i.addListener(c, 'drop', this.onDrop.bind(e))
5451      var A = null
5452    }
5453    function l(e, t, n, r) {
5454      return Math.sqrt(Math.pow(n - e, 2) + Math.pow(r - t, 2))
5455    }
5456    var r = e('../lib/dom'),
5457      i = e('../lib/event'),
5458      s = e('../lib/useragent'),
5459      o = 200,
5460      u = 200,
5461      a = 5
5462    ;(function() {
5463      ;(this.dragWait = function() {
5464        var e = Date.now() - this.mousedownEvent.time
5465        e > this.editor.getDragDelay() && this.startDrag()
5466      }),
5467        (this.dragWaitEnd = function() {
5468          var e = this.editor.container
5469          ;(e.draggable = !1), this.startSelect(this.mousedownEvent.getDocumentPosition()), this.selectEnd()
5470        }),
5471        (this.dragReadyEnd = function(e) {
5472          this.editor.renderer.$cursorLayer.setBlinking(!this.editor.getReadOnly()),
5473            this.editor.unsetStyle('ace_dragging'),
5474            this.editor.renderer.setCursorStyle(''),
5475            this.dragWaitEnd()
5476        }),
5477        (this.startDrag = function() {
5478          this.cancelDrag = !1
5479          var e = this.editor,
5480            t = e.container
5481          ;(t.draggable = !0), e.renderer.$cursorLayer.setBlinking(!1), e.setStyle('ace_dragging')
5482          var n = s.isWin ? 'default' : 'move'
5483          e.renderer.setCursorStyle(n), this.setState('dragReady')
5484        }),
5485        (this.onMouseDrag = function(e) {
5486          var t = this.editor.container
5487          if (s.isIE && this.state == 'dragReady') {
5488            var n = l(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y)
5489            n > 3 && t.dragDrop()
5490          }
5491          if (this.state === 'dragWait') {
5492            var n = l(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y)
5493            n > 0 && ((t.draggable = !1), this.startSelect(this.mousedownEvent.getDocumentPosition()))
5494          }
5495        }),
5496        (this.onMouseDown = function(e) {
5497          if (!this.$dragEnabled) return
5498          this.mousedownEvent = e
5499          var t = this.editor,
5500            n = e.inSelection(),
5501            r = e.getButton(),
5502            i = e.domEvent.detail || 1
5503          if (i === 1 && r === 0 && n) {
5504            if (e.editor.inMultiSelectMode && (e.getAccelKey() || e.getShiftKey())) return
5505            this.mousedownEvent.time = Date.now()
5506            var o = e.domEvent.target || e.domEvent.srcElement
5507            'unselectable' in o && (o.unselectable = 'on')
5508            if (t.getDragDelay()) {
5509              if (s.isWebKit) {
5510                this.cancelDrag = !0
5511                var u = t.container
5512                u.draggable = !0
5513              }
5514              this.setState('dragWait')
5515            } else this.startDrag()
5516            this.captureMouse(e, this.onMouseDrag.bind(this)), (e.defaultPrevented = !0)
5517          }
5518        })
5519    }.call(f.prototype),
5520      (t.DragdropHandler = f))
5521  }),
5522  define('ace/lib/net', ['require', 'exports', 'module', 'ace/lib/dom'], function(e, t, n) {
5523    'use strict'
5524    var r = e('./dom')
5525    ;(t.get = function(e, t) {
5526      var n = new XMLHttpRequest()
5527      n.open('GET', e, !0),
5528        (n.onreadystatechange = function() {
5529          n.readyState === 4 && t(n.responseText)
5530        }),
5531        n.send(null)
5532    }),
5533      (t.loadScript = function(e, t) {
5534        var n = r.getDocumentHead(),
5535          i = document.createElement('script')
5536        ;(i.src = e),
5537          n.appendChild(i),
5538          (i.onload = i.onreadystatechange = function(e, n) {
5539            if (n || !i.readyState || i.readyState == 'loaded' || i.readyState == 'complete')
5540              (i = i.onload = i.onreadystatechange = null), n || t()
5541          })
5542      }),
5543      (t.qualifyURL = function(e) {
5544        var t = document.createElement('a')
5545        return (t.href = e), t.href
5546      })
5547  }),
5548  define('ace/lib/event_emitter', ['require', 'exports', 'module'], function(e, t, n) {
5549    'use strict'
5550    var r = {},
5551      i = function() {
5552        this.propagationStopped = !0
5553      },
5554      s = function() {
5555        this.defaultPrevented = !0
5556      }
5557    ;(r._emit = r._dispatchEvent = function(e, t) {
5558      this._eventRegistry || (this._eventRegistry = {}), this._defaultHandlers || (this._defaultHandlers = {})
5559      var n = this._eventRegistry[e] || [],
5560        r = this._defaultHandlers[e]
5561      if (!n.length && !r) return
5562      if (typeof t != 'object' || !t) t = {}
5563      t.type || (t.type = e),
5564        t.stopPropagation || (t.stopPropagation = i),
5565        t.preventDefault || (t.preventDefault = s),
5566        (n = n.slice())
5567      for (var o = 0; o < n.length; o++) {
5568        n[o](t, this)
5569        if (t.propagationStopped) break
5570      }
5571      if (r && !t.defaultPrevented) return r(t, this)
5572    }),
5573      (r._signal = function(e, t) {
5574        var n = (this._eventRegistry || {})[e]
5575        if (!n) return
5576        n = n.slice()
5577        for (var r = 0; r < n.length; r++) n[r](t, this)
5578      }),
5579      (r.once = function(e, t) {
5580        var n = this
5581        t &&
5582          this.addEventListener(e, function r() {
5583            n.removeEventListener(e, r), t.apply(null, arguments)
5584          })
5585      }),
5586      (r.setDefaultHandler = function(e, t) {
5587        var n = this._defaultHandlers
5588        n || (n = this._defaultHandlers = { _disabled_: {} })
5589        if (n[e]) {
5590          var r = n[e],
5591            i = n._disabled_[e]
5592          i || (n._disabled_[e] = i = []), i.push(r)
5593          var s = i.indexOf(t)
5594          s != -1 && i.splice(s, 1)
5595        }
5596        n[e] = t
5597      }),
5598      (r.removeDefaultHandler = function(e, t) {
5599        var n = this._defaultHandlers
5600        if (!n) return
5601        var r = n._disabled_[e]
5602        if (n[e] == t) {
5603          var i = n[e]
5604          r && this.setDefaultHandler(e, r.pop())
5605        } else if (r) {
5606          var s = r.indexOf(t)
5607          s != -1 && r.splice(s, 1)
5608        }
5609      }),
5610      (r.on = r.addEventListener = function(e, t, n) {
5611        this._eventRegistry = this._eventRegistry || {}
5612        var r = this._eventRegistry[e]
5613        return r || (r = this._eventRegistry[e] = []), r.indexOf(t) == -1 && r[n ? 'unshift' : 'push'](t), t
5614      }),
5615      (r.off = r.removeListener = r.removeEventListener = function(e, t) {
5616        this._eventRegistry = this._eventRegistry || {}
5617        var n = this._eventRegistry[e]
5618        if (!n) return
5619        var r = n.indexOf(t)
5620        r !== -1 && n.splice(r, 1)
5621      }),
5622      (r.removeAllListeners = function(e) {
5623        this._eventRegistry && (this._eventRegistry[e] = [])
5624      }),
5625      (t.EventEmitter = r)
5626  }),
5627  define('ace/lib/app_config', ['require', 'exports', 'module', 'ace/lib/oop', 'ace/lib/event_emitter'], function(
5628    e,
5629    t,
5630    n
5631  ) {
5632    'no use strict'
5633    function o(e) {
5634      typeof console != 'undefined' && console.warn && console.warn.apply(console, arguments)
5635    }
5636    function u(e, t) {
5637      var n = new Error(e)
5638      ;(n.data = t),
5639        typeof console == 'object' && console.error && console.error(n),
5640        setTimeout(function() {
5641          throw n
5642        })
5643    }
5644    var r = e('./oop'),
5645      i = e('./event_emitter').EventEmitter,
5646      s = {
5647        setOptions: function(e) {
5648          Object.keys(e).forEach(function(t) {
5649            this.setOption(t, e[t])
5650          }, this)
5651        },
5652        getOptions: function(e) {
5653          var t = {}
5654          if (!e) {
5655            var n = this.$options
5656            e = Object.keys(n).filter(function(e) {
5657              return !n[e].hidden
5658            })
5659          } else Array.isArray(e) || ((t = e), (e = Object.keys(t)))
5660          return (
5661            e.forEach(function(e) {
5662              t[e] = this.getOption(e)
5663            }, this),
5664            t
5665          )
5666        },
5667        setOption: function(e, t) {
5668          if (this['$' + e] === t) return
5669          var n = this.$options[e]
5670          if (!n) return o('misspelled option "' + e + '"')
5671          if (n.forwardTo) return this[n.forwardTo] && this[n.forwardTo].setOption(e, t)
5672          n.handlesSet || (this['$' + e] = t), n && n.set && n.set.call(this, t)
5673        },
5674        getOption: function(e) {
5675          var t = this.$options[e]
5676          return t
5677            ? t.forwardTo
5678              ? this[t.forwardTo] && this[t.forwardTo].getOption(e)
5679              : t && t.get
5680              ? t.get.call(this)
5681              : this['$' + e]
5682            : o('misspelled option "' + e + '"')
5683        }
5684      },
5685      a = function() {
5686        this.$defaultOptions = {}
5687      }
5688    ;(function() {
5689      r.implement(this, i),
5690        (this.defineOptions = function(e, t, n) {
5691          return (
5692            e.$options || (this.$defaultOptions[t] = e.$options = {}),
5693            Object.keys(n).forEach(function(t) {
5694              var r = n[t]
5695              typeof r == 'string' && (r = { forwardTo: r }),
5696                r.name || (r.name = t),
5697                (e.$options[r.name] = r),
5698                'initialValue' in r && (e['$' + r.name] = r.initialValue)
5699            }),
5700            r.implement(e, s),
5701            this
5702          )
5703        }),
5704        (this.resetOptions = function(e) {
5705          Object.keys(e.$options).forEach(function(t) {
5706            var n = e.$options[t]
5707            'value' in n && e.setOption(t, n.value)
5708          })
5709        }),
5710        (this.setDefaultValue = function(e, t, n) {
5711          var r = this.$defaultOptions[e] || (this.$defaultOptions[e] = {})
5712          r[t] && (r.forwardTo ? this.setDefaultValue(r.forwardTo, t, n) : (r[t].value = n))
5713        }),
5714        (this.setDefaultValues = function(e, t) {
5715          Object.keys(t).forEach(function(n) {
5716            this.setDefaultValue(e, n, t[n])
5717          }, this)
5718        }),
5719        (this.warn = o),
5720        (this.reportError = u)
5721    }.call(a.prototype),
5722      (t.AppConfig = a))
5723  }),
5724  define('ace/config', [
5725    'require',
5726    'exports',
5727    'module',
5728    'ace/lib/lang',
5729    'ace/lib/oop',
5730    'ace/lib/net',
5731    'ace/lib/app_config'
5732  ], function(e, t, n) {
5733    'no use strict'
5734    function f(r) {
5735      if (!u || !u.document) return
5736      a.packaged = r || e.packaged || n.packaged || (u.define && define.packaged)
5737      var i = {},
5738        s = '',
5739        o = document.currentScript || document._currentScript,
5740        f = (o && o.ownerDocument) || document,
5741        c = f.getElementsByTagName('script')
5742      for (var h = 0; h < c.length; h++) {
5743        var p = c[h],
5744          d = p.src || p.getAttribute('src')
5745        if (!d) continue
5746        var v = p.attributes
5747        for (var m = 0, g = v.length; m < g; m++) {
5748          var y = v[m]
5749          y.name.indexOf('data-ace-') === 0 && (i[l(y.name.replace(/^data-ace-/, ''))] = y.value)
5750        }
5751        var b = d.match(/^(.*)\/ace(\-\w+)?\.js(\?|$)/)
5752        b && (s = b[1])
5753      }
5754      s && ((i.base = i.base || s), (i.packaged = !0)),
5755        (i.basePath = i.base),
5756        (i.workerPath = i.workerPath || i.base),
5757        (i.modePath = i.modePath || i.base),
5758        (i.themePath = i.themePath || i.base),
5759        delete i.base
5760      for (var w in i) typeof i[w] != 'undefined' && t.set(w, i[w])
5761    }
5762    function l(e) {
5763      return e.replace(/-(.)/g, function(e, t) {
5764        return t.toUpperCase()
5765      })
5766    }
5767    var r = e('./lib/lang'),
5768      i = e('./lib/oop'),
5769      s = e('./lib/net'),
5770      o = e('./lib/app_config').AppConfig
5771    n.exports = t = new o()
5772    var u = (function() {
5773        return this || (typeof window != 'undefined' && window)
5774      })(),
5775      a = {
5776        packaged: !1,
5777        workerPath: null,
5778        modePath: null,
5779        themePath: null,
5780        basePath: '',
5781        suffix: '.js',
5782        $moduleUrls: {}
5783      }
5784    ;(t.get = function(e) {
5785      if (!a.hasOwnProperty(e)) throw new Error('Unknown config key: ' + e)
5786      return a[e]
5787    }),
5788      (t.set = function(e, t) {
5789        if (!a.hasOwnProperty(e)) throw new Error('Unknown config key: ' + e)
5790        a[e] = t
5791      }),
5792      (t.all = function() {
5793        return r.copyObject(a)
5794      }),
5795      (t.moduleUrl = function(e, t) {
5796        if (a.$moduleUrls[e]) return a.$moduleUrls[e]
5797        var n = e.split('/')
5798        t = t || n[n.length - 2] || ''
5799        var r = t == 'snippets' ? '/' : '-',
5800          i = n[n.length - 1]
5801        if (t == 'worker' && r == '-') {
5802          var s = new RegExp('^' + t + '[\\-_]|[\\-_]' + t + '$', 'g')
5803          i = i.replace(s, '')
5804        }
5805        ;(!i || i == t) && n.length > 1 && (i = n[n.length - 2])
5806        var o = a[t + 'Path']
5807        return (
5808          o == null ? (o = a.basePath) : r == '/' && (t = r = ''),
5809          o && o.slice(-1) != '/' && (o += '/'),
5810          o + t + r + i + this.get('suffix')
5811        )
5812      }),
5813      (t.setModuleUrl = function(e, t) {
5814        return (a.$moduleUrls[e] = t)
5815      }),
5816      (t.$loading = {}),
5817      (t.loadModule = function(n, r) {
5818        var i, o
5819        Array.isArray(n) && ((o = n[0]), (n = n[1]))
5820        try {
5821          i = e(n)
5822        } catch (u) {}
5823        if (i && !t.$loading[n]) return r && r(i)
5824        t.$loading[n] || (t.$loading[n] = []), t.$loading[n].push(r)
5825        if (t.$loading[n].length > 1) return
5826        var a = function() {
5827          e([n], function(e) {
5828            t._emit('load.module', { name: n, module: e })
5829            var r = t.$loading[n]
5830            ;(t.$loading[n] = null),
5831              r.forEach(function(t) {
5832                t && t(e)
5833              })
5834          })
5835        }
5836        if (!t.get('packaged')) return a()
5837        s.loadScript(t.moduleUrl(n, o), a)
5838      }),
5839      (t.init = f)
5840  }),
5841  define('ace/mouse/mouse_handler', [
5842    'require',
5843    'exports',
5844    'module',
5845    'ace/lib/event',
5846    'ace/lib/useragent',
5847    'ace/mouse/default_handlers',
5848    'ace/mouse/default_gutter_handler',
5849    'ace/mouse/mouse_event',
5850    'ace/mouse/dragdrop_handler',
5851    'ace/config'
5852  ], function(e, t, n) {
5853    'use strict'
5854    var r = e('../lib/event'),
5855      i = e('../lib/useragent'),
5856      s = e('./default_handlers').DefaultHandlers,
5857      o = e('./default_gutter_handler').GutterHandler,
5858      u = e('./mouse_event').MouseEvent,
5859      a = e('./dragdrop_handler').DragdropHandler,
5860      f = e('../config'),
5861      l = function(e) {
5862        var t = this
5863        ;(this.editor = e), new s(this), new o(this), new a(this)
5864        var n = function(t) {
5865            var n =
5866              !document.hasFocus ||
5867              !document.hasFocus() ||
5868              (!e.isFocused() && document.activeElement == (e.textInput && e.textInput.getElement()))
5869            n && window.focus(), e.focus()
5870          },
5871          u = e.renderer.getMouseEventTarget()
5872        r.addListener(u, 'click', this.onMouseEvent.bind(this, 'click')),
5873          r.addListener(u, 'mousemove', this.onMouseMove.bind(this, 'mousemove')),
5874          r.addMultiMouseDownListener(
5875            [
5876              u,
5877              e.renderer.scrollBarV && e.renderer.scrollBarV.inner,
5878              e.renderer.scrollBarH && e.renderer.scrollBarH.inner,
5879              e.textInput && e.textInput.getElement()
5880            ].filter(Boolean),
5881            [400, 300, 250],
5882            this,
5883            'onMouseEvent'
5884          ),
5885          r.addMouseWheelListener(e.container, this.onMouseWheel.bind(this, 'mousewheel')),
5886          r.addTouchMoveListener(e.container, this.onTouchMove.bind(this, 'touchmove'))
5887        var f = e.renderer.$gutter
5888        r.addListener(f, 'mousedown', this.onMouseEvent.bind(this, 'guttermousedown')),
5889          r.addListener(f, 'click', this.onMouseEvent.bind(this, 'gutterclick')),
5890          r.addListener(f, 'dblclick', this.onMouseEvent.bind(this, 'gutterdblclick')),
5891          r.addListener(f, 'mousemove', this.onMouseEvent.bind(this, 'guttermousemove')),
5892          r.addListener(u, 'mousedown', n),
5893          r.addListener(f, 'mousedown', n),
5894          i.isIE &&
5895            e.renderer.scrollBarV &&
5896            (r.addListener(e.renderer.scrollBarV.element, 'mousedown', n),
5897            r.addListener(e.renderer.scrollBarH.element, 'mousedown', n)),
5898          e.on('mousemove', function(n) {
5899            if (t.state || t.$dragDelay || !t.$dragEnabled) return
5900            var r = e.renderer.screenToTextCoordinates(n.x, n.y),
5901              i = e.session.selection.getRange(),
5902              s = e.renderer
5903            !i.isEmpty() && i.insideStart(r.row, r.column) ? s.setCursorStyle('default') : s.setCursorStyle('')
5904          })
5905      }
5906    ;(function() {
5907      ;(this.onMouseEvent = function(e, t) {
5908        this.editor._emit(e, new u(t, this.editor))
5909      }),
5910        (this.onMouseMove = function(e, t) {
5911          var n = this.editor._eventRegistry && this.editor._eventRegistry.mousemove
5912          if (!n || !n.length) return
5913          this.editor._emit(e, new u(t, this.editor))
5914        }),
5915        (this.onMouseWheel = function(e, t) {
5916          var n = new u(t, this.editor)
5917          ;(n.speed = this.$scrollSpeed * 2), (n.wheelX = t.wheelX), (n.wheelY = t.wheelY), this.editor._emit(e, n)
5918        }),
5919        (this.onTouchMove = function(e, t) {
5920          var n = new u(t, this.editor)
5921          ;(n.speed = 1), (n.wheelX = t.wheelX), (n.wheelY = t.wheelY), this.editor._emit(e, n)
5922        }),
5923        (this.setState = function(e) {
5924          this.state = e
5925        }),
5926        (this.captureMouse = function(e, t) {
5927          ;(this.x = e.x), (this.y = e.y), (this.isMousePressed = !0)
5928          var n = this.editor,
5929            s = this.editor.renderer
5930          s.$keepTextAreaAtCursor && (s.$keepTextAreaAtCursor = null)
5931          var o = this,
5932            a = function(e) {
5933              if (!e) return
5934              if (i.isWebKit && !e.which && o.releaseMouse) return o.releaseMouse()
5935              ;(o.x = e.clientX),
5936                (o.y = e.clientY),
5937                t && t(e),
5938                (o.mouseEvent = new u(e, o.editor)),
5939                (o.$mouseMoved = !0)
5940            },
5941            f = function(e) {
5942              n.off('beforeEndOperation', c),
5943                clearInterval(h),
5944                l(),
5945                o[o.state + 'End'] && o[o.state + 'End'](e),
5946                (o.state = ''),
5947                s.$keepTextAreaAtCursor == null && ((s.$keepTextAreaAtCursor = !0), s.$moveTextAreaToCursor()),
5948                (o.isMousePressed = !1),
5949                (o.$onCaptureMouseMove = o.releaseMouse = null),
5950                e && o.onMouseEvent('mouseup', e)
5951            },
5952            l = function() {
5953              o[o.state] && o[o.state](), (o.$mouseMoved = !1)
5954            }
5955          if (i.isOldIE && e.domEvent.type == 'dblclick')
5956            return setTimeout(function() {
5957              f(e)
5958            })
5959          var c = function(e) {
5960            n.curOp.command.name &&
5961              n.curOp.selectionChanged &&
5962              (o[o.state + 'End'] && o[o.state + 'End'](), (o.state = ''), o.releaseMouse())
5963          }
5964          n.on('beforeEndOperation', c),
5965            (o.$onCaptureMouseMove = a),
5966            (o.releaseMouse = r.capture(this.editor.container, a, f))
5967          var h = setInterval(l, 20)
5968        }),
5969        (this.releaseMouse = null),
5970        (this.cancelContextMenu = function() {
5971          var e = function(t) {
5972            if (t && t.domEvent && t.domEvent.type != 'contextmenu') return
5973            this.editor.off('nativecontextmenu', e), t && t.domEvent && r.stopEvent(t.domEvent)
5974          }.bind(this)
5975          setTimeout(e, 10), this.editor.on('nativecontextmenu', e)
5976        })
5977    }.call(l.prototype),
5978      f.defineOptions(l.prototype, 'mouseHandler', {
5979        scrollSpeed: { initialValue: 2 },
5980        dragDelay: { initialValue: i.isMac ? 150 : 0 },
5981        dragEnabled: { initialValue: !0 },
5982        focusTimeout: { initialValue: 0 },
5983        tooltipFollowsMouse: { initialValue: !0 }
5984      }),
5985      (t.MouseHandler = l))
5986  }),
5987  define('ace/mouse/fold_handler', ['require', 'exports', 'module', 'ace/lib/dom'], function(e, t, n) {
5988    'use strict'
5989    function i(e) {
5990      e.on('click', function(t) {
5991        var n = t.getDocumentPosition(),
5992          i = e.session,
5993          s = i.getFoldAt(n.row, n.column, 1)
5994        s && (t.getAccelKey() ? i.removeFold(s) : i.expandFold(s), t.stop())
5995        var o = t.domEvent && t.domEvent.target
5996        o &&
5997          r.hasCssClass(o, 'ace_inline_button') &&
5998          r.hasCssClass(o, 'ace_toggle_wrap') &&
5999          (i.setOption('wrap', !0), e.renderer.scrollCursorIntoView())
6000      }),
6001        e.on('gutterclick', function(t) {
6002          var n = e.renderer.$gutterLayer.getRegion(t)
6003          if (n == 'foldWidgets') {
6004            var r = t.getDocumentPosition().row,
6005              i = e.session
6006            i.foldWidgets && i.foldWidgets[r] && e.session.onFoldWidgetClick(r, t), e.isFocused() || e.focus(), t.stop()
6007          }
6008        }),
6009        e.on('gutterdblclick', function(t) {
6010          var n = e.renderer.$gutterLayer.getRegion(t)
6011          if (n == 'foldWidgets') {
6012            var r = t.getDocumentPosition().row,
6013              i = e.session,
6014              s = i.getParentFoldRangeData(r, !0),
6015              o = s.range || s.firstRange
6016            if (o) {
6017              r = o.start.row
6018              var u = i.getFoldAt(r, i.getLine(r).length, 1)
6019              u
6020                ? i.removeFold(u)
6021                : (i.addFold('...', o), e.renderer.scrollCursorIntoView({ row: o.start.row, column: 0 }))
6022            }
6023            t.stop()
6024          }
6025        })
6026    }
6027    var r = e('../lib/dom')
6028    t.FoldHandler = i
6029  }),
6030  define('ace/keyboard/keybinding', ['require', 'exports', 'module', 'ace/lib/keys', 'ace/lib/event'], function(
6031    e,
6032    t,
6033    n
6034  ) {
6035    'use strict'
6036    var r = e('../lib/keys'),
6037      i = e('../lib/event'),
6038      s = function(e) {
6039        ;(this.$editor = e), (this.$data = { editor: e }), (this.$handlers = []), this.setDefaultHandler(e.commands)
6040      }
6041    ;(function() {
6042      ;(this.setDefaultHandler = function(e) {
6043        this.removeKeyboardHandler(this.$defaultHandler), (this.$defaultHandler = e), this.addKeyboardHandler(e, 0)
6044      }),
6045        (this.setKeyboardHandler = function(e) {
6046          var t = this.$handlers
6047          if (t[t.length - 1] == e) return
6048          while (t[t.length - 1] && t[t.length - 1] != this.$defaultHandler) this.removeKeyboardHandler(t[t.length - 1])
6049          this.addKeyboardHandler(e, 1)
6050        }),
6051        (this.addKeyboardHandler = function(e, t) {
6052          if (!e) return
6053          typeof e == 'function' && !e.handleKeyboard && (e.handleKeyboard = e)
6054          var n = this.$handlers.indexOf(e)
6055          n != -1 && this.$handlers.splice(n, 1),
6056            t == undefined ? this.$handlers.push(e) : this.$handlers.splice(t, 0, e),
6057            n == -1 && e.attach && e.attach(this.$editor)
6058        }),
6059        (this.removeKeyboardHandler = function(e) {
6060          var t = this.$handlers.indexOf(e)
6061          return t == -1 ? !1 : (this.$handlers.splice(t, 1), e.detach && e.detach(this.$editor), !0)
6062        }),
6063        (this.getKeyboardHandler = function() {
6064          return this.$handlers[this.$handlers.length - 1]
6065        }),
6066        (this.getStatusText = function() {
6067          var e = this.$data,
6068            t = e.editor
6069          return this.$handlers
6070            .map(function(n) {
6071              return (n.getStatusText && n.getStatusText(t, e)) || ''
6072            })
6073            .filter(Boolean)
6074            .join(' ')
6075        }),
6076        (this.$callKeyboardHandlers = function(e, t, n, r) {
6077          var s,
6078            o = !1,
6079            u = this.$editor.commands
6080          for (var a = this.$handlers.length; a--; ) {
6081            s = this.$handlers[a].handleKeyboard(this.$data, e, t, n, r)
6082            if (!s || !s.command) continue
6083            s.command == 'null' ? (o = !0) : (o = u.exec(s.command, this.$editor, s.args, r)),
6084              o && r && e != -1 && s.passEvent != 1 && s.command.passEvent != 1 && i.stopEvent(r)
6085            if (o) break
6086          }
6087          return (
6088            !o && e == -1 && ((s = { command: 'insertstring' }), (o = u.exec('insertstring', this.$editor, t))),
6089            o && this.$editor._signal && this.$editor._signal('keyboardActivity', s),
6090            o
6091          )
6092        }),
6093        (this.onCommandKey = function(e, t, n) {
6094          var i = r.keyCodeToString(n)
6095          this.$callKeyboardHandlers(t, i, n, e)
6096        }),
6097        (this.onTextInput = function(e) {
6098          this.$callKeyboardHandlers(-1, e)
6099        })
6100    }.call(s.prototype),
6101      (t.KeyBinding = s))
6102  }),
6103  define('ace/lib/bidiutil', ['require', 'exports', 'module'], function(e, t, n) {
6104    'use strict'
6105    function F(e, t, n, r) {
6106      var i = s ? d : p,
6107        c = null,
6108        h = null,
6109        v = null,
6110        m = 0,
6111        g = null,
6112        y = null,
6113        b = -1,
6114        w = null,
6115        E = null,
6116        T = []
6117      if (!r) for (w = 0, r = []; w < n; w++) r[w] = R(e[w])
6118      ;(o = s), (u = !1), (a = !1), (f = !1), (l = !1)
6119      for (E = 0; E < n; E++) {
6120        ;(c = m), (T[E] = h = q(e, r, T, E)), (m = i[c][h]), (g = m & 240), (m &= 15), (t[E] = v = i[m][5])
6121        if (g > 0)
6122          if (g == 16) {
6123            for (w = b; w < E; w++) t[w] = 1
6124            b = -1
6125          } else b = -1
6126        y = i[m][6]
6127        if (y) b == -1 && (b = E)
6128        else if (b > -1) {
6129          for (w = b; w < E; w++) t[w] = v
6130          b = -1
6131        }
6132        r[E] == S && (t[E] = 0), (o |= v)
6133      }
6134      if (l)
6135        for (w = 0; w < n; w++)
6136          if (r[w] == x) {
6137            t[w] = s
6138            for (var C = w - 1; C >= 0; C--) {
6139              if (r[C] != N) break
6140              t[C] = s
6141            }
6142          }
6143    }
6144    function I(e, t, n) {
6145      if (o < e) return
6146      if (e == 1 && s == m && !f) {
6147        n.reverse()
6148        return
6149      }
6150      var r = n.length,
6151        i = 0,
6152        u,
6153        a,
6154        l,
6155        c
6156      while (i < r) {
6157        if (t[i] >= e) {
6158          u = i + 1
6159          while (u < r && t[u] >= e) u++
6160          for (a = i, l = u - 1; a < l; a++, l--) (c = n[a]), (n[a] = n[l]), (n[l] = c)
6161          i = u
6162        }
6163        i++
6164      }
6165    }
6166    function q(e, t, n, r) {
6167      var i = t[r],
6168        o,
6169        c,
6170        h,
6171        p
6172      switch (i) {
6173        case g:
6174        case y:
6175          u = !1
6176        case E:
6177        case w:
6178          return i
6179        case b:
6180          return u ? w : b
6181        case T:
6182          return (u = !0), (a = !0), y
6183        case N:
6184          return E
6185        case C:
6186          if (r < 1 || r + 1 >= t.length || ((o = n[r - 1]) != b && o != w) || ((c = t[r + 1]) != b && c != w)) return E
6187          return u && (c = w), c == o ? c : E
6188        case k:
6189          o = r > 0 ? n[r - 1] : S
6190          if (o == b && r + 1 < t.length && t[r + 1] == b) return b
6191          return E
6192        case L:
6193          if (r > 0 && n[r - 1] == b) return b
6194          if (u) return E
6195          ;(p = r + 1), (h = t.length)
6196          while (p < h && t[p] == L) p++
6197          if (p < h && t[p] == b) return b
6198          return E
6199        case A:
6200          ;(h = t.length), (p = r + 1)
6201          while (p < h && t[p] == A) p++
6202          if (p < h) {
6203            var d = e[r],
6204              v = (d >= 1425 && d <= 2303) || d == 64286
6205            o = t[p]
6206            if (v && (o == y || o == T)) return y
6207          }
6208          if (r < 1 || (o = t[r - 1]) == S) return E
6209          return n[r - 1]
6210        case S:
6211          return (u = !1), (f = !0), s
6212        case x:
6213          return (l = !0), E
6214        case O:
6215        case M:
6216        case D:
6217        case P:
6218        case _:
6219          u = !1
6220        case H:
6221          return E
6222      }
6223    }
6224    function R(e) {
6225      var t = e.charCodeAt(0),
6226        n = t >> 8
6227      return n == 0
6228        ? t > 191
6229          ? g
6230          : B[t]
6231        : n == 5
6232        ? /[\u0591-\u05f4]/.test(e)
6233          ? y
6234          : g
6235        : n == 6
6236        ? /[\u0610-\u061a\u064b-\u065f\u06d6-\u06e4\u06e7-\u06ed]/.test(e)
6237          ? A
6238          : /[\u0660-\u0669\u066b-\u066c]/.test(e)
6239          ? w
6240          : t == 1642
6241          ? L
6242          : /[\u06f0-\u06f9]/.test(e)
6243          ? b
6244          : T
6245        : n == 32 && t <= 8287
6246        ? j[t & 255]
6247        : n == 254
6248        ? t >= 65136
6249          ? T
6250          : E
6251        : E
6252    }
6253    function U(e) {
6254      return e >= '\u064b' && e <= '\u0655'
6255    }
6256    var r = ['\u0621', '\u0641'],
6257      i = ['\u063a', '\u064a'],
6258      s = 0,
6259      o = 0,
6260      u = !1,
6261      a = !1,
6262      f = !1,
6263      l = !1,
6264      c = !1,
6265      h = !1,
6266      p = [
6267        [0, 3, 0, 1, 0, 0, 0],
6268        [0, 3, 0, 1, 2, 2, 0],
6269        [0, 3, 0, 17, 2, 0, 1],
6270        [0, 3, 5, 5, 4, 1, 0],
6271        [0, 3, 21, 21, 4, 0, 1],
6272        [0, 3, 5, 5, 4, 2, 0]
6273      ],
6274      d = [
6275        [2, 0, 1, 1, 0, 1, 0],
6276        [2, 0, 1, 1, 0, 2, 0],
6277        [2, 0, 2, 1, 3, 2, 0],
6278        [2, 0, 2, 33, 3, 1, 1]
6279      ],
6280      v = 0,
6281      m = 1,
6282      g = 0,
6283      y = 1,
6284      b = 2,
6285      w = 3,
6286      E = 4,
6287      S = 5,
6288      x = 6,
6289      T = 7,
6290      N = 8,
6291      C = 9,
6292      k = 10,
6293      L = 11,
6294      A = 12,
6295      O = 13,
6296      M = 14,
6297      _ = 15,
6298      D = 16,
6299      P = 17,
6300      H = 18,
6301      B = [
6302        H,
6303        H,
6304        H,
6305        H,
6306        H,
6307        H,
6308        H,
6309        H,
6310        H,
6311        x,
6312        S,
6313        x,
6314        N,
6315        S,
6316        H,
6317        H,
6318        H,
6319        H,
6320        H,
6321        H,
6322        H,
6323        H,
6324        H,
6325        H,
6326        H,
6327        H,
6328        H,
6329        H,
6330        S,
6331        S,
6332        S,
6333        x,
6334        N,
6335        E,
6336        E,
6337        L,
6338        L,
6339        L,
6340        E,
6341        E,
6342        E,
6343        E,
6344        E,
6345        k,
6346        C,
6347        k,
6348        C,
6349        C,
6350        b,
6351        b,
6352        b,
6353        b,
6354        b,
6355        b,
6356        b,
6357        b,
6358        b,
6359        b,
6360        C,
6361        E,
6362        E,
6363        E,
6364        E,
6365        E,
6366        E,
6367        g,
6368        g,
6369        g,
6370        g,
6371        g,
6372        g,
6373        g,
6374        g,
6375        g,
6376        g,
6377        g,
6378        g,
6379        g,
6380        g,
6381        g,
6382        g,
6383        g,
6384        g,
6385        g,
6386        g,
6387        g,
6388        g,
6389        g,
6390        g,
6391        g,
6392        g,
6393        E,
6394        E,
6395        E,
6396        E,
6397        E,
6398        E,
6399        g,
6400        g,
6401        g,
6402        g,
6403        g,
6404        g,
6405        g,
6406        g,
6407        g,
6408        g,
6409        g,
6410        g,
6411        g,
6412        g,
6413        g,
6414        g,
6415        g,
6416        g,
6417        g,
6418        g,
6419        g,
6420        g,
6421        g,
6422        g,
6423        g,
6424        g,
6425        E,
6426        E,
6427        E,
6428        E,
6429        H,
6430        H,
6431        H,
6432        H,
6433        H,
6434        H,
6435        S,
6436        H,
6437        H,
6438        H,
6439        H,
6440        H,
6441        H,
6442        H,
6443        H,
6444        H,
6445        H,
6446        H,
6447        H,
6448        H,
6449        H,
6450        H,
6451        H,
6452        H,
6453        H,
6454        H,
6455        H,
6456        H,
6457        H,
6458        H,
6459        H,
6460        H,
6461        H,
6462        C,
6463        E,
6464        L,
6465        L,
6466        L,
6467        L,
6468        E,
6469        E,
6470        E,
6471        E,
6472        g,
6473        E,
6474        E,
6475        H,
6476        E,
6477        E,
6478        L,
6479        L,
6480        b,
6481        b,
6482        E,
6483        g,
6484        E,
6485        E,
6486        E,
6487        b,
6488        g,
6489        E,
6490        E,
6491        E,
6492        E,
6493        E
6494      ],
6495      j = [
6496        N,
6497        N,
6498        N,
6499        N,
6500        N,
6501        N,
6502        N,
6503        N,
6504        N,
6505        N,
6506        N,
6507        H,
6508        H,
6509        H,
6510        g,
6511        y,
6512        E,
6513        E,
6514        E,
6515        E,
6516        E,
6517        E,
6518        E,
6519        E,
6520        E,
6521        E,
6522        E,
6523        E,
6524        E,
6525        E,
6526        E,
6527        E,
6528        E,
6529        E,
6530        E,
6531        E,
6532        E,
6533        E,
6534        E,
6535        E,
6536        N,
6537        S,
6538        O,
6539        M,
6540        _,
6541        D,
6542        P,
6543        C,
6544        L,
6545        L,
6546        L,
6547        L,
6548        L,
6549        E,
6550        E,
6551        E,
6552        E,
6553        E,
6554        E,
6555        E,
6556        E,
6557        E,
6558        E,
6559        E,
6560        E,
6561        E,
6562        E,
6563        E,
6564        C,
6565        E,
6566        E,
6567        E,
6568        E,
6569        E,
6570        E,
6571        E,
6572        E,
6573        E,
6574        E,
6575        E,
6576        E,
6577        E,
6578        E,
6579        E,
6580        E,
6581        E,
6582        E,
6583        E,
6584        E,
6585        E,
6586        E,
6587        E,
6588        E,
6589        E,
6590        E,
6591        N
6592      ]
6593    ;(t.L = g),
6594      (t.R = y),
6595      (t.EN = b),
6596      (t.ON_R = 3),
6597      (t.AN = 4),
6598      (t.R_H = 5),
6599      (t.B = 6),
6600      (t.DOT = '\u00b7'),
6601      (t.doBidiReorder = function(e, n, r) {
6602        if (e.length < 2) return {}
6603        var i = e.split(''),
6604          o = new Array(i.length),
6605          u = new Array(i.length),
6606          a = []
6607        ;(s = r ? m : v), F(i, a, i.length, n)
6608        for (var f = 0; f < o.length; o[f] = f, f++);
6609        I(2, a, o), I(1, a, o)
6610        for (var f = 0; f < o.length - 1; f++)
6611          n[f] === w
6612            ? (a[f] = t.AN)
6613            : a[f] === y && ((n[f] > T && n[f] < O) || n[f] === E || n[f] === H)
6614            ? (a[f] = t.ON_R)
6615            : f > 0 &&
6616              i[f - 1] === '\u0644' &&
6617              /\u0622|\u0623|\u0625|\u0627/.test(i[f]) &&
6618              ((a[f - 1] = a[f] = t.R_H), f++)
6619        i[i.length - 1] === t.DOT && (a[i.length - 1] = t.B)
6620        for (var f = 0; f < o.length; f++) u[f] = a[o[f]]
6621        return { logicalFromVisual: o, bidiLevels: u }
6622      }),
6623      (t.hasBidiCharacters = function(e, t) {
6624        var n = !1
6625        for (var r = 0; r < e.length; r++) (t[r] = R(e.charAt(r))), !n && (t[r] == y || t[r] == T) && (n = !0)
6626        return n
6627      }),
6628      (t.getVisualFromLogicalIdx = function(e, t) {
6629        for (var n = 0; n < t.logicalFromVisual.length; n++) if (t.logicalFromVisual[n] == e) return n
6630        return 0
6631      })
6632  }),
6633  define('ace/bidihandler', [
6634    'require',
6635    'exports',
6636    'module',
6637    'ace/lib/bidiutil',
6638    'ace/lib/lang',
6639    'ace/lib/useragent'
6640  ], function(e, t, n) {
6641    'use strict'
6642    var r = e('./lib/bidiutil'),
6643      i = e('./lib/lang'),
6644      s = e('./lib/useragent'),
6645      o = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/,
6646      u = function(e) {
6647        ;(this.session = e),
6648          (this.bidiMap = {}),
6649          (this.currentRow = null),
6650          (this.bidiUtil = r),
6651          (this.charWidths = []),
6652          (this.EOL = '\u00ac'),
6653          (this.showInvisibles = !0),
6654          (this.isRtlDir = !1),
6655          (this.line = ''),
6656          (this.wrapIndent = 0),
6657          (this.isLastRow = !1),
6658          (this.EOF = '\u00b6'),
6659          (this.seenBidi = !1)
6660      }
6661    ;(function() {
6662      ;(this.isBidiRow = function(e, t, n) {
6663        return this.seenBidi
6664          ? (e !== this.currentRow && ((this.currentRow = e), this.updateRowLine(t, n), this.updateBidiMap()),
6665            this.bidiMap.bidiLevels)
6666          : !1
6667      }),
6668        (this.onChange = function(e) {
6669          this.seenBidi
6670            ? (this.currentRow = null)
6671            : e.action == 'insert' && o.test(e.lines.join('\n')) && ((this.seenBidi = !0), (this.currentRow = null))
6672        }),
6673        (this.getDocumentRow = function() {
6674          var e = 0,
6675            t = this.session.$screenRowCache
6676          if (t.length) {
6677            var n = this.session.$getRowCacheIndex(t, this.currentRow)
6678            n >= 0 && (e = this.session.$docRowCache[n])
6679          }
6680          return e
6681        }),
6682        (this.getSplitIndex = function() {
6683          var e = 0,
6684            t = this.session.$screenRowCache
6685          if (t.length) {
6686            var n,
6687              r = this.session.$getRowCacheIndex(t, this.currentRow)
6688            while (this.currentRow - e > 0) {
6689              n = this.session.$getRowCacheIndex(t, this.currentRow - e - 1)
6690              if (n !== r) break
6691              ;(r = n), e++
6692            }
6693          }
6694          return e
6695        }),
6696        (this.updateRowLine = function(e, t) {
6697          e === undefined && (e = this.getDocumentRow()),
6698            (this.wrapIndent = 0),
6699            (this.isLastRow = e === this.session.getLength() - 1),
6700            (this.line = this.session.getLine(e))
6701          if (this.session.$useWrapMode) {
6702            var n = this.session.$wrapData[e]
6703            n &&
6704              (t === undefined && (t = this.getSplitIndex()),
6705              t > 0 && n.length
6706                ? ((this.wrapIndent = n.indent),
6707                  (this.line =
6708                    t < n.length
6709                      ? this.line.substring(n[t - 1], n[n.length - 1])
6710                      : this.line.substring(n[n.length - 1])))
6711                : (this.line = this.line.substring(0, n[t])))
6712          }
6713          var s = this.session,
6714            o = 0,
6715            u
6716          this.line = this.line.replace(/\t|[\u1100-\u2029, \u202F-\uFFE6]/g, function(e, t) {
6717            return e === '	' || s.isFullWidth(e.charCodeAt(0))
6718              ? ((u = e === '	' ? s.getScreenTabSize(t + o) : 2), (o += u - 1), i.stringRepeat(r.DOT, u))
6719              : e
6720          })
6721        }),
6722        (this.updateBidiMap = function() {
6723          var e = [],
6724            t = this.isLastRow ? this.EOF : this.EOL,
6725            n = this.line + (this.showInvisibles ? t : r.DOT)
6726          r.hasBidiCharacters(n, e) ? (this.bidiMap = r.doBidiReorder(n, e, this.isRtlDir)) : (this.bidiMap = {})
6727        }),
6728        (this.markAsDirty = function() {
6729          this.currentRow = null
6730        }),
6731        (this.updateCharacterWidths = function(e) {
6732          if (!this.seenBidi) return
6733          if (this.characterWidth === e.$characterSize.width) return
6734          var t = (this.characterWidth = e.$characterSize.width),
6735            n = e.$measureCharWidth('\u05d4')
6736          ;(this.charWidths[r.L] = this.charWidths[r.EN] = this.charWidths[r.ON_R] = t),
6737            (this.charWidths[r.R] = this.charWidths[r.AN] = n),
6738            (this.charWidths[r.R_H] = s.isChrome ? n : n * 0.45),
6739            (this.charWidths[r.B] = 0),
6740            (this.currentRow = null)
6741        }),
6742        (this.getShowInvisibles = function() {
6743          return this.showInvisibles
6744        }),
6745        (this.setShowInvisibles = function(e) {
6746          ;(this.showInvisibles = e), (this.currentRow = null)
6747        }),
6748        (this.setEolChar = function(e) {
6749          this.EOL = e
6750        }),
6751        (this.setTextDir = function(e) {
6752          this.isRtlDir = e
6753        }),
6754        (this.getPosLeft = function(e) {
6755          e -= this.wrapIndent
6756          var t = r.getVisualFromLogicalIdx(e > 0 ? e - 1 : 0, this.bidiMap),
6757            n = this.bidiMap.bidiLevels,
6758            i = 0
6759          e === 0 && n[t] % 2 !== 0 && t++
6760          for (var s = 0; s < t; s++) i += this.charWidths[n[s]]
6761          return (
6762            e !== 0 && n[t] % 2 === 0 && (i += this.charWidths[n[t]]),
6763            this.wrapIndent && (i += this.wrapIndent * this.charWidths[r.L]),
6764            i
6765          )
6766        }),
6767        (this.getSelections = function(e, t) {
6768          var n = this.bidiMap,
6769            i = n.bidiLevels,
6770            s,
6771            o = this.wrapIndent * this.charWidths[r.L],
6772            u = [],
6773            a = Math.min(e, t) - this.wrapIndent,
6774            f = Math.max(e, t) - this.wrapIndent,
6775            l = !1,
6776            c = !1,
6777            h = 0
6778          for (var p, d = 0; d < i.length; d++)
6779            (p = n.logicalFromVisual[d]),
6780              (s = i[d]),
6781              (l = p >= a && p < f),
6782              l && !c ? (h = o) : !l && c && u.push({ left: h, width: o - h }),
6783              (o += this.charWidths[s]),
6784              (c = l)
6785          return l && d === i.length && u.push({ left: h, width: o - h }), u
6786        }),
6787        (this.offsetToCol = function(e) {
6788          var t = 0,
6789            e = Math.max(e, 0),
6790            n = 0,
6791            i = 0,
6792            s = this.bidiMap.bidiLevels,
6793            o = this.charWidths[s[i]]
6794          this.wrapIndent && (e -= this.wrapIndent * this.charWidths[r.L])
6795          while (e > n + o / 2) {
6796            n += o
6797            if (i === s.length - 1) {
6798              o = 0
6799              break
6800            }
6801            o = this.charWidths[s[++i]]
6802          }
6803          return (
6804            i > 0 && s[i - 1] % 2 !== 0 && s[i] % 2 === 0
6805              ? (e < n && i--, (t = this.bidiMap.logicalFromVisual[i]))
6806              : i > 0 && s[i - 1] % 2 === 0 && s[i] % 2 !== 0
6807              ? (t = 1 + (e > n ? this.bidiMap.logicalFromVisual[i] : this.bidiMap.logicalFromVisual[i - 1]))
6808              : (this.isRtlDir && i === s.length - 1 && o === 0 && s[i - 1] % 2 === 0) ||
6809                (!this.isRtlDir && i === 0 && s[i] % 2 !== 0)
6810              ? (t = 1 + this.bidiMap.logicalFromVisual[i])
6811              : (i > 0 && s[i - 1] % 2 !== 0 && o !== 0 && i--, (t = this.bidiMap.logicalFromVisual[i])),
6812            t + this.wrapIndent
6813          )
6814        })
6815    }.call(u.prototype),
6816      (t.BidiHandler = u))
6817  }),
6818  define('ace/selection', [
6819    'require',
6820    'exports',
6821    'module',
6822    'ace/lib/oop',
6823    'ace/lib/lang',
6824    'ace/lib/event_emitter',
6825    'ace/range'
6826  ], function(e, t, n) {
6827    'use strict'
6828    var r = e('./lib/oop'),
6829      i = e('./lib/lang'),
6830      s = e('./lib/event_emitter').EventEmitter,
6831      o = e('./range').Range,
6832      u = function(e) {
6833        ;(this.session = e),
6834          (this.doc = e.getDocument()),
6835          this.clearSelection(),
6836          (this.cursor = this.lead = this.doc.createAnchor(0, 0)),
6837          (this.anchor = this.doc.createAnchor(0, 0)),
6838          (this.$silent = !1)
6839        var t = this
6840        this.cursor.on('change', function(e) {
6841          ;(t.$cursorChanged = !0),
6842            t.$silent || t._emit('changeCursor'),
6843            !t.$isEmpty && !t.$silent && t._emit('changeSelection'),
6844            !t.$keepDesiredColumnOnChange && e.old.column != e.value.column && (t.$desiredColumn = null)
6845        }),
6846          this.anchor.on('change', function() {
6847            ;(t.$anchorChanged = !0), !t.$isEmpty && !t.$silent && t._emit('changeSelection')
6848          })
6849      }
6850    ;(function() {
6851      r.implement(this, s),
6852        (this.isEmpty = function() {
6853          return this.$isEmpty || (this.anchor.row == this.lead.row && this.anchor.column == this.lead.column)
6854        }),
6855        (this.isMultiLine = function() {
6856          return !this.$isEmpty && this.anchor.row != this.cursor.row
6857        }),
6858        (this.getCursor = function() {
6859          return this.lead.getPosition()
6860        }),
6861        (this.setSelectionAnchor = function(e, t) {
6862          ;(this.$isEmpty = !1), this.anchor.setPosition(e, t)
6863        }),
6864        (this.getAnchor = this.getSelectionAnchor = function() {
6865          return this.$isEmpty ? this.getSelectionLead() : this.anchor.getPosition()
6866        }),
6867        (this.getSelectionLead = function() {
6868          return this.lead.getPosition()
6869        }),
6870        (this.isBackwards = function() {
6871          var e = this.anchor,
6872            t = this.lead
6873          return e.row > t.row || (e.row == t.row && e.column > t.column)
6874        }),
6875        (this.getRange = function() {
6876          var e = this.anchor,
6877            t = this.lead
6878          return this.$isEmpty ? o.fromPoints(t, t) : this.isBackwards() ? o.fromPoints(t, e) : o.fromPoints(e, t)
6879        }),
6880        (this.clearSelection = function() {
6881          this.$isEmpty || ((this.$isEmpty = !0), this._emit('changeSelection'))
6882        }),
6883        (this.selectAll = function() {
6884          this.$setSelection(0, 0, Number.MAX_VALUE, Number.MAX_VALUE)
6885        }),
6886        (this.setRange = this.setSelectionRange = function(e, t) {
6887          var n = t ? e.end : e.start,
6888            r = t ? e.start : e.end
6889          this.$setSelection(n.row, n.column, r.row, r.column)
6890        }),
6891        (this.$setSelection = function(e, t, n, r) {
6892          var i = this.$isEmpty,
6893            s = this.inMultiSelectMode
6894          ;(this.$silent = !0),
6895            (this.$cursorChanged = this.$anchorChanged = !1),
6896            this.anchor.setPosition(e, t),
6897            this.cursor.setPosition(n, r),
6898            (this.$isEmpty = !o.comparePoints(this.anchor, this.cursor)),
6899            (this.$silent = !1),
6900            this.$cursorChanged && this._emit('changeCursor'),
6901            (this.$cursorChanged || this.$anchorChanged || i != this.$isEmpty || s) && this._emit('changeSelection')
6902        }),
6903        (this.$moveSelection = function(e) {
6904          var t = this.lead
6905          this.$isEmpty && this.setSelectionAnchor(t.row, t.column), e.call(this)
6906        }),
6907        (this.selectTo = function(e, t) {
6908          this.$moveSelection(function() {
6909            this.moveCursorTo(e, t)
6910          })
6911        }),
6912        (this.selectToPosition = function(e) {
6913          this.$moveSelection(function() {
6914            this.moveCursorToPosition(e)
6915          })
6916        }),
6917        (this.moveTo = function(e, t) {
6918          this.clearSelection(), this.moveCursorTo(e, t)
6919        }),
6920        (this.moveToPosition = function(e) {
6921          this.clearSelection(), this.moveCursorToPosition(e)
6922        }),
6923        (this.selectUp = function() {
6924          this.$moveSelection(this.moveCursorUp)
6925        }),
6926        (this.selectDown = function() {
6927          this.$moveSelection(this.moveCursorDown)
6928        }),
6929        (this.selectRight = function() {
6930          this.$moveSelection(this.moveCursorRight)
6931        }),
6932        (this.selectLeft = function() {
6933          this.$moveSelection(this.moveCursorLeft)
6934        }),
6935        (this.selectLineStart = function() {
6936          this.$moveSelection(this.moveCursorLineStart)
6937        }),
6938        (this.selectLineEnd = function() {
6939          this.$moveSelection(this.moveCursorLineEnd)
6940        }),
6941        (this.selectFileEnd = function() {
6942          this.$moveSelection(this.moveCursorFileEnd)
6943        }),
6944        (this.selectFileStart = function() {
6945          this.$moveSelection(this.moveCursorFileStart)
6946        }),
6947        (this.selectWordRight = function() {
6948          this.$moveSelection(this.moveCursorWordRight)
6949        }),
6950        (this.selectWordLeft = function() {
6951          this.$moveSelection(this.moveCursorWordLeft)
6952        }),
6953        (this.getWordRange = function(e, t) {
6954          if (typeof t == 'undefined') {
6955            var n = e || this.lead
6956            ;(e = n.row), (t = n.column)
6957          }
6958          return this.session.getWordRange(e, t)
6959        }),
6960        (this.selectWord = function() {
6961          this.setSelectionRange(this.getWordRange())
6962        }),
6963        (this.selectAWord = function() {
6964          var e = this.getCursor(),
6965            t = this.session.getAWordRange(e.row, e.column)
6966          this.setSelectionRange(t)
6967        }),
6968        (this.getLineRange = function(e, t) {
6969          var n = typeof e == 'number' ? e : this.lead.row,
6970            r,
6971            i = this.session.getFoldLine(n)
6972          return (
6973            i ? ((n = i.start.row), (r = i.end.row)) : (r = n),
6974            t === !0 ? new o(n, 0, r, this.session.getLine(r).length) : new o(n, 0, r + 1, 0)
6975          )
6976        }),
6977        (this.selectLine = function() {
6978          this.setSelectionRange(this.getLineRange())
6979        }),
6980        (this.moveCursorUp = function() {
6981          this.moveCursorBy(-1, 0)
6982        }),
6983        (this.moveCursorDown = function() {
6984          this.moveCursorBy(1, 0)
6985        }),
6986        (this.wouldMoveIntoSoftTab = function(e, t, n) {
6987          var r = e.column,
6988            i = e.column + t
6989          return (
6990            n < 0 && ((r = e.column - t), (i = e.column)),
6991            this.session.isTabStop(e) &&
6992              this.doc
6993                .getLine(e.row)
6994                .slice(r, i)
6995                .split(' ').length -
6996                1 ==
6997                t
6998          )
6999        }),
7000        (this.moveCursorLeft = function() {
7001          var e = this.lead.getPosition(),
7002            t
7003          if ((t = this.session.getFoldAt(e.row, e.column, -1))) this.moveCursorTo(t.start.row, t.start.column)
7004          else if (e.column === 0) e.row > 0 && this.moveCursorTo(e.row - 1, this.doc.getLine(e.row - 1).length)
7005          else {
7006            var n = this.session.getTabSize()
7007            this.wouldMoveIntoSoftTab(e, n, -1) && !this.session.getNavigateWithinSoftTabs()
7008              ? this.moveCursorBy(0, -n)
7009              : this.moveCursorBy(0, -1)
7010          }
7011        }),
7012        (this.moveCursorRight = function() {
7013          var e = this.lead.getPosition(),
7014            t
7015          if ((t = this.session.getFoldAt(e.row, e.column, 1))) this.moveCursorTo(t.end.row, t.end.column)
7016          else if (this.lead.column == this.doc.getLine(this.lead.row).length)
7017            this.lead.row < this.doc.getLength() - 1 && this.moveCursorTo(this.lead.row + 1, 0)
7018          else {
7019            var n = this.session.getTabSize(),
7020              e = this.lead
7021            this.wouldMoveIntoSoftTab(e, n, 1) && !this.session.getNavigateWithinSoftTabs()
7022              ? this.moveCursorBy(0, n)
7023              : this.moveCursorBy(0, 1)
7024          }
7025        }),
7026        (this.moveCursorLineStart = function() {
7027          var e = this.lead.row,
7028            t = this.lead.column,
7029            n = this.session.documentToScreenRow(e, t),
7030            r = this.session.screenToDocumentPosition(n, 0),
7031            i = this.session.getDisplayLine(e, null, r.row, r.column),
7032            s = i.match(/^\s*/)
7033          s[0].length != t && !this.session.$useEmacsStyleLineStart && (r.column += s[0].length),
7034            this.moveCursorToPosition(r)
7035        }),
7036        (this.moveCursorLineEnd = function() {
7037          var e = this.lead,
7038            t = this.session.getDocumentLastRowColumnPosition(e.row, e.column)
7039          if (this.lead.column == t.column) {
7040            var n = this.session.getLine(t.row)
7041            if (t.column == n.length) {
7042              var r = n.search(/\s+$/)
7043              r > 0 && (t.column = r)
7044            }
7045          }
7046          this.moveCursorTo(t.row, t.column)
7047        }),
7048        (this.moveCursorFileEnd = function() {
7049          var e = this.doc.getLength() - 1,
7050            t = this.doc.getLine(e).length
7051          this.moveCursorTo(e, t)
7052        }),
7053        (this.moveCursorFileStart = function() {
7054          this.moveCursorTo(0, 0)
7055        }),
7056        (this.moveCursorLongWordRight = function() {
7057          var e = this.lead.row,
7058            t = this.lead.column,
7059            n = this.doc.getLine(e),
7060            r = n.substring(t)
7061          ;(this.session.nonTokenRe.lastIndex = 0), (this.session.tokenRe.lastIndex = 0)
7062          var i = this.session.getFoldAt(e, t, 1)
7063          if (i) {
7064            this.moveCursorTo(i.end.row, i.end.column)
7065            return
7066          }
7067          this.session.nonTokenRe.exec(r) &&
7068            ((t += this.session.nonTokenRe.lastIndex), (this.session.nonTokenRe.lastIndex = 0), (r = n.substring(t)))
7069          if (t >= n.length) {
7070            this.moveCursorTo(e, n.length),
7071              this.moveCursorRight(),
7072              e < this.doc.getLength() - 1 && this.moveCursorWordRight()
7073            return
7074          }
7075          this.session.tokenRe.exec(r) && ((t += this.session.tokenRe.lastIndex), (this.session.tokenRe.lastIndex = 0)),
7076            this.moveCursorTo(e, t)
7077        }),
7078        (this.moveCursorLongWordLeft = function() {
7079          var e = this.lead.row,
7080            t = this.lead.column,
7081            n
7082          if ((n = this.session.getFoldAt(e, t, -1))) {
7083            this.moveCursorTo(n.start.row, n.start.column)
7084            return
7085          }
7086          var r = this.session.getFoldStringAt(e, t, -1)
7087          r == null && (r = this.doc.getLine(e).substring(0, t))
7088          var s = i.stringReverse(r)
7089          ;(this.session.nonTokenRe.lastIndex = 0),
7090            (this.session.tokenRe.lastIndex = 0),
7091            this.session.nonTokenRe.exec(s) &&
7092              ((t -= this.session.nonTokenRe.lastIndex),
7093              (s = s.slice(this.session.nonTokenRe.lastIndex)),
7094              (this.session.nonTokenRe.lastIndex = 0))
7095          if (t <= 0) {
7096            this.moveCursorTo(e, 0), this.moveCursorLeft(), e > 0 && this.moveCursorWordLeft()
7097            return
7098          }
7099          this.session.tokenRe.exec(s) && ((t -= this.session.tokenRe.lastIndex), (this.session.tokenRe.lastIndex = 0)),
7100            this.moveCursorTo(e, t)
7101        }),
7102        (this.$shortWordEndIndex = function(e) {
7103          var t = 0,
7104            n,
7105            r = /\s/,
7106            i = this.session.tokenRe
7107          i.lastIndex = 0
7108          if (this.session.tokenRe.exec(e)) t = this.session.tokenRe.lastIndex
7109          else {
7110            while ((n = e[t]) && r.test(n)) t++
7111            if (t < 1) {
7112              i.lastIndex = 0
7113              while ((n = e[t]) && !i.test(n)) {
7114                ;(i.lastIndex = 0), t++
7115                if (r.test(n)) {
7116                  if (t > 2) {
7117                    t--
7118                    break
7119                  }
7120                  while ((n = e[t]) && r.test(n)) t++
7121                  if (t > 2) break
7122                }
7123              }
7124            }
7125          }
7126          return (i.lastIndex = 0), t
7127        }),
7128        (this.moveCursorShortWordRight = function() {
7129          var e = this.lead.row,
7130            t = this.lead.column,
7131            n = this.doc.getLine(e),
7132            r = n.substring(t),
7133            i = this.session.getFoldAt(e, t, 1)
7134          if (i) return this.moveCursorTo(i.end.row, i.end.column)
7135          if (t == n.length) {
7136            var s = this.doc.getLength()
7137            do e++, (r = this.doc.getLine(e))
7138            while (e < s && /^\s*$/.test(r))
7139            ;/^\s+/.test(r) || (r = ''), (t = 0)
7140          }
7141          var o = this.$shortWordEndIndex(r)
7142          this.moveCursorTo(e, t + o)
7143        }),
7144        (this.moveCursorShortWordLeft = function() {
7145          var e = this.lead.row,
7146            t = this.lead.column,
7147            n
7148          if ((n = this.session.getFoldAt(e, t, -1))) return this.moveCursorTo(n.start.row, n.start.column)
7149          var r = this.session.getLine(e).substring(0, t)
7150          if (t === 0) {
7151            do e--, (r = this.doc.getLine(e))
7152            while (e > 0 && /^\s*$/.test(r))
7153            ;(t = r.length), /\s+$/.test(r) || (r = '')
7154          }
7155          var s = i.stringReverse(r),
7156            o = this.$shortWordEndIndex(s)
7157          return this.moveCursorTo(e, t - o)
7158        }),
7159        (this.moveCursorWordRight = function() {
7160          this.session.$selectLongWords ? this.moveCursorLongWordRight() : this.moveCursorShortWordRight()
7161        }),
7162        (this.moveCursorWordLeft = function() {
7163          this.session.$selectLongWords ? this.moveCursorLongWordLeft() : this.moveCursorShortWordLeft()
7164        }),
7165        (this.moveCursorBy = function(e, t) {
7166          var n = this.session.documentToScreenPosition(this.lead.row, this.lead.column),
7167            r
7168          t === 0 &&
7169            (e !== 0 &&
7170              (this.session.$bidiHandler.isBidiRow(n.row, this.lead.row)
7171                ? ((r = this.session.$bidiHandler.getPosLeft(n.column)),
7172                  (n.column = Math.round(r / this.session.$bidiHandler.charWidths[0])))
7173                : (r = n.column * this.session.$bidiHandler.charWidths[0])),
7174            this.$desiredColumn ? (n.column = this.$desiredColumn) : (this.$desiredColumn = n.column))
7175          var i = this.session.screenToDocumentPosition(n.row + e, n.column, r)
7176          e !== 0 &&
7177            t === 0 &&
7178            i.row === this.lead.row &&
7179            i.column === this.lead.column &&
7180            this.session.lineWidgets &&
7181            this.session.lineWidgets[i.row] &&
7182            (i.row > 0 || e > 0) &&
7183            i.row++,
7184            this.moveCursorTo(i.row, i.column + t, t === 0)
7185        }),
7186        (this.moveCursorToPosition = function(e) {
7187          this.moveCursorTo(e.row, e.column)
7188        }),
7189        (this.moveCursorTo = function(e, t, n) {
7190          var r = this.session.getFoldAt(e, t, 1)
7191          r && ((e = r.start.row), (t = r.start.column)), (this.$keepDesiredColumnOnChange = !0)
7192          var i = this.session.getLine(e)
7193          ;/[\uDC00-\uDFFF]/.test(i.charAt(t)) &&
7194            i.charAt(t - 1) &&
7195            (this.lead.row == e && this.lead.column == t + 1 ? (t -= 1) : (t += 1)),
7196            this.lead.setPosition(e, t),
7197            (this.$keepDesiredColumnOnChange = !1),
7198            n || (this.$desiredColumn = null)
7199        }),
7200        (this.moveCursorToScreen = function(e, t, n) {
7201          var r = this.session.screenToDocumentPosition(e, t)
7202          this.moveCursorTo(r.row, r.column, n)
7203        }),
7204        (this.detach = function() {
7205          this.lead.detach(), this.anchor.detach(), (this.session = this.doc = null)
7206        }),
7207        (this.fromOrientedRange = function(e) {
7208          this.setSelectionRange(e, e.cursor == e.start), (this.$desiredColumn = e.desiredColumn || this.$desiredColumn)
7209        }),
7210        (this.toOrientedRange = function(e) {
7211          var t = this.getRange()
7212          return (
7213            e
7214              ? ((e.start.column = t.start.column),
7215                (e.start.row = t.start.row),
7216                (e.end.column = t.end.column),
7217                (e.end.row = t.end.row))
7218              : (e = t),
7219            (e.cursor = this.isBackwards() ? e.start : e.end),
7220            (e.desiredColumn = this.$desiredColumn),
7221            e
7222          )
7223        }),
7224        (this.getRangeOfMovements = function(e) {
7225          var t = this.getCursor()
7226          try {
7227            e(this)
7228            var n = this.getCursor()
7229            return o.fromPoints(t, n)
7230          } catch (r) {
7231            return o.fromPoints(t, t)
7232          } finally {
7233            this.moveCursorToPosition(t)
7234          }
7235        }),
7236        (this.toJSON = function() {
7237          if (this.rangeCount)
7238            var e = this.ranges.map(function(e) {
7239              var t = e.clone()
7240              return (t.isBackwards = e.cursor == e.start), t
7241            })
7242          else {
7243            var e = this.getRange()
7244            e.isBackwards = this.isBackwards()
7245          }
7246          return e
7247        }),
7248        (this.fromJSON = function(e) {
7249          if (e.start == undefined) {
7250            if (this.rangeList) {
7251              this.toSingleRange(e[0])
7252              for (var t = e.length; t--; ) {
7253                var n = o.fromPoints(e[t].start, e[t].end)
7254                e[t].isBackwards && (n.cursor = n.start), this.addRange(n, !0)
7255              }
7256              return
7257            }
7258            e = e[0]
7259          }
7260          this.rangeList && this.toSingleRange(e), this.setSelectionRange(e, e.isBackwards)
7261        }),
7262        (this.isEqual = function(e) {
7263          if ((e.length || this.rangeCount) && e.length != this.rangeCount) return !1
7264          if (!e.length || !this.ranges) return this.getRange().isEqual(e)
7265          for (var t = this.ranges.length; t--; ) if (!this.ranges[t].isEqual(e[t])) return !1
7266          return !0
7267        })
7268    }.call(u.prototype),
7269      (t.Selection = u))
7270  }),
7271  define('ace/tokenizer', ['require', 'exports', 'module', 'ace/config'], function(e, t, n) {
7272    'use strict'
7273    var r = e('./config'),
7274      i = 2e3,
7275      s = function(e) {
7276        ;(this.states = e), (this.regExps = {}), (this.matchMappings = {})
7277        for (var t in this.states) {
7278          var n = this.states[t],
7279            r = [],
7280            i = 0,
7281            s = (this.matchMappings[t] = { defaultToken: 'text' }),
7282            o = 'g',
7283            u = []
7284          for (var a = 0; a < n.length; a++) {
7285            var f = n[a]
7286            f.defaultToken && (s.defaultToken = f.defaultToken), f.caseInsensitive && (o = 'gi')
7287            if (f.regex == null) continue
7288            f.regex instanceof RegExp && (f.regex = f.regex.toString().slice(1, -1))
7289            var l = f.regex,
7290              c = new RegExp('(?:(' + l + ')|(.))').exec('a').length - 2
7291            Array.isArray(f.token)
7292              ? f.token.length == 1 || c == 1
7293                ? (f.token = f.token[0])
7294                : c - 1 != f.token.length
7295                ? (this.reportError("number of classes and regexp groups doesn't match", {
7296                    rule: f,
7297                    groupCount: c - 1
7298                  }),
7299                  (f.token = f.token[0]))
7300                : ((f.tokenArray = f.token), (f.token = null), (f.onMatch = this.$arrayTokens))
7301              : typeof f.token == 'function' &&
7302                !f.onMatch &&
7303                (c > 1 ? (f.onMatch = this.$applyToken) : (f.onMatch = f.token)),
7304              c > 1 &&
7305                (/\\\d/.test(f.regex)
7306                  ? (l = f.regex.replace(/\\([0-9]+)/g, function(e, t) {
7307                      return '\\' + (parseInt(t, 10) + i + 1)
7308                    }))
7309                  : ((c = 1), (l = this.removeCapturingGroups(f.regex))),
7310                !f.splitRegex && typeof f.token != 'string' && u.push(f)),
7311              (s[i] = a),
7312              (i += c),
7313              r.push(l),
7314              f.onMatch || (f.onMatch = null)
7315          }
7316          r.length || ((s[0] = 0), r.push('$')),
7317            u.forEach(function(e) {
7318              e.splitRegex = this.createSplitterRegexp(e.regex, o)
7319            }, this),
7320            (this.regExps[t] = new RegExp('(' + r.join(')|(') + ')|($)', o))
7321        }
7322      }
7323    ;(function() {
7324      ;(this.$setMaxTokenCount = function(e) {
7325        i = e | 0
7326      }),
7327        (this.$applyToken = function(e) {
7328          var t = this.splitRegex.exec(e).slice(1),
7329            n = this.token.apply(this, t)
7330          if (typeof n == 'string') return [{ type: n, value: e }]
7331          var r = []
7332          for (var i = 0, s = n.length; i < s; i++) t[i] && (r[r.length] = { type: n[i], value: t[i] })
7333          return r
7334        }),
7335        (this.$arrayTokens = function(e) {
7336          if (!e) return []
7337          var t = this.splitRegex.exec(e)
7338          if (!t) return 'text'
7339          var n = [],
7340            r = this.tokenArray
7341          for (var i = 0, s = r.length; i < s; i++) t[i + 1] && (n[n.length] = { type: r[i], value: t[i + 1] })
7342          return n
7343        }),
7344        (this.removeCapturingGroups = function(e) {
7345          var t = e.replace(/\[(?:\\.|[^\]])*?\]|\\.|\(\?[:=!]|(\()/g, function(e, t) {
7346            return t ? '(?:' : e
7347          })
7348          return t
7349        }),
7350        (this.createSplitterRegexp = function(e, t) {
7351          if (e.indexOf('(?=') != -1) {
7352            var n = 0,
7353              r = !1,
7354              i = {}
7355            e.replace(/(\\.)|(\((?:\?[=!])?)|(\))|([\[\]])/g, function(e, t, s, o, u, a) {
7356              return (
7357                r
7358                  ? (r = u != ']')
7359                  : u
7360                  ? (r = !0)
7361                  : o
7362                  ? (n == i.stack && ((i.end = a + 1), (i.stack = -1)), n--)
7363                  : s && (n++, s.length != 1 && ((i.stack = n), (i.start = a))),
7364                e
7365              )
7366            }),
7367              i.end != null && /^\)*$/.test(e.substr(i.end)) && (e = e.substring(0, i.start) + e.substr(i.end))
7368          }
7369          return (
7370            e.charAt(0) != '^' && (e = '^' + e),
7371            e.charAt(e.length - 1) != '$' && (e += '$'),
7372            new RegExp(e, (t || '').replace('g', ''))
7373          )
7374        }),
7375        (this.getLineTokens = function(e, t) {
7376          if (t && typeof t != 'string') {
7377            var n = t.slice(0)
7378            ;(t = n[0]), t === '#tmp' && (n.shift(), (t = n.shift()))
7379          } else var n = []
7380          var r = t || 'start',
7381            s = this.states[r]
7382          s || ((r = 'start'), (s = this.states[r]))
7383          var o = this.matchMappings[r],
7384            u = this.regExps[r]
7385          u.lastIndex = 0
7386          var a,
7387            f = [],
7388            l = 0,
7389            c = 0,
7390            h = { type: null, value: '' }
7391          while ((a = u.exec(e))) {
7392            var p = o.defaultToken,
7393              d = null,
7394              v = a[0],
7395              m = u.lastIndex
7396            if (m - v.length > l) {
7397              var g = e.substring(l, m - v.length)
7398              h.type == p ? (h.value += g) : (h.type && f.push(h), (h = { type: p, value: g }))
7399            }
7400            for (var y = 0; y < a.length - 2; y++) {
7401              if (a[y + 1] === undefined) continue
7402              ;(d = s[o[y]]),
7403                d.onMatch ? (p = d.onMatch(v, r, n, e)) : (p = d.token),
7404                d.next &&
7405                  (typeof d.next == 'string' ? (r = d.next) : (r = d.next(r, n)),
7406                  (s = this.states[r]),
7407                  s || (this.reportError("state doesn't exist", r), (r = 'start'), (s = this.states[r])),
7408                  (o = this.matchMappings[r]),
7409                  (l = m),
7410                  (u = this.regExps[r]),
7411                  (u.lastIndex = m)),
7412                d.consumeLineEnd && (l = m)
7413              break
7414            }
7415            if (v)
7416              if (typeof p == 'string')
7417                (!!d && d.merge === !1) || h.type !== p
7418                  ? (h.type && f.push(h), (h = { type: p, value: v }))
7419                  : (h.value += v)
7420              else if (p) {
7421                h.type && f.push(h), (h = { type: null, value: '' })
7422                for (var y = 0; y < p.length; y++) f.push(p[y])
7423              }
7424            if (l == e.length) break
7425            l = m
7426            if (c++ > i) {
7427              c > 2 * e.length && this.reportError('infinite loop with in ace tokenizer', { startState: t, line: e })
7428              while (l < e.length) h.type && f.push(h), (h = { value: e.substring(l, (l += 2e3)), type: 'overflow' })
7429              ;(r = 'start'), (n = [])
7430              break
7431            }
7432          }
7433          return (
7434            h.type && f.push(h),
7435            n.length > 1 && n[0] !== r && n.unshift('#tmp', r),
7436            { tokens: f, state: n.length ? n : r }
7437          )
7438        }),
7439        (this.reportError = r.reportError)
7440    }.call(s.prototype),
7441      (t.Tokenizer = s))
7442  }),
7443  define('ace/mode/text_highlight_rules', ['require', 'exports', 'module', 'ace/lib/lang'], function(e, t, n) {
7444    'use strict'
7445    var r = e('../lib/lang'),
7446      i = function() {
7447        this.$rules = { start: [{ token: 'empty_line', regex: '^$' }, { defaultToken: 'text' }] }
7448      }
7449    ;(function() {
7450      ;(this.addRules = function(e, t) {
7451        if (!t) {
7452          for (var n in e) this.$rules[n] = e[n]
7453          return
7454        }
7455        for (var n in e) {
7456          var r = e[n]
7457          for (var i = 0; i < r.length; i++) {
7458            var s = r[i]
7459            if (s.next || s.onMatch)
7460              typeof s.next == 'string' && s.next.indexOf(t) !== 0 && (s.next = t + s.next),
7461                s.nextState && s.nextState.indexOf(t) !== 0 && (s.nextState = t + s.nextState)
7462          }
7463          this.$rules[t + n] = r
7464        }
7465      }),
7466        (this.getRules = function() {
7467          return this.$rules
7468        }),
7469        (this.embedRules = function(e, t, n, i, s) {
7470          var o = typeof e == 'function' ? new e().getRules() : e
7471          if (i) for (var u = 0; u < i.length; u++) i[u] = t + i[u]
7472          else {
7473            i = []
7474            for (var a in o) i.push(t + a)
7475          }
7476          this.addRules(o, t)
7477          if (n) {
7478            var f = Array.prototype[s ? 'push' : 'unshift']
7479            for (var u = 0; u < i.length; u++) f.apply(this.$rules[i[u]], r.deepCopy(n))
7480          }
7481          this.$embeds || (this.$embeds = []), this.$embeds.push(t)
7482        }),
7483        (this.getEmbeds = function() {
7484          return this.$embeds
7485        })
7486      var e = function(e, t) {
7487          return (e != 'start' || t.length) && t.unshift(this.nextState, e), this.nextState
7488        },
7489        t = function(e, t) {
7490          return t.shift(), t.shift() || 'start'
7491        }
7492      ;(this.normalizeRules = function() {
7493        function i(s) {
7494          var o = r[s]
7495          o.processed = !0
7496          for (var u = 0; u < o.length; u++) {
7497            var a = o[u],
7498              f = null
7499            Array.isArray(a) && ((f = a), (a = {})),
7500              !a.regex &&
7501                a.start &&
7502                ((a.regex = a.start),
7503                a.next || (a.next = []),
7504                a.next.push(
7505                  { defaultToken: a.token },
7506                  { token: a.token + '.end', regex: a.end || a.start, next: 'pop' }
7507                ),
7508                (a.token = a.token + '.start'),
7509                (a.push = !0))
7510            var l = a.next || a.push
7511            if (l && Array.isArray(l)) {
7512              var c = a.stateName
7513              c || ((c = a.token), typeof c != 'string' && (c = c[0] || ''), r[c] && (c += n++)),
7514                (r[c] = l),
7515                (a.next = c),
7516                i(c)
7517            } else l == 'pop' && (a.next = t)
7518            a.push && ((a.nextState = a.next || a.push), (a.next = e), delete a.push)
7519            if (a.rules)
7520              for (var h in a.rules) r[h] ? r[h].push && r[h].push.apply(r[h], a.rules[h]) : (r[h] = a.rules[h])
7521            var p = typeof a == 'string' ? a : a.include
7522            p &&
7523              (Array.isArray(p)
7524                ? (f = p.map(function(e) {
7525                    return r[e]
7526                  }))
7527                : (f = r[p]))
7528            if (f) {
7529              var d = [u, 1].concat(f)
7530              a.noEscape &&
7531                (d = d.filter(function(e) {
7532                  return !e.next
7533                })),
7534                o.splice.apply(o, d),
7535                u--
7536            }
7537            a.keywordMap &&
7538              ((a.token = this.createKeywordMapper(a.keywordMap, a.defaultToken || 'text', a.caseInsensitive)),
7539              delete a.defaultToken)
7540          }
7541        }
7542        var n = 0,
7543          r = this.$rules
7544        Object.keys(r).forEach(i, this)
7545      }),
7546        (this.createKeywordMapper = function(e, t, n, r) {
7547          var i = Object.create(null)
7548          return (
7549            Object.keys(e).forEach(function(t) {
7550              var s = e[t]
7551              n && (s = s.toLowerCase())
7552              var o = s.split(r || '|')
7553              for (var u = o.length; u--; ) i[o[u]] = t
7554            }),
7555            Object.getPrototypeOf(i) && (i.__proto__ = null),
7556            (this.$keywordList = Object.keys(i)),
7557            (e = null),
7558            n
7559              ? function(e) {
7560                  return i[e.toLowerCase()] || t
7561                }
7562              : function(e) {
7563                  return i[e] || t
7564                }
7565          )
7566        }),
7567        (this.getKeywords = function() {
7568          return this.$keywords
7569        })
7570    }.call(i.prototype),
7571      (t.TextHighlightRules = i))
7572  }),
7573  define('ace/mode/behaviour', ['require', 'exports', 'module'], function(e, t, n) {
7574    'use strict'
7575    var r = function() {
7576      this.$behaviours = {}
7577    }
7578    ;(function() {
7579      ;(this.add = function(e, t, n) {
7580        switch (undefined) {
7581          case this.$behaviours:
7582            this.$behaviours = {}
7583          case this.$behaviours[e]:
7584            this.$behaviours[e] = {}
7585        }
7586        this.$behaviours[e][t] = n
7587      }),
7588        (this.addBehaviours = function(e) {
7589          for (var t in e) for (var n in e[t]) this.add(t, n, e[t][n])
7590        }),
7591        (this.remove = function(e) {
7592          this.$behaviours && this.$behaviours[e] && delete this.$behaviours[e]
7593        }),
7594        (this.inherit = function(e, t) {
7595          if (typeof e == 'function') var n = new e().getBehaviours(t)
7596          else var n = e.getBehaviours(t)
7597          this.addBehaviours(n)
7598        }),
7599        (this.getBehaviours = function(e) {
7600          if (!e) return this.$behaviours
7601          var t = {}
7602          for (var n = 0; n < e.length; n++) this.$behaviours[e[n]] && (t[e[n]] = this.$behaviours[e[n]])
7603          return t
7604        })
7605    }.call(r.prototype),
7606      (t.Behaviour = r))
7607  }),
7608  define('ace/token_iterator', ['require', 'exports', 'module', 'ace/range'], function(e, t, n) {
7609    'use strict'
7610    var r = e('./range').Range,
7611      i = function(e, t, n) {
7612        ;(this.$session = e), (this.$row = t), (this.$rowTokens = e.getTokens(t))
7613        var r = e.getTokenAt(t, n)
7614        this.$tokenIndex = r ? r.index : -1
7615      }
7616    ;(function() {
7617      ;(this.stepBackward = function() {
7618        this.$tokenIndex -= 1
7619        while (this.$tokenIndex < 0) {
7620          this.$row -= 1
7621          if (this.$row < 0) return (this.$row = 0), null
7622          ;(this.$rowTokens = this.$session.getTokens(this.$row)), (this.$tokenIndex = this.$rowTokens.length - 1)
7623        }
7624        return this.$rowTokens[this.$tokenIndex]
7625      }),
7626        (this.stepForward = function() {
7627          this.$tokenIndex += 1
7628          var e
7629          while (this.$tokenIndex >= this.$rowTokens.length) {
7630            ;(this.$row += 1), e || (e = this.$session.getLength())
7631            if (this.$row >= e) return (this.$row = e - 1), null
7632            ;(this.$rowTokens = this.$session.getTokens(this.$row)), (this.$tokenIndex = 0)
7633          }
7634          return this.$rowTokens[this.$tokenIndex]
7635        }),
7636        (this.getCurrentToken = function() {
7637          return this.$rowTokens[this.$tokenIndex]
7638        }),
7639        (this.getCurrentTokenRow = function() {
7640          return this.$row
7641        }),
7642        (this.getCurrentTokenColumn = function() {
7643          var e = this.$rowTokens,
7644            t = this.$tokenIndex,
7645            n = e[t].start
7646          if (n !== undefined) return n
7647          n = 0
7648          while (t > 0) (t -= 1), (n += e[t].value.length)
7649          return n
7650        }),
7651        (this.getCurrentTokenPosition = function() {
7652          return { row: this.$row, column: this.getCurrentTokenColumn() }
7653        }),
7654        (this.getCurrentTokenRange = function() {
7655          var e = this.$rowTokens[this.$tokenIndex],
7656            t = this.getCurrentTokenColumn()
7657          return new r(this.$row, t, this.$row, t + e.value.length)
7658        })
7659    }.call(i.prototype),
7660      (t.TokenIterator = i))
7661  }),
7662  define('ace/mode/behaviour/cstyle', [
7663    'require',
7664    'exports',
7665    'module',
7666    'ace/lib/oop',
7667    'ace/mode/behaviour',
7668    'ace/token_iterator',
7669    'ace/lib/lang'
7670  ], function(e, t, n) {
7671    'use strict'
7672    var r = e('../../lib/oop'),
7673      i = e('../behaviour').Behaviour,
7674      s = e('../../token_iterator').TokenIterator,
7675      o = e('../../lib/lang'),
7676      u = ['text', 'paren.rparen', 'punctuation.operator'],
7677      a = ['text', 'paren.rparen', 'punctuation.operator', 'comment'],
7678      f,
7679      l = {},
7680      c = { '"': '"', "'": "'" },
7681      h = function(e) {
7682        var t = -1
7683        e.multiSelect &&
7684          ((t = e.selection.index),
7685          l.rangeCount != e.multiSelect.rangeCount && (l = { rangeCount: e.multiSelect.rangeCount }))
7686        if (l[t]) return (f = l[t])
7687        f = l[t] = {
7688          autoInsertedBrackets: 0,
7689          autoInsertedRow: -1,
7690          autoInsertedLineEnd: '',
7691          maybeInsertedBrackets: 0,
7692          maybeInsertedRow: -1,
7693          maybeInsertedLineStart: '',
7694          maybeInsertedLineEnd: ''
7695        }
7696      },
7697      p = function(e, t, n, r) {
7698        var i = e.end.row - e.start.row
7699        return { text: n + t + r, selection: [0, e.start.column + 1, i, e.end.column + (i ? 0 : 1)] }
7700      },
7701      d = function(e) {
7702        this.add('braces', 'insertion', function(t, n, r, i, s) {
7703          var u = r.getCursorPosition(),
7704            a = i.doc.getLine(u.row)
7705          if (s == '{') {
7706            h(r)
7707            var l = r.getSelectionRange(),
7708              c = i.doc.getTextRange(l)
7709            if (c !== '' && c !== '{' && r.getWrapBehavioursEnabled()) return p(l, 
7709c, '{', '}')
7710            if (d.isSaneInsertion(r, i))
7711              return /[\]\}\)]/.test(a[u.column]) || r.inMultiSelectMode || (e && e.braces)
7712                ? (d.recordAutoInsert(r, i, '}'), { text: '{}', selection: [1, 1] })
7713                : (d.recordMaybeInsert(r, i, '{'), { text: '{', selection: [1, 1] })
7714          } else if (s == '}') {
7715            h(r)
7716            var v = a.substring(u.column, u.column + 1)
7717            if (v == '}') {
7718              var m = i.$findOpeningBracket('}', { column: u.column + 1, row: u.row })
7719              if (m !== null && d.isAutoInsertedClosing(u, a, s))
7720                return d.popAutoInsertedClosing(), { text: '', selection: [1, 1] }
7721            }
7722          } else {
7723            if (s == '\n' || s == '\r\n') {
7724              h(r)
7725              var g = ''
7726              d.isMaybeInsertedClosing(u, a) &&
7727                ((g = o.stringRepeat('}', f.maybeInsertedBrackets)), d.clearMaybeInsertedClosing())
7728              var v = a.substring(u.column, u.column + 1)
7729              if (v === '}') {
7730                var y = i.findMatchingBracket({ row: u.row, column: u.column + 1 }, '}')
7731                if (!y) return null
7732                var b = this.$getIndent(i.getLine(y.row))
7733              } else {
7734                if (!g) {
7735                  d.clearMaybeInsertedClosing()
7736                  return
7737                }
7738                var b = this.$getIndent(a)
7739              }
7740              var w = b + i.getTabString()
7741              return { text: '\n' + w + '\n' + b + g, selection: [1, w.length, 1, w.length] }
7742            }
7743            d.clearMaybeInsertedClosing()
7744          }
7745        }),
7746          this.add('braces', 'deletion', function(e, t, n, r, i) {
7747            var s = r.doc.getTextRange(i)
7748            if (!i.isMultiLine() && s == '{') {
7749              h(n)
7750              var o = r.doc.getLine(i.start.row),
7751                u = o.substring(i.end.column, i.end.column + 1)
7752              if (u == '}') return i.end.column++, i
7753              f.maybeInsertedBrackets--
7754            }
7755          }),
7756          this.add('parens', 'insertion', function(e, t, n, r, i) {
7757            if (i == '(') {
7758              h(n)
7759              var s = n.getSelectionRange(),
7760                o = r.doc.getTextRange(s)
7761              if (o !== '' && n.getWrapBehavioursEnabled()) return p(s, o, '(', ')')
7762              if (d.isSaneInsertion(n, r)) return d.recordAutoInsert(n, r, ')'), { text: '()', selection: [1, 1] }
7763            } else if (i == ')') {
7764              h(n)
7765              var u = n.getCursorPosition(),
7766                a = r.doc.getLine(u.row),
7767                f = a.substring(u.column, u.column + 1)
7768              if (f == ')') {
7769                var l = r.$findOpeningBracket(')', { column: u.column + 1, row: u.row })
7770                if (l !== null && d.isAutoInsertedClosing(u, a, i))
7771                  return d.popAutoInsertedClosing(), { text: '', selection: [1, 1] }
7772              }
7773            }
7774          }),
7775          this.add('parens', 'deletion', function(e, t, n, r, i) {
7776            var s = r.doc.getTextRange(i)
7777            if (!i.isMultiLine() && s == '(') {
7778              h(n)
7779              var o = r.doc.getLine(i.start.row),
7780                u = o.substring(i.start.column + 1, i.start.column + 2)
7781              if (u == ')') return i.end.column++, i
7782            }
7783          }),
7784          this.add('brackets', 'insertion', function(e, t, n, r, i) {
7785            if (i == '[') {
7786              h(n)
7787              var s = n.getSelectionRange(),
7788                o = r.doc.getTextRange(s)
7789              if (o !== '' && n.getWrapBehavioursEnabled()) return p(s, o, '[', ']')
7790              if (d.isSaneInsertion(n, r)) return d.recordAutoInsert(n, r, ']'), { text: '[]', selection: [1, 1] }
7791            } else if (i == ']') {
7792              h(n)
7793              var u = n.getCursorPosition(),
7794                a = r.doc.getLine(u.row),
7795                f = a.substring(u.column, u.column + 1)
7796              if (f == ']') {
7797                var l = r.$findOpeningBracket(']', { column: u.column + 1, row: u.row })
7798                if (l !== null && d.isAutoInsertedClosing(u, a, i))
7799                  return d.popAutoInsertedClosing(), { text: '', selection: [1, 1] }
7800              }
7801            }
7802          }),
7803          this.add('brackets', 'deletion', function(e, t, n, r, i) {
7804            var s = r.doc.getTextRange(i)
7805            if (!i.isMultiLine() && s == '[') {
7806              h(n)
7807              var o = r.doc.getLine(i.start.row),
7808                u = o.substring(i.start.column + 1, i.start.column + 2)
7809              if (u == ']') return i.end.column++, i
7810            }
7811          }),
7812          this.add('string_dquotes', 'insertion', function(e, t, n, r, i) {
7813            var s = r.$mode.$quotes || c
7814            if (i.length == 1 && s[i]) {
7815              if (this.lineCommentStart && this.lineCommentStart.indexOf(i) != -1) return
7816              h(n)
7817              var o = i,
7818                u = n.getSelectionRange(),
7819                a = r.doc.getTextRange(u)
7820              if (a !== '' && (a.length != 1 || !s[a]) && n.getWrapBehavioursEnabled()) return p(u, a, o, o)
7821              if (!a) {
7822                var f = n.getCursorPosition(),
7823                  l = r.doc.getLine(f.row),
7824                  d = l.substring(f.column - 1, f.column),
7825                  v = l.substring(f.column, f.column + 1),
7826                  m = r.getTokenAt(f.row, f.column),
7827                  g = r.getTokenAt(f.row, f.column + 1)
7828                if (d == '\\' && m && /escape/.test(m.type)) return null
7829                var y = m && /string|escape/.test(m.type),
7830                  b = !g || /string|escape/.test(g.type),
7831                  w
7832                if (v == o) (w = y !== b), w && /string\.end/.test(g.type) && (w = !1)
7833                else {
7834                  if (y && !b) return null
7835                  if (y && b) return null
7836                  var E = r.$mode.tokenRe
7837                  E.lastIndex = 0
7838                  var S = E.test(d)
7839                  E.lastIndex = 0
7840                  var x = E.test(d)
7841                  if (S || x) return null
7842                  if (v && !/[\s;,.})\]\\]/.test(v)) return null
7843                  w = !0
7844                }
7845                return { text: w ? o + o : '', selection: [1, 1] }
7846              }
7847            }
7848          }),
7849          this.add('string_dquotes', 'deletion', function(e, t, n, r, i) {
7850            var s = r.doc.getTextRange(i)
7851            if (!i.isMultiLine() && (s == '"' || s == "'")) {
7852              h(n)
7853              var o = r.doc.getLine(i.start.row),
7854                u = o.substring(i.start.column + 1, i.start.column + 2)
7855              if (u == s) return i.end.column++, i
7856            }
7857          })
7858      }
7859    ;(d.isSaneInsertion = function(e, t) {
7860      var n = e.getCursorPosition(),
7861        r = new s(t, n.row, n.column)
7862      if (!this.$matchTokenType(r.getCurrentToken() || 'text', u)) {
7863        var i = new s(t, n.row, n.column + 1)
7864        if (!this.$matchTokenType(i.getCurrentToken() || 'text', u)) return !1
7865      }
7866      return r.stepForward(), r.getCurrentTokenRow() !== n.row || this.$matchTokenType(r.getCurrentToken() || 'text', a)
7867    }),
7868      (d.$matchTokenType = function(e, t) {
7869        return t.indexOf(e.type || e) > -1
7870      }),
7871      (d.recordAutoInsert = function(e, t, n) {
7872        var r = e.getCursorPosition(),
7873          i = t.doc.getLine(r.row)
7874        this.isAutoInsertedClosing(r, i, f.autoInsertedLineEnd[0]) || (f.autoInsertedBrackets = 0),
7875          (f.autoInsertedRow = r.row),
7876          (f.autoInsertedLineEnd = n + i.substr(r.column)),
7877          f.autoInsertedBrackets++
7878      }),
7879      (d.recordMaybeInsert = function(e, t, n) {
7880        var r = e.getCursorPosition(),
7881          i = t.doc.getLine(r.row)
7882        this.isMaybeInsertedClosing(r, i) || (f.maybeInsertedBrackets = 0),
7883          (f.maybeInsertedRow = r.row),
7884          (f.maybeInsertedLineStart = i.substr(0, r.column) + n),
7885          (f.maybeInsertedLineEnd = i.substr(r.column)),
7886          f.maybeInsertedBrackets++
7887      }),
7888      (d.isAutoInsertedClosing = function(e, t, n) {
7889        return (
7890          f.autoInsertedBrackets > 0 &&
7891          e.row === f.autoInsertedRow &&
7892          n === f.autoInsertedLineEnd[0] &&
7893          t.substr(e.column) === f.autoInsertedLineEnd
7894        )
7895      }),
7896      (d.isMaybeInsertedClosing = function(e, t) {
7897        return (
7898          f.maybeInsertedBrackets > 0 &&
7899          e.row === f.maybeInsertedRow &&
7900          t.substr(e.column) === f.maybeInsertedLineEnd &&
7901          t.substr(0, e.column) == f.maybeInsertedLineStart
7902        )
7903      }),
7904      (d.popAutoInsertedClosing = function() {
7905        ;(f.autoInsertedLineEnd = f.autoInsertedLineEnd.substr(1)), f.autoInsertedBrackets--
7906      }),
7907      (d.clearMaybeInsertedClosing = function() {
7908        f && ((f.maybeInsertedBrackets = 0), (f.maybeInsertedRow = -1))
7909      }),
7910      r.inherits(d, i),
7911      (t.CstyleBehaviour = d)
7912  }),
7913  define('ace/unicode', ['require', 'exports', 'module'], function(e, t, n) {
7914    'use strict'
7915    var r = [
7916        48,
7917        9,
7918        8,
7919        25,
7920        5,
7921        0,
7922        2,
7923        25,
7924        48,
7925        0,
7926        11,
7927        0,
7928        5,
7929        0,
7930        6,
7931        22,
7932        2,
7933        30,
7934        2,
7935        457,
7936        5,
7937        11,
7938        15,
7939        4,
7940        8,
7941        0,
7942        2,
7943        0,
7944        18,
7945        116,
7946        2,
7947        1,
7948        3,
7949        3,
7950        9,
7951        0,
7952        2,
7953        2,
7954        2,
7955        0,
7956        2,
7957        19,
7958        2,
7959        82,
7960        2,
7961        138,
7962        2,
7963        4,
7964        3,
7965        155,
7966        12,
7967        37,
7968        3,
7969        0,
7970        8,
7971        38,
7972        10,
7973        44,
7974        2,
7975        0,
7976        2,
7977        1,
7978        2,
7979        1,
7980        2,
7981        0,
7982        9,
7983        26,
7984        6,
7985        2,
7986        30,
7987        10,
7988        7,
7989        61,
7990        2,
7991        9,
7992        5,
7993        101,
7994        2,
7995        7,
7996        3,
7997        9,
7998        2,
7999        18,
8000        3,
8001        0,
8002        17,
8003        58,
8004        3,
8005        100,
8006        15,
8007        53,
8008        5,
8009        0,
8010        6,
8011        45,
8012        211,
8013        57,
8014        3,
8015        18,
8016        2,
8017        5,
8018        3,
8019        11,
8020        3,
8021        9,
8022        2,
8023        1,
8024        7,
8025        6,
8026        2,
8027        2,
8028        2,
8029        7,
8030        3,
8031        1,
8032        3,
8033        21,
8034        2,
8035        6,
8036        2,
8037        0,
8038        4,
8039        3,
8040        3,
8041        8,
8042        3,
8043        1,
8044        3,
8045        3,
8046        9,
8047        0,
8048        5,
8049        1,
8050        2,
8051        4,
8052        3,
8053        11,
8054        16,
8055        2,
8056        2,
8057        5,
8058        5,
8059        1,
8060        3,
8061        21,
8062        2,
8063        6,
8064        2,
8065        1,
8066        2,
8067        1,
8068        2,
8069        1,
8070        3,
8071        0,
8072        2,
8073        4,
8074        5,
8075        1,
8076        3,
8077        2,
8078        4,
8079        0,
8080        8,
8081        3,
8082        2,
8083        0,
8084        8,
8085        15,
8086        12,
8087        2,
8088        2,
8089        8,
8090        2,
8091        2,
8092        2,
8093        21,
8094        2,
8095        6,
8096        2,
8097        1,
8098        2,
8099        4,
8100        3,
8101        9,
8102        2,
8103        2,
8104        2,
8105        2,
8106        3,
8107        0,
8108        16,
8109        3,
8110        3,
8111        9,
8112        18,
8113        2,
8114        2,
8115        7,
8116        3,
8117        1,
8118        3,
8119        21,
8120        2,
8121        6,
8122        2,
8123        1,
8124        2,
8125        4,
8126        3,
8127        8,
8128        3,
8129        1,
8130        3,
8131        2,
8132        9,
8133        1,
8134        5,
8135        1,
8136        2,
8137        4,
8138        3,
8139        9,
8140        2,
8141        0,
8142        17,
8143        1,
8144        2,
8145        5,
8146        4,
8147        2,
8148        2,
8149        3,
8150        4,
8151        1,
8152        2,
8153        0,
8154        2,
8155        1,
8156        4,
8157        1,
8158        4,
8159        2,
8160        4,
8161        11,
8162        5,
8163        4,
8164        4,
8165        2,
8166        2,
8167        3,
8168        3,
8169        0,
8170        7,
8171        0,
8172        15,
8173        9,
8174        18,
8175        2,
8176        2,
8177        7,
8178        2,
8179        2,
8180        2,
8181        22,
8182        2,
8183        9,
8184        2,
8185        4,
8186        4,
8187        7,
8188        2,
8189        2,
8190        2,
8191        3,
8192        8,
8193        1,
8194        2,
8195        1,
8196        7,
8197        3,
8198        3,
8199        9,
8200        19,
8201        1,
8202        2,
8203        7,
8204        2,
8205        2,
8206        2,
8207        22,
8208        2,
8209        9,
8210        2,
8211        4,
8212        3,
8213        8,
8214        2,
8215        2,
8216        2,
8217        3,
8218        8,
8219        1,
8220        8,
8221        0,
8222        2,
8223        3,
8224        3,
8225        9,
8226        19,
8227        1,
8228        2,
8229        7,
8230        2,
8231        2,
8232        2,
8233        22,
8234        2,
8235        15,
8236        4,
8237        7,
8238        2,
8239        2,
8240        2,
8241        3,
8242        10,
8243        0,
8244        9,
8245        3,
8246        3,
8247        9,
8248        11,
8249        5,
8250        3,
8251        1,
8252        2,
8253        17,
8254        4,
8255        23,
8256        2,
8257        8,
8258        2,
8259        0,
8260        3,
8261        6,
8262        4,
8263        0,
8264        5,
8265        5,
8266        2,
8267        0,
8268        2,
8269        7,
8270        19,
8271        1,
8272        14,
8273        57,
8274        6,
8275        14,
8276        2,
8277        9,
8278        40,
8279        1,
8280        2,
8281        0,
8282        3,
8283        1,
8284        2,
8285        0,
8286        3,
8287        0,
8288        7,
8289        3,
8290        2,
8291        6,
8292        2,
8293        2,
8294        2,
8295        0,
8296        2,
8297        0,
8298        3,
8299        1,
8300        2,
8301        12,
8302        2,
8303        2,
8304        3,
8305        4,
8306        2,
8307        0,
8308        2,
8309        5,
8310        3,
8311        9,
8312        3,
8313        1,
8314        35,
8315        0,
8316        24,
8317        1,
8318        7,
8319        9,
8320        12,
8321        0,
8322        2,
8323        0,
8324        2,
8325        0,
8326        5,
8327        9,
8328        2,
8329        35,
8330        5,
8331        19,
8332        2,
8333        5,
8334        5,
8335        7,
8336        2,
8337        35,
8338        10,
8339        0,
8340        58,
8341        73,
8342        7,
8343        77,
8344        3,
8345        37,
8346        11,
8347        42,
8348        2,
8349        0,
8350        4,
8351        328,
8352        2,
8353        3,
8354        3,
8355        6,
8356        2,
8357        0,
8358        2,
8359        3,
8360        3,
8361        40,
8362        2,
8363        3,
8364        3,
8365        32,
8366        2,
8367        3,
8368        3,
8369        6,
8370        2,
8371        0,
8372        2,
8373        3,
8374        3,
8375        14,
8376        2,
8377        56,
8378        2,
8379        3,
8380        3,
8381        66,
8382        5,
8383        0,
8384        33,
8385        15,
8386        17,
8387        84,
8388        13,
8389        619,
8390        3,
8391        16,
8392        2,
8393        25,
8394        6,
8395        74,
8396        22,
8397        12,
8398        2,
8399        6,
8400        12,
8401        20,
8402        12,
8403        19,
8404        13,
8405        12,
8406        2,
8407        2,
8408        2,
8409        1,
8410        13,
8411        51,
8412        3,
8413        29,
8414        4,
8415        0,
8416        5,
8417        1,
8418        3,
8419        9,
8420        34,
8421        2,
8422        3,
8423        9,
8424        7,
8425        87,
8426        9,
8427        42,
8428        6,
8429        69,
8430        11,
8431        28,
8432        4,
8433        11,
8434        5,
8435        11,
8436        11,
8437        39,
8438        3,
8439        4,
8440        12,
8441        43,
8442        5,
8443        25,
8444        7,
8445        10,
8446        38,
8447        27,
8448        5,
8449        62,
8450        2,
8451        28,
8452        3,
8453        10,
8454        7,
8455        9,
8456        14,
8457        0,
8458        89,
8459        75,
8460        5,
8461        9,
8462        18,
8463        8,
8464        13,
8465        42,
8466        4,
8467        11,
8468        71,
8469        55,
8470        9,
8471        9,
8472        4,
8473        48,
8474        83,
8475        2,
8476        2,
8477        30,
8478        14,
8479        230,
8480        23,
8481        280,
8482        3,
8483        5,
8484        3,
8485        37,
8486        3,
8487        5,
8488        3,
8489        7,
8490        2,
8491        0,
8492        2,
8493        0,
8494        2,
8495        0,
8496        2,
8497        30,
8498        3,
8499        52,
8500        2,
8501        6,
8502        2,
8503        0,
8504        4,
8505        2,
8506        2,
8507        6,
8508        4,
8509        3,
8510        3,
8511        5,
8512        5,
8513        12,
8514        6,
8515        2,
8516        2,
8517        6,
8518        67,
8519        1,
8520        20,
8521        0,
8522        29,
8523        0,
8524        14,
8525        0,
8526        17,
8527        4,
8528        60,
8529        12,
8530        5,
8531        0,
8532        4,
8533        11,
8534        18,
8535        0,
8536        5,
8537        0,
8538        3,
8539        9,
8540        2,
8541        0,
8542        4,
8543        4,
8544        7,
8545        0,
8546        2,
8547        0,
8548        2,
8549        0,
8550        2,
8551        3,
8552        2,
8553        10,
8554        3,
8555        3,
8556        6,
8557        4,
8558        5,
8559        0,
8560        53,
8561        1,
8562        2684,
8563        46,
8564        2,
8565        46,
8566        2,
8567        132,
8568        7,
8569        6,
8570        15,
8571        37,
8572        11,
8573        53,
8574        10,
8575        0,
8576        17,
8577        22,
8578        10,
8579        6,
8580        2,
8581        6,
8582        2,
8583        6,
8584        2,
8585        6,
8586        2,
8587        6,
8588        2,
8589        6,
8590        2,
8591        6,
8592        2,
8593        6,
8594        2,
8595        31,
8596        48,
8597        0,
8598        470,
8599        1,
8600        36,
8601        5,
8602        2,
8603        4,
8604        6,
8605        1,
8606        5,
8607        85,
8608        3,
8609        1,
8610        3,
8611        2,
8612        2,
8613        89,
8614        2,
8615        3,
8616        6,
8617        40,
8618        4,
8619        93,
8620        18,
8621        23,
8622        57,
8623        15,
8624        513,
8625        6581,
8626        75,
8627        20939,
8628        53,
8629        1164,
8630        68,
8631        45,
8632        3,
8633        268,
8634        4,
8635        27,
8636        21,
8637        31,
8638        3,
8639        13,
8640        13,
8641        1,
8642        2,
8643        24,
8644        9,
8645        69,
8646        11,
8647        1,
8648        38,
8649        8,
8650        3,
8651        102,
8652        3,
8653        1,
8654        111,
8655        44,
8656        25,
8657        51,
8658        13,
8659        68,
8660        12,
8661        9,
8662        7,
8663        23,
8664        4,
8665        0,
8666        5,
8667        45,
8668        3,
8669        35,
8670        13,
8671        28,
8672        4,
8673        64,
8674        15,
8675        10,
8676        39,
8677        54,
8678        10,
8679        13,
8680        3,
8681        9,
8682        7,
8683        22,
8684        4,
8685        1,
8686        5,
8687        66,
8688        25,
8689        2,
8690        227,
8691        42,
8692        2,
8693        1,
8694        3,
8695        9,
8696        7,
8697        11171,
8698        13,
8699        22,
8700        5,
8701        48,
8702        8453,
8703        301,
8704        3,
8705        61,
8706        3,
8707        105,
8708        39,
8709        6,
8710        13,
8711        4,
8712        6,
8713        11,
8714        2,
8715        12,
8716        2,
8717        4,
8718        2,
8719        0,
8720        2,
8721        1,
8722        2,
8723        1,
8724        2,
8725        107,
8726        34,
8727        362,
8728        19,
8729        63,
8730        3,
8731        53,
8732        41,
8733        11,
8734        5,
8735        15,
8736        17,
8737        6,
8738        13,
8739        1,
8740        25,
8741        2,
8742        33,
8743        4,
8744        2,
8745        134,
8746        20,
8747        9,
8748        8,
8749        25,
8750        5,
8751        0,
8752        2,
8753        25,
8754        12,
8755        88,
8756        4,
8757        5,
8758        3,
8759        5,
8760        3,
8761        5,
8762        3,
8763        2
8764      ],
8765      i = 0,
8766      s = []
8767    for (var o = 0; o < r.length; o += 2) s.push((i += r[o])), r[o + 1] && s.push(45, (i += r[o + 1]))
8768    t.wordChars = String.fromCharCode.apply(null, s)
8769  }),
8770  define('ace/mode/text', [
8771    'require',
8772    'exports',
8773    'module',
8774    'ace/tokenizer',
8775    'ace/mode/text_highlight_rules',
8776    'ace/mode/behaviour/cstyle',
8777    'ace/unicode',
8778    'ace/lib/lang',
8779    'ace/token_iterator',
8780    'ace/range'
8781  ], function(e, t, n) {
8782    'use strict'
8783    var r = e('../tokenizer').Tokenizer,
8784      i = e('./text_highlight_rules').TextHighlightRules,
8785      s = e('./behaviour/cstyle').CstyleBehaviour,
8786      o = e('../unicode'),
8787      u = e('../lib/lang'),
8788      a = e('../token_iterator').TokenIterator,
8789      f = e('../range').Range,
8790      l = function() {
8791        this.HighlightRules = i
8792      }
8793    ;(function() {
8794      ;(this.$defaultBehaviour = new s()),
8795        (this.tokenRe = new RegExp('^[' + o.wordChars + '\\$_]+', 'g')),
8796        (this.nonTokenRe = new RegExp('^(?:[^' + o.wordChars + '\\$_]|\\s])+', 'g')),
8797        (this.getTokenizer = function() {
8798          return (
8799            this.$tokenizer ||
8800              ((this.$highlightRules = this.$highlightRules || new this.HighlightRules(this.$highlightRuleConfig)),
8801              (this.$tokenizer = new r(this.$highlightRules.getRules()))),
8802            this.$tokenizer
8803          )
8804        }),
8805        (this.lineCommentStart = ''),
8806        (this.blockComment = ''),
8807        (this.toggleCommentLines = function(e, t, n, r) {
8808          function w(e) {
8809            for (var t = n; t <= r; t++) e(i.getLine(t), t)
8810          }
8811          var i = t.doc,
8812            s = !0,
8813            o = !0,
8814            a = Infinity,
8815            f = t.getTabSize(),
8816            l = !1
8817          if (!this.lineCommentStart) {
8818            if (!this.blockComment) return !1
8819            var c = this.blockComment.start,
8820              h = this.blockComment.end,
8821              p = new RegExp('^(\\s*)(?:' + u.escapeRegExp(c) + ')'),
8822              d = new RegExp('(?:' + u.escapeRegExp(h) + ')\\s*$'),
8823              v = function(e, t) {
8824                if (g(e, t)) return
8825                if (!s || /\S/.test(e))
8826                  i.insertInLine({ row: t, column: e.length }, h), i.insertInLine({ row: t, column: a }, c)
8827              },
8828              m = function(e, t) {
8829                var n
8830                ;(n = e.match(d)) && i.removeInLine(t, e.length - n[0].length, e.length),
8831                  (n = e.match(p)) && i.removeInLine(t, n[1].length, n[0].length)
8832              },
8833              g = function(e, n) {
8834                if (p.test(e)) return !0
8835                var r = t.getTokens(n)
8836                for (var i = 0; i < r.length; i++) if (r[i].type === 'comment') return !0
8837              }
8838          } else {
8839            if (Array.isArray(this.lineCommentStart))
8840              var p = this.lineCommentStart.map(u.escapeRegExp).join('|'),
8841                c = this.lineCommentStart[0]
8842            else
8843              var p = u.escapeRegExp(this.lineCommentStart),
8844                c = this.lineCommentStart
8845            ;(p = new RegExp('^(\\s*)(?:' + p + ') ?')), (l = t.getUseSoftTabs())
8846            var m = function(e, t) {
8847                var n = e.match(p)
8848                if (!n) return
8849                var r = n[1].length,
8850                  s = n[0].length
8851                !b(e, r, s) && n[0][s - 1] == ' ' && s--, i.removeInLine(t, r, s)
8852              },
8853              y = c + ' ',
8854              v = function(e, t) {
8855                if (!s || /\S/.test(e))
8856                  b(e, a, a) ? i.insertInLine({ row: t, column: a }, y) : i.insertInLine({ row: t, column: a }, c)
8857              },
8858              g = function(e, t) {
8859                return p.test(e)
8860              },
8861              b = function(e, t, n) {
8862                var r = 0
8863                while (t-- && e.charAt(t) == ' ') r++
8864                if (r % f != 0) return !1
8865                var r = 0
8866                while (e.charAt(n++) == ' ') r++
8867                return f > 2 ? r % f != f - 1 : r % f == 0
8868              }
8869          }
8870          var E = Infinity
8871          w(function(e, t) {
8872            var n = e.search(/\S/)
8873            n !== -1 ? (n < a && (a = n), o && !g(e, t) && (o = !1)) : E > e.length && (E = e.length)
8874          }),
8875            a == Infinity && ((a = E), (s = !1), (o = !1)),
8876            l && a % f != 0 && (a = Math.floor(a / f) * f),
8877            w(o ? m : v)
8878        }),
8879        (this.toggleBlockComment = function(e, t, n, r) {
8880          var i = this.blockComment
8881          if (!i) return
8882          !i.start && i[0] && (i = i[0])
8883          var s = new a(t, r.row, r.column),
8884            o = s.getCurrentToken(),
8885            u = t.selection,
8886            l = t.selection.toOrientedRange(),
8887            c,
8888            h
8889          if (o && /comment/.test(o.type)) {
8890            var p, d
8891            while (o && /comment/.test(o.type)) {
8892              var v = o.value.indexOf(i.start)
8893              if (v != -1) {
8894                var m = s.getCurrentTokenRow(),
8895                  g = s.getCurrentTokenColumn() + v
8896                p = new f(m, g, m, g + i.start.length)
8897                break
8898              }
8899              o = s.stepBackward()
8900            }
8901            var s = new a(t, r.row, r.column),
8902              o = s.getCurrentToken()
8903            while (o && /comment/.test(o.type)) {
8904              var v = o.value.indexOf(i.end)
8905              if (v != -1) {
8906                var m = s.getCurrentTokenRow(),
8907                  g = s.getCurrentTokenColumn() + v
8908                d = new f(m, g, m, g + i.end.length)
8909                break
8910              }
8911              o = s.stepForward()
8912            }
8913            d && t.remove(d), p && (t.remove(p), (c = p.start.row), (h = -i.start.length))
8914          } else (h = i.start.length), (c = n.start.row), t.insert(n.end, i.end), t.insert(n.start, i.start)
8915          l.start.row == c && (l.start.column += h),
8916            l.end.row == c && (l.end.column += h),
8917            t.selection.fromOrientedRange(l)
8918        }),
8919        (this.getNextLineIndent = function(e, t, n) {
8920          return this.$getIndent(t)
8921        }),
8922        (this.checkOutdent = function(e, t, n) {
8923          return !1
8924        }),
8925        (this.autoOutdent = function(e, t, n) {}),
8926        (this.$getIndent = function(e) {
8927          return e.match(/^\s*/)[0]
8928        }),
8929        (this.createWorker = function(e) {
8930          return null
8931        }),
8932        (this.createModeDelegates = function(e) {
8933          ;(this.$embeds = []), (this.$modes = {})
8934          for (var t in e) e[t] && (this.$embeds.push(t), (this.$modes[t] = new e[t]()))
8935          var n = [
8936            'toggleBlockComment',
8937            'toggleCommentLines',
8938            'getNextLineIndent',
8939            'checkOutdent',
8940            'autoOutdent',
8941            'transformAction',
8942            'getCompletions'
8943          ]
8944          for (var t = 0; t < n.length; t++)
8945            (function(e) {
8946              var r = n[t],
8947                i = e[r]
8948              e[n[t]] = function() {
8949                return this.$delegator(r, arguments, i)
8950              }
8951            })(this)
8952        }),
8953        (this.$delegator = function(e, t, n) {
8954          var r = t[0]
8955          typeof r != 'string' && (r = r[0])
8956          for (var i = 0; i < this.$embeds.length; i++) {
8957            if (!this.$modes[this.$embeds[i]]) continue
8958            var s = r.split(this.$embeds[i])
8959            if (!s[0] && s[1]) {
8960              t[0] = s[1]
8961              var o = this.$modes[this.$embeds[i]]
8962              return o[e].apply(o, t)
8963            }
8964          }
8965          var u = n.apply(this, t)
8966          return n ? u : undefined
8967        }),
8968        (this.transformAction = function(e, t, n, r, i) {
8969          if (this.$behaviour) {
8970            var s = this.$behaviour.getBehaviours()
8971            for (var o in s)
8972              if (s[o][t]) {
8973                var u = s[o][t].apply(this, arguments)
8974                if (u) return u
8975              }
8976          }
8977        }),
8978        (this.getKeywords = function(e) {
8979          if (!this.completionKeywords) {
8980            var t = this.$tokenizer.rules,
8981              n = []
8982            for (var r in t) {
8983              var i = t[r]
8984              for (var s = 0, o = i.length; s < o; s++)
8985                if (typeof i[s].token == 'string') /keyword|support|storage/.test(i[s].token) && n.push(i[s].regex)
8986                else if (typeof i[s].token == 'object')
8987                  for (var u = 0, a = i[s].token.length; u < a; u++)
8988                    if (/keyword|support|storage/.test(i[s].token[u])) {
8989                      var r = i[s].regex.match(/\(.+?\)/g)[u]
8990                      n.push(r.substr(1, r.length - 2))
8991                    }
8992            }
8993            this.completionKeywords = n
8994          }
8995          return e ? n.concat(this.$keywordList || []) : this.$keywordList
8996        }),
8997        (this.$createKeywordList = function() {
8998          return (
8999            this.$highlightRules || this.getTokenizer(), (this.$keywordList = this.$highlightRules.$keywordList || [])
9000          )
9001        }),
9002        (this.getCompletions = function(e, t, n, r) {
9003          var i = this.$keywordList || this.$createKeywordList()
9004          return i.map(function(e) {
9005            return { name: e, value: e, score: 0, meta: 'keyword' }
9006          })
9007        }),
9008        (this.$id = 'ace/mode/text')
9009    }.call(l.prototype),
9010      (t.Mode = l))
9011  }),
9012  define('ace/apply_delta', ['require', 'exports', 'module'], function(e, t, n) {
9013    'use strict'
9014    function r(e, t) {
9015      throw (console.log('Invalid Delta:', e), 'Invalid Delta: ' + t)
9016    }
9017    function i(e, t) {
9018      return t.row >= 0 && t.row < e.length && t.column >= 0 && t.column <= e[t.row].length
9019    }
9020    function s(e, t) {
9021      t.action != 'insert' && t.action != 'remove' && r(t, "delta.action must be 'insert' or 'remove'"),
9022        t.lines instanceof Array || r(t, 'delta.lines must be an Array'),
9023        (!t.start || !t.end) && r(t, 'delta.start/end must be an present')
9024      var n = t.start
9025      i(e, t.start) || r(t, 'delta.start must be contained in document')
9026      var s = t.end
9027      t.action == 'remove' && !i(e, s) && r(t, "delta.end must contained in document for 'remove' actions")
9028      var o = s.row - n.row,
9029        u = s.column - (o == 0 ? n.column : 0)
9030      ;(o != t.lines.length - 1 || t.lines[o].length != u) && r(t, 'delta.range must match delta lines')
9031    }
9032    t.applyDelta = function(e, t, n) {
9033      var r = t.start.row,
9034        i = t.start.column,
9035        s = e[r] || ''
9036      switch (t.action) {
9037        case 'insert':
9038          var o = t.lines
9039          if (o.length === 1) e[r] = s.substring(0, i) + t.lines[0] + s.substring(i)
9040          else {
9041            var u = [r, 1].concat(t.lines)
9042            e.splice.apply(e, u), (e[r] = s.substring(0, i) + e[r]), (e[r + t.lines.length - 1] += s.substring(i))
9043          }
9044          break
9045        case 'remove':
9046          var a = t.end.column,
9047            f = t.end.row
9048          r === f
9049            ? (e[r] = s.substring(0, i) + s.substring(a))
9050            : e.splice(r, f - r + 1, s.substring(0, i) + e[f].substring(a))
9051      }
9052    }
9053  }),
9054  define('ace/anchor', ['require', 'exports', 'module', 'ace/lib/oop', 'ace/lib/event_emitter'], function(e, t, n) {
9055    'use strict'
9056    var r = e('./lib/oop'),
9057      i = e('./lib/event_emitter').EventEmitter,
9058      s = (t.Anchor = function(e, t, n) {
9059        ;(this.$onChange = this.onChange.bind(this)),
9060          this.attach(e),
9061          typeof n == 'undefined' ? this.setPosition(t.row, t.column) : this.setPosition(t, n)
9062      })
9063    ;(function() {
9064      function e(e, t, n) {
9065        var r = n ? e.column <= t.column : e.column < t.column
9066        return e.row < t.row || (e.row == t.row && r)
9067      }
9068      function t(t, n, r) {
9069        var i = t.action == 'insert',
9070          s = (i ? 1 : -1) * (t.end.row - t.start.row),
9071          o = (i ? 1 : -1) * (t.end.column - t.start.column),
9072          u = t.start,
9073          a = i ? u : t.end
9074        return e(n, u, r)
9075          ? { row: n.row, column: n.column }
9076          : e(a, n, !r)
9077          ? { row: n.row + s, column: n.column + (n.row == a.row ? o : 0) }
9078          : { row: u.row, column: u.column }
9079      }
9080      r.implement(this, i),
9081        (this.getPosition = function() {
9082          return this.$clipPositionToDocument(this.row, this.column)
9083        }),
9084        (this.getDocument = function() {
9085          return this.document
9086        }),
9087        (this.$insertRight = !1),
9088        (this.onChange = function(e) {
9089          if (e.start.row == e.end.row && e.start.row != this.row) return
9090          if (e.start.row > this.row) return
9091          var n = t(e, { row: this.row, column: this.column }, this.$insertRight)
9092          this.setPosition(n.row, n.column, !0)
9093        }),
9094        (this.setPosition = function(e, t, n) {
9095          var r
9096          n ? (r = { row: e, column: t }) : (r = this.$clipPositionToDocument(e, t))
9097          if (this.row == r.row && this.column == r.column) return
9098          var i = { row: this.row, column: this.column }
9099          ;(this.row = r.row), (this.column = r.column), this._signal('change', { old: i, value: r })
9100        }),
9101        (this.detach = function() {
9102          this.document.removeEventListener('change', this.$onChange)
9103        }),
9104        (this.attach = function(e) {
9105          ;(this.document = e || this.document), this.document.on('change', this.$onChange)
9106        }),
9107        (this.$clipPositionToDocument = function(e, t) {
9108          var n = {}
9109          return (
9110            e >= this.document.getLength()
9111              ? ((n.row = Math.max(0, this.document.getLength() - 1)), (n.column = this.document.getLine(n.row).length))
9112              : e < 0
9113              ? ((n.row = 0), (n.column = 0))
9114              : ((n.row = e), (n.column = Math.min(this.document.getLine(n.row).length, Math.max(0, t)))),
9115            t < 0 && (n.column = 0),
9116            n
9117          )
9118        })
9119    }.call(s.prototype))
9120  }),
9121  define('ace/document', [
9122    'require',
9123    'exports',
9124    'module',
9125    'ace/lib/oop',
9126    'ace/apply_delta',
9127    'ace/lib/event_emitter',
9128    'ace/range',
9129    'ace/anchor'
9130  ], function(e, t, n) {
9131    'use strict'
9132    var r = e('./lib/oop'),
9133      i = e('./apply_delta').applyDelta,
9134      s = e('./lib/event_emitter').EventEmitter,
9135      o = e('./range').Range,
9136      u = e('./anchor').Anchor,
9137      a = function(e) {
9138        ;(this.$lines = ['']),
9139          e.length === 0
9140            ? (this.$lines = [''])
9141            : Array.isArray(e)
9142            ? this.insertMergedLines({ row: 0, column: 0 }, e)
9143            : this.insert({ row: 0, column: 0 }, e)
9144      }
9145    ;(function() {
9146      r.implement(this, s),
9147        (this.setValue = function(e) {
9148          var t = this.getLength() - 1
9149          this.remove(new o(0, 0, t, this.getLine(t).length)), this.insert({ row: 0, column: 0 }, e)
9150        }),
9151        (this.getValue = function() {
9152          return this.getAllLines().join(this.getNewLineCharacter())
9153        }),
9154        (this.createAnchor = function(e, t) {
9155          return new u(this, e, t)
9156        }),
9157        'aaa'.split(/a/).length === 0
9158          ? (this.$split = function(e) {
9159              return e.replace(/\r\n|\r/g, '\n').split('\n')
9160            })
9161          : (this.$split = function(e) {
9162              return e.split(/\r\n|\r|\n/)
9163            }),
9164        (this.$detectNewLine = function(e) {
9165          var t = e.match(/^.*?(\r\n|\r|\n)/m)
9166          ;(this.$autoNewLine = t ? t[1] : '\n'), this._signal('changeNewLineMode')
9167        }),
9168        (this.getNewLineCharacter = function() {
9169          switch (this.$newLineMode) {
9170            case 'windows':
9171              return '\r\n'
9172            case 'unix':
9173              return '\n'
9174            default:
9175              return this.$autoNewLine || '\n'
9176          }
9177        }),
9178        (this.$autoNewLine = ''),
9179        (this.$newLineMode = 'auto'),
9180        (this.setNewLineMode = function(e) {
9181          if (this.$newLineMode === e) return
9182          ;(this.$newLineMode = e), this._signal('changeNewLineMode')
9183        }),
9184        (this.getNewLineMode = function() {
9185          return this.$newLineMode
9186        }),
9187        (this.isNewLine = function(e) {
9188          return e == '\r\n' || e == '\r' || e == '\n'
9189        }),
9190        (this.getLine = function(e) {
9191          return this.$lines[e] || ''
9192        }),
9193        (this.getLines = function(e, t) {
9194          return this.$lines.slice(e, t + 1)
9195        }),
9196        (this.getAllLines = function() {
9197          return this.getLines(0, this.getLength())
9198        }),
9199        (this.getLength = function() {
9200          return this.$lines.length
9201        }),
9202        (this.getTextRange = function(e) {
9203          return this.getLinesForRange(e).join(this.getNewLineCharacter())
9204        }),
9205        (this.getLinesForRange = function(e) {
9206          var t
9207          if (e.start.row === e.end.row) t = [this.getLine(e.start.row).substring(e.start.column, e.end.column)]
9208          else {
9209            ;(t = this.getLines(e.start.row, e.end.row)), (t[0] = (t[0] || '').substring(e.start.column))
9210            var n = t.length - 1
9211            e.end.row - e.start.row == n && (t[n] = t[n].substring(0, e.end.column))
9212          }
9213          return t
9214        }),
9215        (this.insertLines = function(e, t) {
9216          return (
9217            console.warn('Use of document.insertLines is deprecated. Use the insertFullLines method instead.'),
9218            this.insertFullLines(e, t)
9219          )
9220        }),
9221        (this.removeLines = function(e, t) {
9222          return (
9223            console.warn('Use of document.removeLines is deprecated. Use the removeFullLines method instead.'),
9224            this.removeFullLines(e, t)
9225          )
9226        }),
9227        (this.insertNewLine = function(e) {
9228          return (
9229            console.warn(
9230              "Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead."
9231            ),
9232            this.insertMergedLines(e, ['', ''])
9233          )
9234        }),
9235        (this.insert = function(e, t) {
9236          return this.getLength() <= 1 && this.$detectNewLine(t), this.insertMergedLines(e, this.$split(t))
9237        }),
9238        (this.insertInLine = function(e, t) {
9239          var n = this.clippedPos(e.row, e.column),
9240            r = this.pos(e.row, e.column + t.length)
9241          return this.applyDelta({ start: n, end: r, action: 'insert', lines: [t] }, !0), this.clonePos(r)
9242        }),
9243        (this.clippedPos = function(e, t) {
9244          var n = this.getLength()
9245          e === undefined ? (e = n) : e < 0 ? (e = 0) : e >= n && ((e = n - 1), (t = undefined))
9246          var r = this.getLine(e)
9247          return t == undefined && (t = r.length), (t = Math.min(Math.max(t, 0), r.length)), { row: e, column: t }
9248        }),
9249        (this.clonePos = function(e) {
9250          return { row: e.row, column: e.column }
9251        }),
9252        (this.pos = function(e, t) {
9253          return { row: e, column: t }
9254        }),
9255        (this.$clipPosition = function(e) {
9256          var t = this.getLength()
9257          return (
9258            e.row >= t
9259              ? ((e.row = Math.max(0, t - 1)), (e.column = this.getLine(t - 1).length))
9260              : ((e.row = Math.max(0, e.row)),
9261                (e.column = Math.min(Math.max(e.column, 0), this.getLine(e.row).length))),
9262            e
9263          )
9264        }),
9265        (this.insertFullLines = function(e, t) {
9266          e = Math.min(Math.max(e, 0), this.getLength())
9267          var n = 0
9268          e < this.getLength()
9269            ? ((t = t.concat([''])), (n = 0))
9270            : ((t = [''].concat(t)), e--, (n = this.$lines[e].length)),
9271            this.insertMergedLines({ row: e, column: n }, t)
9272        }),
9273        (this.insertMergedLines = function(e, t) {
9274          var n = this.clippedPos(e.row, e.column),
9275            r = { row: n.row + t.length - 1, column: (t.length == 1 ? n.column : 0) + t[t.length - 1].length }
9276          return this.applyDelta({ start: n, end: r, action: 'insert', lines: t }), this.clonePos(r)
9277        }),
9278        (this.remove = function(e) {
9279          var t = this.clippedPos(e.start.row, e.start.column),
9280            n = this.clippedPos(e.end.row, e.end.column)
9281          return (
9282            this.applyDelta({ start: t, end: n, action: 'remove', lines: this.getLinesForRange({ start: t, end: n }) }),
9283            this.clonePos(t)
9284          )
9285        }),
9286        (this.removeInLine = function(e, t, n) {
9287          var r = this.clippedPos(e, t),
9288            i = this.clippedPos(e, n)
9289          return (
9290            this.applyDelta(
9291              { start: r, end: i, action: 'remove', lines: this.getLinesForRange({ start: r, end: i }) },
9292              !0
9293            ),
9294            this.clonePos(r)
9295          )
9296        }),
9297        (this.removeFullLines = function(e, t) {
9298          ;(e = Math.min(Math.max(0, e), this.getLength() - 1)), (t = Math.min(Math.max(0, t), this.getLength() - 1))
9299          var n = t == this.getLength() - 1 && e > 0,
9300            r = t < this.getLength() - 1,
9301            i = n ? e - 1 : e,
9302            s = n ? this.getLine(i).length : 0,
9303            u = r ? t + 1 : t,
9304            a = r ? 0 : this.getLine(u).length,
9305            f = new o(i, s, u, a),
9306            l = this.$lines.slice(e, t + 1)
9307          return this.applyDelta({ start: f.start, end: f.end, action: 'remove', lines: this.getLinesForRange(f) }), l
9308        }),
9309        (this.removeNewLine = function(e) {
9310          e < this.getLength() - 1 &&
9311            e >= 0 &&
9312            this.applyDelta({
9313              start: this.pos(e, this.getLine(e).length),
9314              end: this.pos(e + 1, 0),
9315              action: 'remove',
9316              lines: ['', '']
9317            })
9318        }),
9319        (this.replace = function(e, t) {
9320          e instanceof o || (e = o.fromPoints(e.start, e.end))
9321          if (t.length === 0 && e.isEmpty()) return e.start
9322          if (t == this.getTextRange(e)) return e.end
9323          this.remove(e)
9324          var n
9325          return t ? (n = this.insert(e.start, t)) : (n = e.start), n
9326        }),
9327        (this.applyDeltas = function(e) {
9328          for (var t = 0; t < e.length; t++) this.applyDelta(e[t])
9329        }),
9330        (this.revertDeltas = function(e) {
9331          for (var t = e.length - 1; t >= 0; t--) this.revertDelta(e[t])
9332        }),
9333        (this.applyDelta = function(e, t) {
9334          var n = e.action == 'insert'
9335          if (n ? e.lines.length <= 1 && !e.lines[0] : !o.comparePoints(e.start, e.end)) return
9336          n && e.lines.length > 2e4
9337            ? this.$splitAndapplyLargeDelta(e, 2e4)
9338            : (i(this.$lines, e, t), this._signal('change', e))
9339        }),
9340        (this.$splitAndapplyLargeDelta = function(e, t) {
9341          var n = e.lines,
9342            r = n.length - t + 1,
9343            i = e.start.row,
9344            s = e.start.column
9345          for (var o = 0, u = 0; o < r; o = u) {
9346            u += t - 1
9347            var a = n.slice(o, u)
9348            a.push(''),
9349              this.applyDelta(
9350                { start: this.pos(i + o, s), end: this.pos(i + u, (s = 0)), action: e.action, lines: a },
9351                !0
9352              )
9353          }
9354          ;(e.lines = n.slice(o)), (e.start.row = i + o), (e.start.column = s), this.applyDelta(e, !0)
9355        }),
9356        (this.revertDelta = function(e) {
9357          this.applyDelta({
9358            start: this.clonePos(e.start),
9359            end: this.clonePos(e.end),
9360            action: e.action == 'insert' ? 'remove' : 'insert',
9361            lines: e.lines.slice()
9362          })
9363        }),
9364        (this.indexToPosition = function(e, t) {
9365          var n = this.$lines || this.getAllLines(),
9366            r = this.getNewLineCharacter().length
9367          for (var i = t || 0, s = n.length; i < s; i++) {
9368            e -= n[i].length + r
9369            if (e < 0) return { row: i, column: e + n[i].length + r }
9370          }
9371          return { row: s - 1, column: e + n[s - 1].length + r }
9372        }),
9373        (this.positionToIndex = function(e, t) {
9374          var n = this.$lines || this.getAllLines(),
9375            r = this.getNewLineCharacter().length,
9376            i = 0,
9377            s = Math.min(e.row, n.length)
9378          for (var o = t || 0; o < s; ++o) i += n[o].length + r
9379          return i + e.column
9380        })
9381    }.call(a.prototype),
9382      (t.Document = a))
9383  }),
9384  define('ace/background_tokenizer', ['require', 'exports', 'module', 'ace/lib/oop', 'ace/lib/event_emitter'], function(
9385    e,
9386    t,
9387    n
9388  ) {
9389    'use strict'
9390    var r = e('./lib/oop'),
9391      i = e('./lib/event_emitter').EventEmitter,
9392      s = function(e, t) {
9393        ;(this.running = !1), (this.lines = []), (this.states = []), (this.currentLine = 0), (this.tokenizer = e)
9394        var n = this
9395        this.$worker = function() {
9396          if (!n.running) return
9397          var e = new Date(),
9398            t = n.currentLine,
9399            r = -1,
9400            i = n.doc,
9401            s = t
9402          while (n.lines[t]) t++
9403          var o = i.getLength(),
9404            u = 0
9405          n.running = !1
9406          while (t < o) {
9407            n.$tokenizeRow(t), (r = t)
9408            do t++
9409            while (n.lines[t])
9410            u++
9411            if (u % 5 === 0 && new Date() - e > 20) {
9412              n.running = setTimeout(n.$worker, 20)
9413              break
9414            }
9415          }
9416          ;(n.currentLine = t), r == -1 && (r = t), s <= r && n.fireUpdateEvent(s, r)
9417        }
9418      }
9419    ;(function() {
9420      r.implement(this, i),
9421        (this.setTokenizer = function(e) {
9422          ;(this.tokenizer = e), (this.lines = []), (this.states = []), this.start(0)
9423        }),
9424        (this.setDocument = function(e) {
9425          ;(this.doc = e), (this.lines = []), (this.states = []), this.stop()
9426        }),
9427        (this.fireUpdateEvent = function(e, t) {
9428          var n = { first: e, last: t }
9429          this._signal('update', { data: n })
9430        }),
9431        (this.start = function(e) {
9432          ;(this.currentLine = Math.min(e || 0, this.currentLine, this.doc.getLength())),
9433            this.lines.splice(this.currentLine, this.lines.length),
9434            this.states.splice(this.currentLine, this.states.length),
9435            this.stop(),
9436            (this.running = setTimeout(this.$worker, 700))
9437        }),
9438        (this.scheduleStart = function() {
9439          this.running || (this.running = setTimeout(this.$worker, 700))
9440        }),
9441        (this.$updateOnChange = function(e) {
9442          var t = e.start.row,
9443            n = e.end.row - t
9444          if (n === 0) this.lines[t] = null
9445          else if (e.action == 'remove') this.lines.splice(t, n + 1, null), this.states.splice(t, n + 1, null)
9446          else {
9447            var r = Array(n + 1)
9448            r.unshift(t, 1), this.lines.splice.apply(this.lines, r), this.states.splice.apply(this.states, r)
9449          }
9450          ;(this.currentLine = Math.min(t, this.currentLine, this.doc.getLength())), this.stop()
9451        }),
9452        (this.stop = function() {
9453          this.running && clearTimeout(this.running), (this.running = !1)
9454        }),
9455        (this.getTokens = function(e) {
9456          return this.lines[e] || this.$tokenizeRow(e)
9457        }),
9458        (this.getState = function(e) {
9459          return this.currentLine == e && this.$tokenizeRow(e), this.states[e] || 'start'
9460        }),
9461        (this.$tokenizeRow = function(e) {
9462          var t = this.doc.getLine(e),
9463            n = this.states[e - 1],
9464            r = this.tokenizer.getLineTokens(t, n, e)
9465          return (
9466            this.states[e] + '' != r.state + ''
9467              ? ((this.states[e] = r.state),
9468                (this.lines[e + 1] = null),
9469                this.currentLine > e + 1 && (this.currentLine = e + 1))
9470              : this.currentLine == e && (this.currentLine = e + 1),
9471            (this.lines[e] = r.tokens)
9472          )
9473        })
9474    }.call(s.prototype),
9475      (t.BackgroundTokenizer = s))
9476  }),
9477  define('ace/search_highlight', ['require', 'exports', 'module', 'ace/lib/lang', 'ace/lib/oop', 'ace/range'], function(
9478    e,
9479    t,
9480    n
9481  ) {
9482    'use strict'
9483    var r = e('./lib/lang'),
9484      i = e('./lib/oop'),
9485      s = e('./range').Range,
9486      o = function(e, t, n) {
9487        this.setRegexp(e), (this.clazz = t), (this.type = n || 'text')
9488      }
9489    ;(function() {
9490      ;(this.MAX_RANGES = 500),
9491        (this.setRegexp = function(e) {
9492          if (this.regExp + '' == e + '') return
9493          ;(this.regExp = e), (this.cache = [])
9494        }),
9495        (this.update = function(e, t, n, i) {
9496          if (!this.regExp) return
9497          var o = i.firstRow,
9498            u = i.lastRow
9499          for (var a = o; a <= u; a++) {
9500            var f = this.cache[a]
9501            f == null &&
9502              ((f = r.getMatchOffsets(n.getLine(a), this.regExp)),
9503              f.length > this.MAX_RANGES && (f = f.slice(0, this.MAX_RANGES)),
9504              (f = f.map(function(e) {
9505                return new s(a, e.offset, a, e.offset + e.length)
9506              })),
9507              (this.cache[a] = f.length ? f : ''))
9508            for (var l = f.length; l--; ) t.drawSingleLineMarker(e, f[l].toScreenRange(n), this.clazz, i)
9509          }
9510        })
9511    }.call(o.prototype),
9512      (t.SearchHighlight = o))
9513  }),
9514  define('ace/edit_session/fold_line', ['require', 'exports', 'module', 'ace/range'], function(e, t, n) {
9515    'use strict'
9516    function i(e, t) {
9517      ;(this.foldData = e), Array.isArray(t) ? (this.folds = t) : (t = this.folds = [t])
9518      var n = t[t.length - 1]
9519      ;(this.range = new r(t[0].start.row, t[0].start.column, n.end.row, n.end.column)),
9520        (this.start = this.range.start),
9521        (this.end = this.range.end),
9522        this.folds.forEach(function(e) {
9523          e.setFoldLine(this)
9524        }, this)
9525    }
9526    var r = e('../range').Range
9527    ;(function() {
9528      ;(this.shiftRow = function(e) {
9529        ;(this.start.row += e),
9530          (this.end.row += e),
9531          this.folds.forEach(function(t) {
9532            ;(t.start.row += e), (t.end.row += e)
9533          })
9534      }),
9535        (this.addFold = function(e) {
9536          if (e.sameRow) {
9537            if (e.start.row < this.startRow || e.endRow > this.endRow)
9538              throw new Error("Can't add a fold to this FoldLine as it has no connection")
9539            this.folds.push(e),
9540              this.folds.sort(function(e, t) {
9541                return -e.range.compareEnd(t.start.row, t.start.column)
9542              }),
9543              this.range.compareEnd(e.start.row, e.start.column) > 0
9544                ? ((this.end.row = e.end.row), (this.end.column = e.end.column))
9545                : this.range.compareStart(e.end.row, e.end.column) < 0 &&
9546                  ((this.start.row = e.start.row), (this.start.column = e.start.column))
9547          } else if (e.start.row == this.end.row)
9548            this.folds.push(e), (this.end.row = e.end.row), (this.end.column = e.end.column)
9549          else {
9550            if (e.end.row != this.start.row)
9551              throw new Error("Trying to add fold to FoldRow that doesn't have a matching row")
9552            this.folds.unshift(e), (this.start.row = e.start.row), (this.start.column = e.start.column)
9553          }
9554          e.foldLine = this
9555        }),
9556        (this.containsRow = function(e) {
9557          return e >= this.start.row && e <= this.end.row
9558        }),
9559        (this.walk = function(e, t, n) {
9560          var r = 0,
9561            i = this.folds,
9562            s,
9563            o,
9564            u,
9565            a = !0
9566          t == null && ((t = this.end.row), (n = this.end.column))
9567          for (var f = 0; f < i.length; f++) {
9568            ;(s = i[f]), (o = s.range.compareStart(t, n))
9569            if (o == -1) {
9570              e(null, t, n, r, a)
9571              return
9572            }
9573            ;(u = e(null, s.start.row, s.start.column, r, a)),
9574              (u = !u && e(s.placeholder, s.start.row, s.start.column, r))
9575            if (u || o === 0) return
9576            ;(a = !s.sameRow), (r = s.end.column)
9577          }
9578          e(null, t, n, r, a)
9579        }),
9580        (this.getNextFoldTo = function(e, t) {
9581          var n, r
9582          for (var i = 0; i < this.folds.length; i++) {
9583            ;(n = this.folds[i]), (r = n.range.compareEnd(e, t))
9584            if (r == -1) return { fold: n, kind: 'after' }
9585            if (r === 0) return { fold: n, kind: 'inside' }
9586          }
9587          return null
9588        }),
9589        (this.addRemoveChars = function(e, t, n) {
9590          var r = this.getNextFoldTo(e, t),
9591            i,
9592            s
9593          if (r) {
9594            i = r.fold
9595            if (r.kind == 'inside' && i.start.column != t && i.start.row != e)
9596              window.console && window.console.log(e, t, i)
9597            else if (i.start.row == e) {
9598              s = this.folds
9599              var o = s.indexOf(i)
9600              o === 0 && (this.start.column += n)
9601              for (o; o < s.length; o++) {
9602                ;(i = s[o]), (i.start.column += n)
9603                if (!i.sameRow) return
9604                i.end.column += n
9605              }
9606              this.end.column += n
9607            }
9608          }
9609        }),
9610        (this.split = function(e, t) {
9611          var n = this.getNextFoldTo(e, t)
9612          if (!n || n.kind == 'inside') return null
9613          var r = n.fold,
9614            s = this.folds,
9615            o = this.foldData,
9616            u = s.indexOf(r),
9617            a = s[u - 1]
9618          ;
9618(this.end.row = a.end.row), (this.end.column = a.end.column), (s = s.splice(u, s.length - u))
9619          var f = new i(o, s)
9620          return o.splice(o.indexOf(this) + 1, 0, f), f
9621        }),
9622        (this.merge = function(e) {
9623          var t = e.folds
9624          for (var n = 0; n < t.length; n++) this.addFold(t[n])
9625          var r = this.foldData
9626          r.splice(r.indexOf(e), 1)
9627        }),
9628        (this.toString = function() {
9629          var e = [this.range.toString() + ': [']
9630          return (
9631            this.folds.forEach(function(t) {
9632              e.push('  ' + t.toString())
9633            }),
9634            e.push(']'),
9635            e.join('\n')
9636          )
9637        }),
9638        (this.idxToPosition = function(e) {
9639          var t = 0
9640          for (var n = 0; n < this.folds.length; n++) {
9641            var r = this.folds[n]
9642            e -= r.start.column - t
9643            if (e < 0) return { row: r.start.row, column: r.start.column + e }
9644            e -= r.placeholder.length
9645            if (e < 0) return r.start
9646            t = r.end.column
9647          }
9648          return { row: this.end.row, column: this.end.column + e }
9649        })
9650    }.call(i.prototype),
9651      (t.FoldLine = i))
9652  }),
9653  define('ace/range_list', ['require', 'exports', 'module', 'ace/range'], function(e, t, n) {
9654    'use strict'
9655    var r = e('./range').Range,
9656      i = r.comparePoints,
9657      s = function() {
9658        this.ranges = []
9659      }
9660    ;(function() {
9661      ;(this.comparePoints = i),
9662        (this.pointIndex = function(e, t, n) {
9663          var r = this.ranges
9664          for (var s = n || 0; s < r.length; s++) {
9665            var o = r[s],
9666              u = i(e, o.end)
9667            if (u > 0) continue
9668            var a = i(e, o.start)
9669            return u === 0 ? (t && a !== 0 ? -s - 2 : s) : a > 0 || (a === 0 && !t) ? s : -s - 1
9670          }
9671          return -s - 1
9672        }),
9673        (this.add = function(e) {
9674          var t = !e.isEmpty(),
9675            n = this.pointIndex(e.start, t)
9676          n < 0 && (n = -n - 1)
9677          var r = this.pointIndex(e.end, t, n)
9678          return r < 0 ? (r = -r - 1) : r++, this.ranges.splice(n, r - n, e)
9679        }),
9680        (this.addList = function(e) {
9681          var t = []
9682          for (var n = e.length; n--; ) t.push.apply(t, this.add(e[n]))
9683          return t
9684        }),
9685        (this.substractPoint = function(e) {
9686          var t = this.pointIndex(e)
9687          if (t >= 0) return this.ranges.splice(t, 1)
9688        }),
9689        (this.merge = function() {
9690          var e = [],
9691            t = this.ranges
9692          t = t.sort(function(e, t) {
9693            return i(e.start, t.start)
9694          })
9695          var n = t[0],
9696            r
9697          for (var s = 1; s < t.length; s++) {
9698            ;(r = n), (n = t[s])
9699            var o = i(r.end, n.start)
9700            if (o < 0) continue
9701            if (o == 0 && !r.isEmpty() && !n.isEmpty()) continue
9702            i(r.end, n.end) < 0 && ((r.end.row = n.end.row), (r.end.column = n.end.column)),
9703              t.splice(s, 1),
9704              e.push(n),
9705              (n = r),
9706              s--
9707          }
9708          return (this.ranges = t), e
9709        }),
9710        (this.contains = function(e, t) {
9711          return this.pointIndex({ row: e, column: t }) >= 0
9712        }),
9713        (this.containsPoint = function(e) {
9714          return this.pointIndex(e) >= 0
9715        }),
9716        (this.rangeAtPoint = function(e) {
9717          var t = this.pointIndex(e)
9718          if (t >= 0) return this.ranges[t]
9719        }),
9720        (this.clipRows = function(e, t) {
9721          var n = this.ranges
9722          if (n[0].start.row > t || n[n.length - 1].start.row < e) return []
9723          var r = this.pointIndex({ row: e, column: 0 })
9724          r < 0 && (r = -r - 1)
9725          var i = this.pointIndex({ row: t, column: 0 }, r)
9726          i < 0 && (i = -i - 1)
9727          var s = []
9728          for (var o = r; o < i; o++) s.push(n[o])
9729          return s
9730        }),
9731        (this.removeAll = function() {
9732          return this.ranges.splice(0, this.ranges.length)
9733        }),
9734        (this.attach = function(e) {
9735          this.session && this.detach(),
9736            (this.session = e),
9737            (this.onChange = this.$onChange.bind(this)),
9738            this.session.on('change', this.onChange)
9739        }),
9740        (this.detach = function() {
9741          if (!this.session) return
9742          this.session.removeListener('change', this.onChange), (this.session = null)
9743        }),
9744        (this.$onChange = function(e) {
9745          var t = e.start,
9746            n = e.end,
9747            r = t.row,
9748            i = n.row,
9749            s = this.ranges
9750          for (var o = 0, u = s.length; o < u; o++) {
9751            var a = s[o]
9752            if (a.end.row >= r) break
9753          }
9754          if (e.action == 'insert') {
9755            var f = i - r,
9756              l = -t.column + n.column
9757            for (; o < u; o++) {
9758              var a = s[o]
9759              if (a.start.row > r) break
9760              a.start.row == r &&
9761                a.start.column >= t.column &&
9762                (a.start.column != t.column || !this.$insertRight) &&
9763                ((a.start.column += l), (a.start.row += f))
9764              if (a.end.row == r && a.end.column >= t.column) {
9765                if (a.end.column == t.column && this.$insertRight) continue
9766                a.end.column == t.column &&
9767                  l > 0 &&
9768                  o < u - 1 &&
9769                  a.end.column > a.start.column &&
9770                  a.end.column == s[o + 1].start.column &&
9771                  (a.end.column -= l),
9772                  (a.end.column += l),
9773                  (a.end.row += f)
9774              }
9775            }
9776          } else {
9777            var f = r - i,
9778              l = t.column - n.column
9779            for (; o < u; o++) {
9780              var a = s[o]
9781              if (a.start.row > i) break
9782              a.end.row < i && ((a.end.row = r), (a.end.column = t.column))
9783              if (a.start.row < i || (a.start.row == i && a.start.column <= n.colum))
9784                (a.start.row = r), (a.start.column = t.column)
9785              if (a.end.row == i)
9786                if (a.end.column <= n.column) {
9787                  if (f || a.end.column > t.column) (a.end.column = t.column), (a.end.row = t.row)
9788                } else (a.end.column += l), (a.end.row += f)
9789              if (a.start.row == i)
9790                if (a.start.column <= n.column) {
9791                  if (f || a.start.column > t.column) (a.start.column = t.column), (a.start.row = t.row)
9792                } else (a.start.column += l), (a.start.row += f)
9793            }
9794          }
9795          if (f != 0 && o < u)
9796            for (; o < u; o++) {
9797              var a = s[o]
9798              ;(a.start.row += f), (a.end.row += f)
9799            }
9800        })
9801    }.call(s.prototype),
9802      (t.RangeList = s))
9803  }),
9804  define('ace/edit_session/fold', [
9805    'require',
9806    'exports',
9807    'module',
9808    'ace/range',
9809    'ace/range_list',
9810    'ace/lib/oop'
9811  ], function(e, t, n) {
9812    'use strict'
9813    function u(e, t) {
9814      ;(e.row -= t.row), e.row == 0 && (e.column -= t.column)
9815    }
9816    function a(e, t) {
9817      u(e.start, t), u(e.end, t)
9818    }
9819    function f(e, t) {
9820      e.row == 0 && (e.column += t.column), (e.row += t.row)
9821    }
9822    function l(e, t) {
9823      f(e.start, t), f(e.end, t)
9824    }
9825    var r = e('../range').Range,
9826      i = e('../range_list').RangeList,
9827      s = e('../lib/oop'),
9828      o = (t.Fold = function(e, t) {
9829        ;(this.foldLine = null),
9830          (this.placeholder = t),
9831          (this.range = e),
9832          (this.start = e.start),
9833          (this.end = e.end),
9834          (this.sameRow = e.start.row == e.end.row),
9835          (this.subFolds = this.ranges = [])
9836      })
9837    s.inherits(o, i),
9838      function() {
9839        ;(this.toString = function() {
9840          return '"' + this.placeholder + '" ' + this.range.toString()
9841        }),
9842          (this.setFoldLine = function(e) {
9843            ;(this.foldLine = e),
9844              this.subFolds.forEach(function(t) {
9845                t.setFoldLine(e)
9846              })
9847          }),
9848          (this.clone = function() {
9849            var e = this.range.clone(),
9850              t = new o(e, this.placeholder)
9851            return (
9852              this.subFolds.forEach(function(e) {
9853                t.subFolds.push(e.clone())
9854              }),
9855              (t.collapseChildren = this.collapseChildren),
9856              t
9857            )
9858          }),
9859          (this.addSubFold = function(e) {
9860            if (this.range.isEqual(e)) return
9861            if (!this.range.containsRange(e))
9862              throw new Error("A fold can't intersect already existing fold" + e.range + this.range)
9863            a(e, this.start)
9864            var t = e.start.row,
9865              n = e.start.column
9866            for (var r = 0, i = -1; r < this.subFolds.length; r++) {
9867              i = this.subFolds[r].range.compare(t, n)
9868              if (i != 1) break
9869            }
9870            var s = this.subFolds[r]
9871            if (i == 0) return s.addSubFold(e)
9872            var t = e.range.end.row,
9873              n = e.range.end.column
9874            for (var o = r, i = -1; o < this.subFolds.length; o++) {
9875              i = this.subFolds[o].range.compare(t, n)
9876              if (i != 1) break
9877            }
9878            var u = this.subFolds[o]
9879            if (i == 0) throw new Error("A fold can't intersect already existing fold" + e.range + this.range)
9880            var f = this.subFolds.splice(r, o - r, e)
9881            return e.setFoldLine(this.foldLine), e
9882          }),
9883          (this.restoreRange = function(e) {
9884            return l(e, this.start)
9885          })
9886      }.call(o.prototype)
9887  }),
9888  define('ace/edit_session/folding', [
9889    'require',
9890    'exports',
9891    'module',
9892    'ace/range',
9893    'ace/edit_session/fold_line',
9894    'ace/edit_session/fold',
9895    'ace/token_iterator'
9896  ], function(e, t, n) {
9897    'use strict'
9898    function u() {
9899      ;(this.getFoldAt = function(e, t, n) {
9900        var r = this.getFoldLine(e)
9901        if (!r) return null
9902        var i = r.folds
9903        for (var s = 0; s < i.length; s++) {
9904          var o = i[s]
9905          if (o.range.contains(e, t)) {
9906            if (n == 1 && o.range.isEnd(e, t)) continue
9907            if (n == -1 && o.range.isStart(e, t)) continue
9908            return o
9909          }
9910        }
9911      }),
9912        (this.getFoldsInRange = function(e) {
9913          var t = e.start,
9914            n = e.end,
9915            r = this.$foldData,
9916            i = []
9917          ;(t.column += 1), (n.column -= 1)
9918          for (var s = 0; s < r.length; s++) {
9919            var o = r[s].range.compareRange(e)
9920            if (o == 2) continue
9921            if (o == -2) break
9922            var u = r[s].folds
9923            for (var a = 0; a < u.length; a++) {
9924              var f = u[a]
9925              o = f.range.compareRange(e)
9926              if (o == -2) break
9927              if (o == 2) continue
9928              if (o == 42) break
9929              i.push(f)
9930            }
9931          }
9932          return (t.column -= 1), (n.column += 1), i
9933        }),
9934        (this.getFoldsInRangeList = function(e) {
9935          if (Array.isArray(e)) {
9936            var t = []
9937            e.forEach(function(e) {
9938              t = t.concat(this.getFoldsInRange(e))
9939            }, this)
9940          } else var t = this.getFoldsInRange(e)
9941          return t
9942        }),
9943        (this.getAllFolds = function() {
9944          var e = [],
9945            t = this.$foldData
9946          for (var n = 0; n < t.length; n++) for (var r = 0; r < t[n].folds.length; r++) e.push(t[n].folds[r])
9947          return e
9948        }),
9949        (this.getFoldStringAt = function(e, t, n, r) {
9950          r = r || this.getFoldLine(e)
9951          if (!r) return null
9952          var i = { end: { column: 0 } },
9953            s,
9954            o
9955          for (var u = 0; u < r.folds.length; u++) {
9956            o = r.folds[u]
9957            var a = o.range.compareEnd(e, t)
9958            if (a == -1) {
9959              s = this.getLine(o.start.row).substring(i.end.column, o.start.column)
9960              break
9961            }
9962            if (a === 0) return null
9963            i = o
9964          }
9965          return (
9966            s || (s = this.getLine(o.start.row).substring(i.end.column)),
9967            n == -1 ? s.substring(0, t - i.end.column) : n == 1 ? s.substring(t - i.end.column) : s
9968          )
9969        }),
9970        (this.getFoldLine = function(e, t) {
9971          var n = this.$foldData,
9972            r = 0
9973          t && (r = n.indexOf(t)), r == -1 && (r = 0)
9974          for (r; r < n.length; r++) {
9975            var i = n[r]
9976            if (i.start.row <= e && i.end.row >= e) return i
9977            if (i.end.row > e) return null
9978          }
9979          return null
9980        }),
9981        (this.getNextFoldLine = function(e, t) {
9982          var n = this.$foldData,
9983            r = 0
9984          t && (r = n.indexOf(t)), r == -1 && (r = 0)
9985          for (r; r < n.length; r++) {
9986            var i = n[r]
9987            if (i.end.row >= e) return i
9988          }
9989          return null
9990        }),
9991        (this.getFoldedRowCount = function(e, t) {
9992          var n = this.$foldData,
9993            r = t - e + 1
9994          for (var i = 0; i < n.length; i++) {
9995            var s = n[i],
9996              o = s.end.row,
9997              u = s.start.row
9998            if (o >= t) {
9999              u < t && (u >= e ? (r -= t - u) : (r = 0))
10000              break
10001            }
10002            o >= e && (u >= e ? (r -= o - u) : (r -= o - e + 1))
10003          }
10004          return r
10005        }),
10006        (this.$addFoldLine = function(e) {
10007          return (
10008            this.$foldData.push(e),
10009            this.$foldData.sort(function(e, t) {
10010              return e.start.row - t.start.row
10011            }),
10012            e
10013          )
10014        }),
10015        (this.addFold = function(e, t) {
10016          var n = this.$foldData,
10017            r = !1,
10018            o
10019          e instanceof s ? (o = e) : ((o = new s(t, e)), (o.collapseChildren = t.collapseChildren)),
10020            this.$clipRangeToDocument(o.range)
10021          var u = o.start.row,
10022            a = o.start.column,
10023            f = o.end.row,
10024            l = o.end.column
10025          if (u < f || (u == f && a <= l - 2)) {
10026            var c = this.getFoldAt(u, a, 1),
10027              h = this.getFoldAt(f, l, -1)
10028            if (c && h == c) return c.addSubFold(o)
10029            c && !c.range.isStart(u, a) && this.removeFold(c), h && !h.range.isEnd(f, l) && this.removeFold(h)
10030            var p = this.getFoldsInRange(o.range)
10031            p.length > 0 &&
10032              (this.removeFolds(p),
10033              p.forEach(function(e) {
10034                o.addSubFold(e)
10035              }))
10036            for (var d = 0; d < n.length; d++) {
10037              var v = n[d]
10038              if (f == v.start.row) {
10039                v.addFold(o), (r = !0)
10040                break
10041              }
10042              if (u == v.end.row) {
10043                v.addFold(o), (r = !0)
10044                if (!o.sameRow) {
10045                  var m = n[d + 1]
10046                  if (m && m.start.row == f) {
10047                    v.merge(m)
10048                    break
10049                  }
10050                }
10051                break
10052              }
10053              if (f <= v.start.row) break
10054            }
10055            return (
10056              r || (v = this.$addFoldLine(new i(this.$foldData, o))),
10057              this.$useWrapMode
10058                ? this.$updateWrapData(v.start.row, v.start.row)
10059                : this.$updateRowLengthCache(v.start.row, v.start.row),
10060              (this.$modified = !0),
10061              this._signal('changeFold', { data: o, action: 'add' }),
10062              o
10063            )
10064          }
10065          throw new Error('The range has to be at least 2 characters width')
10066        }),
10067        (this.addFolds = function(e) {
10068          e.forEach(function(e) {
10069            this.addFold(e)
10070          }, this)
10071        }),
10072        (this.removeFold = function(e) {
10073          var t = e.foldLine,
10074            n = t.start.row,
10075            r = t.end.row,
10076            i = this.$foldData,
10077            s = t.folds
10078          if (s.length == 1) i.splice(i.indexOf(t), 1)
10079          else if (t.range.isEnd(e.end.row, e.end.column))
10080            s.pop(), (t.end.row = s[s.length - 1].end.row), (t.end.column = s[s.length - 1].end.column)
10081          else if (t.range.isStart(e.start.row, e.start.column))
10082            s.shift(), (t.start.row = s[0].start.row), (t.start.column = s[0].start.column)
10083          else if (e.sameRow) s.splice(s.indexOf(e), 1)
10084          else {
10085            var o = t.split(e.start.row, e.start.column)
10086            ;(s = o.folds), s.shift(), (o.start.row = s[0].start.row), (o.start.column = s[0].start.column)
10087          }
10088          this.$updating || (this.$useWrapMode ? this.$updateWrapData(n, r) : this.$updateRowLengthCache(n, r)),
10089            (this.$modified = !0),
10090            this._signal('changeFold', { data: e, action: 'remove' })
10091        }),
10092        (this.removeFolds = function(e) {
10093          var t = []
10094          for (var n = 0; n < e.length; n++) t.push(e[n])
10095          t.forEach(function(e) {
10096            this.removeFold(e)
10097          }, this),
10098            (this.$modified = !0)
10099        }),
10100        (this.expandFold = function(e) {
10101          this.removeFold(e),
10102            e.subFolds.forEach(function(t) {
10103              e.restoreRange(t), this.addFold(t)
10104            }, this),
10105            e.collapseChildren > 0 && this.foldAll(e.start.row + 1, e.end.row, e.collapseChildren - 1),
10106            (e.subFolds = [])
10107        }),
10108        (this.expandFolds = function(e) {
10109          e.forEach(function(e) {
10110            this.expandFold(e)
10111          }, this)
10112        }),
10113        (this.unfold = function(e, t) {
10114          var n, i
10115          e == null
10116            ? ((n = new r(0, 0, this.getLength(), 0)), (t = !0))
10117            : typeof e == 'number'
10118            ? (n = new r(e, 0, e, this.getLine(e).length))
10119            : 'row' in e
10120            ? (n = r.fromPoints(e, e))
10121            : (n = e),
10122            (i = this.getFoldsInRangeList(n))
10123          if (t) this.removeFolds(i)
10124          else {
10125            var s = i
10126            while (s.length) this.expandFolds(s), (s = this.getFoldsInRangeList(n))
10127          }
10128          if (i.length) return i
10129        }),
10130        (this.isRowFolded = function(e, t) {
10131          return !!this.getFoldLine(e, t)
10132        }),
10133        (this.getRowFoldEnd = function(e, t) {
10134          var n = this.getFoldLine(e, t)
10135          return n ? n.end.row : e
10136        }),
10137        (this.getRowFoldStart = function(e, t) {
10138          var n = this.getFoldLine(e, t)
10139          return n ? n.start.row : e
10140        }),
10141        (this.getFoldDisplayLine = function(e, t, n, r, i) {
10142          r == null && (r = e.start.row),
10143            i == null && (i = 0),
10144            t == null && (t = e.end.row),
10145            n == null && (n = this.getLine(t).length)
10146          var s = this.doc,
10147            o = ''
10148          return (
10149            e.walk(
10150              function(e, t, n, u) {
10151                if (t < r) return
10152                if (t == r) {
10153                  if (n < i) return
10154                  u = Math.max(i, u)
10155                }
10156                e != null ? (o += e) : (o += s.getLine(t).substring(u, n))
10157              },
10158              t,
10159              n
10160            ),
10161            o
10162          )
10163        }),
10164        (this.getDisplayLine = function(e, t, n, r) {
10165          var i = this.getFoldLine(e)
10166          if (!i) {
10167            var s
10168            return (s = this.doc.getLine(e)), s.substring(r || 0, t || s.length)
10169          }
10170          return this.getFoldDisplayLine(i, e, t, n, r)
10171        }),
10172        (this.$cloneFoldData = function() {
10173          var e = []
10174          return (
10175            (e = this.$foldData.map(function(t) {
10176              var n = t.folds.map(function(e) {
10177                return e.clone()
10178              })
10179              return new i(e, n)
10180            })),
10181            e
10182          )
10183        }),
10184        (this.toggleFold = function(e) {
10185          var t = this.selection,
10186            n = t.getRange(),
10187            r,
10188            i
10189          if (n.isEmpty()) {
10190            var s = n.start
10191            r = this.getFoldAt(s.row, s.column)
10192            if (r) {
10193              this.expandFold(r)
10194              return
10195            }
10196            ;(i = this.findMatchingBracket(s))
10197              ? n.comparePoint(i) == 1
10198                ? (n.end = i)
10199                : ((n.start = i), n.start.column++, n.end.column--)
10200              : (i = this.findMatchingBracket({ row: s.row, column: s.column + 1 }))
10201              ? (n.comparePoint(i) == 1 ? (n.end = i) : (n.start = i), n.start.column++)
10202              : (n = this.getCommentFoldRange(s.row, s.column) || n)
10203          } else {
10204            var o = this.getFoldsInRange(n)
10205            if (e && o.length) {
10206              this.expandFolds(o)
10207              return
10208            }
10209            o.length == 1 && (r = o[0])
10210          }
10211          r || (r = this.getFoldAt(n.start.row, n.start.column))
10212          if (r && r.range.toString() == n.toString()) {
10213            this.expandFold(r)
10214            return
10215          }
10216          var u = '...'
10217          if (!n.isMultiLine()) {
10218            u = this.getTextRange(n)
10219            if (u.length < 4) return
10220            u = u.trim().substring(0, 2) + '..'
10221          }
10222          this.addFold(u, n)
10223        }),
10224        (this.getCommentFoldRange = function(e, t, n) {
10225          var i = new o(this, e, t),
10226            s = i.getCurrentToken(),
10227            u = s.type
10228          if (s && /^comment|string/.test(u)) {
10229            ;(u = u.match(/comment|string/)[0]), u == 'comment' && (u += '|doc-start')
10230            var a = new RegExp(u),
10231              f = new r()
10232            if (n != 1) {
10233              do s = i.stepBackward()
10234              while (s && a.test(s.type))
10235              i.stepForward()
10236            }
10237            ;(f.start.row = i.getCurrentTokenRow()),
10238              (f.start.column = i.getCurrentTokenColumn() + 2),
10239              (i = new o(this, e, t))
10240            if (n != -1) {
10241              var l = -1
10242              do {
10243                s = i.stepForward()
10244                if (l == -1) {
10245                  var c = this.getState(i.$row)
10246                  a.test(c) || (l = i.$row)
10247                } else if (i.$row > l) break
10248              } while (s && a.test(s.type))
10249              s = i.stepBackward()
10250            } else s = i.getCurrentToken()
10251            return (
10252              (f.end.row = i.getCurrentTokenRow()), (f.end.column = i.getCurrentTokenColumn() + s.value.length - 2), f
10253            )
10254          }
10255        }),
10256        (this.foldAll = function(e, t, n) {
10257          n == undefined && (n = 1e5)
10258          var r = this.foldWidgets
10259          if (!r) return
10260          ;(t = t || this.getLength()), (e = e || 0)
10261          for (var i = e; i < t; i++) {
10262            r[i] == null && (r[i] = this.getFoldWidget(i))
10263            if (r[i] != 'start') continue
10264            var s = this.getFoldWidgetRange(i)
10265            if (s && s.isMultiLine() && s.end.row <= t && s.start.row >= e) {
10266              i = s.end.row
10267              try {
10268                var o = this.addFold('...', s)
10269                o && (o.collapseChildren = n)
10270              } catch (u) {}
10271            }
10272          }
10273        }),
10274        (this.$foldStyles = { manual: 1, markbegin: 1, markbeginend: 1 }),
10275        (this.$foldStyle = 'markbegin'),
10276        (this.setFoldStyle = function(e) {
10277          if (!this.$foldStyles[e])
10278            throw new Error('invalid fold style: ' + e + '[' + Object.keys(this.$foldStyles).join(', ') + ']')
10279          if (this.$foldStyle == e) return
10280          ;(this.$foldStyle = e), e == 'manual' && this.unfold()
10281          var t = this.$foldMode
10282          this.$setFolding(null), this.$setFolding(t)
10283        }),
10284        (this.$setFolding = function(e) {
10285          if (this.$foldMode == e) return
10286          ;(this.$foldMode = e),
10287            this.off('change', this.$updateFoldWidgets),
10288            this.off('tokenizerUpdate', this.$tokenizerUpdateFoldWidgets),
10289            this._signal('changeAnnotation')
10290          if (!e || this.$foldStyle == 'manual') {
10291            this.foldWidgets = null
10292            return
10293          }
10294          ;(this.foldWidgets = []),
10295            (this.getFoldWidget = e.getFoldWidget.bind(e, this, this.$foldStyle)),
10296            (this.getFoldWidgetRange = e.getFoldWidgetRange.bind(e, this, this.$foldStyle)),
10297            (this.$updateFoldWidgets = this.updateFoldWidgets.bind(this)),
10298            (this.$tokenizerUpdateFoldWidgets = this.tokenizerUpdateFoldWidgets.bind(this)),
10299            this.on('change', this.$updateFoldWidgets),
10300            this.on('tokenizerUpdate', this.$tokenizerUpdateFoldWidgets)
10301        }),
10302        (this.getParentFoldRangeData = function(e, t) {
10303          var n = this.foldWidgets
10304          if (!n || (t && n[e])) return {}
10305          var r = e - 1,
10306            i
10307          while (r >= 0) {
10308            var s = n[r]
10309            s == null && (s = n[r] = this.getFoldWidget(r))
10310            if (s == 'start') {
10311              var o = this.getFoldWidgetRange(r)
10312              i || (i = o)
10313              if (o && o.end.row >= e) break
10314            }
10315            r--
10316          }
10317          return { range: r !== -1 && o, firstRange: i }
10318        }),
10319        (this.onFoldWidgetClick = function(e, t) {
10320          t = t.domEvent
10321          var n = { children: t.shiftKey, all: t.ctrlKey || t.metaKey, siblings: t.altKey },
10322            r = this.$toggleFoldWidget(e, n)
10323          if (!r) {
10324            var i = t.target || t.srcElement
10325            i && /ace_fold-widget/.test(i.className) && (i.className += ' ace_invalid')
10326          }
10327        }),
10328        (this.$toggleFoldWidget = function(e, t) {
10329          if (!this.getFoldWidget) return
10330          var n = this.getFoldWidget(e),
10331            r = this.getLine(e),
10332            i = n === 'end' ? -1 : 1,
10333            s = this.getFoldAt(e, i === -1 ? 0 : r.length, i)
10334          if (s) return t.children || t.all ? this.removeFold(s) : this.expandFold(s), s
10335          var o = this.getFoldWidgetRange(e, !0)
10336          if (o && !o.isMultiLine()) {
10337            s = this.getFoldAt(o.start.row, o.start.column, 1)
10338            if (s && o.isEqual(s.range)) return this.removeFold(s), s
10339          }
10340          if (t.siblings) {
10341            var u = this.getParentFoldRangeData(e)
10342            if (u.range)
10343              var a = u.range.start.row + 1,
10344                f = u.range.end.row
10345            this.foldAll(a, f, t.all ? 1e4 : 0)
10346          } else
10347            t.children
10348              ? ((f = o ? o.end.row : this.getLength()), this.foldAll(e + 1, f, t.all ? 1e4 : 0))
10349              : o && (t.all && (o.collapseChildren = 1e4), this.addFold('...', o))
10350          return o
10351        }),
10352        (this.toggleFoldWidget = function(e) {
10353          var t = this.selection.getCursor().row
10354          t = this.getRowFoldStart(t)
10355          var n = this.$toggleFoldWidget(t, {})
10356          if (n) return
10357          var r = this.getParentFoldRangeData(t, !0)
10358          n = r.range || r.firstRange
10359          if (n) {
10360            t = n.start.row
10361            var i = this.getFoldAt(t, this.getLine(t).length, 1)
10362            i ? this.removeFold(i) : this.addFold('...', n)
10363          }
10364        }),
10365        (this.updateFoldWidgets = function(e) {
10366          var t = e.start.row,
10367            n = e.end.row - t
10368          if (n === 0) this.foldWidgets[t] = null
10369          else if (e.action == 'remove') this.foldWidgets.splice(t, n + 1, null)
10370          else {
10371            var r = Array(n + 1)
10372            r.unshift(t, 1), this.foldWidgets.splice.apply(this.foldWidgets, r)
10373          }
10374        }),
10375        (this.tokenizerUpdateFoldWidgets = function(e) {
10376          var t = e.data
10377          t.first != t.last &&
10378            this.foldWidgets.length > t.first &&
10379            this.foldWidgets.splice(t.first, this.foldWidgets.length)
10380        })
10381    }
10382    var r = e('../range').Range,
10383      i = e('./fold_line').FoldLine,
10384      s = e('./fold').Fold,
10385      o = e('../token_iterator').TokenIterator
10386    t.Folding = u
10387  }),
10388  define('ace/edit_session/bracket_match', [
10389    'require',
10390    'exports',
10391    'module',
10392    'ace/token_iterator',
10393    'ace/range'
10394  ], function(e, t, n) {
10395    'use strict'
10396    function s() {
10397      ;(this.findMatchingBracket = function(e, t) {
10398        if (e.column == 0) return null
10399        var n = t || this.getLine(e.row).charAt(e.column - 1)
10400        if (n == '') return null
10401        var r = n.match(/([\(\[\{])|([\)\]\}])/)
10402        return r ? (r[1] ? this.$findClosingBracket(r[1], e) : this.$findOpeningBracket(r[2], e)) : null
10403      }),
10404        (this.getBracketRange = function(e) {
10405          var t = this.getLine(e.row),
10406            n = !0,
10407            r,
10408            s = t.charAt(e.column - 1),
10409            o = s && s.match(/([\(\[\{])|([\)\]\}])/)
10410          o ||
10411            ((s = t.charAt(e.column)),
10412            (e = { row: e.row, column: e.column + 1 }),
10413            (o = s && s.match(/([\(\[\{])|([\)\]\}])/)),
10414            (n = !1))
10415          if (!o) return null
10416          if (o[1]) {
10417            var u = this.$findClosingBracket(o[1], e)
10418            if (!u) return null
10419            ;(r = i.fromPoints(e, u)), n || (r.end.column++, r.start.column--), (r.cursor = r.end)
10420          } else {
10421            var u = this.$findOpeningBracket(o[2], e)
10422            if (!u) return null
10423            ;(r = i.fromPoints(u, e)), n || (r.start.column++, r.end.column--), (r.cursor = r.start)
10424          }
10425          return r
10426        }),
10427        (this.$brackets = { ')': '(', '(': ')', ']': '[', '[': ']', '{': '}', '}': '{' }),
10428        (this.$findOpeningBracket = function(e, t, n) {
10429          var i = this.$brackets[e],
10430            s = 1,
10431            o = new r(this, t.row, t.column),
10432            u = o.getCurrentToken()
10433          u || (u = o.stepForward())
10434          if (!u) return
10435          n ||
10436            (n = new RegExp(
10437              '(\\.?' +
10438                u.type
10439                  .replace('.', '\\.')
10440                  .replace('rparen', '.paren')
10441                  .replace(/\b(?:end)\b/, '(?:start|begin|end)') +
10442                ')+'
10443            ))
10444          var a = t.column - o.getCurrentTokenColumn() - 2,
10445            f = u.value
10446          for (;;) {
10447            while (a >= 0) {
10448              var l = f.charAt(a)
10449              if (l == i) {
10450                s -= 1
10451                if (s == 0) return { row: o.getCurrentTokenRow(), column: a + o.getCurrentTokenColumn() }
10452              } else l == e && (s += 1)
10453              a -= 1
10454            }
10455            do u = o.stepBackward()
10456            while (u && !n.test(u.type))
10457            if (u == null) break
10458            ;(f = u.value), (a = f.length - 1)
10459          }
10460          return null
10461        }),
10462        (this.$findClosingBracket = function(e, t, n) {
10463          var i = this.$brackets[e],
10464            s = 1,
10465            o = new r(this, t.row, t.column),
10466            u = o.getCurrentToken()
10467          u || (u = o.stepForward())
10468          if (!u) return
10469          n ||
10470            (n = new RegExp(
10471              '(\\.?' +
10472                u.type
10473                  .replace('.', '\\.')
10474                  .replace('lparen', '.paren')
10475                  .replace(/\b(?:start|begin)\b/, '(?:start|begin|end)') +
10476                ')+'
10477            ))
10478          var a = t.column - o.getCurrentTokenColumn()
10479          for (;;) {
10480            var f = u.value,
10481              l = f.length
10482            while (a < l) {
10483              var c = f.charAt(a)
10484              if (c == i) {
10485                s -= 1
10486                if (s == 0) return { row: o.getCurrentTokenRow(), column: a + o.getCurrentTokenColumn() }
10487              } else c == e && (s += 1)
10488              a += 1
10489            }
10490            do u = o.stepForward()
10491            while (u && !n.test(u.type))
10492            if (u == null) break
10493            a = 0
10494          }
10495          return null
10496        })
10497    }
10498    var r = e('../token_iterator').TokenIterator,
10499      i = e('../range').Range
10500    t.BracketMatch = s
10501  }),
10502  define('ace/edit_session', [
10503    'require',
10504    'exports',
10505    'module',
10506    'ace/lib/oop',
10507    'ace/lib/lang',
10508    'ace/bidihandler',
10509    'ace/config',
10510    'ace/lib/event_emitter',
10511    'ace/selection',
10512    'ace/mode/text',
10513    'ace/range',
10514    'ace/document',
10515    'ace/background_tokenizer',
10516    'ace/search_highlight',
10517    'ace/edit_session/folding',
10518    'ace/edit_session/bracket_match'
10519  ], function(e, t, n) {
10520    'use strict'
10521    var r = e('./lib/oop'),
10522      i = e('./lib/lang'),
10523      s = e('./bidihandler').BidiHandler,
10524      o = e('./config'),
10525      u = e('./lib/event_emitter').EventEmitter,
10526      a = e('./selection').Selection,
10527      f = e('./mode/text').Mode,
10528      l = e('./range').Range,
10529      c = e('./document').Document,
10530      h = e('./background_tokenizer').BackgroundTokenizer,
10531      p = e('./search_highlight').SearchHighlight,
10532      d = function(e, t) {
10533        ;(this.$breakpoints = []),
10534          (this.$decorations = []),
10535          (this.$frontMarkers = {}),
10536          (this.$backMarkers = {}),
10537          (this.$markerId = 1),
10538          (this.$undoSelect = !0),
10539          (this.$foldData = []),
10540          (this.id = 'session' + ++d.$uid),
10541          (this.$foldData.toString = function() {
10542            return this.join('\n')
10543          }),
10544          this.on('changeFold', this.onChangeFold.bind(this)),
10545          (this.$onChange = this.onChange.bind(this))
10546        if (typeof e != 'object' || !e.getLine) e = new c(e)
10547        ;(this.$bidiHandler = new s(this)),
10548          this.setDocument(e),
10549          (this.selection = new a(this)),
10550          o.resetOptions(this),
10551          this.setMode(t),
10552          o._signal('session', this)
10553      }
10554    ;(d.$uid = 0),
10555      function() {
10556        function m(e) {
10557          return e < 4352
10558            ? !1
10559            : (e >= 4352 && e <= 4447) ||
10560                (e >= 4515 && e <= 4519) ||
10561                (e >= 4602 && e <= 4607) ||
10562                (e >= 9001 && e <= 9002) ||
10563                (e >= 11904 && e <= 11929) ||
10564                (e >= 11931 && e <= 12019) ||
10565                (e >= 12032 && e <= 12245) ||
10566                (e >= 12272 && e <= 12283) ||
10567                (e >= 12288 && e <= 12350) ||
10568                (e >= 12353 && e <= 12438) ||
10569                (e >= 12441 && e <= 12543) ||
10570                (e >= 12549 && e <= 12589) ||
10571                (e >= 12593 && e <= 12686) ||
10572                (e >= 12688 && e <= 12730) ||
10573                (e >= 12736 && e <= 12771) ||
10574                (e >= 12784 && e <= 12830) ||
10575                (e >= 12832 && e <= 12871) ||
10576                (e >= 12880 && e <= 13054) ||
10577                (e >= 13056 && e <= 19903) ||
10578                (e >= 19968 && e <= 42124) ||
10579                (e >= 42128 && e <= 42182) ||
10580                (e >= 43360 && e <= 43388) ||
10581                (e >= 44032 && e <= 55203) ||
10582                (e >= 55216 && e <= 55238) ||
10583                (e >= 55243 && e <= 55291) ||
10584                (e >= 63744 && e <= 64255) ||
10585                (e >= 65040 && e <= 65049) ||
10586                (e >= 65072 && e <= 65106) ||
10587                (e >= 65108 && e <= 65126) ||
10588                (e >= 65128 && e <= 65131) ||
10589                (e >= 65281 && e <= 65376) ||
10590                (e >= 65504 && e <= 65510)
10591        }
10592        r.implement(this, u),
10593          (this.setDocument = function(e) {
10594            this.doc && this.doc.removeListener('change', this.$onChange),
10595              (this.doc = e),
10596              e.on('change', this.$onChange),
10597              this.bgTokenizer && this.bgTokenizer.setDocument(this.getDocument()),
10598              this.resetCaches()
10599          }),
10600          (this.getDocument = function() {
10601            return this.doc
10602          }),
10603          (this.$resetRowCache = function(e) {
10604            if (!e) {
10605              ;(this.$docRowCache = []), (this.$screenRowCache = [])
10606              return
10607            }
10608            var t = this.$docRowCache.length,
10609              n = this.$getRowCacheIndex(this.$docRowCache, e) + 1
10610            t > n && (this.$docRowCache.splice(n, t), this.$screenRowCache.splice(n, t))
10611          }),
10612          (this.$getRowCacheIndex = function(e, t) {
10613            var n = 0,
10614              r = e.length - 1
10615            while (n <= r) {
10616              var i = (n + r) >> 1,
10617                s = e[i]
10618              if (t > s) n = i + 1
10619              else {
10620                if (!(t < s)) return i
10621                r = i - 1
10622              }
10623            }
10624            return n - 1
10625          }),
10626          (this.resetCaches = function() {
10627            ;(this.$modified = !0),
10628              (this.$wrapData = []),
10629              (this.$rowLengthCache = []),
10630              this.$resetRowCache(0),
10631              this.bgTokenizer && this.bgTokenizer.start(0)
10632          }),
10633          (this.onChangeFold = function(e) {
10634            var t = e.data
10635            this.$resetRowCache(t.start.row)
10636          }),
10637          (this.onChange = function(e) {
10638            ;
10638(this.$modified = !0), this.$bidiHandler.onChange(e), this.$resetRowCache(e.start.row)
10639            var t = this.$updateInternalDataOnChange(e)
10640            !this.$fromUndo &&
10641              this.$undoManager &&
10642              (t &&
10643                t.length &&
10644                (this.$undoManager.add({ action: 'removeFolds', folds: t }, this.mergeUndoDeltas),
10645                (this.mergeUndoDeltas = !0)),
10646              this.$undoManager.add(e, this.mergeUndoDeltas),
10647              (this.mergeUndoDeltas = !0),
10648              this.$informUndoManager.schedule()),
10649              this.bgTokenizer && this.bgTokenizer.$updateOnChange(e),
10650              this._signal('change', e)
10651          }),
10652          (this.setValue = function(e) {
10653            this.doc.setValue(e),
10654              this.selection.moveTo(0, 0),
10655              this.$resetRowCache(0),
10656              this.setUndoManager(this.$undoManager),
10657              this.getUndoManager().reset()
10658          }),
10659          (this.getValue = this.toString = function() {
10660            return this.doc.getValue()
10661          }),
10662          (this.getSelection = function() {
10663            return this.selection
10664          }),
10665          (this.getState = function(e) {
10666            return this.bgTokenizer.getState(e)
10667          }),
10668          (this.getTokens = function(e) {
10669            return this.bgTokenizer.getTokens(e)
10670          }),
10671          (this.getTokenAt = function(e, t) {
10672            var n = this.bgTokenizer.getTokens(e),
10673              r,
10674              i = 0
10675            if (t == null) {
10676              var s = n.length - 1
10677              i = this.getLine(e).length
10678            } else
10679              for (var s = 0; s < n.length; s++) {
10680                i += n[s].value.length
10681                if (i >= t) break
10682              }
10683            return (r = n[s]), r ? ((r.index = s), (r.start = i - r.value.length), r) : null
10684          }),
10685          (this.setUndoManager = function(e) {
10686            ;(this.$undoManager = e), this.$informUndoManager && this.$informUndoManager.cancel()
10687            if (e) {
10688              var t = this
10689              e.addSession(this),
10690                (this.$syncInformUndoManager = function() {
10691                  t.$informUndoManager.cancel(), (t.mergeUndoDeltas = !1)
10692                }),
10693                (this.$informUndoManager = i.delayedCall(this.$syncInformUndoManager))
10694            } else this.$syncInformUndoManager = function() {}
10695          }),
10696          (this.markUndoGroup = function() {
10697            this.$syncInformUndoManager && this.$syncInformUndoManager()
10698          }),
10699          (this.$defaultUndoManager = {
10700            undo: function() {},
10701            redo: function() {},
10702            reset: function() {},
10703            add: function() {},
10704            addSelection: function() {},
10705            startNewGroup: function() {},
10706            addSession: function() {}
10707          }),
10708          (this.getUndoManager = function() {
10709            return this.$undoManager || this.$defaultUndoManager
10710          }),
10711          (this.getTabString = function() {
10712            return this.getUseSoftTabs() ? i.stringRepeat(' ', this.getTabSize()) : '	'
10713          }),
10714          (this.setUseSoftTabs = function(e) {
10715            this.setOption('useSoftTabs', e)
10716          }),
10717          (this.getUseSoftTabs = function() {
10718            return this.$useSoftTabs && !this.$mode.$indentWithTabs
10719          }),
10720          (this.setTabSize = function(e) {
10721            this.setOption('tabSize', e)
10722          }),
10723          (this.getTabSize = function() {
10724            return this.$tabSize
10725          }),
10726          (this.isTabStop = function(e) {
10727            return this.$useSoftTabs && e.column % this.$tabSize === 0
10728          }),
10729          (this.setNavigateWithinSoftTabs = function(e) {
10730            this.setOption('navigateWithinSoftTabs', e)
10731          }),
10732          (this.getNavigateWithinSoftTabs = function() {
10733            return this.$navigateWithinSoftTabs
10734          }),
10735          (this.$overwrite = !1),
10736          (this.setOverwrite = function(e) {
10737            this.setOption('overwrite', e)
10738          }),
10739          (this.getOverwrite = function() {
10740            return this.$overwrite
10741          }),
10742          (this.toggleOverwrite = function() {
10743            this.setOverwrite(!this.$overwrite)
10744          }),
10745          (this.addGutterDecoration = function(e, t) {
10746            this.$decorations[e] || (this.$decorations[e] = ''),
10747              (this.$decorations[e] += ' ' + t),
10748              this._signal('changeBreakpoint', {})
10749          }),
10750          (this.removeGutterDecoration = function(e, t) {
10751            ;(this.$decorations[e] = (this.$decorations[e] || '').replace(' ' + t, '')),
10752              this._signal('changeBreakpoint', {})
10753          }),
10754          (this.getBreakpoints = function() {
10755            return this.$breakpoints
10756          }),
10757          (this.setBreakpoints = function(e) {
10758            this.$breakpoints = []
10759            for (var t = 0; t < e.length; t++) this.$breakpoints[e[t]] = 'ace_breakpoint'
10760            this._signal('changeBreakpoint', {})
10761          }),
10762          (this.clearBreakpoints = function() {
10763            ;(this.$breakpoints = []), this._signal('changeBreakpoint', {})
10764          }),
10765          (this.setBreakpoint = function(e, t) {
10766            t === undefined && (t = 'ace_breakpoint'),
10767              t ? (this.$breakpoints[e] = t) : delete this.$breakpoints[e],
10768              this._signal('changeBreakpoint', {})
10769          }),
10770          (this.clearBreakpoint = function(e) {
10771            delete this.$breakpoints[e], this._signal('changeBreakpoint', {})
10772          }),
10773          (this.addMarker = function(e, t, n, r) {
10774            var i = this.$markerId++,
10775              s = {
10776                range: e,
10777                type: n || 'line',
10778                renderer: typeof n == 'function' ? n : null,
10779                clazz: t,
10780                inFront: !!r,
10781                id: i
10782              }
10783            return (
10784              r
10785                ? ((this.$frontMarkers[i] = s), this._signal('changeFrontMarker'))
10786                : ((this.$backMarkers[i] = s), this._signal('changeBackMarker')),
10787              i
10788            )
10789          }),
10790          (this.addDynamicMarker = function(e, t) {
10791            if (!e.update) return
10792            var n = this.$markerId++
10793            return (
10794              (e.id = n),
10795              (e.inFront = !!t),
10796              t
10797                ? ((this.$frontMarkers[n] = e), this._signal('changeFrontMarker'))
10798                : ((this.$backMarkers[n] = e), this._signal('changeBackMarker')),
10799              e
10800            )
10801          }),
10802          (this.removeMarker = function(e) {
10803            var t = this.$frontMarkers[e] || this.$backMarkers[e]
10804            if (!t) return
10805            var n = t.inFront ? this.$frontMarkers : this.$backMarkers
10806            delete n[e], this._signal(t.inFront ? 'changeFrontMarker' : 'changeBackMarker')
10807          }),
10808          (this.getMarkers = function(e) {
10809            return e ? this.$frontMarkers : this.$backMarkers
10810          }),
10811          (this.highlight = function(e) {
10812            if (!this.$searchHighlight) {
10813              var t = new p(null, 'ace_selected-word', 'text')
10814              this.$searchHighlight = this.addDynamicMarker(t)
10815            }
10816            this.$searchHighlight.setRegexp(e)
10817          }),
10818          (this.highlightLines = function(e, t, n, r) {
10819            typeof t != 'number' && ((n = t), (t = e)), n || (n = 'ace_step')
10820            var i = new l(e, 0, t, Infinity)
10821            return (i.id = this.addMarker(i, n, 'fullLine', r)), i
10822          }),
10823          (this.setAnnotations = function(e) {
10824            ;(this.$annotations = e), this._signal('changeAnnotation', {})
10825          }),
10826          (this.getAnnotations = function() {
10827            return this.$annotations || []
10828          }),
10829          (this.clearAnnotations = function() {
10830            this.setAnnotations([])
10831          }),
10832          (this.$detectNewLine = function(e) {
10833            var t = e.match(/^.*?(\r?\n)/m)
10834            t ? (this.$autoNewLine = t[1]) : (this.$autoNewLine = '\n')
10835          }),
10836          (this.getWordRange = function(e, t) {
10837            var n = this.getLine(e),
10838              r = !1
10839            t > 0 && (r = !!n.charAt(t - 1).match(this.tokenRe)), r || (r = !!n.charAt(t).match(this.tokenRe))
10840            if (r) var i = this.tokenRe
10841            else if (/^\s+$/.test(n.slice(t - 1, t + 1))) var i = /\s/
10842            else var i = this.nonTokenRe
10843            var s = t
10844            if (s > 0) {
10845              do s--
10846              while (s >= 0 && n.charAt(s).match(i))
10847              s++
10848            }
10849            var o = t
10850            while (o < n.length && n.charAt(o).match(i)) o++
10851            return new l(e, s, e, o)
10852          }),
10853          (this.getAWordRange = function(e, t) {
10854            var n = this.getWordRange(e, t),
10855              r = this.getLine(n.end.row)
10856            while (r.charAt(n.end.column).match(/[ \t]/)) n.end.column += 1
10857            return n
10858          }),
10859          (this.setNewLineMode = function(e) {
10860            this.doc.setNewLineMode(e)
10861          }),
10862          (this.getNewLineMode = function() {
10863            return this.doc.getNewLineMode()
10864          }),
10865          (this.setUseWorker = function(e) {
10866            this.setOption('useWorker', e)
10867          }),
10868          (this.getUseWorker = function() {
10869            return this.$useWorker
10870          }),
10871          (this.onReloadTokenizer = function(e) {
10872            var t = e.data
10873            this.bgTokenizer.start(t.first), this._signal('tokenizerUpdate', e)
10874          }),
10875          (this.$modes = {}),
10876          (this.$mode = null),
10877          (this.$modeId = null),
10878          (this.setMode = function(e, t) {
10879            if (e && typeof e == 'object') {
10880              if (e.getTokenizer) return this.$onChangeMode(e)
10881              var n = e,
10882                r = n.path
10883            } else r = e || 'ace/mode/text'
10884            this.$modes['ace/mode/text'] || (this.$modes['ace/mode/text'] = new f())
10885            if (this.$modes[r] && !n) {
10886              this.$onChangeMode(this.$modes[r]), t && t()
10887              return
10888            }
10889            ;(this.$modeId = r),
10890              o.loadModule(
10891                ['mode', r],
10892                function(e) {
10893                  if (this.$modeId !== r) return t && t()
10894                  this.$modes[r] && !n
10895                    ? this.$onChangeMode(this.$modes[r])
10896                    : e &&
10897                      e.Mode &&
10898                      ((e = new e.Mode(n)), n || ((this.$modes[r] = e), (e.$id = r)), this.$onChangeMode(e)),
10899                    t && t()
10900                }.bind(this)
10901              ),
10902              this.$mode || this.$onChangeMode(this.$modes['ace/mode/text'], !0)
10903          }),
10904          (this.$onChangeMode = function(e, t) {
10905            t || (this.$modeId = e.$id)
10906            if (this.$mode === e) return
10907            ;(this.$mode = e), this.$stopWorker(), this.$useWorker && this.$startWorker()
10908            var n = e.getTokenizer()
10909            if (n.addEventListener !== undefined) {
10910              var r = this.onReloadTokenizer.bind(this)
10911              n.addEventListener('update', r)
10912            }
10913            if (!this.bgTokenizer) {
10914              this.bgTokenizer = new h(n)
10915              var i = this
10916              this.bgTokenizer.addEventListener('update', function(e) {
10917                i._signal('tokenizerUpdate', e)
10918              })
10919            } else this.bgTokenizer.setTokenizer(n)
10920            this.bgTokenizer.setDocument(this.getDocument()),
10921              (this.tokenRe = e.tokenRe),
10922              (this.nonTokenRe = e.nonTokenRe),
10923              t ||
10924                (e.attachToSession && e.attachToSession(this),
10925                this.$options.wrapMethod.set.call(this, this.$wrapMethod),
10926                this.$setFolding(e.foldingRules),
10927                this.bgTokenizer.start(0),
10928                this._emit('changeMode'))
10929          }),
10930          (this.$stopWorker = function() {
10931            this.$worker && (this.$worker.terminate(), (this.$worker = null))
10932          }),
10933          (this.$startWorker = function() {
10934            try {
10935              this.$worker = this.$mode.createWorker(this)
10936            } catch (e) {
10937              o.warn('Could not load worker', e), (this.$worker = null)
10938            }
10939          }),
10940          (this.getMode = function() {
10941            return this.$mode
10942          }),
10943          (this.$scrollTop = 0),
10944          (this.setScrollTop = function(e) {
10945            if (this.$scrollTop === e || isNaN(e)) return
10946            ;(this.$scrollTop = e), this._signal('changeScrollTop', e)
10947          }),
10948          (this.getScrollTop = function() {
10949            return this.$scrollTop
10950          }),
10951          (this.$scrollLeft = 0),
10952          (this.setScrollLeft = function(e) {
10953            if (this.$scrollLeft === e || isNaN(e)) return
10954            ;(this.$scrollLeft = e), this._signal('changeScrollLeft', e)
10955          }),
10956          (this.getScrollLeft = function() {
10957            return this.$scrollLeft
10958          }),
10959          (this.getScreenWidth = function() {
10960            return (
10961              this.$computeWidth(),
10962              this.lineWidgets ? Math.max(this.getLineWidgetMaxWidth(), this.screenWidth) : this.screenWidth
10963            )
10964          }),
10965          (this.getLineWidgetMaxWidth = function() {
10966            if (this.lineWidgetsWidth != null) return this.lineWidgetsWidth
10967            var e = 0
10968            return (
10969              this.lineWidgets.forEach(function(t) {
10970                t && t.screenWidth > e && (e = t.screenWidth)
10971              }),
10972              (this.lineWidgetWidth = e)
10973            )
10974          }),
10975          (this.$computeWidth = function(e) {
10976            if (this.$modified || e) {
10977              this.$modified = !1
10978              if (this.$useWrapMode) return (this.screenWidth = this.$wrapLimit)
10979              var t = this.doc.getAllLines(),
10980                n = this.$rowLengthCache,
10981                r = 0,
10982                i = 0,
10983                s = this.$foldData[i],
10984                o = s ? s.start.row : Infinity,
10985                u = t.length
10986              for (var a = 0; a < u; a++) {
10987                if (a > o) {
10988                  a = s.end.row + 1
10989                  if (a >= u) break
10990                  ;(s = this.$foldData[i++]), (o = s ? s.start.row : Infinity)
10991                }
10992                n[a] == null && (n[a] = this.$getStringScreenWidth(t[a])[0]), n[a] > r && (r = n[a])
10993              }
10994              this.screenWidth = r
10995            }
10996          }),
10997          (this.getLine = function(e) {
10998            return this.doc.getLine(e)
10999          }),
11000          (this.getLines = function(e, t) {
11001            return this.doc.getLines(e, t)
11002          }),
11003          (this.getLength = function() {
11004            return this.doc.getLength()
11005          }),
11006          (this.getTextRange = function(e) {
11007            return this.doc.getTextRange(e || this.selection.getRange())
11008          }),
11009          (this.insert = function(e, t) {
11010            return this.doc.insert(e, t)
11011          }),
11012          (this.remove = function(e) {
11013            return this.doc.remove(e)
11014          }),
11015          (this.removeFullLines = function(e, t) {
11016            return this.doc.removeFullLines(e, t)
11017          }),
11018          (this.undoChanges = function(e, t) {
11019            if (!e.length) return
11020            this.$fromUndo = !0
11021            for (var n = e.length - 1; n != -1; n--) {
11022              var r = e[n]
11023              r.action == 'insert' || r.action == 'remove' ? this.doc.revertDelta(r) : r.folds && this.addFolds(r.folds)
11024            }
11025            !t &&
11026              this.$undoSelect &&
11027              (e.selectionBefore
11028                ? this.selection.fromJSON(e.selectionBefore)
11029                : this.selection.setRange(this.$getUndoSelection(e, !0))),
11030              (this.$fromUndo = !1)
11031          }),
11032          (this.redoChanges = function(e, t) {
11033            if (!e.length) return
11034            this.$fromUndo = !0
11035            for (var n = 0; n < e.length; n++) {
11036              var r = e[n]
11037              ;(r.action == 'insert' || r.action == 'remove') && this.doc.applyDelta(r)
11038            }
11039            !t &&
11040              this.$undoSelect &&
11041              (e.selectionAfter
11042                ? this.selection.fromJSON(e.selectionAfter)
11043                : this.selection.setRange(this.$getUndoSelection(e, !1))),
11044              (this.$fromUndo = !1)
11045          }),
11046          (this.setUndoSelect = function(e) {
11047            this.$undoSelect = e
11048          }),
11049          (this.$getUndoSelection = function(e, t) {
11050            function n(e) {
11051              return t ? e.action !== 'insert' : e.action === 'insert'
11052            }
11053            var r, i, s
11054            for (var o = 0; o < e.length; o++) {
11055              var u = e[o]
11056              if (!u.start) continue
11057              if (!r) {
11058                n(u) ? ((r = l.fromPoints(u.start, u.end)), (s = !0)) : ((r = l.fromPoints(u.start, u.start)), (s = !1))
11059                continue
11060              }
11061              n(u)
11062                ? ((i = u.start),
11063                  r.compare(i.row, i.column) == -1 && r.setStart(i),
11064                  (i = u.end),
11065                  r.compare(i.row, i.column) == 1 && r.setEnd(i),
11066                  (s = !0))
11067                : ((i = u.start), r.compare(i.row, i.column) == -1 && (r = l.fromPoints(u.start, u.start)), (s = !1))
11068            }
11069            return r
11070          }),
11071          (this.replace = function(e, t) {
11072            return this.doc.replace(e, t)
11073          }),
11074          (this.moveText = function(e, t, n) {
11075            var r = this.getTextRange(e),
11076              i = this.getFoldsInRange(e),
11077              s = l.fromPoints(t, t)
11078            if (!n) {
11079              this.remove(e)
11080              var o = e.start.row - e.end.row,
11081                u = o ? -e.end.column : e.start.column - e.end.column
11082              u &&
11083                (s.start.row == e.end.row && s.start.column > e.end.column && (s.start.column += u),
11084                s.end.row == e.end.row && s.end.column > e.end.column && (s.end.column += u)),
11085                o && s.start.row >= e.end.row && ((s.start.row += o), (s.end.row += o))
11086            }
11087            s.end = this.insert(s.start, r)
11088            if (i.length) {
11089              var a = e.start,
11090                f = s.start,
11091                o = f.row - a.row,
11092                u = f.column - a.column
11093              this.addFolds(
11094                i.map(function(e) {
11095                  return (
11096                    (e = e.clone()),
11097                    e.start.row == a.row && (e.start.column += u),
11098                    e.end.row == a.row && (e.end.column += u),
11099                    (e.start.row += o),
11100                    (e.end.row += o),
11101                    e
11102                  )
11103                })
11104              )
11105            }
11106            return s
11107          }),
11108          (this.indentRows = function(e, t, n) {
11109            n = n.replace(/\t/g, this.getTabString())
11110            for (var r = e; r <= t; r++) this.doc.insertInLine({ row: r, column: 0 }, n)
11111          }),
11112          (this.outdentRows = function(e) {
11113            var t = e.collapseRows(),
11114              n = new l(0, 0, 0, 0),
11115              r = this.getTabSize()
11116            for (var i = t.start.row; i <= t.end.row; ++i) {
11117              var s = this.getLine(i)
11118              ;(n.start.row = i), (n.end.row = i)
11119              for (var o = 0; o < r; ++o) if (s.charAt(o) != ' ') break
11120              o < r && s.charAt(o) == '	'
11121                ? ((n.start.column = o), (n.end.column = o + 1))
11122                : ((n.start.column = 0), (n.end.column = o)),
11123                this.remove(n)
11124            }
11125          }),
11126          (this.$moveLines = function(e, t, n) {
11127            ;(e = this.getRowFoldStart(e)), (t = this.getRowFoldEnd(t))
11128            if (n < 0) {
11129              var r = this.getRowFoldStart(e + n)
11130              if (r < 0) return 0
11131              var i = r - e
11132            } else if (n > 0) {
11133              var r = this.getRowFoldEnd(t + n)
11134              if (r > this.doc.getLength() - 1) return 0
11135              var i = r - t
11136            } else {
11137              ;(e = this.$clipRowToDocument(e)), (t = this.$clipRowToDocument(t))
11138              var i = t - e + 1
11139            }
11140            var s = new l(e, 0, t, Number.MAX_VALUE),
11141              o = this.getFoldsInRange(s).map(function(e) {
11142                return (e = e.clone()), (e.start.row += i), (e.end.row += i), e
11143              }),
11144              u = n == 0 ? this.doc.getLines(e, t) : this.doc.removeFullLines(e, t)
11145            return this.doc.insertFullLines(e + i, u), o.length && this.addFolds(o), i
11146          }),
11147          (this.moveLinesUp = function(e, t) {
11148            return this.$moveLines(e, t, -1)
11149          }),
11150          (this.moveLinesDown = function(e, t) {
11151            return this.$moveLines(e, t, 1)
11152          }),
11153          (this.duplicateLines = function(e, t) {
11154            return this.$moveLines(e, t, 0)
11155          }),
11156          (this.$clipRowToDocument = function(e) {
11157            return Math.max(0, Math.min(e, this.doc.getLength() - 1))
11158          }),
11159          (this.$clipColumnToRow = function(e, t) {
11160            return t < 0 ? 0 : Math.min(this.doc.getLine(e).length, t)
11161          }),
11162          (this.$clipPositionToDocument = function(e, t) {
11163            t = Math.max(0, t)
11164            if (e < 0) (e = 0), (t = 0)
11165            else {
11166              var n = this.doc.getLength()
11167              e >= n
11168                ? ((e = n - 1), (t = this.doc.getLine(n - 1).length))
11169                : (t = Math.min(this.doc.getLine(e).length, t))
11170            }
11171            return { row: e, column: t }
11172          }),
11173          (this.$clipRangeToDocument = function(e) {
11174            e.start.row < 0
11175              ? ((e.start.row = 0), (e.start.column = 0))
11176              : (e.start.column = this.$clipColumnToRow(e.start.row, e.start.column))
11177            var t = this.doc.getLength() - 1
11178            return (
11179              e.end.row > t
11180                ? ((e.end.row = t), (e.end.column = this.doc.getLine(t).length))
11181                : (e.end.column = this.$clipColumnToRow(e.end.row, e.end.column)),
11182              e
11183            )
11184          }),
11185          (this.$wrapLimit = 80),
11186          (this.$useWrapMode = !1),
11187          (this.$wrapLimitRange = { min: null, max: null }),
11188          (this.setUseWrapMode = function(e) {
11189            if (e != this.$useWrapMode) {
11190              ;(this.$useWrapMode = e), (this.$modified = !0), this.$resetRowCache(0)
11191              if (e) {
11192                var t = this.getLength()
11193                ;(this.$wrapData = Array(t)), this.$updateWrapData(0, t - 1)
11194              }
11195              this._signal('changeWrapMode')
11196            }
11197          }),
11198          (this.getUseWrapMode = function() {
11199            return this.$useWrapMode
11200          }),
11201          (this.setWrapLimitRange = function(e, t) {
11202            if (this.$wrapLimitRange.min !== e || this.$wrapLimitRange.max !== t)
11203              (this.$wrapLimitRange = { min: e, max: t }),
11204                (this.$modified = !0),
11205                this.$bidiHandler.markAsDirty(),
11206                this.$useWrapMode && this._signal('changeWrapMode')
11207          }),
11208          (this.adjustWrapLimit = function(e, t) {
11209            var n = this.$wrapLimitRange
11210            n.max < 0 && (n = { min: t, max: t })
11211            var r = this.$constrainWrapLimit(e, n.min, n.max)
11212            return r != this.$wrapLimit && r > 1
11213              ? ((this.$wrapLimit = r),
11214                (this.$modified = !0),
11215                this.$useWrapMode &&
11216                  (this.$updateWrapData(0, this.getLength() - 1),
11217                  this.$resetRowCache(0),
11218                  this._signal('changeWrapLimit')),
11219                !0)
11220              : !1
11221          }),
11222          (this.$constrainWrapLimit = function(e, t, n) {
11223            return t && (e = Math.max(t, e)), n && (e = Math.min(n, e)), e
11224          }),
11225          (this.getWrapLimit = function() {
11226            return this.$wrapLimit
11227          }),
11228          (this.setWrapLimit = function(e) {
11229            this.setWrapLimitRange(e, e)
11230          }),
11231          (this.getWrapLimitRange = function() {
11232            return { min: this.$wrapLimitRange.min, max: this.$wrapLimitRange.max }
11233          }),
11234          (this.$updateInternalDataOnChange = function(e) {
11235            var t = this.$useWrapMode,
11236              n = e.action,
11237              r = e.start,
11238              i = e.end,
11239              s = r.row,
11240              o = i.row,
11241              u = o - s,
11242              a = null
11243            this.$updating = !0
11244            if (u != 0)
11245              if (n === 'remove') {
11246                this[t ? '$wrapData' : '$rowLengthCache'].splice(s, u)
11247                var f = this.$foldData
11248                ;(a = this.getFoldsInRange(e)), this.removeFolds(a)
11249                var l = this.getFoldLine(i.row),
11250                  c = 0
11251                if (l) {
11252                  l.addRemoveChars(i.row, i.column, r.column - i.column), l.shiftRow(-u)
11253                  var h = this.getFoldLine(s)
11254                  h && h !== l && (h.merge(l), (l = h)), (c = f.indexOf(l) + 1)
11255                }
11256                for (c; c < f.length; c++) {
11257                  var l = f[c]
11258                  l.start.row >= i.row && l.shiftRow(-u)
11259                }
11260                o = s
11261              } else {
11262                var p = Array(u)
11263                p.unshift(s, 0)
11264                var d = t ? this.$wrapData : this.$rowLengthCache
11265                d.splice.apply(d, p)
11266                var f = this.$foldData,
11267                  l = this.getFoldLine(s),
11268                  c = 0
11269                if (l) {
11270                  var v = l.range.compareInside(r.row, r.column)
11271                  v == 0
11272                    ? ((l = l.split(r.row, r.column)),
11273                      l && (l.shiftRow(u), l.addRemoveChars(o, 0, i.column - r.column)))
11274                    : v == -1 && (l.addRemoveChars(s, 0, i.column - r.column), l.shiftRow(u)),
11275                    (c = f.indexOf(l) + 1)
11276                }
11277                for (c; c < f.length; c++) {
11278                  var l = f[c]
11279                  l.start.row >= s && l.shiftRow(u)
11280                }
11281              }
11282            else {
11283              ;(u = Math.abs(e.start.column - e.end.column)),
11284                n === 'remove' && ((a = this.getFoldsInRange(e)), this.removeFolds(a), (u = -u))
11285              var l = this.getFoldLine(s)
11286              l && l.addRemoveChars(s, r.column, u)
11287            }
11288            return (
11289              t &&
11290                this.$wrapData.length != this.doc.getLength() &&
11291                console.error('doc.getLength() and $wrapData.length have to be the same!'),
11292              (this.$updating = !1),
11293              t ? this.$updateWrapData(s, o) : this.$updateRowLengthCache(s, o),
11294              a
11295            )
11296          }),
11297          (this.$updateRowLengthCache = function(e, t, n) {
11298            ;(this.$rowLengthCache[e] = null), (this.$rowLengthCache[t] = null)
11299          }),
11300          (this.$updateWrapData = function(e, t) {
11301            var r = this.doc.getAllLines(),
11302              i = this.getTabSize(),
11303              o = this.$wrapData,
11304              u = this.$wrapLimit,
11305              a,
11306              f,
11307              l = e
11308            t = Math.min(t, r.length - 1)
11309            while (l <= t)
11310              (f = this.getFoldLine(l, f)),
11311                f
11312                  ? ((a = []),
11313                    f.walk(
11314                      function(e, t, i, o) {
11315                        var u
11316                        if (e != null) {
11317                          ;(u = this.$getDisplayTokens(e, a.length)), (u[0] = n)
11318                          for (var f = 1; f < u.length; f++) u[f] = s
11319                        } else u = this.$getDisplayTokens(r[t].substring(o, i), a.length)
11320                        a = a.concat(u)
11321                      }.bind(this),
11322                      f.end.row,
11323                      r[f.end.row].length + 1
11324                    ),
11325                    (o[f.start.row] = this.$computeWrapSplits(a, u, i)),
11326                    (l = f.end.row + 1))
11327                  : ((a = this.$getDisplayTokens(r[l])), (o[l] = this.$computeWrapSplits(a, u, i)), l++)
11328          })
11329        var e = 1,
11330          t = 2,
11331          n = 3,
11332          s = 4,
11333          a = 9,
11334          c = 10,
11335          d = 11,
11336          v = 12
11337        ;(this.$computeWrapSplits = function(e, r, i) {
11338          function g() {
11339            var t = 0
11340            if (m === 0) return t
11341            if (p)
11342              for (var n = 0; n < e.length; n++) {
11343                var r = e[n]
11344                if (r == c) t += 1
11345                else {
11346                  if (r != d) {
11347                    if (r == v) continue
11348                    break
11349                  }
11350                  t += i
11351                }
11352              }
11353            return h && p !== !1 && (t += i), Math.min(t, m)
11354          }
11355          function y(t) {
11356            var n = e.slice(f, t),
11357              r = n.length
11358            n
11359              .join('')
11360              .replace(/12/g, function() {
11361                r -= 1
11362              })
11363              .replace(/2/g, function() {
11364                r -= 1
11365              }),
11366              o.length || ((b = g()), (o.indent = b)),
11367              (l += r),
11368              o.push(l),
11369              (f = t)
11370          }
11371          if (e.length == 0) return []
11372          var o = [],
11373            u = e.length,
11374            f = 0,
11375            l = 0,
11376            h = this.$wrapAsCode,
11377            p = this.$indentedSoftWrap,
11378            m = r <= Math.max(2 * i, 8) || p === !1 ? 0 : Math.floor(r / 2),
11379            b = 0
11380          while (u - f > r - b) {
11381            var w = f + r - b
11382            if (e[w - 1] >= c && e[w] >= c) {
11383              y(w)
11384              continue
11385            }
11386            if (e[w] == n || e[w] == s) {
11387              for (w; w != f - 1; w--) if (e[w] == n) break
11388              if (w > f) {
11389                y(w)
11390                continue
11391              }
11392              w = f + r
11393              for (w; w < e.length; w++) if (e[w] != s) break
11394              if (w == e.length) break
11395              y(w)
11396              continue
11397            }
11398            var E = Math.max(w - (r - (r >> 2)), f - 1)
11399            while (w > E && e[w] < n) w--
11400            if (h) {
11401              while (w > E && e[w] < n) w--
11402              while (w > E && e[w] == a) w--
11403            } else while (w > E && e[w] < c) w--
11404            if (w > E) {
11405              y(++w)
11406              continue
11407            }
11408            ;(w = f + r), e[w] == t && w--, y(w - b)
11409          }
11410          return o
11411        }),
11412          (this.$getDisplayTokens = function(n, r) {
11413            var i = [],
11414              s
11415            r = r || 0
11416            for (var o = 0; o < n.length; o++) {
11417              var u = n.charCodeAt(o)
11418              if (u == 9) {
11419                ;(s = this.getScreenTabSize(i.length + r)), i.push(d)
11420                for (var f = 1; f < s; f++) i.push(v)
11421              } else
11422                u == 32
11423                  ? i.push(c)
11424                  : (u > 39 && u < 48) || (u > 57 && u < 64)
11425                  ? i.push(a)
11426                  : u >= 4352 && m(u)
11427                  ? i.push(e, t)
11428                  : i.push(e)
11429            }
11430            return i
11431          }),
11432          (this.$getStringScreenWidth = function(e, t, n) {
11433            if (t == 0) return [0, 0]
11434            t == null && (t = Infinity), (n = n || 0)
11435            var r, i
11436            for (i = 0; i < e.length; i++) {
11437              ;(r = e.charCodeAt(i)), r == 9 ? (n += this.getScreenTabSize(n)) : r >= 4352 && m(r) ? (n += 2) : (n += 1)
11438              if (n > t) break
11439            }
11440            return [n, i]
11441          }),
11442          (this.lineWidgets = null),
11443          (this.getRowLength = function(e) {
11444            if (this.lineWidgets) var t = (this.lineWidgets[e] && this.lineWidgets[e].rowCount) || 0
11445            else t = 0
11446            return !this.$useWrapMode || !this.$wrapData[e] ? 1 + t : this.$wrapData[e].length + 1 + t
11447          }),
11448          (this.getRowLineCount = function(e) {
11449            return !this.$useWrapMode || !this.$wrapData[e] ? 1 : this.$wrapData[e].length + 1
11450          }),
11451          (this.getRowWrapIndent = function(e) {
11452            if (this.$useWrapMode) {
11453              var t = this.screenToDocumentPosition(e, Number.MAX_VALUE),
11454                n = this.$wrapData[t.row]
11455              return n.length && n[0] < t.column ? n.indent : 0
11456            }
11457            return 0
11458          }),
11459          (this.getScreenLastRowColumn = function(e) {
11460            var t = this.screenToDocumentPosition(e, Number.MAX_VALUE)
11461            return this.documentToScreenColumn(t.row, t.column)
11462          }),
11463          (this.getDocumentLastRowColumn = function(e, t) {
11464            var n = this.documentToScreenRow(e, t)
11465            return this.getScreenLastRowColumn(n)
11466          }),
11467          (this.getDocumentLastRowColumnPosition = function(e, t) {
11468            var n = this.documentToScreenRow(e, t)
11469            return this.screenToDocumentPosition(n, Number.MAX_VALUE / 10)
11470          }),
11471          (this.getRowSplitData = function(e) {
11472            return this.$useWrapMode ? this.$wrapData[e] : undefined
11473          }),
11474          (this.getScreenTabSize = function(e) {
11475            return this.$tabSize - (e % this.$tabSize)
11476          }),
11477          (this.screenToDocumentRow = function(e, t) {
11478            return this.screenToDocumentPosition(e, t).row
11479          }),
11480          (this.screenToDocumentColumn = function(e, t) {
11481            return this.screenToDocumentPosition(e, t).column
11482          }),
11483          (this.screenToDocumentPosition = function(e, t, n) {
11484            if (e < 0) return { row: 0, column: 0 }
11485            var r,
11486              i = 0,
11487              s = 0,
11488              o,
11489              u = 0,
11490              a = 0,
11491              f = this.$screenRowCache,
11492              l = this.$getRowCacheIndex(f, e),
11493              c = f.length
11494            if (c && l >= 0)
11495              var u = f[l],
11496                i = this.$docRowCache[l],
11497                h = e > f[c - 1]
11498            else var h = !c
11499            var p = this.getLength() - 1,
11500              d = this.getNextFoldLine(i),
11501              v = d ? d.start.row : Infinity
11502            while (u <= e) {
11503              a = this.getRowLength(i)
11504              if (u + a > e || i >= p) break
11505              ;(u += a),
11506                i++,
11507                i > v && ((i = d.end.row + 1), (d = this.getNextFoldLine(i, d)), (v = d ? d.start.row : Infinity)),
11508                h && (this.$docRowCache.push(i), this.$screenRowCache.push(u))
11509            }
11510            if (d && d.start.row <= i) (r = this.getFoldDisplayLine(d)), (i = d.start.row)
11511            else {
11512              if (u + a <= e || i > p) return { row: p, column: this.getLine(p).length }
11513              ;(r = this.getLine(i)), (d = null)
11514            }
11515            var m = 0,
11516              g = Math.floor(e - u)
11517            if (this.$useWrapMode) {
11518              var y = this.$wrapData[i]
11519              y &&
11520                ((o = y[g]),
11521                g > 0 && y.length && ((m = y.indent), (s = y[g - 1] || y[y.length - 1]), (r = r.substring(s))))
11522            }
11523            return (
11524              n !== undefined && this.$bidiHandler.isBidiRow(u + g, i, g) && (t = this.$bidiHandler.offsetToCol(n)),
11525              (s += this.$getStringScreenWidth(r, t - m)[1]),
11526              this.$useWrapMode && s >= o && (s = o - 1),
11527              d ? d.idxToPosition(s) : { row: i, column: s }
11528            )
11529          }),
11530          (this.documentToScreenPosition = function(e, t) {
11531            if (typeof t == 'undefined') var n = this.$clipPositionToDocument(e.row, e.column)
11532            else n = this.$clipPositionToDocument(e, t)
11533            ;(e = n.row), (t = n.column)
11534            var r = 0,
11535              i = null,
11536              s = null
11537            ;(s = this.getFoldAt(e, t, 1)), s && ((e = s.start.row), (t = s.start.column))
11538            var o,
11539              u = 0,
11540              a = this.$docRowCache,
11541              f = this.$getRowCacheIndex(a, e),
11542              l = a.length
11543            if (l && f >= 0)
11544              var u = a[f],
11545                r = this.$screenRowCache[f],
11546                c = e > a[l - 1]
11547            else var c = !l
11548            var h = this.getNextFoldLine(u),
11549              p = h ? h.start.row : Infinity
11550            while (u < e) {
11551              if (u >= p) {
11552                o = h.end.row + 1
11553                if (o > e) break
11554                ;(h = this.getNextFoldLine(o, h)), (p = h ? h.start.row : Infinity)
11555              } else o = u + 1
11556              ;(r += this.getRowLength(u)), (u = o), c && (this.$docRowCache.push(u), this.$screenRowCache.push(r))
11557            }
11558            var d = ''
11559            h && u >= p
11560              ? ((d = this.getFoldDisplayLine(h, e, t)), (i = h.start.row))
11561              : ((d = this.getLine(e).substring(0, t)), (i = e))
11562            var v = 0
11563            if (this.$useWrapMode) {
11564              var m = this.$wrapData[i]
11565              if (m) {
11566                var g = 0
11567                while (d.length >= m[g]) r++, g++
11568                ;(d = d.substring(m[g - 1] || 0, d.length)), (v = g > 0 ? m.indent : 0)
11569              }
11570            }
11571            return { row: r, column: v + this.$getStringScreenWidth(d)[0] }
11572          }),
11573          (this.documentToScreenColumn = function(e, t) {
11574            return this.documentToScreenPosition(e, t).column
11575          }),
11576          (this.documentToScreenRow = function(e, t) {
11577            return this.documentToScreenPosition(e, t).row
11578          }),
11579          (this.getScreenLength = function() {
11580            var e = 0,
11581              t = null
11582            if (!this.$useWrapMode) {
11583              e = this.getLength()
11584              var n = this.$foldData
11585              for (var r = 0; r < n.length; r++) (t = n[r]), (e -= t.end.row - t.start.row)
11586            } else {
11587              var i = this.$wrapData.length,
11588                s = 0,
11589                r = 0,
11590                t = this.$foldData[r++],
11591                o = t ? t.start.row : Infinity
11592              while (s < i) {
11593                var u = this.$wrapData[s]
11594                ;(e += u ? u.length + 1 : 1),
11595                  s++,
11596                  s > o && ((s = t.end.row + 1), (t = this.$foldData[r++]), (o = t ? t.start.row : Infinity))
11597              }
11598            }
11599            return this.lineWidgets && (e += this.$getWidgetScreenLength()), e
11600          }),
11601          (this.$setFontMetrics = function(e) {
11602            if (!this.$enableVarChar) return
11603            this.$getStringScreenWidth = function(t, n, r) {
11604              if (n === 0) return [0, 0]
11605              n || (n = Infinity), (r = r || 0)
11606              var i, s
11607              for (s = 0; s < t.length; s++) {
11608                ;
11608(i = t.charAt(s)), i === '	' ? (r += this.getScreenTabSize(r)) : (r += e.getCharacterWidth(i))
11609                if (r > n) break
11610              }
11611              return [r, s]
11612            }
11613          }),
11614          (this.destroy = function() {
11615            this.bgTokenizer && (this.bgTokenizer.setDocument(null), (this.bgTokenizer = null)), this.$stopWorker()
11616          }),
11617          (this.isFullWidth = m)
11618      }.call(d.prototype),
11619      e('./edit_session/folding').Folding.call(d.prototype),
11620      e('./edit_session/bracket_match').BracketMatch.call(d.prototype),
11621      o.defineOptions(d.prototype, 'session', {
11622        wrap: {
11623          set: function(e) {
11624            !e || e == 'off'
11625              ? (e = !1)
11626              : e == 'free'
11627              ? (e = !0)
11628              : e == 'printMargin'
11629              ? (e = -1)
11630              : typeof e == 'string' && (e = parseInt(e, 10) || !1)
11631            if (this.$wrap == e) return
11632            this.$wrap = e
11633            if (!e) this.setUseWrapMode(!1)
11634            else {
11635              var t = typeof e == 'number' ? e : null
11636              this.setWrapLimitRange(t, t), this.setUseWrapMode(!0)
11637            }
11638          },
11639          get: function() {
11640            return this.getUseWrapMode()
11641              ? this.$wrap == -1
11642                ? 'printMargin'
11643                : this.getWrapLimitRange().min
11644                ? this.$wrap
11645                : 'free'
11646              : 'off'
11647          },
11648          handlesSet: !0
11649        },
11650        wrapMethod: {
11651          set: function(e) {
11652            ;(e = e == 'auto' ? this.$mode.type != 'text' : e != 'text'),
11653              e != this.$wrapAsCode &&
11654                ((this.$wrapAsCode = e),
11655                this.$useWrapMode &&
11656                  ((this.$modified = !0), this.$resetRowCache(0), this.$updateWrapData(0, this.getLength() - 1)))
11657          },
11658          initialValue: 'auto'
11659        },
11660        indentedSoftWrap: { initialValue: !0 },
11661        firstLineNumber: {
11662          set: function() {
11663            this._signal('changeBreakpoint')
11664          },
11665          initialValue: 1
11666        },
11667        useWorker: {
11668          set: function(e) {
11669            ;(this.$useWorker = e), this.$stopWorker(), e && this.$startWorker()
11670          },
11671          initialValue: !0
11672        },
11673        useSoftTabs: { initialValue: !0 },
11674        tabSize: {
11675          set: function(e) {
11676            if (isNaN(e) || this.$tabSize === e) return
11677            ;(this.$modified = !0), (this.$rowLengthCache = []), (this.$tabSize = e), this._signal('changeTabSize')
11678          },
11679          initialValue: 4,
11680          handlesSet: !0
11681        },
11682        navigateWithinSoftTabs: { initialValue: !1 },
11683        foldStyle: {
11684          set: function(e) {
11685            this.setFoldStyle(e)
11686          },
11687          handlesSet: !0
11688        },
11689        overwrite: {
11690          set: function(e) {
11691            this._signal('changeOverwrite')
11692          },
11693          initialValue: !1
11694        },
11695        newLineMode: {
11696          set: function(e) {
11697            this.doc.setNewLineMode(e)
11698          },
11699          get: function() {
11700            return this.doc.getNewLineMode()
11701          },
11702          handlesSet: !0
11703        },
11704        mode: {
11705          set: function(e) {
11706            this.setMode(e)
11707          },
11708          get: function() {
11709            return this.$modeId
11710          },
11711          handlesSet: !0
11712        }
11713      }),
11714      (t.EditSession = d)
11715  }),
11716  define('ace/search', ['require', 'exports', 'module', 'ace/lib/lang', 'ace/lib/oop', 'ace/range'], function(e, t, n) {
11717    'use strict'
11718    function u(e, t) {
11719      function n(e) {
11720        return /\w/.test(e) || t.regExp ? '\\b' : ''
11721      }
11722      return n(e[0]) + e + n(e[e.length - 1])
11723    }
11724    var r = e('./lib/lang'),
11725      i = e('./lib/oop'),
11726      s = e('./range').Range,
11727      o = function() {
11728        this.$options = {}
11729      }
11730    ;(function() {
11731      ;(this.set = function(e) {
11732        return i.mixin(this.$options, e), this
11733      }),
11734        (this.getOptions = function() {
11735          return r.copyObject(this.$options)
11736        }),
11737        (this.setOptions = function(e) {
11738          this.$options = e
11739        }),
11740        (this.find = function(e) {
11741          var t = this.$options,
11742            n = this.$matchIterator(e, t)
11743          if (!n) return !1
11744          var r = null
11745          return (
11746            n.forEach(function(e, n, i, o) {
11747              return (
11748                (r = new s(e, n, i, o)),
11749                n == o && t.start && t.start.start && t.skipCurrent != 0 && r.isEqual(t.start) ? ((r = null), !1) : !0
11750              )
11751            }),
11752            r
11753          )
11754        }),
11755        (this.findAll = function(e) {
11756          var t = this.$options
11757          if (!t.needle) return []
11758          this.$assembleRegExp(t)
11759          var n = t.range,
11760            i = n ? e.getLines(n.start.row, n.end.row) : e.doc.getAllLines(),
11761            o = [],
11762            u = t.re
11763          if (t.$isMultiLine) {
11764            var a = u.length,
11765              f = i.length - a,
11766              l
11767            e: for (var c = u.offset || 0; c <= f; c++) {
11768              for (var h = 0; h < a; h++) if (i[c + h].search(u[h]) == -1) continue e
11769              var p = i[c],
11770                d = i[c + a - 1],
11771                v = p.length - p.match(u[0])[0].length,
11772                m = d.match(u[a - 1])[0].length
11773              if (l && l.end.row 
11773=== c && l.end.column > v) continue
11774              o.push((l = new s(c, v, c + a - 1, m))), a > 2 && (c = c + a - 2)
11775            }
11776          } else
11777            for (var g = 0; g < i.length; g++) {
11778              var y = r.getMatchOffsets(i[g], u)
11779              for (var h = 0; h < y.length; h++) {
11780                var b = y[h]
11781                o.push(new s(g, b.offset, g, b.offset + b.length))
11782              }
11783            }
11784          if (n) {
11785            var w = n.start.column,
11786              E = n.start.column,
11787              g = 0,
11788              h = o.length - 1
11789            while (g < h && o[g].start.column < w && o[g].start.row == n.start.row) g++
11790            while (g < h && o[h].end.column > E && o[h].end.row == n.end.row) h--
11791            o = o.slice(g, h + 1)
11792            for (g = 0, h = o.length; g < h; g++) (o[g].start.row += n.start.row), (o[g].end.row += n.start.row)
11793          }
11794          return o
11795        }),
11796        (this.replace = function(e, t) {
11797          var n = this.$options,
11798            r = this.$assembleRegExp(n)
11799          if (n.$isMultiLine) return t
11800          if (!r) return
11801          var i = r.exec(e)
11802          if (!i || i[0].length != e.length) return null
11803          t = e.replace(r, t)
11804          if (n.preserveCase) {
11805            t = t.split('')
11806            for (var s = Math.min(e.length, e.length); s--; ) {
11807              var o = e[s]
11808              o && o.toLowerCase() != o ? (t[s] = t[s].toUpperCase()) : (t[s] = t[s].toLowerCase())
11809            }
11810            t = t.join('')
11811          }
11812          return t
11813        }),
11814        (this.$assembleRegExp = function(e, t) {
11815          if (e.needle instanceof RegExp) return (e.re = e.needle)
11816          var n = e.needle
11817          if (!e.needle) return (e.re = !1)
11818          e.regExp || (n = r.escapeRegExp(n)), e.wholeWord && (n = u(n, e))
11819          var i = e.caseSensitive ? 'gm' : 'gmi'
11820          e.$isMultiLine = !t && /[\n\r]/.test(n)
11821          if (e.$isMultiLine) return (e.re = this.$assembleMultilineRegExp(n, i))
11822          try {
11823            var s = new RegExp(n, i)
11824          } catch (o) {
11825            s = !1
11826          }
11827          return (e.re = s)
11828        }),
11829        (this.$assembleMultilineRegExp = function(e, t) {
11830          var n = e.replace(/\r\n|\r|\n/g, '$\n^').split('\n'),
11831            r = []
11832          for (var i = 0; i < n.length; i++)
11833            try {
11834              r.push(new RegExp(n[i], t))
11835            } catch (s) {
11836              return !1
11837            }
11838          return r
11839        }),
11840        (this.$matchIterator = function(e, t) {
11841          var n = this.$assembleRegExp(t)
11842          if (!n) return !1
11843          var r = t.backwards == 1,
11844            i = t.skipCurrent != 0,
11845            s = t.range,
11846            o = t.start
11847          o || (o = s ? s[r ? 'end' : 'start'] : e.selection.getRange()), o.start && (o = o[i != r ? 'end' : 'start'])
11848          var u = s ? s.start.row : 0,
11849            a = s ? s.end.row : e.getLength() - 1
11850          if (r)
11851            var f = function(e) {
11852              var n = o.row
11853              if (c(n, o.column, e)) return
11854              for (n--; n >= u; n--) if (c(n, Number.MAX_VALUE, e)) return
11855              if (t.wrap == 0) return
11856              for (n = a, u = o.row; n >= u; n--) if (c(n, Number.MAX_VALUE, e)) return
11857            }
11858          else
11859            var f = function(e) {
11860              var n = o.row
11861              if (c(n, o.column, e)) return
11862              for (n += 1; n <= a; n++) if (c(n, 0, e)) return
11863              if (t.wrap == 0) return
11864              for (n = u, a = o.row; n <= a; n++) if (c(n, 0, e)) return
11865            }
11866          if (t.$isMultiLine)
11867            var l = n.length,
11868              c = function(t, i, s) {
11869                var o = r ? t - l + 1 : t
11870                if (o < 0) return
11871                var u = e.getLine(o),
11872                  a = u.search(n[0])
11873                if ((!r && a < i) || a === -1) return
11874                for (var f = 1; f < l; f++) {
11875                  u = e.getLine(o + f)
11876                  if (u.search(n[f]) == -1) return
11877                }
11878                var c = u.match(n[l - 1])[0].length
11879                if (r && c > i) return
11880                if (s(o, a, o + l - 1, c)) return !0
11881              }
11882          else if (r)
11883            var c = function(t, r, i) {
11884              var s = e.getLine(t),
11885                o = [],
11886                u,
11887                a = 0
11888              n.lastIndex = 0
11889              while ((u = n.exec(s))) {
11890                var f = u[0].length
11891                a = u.index
11892                if (!f) {
11893                  if (a >= s.length) break
11894                  n.lastIndex = a += 1
11895                }
11896                if (u.index + f > r) break
11897                o.push(u.index, f)
11898              }
11899              for (var l = o.length - 1; l >= 0; l -= 2) {
11900                var c = o[l - 1],
11901                  f = o[l]
11902                if (i(t, c, t, c + f)) return !0
11903              }
11904            }
11905          else
11906            var c = function(t, r, i) {
11907              var s = e.getLine(t),
11908                o,
11909                u
11910              n.lastIndex = r
11911              while ((u = n.exec(s))) {
11912                var a = u[0].length
11913                o = u.index
11914                if (i(t, o, t, o + a)) return !0
11915                if (!a) {
11916                  n.lastIndex = o += 1
11917                  if (o >= s.length) return !1
11918                }
11919              }
11920            }
11921          return { forEach: f }
11922        })
11923    }.call(o.prototype),
11924      (t.Search = o))
11925  }),
11926  define('ace/keyboard/hash_handler', ['require', 'exports', 'module', 'ace/lib/keys', 'ace/lib/useragent'], function(
11927    e,
11928    t,
11929    n
11930  ) {
11931    'use strict'
11932    function o(e, t) {
11933      ;(this.platform = t || (i.isMac ? 'mac' : 'win')),
11934        (this.commands = {}),
11935        (this.commandKeyBinding = {}),
11936        this.addCommands(e),
11937        (this.$singleCommand = !0)
11938    }
11939    function u(e, t) {
11940      o.call(this, e, t), (this.$singleCommand = !1)
11941    }
11942    var r = e('../lib/keys'),
11943      i = e('../lib/useragent'),
11944      s = r.KEY_MODS
11945    ;(u.prototype = o.prototype),
11946      function() {
11947        function e(e) {
11948          return (typeof e == 'object' && e.bindKey && e.bindKey.position) || (e.isDefault ? -100 : 0)
11949        }
11950        ;(this.addCommand = function(e) {
11951          this.commands[e.name] && this.removeCommand(e),
11952            (this.commands[e.name] = e),
11953            e.bindKey && this._buildKeyHash(e)
11954        }),
11955          (this.removeCommand = function(e, t) {
11956            var n = e && (typeof e == 'string' ? e : e.name)
11957            ;(e = this.commands[n]), t || delete this.commands[n]
11958            var r = this.commandKeyBinding
11959            for (var i in r) {
11960              var s = r[i]
11961              if (s == e) delete r[i]
11962              else if (Array.isArray(s)) {
11963                var o = s.indexOf(e)
11964                o != -1 && (s.splice(o, 1), s.length == 1 && (r[i] = s[0]))
11965              }
11966            }
11967          }),
11968          (this.bindKey = function(e, t, n) {
11969            typeof e == 'object' && e && (n == undefined && (n = e.position), (e = e[this.platform]))
11970            if (!e) return
11971            if (typeof t == 'function') return this.addCommand({ exec: t, bindKey: e, name: t.name || e })
11972            e.split('|').forEach(function(e) {
11973              var r = ''
11974              if (e.indexOf(' ') != -1) {
11975                var i = e.split(/\s+/)
11976                ;(e = i.pop()),
11977                  i.forEach(function(e) {
11978                    var t = this.parseKeys(e),
11979                      n = s[t.hashId] + t.key
11980                    ;(r += (r ? ' ' : '') + n), this._addCommandToBinding(r, 'chainKeys')
11981                  }, this),
11982                  (r += ' ')
11983              }
11984              var o = this.parseKeys(e),
11985                u = s[o.hashId] + o.key
11986              this._addCommandToBinding(r + u, t, n)
11987            }, this)
11988          }),
11989          (this._addCommandToBinding = function(t, n, r) {
11990            var i = this.commandKeyBinding,
11991              s
11992            if (!n) delete i[t]
11993            else if (!i[t] || this.$singleCommand) i[t] = n
11994            else {
11995              Array.isArray(i[t]) ? (s = i[t].indexOf(n)) != -1 && i[t].splice(s, 1) : (i[t] = [i[t]]),
11996                typeof r != 'number' && (r = e(n))
11997              var o = i[t]
11998              for (s = 0; s < o.length; s++) {
11999                var u = o[s],
12000                  a = e(u)
12001                if (a > r) break
12002              }
12003              o.splice(s, 0, n)
12004            }
12005          }),
12006          (this.addCommands = function(e) {
12007            e &&
12008              Object.keys(e).forEach(function(t) {
12009                var n = e[t]
12010                if (!n) return
12011                if (typeof n == 'string') return this.bindKey(n, t)
12012                typeof n == 'function' && (n = { exec: n })
12013                if (typeof n != 'object') return
12014                n.name || (n.name = t), this.addCommand(n)
12015              }, this)
12016          }),
12017          (this.removeCommands = function(e) {
12018            Object.keys(e).forEach(function(t) {
12019              this.removeCommand(e[t])
12020            }, this)
12021          }),
12022          (this.bindKeys = function(e) {
12023            Object.keys(e).forEach(function(t) {
12024              this.bindKey(t, e[t])
12025            }, this)
12026          }),
12027          (this._buildKeyHash = function(e) {
12028            this.bindKey(e.bindKey, e)
12029          }),
12030          (this.parseKeys = function(e) {
12031            var t = e
12032                .toLowerCase()
12033                .split(/[\-\+]([\-\+])?/)
12034                .filter(function(e) {
12035                  return e
12036                }),
12037              n = t.pop(),
12038              i = r[n]
12039            if (r.FUNCTION_KEYS[i]) n = r.FUNCTION_KEYS[i].toLowerCase()
12040            else {
12041              if (!t.length) return { key: n, hashId: -1 }
12042              if (t.length == 1 && t[0] == 'shift') return { key: n.toUpperCase(), hashId: -1 }
12043            }
12044            var s = 0
12045            for (var o = t.length; o--; ) {
12046              var u = r.KEY_MODS[t[o]]
12047              if (u == null)
12048                return typeof console != 'undefined' && console.error('invalid modifier ' + t[o] + ' in ' + e), !1
12049              s |= u
12050            }
12051            return { key: n, hashId: s }
12052          }),
12053          (this.findKeyCommand = function(t, n) {
12054            var r = s[t] + n
12055            return this.commandKeyBinding[r]
12056          }),
12057          (this.handleKeyboard = function(e, t, n, r) {
12058            if (r < 0) return
12059            var i = s[t] + n,
12060              o = this.commandKeyBinding[i]
12061            e.$keyChain && ((e.$keyChain += ' ' + i), (o = this.commandKeyBinding[e.$keyChain] || o))
12062            if (o)
12063              if (o == 'chainKeys' || o[o.length - 1] == 'chainKeys')
12064                return (e.$keyChain = e.$keyChain || i), { command: 'null' }
12065            if (e.$keyChain)
12066              if ((!!t && t != 4) || n.length != 1) {
12067                if (t == -1 || r > 0) e.$keyChain = ''
12068              } else e.$keyChain = e.$keyChain.slice(0, -i.length - 1)
12069            return { command: o }
12070          }),
12071          (this.getStatusText = function(e, t) {
12072            return t.$keyChain || ''
12073          })
12074      }.call(o.prototype),
12075      (t.HashHandler = o),
12076      (t.MultiHashHandler = u)
12077  }),
12078  define('ace/commands/command_manager', [
12079    'require',
12080    'exports',
12081    'module',
12082    'ace/lib/oop',
12083    'ace/keyboard/hash_handler',
12084    'ace/lib/event_emitter'
12085  ], function(e, t, n) {
12086    'use strict'
12087    var r = e('../lib/oop'),
12088      i = e('../keyboard/hash_handler').MultiHashHandler,
12089      s = e('../lib/event_emitter').EventEmitter,
12090      o = function(e, t) {
12091        i.call(this, t, e),
12092          (this.byName = this.commands),
12093          this.setDefaultHandler('exec', function(e) {
12094            return e.command.exec(e.editor, e.args || {})
12095          })
12096      }
12097    r.inherits(o, i),
12098      function() {
12099        r.implement(this, s),
12100          (this.exec = function(e, t, n) {
12101            if (Array.isArray(e)) {
12102              for (var r = e.length; r--; ) if (this.exec(e[r], t, n)) return !0
12103              return !1
12104            }
12105            typeof e == 'string' && (e = this.commands[e])
12106            if (!e) return !1
12107            if (t && t.$readOnly && !e.readOnly) return !1
12108            if (e.isAvailable && !e.isAvailable(t)) return !1
12109            var i = { editor: t, command: e, args: n }
12110            return (i.returnValue = this._emit('exec', i)), this._signal('afterExec', i), i.returnValue === !1 ? !1 : !0
12111          }),
12112          (this.toggleRecording = function(e) {
12113            if (this.$inReplay) return
12114            return (
12115              e && e._emit('changeStatus'),
12116              this.recording
12117                ? (this.macro.pop(),
12118                  this.removeEventListener('exec', this.$addCommandToMacro),
12119                  this.macro.length || (this.macro = this.oldMacro),
12120                  (this.recording = !1))
12121                : (this.$addCommandToMacro ||
12122                    (this.$addCommandToMacro = function(e) {
12123                      this.macro.push([e.command, e.args])
12124                    }.bind(this)),
12125                  (this.oldMacro = this.macro),
12126                  (this.macro = []),
12127                  this.on('exec', this.$addCommandToMacro),
12128                  (this.recording = !0))
12129            )
12130          }),
12131          (this.replay = function(e) {
12132            if (this.$inReplay || !this.macro) return
12133            if (this.recording) return this.toggleRecording(e)
12134            try {
12135              ;(this.$inReplay = !0),
12136                this.macro.forEach(function(t) {
12137                  typeof t == 'string' ? this.exec(t, e) : this.exec(t[0], e, t[1])
12138                }, this)
12139            } finally {
12140              this.$inReplay = !1
12141            }
12142          }),
12143          (this.trimMacro = function(e) {
12144            return e.map(function(e) {
12145              return typeof e[0] != 'string' && (e[0] = e[0].name), e[1] || (e = e[0]), e
12146            })
12147          })
12148      }.call(o.prototype),
12149      (t.CommandManager = o)
12150  }),
12151  define('ace/commands/default_commands', [
12152    'require',
12153    'exports',
12154    'module',
12155    'ace/lib/lang',
12156    'ace/config',
12157    'ace/range'
12158  ], function(e, t, n) {
12159    'use strict'
12160    function o(e, t) {
12161      return { win: e, mac: t }
12162    }
12163    var r = e('../lib/lang'),
12164      i = e('../config'),
12165      s = e('../range').Range
12166    t.commands = [
12167      {
12168        name: 'showSettingsMenu',
12169        bindKey: o('Ctrl-,', 'Command-,'),
12170        exec: function(e) {
12171          i.loadModule('ace/ext/settings_menu', function(t) {
12172            t.init(e), e.showSettingsMenu()
12173          })
12174        },
12175        readOnly: !0
12176      },
12177      {
12178        name: 'goToNextError',
12179        bindKey: o('Alt-E', 'F4'),
12180        exec: function(e) {
12181          i.loadModule('./ext/error_marker', function(t) {
12182            t.showErrorMarker(e, 1)
12183          })
12184        },
12185        scrollIntoView: 'animate',
12186        readOnly: !0
12187      },
12188      {
12189        name: 'goToPreviousError',
12190        bindKey: o('Alt-Shift-E', 'Shift-F4'),
12191        exec: function(e) {
12192          i.loadModule('./ext/error_marker', function(t) {
12193            t.showErrorMarker(e, -1)
12194          })
12195        },
12196        scrollIntoView: 'animate',
12197        readOnly: !0
12198      },
12199      {
12200        name: 'selectall',
12201        bindKey: o('Ctrl-A', 'Command-A'),
12202        exec: function(e) {
12203          e.selectAll()
12204        },
12205        readOnly: !0
12206      },
12207      {
12208        name: 'centerselection',
12209        bindKey: o(null, 'Ctrl-L'),
12210        exec: function(e) {
12211          e.centerSelection()
12212        },
12213        readOnly: !0
12214      },
12215      {
12216        name: 'gotoline',
12217        bindKey: o('Ctrl-L', 'Command-L'),
12218        exec: function(e, t) {
12219          typeof t != 'number' && (t = parseInt(prompt('Enter line number:'), 10)), isNaN(t) || e.gotoLine(t)
12220        },
12221        readOnly: !0
12222      },
12223      {
12224        name: 'fold',
12225        bindKey: o('Alt-L|Ctrl-F1', 'Command-Alt-L|Command-F1'),
12226        exec: function(e) {
12227          e.session.toggleFold(!1)
12228        },
12229        multiSelectAction: 'forEach',
12230        scrollIntoView: 'center',
12231        readOnly: !0
12232      },
12233      {
12234        name: 'unfold',
12235        bindKey: o('Alt-Shift-L|Ctrl-Shift-F1', 'Command-Alt-Shift-L|Command-Shift-F1'),
12236        exec: function(e) {
12237          e.session.toggleFold(!0)
12238        },
12239        multiSelectAction: 'forEach',
12240        scrollIntoView: 'center',
12241        readOnly: !0
12242      },
12243      {
12244        name: 'toggleFoldWidget',
12245        bindKey: o('F2', 'F2'),
12246        exec: function(e) {
12247          e.session.toggleFoldWidget()
12248        },
12249        multiSelectAction: 'forEach',
12250        scrollIntoView: 'center',
12251        readOnly: !0
12252      },
12253      {
12254        name: 'toggleParentFoldWidget',
12255        bindKey: o('Alt-F2', 'Alt-F2'),
12256        exec: function(e) {
12257          e.session.toggleFoldWidget(!0)
12258        },
12259        multiSelectAction: 'forEach',
12260        scrollIntoView: 'center',
12261        readOnly: !0
12262      },
12263      {
12264        name: 'foldall',
12265        bindKey: o(null, 'Ctrl-Command-Option-0'),
12266        exec: function(e) {
12267          e.session.foldAll()
12268        },
12269        scrollIntoView: 'center',
12270        readOnly: !0
12271      },
12272      {
12273        name: 'foldOther',
12274        bindKey: o('Alt-0', 'Command-Option-0'),
12275        exec: function(e) {
12276          e.session.foldAll(), e.session.unfold(e.selection.getAllRanges())
12277        },
12278        scrollIntoView: 'center',
12279        readOnly: !0
12280      },
12281      {
12282        name: 'unfoldall',
12283        bindKey: o('Alt-Shift-0', 'Command-Option-Shift-0'),
12284        exec: function(e) {
12285          e.session.unfold()
12286        },
12287        scrollIntoView: 'center',
12288        readOnly: !0
12289      },
12290      {
12291        name: 'findnext',
12292        bindKey: o('Ctrl-K', 'Command-G'),
12293        exec: function(e) {
vendor: 13,126 bytes, lines 12294-12786
12294          e.findNext()
12295        },
12296        multiSelectAction: 'forEach',
12297        scrollIntoView: 'center',
12298        readOnly: !0
12299      },
12300      {
12301        name: 'findprevious',
12302        bindKey: o('Ctrl-Shift-K', 'Command-Shift-G'),
12303        exec: function(e) {
12304          e.findPrevious()
12305        },
12306        multiSelectAction: 'forEach',
12307        scrollIntoView: 'center',
12308        readOnly: !0
12309      },
12310      {
12311        name: 'selectOrFindNext',
12312        bindKey: o('Alt-K', 'Ctrl-G'),
12313        exec: function(e) {
12314          e.selection.isEmpty() ? e.selection.selectWord() : e.findNext()
12315        },
12316        readOnly: !0
12317      },
12318      {
12319        name: 'selectOrFindPrevious',
12320        bindKey: o('Alt-Shift-K', 'Ctrl-Shift-G'),
12321        exec: function(e) {
12322          e.selection.isEmpty() ? e.selection.selectWord() : e.findPrevious()
12323        },
12324        readOnly: !0
12325      },
12326      {
12327        name: 'find',
12328        bindKey: o('Ctrl-F', 'Command-F'),
12329        exec: function(e) {
12330          i.loadModule('ace/ext/searchbox', function(t) {
12331            t.Search(e)
12332          })
12333        },
12334        readOnly: !0
12335      },
12336      {
12337        name: 'overwrite',
12338        bindKey: 'Insert',
12339        exec: function(e) {
12340          e.toggleOverwrite()
12341        },
12342        readOnly: !0
12343      },
12344      {
12345        name: 'selecttostart',
12346        bindKey: o('Ctrl-Shift-Home', 'Command-Shift-Home|Command-Shift-Up'),
12347        exec: function(e) {
12348          e.getSelection().selectFileStart()
12349        },
12350        multiSelectAction: 'forEach',
12351        readOnly: !0,
12352        scrollIntoView: 'animate',
12353        aceCommandGroup: 'fileJump'
12354      },
12355      {
12356        name: 'gotostart',
12357        bindKey: o('Ctrl-Home', 'Command-Home|Command-Up'),
12358        exec: function(e) {
12359          e.navigateFileStart()
12360        },
12361        multiSelectAction: 'forEach',
12362        readOnly: !0,
12363        scrollIntoView: 'animate',
12364        aceCommandGroup: 'fileJump'
12365      },
12366      {
12367        name: 'selectup',
12368        bindKey: o('Shift-Up', 'Shift-Up|Ctrl-Shift-P'),
12369        exec: function(e) {
12370          e.getSelection().selectUp()
12371        },
12372        multiSelectAction: 'forEach',
12373        scrollIntoView: 'cursor',
12374        readOnly: !0
12375      },
12376      {
12377        name: 'golineup',
12378        bindKey: o('Up', 'Up|Ctrl-P'),
12379        exec: function(e, t) {
12380          e.navigateUp(t.times)
12381        },
12382        multiSelectAction: 'forEach',
12383        scrollIntoView: 'cursor',
12384        readOnly: !0
12385      },
12386      {
12387        name: 'selecttoend',
12388        bindKey: o('Ctrl-Shift-End', 'Command-Shift-End|Command-Shift-Down'),
12389        exec: function(e) {
12390          e.getSelection().selectFileEnd()
12391        },
12392        multiSelectAction: 'forEach',
12393        readOnly: !0,
12394        scrollIntoView: 'animate',
12395        aceCommandGroup: 'fileJump'
12396      },
12397      {
12398        name: 'gotoend',
12399        bindKey: o('Ctrl-End', 'Command-End|Command-Down'),
12400        exec: function(e) {
12401          e.navigateFileEnd()
12402        },
12403        multiSelectAction: 'forEach',
12404        readOnly: !0,
12405        scrollIntoView: 'animate',
12406        aceCommandGroup: 'fileJump'
12407      },
12408      {
12409        name: 'selectdown',
12410        bindKey: o('Shift-Down', 'Shift-Down|Ctrl-Shift-N'),
12411        exec: function(e) {
12412          e.getSelection().selectDown()
12413        },
12414        multiSelectAction: 'forEach',
12415        scrollIntoView: 'cursor',
12416        readOnly: !0
12417      },
12418      {
12419        name: 'golinedown',
12420        bindKey: o('Down', 'Down|Ctrl-N'),
12421        exec: function(e, t) {
12422          e.navigateDown(t.times)
12423        },
12424        multiSelectAction: 'forEach',
12425        scrollIntoView: 'cursor',
12426        readOnly: !0
12427      },
12428      {
12429        name: 'selectwordleft',
12430        bindKey: o('Ctrl-Shift-Left', 'Option-Shift-Left'),
12431        exec: function(e) {
12432          e.getSelection().selectWordLeft()
12433        },
12434        multiSelectAction: 'forEach',
12435        scrollIntoView: 'cursor',
12436        readOnly: !0
12437      },
12438      {
12439        name: 'gotowordleft',
12440        bindKey: o('Ctrl-Left', 'Option-Left'),
12441        exec: function(e) {
12442          e.navigateWordLeft()
12443        },
12444        multiSelectAction: 'forEach',
12445        scrollIntoView: 'cursor',
12446        readOnly: !0
12447      },
12448      {
12449        name: 'selecttolinestart',
12450        bindKey: o('Alt-Shift-Left', 'Command-Shift-Left|Ctrl-Shift-A'),
12451        exec: function(e) {
12452          e.getSelection().selectLineStart()
12453        },
12454        multiSelectAction: 'forEach',
12455        scrollIntoView: 'cursor',
12456        readOnly: !0
12457      },
12458      {
12459        name: 'gotolinestart',
12460        bindKey: o('Alt-Left|Home', 'Command-Left|Home|Ctrl-A'),
12461        exec: function(e) {
12462          e.navigateLineStart()
12463        },
12464        multiSelectAction: 'forEach',
12465        scrollIntoView: 'cursor',
12466        readOnly: !0
12467      },
12468      {
12469        name: 'selectleft',
12470        bindKey: o('Shift-Left', 'Shift-Left|Ctrl-Shift-B'),
12471        exec: function(e) {
12472          e.getSelection().selectLeft()
12473        },
12474        multiSelectAction: 'forEach',
12475        scrollIntoView: 'cursor',
12476        readOnly: !0
12477      },
12478      {
12479        name: 'gotoleft',
12480        bindKey: o('Left', 'Left|Ctrl-B'),
12481        exec: function(e, t) {
12482          e.navigateLeft(t.times)
12483        },
12484        multiSelectAction: 'forEach',
12485        scrollIntoView: 'cursor',
12486        readOnly: !0
12487      },
12488      {
12489        name: 'selectwordright',
12490        bindKey: o('Ctrl-Shift-Right', 'Option-Shift-Right'),
12491        exec: function(e) {
12492          e.getSelection().selectWordRight()
12493        },
12494        multiSelectAction: 'forEach',
12495        scrollIntoView: 'cursor',
12496        readOnly: !0
12497      },
12498      {
12499        name: 'gotowordright',
12500        bindKey: o('Ctrl-Right', 'Option-Right'),
12501        exec: function(e) {
12502          e.navigateWordRight()
12503        },
12504        multiSelectAction: 'forEach',
12505        scrollIntoView: 'cursor',
12506        readOnly: !0
12507      },
12508      {
12509        name: 'selecttolineend',
12510        bindKey: o('Alt-Shift-Right', 'Command-Shift-Right|Shift-End|Ctrl-Shift-E'),
12511        exec: function(e) {
12512          e.getSelection().selectLineEnd()
12513        },
12514        multiSelectAction: 'forEach',
12515        scrollIntoView: 'cursor',
12516        readOnly: !0
12517      },
12518      {
12519        name: 'gotolineend',
12520        bindKey: o('Alt-Right|End', 'Command-Right|End|Ctrl-E'),
12521        exec: function(e) {
12522          e.navigateLineEnd()
12523        },
12524        multiSelectAction: 'forEach',
12525        scrollIntoView: 'cursor',
12526        readOnly: !0
12527      },
12528      {
12529        name: 'selectright',
12530        bindKey: o('Shift-Right', 'Shift-Right'),
12531        exec: function(e) {
12532          e.getSelection().selectRight()
12533        },
12534        multiSelectAction: 'forEach',
12535        scrollIntoView: 'cursor',
12536        readOnly: !0
12537      },
12538      {
12539        name: 'gotoright',
12540        bindKey: o('Right', 'Right|Ctrl-F'),
12541        exec: function(e, t) {
12542          e.navigateRight(t.times)
12543        },
12544        multiSelectAction: 'forEach',
12545        scrollIntoView: 'cursor',
12546        readOnly: !0
12547      },
12548      {
12549        name: 'selectpagedown',
12550        bindKey: 'Shift-PageDown',
12551        exec: function(e) {
12552          e.selectPageDown()
12553        },
12554        readOnly: !0
12555      },
12556      {
12557        name: 'pagedown',
12558        bindKey: o(null, 'Option-PageDown'),
12559        exec: function(e) {
12560          e.scrollPageDown()
12561        },
12562        readOnly: !0
12563      },
12564      {
12565        name: 'gotopagedown',
12566        bindKey: o('PageDown', 'PageDown|Ctrl-V'),
12567        exec: function(e) {
12568          e.gotoPageDown()
12569        },
12570        readOnly: !0
12571      },
12572      {
12573        name: 'selectpageup',
12574        bindKey: 'Shift-PageUp',
12575        exec: function(e) {
12576          e.selectPageUp()
12577        },
12578        readOnly: !0
12579      },
12580      {
12581        name: 'pageup',
12582        bindKey: o(null, 'Option-PageUp'),
12583        exec: function(e) {
12584          e.scrollPageUp()
12585        },
12586        readOnly: !0
12587      },
12588      {
12589        name: 'gotopageup',
12590        bindKey: 'PageUp',
12591        exec: function(e) {
12592          e.gotoPageUp()
12593        },
12594        readOnly: !0
12595      },
12596      {
12597        name: 'scrollup',
12598        bindKey: o('Ctrl-Up', null),
12599        exec: function(e) {
12600          e.renderer.scrollBy(0, -2 * e.renderer.layerConfig.lineHeight)
12601        },
12602        readOnly: !0
12603      },
12604      {
12605        name: 'scrolldown',
12606        bindKey: o('Ctrl-Down', null),
12607        exec: function(e) {
12608          e.renderer.scrollBy(0, 2 * e.renderer.layerConfig.lineHeight)
12609        },
12610        readOnly: !0
12611      },
12612      {
12613        name: 'selectlinestart',
12614        bindKey: 'Shift-Home',
12615        exec: function(e) {
12616          e.getSelection().selectLineStart()
12617        },
12618        multiSelectAction: 'forEach',
12619        scrollIntoView: 'cursor',
12620        readOnly: !0
12621      },
12622      {
12623        name: 'selectlineend',
12624        bindKey: 'Shift-End',
12625        exec: function(e) {
12626          e.getSelection().selectLineEnd()
12627        },
12628        multiSelectAction: 'forEach',
12629        scrollIntoView: 'cursor',
12630        readOnly: !0
12631      },
12632      {
12633        name: 'togglerecording',
12634        bindKey: o('Ctrl-Alt-E', 'Command-Option-E'),
12635        exec: function(e) {
12636          e.commands.toggleRecording(e)
12637        },
12638        readOnly: !0
12639      },
12640      {
12641        name: 'replaymacro',
12642        bindKey: o('Ctrl-Shift-E', 'Command-Shift-E'),
12643        exec: function(e) {
12644          e.commands.replay(e)
12645        },
12646        readOnly: !0
12647      },
12648      {
12649        name: 'jumptomatching',
12650        bindKey: o('Ctrl-P', 'Ctrl-P'),
12651        exec: function(e) {
12652          e.jumpToMatching()
12653        },
12654        multiSelectAction: 'forEach',
12655        scrollIntoView: 'animate',
12656        readOnly: !0
12657      },
12658      {
12659        name: 'selecttomatching',
12660        bindKey: o('Ctrl-Shift-P', 'Ctrl-Shift-P'),
12661        exec: function(e) {
12662          e.jumpToMatching(!0)
12663        },
12664        multiSelectAction: 'forEach',
12665        scrollIntoView: 'animate',
12666        readOnly: !0
12667      },
12668      {
12669        name: 'expandToMatching',
12670        bindKey: o('Ctrl-Shift-M', 'Ctrl-Shift-M'),
12671        exec: function(e) {
12672          e.jumpToMatching(!0, !0)
12673        },
12674        multiSelectAction: 'forEach',
12675        scrollIntoView: 'animate',
12676        readOnly: !0
12677      },
12678      { name: 'passKeysToBrowser', bindKey: o(null, null), exec: function() {}, passEvent: !0, readOnly: !0 },
12679      { name: 'copy', exec: function(e) {}, readOnly: !0 },
12680      {
12681        name: 'cut',
12682        exec: function(e) {
12683          var t = e.$copyWithEmptySelection && e.selection.isEmpty(),
12684            n = t ? e.selection.getLineRange() : e.selection.getRange()
12685          e._emit('cut', n), n.isEmpty() || e.session.remove(n), e.clearSelection()
12686        },
12687        scrollIntoView: 'cursor',
12688        multiSelectAction: 'forEach'
12689      },
12690      {
12691        name: 'paste',
12692        exec: function(e, t) {
12693          e.$handlePaste(t)
12694        },
12695        scrollIntoView: 'cursor'
12696      },
12697      {
12698        name: 'removeline',
12699        bindKey: o('Ctrl-D', 'Command-D'),
12700        exec: function(e) {
12701          e.removeLines()
12702        },
12703        scrollIntoView: 'cursor',
12704        multiSelectAction: 'forEachLine'
12705      },
12706      {
12707        name: 'duplicateSelection',
12708        bindKey: o('Ctrl-Shift-D', 'Command-Shift-D'),
12709        exec: function(e) {
12710          e.duplicateSelection()
12711        },
12712        scrollIntoView: 'cursor',
12713        multiSelectAction: 'forEach'
12714      },
12715      {
12716        name: 'sortlines',
12717        bindKey: o('Ctrl-Alt-S', 'Command-Alt-S'),
12718        exec: function(e) {
12719          e.sortLines()
12720        },
12721        scrollIntoView: 'selection',
12722        multiSelectAction: 'forEachLine'
12723      },
12724      {
12725        name: 'togglecomment',
12726        bindKey: o('Ctrl-/', 'Command-/'),
12727        exec: function(e) {
12728          e.toggleCommentLines()
12729        },
12730        multiSelectAction: 'forEachLine',
12731        scrollIntoView: 'selectionPart'
12732      },
12733      {
12734        name: 'toggleBlockComment',
12735        bindKey: o('Ctrl-Shift-/', 'Command-Shift-/'),
12736        exec: function(e) {
12737          e.toggleBlockComment()
12738        },
12739        multiSelectAction: 'forEach',
12740        scrollIntoView: 'selectionPart'
12741      },
12742      {
12743        name: 'modifyNumberUp',
12744        bindKey: o('Ctrl-Shift-Up', 'Alt-Shift-Up'),
12745        exec: function(e) {
12746          e.modifyNumber(1)
12747        },
12748        scrollIntoView: 'cursor',
12749        multiSelectAction: 'forEach'
12750      },
12751      {
12752        name: 'modifyNumberDown',
12753        bindKey: o('Ctrl-Shift-Down', 'Alt-Shift-Down'),
12754        exec: function(e) {
12755          e.modifyNumber(-1)
12756        },
12757        scrollIntoView: 'cursor',
12758        multiSelectAction: 'forEach'
12759      },
12760      {
12761        name: 'replace',
12762        bindKey: o('Ctrl-H', 'Command-Option-F'),
12763        exec: function(e) {
12764          i.loadModule('ace/ext/searchbox', function(t) {
12765            t.Search(e, !0)
12766          })
12767        }
12768      },
12769      {
12770        name: 'undo',
12771        bindKey: o('Ctrl-Z', 'Command-Z'),
12772        exec: function(e) {
12773          e.undo()
12774        }
12775      },
12776      {
12777        name: 'redo',
12778        bindKey: o('Ctrl-Shift-Z|Ctrl-Y', 'Command-Shift-Z|Command-Y'),
12779        exec: function(e) {
12780          e.redo()
12781        }
12782      },
12783      {
12784        name: 'copylinesup',
12785        bindKey: o('Alt-Shift-Up', 'Command-Option-Up'),
12786        exec: function(e) {
12787          e.copyLinesUp()
12788        },
12789        scrollIntoView: 'cursor'
12790      },
12791      {
12792        name: 'movelinesup',
12793        bindKey: o('Alt-Up', 'Option-Up'),
12794        exec: function(e) {
12795          e.moveLinesUp()
12796        },
12797        scrollIntoView: 'cursor'
12798      },
12799      {
12800        name: 'copylinesdown',
12801        bindKey: o('Alt-Shift-Down', 'Command-Option-Down'),
12802        exec: function(e) {
12803          e.copyLinesDown()
12804        },
12805        scrollIntoView: 'cursor'
12806      },
12807      {
12808        name: 'movelinesdown',
12809        bindKey: o('Alt-Down', 'Option-Down'),
12810        exec: function(e) {
12811          e.moveLinesDown()
12812        },
12813        scrollIntoView: 'cursor'
12814      },
12815      {
12816        name: 'del',
12817        bindKey: o('Delete', 'Delete|Ctrl-D|Shift-Delete'),
12818        exec: function(e) {
12819          e.remove('right')
12820        },
12821        multiSelectAction: 'forEach',
12822        scrollIntoView: 'cursor'
12823      },
12824      {
12825        name: 'backspace',
12826        bindKey: o('Shift-Backspace|Backspace', 'Ctrl-Backspace|Shift-Backspace|Backspace|Ctrl-H'),
12827        exec: function(e) {
12828          e.remove('left')
12829        },
12830        multiSelectAction: 'forEach',
12831        scrollIntoView: 'cursor'
12832      },
12833      {
12834        name: 'cut_or_delete',
12835        bindKey: o('Shift-Delete', null),
12836        exec: function(e) {
12837          if (!e.selection.isEmpty()) return !1
12838          e.remove('left')
12839        },
12840        multiSelectAction: 'forEach',
12841        scrollIntoView: 'cursor'
12842      },
12843      {
12844        name: 'removetolinestart',
12845        bindKey: o('Alt-Backspace', 'Command-Backspace'),
12846        exec: function(e) {
12847          e.removeToLineStart()
12848        },
12849        multiSelectAction: 'forEach',
12850        scrollIntoView: 'cursor'
12851      },
12852      {
12853        name: 'removetolineend',
12854        bindKey: o('Alt-Delete', 'Ctrl-K|Command-Delete'),
12855        exec: function(e) {
12856          e.removeToLineEnd()
12857        },
12858        multiSelectAction: 'forEach',
12859        scrollIntoView: 'cursor'
12860      },
12861      {
12862        name: 'removetolinestarthard',
12863        bindKey: o('Ctrl-Shift-Backspace', null),
12864        exec: function(e) {
12865          var t = e.selection.getRange()
12866          ;(t.start.column = 0), e.session.remove(t)
12867        },
12868        multiSelectAction: 'forEach',
12869        scrollIntoView: 'cursor'
12870      },
12871      {
12872        name: 'removetolineendhard',
12873        bindKey: o('Ctrl-Shift-Delete', null),
12874        exec: function(e) {
12875          var t = e.selection.getRange()
12876          ;(t.end.column = Number.MAX_VALUE), e.session.remove(t)
12877        },
12878        multiSelectAction: 'forEach',
12879        scrollIntoView: 'cursor'
12880      },
12881      {
12882        name: 'removewordleft',
12883        bindKey: o('Ctrl-Backspace', 'Alt-Backspace|Ctrl-Alt-Backspace'),
12884        exec: function(e) {
12885          e.removeWordLeft()
12886        },
12887        multiSelectAction: 'forEach',
12888        scrollIntoView: 'cursor'
12889      },
12890      {
12891        name: 'removewordright',
12892        bindKey: o('Ctrl-Delete', 'Alt-Delete'),
12893        exec: function(e) {
12894          e.removeWordRight()
12895        },
12896        multiSelectAction: 'forEach',
12897        scrollIntoView: 'cursor'
12898      },
12899      {
12900        name: 'outdent',
12901        bindKey: o('Shift-Tab', 'Shift-Tab'),
12902        exec: function(e) {
12903          e.blockOutdent()
12904        },
12905        multiSelectAction: 'forEach',
12906        scrollIntoView: 'selectionPart'
12907      },
12908      {
12909        name: 'indent',
12910        bindKey: o('Tab', 'Tab'),
12911        exec: function(e) {
12912          e.indent()
12913        },
12914        multiSelectAction: 'forEach',
12915        scrollIntoView: 'selectionPart'
12916      },
12917      {
12918        name: 'blockoutdent',
12919        bindKey: o('Ctrl-[', 'Ctrl-['),
12920        exec: function(e) {
12921          e.blockOutdent()
12922        },
12923        multiSelectAction: 'forEachLine',
12924        scrollIntoView: 'selectionPart'
12925      },
12926      {
12927        name: 'blockindent',
12928        bindKey: o('Ctrl-]', 'Ctrl-]'),
12929        exec: function(e) {
12930          e.blockIndent()
12931        },
12932        multiSelectAction: 'forEachLine',
12933        scrollIntoView: 'selectionPart'
12934      },
12935      {
12936        name: 'insertstring',
12937        exec: function(e, t) {
12938          e.insert(t)
12939        },
12940        multiSelectAction: 'forEach',
12941        scrollIntoView: 'cursor'
12942      },
12943      {
12944        name: 'inserttext',
12945        exec: function(e, t) {
12946          e.insert(r.stringRepeat(t.text || '', t.times || 1))
12947        },
12948        multiSelectAction: 'forEach',
12949        scrollIntoView: 'cursor'
12950      },
12951      {
12952        name: 'splitline',
12953        bindKey: o(null, 'Ctrl-O'),
12954        exec: function(e) {
12955          e.splitLine()
12956        },
12957        multiSelectAction: 'forEach',
12958        scrollIntoView: 'cursor'
12959      },
12960      {
12961        name: 'transposeletters',
12962        bindKey: o('Alt-Shift-X', 'Ctrl-T'),
12963        exec: function(e) {
12964          e.transposeLetters()
12965        },
12966        multiSelectAction: function(e) {
12967          e.transposeSelections(1)
12968        },
12969        scrollIntoView: 'cursor'
12970      },
12971      {
12972        name: 'touppercase',
12973        bindKey: o('Ctrl-U', 'Ctrl-U'),
12974        exec: function(e) {
12975          e.toUpperCase()
12976        },
12977        multiSelectAction: 'forEach',
12978        scrollIntoView: 'cursor'
12979      },
12980      {
12981        name: 'tolowercase',
12982        bindKey: o('Ctrl-Shift-U', 'Ctrl-Shift-U'),
12983        exec: function(e) {
12984          e.toLowerCase()
12985        },
12986        multiSelectAction: 'forEach',
12987        scrollIntoView: 'cursor'
12988      },
12989      {
12990        name: 'expandtoline',
12991        bindKey: o('Ctrl-Shift-L', 'Command-Shift-L'),
12992        exec: function(e) {
12993          var t = e.selection.getRange()
12994          ;(t.start.column = t.end.column = 0), t.end.row++, e.selection.setRange(t, !1)
12995        },
12996        multiSelectAction: 'forEach',
12997        scrollIntoView: 'cursor',
12998        readOnly: !0
12999      },
13000      {
13001        name: 'joinlines',
13002        bindKey: o(null, null),
13003        exec: function(e) {
13004          var t = e.selection.isBackwards(),
13005            n = t ? e.selection.getSelectionLead() : e.selection.getSelectionAnchor(),
13006            i = t ? e.selection.getSelectionAnchor() : e.selection.getSelectionLead(),
13007            o = e.session.doc.getLine(n.row).length,
13008            u = e.session.doc.getTextRange(e.selection.getRange()),
13009            a = u.replace(/\n\s*/, ' ').length,
13010            f = e.session.doc.getLine(n.row)
13011          for (var l = n.row + 1; l <= i.row + 1; l++) {
13012            var c = r.stringTrimLeft(r.stringTrimRight(e.session.doc.getLine(l)))
13013            c.length !== 0 && (c = ' ' + c), (f += c)
13014          }
13015          i.row + 1 < e.session.doc.getLength() - 1 && (f += e.session.doc.getNewLineCharacter()),
13016            e.clearSelection(),
13017            e.session.doc.replace(new s(n.row, 0, i.row + 2, 0), f),
13018            a > 0
13019              ? (e.selection.moveCursorTo(n.row, n.column), e.selection.selectTo(n.row, n.column + a))
13020              : ((o = e.session.doc.getLine(n.row).length > o ? o + 1 : o), e.selection.moveCursorTo(n.row, o))
13021        },
13022        multiSelectAction: 'forEach',
13023        readOnly: !0
13024      },
13025      {
13026        name: 'invertSelection',
13027        bindKey: o(null, null),
13028        exec: function(e) {
13029          var t = e.session.doc.getLength() - 1,
13030            n = e.session.doc.getLine(t).length,
13031            r = e.selection.rangeList.ranges,
13032            i = []
13033          r.length < 1 && (r = [e.selection.getRange()])
13034          for (var o = 0; o < r.length; o++)
13035            o == r.length - 1 &&
13036              (r[o].end.row !== t || r[o].end.column !== n) &&
13037              i.push(new s(r[o].end.row, r[o].end.column, t, n)),
13038              o === 0
13039                ? (r[o].start.row !== 0 || r[o].start.column !== 0) &&
13040                  i.push(new s(0, 0, r[o].start.row, r[o].start.column))
13041                : i.push(new s(r[o - 1].end.row, r[o - 1].end.column, r[o].start.row, r[o].start.column))
13042          e.exitMultiSelectMode(), e.clearSelection()
13043          for (var o = 0; o < i.length; o++) e.selection.addRange(i[o], !1)
13044        },
13045        readOnly: !0,
13046        scrollIntoView: 'none'
13047      }
13048    ]
13049  }),
13050  define('ace/clipboard', ['require', 'exports', 'module'], function(e, t, n) {
13051    'use strict'
13052    n.exports = { lineMode: !1 }
13053  }),
13054  define('ace/editor', [
13055    'require',
13056    'exports',
13057    'module',
13058    'ace/lib/fixoldbrowsers',
13059    'ace/lib/oop',
13060    'ace/lib/dom',
13061    'ace/lib/lang',
13062    'ace/lib/useragent',
13063    'ace/keyboard/textinput',
13064    'ace/mouse/mouse_handler',
13065    'ace/mouse/fold_handler',
13066    'ace/keyboard/keybinding',
13067    'ace/edit_session',
13068    'ace/search',
13069    'ace/range',
13070    'ace/lib/event_emitter',
13071    'ace/commands/command_manager',
13072    'ace/commands/default_commands',
13073    'ace/config',
13074    'ace/token_iterator',
13075    'ace/clipboard'
13076  ], function(e, t, n) {
13077    'use strict'
13078    e('./lib/fixoldbrowsers')
13079    var r = e('./lib/oop'),
13080      i = e('./lib/dom'),
13081      s = e('./lib/lang'),
13082      o = e('./lib/useragent'),
13083      u = e('./keyboard/textinput').TextInput,
13084      a = e('./mouse/mouse_handler').MouseHandler,
13085      f = e('./mouse/fold_handler').FoldHandler,
13086      l = e('./keyboard/keybinding').KeyBinding,
13087      c = e('./edit_session').EditSession,
13088      h = e('./search').Search,
13089      p = e('./range').Range,
13090      d = e('./lib/event_emitter').EventEmitter,
13091      v = e('./commands/command_manager').CommandManager,
13092      m = e('./commands/default_commands').commands,
13093      g = e('./config'),
13094      y = e('./token_iterator').TokenIterator,
13095      b = e('./clipboard'),
13096      w = function(e, t, n) {
13097        var r = e.getContainerElement()
13098        ;(this.container = r),
13099          (this.renderer = e),
13100          (this.id = 'editor' + ++w.$uid),
13101          (this.commands = new v(o.isMac ? 'mac' : 'win', m)),
13102          typeof document == 'object' &&
13103            ((this.textInput = new u(e.getTextAreaContainer(), this)),
13104            (this.renderer.textarea = this.textInput.getElement()),
13105            (this.$mouseHandler = new a(this)),
13106            new f(this)),
13107          (this.keyBinding = new l(this)),
13108          (this.$search = new h().set({ wrap: !0 })),
13109          (this.$historyTracker = this.$historyTracker.bind(this)),
13110          this.commands.on('exec', this.$historyTracker),
13111          this.$initOperationListeners(),
13112          (this._$emitInputEvent = s.delayedCall(
13113            function() {
13114              this._signal('input', {}),
13115                this.session && this.session.bgTokenizer && this.session.bgTokenizer.scheduleStart()
13116            }.bind(this)
13117          )),
13118          this.on('change', function(e, t) {
13119            t._$emitInputEvent.schedule(31)
13120          }),
13121          this.setSession(t || (n && n.session) || new c('')),
13122          g.resetOptions(this),
13123          n && this.setOptions(n),
13124          g._signal('editor', this)
13125      }
13126    ;(w.$uid = 0),
13127      function() {
13128        r.implement(this, d),
13129          (this.$initOperationListeners = function() {
13130            this.commands.on('exec', this.startOperation.bind(this), !0),
13131              this.commands.on('afterExec', this.endOperation.bind(this), !0),
13132              (this.$opResetTimer = s.delayedCall(this.endOperation.bind(this))),
13133              this.on(
13134                'change',
13135                function() {
13136                  this.curOp || (this.startOperation(), (this.curOp.selectionBefore = this.$lastSel)),
13137                    (this.curOp.docChanged = !0)
13138                }.bind(this),
13139                !0
13140              ),
13141              this.on(
13142                'changeSelection',
13143                function() {
13144                  this.curOp || (this.startOperation(), (this.curOp.selectionBefore = this.$lastSel)),
13145                    (this.curOp.selectionChanged = !0)
13146                }.bind(this),
13147                !0
13148              )
13149          }),
13150          (this.curOp = null),
13151          (this.prevOp = {}),
13152          (this.startOperation = function(e) {
13153            if (this.curOp) {
13154              if (!e || this.curOp.command) return
13155              this.prevOp = this.curOp
13156            }
13157            e || ((this.previousCommand = null), (e = {})),
13158              this.$opResetTimer.schedule(),
13159              (this.curOp = this.session.curOp = {
13160                command: e.command || {},
13161                args: e.args,
13162                scrollTop: this.renderer.scrollTop
13163              }),
13164              (this.curOp.selectionBefore = this.selection.toJSON())
13165          }),
13166          (this.endOperation = function(e) {
13167            if (this.curOp) {
13168              if (e && e.returnValue === !1) return (this.curOp = null)
13169              this._signal('beforeEndOperation')
13170              var t = this.curOp.command,
13171                n = t && t.scrollIntoView
13172              if (n) {
13173                switch (n) {
13174                  case 'center-animate':
13175                    n = 'animate'
13176                  case 'center':
13177                    this.renderer.scrollCursorIntoView(null, 0.5)
13178                    break
13179                  case 'animate':
13180                  case 'cursor':
13181                    this.renderer.scrollCursorIntoView()
13182                    break
13183                  case 'selectionPart':
13184                    var r = this.selection.getRange(),
13185                      i = this.renderer.layerConfig
13186                    ;(r.start.row >= i.lastRow || r.end.row <= i.firstRow) &&
13187                      this.renderer.scrollSelectionIntoView(this.selection.anchor, this.selection.lead)
13188                    break
13189                  default:
13190                }
13191                n == 'animate' && this.renderer.animateScrolling(this.curOp.scrollTop)
13192              }
13193              var s = this.selection.toJSON()
13194              ;(this.curOp.selectionAfter = s),
13195                (this.$lastSel = this.selection.toJSON()),
13196                this.session.getUndoManager().addSelection(s),
13197                (this.prevOp = this.curOp),
13198                (this.curOp = null)
13199            }
13200          }),
13201          (this.$mergeableCommands = ['backspace', 'del', 'insertstring']),
13202          (this.$historyTracker = function(e) {
13203            if (!this.$mergeUndoDeltas) return
13204            var t = this.prevOp,
13205              n = this.$mergeableCommands,
13206              r = t.command && e.command.name == t.command.name
13207            if (e.command.name == 'insertstring') {
13208              var i = e.args
13209              this.mergeNextCommand === undefined && (this.mergeNextCommand = !0),
13210                (r = r && this.mergeNextCommand && (!/\s/.test(i) || /\s/.test(t.args))),
13211                (this.mergeNextCommand = !0)
13212            } else r = r && n.indexOf(e.command.name) !== -1
13213            this.$mergeUndoDeltas != 'always' && Date.now() - this.sequenceStartTime > 2e3 && (r = !1),
13214              r
13215                ? (this.session.mergeUndoDeltas = !0)
13216                : n.indexOf(e.command.name) !== -1 && (this.sequenceStartTime = Date.now())
13217          }),
13218          (this.setKeyboardHandler = function(e, t) {
13219            if (e && typeof e == 'string' && e != 'ace') {
13220              this.$keybindingId = e
13221              var n = this
13222              g.loadModule(['keybinding', e], function(r) {
13223                n.$keybindingId == e && n.keyBinding.setKeyboardHandler(r && r.handler), t && t()
13224              })
13225            } else (this.$keybindingId = null), this.keyBinding.setKeyboardHandler(e), t && t()
13226          }),
13227          (this.getKeyboardHandler = function() {
13228            return this.keyBinding.getKeyboardHandler()
13229          }),
13230          (this.setSession = function(e) {
13231            if (this.session == e) return
13232            this.curOp && this.endOperation(), (this.curOp = {})
13233            var t = this.session
13234            if (t) {
13235              this.session.off('change', this.$onDocumentChange),
13236                this.session.off('changeMode', this.$onChangeMode),
13237                this.session.off('tokenizerUpdate', this.$onTokenizerUpdate),
13238                this.session.off('changeTabSize', this.$onChangeTabSize),
13239                this.session.off('changeWrapLimit', this.$onChangeWrapLimit),
13240                this.session.off('changeWrapMode', this.$onChangeWrapMode),
13241                this.session.off('changeFold', this.$onChangeFold),
13242                this.session.off('changeFrontMarker', this.$onChangeFrontMarker),
13243                this.session.off('changeBackMarker', this.$onChangeBackMarker),
13244                this.session.off('changeBreakpoint', this.$onChangeBreakpoint),
13245                this.session.off('changeAnnotation', this.$onChangeAnnotation),
13246                this.session.off('changeOverwrite', this.$onCursorChange),
13247                this.session.off('changeScrollTop', this.$onScrollTopChange),
13248                this.session.off('changeScrollLeft', this.$onScrollLeftChange)
13249              var n = this.session.getSelection()
13250              n.off('changeCursor', this.$onCursorChange), n.off('changeSelection', this.$onSelectionChange)
13251            }
13252            ;(this.session = e),
13253              e
13254                ? ((this.$onDocumentChange = this.onDocumentChange.bind(this)),
13255                  e.on('change', this.$onDocumentChange),
13256                  this.renderer.setSession(e),
13257                  (this.$onChangeMode = this.onChangeMode.bind(this)),
13258                  e.on('changeMode', this.$onChangeMode),
13259                  (this.$onTokenizerUpdate = this.onTokenizerUpdate.bind(this)),
13260                  e.on('tokenizerUpdate', this.$onTokenizerUpdate),
13261                  (this.$onChangeTabSize = this.renderer.onChangeTabSize.bind(this.renderer)),
13262                  e.on('changeTabSize', this.$onChangeTabSize),
13263                  (this.$onChangeWrapLimit = this.onChangeWrapLimit.bind(this)),
13264                  e.on('changeWrapLimit', this.$onChangeWrapLimit),
13265                  (this.$onChangeWrapMode = this.onChangeWrapMode.bind(this)),
13266                  e.on('changeWrapMode', this.$onChangeWrapMode),
13267                  (this.$onChangeFold = this.onChangeFold.bind(this)),
13268                  e.on('changeFold', this.$onChangeFold),
13269                  (this.$onChangeFrontMarker = this.onChangeFrontMarker.bind(this)),
13270                  this.session.on('changeFrontMarker', this.$onChangeFrontMarker),
13271                  (this.$onChangeBackMarker = this.onChangeBackMarker.bind(this)),
13272                  this.session.on('changeBackMarker', this.$onChangeBackMarker),
13273                  (this.$onChangeBreakpoint = this.onChangeBreakpoint.bind(this)),
13274                  this.session.on('changeBreakpoint', this.$onChangeBreakpoint),
13275                  (this.$onChangeAnnotation = this.onChangeAnnotation.bind(this)),
13276                  this.session.on('changeAnnotation', this.$onChangeAnnotation),
13277                  (this.$onCursorChange = this.onCursorChange.bind(this)),
13278                  this.session.on('changeOverwrite', this.$onCursorChange),
13279                  (this.$onScrollTopChange = this.onScrollTopChange.bind(this)),
13280                  this.session.on('changeScrollTop', this.$onScrollTopChange),
13281                  (this.$onScrollLeftChange = this.onScrollLeftChange.bind(this)),
13282                  this.session.on('changeScrollLeft', this.$onScrollLeftChange),
13283                  (this.selection = e.getSelection()),
13284                  this.selection.on('changeCursor', this.$onCursorChange),
13285                  (this.$onSelectionChange = this.onSelectionChange.bind(this)),
13286                  this.selection.on('changeSelection', this.$onSelectionChange),
13287                  this.onChangeMode(),
13288                  this.onCursorChange(),
13289                  this.onScrollTopChange(),
13290                  this.onScrollLeftChange(),
13291                  this.onSelectionChange(),
13292                  this.onChangeFrontMarker(),
13293                  this.onChangeBackMarker(),
13294                  this.onChangeBreakpoint(),
13295                  this.onChangeAnnotation(),
13296                  this.session.getUseWrapMode() && this.renderer.adjustWrapLimit(),
13297                  this.renderer.updateFull())
13298                : ((this.selection = null), this.renderer.setSession(e)),
13299              this._signal('changeSession', { session: e, oldSession: t }),
13300              (this.curOp = null),
13301              t && t._signal('changeEditor', { oldEditor: this }),
13302              e && e._signal('changeEditor', { editor: this }),
13303              e && e.bgTokenizer && e.bgTokenizer.scheduleStart()
13304          }),
13305          (this.getSession = function() {
13306            return this.session
13307          }),
13308          (this.setValue = function(e, t) {
13309            return (
13310              this.session.doc.setValue(e),
13311              t ? (t == 1 ? this.navigateFileEnd() : t == -1 && this.navigateFileStart()) : this.selectAll(),
13312              e
13313            )
13314          }),
13315          (this.getValue = function() {
13316            return this.session.getValue()
13317          }),
13318          (this.getSelection = function() {
13319            return this.selection
13320          }),
13321          (this.resize = function(e) {
13322            this.renderer.onResize(e)
13323          }),
13324          (this.setTheme = function(e, t) {
13325            this.renderer.setTheme(e, t)
13326          }),
13327          (this.getTheme = function() {
13328            return this.renderer.getTheme()
13329          }),
13330          (this.setStyle = function(e) {
13331            this.renderer.setStyle(e)
13332          }),
13333          (this.unsetStyle = function(e) {
13334            this.renderer.unsetStyle(e)
13335          }),
13336          (this.getFontSize = function() {
13337            return this.getOption('fontSize') || i.computedStyle(this.container).fontSize
13338          }),
13339          (this.setFontSize = function(e) {
13340            this.setOption('fontSize', e)
13341          }),
13342          (this.$highlightBrackets = function() {
13343            this.session.$bracketHighlight &&
13344              (this.session.removeMarker(this.session.$bracketHighlight), (this.session.$bracketHighlight = null))
13345            if (this.$highlightPending) return
13346            var e = this
13347            ;(this.$highlightPending = !0),
13348              setTimeout(function() {
13349                e.$highlightPending = !1
13350                var t = e.session
13351                if (!t || !t.bgTokenizer) return
13352                var n = t.findMatchingBracket(e.getCursorPosition())
13353                if (n) var r = new p(n.row, n.column, n.row, n.column + 1)
13354                else if (t.$mode.getMatching) var r = t.$mode.getMatching(e.session)
13355                r && (t.$bracketHighlight = t.addMarker(r, 'ace_bracket', 'text'))
13356              }, 50)
13357          }),
13358          (this.$highlightTags = function() {
13359            if (this.$highlightTagPending) return
13360            var e = this
13361            ;(this.$highlightTagPending = !0),
13362              setTimeout(function() {
13363                e.$highlightTagPending = !1
13364                var t = e.session
13365                if (!t || !t.bgTokenizer) return
13366                var n = e.getCursorPosition(),
13367                  r = new y(e.session, n.row, n.column),
13368                  i = r.getCurrentToken()
13369                if (!i || !/\b(?:tag-open|tag-name)/.test(i.type)) {
13370                  t.removeMarker(t.$tagHighlight), (t.$tagHighlight = null)
13371                  return
13372                }
13373                if (i.type.indexOf('tag-open') != -1) {
13374                  i = r.stepForward()
13375                  if (!i) return
13376                }
13377                var s = i.value,
13378                  o = 0,
13379                  u = r.stepBackward()
13380                if (u.value == '<') {
13381                  do
13382                    (u = i),
13383                      (i = r.stepForward()),
13384                      i &&
13385                        i.value === s &&
13386                        i.type.indexOf('tag-name') !== -1 &&
13387                        (u.value === '<' ? o++ : u.value === '</' && o--)
13388                  while (i && o >= 0)
13389                } else {
13390                  do
13391                    (i = u),
13392                      (u = r.stepBackward()),
13393                      i &&
13394                        i.value === s &&
13395                        i.type.indexOf('tag-name') !== -1 &&
13396                        (u.value === '<' ? o++ : u.value === '</' && o--)
13397                  while (u && o <= 0)
13398                  r.stepForward()
13399                }
13400                if (!i) {
13401                  t.removeMarker(t.$tagHighlight), (t.$tagHighlight = null)
13402                  return
13403                }
13404                var a = r.getCurrentTokenRow(),
13405                  f = r.getCurrentTokenColumn(),
13406                  l = new p(a, f, a, f + i.value.length),
13407                  c = t.$backMarkers[t.$tagHighlight]
13408                t.$tagHighlight &&
13409                  c != undefined &&
13410                  l.compareRange(c.range) !== 0 &&
13411                  (t.removeMarker(t.$tagHighlight), (t.$tagHighlight = null)),
13412                  t.$tagHighlight || (t.$tagHighlight = t.addMarker(l, 'ace_bracket', 'text'))
13413              }, 50)
13414          }),
13415          (this.focus = function() {
13416            var e = this
13417            setTimeout(function() {
13418              e.isFocused() || e.textInput.focus()
13419            }),
13420              this.textInput.focus()
13421          }),
13422          (this.isFocused = function() {
13423            return this.textInput.isFocused()
13424          }),
13425          (this.blur = function() {
13426            this.textInput.blur()
13427          }),
13428          (this.onFocus = function(e) {
13429            if (this.$isFocused) return
13430            ;(this.$isFocused = !0), this.renderer.showCursor(), this.renderer.visualizeFocus(), this._emit('focus', e)
13431          }),
13432          (this.onBlur = function(e) {
13433            if (!this.$isFocused) return
13434            ;(this.$isFocused = !1), this.renderer.hideCursor(), this.renderer.visualizeBlur(), this._emit('blur', e)
13435          }),
13436          (this.$cursorChange = function() {
13437            this.renderer.updateCursor()
13438          }),
13439          (this.onDocumentChange = function(e) {
13440            var t = this.session.$useWrapMode,
13441              n = e.start.row == e.end.row ? e.end.row : Infinity
13442            this.renderer.updateLines(e.start.row, n, t),
13443              this._signal('change', e),
13444              this.$cursorChange(),
13445              this.$updateHighlightActiveLine()
13446          }),
13447          (this.onTokenizerUpdate = function(e) {
13448            var t = e.data
13449            this.renderer.updateLines(t.first, t.last)
13450          }),
13451          (this.onScrollTopChange = function() {
13452            this.renderer.scrollToY(this.session.getScrollTop())
13453          }),
13454          (this.onScrollLeftChange = function() {
13455            this.renderer.scrollToX(this.session.getScrollLeft())
13456          }),
13457          (this.onCursorChange = function() {
13458            this.$cursorChange(),
13459              this.$highlightBrackets(),
13460              this.$highlightTags(),
13461              this.$updateHighlightActiveLine(),
13462              this._signal('changeSelection')
13463          }),
13464          (this.$updateHighlightActiveLine = function() {
13465            var e = this.getSession(),
13466              t
13467            if (this.$highlightActiveLine) {
13468              if (this.$selectionStyle != 'line' || !this.selection.isMultiLine()) t = this.getCursorPosition()
13469              this.renderer.theme &&
13470                this.renderer.theme.$selectionColorConflict &&
13471                !this.selection.isEmpty() &&
13472                (t = !1),
13473                this.renderer.$maxLines && this.session.getLength() === 1 && !(this.renderer.$minLines > 1) && (t = !1)
13474            }
13475            if (e.$highlightLineMarker && !t) e.removeMarker(e.$highlightLineMarker.id), (e.$highlightLineMarker = null)
13476            else if (!e.$highlightLineMarker && t) {
13477              var n = new p(t.row, t.column, t.row, Infinity)
13478              ;(n.id = e.addMarker(n, 'ace_active-line', 'screenLine')), (e.$highlightLineMarker = n)
13479            } else
13480              t &&
13481                ((e.$highlightLineMarker.start.row = t.row),
13482                (e.$highlightLineMarker.end.row = t.row),
13483                (e.$highlightLineMarker.start.column = t.column),
13484                e._signal('changeBackMarker'))
13485          }),
13486          (this.onSelectionChange = function(e) {
13487            var t = this.session
13488            t.$selectionMarker && t.removeMarker(t.$selectionMarker), (t.$selectionMarker = null)
13489            if (!this.selection.isEmpty()) {
13490              var n = this.selection.getRange(),
13491                r = this.getSelectionStyle()
13492              t.$selectionMarker = t.addMarker(n, 'ace_selection', r)
13493            } else this.$updateHighlightActiveLine()
13494            var i = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp()
13495            this.session.highlight(i), this._signal('changeSelection')
13496          }),
13497          (this.$getSelectionHighLightRegexp = function() {
13498            var e = this.session,
13499              t = this.getSelectionRange()
13500            if (t.isEmpty() || t.isMultiLine()) return
13501            var n = t.start.column,
13502              r = t.end.column,
13503              i = e.getLine(t.start.row),
13504              s = i.substring(n, r)
13505            if (s.length > 5e3 || !/[\w\d]/.test(s)) return
13506            var o = this.$search.$assembleRegExp({ wholeWord: !0, caseSensitive: !0, needle: s }),
13507              u = i.substring(n - 1, r + 1)
13508            if (!o.test(u)) return
13509            return o
13510          }),
13511          (this.onChangeFrontMarker = function() {
13512            this.renderer.updateFrontMarkers()
13513          }),
13514          (this.onChangeBackMarker = function() {
13515            this.renderer.updateBackMarkers()
13516          }),
13517          (this.onChangeBreakpoint = function() {
13518            this.renderer.updateBreakpoints()
13519          }),
13520          (this.onChangeAnnotation = function() {
13521            this.renderer.setAnnotations(this.session.getAnnotations())
13522          }),
13523          (this.onChangeMode = function(e) {
13524            this.renderer.updateText(), this._emit('changeMode', e)
13525          }),
13526          (this.onChangeWrapLimit = function() {
13527            this.renderer.updateFull()
13528          }),
13529          (this.onChangeWrapMode = function() {
13530            this.renderer.onResize(!0)
13531          }),
13532          (this.onChangeFold = function() {
13533            this.$updateHighlightActiveLine(), this.renderer.updateFull()
13534          }),
13535          (this.getSelectedText = function() {
13536            return this.session.getTextRange(this.getSelectionRange())
13537          }),
13538          (this.getCopyText = function() {
13539            var e = this.getSelectedText(),
13540              t = this.session.doc.getNewLineCharacter(),
13541              n = !1
13542            if (!e && this.$copyWithEmptySelection) {
13543              n = !0
13544              var r = this.selection.getAllRanges()
13545              for (var i = 0; i < r.length; i++) {
13546                var s = r[i]
13547                if (i && r[i - 1].start.row == s.start.row) continue
13548                e += this.session.getLine(s.start.row) + t
13549              }
13550            }
13551            var o = { text: e }
13552            return this._signal('copy', o), (b.lineMode = n ? o.text : ''), o.text
13553          }),
13554          (this.onCopy = function() {
13555            this.commands.exec('copy', this)
13556          }),
13557          (this.onCut = function() {
13558            this.commands.exec('cut', this)
13559          }),
13560          (this.onPaste = function(e, t) {
13561            var n = { text: e, event: t }
13562            this.commands.exec('paste', this, n)
13563          }),
13564          (this.$handlePaste = function(e) {
13565            typeof e == 'string' && (e = { text: e }), this._signal('paste', e)
13566            var t = e.text,
13567              n = t == b.lineMode,
13568              r = this.session
13569            if (!this.inMultiSelectMode || this.inVirtualSelectionMode)
13570              n ? r.insert({ row: this.selection.lead.row, column: 0 }, t) : this.insert(t)
13571            else if (n)
13572              this.selection.rangeList.ranges.forEach(function(e) {
13573                r.insert({ row: e.start.row, column: 0 }, t)
13574              })
13575            else {
13576              var i = t.split(/\r\n|\r|\n/),
13577                s = this.selection.rangeList.ranges
13578              if (i.length > s.length || i.length < 2 || !i[1]) return this.commands.exec('insertstring', this, t)
13579              for (var o = s.length; o--; ) {
13580                var u = s[o]
13581                u.isEmpty() || r.remove(u), r.insert(u.start, i[o])
13582              }
13583            }
13584          }),
13585          (this.execCommand = function(e, t) {
13586            return this.commands.exec(e, this, t)
13587          }),
13588          (this.insert = function(e, t) {
13589            var n = this.session,
13590              r = n.getMode(),
13591              i = this.getCursorPosition()
13592            if (this.getBehavioursEnabled() && !t) {
13593              var s = r.transformAction(n.getState(i.row), 'insertion', this, n, e)
13594              s &&
13595                (e !== s.text &&
13596                  (this.inVirtualSelectionMode || ((this.session.mergeUndoDeltas = !1), (this.mergeNextCommand = !1))),
13597                (e = s.text))
13598            }
13599            e == '	' && (e = this.session.getTabString())
13600            if (!this.selection.isEmpty()) {
13601              var o = this.getSelectionRange()
13602              ;(i = this.session.remove(o)), this.clearSelection()
13603            } else if (this.session.getOverwrite() && e.indexOf('\n') == -1) {
13604              var o = new p.fromPoints(i, i)
13605              ;(o.end.column += e.length), this.session.remove(o)
13606            }
13607            if (e == '\n' || e == '\r\n') {
13608              var u = n.getLine(i.row)
13609              if (i.column > u.search(/\S|$/)) {
13610                var a = u.substr(i.column).search(/\S|$/)
13611                n.doc.removeInLine(i.row, i.column, i.column + a)
13612              }
13613            }
13614            this.clearSelection()
13615            var f = i.column,
13616              l = n.getState(i.row),
13617              u = n.getLine(i.row),
13618              c = r.checkOutdent(l, u, e),
13619              h = n.insert(i, e)
13620            s &&
13621              s.selection &&
13622              (s.selection.length == 2
13623                ? this.selection.setSelectionRange(new p(i.row, f + s.selection[0], i.row, f + s.selection[1]))
13624                : this.selection.setSelectionRange(
13625                    new p(i.row + s.selection[0], s.selection[1], i.row + s.selection[2], s.selection[3])
13626                  ))
13627            if (n.getDocument().isNewLine(e)) {
13628              var d = r.getNextLineIndent(l, u.slice(0, i.column), n.getTabString())
13629              n.insert({ row: i.row + 1, column: 0 }, d)
13630            }
13631            c && r.autoOutdent(l, n, i.row)
13632          }),
13633          (this.onTextInput = function(e) {
13634            this.keyBinding.onTextInput(e)
13635          }),
13636          (this.onCommandKey = function(e, t, n) {
13637            this.keyBinding.onCommandKey(e, t, n)
13638          }),
13639          (this.setOverwrite = function(e) {
13640            this.session.setOverwrite(e)
13641          }),
13642          (this.getOverwrite = function() {
13643            return this.session.getOverwrite()
13644          }),
13645          (this.toggleOverwrite = function() {
13646            this.session.toggleOverwrite()
13647          }),
13648          (this.setScrollSpeed = function(e) {
13649            this.setOption('scrollSpeed', e)
13650          }),
13651          (this.getScrollSpeed = function() {
13652            return this.getOption('scrollSpeed')
13653          }),
13654          (this.setDragDelay = function(e) {
13655            this.setOption('dragDelay', e)
13656          }),
13657          (this.getDragDelay = function() {
13658            return this.getOption('dragDelay')
13659          }),
13660          (this.setSelectionStyle = function(e) {
13661            this.setOption('selectionStyle', e)
13662          }),
13663          (this.getSelectionStyle = function() {
13664            return this.getOption('selectionStyle')
13665          }),
13666          (this.setHighlightActiveLine = function(e) {
13667            this.setOption('highlightActiveLine', e)
13668          }),
13669          (this.getHighlightActiveLine = function() {
13670            return this.getOption('highlightActiveLine')
13671          }),
13672          (this.setHighlightGutterLine = function(e) {
13673            this.setOption('highlightGutterLine', e)
13674          }),
13675          (this.getHighlightGutterLine = function() {
13676            return this.getOption('highlightGutterLine')
13677          }),
13678          (this.setHighlightSelectedWord = function(e) {
13679            this.setOption('highlightSelectedWord', e)
13680          }),
13681          (this.getHighlightSelectedWord = function() {
13682            return this.$highlightSelectedWord
13683          }),
13684          (this.setAnimatedScroll = function(e) {
13685            this.renderer.setAnimatedScroll(e)
13686          }),
13687          (this.getAnimatedScroll = function() {
13688            return this.renderer.getAnimatedScroll()
13689          }),
13690          (this.setShowInvisibles = function(e) {
13691            this.renderer.setShowInvisibles(e)
13692          }),
13693          (this.getShowInvisibles = function() {
13694            return this.renderer.getShowInvisibles()
13695          }),
13696          (this.setDisplayIndentGuides = function(e) {
13697            this.renderer.setDisplayIndentGuides(e)
13698          }),
13699          (this.getDisplayIndentGuides = function() {
13700            return this.renderer.getDisplayIndentGuides()
13701          }),
13702          (this.setShowPrintMargin = function(e) {
13703            this.renderer.setShowPrintMargin(e)
13704          }),
13705          (this.getShowPrintMargin = function() {
13706            return this.renderer.getShowPrintMargin()
13707          }),
13708          (this.setPrintMarginColumn = function(e) {
13709            this.renderer.setPrintMarginColumn(e)
13710          }),
13711          (this.getPrintMarginColumn = function() {
13712            return this.renderer.getPrintMarginColumn()
13713          }),
13714          (this.setReadOnly = function(e) {
13715            this.setOption('readOnly', e)
13716          }),
13717          (this.getReadOnly = function() {
13718            return this.getOption('readOnly')
13719          }),
13720          (this.setBehavioursEnabled = function(e) {
13721            this.setOption('behavioursEnabled', e)
13722          }),
13723          (this.getBehavioursEnabled = function() {
13724            return this.getOption('behavioursEnabled')
13725          }),
13726          (this.setWrapBehavioursEnabled = function(e) {
13727            this.setOption('wrapBehavioursEnabled', e)
13728          }),
13729          (this.getWrapBehavioursEnabled = function() {
13730            return this.getOption('wrapBehavioursEnabled')
13731          }),
13732          (this.setShowFoldWidgets = function(e) {
13733            this.setOption('showFoldWidgets', e)
13734          }),
13735          (this.getShowFoldWidgets = function() {
13736            return this.getOption('showFoldWidgets')
13737          }),
13738          (this.setFadeFoldWidgets = function(e) {
13739            this.setOption('fadeFoldWidgets', e)
13740          }),
13741          (this.getFadeFoldWidgets = function() {
13742            return this.getOption('fadeFoldWidgets')
13743          }),
13744          (this.remove = function(e) {
13745            this.selection.isEmpty() && (e == 'left' ? this.selection.selectLeft() : this.selection.selectRight())
13746            var t = this.getSelectionRange()
13747            if (this.getBehavioursEnabled()) {
13748              var n = this.session,
13749                r = n.getState(t.start.row),
13750                i = n.getMode().transformAction(r, 'deletion', this, n, t)
13751              if (t.end.column === 0) {
13752                var s = n.getTextRange(t)
13753                if (s[s.length - 1] == '\n') {
13754                  var o = n.getLine(t.end.row)
13755                  ;/^\s+$/.test(o) && (t.end.column = o.length)
13756                }
13757              }
13758              i && (t = i)
13759            }
13760            this.session.remove(t), this.clearSelection()
13761          }),
13762          (this.removeWordRight = function() {
13763            this.selection.isEmpty() && this.selection.selectWordRight(),
13764              this.session.remove(this.getSelectionRange()),
13765              this.clearSelection()
13766          }),
13767          (this.removeWordLeft = function() {
13768            this.selection.isEmpty() && this.selection.selectWordLeft(),
13769              this.session.remove(this.getSelectionRange()),
13770              this.clearSelection()
13771          }),
13772          (this.removeToLineStart = function() {
13773            this.selection.isEmpty() && this.selection.selectLineStart(),
13774              this.session.remove(this.getSelectionRange()),
13775              this.clearSelection()
13776          }),
13777          (this.removeToLineEnd = function() {
13778            this.selection.isEmpty() && this.selection.selectLineEnd()
13779            var e = this.getSelectionRange()
13780            e.start.column == e.end.column && e.start.row == e.end.row && ((e.end.column = 0), e.end.row++),
13781              this.session.remove(e),
13782              this.clearSelection()
13783          }),
13784          (this.splitLine = function() {
13785            this.selection.isEmpty() || (this.session.remove(this.getSelectionRange()), this.clearSelection())
13786            var e = this.getCursorPosition()
13787            this.insert('\n'), this.moveCursorToPosition(e)
13788          }),
13789          (this.transposeLetters = function() {
13790            if (!this.selection.isEmpty()) return
13791            var e = this.getCursorPosition(),
13792              t = e.column
13793            if (t === 0) return
13794            var n = this.session.getLine(e.row),
13795              r,
13796              i
13797            t < n.length
13798              ? ((r = n.charAt(t) + n.charAt(t - 1)), (i = new p(e.row, t - 1, e.row, t + 1)))
13799              : ((r = n.charAt(t - 1) + n.charAt(t - 2)), (i = new p(e.row, t - 2, e.row, t))),
13800              this.session.replace(i, r),
13801              this.session.selection.moveToPosition(i.end)
13802          }),
13803          (this.toLowerCase = function() {
13804            var e = this.getSelectionRange()
13805            this.selection.isEmpty() && this.selection.selectWord()
13806            var t = this.getSelectionRange(),
13807              n = this.session.getTextRange(t)
13808            this.session.replace(t, n.toLowerCase()), this.selection.setSelectionRange(e)
13809          }),
13810          (this.toUpperCase = function() {
13811            var e = this.getSelectionRange()
13812            this.selection.isEmpty() && this.selection.selectWord()
13813            var t = this.getSelectionRange(),
13814              n = this.session.getTextRange(t)
13815            this.session.replace(t, n.toUpperCase()), this.selection.setSelectionRange(e)
13816          }),
13817          (this.indent = function() {
13818            var e = this.session,
13819              t = this.getSelectionRange()
13820            if (t.start.row < t.end.row) {
13821              var n = this.$getSelectedRows()
13822              e.indentRows(n.first, n.last, '	')
13823              return
13824            }
13825            if (t.start.column < t.end.column) {
13826              var r = e.getTextRange(t)
13827              if (!/^\s+$/.test(r)) {
13828                var n = this.$getSelectedRows()
13829                e.indentRows(n.first, n.last, '	')
13830                return
13831              }
13832            }
13833            var i = e.getLine(t.start.row),
13834              o = t.start,
13835              u = e.getTabSize(),
13836              a = e.documentToScreenColumn(o.row, o.column)
13837            if (this.session.getUseSoftTabs())
13838              var f = u - (a % u),
13839                l = s.stringRepeat(' ', f)
13840            else {
13841              var f = a % u
13842              while (i[t.start.column - 1] == ' ' && f) t.start.column--, f--
13843              this.selection.setSelectionRange(t), (l = '	')
13844            }
13845            return this.insert(l)
13846          }),
13847          (this.blockIndent = function() {
13848            var e = this.$getSelectedRows()
13849            this.session.indentRows(e.first, e.last, '	')
13850          }),
13851          (this.blockOutdent = function() {
13852            var e = this.session.getSelection()
13853            this.session.outdentRows(e.getRange())
13854          }),
13855          (this.sortLines = function() {
13856            var e = this.$getSelectedRows(),
13857              t = this.session,
13858              n = []
13859            for (var r = e.first; r <= e.last; r++) n.push(t.getLine(r))
13860            n.sort(function(e, t) {
13861              return e.toLowerCase() < t.toLowerCase() ? -1 : e.toLowerCase() > t.toLowerCase() ? 1 : 0
13862            })
13863            var i = new p(0, 0, 0, 0)
13864            for (var r = e.first; r <= e.last; r++) {
13865              var s = t.getLine(r)
13866              ;
13866(i.start.row = r), (i.end.row = r), (i.end.column = s.length), t.replace(i, n[r - e.first])
13867            }
13868          }),
13869          (this.toggleCommentLines = function() {
13870            var e = this.session.getState(this.getCursorPosition().row),
13871              t = this.$getSelectedRows()
13872            this.session.getMode().toggleCommentLines(e, this.session, t.first, t.last)
13873          }),
13874          (this.toggleBlockComment = function() {
13875            var e = this.getCursorPosition(),
13876              t = this.session.getState(e.row),
13877              n = this.getSelectionRange()
13878            this.session.getMode().toggleBlockComment(t, this.session, n, e)
13879          }),
13880          (this.getNumberAt = function(e, t) {
13881            var n = /[\-]?[0-9]+(?:\.[0-9]+)?/g
13882            n.lastIndex = 0
13883            var r = this.session.getLine(e)
13884            while (n.lastIndex < t) {
13885              var i = n.exec(r)
13886              if (i.index <= t && i.index + i[0].length >= t) {
13887                var s = { value: i[0], start: i.index, end: i.index + i[0].length }
13888                return s
13889              }
13890            }
13891            return null
13892          }),
13893          (this.modifyNumber = function(e) {
13894            var t = this.selection.getCursor().row,
13895              n = this.selection.getCursor().column,
13896              r = new p(t, n - 1, t, n),
13897              i = this.session.getTextRange(r)
13898            if (!isNaN(parseFloat(i)) && isFinite(i)) {
13899              var s = this.getNumberAt(t, n)
13900              if (s) {
13901                var o = s.value.indexOf('.') >= 0 ? s.start + s.value.indexOf('.') + 1 : s.end,
13902                  u = s.start + s.value.length - o,
13903                  a = parseFloat(s.value)
13904                ;(a *= Math.pow(10, u)),
13905                  o !== s.end && n < o ? (e *= Math.pow(10, s.end - n - 1)) : (e *= Math.pow(10, s.end - n)),
13906                  (a += e),
13907                  (a /= Math.pow(10, u))
13908                var f = a.toFixed(u),
13909                  l = new p(t, s.start, t, s.end)
13910                this.session.replace(l, f), this.moveCursorTo(t, Math.max(s.start + 1, n + f.length - s.value.length))
13911              }
13912            }
13913          }),
13914          (this.removeLines = function() {
13915            var e = this.$getSelectedRows()
13916            this.session.removeFullLines(e.first, e.last), this.clearSelection()
13917          }),
13918          (this.duplicateSelection = function() {
13919            var e = this.selection,
13920              t = this.session,
13921              n = e.getRange(),
13922              r = e.isBackwards()
13923            if (n.isEmpty()) {
13924              var i = n.start.row
13925              t.duplicateLines(i, i)
13926            } else {
13927              var s = r ? n.start : n.end,
13928                o = t.insert(s, t.getTextRange(n), !1)
13929              ;(n.start = s), (n.end = o), e.setSelectionRange(n, r)
13930            }
13931          }),
13932          (this.moveLinesDown = function() {
13933            this.$moveLines(1, !1)
13934          }),
13935          (this.moveLinesUp = function() {
13936            this.$moveLines(-1, !1)
13937          }),
13938          (this.moveText = function(e, t, n) {
13939            return this.session.moveText(e, t, n)
13940          }),
13941          (this.copyLinesUp = function() {
13942            this.$moveLines(-1, !0)
13943          }),
13944          (this.copyLinesDown = function() {
13945            this.$moveLines(1, !0)
13946          }),
13947          (this.$moveLines = function(e, t) {
13948            var n,
13949              r,
13950              i = this.selection
13951            if (!i.inMultiSelectMode || this.inVirtualSelectionMode) {
13952              var s = i.toOrientedRange()
13953              ;(n = this.$getSelectedRows(s)),
13954                (r = this.session.$moveLines(n.first, n.last, t ? 0 : e)),
13955                t && e == -1 && (r = 0),
13956                s.moveBy(r, 0),
13957                i.fromOrientedRange(s)
13958            } else {
13959              var o = i.rangeList.ranges
13960              i.rangeList.detach(this.session), (this.inVirtualSelectionMode = !0)
13961              var u = 0,
13962                a = 0,
13963                f = o.length
13964              for (var l = 0; l < f; l++) {
13965                var c = l
13966                o[l].moveBy(u, 0), (n = this.$getSelectedRows(o[l]))
13967                var h = n.first,
13968                  p = n.last
13969                while (++l < f) {
13970                  a && o[l].moveBy(a, 0)
13971                  var d = this.$getSelectedRows(o[l])
13972                  if (t && d.first != p) break
13973                  if (!t && d.first > p + 1) break
13974                  p = d.last
13975                }
13976                l--, (u = this.session.$moveLines(h, p, t ? 0 : e)), t && e == -1 && (c = l + 1)
13977                while (c <= l) o[c].moveBy(u, 0), c++
13978                t || (u = 0), (a += u)
13979              }
13980              i.fromOrientedRange(i.ranges[0]), i.rangeList.attach(this.session), (this.inVirtualSelectionMode = !1)
13981            }
13982          }),
13983          (this.$getSelectedRows = function(e) {
13984            return (
13985              (e = (e || this.getSelectionRange()).collapseRows()),
13986              { first: this.session.getRowFoldStart(e.start.row), last: this.session.getRowFoldEnd(e.end.row) }
13987            )
13988          }),
13989          (this.onCompositionStart = function(e) {
13990            this.renderer.showComposition(this.getCursorPosition())
13991          }),
13992          (this.onCompositionUpdate = function(e) {
13993            this.renderer.setCompositionText(e)
13994          }),
13995          (this.onCompositionEnd = function() {
13996            this.renderer.hideComposition()
13997          }),
13998          (this.getFirstVisibleRow = function() {
13999            return this.renderer.getFirstVisibleRow()
14000          }),
14001          (this.getLastVisibleRow = function() {
14002            return this.renderer.getLastVisibleRow()
14003          }),
14004          (this.isRowVisible = function(e) {
14005            return e >= this.getFirstVisibleRow() && e <= this.getLastVisibleRow()
14006          }),
14007          (this.isRowFullyVisible = function(e) {
14008            return e >= this.renderer.getFirstFullyVisibleRow() && e <= this.renderer.getLastFullyVisibleRow()
14009          }),
14010          (this.$getVisibleRowCount = function() {
14011            return this.renderer.getScrollBottomRow() - this.renderer.getScrollTopRow() + 1
14012          }),
14013          (this.$moveByPage = function(e, t) {
14014            var n = this.renderer,
14015              r = this.renderer.layerConfig,
14016              i = e * Math.floor(r.height / r.lineHeight)
14017            t === !0
14018              ? this.selection.$moveSelection(function() {
14019                  this.moveCursorBy(i, 0)
14020                })
14021              : t === !1 && (this.selection.moveCursorBy(i, 0), this.selection.clearSelection())
14022            var s = n.scrollTop
14023            n.scrollBy(0, i * r.lineHeight), t != null && n.scrollCursorIntoView(null, 0.5), n.animateScrolling(s)
14024          }),
14025          (this.selectPageDown = function() {
14026            this.$moveByPage(1, !0)
14027          }),
14028          (this.selectPageUp = function() {
14029            this.$moveByPage(-1, !0)
14030          }),
14031          (this.gotoPageDown = function() {
14032            this.$moveByPage(1, !1)
14033          }),
14034          (this.gotoPageUp = function() {
14035            this.$moveByPage(-1, !1)
14036          }),
14037          (this.scrollPageDown = function() {
14038            this.$moveByPage(1)
14039          }),
14040          (this.scrollPageUp = function() {
14041            this.$moveByPage(-1)
14042          }),
14043          (this.scrollToRow = function(e) {
14044            this.renderer.scrollToRow(e)
14045          }),
14046          (this.scrollToLine = function(e, t, n, r) {
14047            this.renderer.scrollToLine(e, t, n, r)
14048          }),
14049          (this.centerSelection = function() {
14050            var e = this.getSelectionRange(),
14051              t = {
14052                row: Math.floor(e.start.row + (e.end.row - e.start.row) / 2),
14053                column: Math.floor(e.start.column + (e.end.column - e.start.column) / 2)
14054              }
14055            this.renderer.alignCursor(t, 0.5)
14056          }),
14057          (this.getCursorPosition = function() {
14058            return this.selection.getCursor()
14059          }),
14060          (this.getCursorPositionScreen = function() {
14061            return this.session.documentToScreenPosition(this.getCursorPosition())
14062          }),
14063          (this.getSelectionRange = function() {
14064            return this.selection.getRange()
14065          }),
14066          (this.selectAll = function() {
14067            this.selection.selectAll()
14068          }),
14069          (this.clearSelection = function() {
14070            this.selection.clearSelection()
14071          }),
14072          (this.moveCursorTo = function(e, t) {
14073            this.selection.moveCursorTo(e, t)
14074          }),
14075          (this.moveCursorToPosition = function(e) {
14076            this.selection.moveCursorToPosition(e)
14077          }),
14078          (this.jumpToMatching = function(e, t) {
14079            var n = this.getCursorPosition(),
14080              r = new y(this.session, n.row, n.column),
14081              i = r.getCurrentToken(),
14082              s = i || r.stepForward()
14083            if (!s) return
14084            var o,
14085              u = !1,
14086              a = {},
14087              f = n.column - s.start,
14088              l,
14089              c = { ')': '(', '(': '(', ']': '[', '[': '[', '{': '{', '}': '{' }
14090            do {
14091              if (s.value.match(/[{}()\[\]]/g))
14092                for (; f < s.value.length && !u; f++) {
14093                  if (!c[s.value[f]]) continue
14094                  ;(l = c[s.value[f]] + '.' + s.type.replace('rparen', 'lparen')), isNaN(a[l]) && (a[l] = 0)
14095                  switch (s.value[f]) {
14096                    case '(':
14097                    case '[':
14098                    case '{':
14099                      a[l]++
14100                      break
14101                    case ')':
14102                    case ']':
14103                    case '}':
14104                      a[l]--, a[l] === -1 && ((o = 'bracket'), (u = !0))
14105                  }
14106                }
14107              else
14108                s.type.indexOf('tag-name') !== -1 &&
14109                  (isNaN(a[s.value]) && (a[s.value] = 0),
14110                  i.value === '<' ? a[s.value]++ : i.value === '</' && a[s.value]--,
14111                  a[s.value] === -1 && ((o = 'tag'), (u = !0)))
14112              u || ((i = s), (s = r.stepForward()), (f = 0))
14113            } while (s && !u)
14114            if (!o) return
14115            var h, d
14116            if (o === 'bracket') {
14117              h = this.session.getBracketRange(n)
14118              if (!h) {
14119                ;(h = new p(
14120                  r.getCurrentTokenRow(),
14121                  r.getCurrentTokenColumn() + f - 1,
14122                  r.getCurrentTokenRow(),
14123                  r.getCurrentTokenColumn() + f - 1
14124                )),
14125                  (d = h.start)
14126                if (t || (d.row === n.row && Math.abs(d.column - n.column) < 2)) h = this.session.getBracketRange(d)
14127              }
14128            } else if (o === 'tag') {
14129              if (!s || s.type.indexOf('tag-name') === -1) return
14130              var v = s.value
14131              h = new p(
14132                r.getCurrentTokenRow(),
14133                r.getCurrentTokenColumn() - 2,
14134                r.getCurrentTokenRow(),
14135                r.getCurrentTokenColumn() - 2
14136              )
14137              if (h.compare(n.row, n.column) === 0) {
14138                u = !1
14139                do
14140                  (s = i),
14141                    (i = r.stepBackward()),
14142                    i &&
14143                      (i.type.indexOf('tag-close') !== -1 &&
14144                        h.setEnd(r.getCurrentTokenRow(), r.getCurrentTokenColumn() + 1),
14145                      s.value === v &&
14146                        s.type.indexOf('tag-name') !== -1 &&
14147                        (i.value === '<' ? a[v]++ : i.value === '</' && a[v]--, a[v] === 0 && (u = !0)))
14148                while (i && !u)
14149              }
14150              s &&
14151                s.type.indexOf('tag-name') &&
14152                ((d = h.start), d.row == n.row && Math.abs(d.column - n.column) < 2 && (d = h.end))
14153            }
14154            ;(d = (h && h.cursor) || d),
14155              d &&
14156                (e
14157                  ? h && t
14158                    ? this.selection.setRange(h)
14159                    : h && h.isEqual(this.getSelectionRange())
14160                    ? this.clearSelection()
14161                    : this.selection.selectTo(d.row, d.column)
14162                  : this.selection.moveTo(d.row, d.column))
14163          }),
14164          (this.gotoLine = function(e, t, n) {
14165            this.selection.clearSelection(),
14166              this.session.unfold({ row: e - 1, column: t || 0 }),
14167              this.exitMultiSelectMode && this.exitMultiSelectMode(),
14168              this.moveCursorTo(e - 1, t || 0),
14169              this.isRowFullyVisible(e - 1) || this.scrollToLine(e - 1, !0, n)
14170          }),
14171          (this.navigateTo = function(e, t) {
14172            this.selection.moveTo(e, t)
14173          }),
14174          (this.navigateUp = function(e) {
14175            if (this.selection.isMultiLine() && !this.selection.isBackwards()) {
14176              var t = this.selection.anchor.getPosition()
14177              return this.moveCursorToPosition(t)
14178            }
14179            this.selection.clearSelection(), this.selection.moveCursorBy(-e || -1, 0)
14180          }),
14181          (this.navigateDown = function(e) {
14182            if (this.selection.isMultiLine() && this.selection.isBackwards()) {
14183              var t = this.selection.anchor.getPosition()
14184              return this.moveCursorToPosition(t)
14185            }
14186            this.selection.clearSelection(), this.selection.moveCursorBy(e || 1, 0)
14187          }),
14188          (this.navigateLeft = function(e) {
14189            if (!this.selection.isEmpty()) {
14190              var t = this.getSelectionRange().start
14191              this.moveCursorToPosition(t)
14192            } else {
14193              e = e || 1
14194              while (e--) this.selection.moveCursorLeft()
14195            }
14196            this.clearSelection()
14197          }),
14198          (this.navigateRight = function(e) {
14199            if (!this.selection.isEmpty()) {
14200              var t = this.getSelectionRange().end
14201              this.moveCursorToPosition(t)
14202            } else {
14203              e = e || 1
14204              while (e--) this.selection.moveCursorRight()
14205            }
14206            this.clearSelection()
14207          }),
14208          (this.navigateLineStart = function() {
14209            this.selection.moveCursorLineStart(), this.clearSelection()
14210          }),
14211          (this.navigateLineEnd = function() {
14212            this.selection.moveCursorLineEnd(), this.clearSelection()
14213          }),
14214          (this.navigateFileEnd = function() {
14215            this.selection.moveCursorFileEnd(), this.clearSelection()
14216          }),
14217          (this.navigateFileStart = function() {
14218            this.selection.moveCursorFileStart(), this.clearSelection()
14219          }),
14220          (this.navigateWordRight = function() {
14221            this.selection.moveCursorWordRight(), this.clearSelection()
14222          }),
14223          (this.navigateWordLeft = function() {
14224            this.selection.moveCursorWordLeft(), this.clearSelection()
14225          }),
14226          (this.replace = function(e, t) {
14227            t && this.$search.set(t)
14228            var n = this.$search.find(this.session),
14229              r = 0
14230            return n
14231              ? (this.$tryReplace(n, e) && (r = 1),
14232                this.selection.setSelectionRange(n),
14233                this.renderer.scrollSelectionIntoView(n.start, n.end),
14234                r)
14235              : r
14236          }),
14237          (this.replaceAll = function(e, t) {
14238            t && this.$search.set(t)
14239            var n = this.$search.findAll(this.session),
14240              r = 0
14241            if (!n.length) return r
14242            var i = this.getSelectionRange()
14243            this.selection.moveTo(0, 0)
14244            for (var s = n.length - 1; s >= 0; --s) this.$tryReplace(n[s], e) && r++
14245            return this.selection.setSelectionRange(i), r
14246          }),
14247          (this.$tryReplace = function(e, t) {
14248            var n = this.session.getTextRange(e)
14249            return (t = this.$search.replace(n, t)), t !== null ? ((e.end = this.session.replace(e, t)), e) : null
14250          }),
14251          (this.getLastSearchOptions = function() {
14252            return this.$search.getOptions()
14253          }),
14254          (this.find = function(e, t, n) {
14255            t || (t = {}),
14256              typeof e == 'string' || e instanceof RegExp ? (t.needle = e) : typeof e == 'object' && r.mixin(t, e)
14257            var i = this.selection.getRange()
14258            t.needle == null &&
14259              ((e = this.session.getTextRange(i) || this.$search.$options.needle),
14260              e || ((i = this.session.getWordRange(i.start.row, i.start.column)), (e = this.session.getTextRange(i))),
14261              this.$search.set({ needle: e })),
14262              this.$search.set(t),
14263              t.start || this.$search.set({ start: i })
14264            var s = this.$search.find(this.session)
14265            if (t.preventScroll) return s
14266            if (s) return this.revealRange(s, n), s
14267            t.backwards ? (i.start = i.end) : (i.end = i.start), this.selection.setRange(i)
14268          }),
14269          (this.findNext = function(e, t) {
14270            this.find({ skipCurrent: !0, backwards: !1 }, e, t)
14271          }),
14272          (this.findPrevious = function(e, t) {
14273            this.find(e, { skipCurrent: !0, backwards: !0 }, t)
14274          }),
14275          (this.revealRange = function(e, t) {
14276            this.session.unfold(e), this.selection.setSelectionRange(e)
14277            var n = this.renderer.scrollTop
14278            this.renderer.scrollSelectionIntoView(e.start, e.end, 0.5), t !== !1 && this.renderer.animateScrolling(n)
14279          }),
14280          (this.undo = function() {
14281            this.session.getUndoManager().undo(this.session), this.renderer.scrollCursorIntoView(null, 0.5)
14282          }),
14283          (this.redo = function() {
14284            this.session.getUndoManager().redo(this.session), this.renderer.scrollCursorIntoView(null, 0.5)
14285          }),
14286          (this.destroy = function() {
14287            this.renderer.destroy(), this._signal('destroy', this), this.session && this.session.destroy()
14288          }),
14289          (this.setAutoScrollEditorIntoView = function(e) {
14290            if (!e) return
14291            var t,
14292              n = this,
14293              r = !1
14294            this.$scrollAnchor || (this.$scrollAnchor = document.createElement('div'))
14295            var i = this.$scrollAnchor
14296            ;(i.style.cssText = 'position:absolute'), this.container.insertBefore(i, this.container.firstChild)
14297            var s = this.on('changeSelection', function() {
14298                r = !0
14299              }),
14300              o = this.renderer.on('beforeRender', function() {
14301                r && (t = n.renderer.container.getBoundingClientRect())
14302              }),
14303              u = this.renderer.on('afterRender', function() {
14304                if (r && t && (n.isFocused() || (n.searchBox && n.searchBox.isFocused()))) {
14305                  var e = n.renderer,
14306                    s = e.$cursorLayer.$pixelPos,
14307                    o = e.layerConfig,
14308                    u = s.top - o.offset
14309                  s.top >= 0 && u + t.top < 0
14310                    ? (r = !0)
14311                    : s.top < o.height && s.top + t.top + o.lineHeight > window.innerHeight
14312                    ? (r = !1)
14313                    : (r = null),
14314                    r != null &&
14315                      ((i.style.top = u + 'px'),
14316                      (i.style.left = s.left + 'px'),
14317                      (i.style.height = o.lineHeight + 'px'),
14318                      i.scrollIntoView(r)),
14319                    (r = t = null)
14320                }
14321              })
14322            this.setAutoScrollEditorIntoView = function(e) {
14323              if (e) return
14324              delete this.setAutoScrollEditorIntoView,
14325                this.off('changeSelection', s),
14326                this.renderer.off('afterRender', u),
14327                this.renderer.off('beforeRender', o)
14328            }
14329          }),
14330          (this.$resetCursorStyle = function() {
14331            var e = this.$cursorStyle || 'ace',
14332              t = this.renderer.$cursorLayer
14333            if (!t) return
14334            t.setSmoothBlinking(/smooth/.test(e)),
14335              (t.isBlinking = !this.$readOnly && e != 'wide'),
14336              i.setCssClass(t.element, 'ace_slim-cursors', /slim/.test(e))
14337          })
14338      }.call(w.prototype),
14339      g.defineOptions(w.prototype, 'editor', {
14340        selectionStyle: {
14341          set: function(e) {
14342            this.onSelectionChange(), this._signal('changeSelectionStyle', { data: e })
14343          },
14344          initialValue: 'line'
14345        },
14346        highlightActiveLine: {
14347          set: function() {
14348            this.$updateHighlightActiveLine()
14349          },
14350          initialValue: !0
14351        },
14352        highlightSelectedWord: {
14353          set: function(e) {
14354            this.$onSelectionChange()
14355          },
14356          initialValue: !0
14357        },
14358        readOnly: {
14359          set: function(e) {
14360            this.textInput.setReadOnly(e), this.$resetCursorStyle()
14361          },
14362          initialValue: !1
14363        },
14364        copyWithEmptySelection: {
14365          set: function(e) {
14366            this.textInput.setCopyWithEmptySelection(e)
14367          },
14368          initialValue: !1
14369        },
14370        cursorStyle: {
14371          set: function(e) {
14372            this.$resetCursorStyle()
14373          },
14374          values: ['ace', 'slim', 'smooth', 'wide'],
14375          initialValue: 'ace'
14376        },
14377        mergeUndoDeltas: { values: [!1, !0, 'always'], initialValue: !0 },
14378        behavioursEnabled: { initialValue: !0 },
14379        wrapBehavioursEnabled: { initialValue: !0 },
14380        autoScrollEditorIntoView: {
14381          set: function(e) {
14382            this.setAutoScrollEditorIntoView(e)
14383          }
14384        },
14385        keyboardHandler: {
14386          set: function(e) {
14387            this.setKeyboardHandler(e)
14388          },
14389          get: function() {
14390            return this.$keybindingId
14391          },
14392          handlesSet: !0
14393        },
14394        value: {
14395          set: function(e) {
14396            this.session.setValue(e)
14397          },
14398          get: function() {
14399            return this.getValue()
14400          },
14401          handlesSet: !0,
14402          hidden: !0
14403        },
14404        session: {
14405          set: function(e) {
14406            this.setSession(e)
14407          },
14408          get: function() {
14409            return this.session
14410          },
14411          handlesSet: !0,
14412          hidden: !0
14413        },
14414        hScrollBarAlwaysVisible: 'renderer',
14415        vScrollBarAlwaysVisible: 'renderer',
14416        highlightGutterLine: 'renderer',
14417        animatedScroll: 'renderer',
14418        showInvisibles: 'renderer',
14419        showPrintMargin: 'renderer',
14420        printMarginColumn: 'renderer',
14421        printMargin: 'renderer',
14422        fadeFoldWidgets: 'renderer',
14423        showFoldWidgets: 'renderer',
14424        showLineNumbers: 'renderer',
14425        showGutter: 'renderer',
14426        displayIndentGuides: 'renderer',
14427        fontSize: 'renderer',
14428        fontFamily: 'renderer',
14429        maxLines: 'renderer',
14430        minLines: 'renderer',
14431        scrollPastEnd: 'renderer',
14432        fixedWidthGutter: 'renderer',
14433        theme: 'renderer',
14434        hasCssTransforms: 'renderer',
14435        maxPixelHeight: 'renderer',
14436        scrollSpeed: '$mouseHandler',
14437        dragDelay: '$mouseHandler',
14438        dragEnabled: '$mouseHandler',
14439        focusTimeout: '$mouseHandler',
14440        tooltipFollowsMouse: '$mouseHandler',
14441        firstLineNumber: 'session',
14442        overwrite: 'session',
14443        newLineMode: 'session',
14444        useWorker: 'session',
14445        useSoftTabs: 'session',
14446        navigateWithinSoftTabs: 'session',
14447        tabSize: 'session',
14448        wrap: 'session',
14449        indentedSoftWrap: 'session',
14450        foldStyle: 'session',
14451        mode: 'session'
14452      }),
14453      (t.Editor = w)
14454  }),
14455  define('ace/undomanager', ['require', 'exports', 'module', 'ace/range'], function(e, t, n) {
14456    'use strict'
14457    function i(e, t) {
14458      for (var n = t; n--; ) {
14459        var r = e[n]
14460        if (r && !r[0].ignore) {
14461          while (n < t - 1) {
14462            var i = d(e[n], e[n + 1])
14463            ;(e[n] = i[0]), (e[n + 1] = i[1]), n++
14464          }
14465          return !0
14466        }
14467      }
14468    }
14469    function a(e) {
14470      var t = e.action == 'insert',
14471        n = e.start,
14472        r = e.end,
14473        i = (r.row - n.row) * (t ? 1 : -1),
14474        s = (r.column - n.column) * (t ? 1 : -1)
14475      t && (r = n)
14476      for (var o in this.marks) {
14477        var a = this.marks[o],
14478          f = u(a, n)
14479        if (f < 0) continue
14480        if (f === 0 && t) {
14481          if (a.bias != 1) {
14482            a.bias == -1
14483            continue
14484          }
14485          f = 1
14486        }
14487        var l = t ? f : u(a, r)
14488        if (l > 0) {
14489          ;(a.row += i), (a.column += a.row == r.row ? s : 0)
14490          continue
14491        }
14492        !t && l <= 0 && ((a.row = n.row), (a.column = n.column), l === 0 && (a.bias = 1))
14493      }
14494    }
14495    function f(e) {
14496      return { row: e.row, column: e.column }
14497    }
14498    function l(e) {
14499      return { start: f(e.start), end: f(e.end), action: e.action, lines: e.lines.slice() }
14500    }
14501    function c(e) {
14502      e = e || this
14503      if (Array.isArray(e)) return e.map(c).join('\n')
14504      var t = ''
14505      e.action
14506        ? ((t = e.action == 'insert' ? '+' : '-'), (t += '[' + e.lines + ']'))
14507        : e.value && (Array.isArray(e.value) ? (t = e.value.map(h).join('\n')) : (t = h(e.value))),
14508        e.start && (t += h(e))
14509      if (e.id || e.rev) t += '	(' + (e.id || e.rev) + ')'
14510      return t
14511    }
14512    function h(e) {
14513      return e.start.row + ':' + e.start.column + '=>' + e.end.row + ':' + e.end.column
14514    }
14515    function p(e, t) {
14516      var n = e.action == 'insert',
14517        r = t.action == 'insert'
14518      if (n && r)
14519        if (o(t.start, e.end) >= 0) m(t, e, -1)
14520        else {
14521          if (!(o(t.start, e.start) <= 0)) return null
14522          m(e, t, 1)
14523        }
14524      else if (n && !r)
14525        if (o(t.start, e.end) >= 0) m(t, e, -1)
14526        else {
14527          if (!(o(t.end, e.start) <= 0)) return null
14528          m(e, t, -1)
14529        }
14530      else if (!n && r)
14531        if (o(t.start, e.start) >= 0) m(t, e, 1)
14532        else {
14533          if (!(o(t.start, e.start) <= 0)) return null
14534          m(e, t, 1)
14535        }
14536      else if (!n && !r)
14537        if (o(t.start, e.start) >= 0) m(t, e, 1)
14538        else {
14539          if (!(o(t.end, e.start) <= 0)) return null
14540          m(e, t, -1)
14541        }
14542      return [t, e]
14543    }
14544    function d(e, t) {
14545      for (var n = e.length; n--; )
14546        for (var r = 0; r < t.length; r++)
14547          if (!p(e[n], t[r])) {
14548            while (n < e.length) {
14549              while (r--) p(t[r], e[n])
14550              ;(r = t.length), n++
14551            }
14552            return [e, t]
14553          }
14554      return (e.selectionBefore = t.selectionBefore = e.selectionAfter = t.selectionAfter = null), [t, e]
14555    }
14556    function v(e, t) {
14557      var n = e.action == 'insert',
14558        r = t.action == 'insert'
14559      if (n && r) o(e.start, t.start) < 0 ? m(t, e, 1) : m(e, t, 1)
14560      else if (n && !r)
14561        o(e.start, t.end) >= 0
14562          ? m(e, t, -1)
14563          : o(e.start, t.start) <= 0
14564          ? m(t, e, 1)
14565          : (m(e, s.fromPoints(t.start, e.start), -1), m(t, e, 1))
14566      else if (!n && r)
14567        o(t.start, e.end) >= 0
14568          ? m(t, e, -1)
14569          : o(t.start, e.start) <= 0
14570          ? m(e, t, 1)
14571          : (m(t, s.fromPoints(e.start, t.start), -1), m(e, t, 1))
14572      else if (!n && !r)
14573        if (o(t.start, e.end) >= 0) m(t, e, -1)
14574        else {
14575          if (!(o(t.end, e.start) <= 0)) {
14576            var i, u
14577            return (
14578              o(e.start, t.start) < 0 && ((i = e), (e = y(e, t.start))),
14579              o(e.end, t.end) > 0 && (u = y(e, t.end)),
14580              g(t.end, e.start, e.end, -1),
14581              u && !i && ((e.lines = u.lines), (e.start = u.start), (e.end = u.end), (u = e)),
14582              [t, i, u].filter(Boolean)
14583            )
14584          }
14585          m(e, t, -1)
14586        }
14587      return [t, e]
14588    }
14589    function m(e, t, n) {
14590      g(e.start, t.start, t.end, n), g(e.end, t.start, t.end, n)
14591    }
14592    function g(e, t, n, r) {
14593      e.row == (r == 1 ? t : n).row && (e.column += r * (n.column - t.column)), (e.row += r * (n.row - t.row))
14594    }
14595    function y(e, t) {
14596      var n = e.lines,
14597        r = e.end
14598      e.end = f(t)
14599      var i = e.end.row - e.start.row,
14600        s = n.splice(i, n.length),
14601        o = i ? t.column : t.column - e.start.column
14602      n.push(s[0].substring(0, o)), (s[0] = s[0].substr(o))
14603      var u = { start: f(t), end: r, lines: s, action: e.action }
14604      return u
14605    }
14606    function b(e, t) {
14607      t = l(t)
14608      for (var n = e.length; n--; ) {
14609        var r = e[n]
14610        for (var i = 0; i < r.length; i++) {
14611          var s = r[i],
14612            o = v(s, t)
14613          ;(t = o[0]), o.length != 2 && (o[2] ? (r.splice(i + 1, 1, o[1], o[2]), i++) : o[1] || (r.splice(i, 1), i--))
14614        }
14615        r.length || e.splice(n, 1)
14616      }
14617      return e
14618    }
14619    function w(e, t) {
14620      for (var n = 0; n < t.length; n++) {
14621        var r = t[n]
14622        for (var i = 0; i < r.length; i++) b(e, r[i])
14623      }
14624    }
14625    var r = function() {
14626      ;(this.$maxRev = 0), (this.$fromUndo = !1), this.reset()
14627    }
14628    ;(function() {
14629      ;(this.addSession = function(e) {
14630        this.$session = e
14631      }),
14632        (this.add = function(e, t, n) {
14633          if (this.$fromUndo) return
14634          if (e == this.$lastDelta) return
14635          if (t === !1 || !this.lastDeltas)
14636            (this.lastDeltas = []), this.$undoStack.push(this.lastDeltas), (e.id = this.$rev = ++this.$maxRev)
14637          if (e.action == 'remove' || e.action == 'insert') this.$lastDelta = e
14638          this.lastDeltas.push(e)
14639        }),
14640        (this.addSelection = function(e, t) {
14641          this.selections.push({ value: e, rev: t || this.$rev })
14642        }),
14643        (this.startNewGroup = function() {
14644          return (this.lastDeltas = null), this.$rev
14645        }),
14646        (this.markIgnored = function(e, t) {
14647          t == null && (t = this.$rev + 1)
14648          var n = this.$undoStack
14649          for (var r = n.length; r--; ) {
14650            var i = n[r][0]
14651            if (i.id <= e) break
14652            i.id < t && (i.ignore = !0)
14653          }
14654          this.lastDeltas = null
14655        }),
14656        (this.getSelection = function(e, t) {
14657          var n = this.selections
14658          for (var r = n.length; r--; ) {
14659            var i = n[r]
14660            if (i.rev < e) return t && (i = n[r + 1]), i
14661          }
14662        }),
14663        (this.getRevision = function() {
14664          return this.$rev
14665        }),
14666        (this.getDeltas = function(e, t) {
14667          t == null && (t = this.$rev + 1)
14668          var n = this.$undoStack,
14669            r = null,
14670            i = 0
14671          for (var s = n.length; s--; ) {
14672            var o = n[s][0]
14673            o.id < t && !r && (r = s + 1)
14674            if (o.id <= e) {
14675              i = s + 1
14676              break
14677            }
14678          }
14679          return n.slice(i, r)
14680        }),
14681        (this.getChangedRanges = function(e, t) {
14682          t == null && (t = this.$rev + 1)
14683        }),
14684        (this.getChangedLines = function(e, t) {
14685          t == null && (t = this.$rev + 1)
14686        }),
14687        (this.undo = function(e, t) {
14688          this.lastDeltas = null
14689          var n = this.$undoStack
14690          if (!i(n, n.length)) return
14691          e || (e = this.$session),
14692            this.$redoStackBaseRev !== this.$rev && this.$redoStack.length && (this.$redoStack = []),
14693            (this.$fromUndo = !0)
14694          var r = n.pop(),
14695            s = null
14696          return (
14697            r && r.length && ((s = e.undoChanges(r, t)), this.$redoStack.push(r), this.$syncRev()),
14698            (this.$fromUndo = !1),
14699            s
14700          )
14701        }),
14702        (this.redo = function(e, t) {
14703          ;(this.lastDeltas = null), e || (e = this.$session), (this.$fromUndo = !0)
14704          if (this.$redoStackBaseRev != this.$rev) {
14705            var n = this.getDeltas(this.$redoStackBaseRev, this.$rev + 1)
14706            w(this.$redoStack, n),
14707              (this.$redoStackBaseRev = this.$rev),
14708              this.$redoStack.forEach(function(e) {
14709                e[0].id = ++this.$maxRev
14710              }, this)
14711          }
14712          var r = this.$redoStack.pop(),
14713            i = null
14714          return r && ((i = e.redoChanges(r, t)), this.$undoStack.push(r), this.$syncRev()), (this.$fromUndo = !1), i
14715        }),
14716        (this.$syncRev = function() {
14717          var e = this.$undoStack,
14718            t = e[e.length - 1],
14719            n = (t && t[0].id) || 0
14720          ;(this.$redoStackBaseRev = n), (this.$rev = n)
14721        }),
14722        (this.reset = function() {
14723          ;(this.lastDeltas = null),
14724            (this.$lastDelta = null),
14725            (this.$undoStack = []),
14726            (this.$redoStack = []),
14727            (this.$rev = 0),
14728            (this.mark = 0),
14729            (this.$redoStackBaseRev = this.$rev),
14730            (this.selections = [])
14731        }),
14732        (this.canUndo = function() {
14733          return this.$undoStack.length > 0
14734        }),
14735        (this.canRedo = function() {
14736          return this.$redoStack.length > 0
14737        }),
14738        (this.bookmark = function(e) {
14739          e == undefined && (e = this.$rev), (this.mark = e)
14740        }),
14741        (this.isAtBookmark = function() {
14742          return this.$rev === this.mark
14743        }),
14744        (this.toJSON = function() {}),
14745        (this.fromJSON = function() {}),
14746        (this.hasUndo = this.canUndo),
14747        (this.hasRedo = this.canRedo),
14748        (this.isClean = this.isAtBookmark),
14749        (this.markClean = this.bookmark),
14750        (this.$prettyPrint = function(e) {
14751          return e ? c(e) : c(this.$undoStack) + '\n---\n' + c(this.$redoStack)
14752        })
14753    }.call(r.prototype))
14754    var s = e('./range').Range,
14755      o = s.comparePoints,
14756      u = s.comparePoints
14757    t.UndoManager = r
14758  }),
14759  define('ace/layer/gutter', [
14760    'require',
14761    'exports',
14762    'module',
14763    'ace/lib/dom',
14764    'ace/lib/oop',
14765    'ace/lib/lang',
14766    'ace/lib/event_emitter'
14767  ], function(e, t, n) {
14768    'use strict'
14769    var r = e('../lib/dom'),
14770      i = e('../lib/oop'),
14771      s = e('../lib/lang'),
14772      o = e('../lib/event_emitter').EventEmitter,
14773      u = function(e) {
14774        ;(this.element = r.createElement('div')),
14775          (this.element.className = 'ace_layer ace_gutter-layer'),
14776          e.appendChild(this.element),
14777          this.setShowFoldWidgets(this.$showFoldWidgets),
14778          (this.gutterWidth = 0),
14779          (this.$annotations = []),
14780          (this.$updateAnnotations = this.$updateAnnotations.bind(this)),
14781          (this.$cells = [])
14782      }
14783    ;(function() {
14784      i.implement(this, o),
14785        (this.setSession = function(e) {
14786          this.session && this.session.removeEventListener('change', this.$updateAnnotations),
14787            (this.session = e),
14788            e && e.on('change', this.$updateAnnotations)
14789        }),
14790        (this.addGutterDecoration = function(e, t) {
14791          window.console && console.warn && console.warn('deprecated use session.addGutterDecoration'),
14792            this.session.addGutterDecoration(e, t)
14793        }),
14794        (this.removeGutterDecoration = function(e, t) {
14795          window.console && console.warn && console.warn('deprecated use session.removeGutterDecoration'),
14796            this.session.removeGutterDecoration(e, t)
14797        }),
14798        (this.setAnnotations = function(e) {
14799          this.$annotations = []
14800          for (var t = 0; t < e.length; t++) {
14801            var n = e[t],
14802              r = n.row,
14803              i = this.$annotations[r]
14804            i || (i = this.$annotations[r] = { text: [] })
14805            var o = n.text
14806            ;(o = o ? s.escapeHTML(o) : n.html || ''), i.text.indexOf(o) === -1 && i.text.push(o)
14807            var u = n.type
14808            u == 'error'
14809              ? (i.className = ' ace_error')
14810              : u == 'warning' && i.className != ' ace_error'
14811              ? (i.className = ' ace_warning')
14812              : u == 'info' && !i.className && (i.className = ' ace_info')
14813          }
14814        }),
14815        (this.$updateAnnotations = function(e) {
14816          if (!this.$annotations.length) return
14817          var t = e.start.row,
14818            n = e.end.row - t
14819          if (n !== 0)
14820            if (e.action == 'remove') this.$annotations.splice(t, n + 1, null)
14821            else {
14822              var r = new Array(n + 1)
14823              r.unshift(t, 1), this.$annotations.splice.apply(this.$annotations, r)
14824            }
14825        }),
14826        (this.update = function(e) {
14827          var t = this.session,
14828            n = e.firstRow,
14829            i = Math.min(e.lastRow + e.gutterOffset, t.getLength() - 1),
14830            s = t.getNextFoldLine(n),
14831            o = s ? s.start.row : Infinity,
14832            u = this.$showFoldWidgets && t.foldWidgets,
14833            a = t.$breakpoints,
14834            f = t.$decorations,
14835            l = t.$firstLineNumber,
14836            c = 0,
14837            h = t.gutterRenderer || this.$renderer,
14838            p = null,
14839            d = -1,
14840            v = n
14841          for (;;) {
14842            v > o && ((v = s.end.row + 1), (s = t.getNextFoldLine(v, s)), (o = s ? s.start.row : Infinity))
14843            if (v > i) {
14844              while (this.$cells.length > d + 1) (p = this.$cells.pop()), this.element.removeChild(p.element)
14845              break
14846            }
14847            ;(p = this.$cells[++d]),
14848              p ||
14849                ((p = { element: null, textNode: null, foldWidget: null }),
14850                (p.element = r.createElement('div')),
14851                (p.textNode = document.createTextNode('')),
14852                p.element.appendChild(p.textNode),
14853                this.element.appendChild(p.element),
14854                (this.$cells[d] = p))
14855            var m = 'ace_gutter-cell '
14856            a[v] && (m += a[v]),
14857              f[v] && (m += f[v]),
14858              this.$annotations[v] && (m += this.$annotations[v].className),
14859              p.element.className != m && (p.element.className = m)
14860            var g = t.getRowLength(v) * e.lineHeight + 'px'
14861            g != p.element.style.height && (p.element.style.height = g)
14862            if (u) {
14863              var y = u[v]
14864              y == null && (y = u[v] = t.getFoldWidget(v))
14865            }
14866            if (y) {
14867              p.foldWidget || ((p.foldWidget = r.createElement('span')), p.element.appendChild(p.foldWidget))
14868              var m = 'ace_fold-widget ace_' + y
14869              y == 'start' && v == o && v < s.end.row ? (m += ' ace_closed') : (m += ' ace_open'),
14870                p.foldWidget.className != m && (p.foldWidget.className = m)
14871              var g = e.lineHeight + 'px'
14872              p.foldWidget.style.height != g && (p.foldWidget.style.height = g)
14873            } else p.foldWidget && (p.element.removeChild(p.foldWidget), (p.foldWidget = null))
14874            var b = (c = h ? h.getText(t, v) : v + l)
14875            b !== p.textNode.data && (p.textNode.data = b), v++
14876          }
14877          this.element.style.height = e.minHeight + 'px'
14878          if (this.$fixedWidth || t.$useWrapMode) c = t.getLength() + l
14879          var w = h ? h.getWidth(t, c, e) : c.toString().length * e.characterWidth,
14880            E = this.$padding || this.$computePadding()
14881          ;(w += E.left + E.right),
14882            w !== this.gutterWidth &&
14883              !isNaN(w) &&
14884              ((this.gutterWidth = w),
14885              (this.element.style.width = Math.ceil(this.gutterWidth) + 'px'),
14886              this._emit('changeGutterWidth', w))
14887        }),
14888        (this.$fixedWidth = !1),
14889        (this.$showLineNumbers = !0),
14890        (this.$renderer = ''),
14891        (this.setShowLineNumbers = function(e) {
14892          this.$renderer = !e && {
14893            getWidth: function() {
14894              return ''
14895            },
14896            getText: function() {
14897              return ''
14898            }
14899          }
14900        }),
14901        (this.getShowLineNumbers = function() {
14902          return this.$showLineNumbers
14903        }),
14904        (this.$showFoldWidgets = !0),
14905        (this.setShowFoldWidgets = function(e) {
14906          e
14907            ? r.addCssClass(this.element, 'ace_folding-enabled')
14908            : r.removeCssClass(this.element, 'ace_folding-enabled'),
14909            (this.$showFoldWidgets = e),
14910            (this.$padding = null)
14911        }),
14912        (this.getShowFoldWidgets = function() {
14913          return this.$showFoldWidgets
14914        }),
14915        (this.$computePadding = function() {
14916          if (!this.element.firstChild) return { left: 0, right: 0 }
14917          var e = r.computedStyle(this.element.firstChild)
14918          return (
14919            (this.$padding = {}),
14920            (this.$padding.left = parseInt(e.paddingLeft) + 1 || 0),
14921            (this.$padding.right = parseInt(e.paddingRight) || 0),
14922            this.$padding
14923          )
14924        }),
14925        (this.getRegion = function(e) {
14926          var t = this.$padding || this.$computePadding(),
14927            n = this.element.getBoundingClientRect()
14928          if (e.x < t.left + n.left) return 'markers'
14929          if (this.$showFoldWidgets && e.x > n.right - t.right) return 'foldWidgets'
14930        })
14931    }.call(u.prototype),
14932      (t.Gutter = u))
14933  }),
14934  define('ace/layer/marker', ['require', 'exports', 'module', 'ace/range', 'ace/lib/dom'], function(e, t, n) {
14935    'use strict'
14936    var r = e('../range').Range,
14937      i = e('../lib/dom'),
14938      s = function(e) {
14939        ;(this.element = i.createElement('div')),
14940          (this.element.className = 'ace_layer ace_marker-layer'),
14941          e.appendChild(this.element)
14942      }
14943    ;(function() {
14944      function e(e, t, n, r) {
14945        return (e ? 1 : 0) | (t ? 2 : 0) | (n ? 4 : 0) | (r ? 8 : 0)
14946      }
14947      ;(this.$padding = 0),
14948        (this.setPadding = function(e) {
14949          this.$padding = e
14950        }),
14951        (this.setSession = function(e) {
14952          this.session = e
14953        }),
14954        (this.setMarkers = function(e) {
14955          this.markers = e
14956        }),
14957        (this.update = function(e) {
14958          if (!e) return
14959          this.config = e
14960          var t = []
14961          for (var n in this.markers) {
14962            var r = this.markers[n]
14963            if (!r.range) {
14964              r.update(t, this, this.session, e)
14965              continue
14966            }
14967            var i = r.range.clipRows(e.firstRow, e.lastRow)
14968            if (i.isEmpty()) continue
14969            i = i.toScreenRange(this.session)
14970            if (r.renderer) {
14971              var s = this.$getTop(i.start.row, e),
14972                o =
14973                  this.$padding +
14974                  (this.session.$bidiHandler.isBidiRow(i.start.row)
14975                    ? this.session.$bidiHandler.getPosLeft(i.start.column)
14976                    : i.start.column * e.characterWidth)
14977              r.renderer(t, i, o, s, e)
14978            } else
14979              r.type == 'fullLine'
14980                ? this.drawFullLineMarker(t, i, r.clazz, e)
14981                : r.type == 'screenLine'
14982                ? this.drawScreenLineMarker(t, i, r.clazz, e)
14983                : i.isMultiLine()
14984                ? r.type == 'text'
14985                  ? this.drawTextMarker(t, i, r.clazz, e)
14986                  : this.drawMultiLineMarker(t, i, r.clazz, e)
14987                : this.session.$bidiHandler.isBidiRow(i.start.row)
14988                ? this.drawBidiSingleLineMarker(t, i, r.clazz + ' ace_start' + ' ace_br15', e)
14989                : this.drawSingleLineMarker(t, i, r.clazz + ' ace_start' + ' ace_br15', e)
14990          }
14991          this.element.innerHTML = t.join('')
14992        }),
14993        (this.$getTop = function(e, t) {
14994          return (e - t.firstRowScreen) * t.lineHeight
14995        }),
14996        (this.drawTextMarker = function(t, n, i, s, o) {
14997          var u = this.session,
14998            a = n.start.row,
14999            f = n.end.row,
15000            l = a,
15001            c = 0,
15002            h = 0,
15003            p = u.getScreenLastRowColumn(l),
15004            d = null,
15005            v = new r(l, n.start.column, l, h)
15006          for (; l <= f; l++)
15007            (v.start.row = v.end.row = l),
15008              (v.start.column = l == a ? n.start.column : u.getRowWrapIndent(l)),
15009              (v.end.column = p),
15010              (c = h),
15011              (h = p),
15012              (p = l + 1 < f ? u.getScreenLastRowColumn(l + 1) : l == f ? 0 : n.end.column),
15013              (d =
15014                i +
15015                (l == a ? ' ace_start' : '') +
15016                ' ace_br' +
15017                e(l == a || (l == a + 1 && n.start.column), c < h, h > p, l == f)),
15018              this.session.$bidiHandler.isBidiRow(l)
15019                ? this.drawBidiSingleLineMarker(t, v, d, s, l == f ? 0 : 1, o)
15020                : this.drawSingleLineMarker(t, v, d, s, l == f ? 0 : 1, o)
15021        }),
15022        (this.drawMultiLineMarker = function(e, t, n, r, i) {
15023          var s = this.$padding,
15024            o,
15025            u,
15026            a
15027          i = i || ''
15028          if (this.session.$bidiHandler.isBidiRow(t.start.row)) {
15029            var f = t.clone()
15030            ;(f.end.row = f.start.row),
15031              (f.end.column = this.session.getLine(f.start.row).length),
15032              this.drawBidiSingleLineMarker(e, f, n + ' ace_br1 ace_start', r, null, i)
15033          } else
15034            (o = r.lineHeight),
15035              (u = this.$getTop(t.start.row, r)),
15036              (a = s + t.start.column * r.characterWidth),
15037              e.push(
15038                "<div class='",
15039                n,
15040                " ace_br1 ace_start' style='",
15041                'height:',
15042                o,
15043                'px;',
15044                'right:0;',
15045                'top:',
15046                u,
15047                'px;',
15048                'left:',
15049                a,
15050                'px;',
15051                i,
15052                "'></div>"
15053              )
15054          if (this.session.$bidiHandler.isBidiRow(t.end.row)) {
15055            var f = t.clone()
15056            ;(f.start.row = f.end.row),
15057              (f.start.column = 0),
15058              this.drawBidiSingleLineMarker(e, f, n + ' ace_br12', r, null, i)
15059          } else {
15060            var l = t.end.column * r.characterWidth
15061            ;(o = r.lineHeight),
15062              (u = this.$getTop(t.end.row, r)),
15063              e.push(
15064                "<div class='",
15065                n,
15066                " ace_br12' style='",
15067                'height:',
15068                o,
15069                'px;',
15070                'width:',
15071                l,
15072                'px;',
15073                'top:',
15074                u,
15075                'px;',
15076                'left:',
15077                s,
15078                'px;',
15079                i,
15080                "'></div>"
15081              )
15082          }
15083          o = (t.end.row - t.start.row - 1) * r.lineHeight
15084          if (o <= 0) return
15085          u = this.$getTop(t.start.row + 1, r)
15086          var c = (t.start.column ? 1 : 0) | (t.end.column ? 0 : 8)
15087          e.push(
15088            "<div class='",
15089            n,
15090            c ? ' ace_br' + c : '',
15091            "' style='",
15092            'height:',
15093            o,
15094            'px;',
15095            'right:0;',
15096            'top:',
15097            u,
15098            'px;',
15099            'left:',
15100            s,
15101            'px;',
15102            i,
15103            "'></div>"
15104          )
15105        }),
15106        (this.drawSingleLineMarker = function(e, t, n, r, i, s) {
15107          var o = r.lineHeight,
15108            u = (t.end.column + (i || 0) - t.start.column) * r.characterWidth,
15109            a = this.$getTop(t.start.row, r),
15110            f = this.$padding + t.start.column * r.characterWidth
15111          e.push(
15112            "<div class='",
15113            n,
15114            "' style='",
15115            'height:',
15116            o,
15117            'px;',
15118            'width:',
15119            u,
15120            'px;',
15121            'top:',
15122            a,
15123            'px;',
15124            'left:',
15125            f,
15126            'px;',
15127            s || '',
15128            "'></div>"
15129          )
15130        }),
15131        (this.drawBidiSingleLineMarker = function(e, t, n, r, i, s) {
15132          var o = r.lineHeight,
15133            u = this.$getTop(t.start.row, r),
15134            a = this.$padding,
15135            f = this.session.$bidiHandler.getSelections(t.start.column, t.end.column)
15136          f.forEach(function(t) {
15137            e.push(
15138              "<div class='",
15139              n,
15140              "' style='",
15141              'height:',
15142              o,
15143              'px;',
15144              'width:',
15145              t.width + (i || 0),
15146              'px;',
15147              'top:',
15148              u,
15149              'px;',
15150              'left:',
15151              a + t.left,
15152              'px;',
15153              s || '',
15154              "'></div>"
15155            )
15156          })
15157        }),
15158        (this.drawFullLineMarker = function(e, t, n, r, i) {
15159          var s = this.$getTop(t.start.row, r),
15160            o = r.lineHeight
15161          t.start.row != t.end.row && (o += this.$getTop(t.end.row, r) - s),
15162            e.push(
15163              "<div class='",
15164              n,
15165              "' style='",
15166              'height:',
15167              o,
15168              'px;',
15169              'top:',
15170              s,
15171              'px;',
15172              'left:0;right:0;',
15173              i || '',
15174              "'></div>"
15175            )
15176        }),
15177        (this.drawScreenLineMarker = function(e, t, n, r, i) {
15178          var s = this.$getTop(t.start.row, r),
15179            o = r.lineHeight
15180          e.push(
15181            "<div class='",
15182            n,
15183            "' style='",
15184            'height:',
15185            o,
15186            'px;',
15187            'top:',
15188            s,
15189            'px;',
15190            'left:0;right:0;',
15191            i || '',
15192            "'></div>"
15193          )
15194        })
15195    }.call(s.prototype),
15196      (t.Marker = s))
15197  }),
15198  define('ace/layer/text', [
15199    'require',
15200    'exports',
15201    'module',
15202    'ace/lib/oop',
15203    'ace/lib/dom',
15204    'ace/lib/lang',
15205    'ace/lib/useragent',
15206    'ace/lib/event_emitter'
15207  ], function(e, t, n) {
15208    'use strict'
15209    var r = e('../lib/oop'),
15210      i = e('../lib/dom'),
15211      s = e('../lib/lang'),
15212      o = e('../lib/useragent'),
15213      u = e('../lib/event_emitter').EventEmitter,
15214      a = function(e) {
15215        ;(this.element = i.createElement('div')),
15216          (this.element.className = 'ace_layer ace_text-layer'),
15217          e.appendChild(this.element),
15218          (this.$updateEolChar = this.$updateEolChar.bind(this))
15219      }
15220    ;(function() {
15221      r.implement(this, u),
15222        (this.EOF_CHAR = '\u00b6'),
15223        (this.EOL_CHAR_LF = '\u00ac'),
15224        (this.EOL_CHAR_CRLF = '\u00a4'),
15225        (this.EOL_CHAR = this.EOL_CHAR_LF),
15226        (this.TAB_CHAR = '\u2014'),
15227        (this.SPACE_CHAR = '\u00b7'),
15228        (this.$padding = 0),
15229        (this.MAX_LINE_LENGTH = 1e4),
15230        (this.$updateEolChar = function() {
15231          var e = this.session.doc.getNewLineCharacter() == '\n' ? this.EOL_CHAR_LF : this.EOL_CHAR_CRLF
15232          if (this.EOL_CHAR != e) return (this.EOL_CHAR = e), !0
15233        }),
15234        (this.setPadding = function(e) {
15235          ;(this.$padding = e), (this.element.style.padding = '0 ' + e + 'px')
15236        }),
15237        (this.getLineHeight = function() {
15238          return this.$fontMetrics.$characterSize.height || 0
15239        }),
15240        (this.getCharacterWidth = function() {
15241          return this.$fontMetrics.$characterSize.width || 0
15242        }),
15243        (this.$setFontMetrics = function(e) {
15244          ;(this.$fontMetrics = e),
15245            this.$fontMetrics.on(
15246              'changeCharacterSize',
15247              function(e) {
15248                this._signal('changeCharacterSize', e)
15249              }.bind(this)
15250            ),
15251            this.$pollSizeChanges()
15252        }),
15253        (this.checkForSizeChanges = function() {
15254          this.$fontMetrics.checkForSizeChanges()
15255        }),
15256        (this.$pollSizeChanges = function() {
15257          return (this.$pollSizeChangesTimer = this.$fontMetrics.$pollSizeChanges())
15258        }),
15259        (this.setSession = function(e) {
15260          ;(this.session = e), e && this.$computeTabString()
15261        }),
15262        (this.showInvisibles = !1),
15263        (this.setShowInvisibles = function(e) {
15264          return this.showInvisibles == e ? !1 : ((this.showInvisibles = e), this.$computeTabString(), !0)
15265        }),
15266        (this.displayIndentGuides = !0),
15267        (this.setDisplayIndentGuides = function(e) {
15268          return this.displayIndentGuides == e ? !1 : ((this.displayIndentGuides = e), this.$computeTabString(), !0)
15269        }),
15270        (this.$tabStrings = []),
15271        (this.onChangeTabSize = this.$computeTabString = function() {
15272          var e = this.session.getTabSize()
15273          this.tabSize = e
15274          var t = (this.$tabStrings = [0])
15275          for (var n = 1; n < e + 1; n++)
15276            this.showInvisibles
15277              ? t.push("<span class='ace_invisible ace_invisible_tab'>" + s.stringRepeat(this.TAB_CHAR, n) + '</span>')
15278              : t.push(s.stringRepeat(' ', n))
15279          if (this.displayIndentGuides) {
15280            this.$indentGuideRe = /\s\S| \t|\t |\s$/
15281            var r = 'ace_indent-guide',
15282              i = '',
15283              o = ''
15284            if (this.showInvisibles) {
15285              ;(r += ' ace_invisible'), (i = ' ace_invisible_space'), (o = ' ace_invisible_tab')
15286              var u = s.stringRepeat(this.SPACE_CHAR, this.tabSize),
15287                a = s.stringRepeat(this.TAB_CHAR, this.tabSize)
15288            } else
15289              var u = s.stringRepeat(' ', this.tabSize),
15290                a = u
15291            ;(this.$tabStrings[' '] = "<span class='" + r + i + "'>" + u + '</span>'),
15292              (this.$tabStrings['	'] = "<span class='" + r + o + "'>" + a + '</span>')
15293          }
15294        }),
15295        (this.updateLines = function(e, t, n) {
15296          ;(this.config.lastRow != e.lastRow || this.config.firstRow != e.firstRow) && this.scrollLines(e),
15297            (this.config = e)
15298          var r = Math.max(t, e.firstRow),
15299            i = Math.min(n, e.lastRow),
15300            s = this.element.childNodes,
15301            o = 0
15302          for (var u = e.firstRow; u < r; u++) {
15303            var a = this.session.getFoldLine(u)
15304            if (a) {
15305              if (a.containsRow(r)) {
15306                r = a.start.row
15307                break
15308              }
15309              u = a.end.row
15310            }
15311            o++
15312          }
15313          var u = r,
15314            a = this.session.getNextFoldLine(u),
15315            f = a ? a.start.row : Infinity
15316          for (;;) {
15317            u > f && ((u = a.end.row + 1), (a = this.session.getNextFoldLine(u, a)), (f = a ? a.start.row : Infinity))
15318            if (u > i) break
15319            var l = s[o++]
15320            if (l) {
15321              var c = []
15322              this.$renderLine(c, u, !this.$useLineGroups(), u == f ? a : !1),
15323                (l.style.height = e.lineHeight * this.session.getRowLength(u) + 'px'),
15324                (l.innerHTML = c.join(''))
15325            }
15326            u++
15327          }
15328        }),
15329        (this.scrollLines = function(e) {
15330          var t = this.config
15331          this.config = e
15332          if (!t || t.lastRow < e.firstRow) return this.update(e)
15333          if (e.lastRow < t.firstRow) return this.update(e)
15334          var n = this.element
15335          if (t.firstRow < e.firstRow)
15336            for (var r = this.session.getFoldedRowCount(t.firstRow, e.firstRow - 1); r > 0; r--)
15337              n.removeChild(n.firstChild)
15338          if (t.lastRow > e.lastRow)
15339            for (var r = this.session.getFoldedRowCount(e.lastRow + 1, t.lastRow); r > 0; r--)
15340              n.removeChild(n.lastChild)
15341          if (e.firstRow < t.firstRow) {
15342            var i = this.$renderLinesFragment(e, e.firstRow, t.firstRow - 1)
15343            n.firstChild ? n.insertBefore(i, n.firstChild) : n.appendChild(i)
15344          }
15345          if (e.lastRow > t.lastRow) {
15346            var i = this.$renderLinesFragment(e, t.lastRow + 1, e.lastRow)
15347            n.appendChild(i)
15348          }
15349        }),
15350        (this.$renderLinesFragment = function(e, t, n) {
15351          var r = this.element.ownerDocument.createDocumentFragment(),
15352            s = t,
15353            o = this.session.getNextFoldLine(s),
15354            u = o ? o.start.row : Infinity
15355          for (;;) {
15356            s > u && ((s = o.end.row + 1), (o = this.session.getNextFoldLine(s, o)), (u = o ? o.start.row : Infinity))
15357            if (s > n) break
15358            var a = i.createElement('div'),
15359              f = []
15360            this.$renderLine(f, s, !1, s == u ? o : !1), (a.innerHTML = f.join(''))
15361            if (this.$useLineGroups())
15362              (a.className = 'ace_line_group'),
15363                r.appendChild(a),
15364                (a.style.height = e.lineHeight * this.session.getRowLength(s) + 'px')
15365            else while (a.firstChild) r.appendChild(a.firstChild)
15366            s++
15367          }
15368          return r
15369        }),
15370        (this.update = function(e) {
15371          this.config = e
15372          var t = [],
15373            n = e.firstRow,
15374            r = e.lastRow,
15375            i = n,
15376            s = this.session.getNextFoldLine(i),
15377            o = s ? s.start.row : Infinity
15378          for (;;) {
15379            i > o && ((i = s.end.row + 1), (s = this.session.getNextFoldLine(i, s)), (o = s ? s.start.row : Infinity))
15380            if (i > r) break
15381            this.$useLineGroups() &&
15382              t.push("<div class='ace_line_group' style='height:", e.lineHeight * this.session.getRowLength(i), "px'>"),
15383              this.$renderLine(t, i, !1, i == o ? s : !1),
15384              this.$useLineGroups() && t.push('</div>'),
15385              i++
15386          }
15387          this.element.innerHTML = t.join('')
15388        }),
15389        (this.$textToken = { text: !0, rparen: !0, lparen: !0 }),
15390        (this.$renderToken = function(e, t, n, r) {
15391          var i = this,
15392            o = /\t|&|<|>|( +)|([\x00-\x1f\x80-\xa0\xad\u1680\u180E\u2000-\u200f\u2028\u2029\u202F\u205F\u3000\uFEFF\uFFF9-\uFFFC])|[\u1100-\u115F\u11A3-\u11A7\u11FA-\u11FF\u2329-\u232A\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3000-\u303E\u3041-\u3096\u3099-\u30FF\u3105-\u312D\u3131-\u318E\u3190-\u31BA\u31C0-\u31E3\u31F0-\u321E\u3220-\u3247\u3250-\u32FE\u3300-\u4DBF\u4E00-\uA48C\uA490-\uA4C6\uA960-\uA97C\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFAFF\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE66\uFE68-\uFE6B\uFF01-\uFF60\uFFE0-\uFFE6]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
15393            u = function(e, n, r, o, u) {
15394              if (n)
15395                return i.showInvisibles
15396                  ? "<span class='ace_invisible ace_invisible_space'>" +
15397                      s.stringRepeat(i.SPACE_CHAR, e.length) +
15398                      '</span>'
15399                  : e
15400              if (e == '&') return '&#38;'
15401              if (e == '<') return '&#60;'
15402              if (e == '>') return '&#62;'
15403              if (e == '	') {
15404                var a = i.session.getScreenTabSize(t + o)
15405                return (t += a - 1), i.$tabStrings[a]
15406              }
15407              if (e == '\u3000') {
15408                var f = i.showInvisibles ? 'ace_cjk ace_invisible ace_invisible_space' : 'ace_cjk',
15409                  l = i.showInvisibles ? i.SPACE_CHAR : ''
15410                return (
15411                  (t += 1),
15412                  "<span class='" + f + "' style='width:" + i.config.characterWidth * 2 + "px'>" + l + '</span>'
15413                )
15414              }
15415              return r
15416                ? "<span class='ace_invisible ace_invisible_space ace_invalid'>" + i.SPACE_CHAR + '</span>'
15417                : ((t += 1),
15418                  "<span class='ace_cjk' style='width:" + i.config.characterWidth * 2 + "px'>" + e + '</span>')
15419            },
15420            a = r.replace(o, u)
15421          if (!this.$textToken[n.type]) {
15422            var f = 'ace_' + n.type.replace(/\./g, ' ace_'),
15423              l = ''
15424            n.type == 'fold' && (l = " style='width:" + n.value.length * this.config.characterWidth + "px;' "),
15425              e.push("<span class='", f, "'", l, '>', a, '</span>')
15426          } else e.push(a)
15427          return t + r.length
15428        }),
15429        (this.renderIndentGuide = function(e, t, n) {
15430          var r = t.search(this.$indentGuideRe)
15431          return r <= 0 || r >= n
15432            ? t
15433            : t[0] == ' '
15434            ? ((r -= r % this.tabSize), e.push(s.stringRepeat(this.$tabStrings[' '], r / this.tabSize)), t.substr(r))
15435            : t[0] == '	'
15436            ? (e.push(s.stringRepeat(this.$tabStrings['	'], r)), t.substr(r))
15437            : t
15438        }),
15439        (this.$renderWrappedLine = function(e, t, n, r) {
15440          var i = 0,
15441            o = 0,
15442            u = n[0],
15443            a = 0
15444          for (var f = 0; f < t.length; f++) {
15445            var l = t[f],
15446              c = l.value
15447            if (f == 0 && this.displayIndentGuides) {
15448              ;(i = c.length), (c = this.renderIndentGuide(e, c, u))
15449              if (!c) continue
15450              i -= c.length
15451            }
15452            if (i + c.length < u) (a = this.$renderToken(e, a, l, c)), (i += c.length)
15453            else {
15454              while (i + c.length >= u)
15455                (a = this.$renderToken(e, a, l, c.substring(0, u - i))),
15456                  (c = c.substring(u - i)),
15457                  (i = u),
15458                  r || e.push('</div>', "<div class='ace_line' style='height:", this.config.lineHeight, "px'>"),
15459                  e.push(s.stringRepeat('\u00a0', n.indent)),
15460                  o++,
15461                  (a = 0),
15462                  (u = n[o] || Number.MAX_VALUE)
15463              c.length != 0 && ((i += c.length), (a = this.$renderToken(e, a, l, c)))
15464            }
15465          }
15466        }),
15467        (this.$renderSimpleLine = function(e, t) {
15468          var n = 0,
15469            r = t[0],
15470            i = r.value
15471          this.displayIndentGuides && (i = this.renderIndentGuide(e, i)), i && (n = this.$renderToken(e, n, r, i))
15472          for (var s = 1; s < t.length; s++) {
15473            ;(r = t[s]), (i = r.value)
15474            if (n + i.length > this.MAX_LINE_LENGTH) return this.$renderOverflowMessage(e, n, r, i)
15475            n = this.$renderToken(e, n, r, i)
15476          }
15477        }),
15478        (this.$renderOverflowMessage = function(e, t, n, r) {
15479          this.$renderToken(e, t, n, r.slice(0, this.MAX_LINE_LENGTH - t)),
15480            e.push(
15481              "<span style='position:absolute;right:0' class='ace_inline_button ace_keyword ace_toggle_wrap'>&lt;click to see more...&gt;</span>"
15482            )
15483        }),
15484        (this.$renderLine = function(e, t, n, r) {
15485          !r && r != 0 && (r = this.session.getFoldLine(t))
15486          if (r) var i = this.$getFoldLineTokens(t, r)
15487          else var i = this.session.getTokens(t)
15488          n ||
15489            e.push(
15490              "<div class='ace_line' style='height:",
15491              this.config.lineHeight * (this.$useLineGroups() ? 1 : this.session.getRowLength(t)),
15492              "px'>"
15493            )
15494          if (i.length) {
15495            var s = this.session.getRowSplitData(t)
15496            s && s.length ? this.$renderWrappedLine(e, i, s, n) : this.$renderSimpleLine(e, i)
15497          }
15498          this.showInvisibles &&
15499            (r && (t = r.end.row),
15500            e.push(
15501              "<span class='ace_invisible ace_invisible_eol'>",
15502              t == this.session.getLength() - 1 ? this.EOF_CHAR : this.EOL_CHAR,
15503              '</span>'
15504            )),
15505            n || e.push('</div>')
15506        }),
15507        (this.$getFoldLineTokens = function(e, t) {
15508          function i(e, t, n) {
15509            var i = 0,
15510              s = 0
15511            while (s + e[i].value.length < t) {
15512              ;(s += e[i].value.length), i++
15513              if (i == e.length) return
15514            }
15515            if (s != t) {
15516              var o = e[i].value.substring(t - s)
15517              o.length > n - t && (o = o.substring(0, n - t)),
15518                r.push({ type: e[i].type, value: o }),
15519                (s = t + o.length),
15520                (i += 1)
15521            }
15522            while (s < n && i < e.length) {
15523              var o = e[i].value
15524              o.length + s > n ? r.push({ type: e[i].type, value: o.substring(0, n - s) }) : r.push(e[i]),
15525                (s += o.length),
15526                (i += 1)
15527            }
15528          }
15529          var n = this.session,
15530            r = [],
15531            s = n.getTokens(e)
15532          return (
15533            t.walk(
15534              function(e, t, o, u, a) {
15535                e != null ? r.push({ type: 'fold', value: e }) : (a && (s = n.getTokens(t)), s.length && i(s, u, o))
15536              },
15537              t.end.row,
15538              this.session.getLine(t.end.row).length
15539            ),
15540            r
15541          )
15542        }),
15543        (this.$useLineGroups = function() {
15544          return this.session.getUseWrapMode()
15545        }),
15546        (this.destroy = function() {
15547          clearInterval(this.$pollSizeChangesTimer),
15548            this.$measureNode && this.$measureNode.parentNode.removeChild(this.$measureNode),
15549            delete this.$measureNode
15550        })
15551    }.call(a.prototype),
15552      (t.Text = a))
15553  }),
15554  define('ace/layer/cursor', ['require', 'exports', 'module', 'ace/lib/dom'], function(e, t, n) {
15555    'use strict'
15556    var r = e('../lib/dom'),
15557      i,
15558      s = function(e) {
15559        ;(this.element = r.createElement('div')),
15560          (this.element.className = 'ace_layer ace_cursor-layer'),
15561          e.appendChild(this.element),
15562          i === undefined && (i = !('opacity' in this.element.style)),
15563          (this.isVisible = !1),
15564          (this.isBlinking = !0),
15565          (this.blinkInterval = 1e3),
15566          (this.smoothBlinking = !1),
15567          (this.cursors = []),
15568          (this.cursor = this.addCursor()),
15569          r.addCssClass(this.element, 'ace_hidden-cursors'),
15570          (this.$updateCursors = (i ? this.$updateVisibility : this.$updateOpacity).bind(this))
15571      }
15572    ;(function() {
15573      ;(this.$updateVisibility = function(e) {
15574        var t = this.cursors
15575        for (var n = t.length; n--; ) t[n].style.visibility = e ? '' : 'hidden'
15576      }),
15577        (this.$updateOpacity = function(e) {
15578          var t = this.cursors
15579          for (var n = t.length; n--; ) t[n].style.opacity = e ? '' : '0'
15580        }),
15581        (this.$startCssAnimation = function() {
15582          var e = this.cursors
15583          for (var t = e.length; t--; ) e[t].style.animationDuration = this.blinkInterval + 'ms'
15584          setTimeout(
15585            function() {
15586              r.addCssClass(this.element, 'ace_animate-blinking')
15587            }.bind(this)
15588          )
15589        }),
15590        (this.$stopCssAnimation = function() {
15591          r.removeCssClass(this.element, 'ace_animate-blinking')
15592        }),
15593        (this.$padding = 0),
15594        (this.setPadding = function(e) {
15595          this.$padding = e
15596        }),
15597        (this.setSession = function(e) {
15598          this.session = e
15599        }),
15600        (this.setBlinking = function(e) {
15601          e != this.isBlinking && ((this.isBlinking = e), this.restartTimer())
15602        }),
15603        (this.setBlinkInterval = function(e) {
15604          e != this.blinkInterval && ((this.blinkInterval = e), this.restartTimer())
15605        }),
15606        (this.setSmoothBlinking = function(e) {
15607          e != this.smoothBlinking &&
15608            !i &&
15609            ((this.smoothBlinking = e),
15610            r.setCssClass(this.element, 'ace_smooth-blinking', e),
15611            this.$updateCursors(!0),
15612            (this.$updateCursors = this.$updateOpacity.bind(this)),
15613            this.restartTimer())
15614        }),
15615        (this.addCursor = function() {
15616          var e = r.createElement('div')
15617          return (e.className = 'ace_cursor'), this.element.appendChild(e), this.cursors.push(e), e
15618        }),
15619        (this.removeCursor = function() {
15620          if (this.cursors.length > 1) {
15621            var e = this.cursors.pop()
15622            return e.parentNode.removeChild(e), e
15623          }
15624        }),
15625        (this.hideCursor = function() {
15626          ;(this.isVisible = !1), r.addCssClass(this.element, 'ace_hidden-cursors'), this.restartTimer()
15627        }),
15628        (this.showCursor = function() {
15629          ;(this.isVisible = !0), r.removeCssClass(this.element, 'ace_hidden-cursors'), this.restartTimer()
15630        }),
15631        (this.restartTimer = function() {
15632          var e = this.$updateCursors
15633          clearInterval(this.intervalId),
15634            clearTimeout(this.timeoutId),
15635            this.$stopCssAnimation(),
15636            this.smoothBlinking && r.removeCssClass(this.element, 'ace_smooth-blinking'),
15637            e(!0)
15638          if (!this.isBlinking || !this.blinkInterval || !this.isVisible) return
15639          this.smoothBlinking &&
15640            setTimeout(
15641              function() {
15642                r.addCssClass(this.element, 'ace_smooth-blinking')
15643              }.bind(this)
15644            )
15645          if (r.HAS_CSS_ANIMATION) this.$startCssAnimation()
15646          else {
15647            var t = function() {
15648              this.timeoutId = setTimeout(function() {
15649                e(!1)
15650              }, 0.6 * this.blinkInterval)
15651            }.bind(this)
15652            ;(this.intervalId = setInterval(function() {
15653              e(!0), t()
15654            }, this.blinkInterval)),
15655              t()
15656          }
15657        }),
15658        (this.getPixelPosition = function(e, t) {
15659          if (!this.config || !this.session) return { left: 0, top: 0 }
15660          e || (e = this.session.selection.getCursor())
15661          var n = this.session.documentToScreenPosition(e),
15662            r =
15663              this.$padding +
15664              (this.session.$bidiHandler.isBidiRow(n.row, e.row)
15665                ? this.session.$bidiHandler.getPosLeft(n.column)
15666                : n.column * this.config.characterWidth),
15667            i = (n.row - (t ? this.config.firstRowScreen : 0)) * this.config.lineHeight
15668          return { left: r, top: i }
15669        }),
15670        (this.update = function(e) {
15671          this.config = e
15672          var t = this.session.$selectionMarkers,
15673            n = 0,
15674            r = 0
15675          if (t === undefined || t.length === 0) t = [{ cursor: null }]
15676          for (var n = 0, i = t.length; n < i; n++) {
15677            var s = this.getPixelPosition(t[n].cursor, !0)
15678            if ((s.top > e.height + e.offset || s.top < 0) && n > 1) continue
15679            var o = (this.cursors[r++] || this.addCursor()).style
15680            this.drawCursor
15681              ? this.drawCursor(o, s, e, t[n], this.session)
15682              : ((o.left = s.left + 'px'),
15683                (o.top = s.top + 'px'),
15684                (o.width = e.characterWidth + 'px'),
15685                (o.height = e.lineHeight + 'px'))
15686          }
15687          while (this.cursors.length >
15687 r) this.removeCursor()
15688          var u = this.session.getOverwrite()
15689          this.$setOverwrite(u), (this.$pixelPos = s), this.restartTimer()
15690        }),
15691        (this.drawCursor = null),
15692        (this.$setOverwrite = function(e) {
15693          e != this.overwrite &&
15694            ((this.overwrite = e),
15695            e
15696              ? r.addCssClass(this.element, 'ace_overwrite-cursors')
15697              : r.removeCssClass(this.element, 'ace_overwrite-cursors'))
15698        }),
15699        (this.destroy = function() {
15700          clearInterval(this.intervalId), clearTimeout(this.timeoutId)
15701        })
15702    }.call(s.prototype),
15703      (t.Cursor = s))
15704  }),
15705  define('ace/scrollbar', [
15706    'require',
15707    'exports',
15708    'module',
15709    'ace/lib/oop',
15710    'ace/lib/dom',
15711    'ace/lib/event',
15712    'ace/lib/event_emitter'
15713  ], function(e, t, n) {
15714    'use strict'
15715    var r = e('./lib/oop'),
15716      i = e('./lib/dom'),
15717      s = e('./lib/event'),
15718      o = e('./lib/event_emitter').EventEmitter,
15719      u = 32768,
15720      a = function(e) {
15721        ;(this.element = i.createElement('div')),
15722          (this.element.className = 'ace_scrollbar ace_scrollbar' + this.classSuffix),
15723          (this.inner = i.createElement('div')),
15724          (this.inner.className = 'ace_scrollbar-inner'),
15725          this.element.appendChild(this.inner),
15726          e.appendChild(this.element),
15727          this.setVisible(!1),
15728          (this.skipEvent = !1),
15729          s.addListener(this.element, 'scroll', this.onScroll.bind(this)),
15730          s.addListener(this.element, 'mousedown', s.preventDefault)
15731      }
15732    ;(function() {
15733      r.implement(this, o),
15734        (this.setVisible = function(e) {
15735          ;(this.element.style.display = e ? '' : 'none'), (this.isVisible = e), (this.coeff = 1)
15736        })
15737    }.call(a.prototype))
15738    var f = function(e, t) {
15739      a.call(this, e),
15740        (this.scrollTop = 0),
15741        (this.scrollHeight = 0),
15742        (t.$scrollbarWidth = this.width = i.scrollbarWidth(e.ownerDocument)),
15743        (this.inner.style.width = this.element.style.width = (this.width || 15) + 5 + 'px'),
15744        (this.$minWidth = 0)
15745    }
15746    r.inherits(f, a),
15747      function() {
15748        ;(this.classSuffix = '-v'),
15749          (this.onScroll = function() {
15750            if (!this.skipEvent) {
15751              this.scrollTop = this.element.scrollTop
15752              if (this.coeff != 1) {
15753                var e = this.element.clientHeight / this.scrollHeight
15754                this.scrollTop = (this.scrollTop * (1 - e)) / (this.coeff - e)
15755              }
15756              this._emit('scroll', { data: this.scrollTop })
15757            }
15758            this.skipEvent = !1
15759          }),
15760          (this.getWidth = function() {
15761            return Math.max(this.isVisible ? this.width : 0, this.$minWidth || 0)
15762          }),
15763          (this.setHeight = function(e) {
15764            this.element.style.height = e + 'px'
15765          }),
15766          (this.setInnerHeight = this.setScrollHeight = function(e) {
15767            ;(this.scrollHeight = e),
15768              e > u ? ((this.coeff = u / e), (e = u)) : this.coeff != 1 && (this.coeff = 1),
15769              (this.inner.style.height = e + 'px')
15770          }),
15771          (this.setScrollTop = function(e) {
15772            this.scrollTop != e &&
15773              ((this.skipEvent = !0), (this.scrollTop = e), (this.element.scrollTop = e * this.coeff))
15774          })
15775      }.call(f.prototype)
15776    var l = function(e, t) {
15777      a.call(this, e),
15778        (this.scrollLeft = 0),
15779        (this.height = t.$scrollbarWidth),
15780        (this.inner.style.height = this.element.style.height = (this.height || 15) + 5 + 'px')
15781    }
15782    r.inherits(l, a),
15783      function() {
15784        ;(this.classSuffix = '-h'),
15785          (this.onScroll = function() {
15786            this.skipEvent ||
15787              ((this.scrollLeft = this.element.scrollLeft), this._emit('scroll', { data: this.scrollLeft })),
15788              (this.skipEvent = !1)
15789          }),
15790          (this.getHeight = function() {
15791            return this.isVisible ? this.height : 0
15792          }),
15793          (this.setWidth = function(e) {
15794            this.element.style.width = e + 'px'
15795          }),
15796          (this.setInnerWidth = function(e) {
15797            this.inner.style.width = e + 'px'
15798          }),
15799          (this.setScrollWidth = function(e) {
15800            this.inner.style.width = e + 'px'
15801          }),
15802          (this.setScrollLeft = function(e) {
15803            this.scrollLeft != e && ((this.skipEvent = !0), (this.scrollLeft = this.element.scrollLeft = e))
15804          })
15805      }.call(l.prototype),
15806      (t.ScrollBar = f),
15807      (t.ScrollBarV = f),
15808      (t.ScrollBarH = l),
15809      (t.VScrollBar = f),
15810      (t.HScrollBar = l)
15811  }),
15812  define('ace/renderloop', ['require', 'exports', 'module', 'ace/lib/event'], function(e, t, n) {
15813    'use strict'
15814    var r = e('./lib/event'),
15815      i = function(e, t) {
15816        ;(this.onRender = e), (this.pending = !1), (this.changes = 0), (this.window = t || window)
15817      }
15818    ;(function() {
15819      this.schedule = function(e) {
15820        this.changes = this.changes | e
15821        if (this.changes) {
15822          var t = this
15823          r.nextFrame(function(e) {
15824            var n = t.changes
15825            n && (r.blockIdle(100), (t.changes = 0), t.onRender(n)), t.changes && t.schedule()
15826          })
15827        }
15828      }
15829    }.call(i.prototype),
15830      (t.RenderLoop = i))
15831  }),
15832  define('ace/layer/font_metrics', [
15833    'require',
15834    'exports',
15835    'module',
15836    'ace/lib/oop',
15837    'ace/lib/dom',
15838    'ace/lib/lang',
15839    'ace/lib/event',
15840    'ace/lib/useragent',
15841    'ace/lib/event_emitter'
15842  ], function(e, t, n) {
15843    var r = e('../lib/oop'),
15844      i = e('../lib/dom'),
15845      s = e('../lib/lang'),
15846      o = e('../lib/event'),
15847      u = e('../lib/useragent'),
15848      a = e('../lib/event_emitter').EventEmitter,
15849      f = 256,
15850      l = typeof ResizeObserver == 'function',
15851      c = 200,
15852      h = (t.FontMetrics = function(e) {
15853        ;(this.el = i.createElement('div')),
15854          this.$setMeasureNodeStyles(this.el.style, !0),
15855          (this.$main = i.createElement('div')),
15856          this.$setMeasureNodeStyles(this.$main.style),
15857          (this.$measureNode = i.createElement('div')),
15858          this.$setMeasureNodeStyles(this.$measureNode.style),
15859          this.el.appendChild(this.$main),
15860          this.el.appendChild(this.$measureNode),
15861          e.appendChild(this.el),
15862          (this.$measureNode.innerHTML = s.stringRepeat('X', f)),
15863          (this.$characterSize = { width: 0, height: 0 }),
15864          l ? this.$addObserver() : this.checkForSizeChanges()
15865      })
15866    ;(function() {
15867      r.implement(this, a),
15868        (this.$characterSize = { width: 0, height: 0 }),
15869        (this.$setMeasureNodeStyles = function(e, t) {
15870          ;(e.width = e.height = 'auto'),
15871            (e.left = e.top = '0px'),
15872            (e.visibility = 'hidden'),
15873            (e.position = 'absolute'),
15874            (e.whiteSpace = 'pre'),
15875            u.isIE < 8 ? (e['font-family'] = 'inherit') : (e.font = 'inherit'),
15876            (e.overflow = t ? 'hidden' : 'visible')
15877        }),
15878        (this.checkForSizeChanges = function(e) {
15879          e === undefined && (e = this.$measureSizes())
15880          if (e && (this.$characterSize.width !== e.width || this.$characterSize.height !== e.height)) {
15881            this.$measureNode.style.fontWeight = 'bold'
15882            var t = this.$measureSizes()
15883            ;(this.$measureNode.style.fontWeight = ''),
15884              (this.$characterSize = e),
15885              (this.charSizes = Object.create(null)),
15886              (this.allowBoldFonts = t && t.width === e.width && t.height === e.height),
15887              this._emit('changeCharacterSize', { data: e })
15888          }
15889        }),
15890        (this.$addObserver = function() {
15891          var e = this
15892          ;(this.$observer = new window.ResizeObserver(function(t) {
15893            var n = t[0].contentRect
15894            e.checkForSizeChanges({ height: n.height, width: n.width / f })
15895          })),
15896            this.$observer.observe(this.$measureNode)
15897        }),
15898        (this.$pollSizeChanges = function() {
15899          if (this.$pollSizeChangesTimer || this.$observer) return this.$pollSizeChangesTimer
15900          var e = this
15901          return (this.$pollSizeChangesTimer = o.onIdle(function t() {
15902            e.checkForSizeChanges(), o.onIdle(t, 500)
15903          }, 500))
15904        }),
15905        (this.setPolling = function(e) {
15906          e
15907            ? this.$pollSizeChanges()
15908            : this.$pollSizeChangesTimer &&
15909              (clearInterval(this.$pollSizeChangesTimer), (this.$pollSizeChangesTimer = 0))
15910        }),
15911        (this.$measureSizes = function(e) {
15912          var t = { height: (e || this.$measureNode).clientHeight, width: (e || this.$measureNode).clientWidth / f }
15913          return t.width === 0 || t.height === 0 ? null : t
15914        }),
15915        (this.$measureCharWidth = function(e) {
15916          this.$main.innerHTML = s.stringRepeat(e, f)
15917          var t = this.$main.getBoundingClientRect()
15918          return t.width / f
15919        }),
15920        (this.getCharacterWidth = function(e) {
15921          var t = this.charSizes[e]
15922          return t === undefined && (t = this.charSizes[e] = this.$measureCharWidth(e) / this.$characterSize.width), t
15923        }),
15924        (this.destroy = function() {
15925          clearInterval(this.$pollSizeChangesTimer),
15926            this.el && this.el.parentNode && this.el.parentNode.removeChild(this.el)
15927        }),
15928        (this.$getZoom = function e(t) {
15929          return t ? (window.getComputedStyle(t).zoom || 1) * e(t.parentElement) : 1
15930        }),
15931        (this.$initTransformMeasureNodes = function() {
15932          var e = function(e, t) {
15933            return ['div', { style: 'position: absolute;top:' + e + 'px;left:' + t + 'px;' }]
15934          }
15935          this.els = i.buildDom([e(0, 0), e(c, 0), e(0, c), e(c, c)], this.el)
15936        }),
15937        (this.transformCoordinates = function(e, t) {
15938          function r(e, t, n) {
15939            var r = e[1] * t[0] - e[0] * t[1]
15940            return [(-t[1] * n[0] + t[0] * n[1]) / r, (+e[1] * n[0] - e[0] * n[1]) / r]
15941          }
15942          function i(e, t) {
15943            return [e[0] - t[0], e[1] - t[1]]
15944          }
15945          function s(e, t) {
15946            return [e[0] + t[0], e[1] + t[1]]
15947          }
15948          function o(e, t) {
15949            return [e * t[0], e * t[1]]
15950          }
15951          function u(e) {
15952            var t = e.getBoundingClientRect()
15953            return [t.left, t.top]
15954          }
15955          if (e) {
15956            var n = this.$getZoom(this.el)
15957            e = o(1 / n, e)
15958          }
15959          this.els || this.$initTransformMeasureNodes()
15960          var a = u(this.els[0]),
15961            f = u(this.els[1]),
15962            l = u(this.els[2]),
15963            h = u(this.els[3]),
15964            p = r(i(h, f), i(h, l), i(s(f, l), s(h, a))),
15965            d = o(1 + p[0], i(f, a)),
15966            v = o(1 + p[1], i(l, a))
15967          if (t) {
15968            var m = t,
15969              g = (p[0] * m[0]) / c + (p[1] * m[1]) / c + 1,
15970              y = s(o(m[0], d), o(m[1], v))
15971            return s(o(1 / g / c, y), a)
15972          }
15973          var b = i(e, a),
15974            w = r(i(d, o(p[0], b)), i(v, o(p[1], b)), b)
15975          return o(c, w)
15976        })
15977    }.call(h.prototype))
15978  }),
15979  define('ace/virtual_renderer', [
15980    'require',
15981    'exports',
15982    'module',
15983    'ace/lib/oop',
15984    'ace/lib/dom',
15985    'ace/config',
15986    'ace/lib/useragent',
15987    'ace/layer/gutter',
15988    'ace/layer/marker',
15989    'ace/layer/text',
15990    'ace/layer/cursor',
15991    'ace/scrollbar',
15992    'ace/scrollbar',
15993    'ace/renderloop',
15994    'ace/layer/font_metrics',
15995    'ace/lib/event_emitter'
15996  ], function(e, t, n) {
15997    'use strict'
15998    var r = e('./lib/oop'),
15999      i = e('./lib/dom'),
16000      s = e('./config'),
16001      o = e('./lib/useragent'),
16002      u = e('./layer/gutter').Gutter,
16003      a = e('./layer/marker').Marker,
16004      f = e('./layer/text').Text,
16005      l = e('./layer/cursor').Cursor,
16006      c = e('./scrollbar').HScrollBar,
16007      h = e('./scrollbar').VScrollBar,
16008      p = e('./renderloop').RenderLoop,
16009      d = e('./layer/font_metrics').FontMetrics,
16010      v = e('./lib/event_emitter').EventEmitter,
16011      m =
16012        '.ace_editor {position: relative;overflow: hidden;font: 12px/normal \'Monaco\', \'Menlo\', \'Ubuntu Mono\', \'Consolas\', \'source-code-pro\', monospace;direction: ltr;text-align: left;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);}.ace_scroller {position: absolute;overflow: hidden;top: 0;bottom: 0;background-color: inherit;-ms-user-select: none;-moz-user-select: none;-webkit-user-select: none;user-select: none;cursor: text;}.ace_content {position: absolute;box-sizing: border-box;min-width: 100%;}.ace_dragging .ace_scroller:before{position: absolute;top: 0;left: 0;right: 0;bottom: 0;content: \'\';background: rgba(250, 250, 250, 0.01);z-index: 1000;}.ace_dragging.ace_dark .ace_scroller:before{background: rgba(0, 0, 0, 0.01);}.ace_selecting, .ace_selecting * {cursor: text !important;}.ace_gutter {position: absolute;overflow : hidden;width: auto;top: 0;bottom: 0;left: 0;cursor: default;z-index: 4;-ms-user-select: none;-moz-user-select: none;-webkit-user-select: none;user-select: none;}.ace_gutter-active-line {position: absolute;
16012left: 0;right: 0;}.ace_scroller.ace_scroll-left {box-shadow: 17px 0 16px -16px rgba(0, 0, 0, 0.4) inset;}.ace_gutter-cell {padding-left: 19px;padding-right: 6px;background-repeat: no-repeat;}.ace_gutter-cell.ace_error {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABOFBMVEX/////////QRswFAb/Ui4wFAYwFAYwFAaWGAfDRymzOSH/PxswFAb/SiUwFAYwFAbUPRvjQiDllog5HhHdRybsTi3/Tyv9Tir+Syj/UC3////XurebMBIwFAb/RSHbPx/gUzfdwL3kzMivKBAwFAbbvbnhPx66NhowFAYwFAaZJg8wFAaxKBDZurf/RB6mMxb/SCMwFAYwFAbxQB3+RB4wFAb/Qhy4Oh+4QifbNRcwFAYwFAYwFAb/QRzdNhgwFAYwFAbav7v/Uy7oaE68MBK5LxLewr/r2NXewLswFAaxJw4wFAbkPRy2PyYwFAaxKhLm1tMwFAazPiQwFAaUGAb/QBrfOx3bvrv/VC/maE4wFAbRPBq6MRO8Qynew8Dp2tjfwb0wFAbx6eju5+by6uns4uH9/f36+vr/GkHjAAAAYnRSTlMAGt+64rnWu/bo8eAA4InH3+DwoN7j4eLi4xP99Nfg4+b+/u9B/eDs1MD1mO7+4PHg2MXa347g7vDizMLN4eG+Pv7i5evs/v79yu7S3/DV7/498Yv24eH+4ufQ3Ozu/v7+y13sRqwAAADLSURBVHjaZc/XDsFgGIBhtDrshlitmk2IrbHFqL2pvXf/+78DPokj7+Fz9qpU/9UXJIlhmPaTaQ6QPaz0mm+5gwkgovcV6GZzd5JtCQwgsxoHOvJO15kleRLAnMgHFIESUEPmawB9ngmelTtipwwfASilxOLyiV5UVUyVAfbG0cCPHig+GBkzAENHS0AstVF6bacZIOzgLmxsHbt2OecNgJC83JERmePUYq8ARGkJx6XtFsdddBQgZE2nPR6CICZhawjA4Fb/chv+399kfR+MMMDGOQAAAABJRU5ErkJggg==");background-repeat: no-repeat;background-position: 2px center;}.ace_gutter-cell.ace_warning {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAmVBMVEX///8AAAD///8AAAAAAABPSzb/5sAAAAB/blH/73z/ulkAAAAAAAD85pkAAAAAAAACAgP/vGz/rkDerGbGrV7/pkQICAf////e0IsAAAD/oED/qTvhrnUAAAD/yHD/njcAAADuv2r/nz//oTj/p064oGf/zHAAAAA9Nir/tFIAAAD/tlTiuWf/tkIAAACynXEAAAAAAAAtIRW7zBpBAAAAM3RSTlMAABR1m7RXO8Ln31Z36zT+neXe5OzooRDfn+TZ4p3h2hTf4t3k3ucyrN1K5+Xaks52Sfs9CXgrAAAAjklEQVR42o3PbQ+CIBQFYEwboPhSYgoYunIqqLn6/z8uYdH8Vmdnu9vz4WwXgN/xTPRD2+sgOcZjsge/whXZgUaYYvT8QnuJaUrjrHUQreGczuEafQCO/SJTufTbroWsPgsllVhq3wJEk2jUSzX3CUEDJC84707djRc5MTAQxoLgupWRwW6UB5fS++NV8AbOZgnsC7BpEAAAAABJRU5ErkJggg==");background-position: 2px center;}.ace_gutter-cell.ace_info {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAJ0Uk5TAAB2k804AAAAPklEQVQY02NgIB68QuO3tiLznjAwpKTgNyDbMegwisCHZUETUZV0ZqOquBpXj2rtnpSJT1AEnnRmL2OgGgAAIKkRQap2htgAAAAASUVORK5CYII=");background-position: 2px center;}.ace_dark .ace_gutter-cell.ace_info {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAChoaGAgIAqKiq+vr6tra1ZWVmUlJSbm5s8PDxubm56enrdgzg3AAAAAXRSTlMAQObYZgAAAClJREFUeNpjYMAPdsMYHegyJZFQBlsUlMFVCWUYKkAZMxZAGdxlDMQBAG+TBP4B6RyJAAAAAElFTkSuQmCC");}.ace_scrollbar {position: absolute;right: 0;bottom: 0;z-index: 6;}.ace_scrollbar-inner {position: absolute;cursor: text;left: 0;top: 0;}.ace_scrollbar-v{overflow-x: hidden;overflow-y: scroll;top: 0;}.ace_scrollbar-h {overflow-x: scroll;overflow-y: hidden;left: 0;}.ace_print-margin {position: absolute;height: 100%;}.ace_text-input {position: absolute;z-index: 0;width: 0.5em;height: 1em;opacity: 0;background: transparent;-moz-appearance: none;appearance: none;border: none;resize: none;outline: none;overflow: hidden;font: inherit;padding: 0 1px;margin: 0 -1px;text-indent: -1em;-ms-user-select: text;-moz-user-select: text;-webkit-user-select: text;user-select: text;white-space: pre!important;}.ace_text-input.ace_composition {background: inherit;color: inherit;z-index: 1000;opacity: 1;text-indent: 0;}[ace_nocontext=true] {transform: none!important;filter: none!important;perspective: none!important;clip-path: none!important;mask : none!important;contain: none!important;perspective: none!important;mix-blend-mode: initial!important;z-index: auto;}.ace_layer {z-index: 1;position: absolute;overflow: hidden;word-wrap: normal;white-space: pre;height: 100%;width: 100%;box-sizing: border-box;pointer-events: none;}.ace_gutter-layer {position: relative;width: auto;text-align: right;pointer-events: auto;}.ace_text-layer {font: inherit !important;}.ace_cjk {display: inline-block;text-align: center;}.ace_cursor-layer {z-index: 4;}.ace_cursor {z-index: 4;position: absolute;box-sizing: border-box;border-left: 2px solid;transform: translatez(0);}.ace_multiselect .ace_cursor {border-left-width: 1px;}.ace_slim-cursors .ace_cursor {border-left-width: 1px;}.ace_overwrite-cursors .ace_cursor {border-left-width: 0;border-bottom: 1px solid;}.ace_hidden-cursors .ace_cursor {opacity: 0.2;}.ace_smooth-blinking .ace_cursor {transition: opacity 0.18s;}.ace_animate-blinking .ace_cursor {animation-duration: 1000ms;animation-timing-function: step-end;animation-name: blink-ace-animate;animation-iteration-count: infinite;}.ace_animate-blinking.ace_smooth-blinking .ace_cursor {animation-duration: 1000ms;animation-timing-function: ease-in-out;animation-name: blink-ace-animate-smooth;}@keyframes blink-ace-animate {from, to { opacity: 1; }60% { opacity: 0; }}@keyframes blink-ace-animate-smooth {from, to { opacity: 1; }45% { opacity: 1; }60% { opacity: 0; }85% { opacity: 0; }}.ace_marker-layer .ace_step, .ace_marker-layer .ace_stack {position: absolute;z-index: 3;}.ace_marker-layer .ace_selection {position: absolute;z-index: 5;}.ace_marker-layer .ace_bracket {position: absolute;z-index: 6;}.ace_marker-layer .ace_active-line {position: absolute;z-index: 2;}.ace_marker-layer .ace_selected-word {position: absolute;z-index: 4;box-sizing: border-box;}.ace_line .ace_fold {box-sizing: border-box;display: inline-block;height: 11px;margin-top: -2px;vertical-align: middle;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII="),url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACJJREFUeNpi+P//fxgTAwPDBxDxD078RSX+YeEyDFMCIMAAI3INmXiwf2YAAAAASUVORK5CYII=");background-repeat: no-repeat, repeat-x;background-position: center center, top left;color: transparent;border: 1px solid black;border-radius: 2px;
16012cursor: pointer;pointer-events: auto;}.ace_dark .ace_fold {}.ace_fold:hover{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII="),url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACBJREFUeNpi+P//fz4TAwPDZxDxD5X4i5fLMEwJgAADAEPVDbjNw87ZAAAAAElFTkSuQmCC");}.ace_tooltip {background-color: #FFF;background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1));border: 1px solid gray;border-radius: 1px;box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);color: black;max-width: 100%;padding: 3px 4px;position: fixed;z-index: 999999;box-sizing: border-box;cursor: default;white-space: pre;word-wrap: break-word;line-height: normal;font-style: normal;font-weight: normal;letter-spacing: normal;pointer-events: none;}.ace_folding-enabled > .ace_gutter-cell {padding-right: 13px;}.ace_fold-widget {box-sizing: border-box;margin: 0 -12px 0 1px;display: none;width: 11px;vertical-align: top;background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42mWKsQ0AMAzC8ixLlrzQjzmBiEjp0A6WwBCSPgKAXoLkqSot7nN3yMwR7pZ32NzpKkVoDBUxKAAAAABJRU5ErkJggg==");background-repeat: no-repeat;background-position: center;border-radius: 3px;border: 1px solid transparent;cursor: pointer;}.ace_folding-enabled .ace_fold-widget {display: inline-block;   }.ace_fold-widget.ace_end {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42m3HwQkAMAhD0YzsRchFKI7sAikeWkrxwScEB0nh5e7KTPWimZki4tYfVbX+MNl4pyZXejUO1QAAAABJRU5ErkJggg==");}.ace_fold-widget.ace_closed {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAGCAYAAAAG5SQMAAAAOUlEQVR42jXKwQkAMAgDwKwqKD4EwQ26sSOkVWjgIIHAzPiCgaqiqnJHZnKICBERHN194O5b9vbLuAVRL+l0YWnZAAAAAElFTkSuQmCCXA==");}.ace_fold-widget:hover {border: 1px solid rgba(0, 0, 0, 0.3);background-color: rgba(255, 255, 255, 0.2);box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);}.ace_fold-widget:active {border: 1px solid rgba(0, 0, 0, 0.4);background-color: rgba(0, 0, 0, 0.05);box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);}.ace_dark .ace_fold-widget {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHklEQVQIW2P4//8/AzoGEQ7oGCaLLAhWiSwB146BAQCSTPYocqT0AAAAAElFTkSuQmCC");}.ace_dark .ace_fold-widget.ace_end {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAH0lEQVQIW2P4//8/AxQ7wNjIAjDMgC4AxjCVKBirIAAF0kz2rlhxpAAAAABJRU5ErkJggg==");}.ace_dark .ace_fold-widget.ace_closed {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAHElEQVQIW2P4//+/AxAzgDADlOOAznHAKgPWAwARji8UIDTfQQAAAABJRU5ErkJggg==");}.ace_dark .ace_fold-widget:hover {box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);background-color: rgba(255, 255, 255, 0.1);}.ace_dark .ace_fold-widget:active {box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);}.ace_inline_button {border: 1px solid lightgray;display: inline-block;margin: -1px 8px;padding: 0 5px;pointer-events: auto;cursor: pointer;}.ace_inline_button:hover {border-color: gray;background: rgba(200,200,200,0.2);display: inline-block;pointer-events: auto;}.ace_fold-widget.ace_invalid {background-color: #FFB4B4;border-color: #DE5555;}.ace_fade-fold-widgets .ace_fold-widget {transition: opacity 0.4s ease 0.05s;opacity: 0;}.ace_fade-fold-widgets:hover .ace_fold-widget {transition: opacity 0.05s ease 0.05s;opacity:1;}.ace_underline {text-decoration: underline;}.ace_bold {font-weight: bold;}.ace_nobold .ace_bold {font-weight: normal;}.ace_italic {font-style: italic;}.ace_error-marker {background-color: rgba(255, 0, 0,0.2);position: absolute;z-index: 9;}.ace_highlight-marker {background-color: rgba(255, 255, 0,0.2);position: absolute;z-index: 8;}.ace_br1 {border-top-left-radius    : 3px;}.ace_br2 {border-top-right-radius   : 3px;}.ace_br3 {border-top-left-radius    : 3px; border-top-right-radius:    3px;}.ace_br4 {border-bottom-right-radius: 3px;}.ace_br5 {border-top-left-radius    : 3px; border-bottom-right-radius: 3px;}.ace_br6 {border-top-right-radius   : 3px; border-bottom-right-radius: 3px;}.ace_br7 {border-top-left-radius    : 3px; border-top-right-radius:    3px; border-bottom-right-radius: 3px;}.ace_br8 {border-bottom-left-radius : 3px;}.ace_br9 {border-top-left-radius    : 3px; border-bottom-left-radius:  3px;}.ace_br10{border-top-right-radius   : 3px; border-bottom-left-radius:  3px;}.ace_br11{border-top-left-radius    : 3px; border-top-right-radius:    3px; border-bottom-left-radius:  3px;}.ace_br12{border-bottom-right-radius: 3px; border-bottom-left-radius:  3px;}.ace_br13{border-top-left-radius    : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius:  3px;}.ace_br14{border-top-right-radius   : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius:  3px;}.ace_br15{border-top-left-radius    : 3px; border-top-right-radius:    3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_text-input-ios {position: absolute !important;top: -100000px !important;left: -100000px !important;}'
16013    i.importCssString(m, 'ace_editor.css')
16014    var g = function(e, t) {
16015      var n = this
16016      ;(this.container = e || i.createElement('div')),
16017        i.addCssClass(this.container, 'ace_editor'),
16018        this.setTheme(t),
16019        (this.$gutter = i.createElement('div')),
16020        (this.$gutter.className = 'ace_gutter'),
16021        this.container.appendChild(this.$gutter),
16022        this.$gutter.setAttribute('aria-hidden', !0),
16023        (this.scroller = i.createElement('div')),
16024        (this.scroller.className = 'ace_scroller'),
16025        this.container.appendChild(this.scroller),
16026        (this.content = i.createElement('div')),
16027        (this.content.className = 'ace_content'),
16028        this.scroller.appendChild(this.content),
16029        (this.$gutterLayer = new u(this.$gutter)),
16030        this.$gutterLayer.on('changeGutterWidth', this.onGutterResize.bind(this)),
16031        (this.$markerBack = new a(this.content))
16032      var r = (this.$textLayer = new f(this.content))
16033      ;(this.canvas = r.element),
16034        (this.$markerFront = new a(this.content)),
16035        (this.$cursorLayer = new l(this.content)),
16036        (this.$horizScroll = !1),
16037        (this.$vScroll = !1),
16038        (this.scrollBar = this.scrollBarV = new h(this.container, this)),
16039        (this.scrollBarH = new c(this.container, this)),
16040        this.scrollBarV.addEventListener('scroll', function(e) {
16041          n.$scrollAnimation || n.session.setScrollTop(e.data - n.scrollMargin.top)
16042        }),
16043        this.scrollBarH.addEventListener('scroll', function(e) {
16044          n.$scrollAnimation || n.session.setScrollLeft(e.data - n.scrollMargin.left)
16045        }),
16046        (this.scrollTop = 0),
16047        (this.scrollLeft = 0),
16048        (this.cursorPos = { row: 0, column: 0 }),
16049        (this.$fontMetrics = new d(this.container)),
16050        this.$textLayer.$setFontMetrics(this.$fontMetrics),
16051        this.$textLayer.addEventListener('changeCharacterSize', function(e) {
16052          n.updateCharacterSize(),
16053            n.onResize(!0, n.gutterWidth, n.$size.width, n.$size.height),
16054            n._signal('changeCharacterSize', e)
16055        }),
16056        (this.$size = { width: 0, height: 0, scrollerHeight: 0, scrollerWidth: 0, $dirty: !0 }),
16057        (this.layerConfig = {
16058          width: 1,
16059          padding: 0,
16060          firstRow: 0,
16061          firstRowScreen: 0,
16062          lastRow: 0,
16063          lineHeight: 0,
16064          characterWidth: 0,
16065          minHeight: 1,
16066          maxHeight: 1,
16067          offset: 0,
16068          height: 1,
16069          gutterOffset: 1
16070        }),
16071        (this.scrollMargin = { left: 0, right: 0, top: 0, bottom: 0, v: 0, h: 0 }),
16072        (this.$loop = new p(this.$renderChanges.bind(this), this.container.ownerDocument.defaultView)),
16073        this.$loop.schedule(this.CHANGE_FULL),
16074        this.updateCharacterSize(),
16075        this.setPadding(4),
16076        s.resetOptions(this),
16077        s._emit('renderer', this)
16078    }
16079    ;(function() {
16080      ;(this.CHANGE_CURSOR = 1),
16081        (this.CHANGE_MARKER = 2),
16082        (this.CHANGE_GUTTER = 4),
16083        (this.CHANGE_SCROLL = 8),
16084        (this.CHANGE_LINES = 16),
16085        (this.CHANGE_TEXT = 32),
16086        (this.CHANGE_SIZE = 64),
16087        (this.CHANGE_MARKER_BACK = 128),
16088        (this.CHANGE_MARKER_FRONT = 256),
16089        (this.CHANGE_FULL = 512),
16090        (this.CHANGE_H_SCROLL = 1024),
16091        r.implement(this, v),
16092        (this.updateCharacterSize = function() {
16093          this.$textLayer.allowBoldFonts != this.$allowBoldFonts &&
16094            ((this.$allowBoldFonts = this.$textLayer.allowBoldFonts),
16095            this.setStyle('ace_nobold', !this.$allowBoldFonts)),
16096            (this.layerConfig.characterWidth = this.characterWidth = this.$textLayer.getCharacterWidth()),
16097            (this.layerConfig.lineHeight = this.lineHeight = this.$textLayer.getLineHeight()),
16098            this.$updatePrintMargin()
16099        }),
16100        (this.setSession = function(e) {
16101          this.session && this.session.doc.off('changeNewLineMode', this.onChangeNewLineMode),
16102            (this.session = e),
16103            e && this.scrollMargin.top && e.getScrollTop() <= 0 && e.setScrollTop(-this.scrollMargin.top),
16104            this.$cursorLayer.setSession(e),
16105            this.$markerBack.setSession(e),
16106            this.$markerFront.setSession(e),
16107            this.$gutterLayer.setSession(e),
16108            this.$textLayer.setSession(e)
16109          if (!e) return
16110          this.$loop.schedule(this.CHANGE_FULL),
16111            this.session.$setFontMetrics(this.$fontMetrics),
16112            (this.scrollBarH.scrollLeft = this.scrollBarV.scrollTop = null),
16113            (this.onChangeNewLineMode = this.onChangeNewLineMode.bind(this)),
16114            this.onChangeNewLineMode(),
16115            this.session.doc.on('changeNewLineMode', this.onChangeNewLineMode)
16116        }),
16117        (this.updateLines = function(e, t, n) {
16118          t === undefined && (t = Infinity),
16119            this.$changedLines
16120              ? (this.$changedLines.firstRow > e && (this.$changedLines.firstRow = e),
16121                this.$changedLines.lastRow < t && (this.$changedLines.lastRow = t))
16122              : (this.$changedLines = { firstRow: e, lastRow: t })
16123          if (this.$changedLines.lastRow < this.layerConfig.firstRow) {
16124            if (!n) return
16125            this.$changedLines.lastRow = this.layerConfig.lastRow
16126          }
16127          if (this.$changedLines.firstRow > this.layerConfig.lastRow) return
16128          this.$loop.schedule(this.CHANGE_LINES)
16129        }),
16130        (this.onChangeNewLineMode = function() {
16131          this.$loop.schedule(this.CHANGE_TEXT),
16132            this.$textLayer.$updateEolChar(),
16133            this.session.$bidiHandler.setEolChar(this.$textLayer.EOL_CHAR)
16134        }),
16135        (this.onChangeTabSize = function() {
16136          this.$loop.schedule(this.CHANGE_TEXT | this.CHANGE_MARKER), this.$textLayer.onChangeTabSize()
16137        }),
16138        (this.updateText = function() {
16139          this.$loop.schedule(this.CHANGE_TEXT)
16140        }),
16141        (this.updateFull = function(e) {
16142          e ? this.$renderChanges(this.CHANGE_FULL, !0) : this.$loop.schedule(this.CHANGE_FULL)
16143        }),
16144        (this.updateFontSize = function() {
16145          this.$textLayer.checkForSizeChanges()
16146        }),
16147        (this.$changes = 0),
16148        (this.$updateSizeAsync = function() {
16149          this.$loop.pending ? (this.$size.$dirty = !0) : this.onResize()
16150        }),
16151        (this.onResize = function(e, t, n, r) {
16152          if (this.resizing > 2) return
16153          this.resizing > 0 ? this.resizing++ : (this.resizing = e ? 1 : 0)
16154          var i = this.container
16155          r || (r = i.clientHeight || i.scrollHeight), n || (n = i.clientWidth || i.scrollWidth)
16156          var s = this.$updateCachedSize(e, t, n, r)
16157          if (!this.$size.scrollerHeight || (!n && !r)) return (this.resizing = 0)
16158          e && (this.$gutterLayer.$padding = null),
16159            e ? this.$renderChanges(s | this.$changes, !0) : this.$loop.schedule(s | this.$changes),
16160            this.resizing && (this.resizing = 0),
16161            (this.scrollBarV.scrollLeft = this.scrollBarV.scrollTop = null)
16162        }),
16163        (this.$updateCachedSize = function(e, t, n, r) {
16164          r -= this.$extraHeight || 0
16165          var i = 0,
16166            s = this.$size,
16167            o = { width: s.width, height: s.height, scrollerHeight: s.scrollerHeight, scrollerWidth: s.scrollerWidth }
16168          r &&
16169            (e || s.height != r) &&
16170            ((s.height = r),
16171            (i |= this.CHANGE_SIZE),
16172            (s.scrollerHeight = s.height),
16173            this.$horizScroll && (s.scrollerHeight -= this.scrollBarH.getHeight()),
16174            (this.scrollBarV.element.style.bottom = this.scrollBarH.getHeight() + 'px'),
16175            (i |= this.CHANGE_SCROLL))
16176          if (n && (e || s.width != n)) {
16177            ;(i |= this.CHANGE_SIZE),
16178              (s.width = n),
16179              t == null && (t = this.$showGutter ? this.$gutter.offsetWidth : 0),
16180              (this.gutterWidth = t),
16181              (this.scrollBarH.element.style.left = this.scroller.style.left = t + 'px'),
16182              (s.scrollerWidth = Math.max(0, n - t - this.scrollBarV.getWidth())),
16183              (this.scrollBarH.element.style.right = this.scroller.style.right = this.scrollBarV.getWidth() + 'px'),
16184              (this.scroller.style.bottom = this.scrollBarH.getHeight() + 'px')
16185            if ((this.session && this.session.getUseWrapMode() && this.adjustWrapLimit()) || e) i |= this.CHANGE_FULL
16186          }
16187          return (s.$dirty = !n || !r), i && this._signal('resize', o), i
16188        }),
16189        (this.onGutterResize = function() {
16190          var e = this.$showGutter ? this.$gutter.offsetWidth : 0
16191          e != this.gutterWidth &&
16192            (this.$changes |= this.$updateCachedSize(!0, e, this.$size.width, this.$size.height)),
16193            this.session.getUseWrapMode() && this.adjustWrapLimit()
16194              ? this.$loop.schedule(this.CHANGE_FULL)
16195              : this.$size.$dirty
16196              ? this.$loop.schedule(this.CHANGE_FULL)
16197              : (this.$computeLayerConfig(), this.$loop.schedule(this.CHANGE_MARKER))
16198        }),
16199        (this.adjustWrapLimit = function() {
16200          var e = this.$size.scrollerWidth - this.$padding * 2,
16201            t = Math.floor(e / this.characterWidth)
16202          return this.session.adjustWrapLimit(t, this.$showPrintMargin && this.$printMarginColumn)
16203        }),
16204        (this.setAnimatedScroll = function(e) {
16205          this.setOption('animatedScroll', e)
16206        }),
16207        (this.getAnimatedScroll = function() {
16208          return this.$animatedScroll
16209        }),
16210        (this.setShowInvisibles = function(e) {
16211          this.setOption('showInvisibles', e), this.session.$bidiHandler.setShowInvisibles(e)
16212        }),
16213        (this.getShowInvisibles = function() {
16214          return this.getOption('showInvisibles')
16215        }),
16216        (this.getDisplayIndentGuides = function() {
16217          return this.getOption('displayIndentGuides')
16218        }),
16219        (this.setDisplayIndentGuides = function(e) {
16220          this.setOption('displayIndentGuides', e)
16221        }),
16222        (this.setShowPrintMargin = function(e) {
16223          this.setOption('showPrintMargin', e)
16224        }),
16225        (this.getShowPrintMargin = function() {
16226          return this.getOption('showPrintMargin')
16227        }),
16228        (this.setPrintMarginColumn = function(e) {
16229          this.setOption('printMarginColumn', e)
16230        }),
16231        (this.getPrintMarginColumn = function() {
16232          return this.getOption('printMarginColumn')
16233        }),
16234        (this.getShowGutter = function() {
16235          return this.getOption('showGutter')
16236        }),
16237        (this.setShowGutter = function(e) {
16238          return this.setOption('showGutter', e)
16239        }),
16240        (this.getFadeFoldWidgets = function() {
16241          return this.getOption('fadeFoldWidgets')
16242        }),
16243        (this.setFadeFoldWidgets = function(e) {
16244          this.setOption('fadeFoldWidgets', e)
16245        }),
16246        (this.setHighlightGutterLine = function(e) {
16247          this.setOption('highlightGutterLine', e)
16248        }),
16249        (this.getHighlightGutterLine = function() {
16250          return this.getOption('highlightGutterLine')
16251        }),
16252        (this.$updateGutterLineHighlight = function() {
16253          var e = this.$cursorLayer.$pixelPos,
16254            t = this.layerConfig.lineHeight
16255          if (this.session.getUseWrapMode()) {
16256            var n = this.session.selection.getCursor()
16257            ;(n.column = 0), (e = this.$cursorLayer.getPixelPosition(n, !0)), (t *= this.session.getRowLength(n.row))
16258          }
16259          ;(this.$gutterLineHighlight.style.top = e.top - this.layerConfig.offset + 'px'),
16260            (this.$gutterLineHighlight.style.height = t + 'px')
16261        }),
16262        (this.$updatePrintMargin = function() {
16263          if (!this.$showPrintMargin && !this.$printMarginEl) return
16264          if (!this.$printMarginEl) {
16265            var e = i.createElement('div')
16266            ;(e.className = 'ace_layer ace_print-margin-layer'),
16267              (this.$printMarginEl = i.createElement('div')),
16268              (this.$printMarginEl.className = 'ace_print-margin'),
16269              e.appendChild(this.$printMarginEl),
16270              this.content.insertBefore(e, this.content.firstChild)
16271          }
16272          var t = this.$printMarginEl.style
16273          ;(t.left = Math.round(this.characterWidth * this.$printMarginColumn + this.$padding) + 'px'),
16274            (t.visibility = this.$showPrintMargin ? 'visible' : 'hidden'),
16275            this.session && this.session.$wrap == -1 && this.adjustWrapLimit()
16276        }),
16277        (this.getContainerElement = function() {
16278          return this.container
16279        }),
16280        (this.getMouseEventTarget = function() {
16281          return this.scroller
16282        }),
16283        (this.getTextAreaContainer = function() {
16284          return this.container
16285        }),
16286        (this.$moveTextAreaToCursor = function() {
16287          var e = this.textarea.style
16288          if (!this.$keepTextAreaAtCursor) {
16289            e.left = '-100px'
16290            return
16291          }
16292          var t = this.layerConfig,
16293            n = this.$cursorLayer.$pixelPos.top,
16294            r = this.$cursorLayer.$pixelPos.left
16295          n -= t.offset
16296          var i = this.lineHeight
16297          if (n < 0 || n > t.height - i) {
16298            e.top = e.left = '0'
16299            return
16300          }
16301          var s = this.characterWidth
16302          if (this.$composition) {
16303            var o = this.textarea.value.replace(/^\x01+/, '')
16304            ;(s *= this.session.$getStringScreenWidth(o)[0] + 2), (i += 2)
16305          }
16306          ;(r -= this.scrollLeft),
16307            r > this.$size.scrollerWidth - s && (r = this.$size.scrollerWidth - s),
16308            (r += this.gutterWidth),
16309            (e.height = i + 'px'),
16310            (e.width = s + 'px'),
16311            (e.left = Math.min(r, this.$size.scrollerWidth - s) + 'px'),
16312            (e.top = Math.min(n, this.$size.height - i) + 'px')
16313        }),
16314        (this.getFirstVisibleRow = function() {
16315          return this.layerConfig.firstRow
16316        }),
16317        (this.getFirstFullyVisibleRow = function() {
16318          return this.layerConfig.firstRow + (this.layerConfig.offset === 0 ? 0 : 1)
16319        }),
16320        (this.getLastFullyVisibleRow = function() {
16321          var e = this.layerConfig,
16322            t = e.lastRow,
16323            n = this.session.documentToScreenRow(t, 0) * e.lineHeight
16324          return n - this.session.getScrollTop() > e.height - e.lineHeight ? t - 1 : t
16325        }),
16326        (this.getLastVisibleRow = function() {
16327          return this.layerConfig.lastRow
16328        }),
16329        (this.$padding = null),
16330        (this.setPadding = function(e) {
16331          ;(this.$padding = e),
16332            this.$textLayer.setPadding(e),
16333            this.$cursorLayer.setPadding(e),
16334            this.$markerFront.setPadding(e),
16335            this.$markerBack.setPadding(e),
16336            this.$loop.schedule(this.CHANGE_FULL),
16337            this.$updatePrintMargin()
16338        }),
16339        (this.setScrollMargin = function(e, t, n, r) {
16340          var i = this.scrollMargin
16341          ;(i.top = e | 0),
16342            (i.bottom = t | 0),
16343            (i.right = r | 0),
16344            (i.left = n | 0),
16345            (i.v = i.top + i.bottom),
16346            (i.h = i.left + i.right),
16347            i.top && this.scrollTop <= 0 && this.session && this.session.setScrollTop(-i.top),
16348            this.updateFull()
16349        }),
16350        (this.getHScrollBarAlwaysVisible = function() {
16351          return this.$hScrollBarAlwaysVisible
16352        }),
16353        (this.setHScrollBarAlwaysVisible = function(e) {
16354          this.setOption('hScrollBarAlwaysVisible', e)
16355        }),
16356        (this.getVScrollBarAlwaysVisible = function() {
16357          return this.$vScrollBarAlwaysVisible
16358        }),
16359        (this.setVScrollBarAlwaysVisible = function(e) {
16360          this.setOption('vScrollBarAlwaysVisible', e)
16361        }),
16362        (this.$updateScrollBarV = function() {
16363          var e = this.layerConfig.maxHeight,
16364            t = this.$size.scrollerHeight
16365          !this.$maxLines &&
16366            this.$scrollPastEnd &&
16367            ((e -= (t - this.lineHeight) * this.$scrollPastEnd),
16368            this.scrollTop > e - t && ((e = this.scrollTop + t), (this.scrollBarV.scrollTop = null))),
16369            this.scrollBarV.setScrollHeight(e + this.scrollMargin.v),
16370            this.scrollBarV.setScrollTop(this.scrollTop + this.scrollMargin.top)
16371        }),
16372        (this.$updateScrollBarH = function() {
16373          this.scrollBarH.setScrollWidth(this.layerConfig.width + 2 * this.$padding + this.scrollMargin.h),
16374            this.scrollBarH.setScrollLeft(this.scrollLeft + this.scrollMargin.left)
16375        }),
16376        (this.$frozen = !1),
16377        (this.freeze = function() {
16378          this.$frozen = !0
16379        }),
16380        (this.unfreeze = function() {
16381          this.$frozen = !1
16382        }),
16383        (this.$renderChanges = function(e, t) {
16384          this.$changes && ((e |= this.$changes), (this.$changes = 0))
16385          if (!this.session || !this.container.offsetWidth || this.$frozen || (!e && !t)) {
16386            this.$changes |= e
16387            return
16388          }
16389          if (this.$size.$dirty) return (this.$changes |= e), this.onResize(!0)
16390          this.lineHeight || this.$textLayer.checkForSizeChanges(),
16391            this._signal('beforeRender'),
16392            this.session &&
16393              this.session.$bidiHandler &&
16394              this.session.$bidiHandler.updateCharacterWidths(this.$fontMetrics)
16395          var n = this.layerConfig
16396          if (
16397            e & this.CHANGE_FULL ||
16398            e & this.CHANGE_SIZE ||
16399            e & this.CHANGE_TEXT ||
16400            e & this.CHANGE_LINES ||
16401            e & this.CHANGE_SCROLL ||
16402            e & this.CHANGE_H_SCROLL
16403          ) {
16404            e |= this.$computeLayerConfig()
16405            if (n.firstRow != this.layerConfig.firstRow && n.firstRowScreen == this.layerConfig.firstRowScreen) {
16406              var r = this.scrollTop + (n.firstRow - this.layerConfig.firstRow) * this.lineHeight
16407              r > 0 && ((this.scrollTop = r), (e |= this.CHANGE_SCROLL), (e |= this.$computeLayerConfig()))
16408            }
16409            ;(n = this.layerConfig),
16410              this.$updateScrollBarV(),
16411              e & this.CHANGE_H_SCROLL && this.$updateScrollBarH(),
16412              (this.$gutterLayer.element.style.marginTop = -n.offset + 'px'),
16413              (this.content.style.marginTop = -n.offset + 'px'),
16414              (this.content.style.width = n.width + 2 * this.$padding + 'px'),
16415              (this.content.style.height = n.minHeight + 'px')
16416          }
16417          e & this.CHANGE_H_SCROLL &&
16418            ((this.content.style.marginLeft = -this.scrollLeft + 'px'),
16419            (this.scroller.className = this.scrollLeft <= 0 ? 'ace_scroller' : 'ace_scroller ace_scroll-left'))
16420          if (e & this.CHANGE_FULL) {
16421            this.$textLayer.update(n),
16422              this.$showGutter && this.$gutterLayer.update(n),
16423              this.$markerBack.update(n),
16424              this.$markerFront.update(n),
16425              this.$cursorLayer.update(n),
16426              this.$moveTextAreaToCursor(),
16427              this.$highlightGutterLine && this.$updateGutterLineHighlight(),
16428              this._signal('afterRender')
16429            return
16430          }
16431          if (e & this.CHANGE_SCROLL) {
16432            e & this.CHANGE_TEXT || e & this.CHANGE_LINES ? this.$textLayer.update(n) : this.$textLayer.scrollLines(n),
16433              this.$showGutter && this.$gutterLayer.update(n),
16434              this.$markerBack.update(n),
16435              this.$markerFront.update(n),
16436              this.$cursorLayer.update(n),
16437              this.$highlightGutterLine && this.$updateGutterLineHighlight(),
16438              this.$moveTextAreaToCursor(),
16439              this._signal('afterRender')
16440            return
16441          }
16442          e & this.CHANGE_TEXT
16443            ? (this.$textLayer.update(n), this.$showGutter && this.$gutterLayer.update(n))
16444            : e & this.CHANGE_LINES
16445            ? (this.$updateLines() || (e & this.CHANGE_GUTTER && this.$showGutter)) && this.$gutterLayer.update(n)
16446            : (e & this.CHANGE_TEXT || e & this.CHANGE_GUTTER) && this.$showGutter && this.$gutterLayer.update(n),
16447            e & this.CHANGE_CURSOR &&
16448              (this.$cursorLayer.update(n),
16449              this.$moveTextAreaToCursor(),
16450              this.$highlightGutterLine && this.$updateGutterLineHighlight()),
16451            e & (this.CHANGE_MARKER | this.CHANGE_MARKER_FRONT) && this.$markerFront.update(n),
16452            e & (this.CHANGE_MARKER | this.CHANGE_MARKER_BACK) && this.$markerBack.update(n),
16453            this._signal('afterRender')
16454        }),
16455        (this.$autosize = function() {
16456          var e = this.session.getScreenLength() * this.lineHeight,
16457            t = this.$maxLines * this.lineHeight,
16458            n =
16459              Math.min(t, Math.max((this.$minLines || 1) * this.lineHeight, e)) +
16460              this.scrollMargin.v +
16461              (this.$extraHeight || 0)
16462          this.$horizScroll && (n += this.scrollBarH.getHeight()),
16463            this.$maxPixelHeight && n > this.$maxPixelHeight && (n = this.$maxPixelHeight)
16464          var r = n <= 2 * this.lineHeight,
16465            i = !r && e > t
16466          if (n != this.desiredHeight || this.$size.height != this.desiredHeight || i != this.$vScroll) {
16467            i != this.$vScroll && ((this.$vScroll = i), this.scrollBarV.setVisible(i))
16468            var s = this.container.clientWidth
16469            ;(this.container.style.height = n + 'px'),
16470              this.$updateCachedSize(!0, this.$gutterWidth, s, n),
16471              (this.desiredHeight = n),
16472              this._signal('autosize')
16473          }
16474        }),
16475        (this.$computeLayerConfig = function() {
16476          var e = this.session,
16477            t = this.$size,
16478            n = t.height <= 2 * this.lineHeight,
16479            r = this.session.getScreenLength(),
16480            i = r * this.lineHeight,
16481            s = this.$getLongestLine(),
16482            o = !n && (this.$hScrollBarAlwaysVisible || t.scrollerWidth - s - 2 * this.$padding < 0),
16483            u = this.$horizScroll !== o
16484          u && ((this.$horizScroll = o), this.scrollBarH.setVisible(o))
16485          var a = this.$vScroll
16486          this.$maxLines && this.lineHeight > 1 && this.$autosize()
16487          var f = this.scrollTop % this.lineHeight,
16488            l = t.scrollerHeight + this.lineHeight,
16489            c = !this.$maxLines && this.$scrollPastEnd ? (t.scrollerHeight - this.lineHeight) * this.$scrollPastEnd : 0
16490          i += c
16491          var h = this.scrollMargin
16492          this.session.setScrollTop(Math.max(-h.top, Math.min(this.scrollTop, i - t.scrollerHeight + h.bottom))),
16493            this.session.setScrollLeft(
16494              Math.max(-h.left, Math.min(this.scrollLeft, s + 2 * this.$padding - t.scrollerWidth + h.right))
16495            )
16496          var p = !n && (this.$vScrollBarAlwaysVisible || t.scrollerHeight - i + c < 0 || this.scrollTop > h.top),
16497            d = a !== p
16498          d && ((this.$vScroll = p), this.scrollBarV.setVisible(p))
16499          var v = Math.ceil(l / this.lineHeight) - 1,
16500            m = Math.max(0, Math.round((this.scrollTop - f) / this.lineHeight)),
16501            g = m + v,
16502            y,
16503            b,
16504            w = this.lineHeight
16505          m = e.screenToDocumentRow(m, 0)
16506          var E = e.getFoldLine(m)
16507          E && (m = E.start.row),
16508            (y = e.documentToScreenRow(m, 0)),
16509            (b = e.getRowLength(m) * w),
16510            (g = Math.min(e.screenToDocumentRow(g, 0), e.getLength() - 1)),
16511            (l = t.scrollerHeight + e.getRowLength(g) * w + b),
16512            (f = this.scrollTop - y * w)
16513          var S = 0
16514          if (this.layerConfig.width != s || u) S = this.CHANGE_H_SCROLL
16515          if (u || d)
16516            (S = this.$updateCachedSize(!0, this.gutterWidth, t.width, t.height)),
16517              this._signal('scrollbarVisibilityChanged'),
16518              d && (s = this.$getLongestLine())
16519          return (
16520            (this.layerConfig = {
16521              width: s,
16522              padding: this.$padding,
16523              firstRow: m,
16524              firstRowScreen: y,
16525              lastRow: g,
16526              lineHeight: w,
16527              characterWidth: this.characterWidth,
16528              minHeight: l,
16529              maxHeight: i,
16530              offset: f,
16531              gutterOffset: w ? Math.max(0, Math.ceil((f + t.height - t.scrollerHeight) / w)) : 0,
16532              height: this.$size.scrollerHeight
16533            }),
16534            S
16535          )
16536        }),
16537        (this.$updateLines = function() {
16538          if (!this.$changedLines) return
16539          var e = this.$changedLines.firstRow,
16540            t = this.$changedLines.lastRow
16541          this.$changedLines = null
16542          var n = this.layerConfig
16543          if (e > n.lastRow + 1) return
16544          if (t < n.firstRow) return
16545          if (t === Infinity) {
16546            this.$showGutter && this.$gutterLayer.update(n), this.$textLayer.update(n)
16547            return
16548          }
16549          return this.$textLayer.updateLines(n, e, t), !0
16550        }),
16551        (this.$getLongestLine = function() {
16552          var e = this.session.getScreenWidth()
16553          return (
16554            this.showInvisibles && !this.session.$useWrapMode && (e += 1),
16555            this.$textLayer && e > this.$textLayer.MAX_LINE_LENGTH && (e = this.$textLayer.MAX_LINE_LENGTH + 3
165550),
16556            Math.max(this.$size.scrollerWidth - 2 * this.$padding, Math.round(e * this.characterWidth))
16557          )
16558        }),
16559        (this.updateFrontMarkers = function() {
16560          this.$markerFront.setMarkers(this.session.getMarkers(!0)), this.$loop.schedule(this.CHANGE_MARKER_FRONT)
16561        }),
16562        (this.updateBackMarkers = function() {
16563          this.$markerBack.setMarkers(this.session.getMarkers()), this.$loop.schedule(this.CHANGE_MARKER_BACK)
16564        }),
16565        (this.addGutterDecoration = function(e, t) {
16566          this.$gutterLayer.addGutterDecoration(e, t)
16567        }),
16568        (this.removeGutterDecoration = function(e, t) {
16569          this.$gutterLayer.removeGutterDecoration(e, t)
16570        }),
16571        (this.updateBreakpoints = function(e) {
16572          this.$loop.schedule(this.CHANGE_GUTTER)
16573        }),
16574        (this.setAnnotations = function(e) {
16575          this.$gutterLayer.setAnnotations(e), this.$loop.schedule(this.CHANGE_GUTTER)
16576        }),
16577        (this.updateCursor = function() {
16578          this.$loop.schedule(this.CHANGE_CURSOR)
16579        }),
16580        (this.hideCursor = function() {
16581          this.$cursorLayer.hideCursor()
16582        }),
16583        (this.showCursor = function() {
16584          this.$cursorLayer.showCursor()
16585        }),
16586        (this.scrollSelectionIntoView = function(e, t, n) {
16587          this.scrollCursorIntoView(e, n), this.scrollCursorIntoView(t, n)
16588        }),
16589        (this.scrollCursorIntoView = function(e, t, n) {
16590          if (this.$size.scrollerHeight === 0) return
16591          var r = this.$cursorLayer.getPixelPosition(e),
16592            i = r.left,
16593            s = r.top,
16594            o = (n && n.top) || 0,
16595            u = (n && n.bottom) || 0,
16596            a = this.$scrollAnimation ? this.session.getScrollTop() : this.scrollTop
16597          a + o > s
16598            ? (t && a + o > s + this.lineHeight && (s -= t * this.$size.scrollerHeight),
16599              s === 0 && (s = -this.scrollMargin.top),
16600              this.session.setScrollTop(s))
16601            : a + this.$size.scrollerHeight - u < s + this.lineHeight &&
16602              (t && a + this.$size.scrollerHeight - u < s - this.lineHeight && (s += t * this.$size.scrollerHeight),
16603              this.session.setScrollTop(s + this.lineHeight - this.$size.scrollerHeight))
16604          var f = this.scrollLeft
16605          f > i
16606            ? (i < this.$padding + 2 * this.layerConfig.characterWidth && (i = -this.scrollMargin.left),
16607              this.session.setScrollLeft(i))
16608            : f + this.$size.scrollerWidth < i + this.characterWidth
16609            ? this.session.setScrollLeft(Math.round(i + this.characterWidth - this.$size.scrollerWidth))
16610            : f <= this.$padding && i - f < this.characterWidth && this.session.setScrollLeft(0)
16611        }),
16612        (this.getScrollTop = function() {
16613          return this.session.getScrollTop()
16614        }),
16615        (this.getScrollLeft = function() {
16616          return this.session.getScrollLeft()
16617        }),
16618        (this.getScrollTopRow = function() {
16619          return this.scrollTop / this.lineHeight
16620        }),
16621        (this.getScrollBottomRow = function() {
16622          return Math.max(0, Math.floor((this.scrollTop + this.$size.scrollerHeight) / this.lineHeight) - 1)
16623        }),
16624        (this.scrollToRow = function(e) {
16625          this.session.setScrollTop(e * this.lineHeight)
16626        }),
16627        (this.alignCursor = function(e, t) {
16628          typeof e == 'number' && (e = { row: e, column: 0 })
16629          var n = this.$cursorLayer.getPixelPosition(e),
16630            r = this.$size.scrollerHeight - this.lineHeight,
16631            i = n.top - r * (t || 0)
16632          return this.session.setScrollTop(i), i
16633        }),
16634        (this.STEPS = 8),
16635        (this.$calcSteps = function(e, t) {
16636          var n = 0,
16637            r = this.STEPS,
16638            i = [],
16639            s = function(e, t, n) {
16640              return n * (Math.pow(e - 1, 3) + 1) + t
16641            }
16642          for (n = 0; n < r; ++n) i.push(s(n / this.STEPS, e, t - e))
16643          return i
16644        }),
16645        (this.scrollToLine = function(e, t, n, r) {
16646          var i = this.$cursorLayer.getPixelPosition({ row: e, column: 0 }),
16647            s = i.top
16648          t && (s -= this.$size.scrollerHeight / 2)
16649          var o = this.scrollTop
16650          this.session.setScrollTop(s), n !== !1 && this.animateScrolling(o, r)
16651        }),
16652        (this.animateScrolling = function(e, t) {
16653          var n = this.scrollTop
16654          if (!this.$animatedScroll) return
16655          var r = this
16656          if (e == n) return
16657          if (this.$scrollAnimation) {
16658            var i = this.$scrollAnimation.steps
16659            if (i.length) {
16660              e = i[0]
16661              if (e == n) return
16662            }
16663          }
16664          var s = r.$calcSteps(e, n)
16665          ;(this.$scrollAnimation = { from: e, to: n, steps: s }),
16666            clearInterval(this.$timer),
16667            r.session.setScrollTop(s.shift()),
16668            (r.session.$scrollTop = n),
16669            (this.$timer = setInterval(function() {
16670              s.length
16671                ? (r.session.setScrollTop(s.shift()), (r.session.$scrollTop = n))
16672                : n != null
16673                ? ((r.session.$scrollTop = -1), r.session.setScrollTop(n), (n = null))
16674                : ((r.$timer = clearInterval(r.$timer)), (r.$scrollAnimation = null), t && t())
16675            }, 10))
16676        }),
16677        (this.scrollToY = function(e) {
16678          this.scrollTop !== e && (this.$loop.schedule(this.CHANGE_SCROLL), (this.scrollTop = e))
16679        }),
16680        (this.scrollToX = function(e) {
16681          this.scrollLeft !== e && (this.scrollLeft = e), this.$loop.schedule(this.CHANGE_H_SCROLL)
16682        }),
16683        (this.scrollTo = function(e, t) {
16684          this.session.setScrollTop(t), this.session.setScrollLeft(t)
16685        }),
16686        (this.scrollBy = function(e, t) {
16687          t && this.session.setScrollTop(this.session.getScrollTop() + t),
16688            e && this.session.setScrollLeft(this.session.getScrollLeft() + e)
16689        }),
16690        (this.isScrollableBy = function(e, t) {
16691          if (t < 0 && this.session.getScrollTop() >= 1 - this.scrollMargin.top) return !0
16692          if (
16693            t > 0 &&
16694            this.session.getScrollTop() + this.$size.scrollerHeight - this.layerConfig.maxHeight <
16695              -1 + this.scrollMargin.bottom
16696          )
16697            return !0
16698          if (e < 0 && this.session.getScrollLeft() >= 1 - this.scrollMargin.left) return !0
16699          if (
16700            e > 0 &&
16701            this.session.getScrollLeft() + this.$size.scrollerWidth - this.layerConfig.width <
16702              -1 + this.scrollMargin.right
16703          )
16704            return !0
16705        }),
16706        (this.pixelToScreenCoordinates = function(e, t) {
16707          var n
16708          if (this.$hasCssTransforms) {
16709            n = { top: 0, left: 0 }
16710            var r = this.$fontMetrics.transformCoordinates([e, t])
16711            ;(e = r[1] - this.gutterWidth), (t = r[0])
16712          } else n = this.scroller.getBoundingClientRect()
16713          var i = e + this.scrollLeft - n.left - this.$padding,
16714            s = i / this.characterWidth,
16715            o = Math.floor((t + this.scrollTop - n.top) / this.lineHeight),
16716            u = this.$blockCursor ? Math.floor(s) : Math.round(s)
16717          return { row: o, column: u, side: s - u > 0 ? 1 : -1, offsetX: i }
16718        }),
16719        (this.screenToTextCoordinates = function(e, t) {
16720          var n
16721          if (this.$hasCssTransforms) {
16722            n = { top: 0, left: 0 }
16723            var r = this.$fontMetrics.transformCoordinates([e, t])
16724            ;(e = r[1] - this.gutterWidth), (t = r[0])
16725          } else n = this.scroller.getBoundingClientRect()
16726          var i = e + this.scrollLeft - n.left - this.$padding,
16727            s = i / this.characterWidth,
16728            o = this.$blockCursor ? Math.floor(s) : Math.round(s),
16729            u = (t + this.scrollTop - n.top) / this.lineHeight
16730          return this.session.screenToDocumentPosition(u, Math.max(o, 0), i)
16731        }),
16732        (this.textToScreenCoordinates = function(e, t) {
16733          var n = this.scroller.getBoundingClientRect(),
16734            r = this.session.documentToScreenPosition(e, t),
16735            i =
16736              this.$padding +
16737              (this.session.$bidiHandler.isBidiRow(r.row, e)
16738                ? this.session.$bidiHandler.getPosLeft(r.column)
16739                : Math.round(r.column * this.characterWidth)),
16740            s = r.row * this.lineHeight
16741          return { pageX: n.left + i - this.scrollLeft, pageY: n.top + s - this.scrollTop }
16742        }),
16743        (this.visualizeFocus = function() {
16744          i.addCssClass(this.container, 'ace_focus')
16745        }),
16746        (this.visualizeBlur = function() {
16747          i.removeCssClass(this.container, 'ace_focus')
16748        }),
16749        (this.showComposition = function(e) {
16750          this.$composition ||
16751            (this.$composition = {
16752              keepTextAreaAtCursor: this.$keepTextAreaAtCursor,
16753              cssText: this.textarea.style.cssText
16754            }),
16755            (this.$keepTextAreaAtCursor = !0),
16756            i.addCssClass(this.textarea, 'ace_composition'),
16757            (this.textarea.style.cssText = ''),
16758            this.$moveTextAreaToCursor()
16759        }),
16760        (this.setCompositionText = function(e) {
16761          this.$moveTextAreaToCursor()
16762        }),
16763        (this.hideComposition = function() {
16764          if (!this.$composition) return
16765          i.removeCssClass(this.textarea, 'ace_composition'),
16766            (this.$keepTextAreaAtCursor = this.$composition.keepTextAreaAtCursor),
16767            (this.textarea.style.cssText = this.$composition.cssText),
16768            (this.$composition = null)
16769        }),
16770        (this.setTheme = function(e, t) {
16771          function o(r) {
16772            if (n.$themeId != e) return t && t()
16773            if (!r || !r.cssClass) throw new Error("couldn't load module " + e + " or it didn't call define")
16774            r.$id && (n.$themeId = r.$id),
16775              i.importCssString(r.cssText, r.cssClass, n.container),
16776              n.theme && i.removeCssClass(n.container, n.theme.cssClass)
16777            var s = 'padding' in r ? r.padding : 'padding' in (n.theme || {}) ? 4 : n.$padding
16778            n.$padding && s != n.$padding && n.setPadding(s),
16779              (n.$theme = r.cssClass),
16780              (n.theme = r),
16781              i.addCssClass(n.container, r.cssClass),
16782              i.setCssClass(n.container, 'ace_dark', r.isDark),
16783              n.$size && ((n.$size.width = 0), n.$updateSizeAsync()),
16784              n._dispatchEvent('themeLoaded', { theme: r }),
16785              t && t()
16786          }
16787          var n = this
16788          ;(this.$themeId = e), n._dispatchEvent('themeChange', { theme: e })
16789          if (!e || typeof e == 'string') {
16790            var r = e || this.$options.theme.initialValue
16791            s.loadModule(['theme', r], o)
16792          } else o(e)
16793        }),
16794        (this.getTheme = function() {
16795          return this.$themeId
16796        }),
16797        (this.setStyle = function(e, t) {
16798          i.setCssClass(this.container, e, t !== !1)
16799        }),
16800        (this.unsetStyle = function(e) {
16801          i.removeCssClass(this.container, e)
16802        }),
16803        (this.setCursorStyle = function(e) {
16804          this.scroller.style.cursor != e && (this.scroller.style.cursor = e)
16805        }),
16806        (this.setMouseCursor = function(e) {
16807          this.scroller.style.cursor = e
16808        }),
16809        (this.attachToShadowRoot = function() {
16810          i.importCssString(m, 'ace_editor.css', this.container)
16811        }),
16812        (this.destroy = function() {
16813          this.$textLayer.destroy(), this.$cursorLayer.destroy()
16814        })
16815    }.call(g.prototype),
16816      s.defineOptions(g.prototype, 'renderer', {
16817        animatedScroll: { initialValue: !1 },
16818        showInvisibles: {
16819          set: function(e) {
16820            this.$textLayer.setShowInvisibles(e) && this.$loop.schedule(this.CHANGE_TEXT)
16821          },
16822          initialValue: !1
16823        },
16824        showPrintMargin: {
16825          set: function() {
16826            this.$updatePrintMargin()
16827          },
16828          initialValue: !0
16829        },
16830        printMarginColumn: {
16831          set: function() {
16832            this.$updatePrintMargin()
16833          },
16834          initialValue: 80
16835        },
16836        printMargin: {
16837          set: function(e) {
16838            typeof e == 'number' && (this.$printMarginColumn = e),
16839              (this.$showPrintMargin = !!e),
16840              this.$updatePrintMargin()
16841          },
16842          get: function() {
16843            return this.$showPrintMargin && this.$printMarginColumn
16844          }
16845        },
16846        showGutter: {
16847          set: function(e) {
16848            ;(this.$gutter.style.display = e ? 'block' : 'none'),
16849              this.$loop.schedule(this.CHANGE_FULL),
16850              this.onGutterResize()
16851          },
16852          initialValue: !0
16853        },
16854        fadeFoldWidgets: {
16855          set: function(e) {
16856            i.setCssClass(this.$gutter, 'ace_fade-fold-widgets', e)
16857          },
16858          initialValue: !1
16859        },
16860        showFoldWidgets: {
16861          set: function(e) {
16862            this.$gutterLayer.setShowFoldWidgets(e)
16863          },
16864          initialValue: !0
16865        },
16866        showLineNumbers: {
16867          set: function(e) {
16868            this.$gutterLayer.setShowLineNumbers(e), this.$loop.schedule(this.CHANGE_GUTTER)
16869          },
16870          initialValue: !0
16871        },
16872        displayIndentGuides: {
16873          set: function(e) {
16874            this.$textLayer.setDisplayIndentGuides(e) && this.$loop.schedule(this.CHANGE_TEXT)
16875          },
16876          initialValue: !0
16877        },
16878        highlightGutterLine: {
16879          set: function(e) {
16880            if (!this.$gutterLineHighlight) {
16881              ;(this.$gutterLineHighlight = i.createElement('div')),
16882                (this.$gutterLineHighlight.className = 'ace_gutter-active-line'),
16883                this.$gutter.appendChild(this.$gutterLineHighlight)
16884              return
16885            }
16886            ;(this.$gutterLineHighlight.style.display = e ? '' : 'none'),
16887              this.$cursorLayer.$pixelPos && this.$updateGutterLineHighlight()
16888          },
16889          initialValue: !1,
16890          value: !0
16891        },
16892        hScrollBarAlwaysVisible: {
16893          set: function(e) {
16894            ;(!this.$hScrollBarAlwaysVisible || !this.$horizScroll) && this.$loop.schedule(this.CHANGE_SCROLL)
16895          },
16896          initialValue: !1
16897        },
16898        vScrollBarAlwaysVisible: {
16899          set: function(e) {
16900            ;(!this.$vScrollBarAlwaysVisible || !this.$vScroll) && this.$loop.schedule(this.CHANGE_SCROLL)
16901          },
16902          initialValue: !1
16903        },
16904        fontSize: {
16905          set: function(e) {
16906            typeof e == 'number' && (e += 'px'), (this.container.style.fontSize = e), this.updateFontSize()
16907          },
16908          initialValue: 12
16909        },
16910        fontFamily: {
16911          set: function(e) {
16912            ;(this.container.style.fontFamily = e), this.updateFontSize()
16913          }
16914        },
16915        maxLines: {
16916          set: function(e) {
16917            this.updateFull()
16918          }
16919        },
16920        minLines: {
16921          set: function(e) {
16922            this.updateFull()
16923          }
16924        },
16925        maxPixelHeight: {
16926          set: function(e) {
16927            this.updateFull()
16928          },
16929          initialValue: 0
16930        },
16931        scrollPastEnd: {
16932          set: function(e) {
16933            e = +e || 0
16934            if (this.$scrollPastEnd == e) return
16935            ;(this.$scrollPastEnd = e), this.$loop.schedule(this.CHANGE_SCROLL)
16936          },
16937          initialValue: 0,
16938          handlesSet: !0
16939        },
16940        fixedWidthGutter: {
16941          set: function(e) {
16942            ;(this.$gutterLayer.$fixedWidth = !!e), this.$loop.schedule(this.CHANGE_GUTTER)
16943          }
16944        },
16945        theme: {
16946          set: function(e) {
16947            this.setTheme(e)
16948          },
16949          get: function() {
16950            return this.$themeId || this.theme
16951          },
16952          initialValue: './theme/textmate',
16953          handlesSet: !0
16954        },
16955        hasCssTransforms: {}
16956      }),
16957      (t.VirtualRenderer = g))
16958  }),
16959  define('ace/worker/worker_client', [
16960    'require',
16961    'exports',
16962    'module',
16963    'ace/lib/oop',
16964    'ace/lib/net',
16965    'ace/lib/event_emitter',
16966    'ace/config'
16967  ], function(e, t, n) {
16968    'use strict'
16969    function u(e) {
16970      var t = "importScripts('" + i.qualifyURL(e) + "');"
16971      try {
16972        return new Blob([t], { type: 'application/javascript' })
16973      } catch (n) {
16974        var r = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder,
16975          s = new r()
16976        return s.append(t), s.getBlob('application/javascript')
16977      }
16978    }
16979    function a(e) {
16980      if (typeof Worker == 'undefined') return { postMessage: function() {}, terminate: function() {} }
16981      var t = u(e),
16982        n = window.URL || window.webkitURL,
16983        r = n.createObjectURL(t)
16984      return new Worker(r)
16985    }
16986    var r = e('../lib/oop'),
16987      i = e('../lib/net'),
16988      s = e('../lib/event_emitter').EventEmitter,
16989      o = e('../config'),
16990      f = function(t, n, r, i, s) {
16991        ;(this.$sendDeltaQueue = this.$sendDeltaQueue.bind(this)),
16992          (this.changeListener = this.changeListener.bind(this)),
16993          (this.onMessage = this.onMessage.bind(this)),
16994          e.nameToUrl && !e.toUrl && (e.toUrl = e.nameToUrl)
16995        if (o.get('packaged') || !e.toUrl) i = i || o.moduleUrl(n, 'worker')
16996        else {
16997          var u = this.$normalizePath
16998          i = i || u(e.toUrl('ace/worker/worker.js', null, '_'))
16999          var f = {}
17000          t.forEach(function(t) {
17001            f[t] = u(e.toUrl(t, null, '_').replace(/(\.js)?(\?.*)?$/, ''))
17002          })
17003        }
17004        ;(this.$worker = a(i)),
17005          s && this.send('importScripts', s),
17006          this.$worker.postMessage({ init: !0, tlns: f, module: n, classname: r }),
17007          (this.callbackId = 1),
17008          (this.callbacks = {}),
17009          (this.$worker.onmessage = this.onMessage)
17010      }
17011    ;(function() {
17012      r.implement(this, s),
17013        (this.onMessage = function(e) {
17014          var t = e.data
17015          switch (t.type) {
17016            case 'event':
17017              this._signal(t.name, { data: t.data })
17018              break
17019            case 'call':
17020              var n = this.callbacks[t.id]
17021              n && (n(t.data), delete this.callbacks[t.id])
17022              break
17023            case 'error':
17024              this.reportError(t.data)
17025              break
17026            case 'log':
17027              window.console && console.log && console.log.apply(console, t.data)
17028          }
17029        }),
17030        (this.reportError = function(e) {
17031          window.console && console.error && console.error(e)
17032        }),
17033        (this.$normalizePath = function(e) {
17034          return i.qualifyURL(e)
17035        }),
17036        (this.terminate = function() {
17037          this._signal('terminate', {}),
17038            (this.deltaQueue = null),
17039            this.$worker.terminate(),
17040            (this.$worker = null),
17041            this.$doc && this.$doc.off('change', this.changeListener),
17042            (this.$doc = null)
17043        }),
17044        (this.send = function(e, t) {
17045          this.$worker.postMessage({ command: e, args: t })
17046        }),
17047        (this.call = function(e, t, n) {
17048          if (n) {
17049            var r = this.callbackId++
17050            ;(this.callbacks[r] = n), t.push(r)
17051          }
17052          this.send(e, t)
17053        }),
17054        (this.emit = function(e, t) {
17055          try {
17056            this.$worker.postMessage({ event: e, data: { data: t.data } })
17057          } catch (n) {
17058            console.error(n.stack)
17059          }
17060        }),
17061        (this.attachToDocument = function(e) {
17062          this.$doc && this.terminate(),
17063            (this.$doc = e),
17064            this.call('setValue', [e.getValue()]),
17065            e.on('change', this.changeListener)
17066        }),
17067        (this.changeListener = function(e) {
17068          this.deltaQueue || ((this.deltaQueue = []), setTimeout(this.$sendDeltaQueue, 0)),
17069            e.action == 'insert' ? this.deltaQueue.push(e.start, e.lines) : this.deltaQueue.push(e.start, e.end)
17070        }),
17071        (this.$sendDeltaQueue = function() {
17072          var e = this.deltaQueue
17073          if (!e) return
17074          ;(this.deltaQueue = null),
17075            e.length > 50 && e.length > this.$doc.getLength() >> 1
17076              ? this.call('setValue', [this.$doc.getValue()])
17077              : this.emit('change', { data: e })
17078        })
17079    }.call(f.prototype))
17080    var l = function(e, t, n) {
17081      ;(this.$sendDeltaQueue = this.$sendDeltaQueue.bind(this)),
17082        (this.changeListener = this.changeListener.bind(this)),
17083        (this.callbackId = 1),
17084        (this.callbacks = {}),
17085        (this.messageBuffer = [])
17086      var r = null,
17087        i = !1,
17088        u = Object.create(s),
17089        a = this
17090      ;(this.$worker = {}),
17091        (this.$worker.terminate = function() {}),
17092        (this.$worker.postMessage = function(e) {
17093          a.messageBuffer.push(e), r && (i ? setTimeout(f) : f())
17094        }),
17095        (this.setEmitSync = function(e) {
17096          i = e
17097        })
17098      var f = function() {
17099        var e = a.messageBuffer.shift()
17100        e.command ? r[e.command].apply(r, e.args) : e.event && u._signal(e.event, e.data)
17101      }
17102      ;(u.postMessage = function(e) {
17103        a.onMessage({ data: e })
17104      }),
17105        (u.callback = function(e, t) {
17106          this.postMessage({ type: 'call', id: t, data: e })
17107        }),
17108        (u.emit = function(e, t) {
17109          this.postMessage({ type: 'event', name: e, data: t })
17110        }),
17111        o.loadModule(['worker', t], function(e) {
17112          r = new e[n](u)
17113          while (a.messageBuffer.length) f()
17114        })
17115    }
17116    ;(l.prototype = f.prototype), (t.UIWorkerClient = l), (t.WorkerClient = f), (t.createWorker = a)
17117  }),
17118  define('ace/placeholder', [
17119    'require',
17120    'exports',
17121    'module',
17122    'ace/range',
17123    'ace/lib/event_emitter',
17124    'ace/lib/oop'
17125  ], function(e, t, n) {
17126    'use strict'
17127    var r = e('./range').Range,
17128      i = e('./lib/event_emitter').EventEmitter,
17129      s = e('./lib/oop'),
17130      o = function(e, t, n, r, i, s) {
17131        var o = this
17132        ;(this.length = t),
17133          (this.session = e),
17134          (this.doc = e.getDocument()),
17135          (this.mainClass = i),
17136          (this.othersClass = s),
17137          (this.$onUpdate = this.onUpdate.bind(this)),
17138          this.doc.on('change', this.$onUpdate),
17139          (this.$others = r),
17140          (this.$onCursorChange = function() {
17141            setTimeout(function() {
17142              o.onCursorChange()
17143            })
17144          }),
17145          (this.$pos = n)
17146        var u = e.getUndoManager().$undoStack || e.getUndoManager().$undostack || { length: -1 }
17147        ;(this.$undoStackDepth = u.length), this.setup(), e.selection.on('changeCursor', this.$onCursorChange)
17148      }
17149    ;(function() {
17150      s.implement(this, i),
17151        (this.setup = function() {
17152          var e = this,
17153            t = this.doc,
17154            n = this.session
17155          ;(this.selectionBefore = n.selection.toJSON()),
17156            n.selection.inMultiSelectMode && n.selection.toSingleRange(),
17157            (this.pos = t.createAnchor(this.$pos.row, this.$pos.column))
17158          var i = this.pos
17159          ;(i.$insertRight = !0),
17160            i.detach(),
17161            (i.markerId = n.addMarker(new r(i.row, i.column, i.row, i.column + this.length), this.mainClass, null, !1)),
17162            (this.others = []),
17163            this.$others.forEach(function(n) {
17164              var r = t.createAnchor(n.row, n.column)
17165              ;(r.$insertRight = !0), r.detach(), e.others.push(r)
17166            }),
17167            n.setUndoSelect(!1)
17168        }),
17169        (this.showOtherMarkers = function() {
17170          if (this.othersActive) return
17171          var e = this.session,
17172            t = this
17173          ;(this.othersActive = !0),
17174            this.others.forEach(function(n) {
17175              n.markerId = e.addMarker(new r(n.row, n.column, n.row, n.column + t.length), t.othersClass, null, !1)
17176            })
17177        }),
17178        (this.hideOtherMarkers = function() {
17179          if (!this.othersActive) return
17180          this.othersActive = !1
17181          for (var e = 0; e < this.others.length; e++) this.session.removeMarker(this.others[e].markerId)
17182        }),
17183        (this.onUpdate = function(e) {
17184          if (this.$updating) return this.updateAnchors(e)
17185          var t = e
17186          if (t.start.row !== t.end.row) return
17187          if (t.start.row !== this.pos.row) return
17188          this.$updating = !0
17189          var n = e.action === 'insert' ? t.end.column - t.start.column : t.start.column - t.end.column,
17190            i = t.start.column >= this.pos.column && t.start.column <= this.pos.column + this.length + 1,
17191            s = t.start.column - this.pos.column
17192          this.updateAnchors(e), i && (this.length += n)
17193          if (i && !this.session.$fromUndo)
17194            if (e.action === 'insert')
17195              for (var o = this.others.length - 1; o >= 0; o--) {
17196                var u = this.others[o],
17197                  a = { row: u.row, column: u.column + s }
17198                this.doc.insertMergedLines(a, e.lines)
17199              }
17200            else if (e.action === 'remove')
17201              for (var o = this.others.length - 1; o >= 0; o--) {
17202                var u = this.others[o],
17203                  a = { row: u.row, column: u.column + s }
17204                this.doc.remove(new r(a.row, a.column, a.row, a.column - n))
17205              }
17206          ;(this.$updating = !1), this.updateMarkers()
17207        }),
17208        (this.updateAnchors = function(e) {
17209          this.pos.onChange(e)
17210          for (var t = this.others.length; t--; ) this.others[t].onChange(e)
17211          this.updateMarkers()
17212        }),
17213        (this.updateMarkers = function() {
17214          if (this.$updating) return
17215          var e = this,
17216            t = this.session,
17217            n = function(n, i) {
17218              t.removeMarker(n.markerId),
17219                (n.markerId = t.addMarker(new r(n.row, n.column, n.row, n.column + e.length), i, null, !1))
17220            }
17221          n(this.pos, this.mainClass)
17222          for (var i = this.others.length; i--; ) n(this.others[i], this.othersClass)
17223        }),
17224        (this.onCursorChange = function(e) {
17225          if (this.$updating || !this.session) return
17226          var t = this.session.selection.getCursor()
17227          t.row === this.pos.row && t.column >= this.pos.column && t.column <= this.pos.column + this.length
17228            ? (this.showOtherMarkers(), this._emit('cursorEnter', e))
17229            : (this.hideOtherMarkers(), this._emit('cursorLeave', e))
17230        }),
17231        (this.detach = function() {
17232          this.session.removeMarker(this.pos && this.pos.markerId),
17233            this.hideOtherMarkers(),
17234            this.doc.removeEventListener('change', this.$onUpdate),
17235            this.session.selection.removeEventListener('changeCursor', this.$onCursorChange),
17236            this.session.setUndoSelect(!0),
17237            (this.session = null)
17238        }),
17239        (this.cancel = function() {
17240          if (this.$undoStackDepth === -1) return
17241          var e = this.session.getUndoManager(),
17242            t = (e.$undoStack || e.$undostack).length - this.$undoStackDepth
17243          for (var n = 0; n < t; n++) e.undo(this.session, !0)
17244          this.selectionBefore && this.session.selection.fromJSON(this.selectionBefore)
17245        })
17246    }.call(o.prototype),
17247      (t.PlaceHolder = o))
17248  }),
17249  define('ace/mouse/multi_select_handler', [
17250    'require',
17251    'exports',
17252    'module',
17253    'ace/lib/event',
17254    'ace/lib/useragent'
17255  ], function(e, t, n) {
17256    function s(e, t) {
17257      return e.row == t.row && e.column == t.column
17258    }
17259    function o(e) {
17260      var t = e.domEvent,
17261        n = t.altKey,
17262        o = t.shiftKey,
17263        u = t.ctrlKey,
17264        a = e.getAccelKey(),
17265        f = e.getButton()
17266      u && i.isMac && (f = t.button)
17267      if (e.editor.inMultiSelectMode && f == 2) {
17268        e.editor.textInput.onContextMenu(e.domEvent)
17269        return
17270      }
17271      if (!u && !n && !a) {
17272        f === 0 && e.editor.inMultiSelectMode && e.editor.exitMultiSelectMode()
17273        return
17274      }
17275      if (f !== 0) return
17276      var l = e.editor,
17277        c = l.selection,
17278        h = l.inMultiSelectMode,
17279        p = e.getDocumentPosition(),
17280        d = c.getCursor(),
17281        v = e.inSelection() || (c.isEmpty() && s(p, d)),
17282        m = e.x,
17283        g = e.y,
17284        y = function(e) {
17285          ;(m = e.clientX), (g = e.clientY)
17286        },
17287        b = l.session,
17288        w = l.renderer.pixelToScreenCoordinates(m, g),
17289        E = w,
17290        S
17291      if (l.$mouseHandler.$enableJumpToDef)
17292        (u && n) || (a && n) ? (S = o ? 'block' : 'add') : n && l.$blockSelectEnabled && (S = 'block')
17293      else if (a && !n) {
17294        S = 'add'
17295        if (!h && o) return
17296      } else n && l.$blockSelectEnabled && (S = 'block')
17297      S && i.isMac && t.ctrlKey && l.$mouseHandler.cancelContextMenu()
17298      if (S == 'add') {
17299        if (!h && v) return
17300        if (!h) {
17301          var x = c.toOrientedRange()
17302          l.addSelectionMarker(x)
17303        }
17304        var T = c.rangeList.rangeAtPoint(p)
17305        ;(l.inVirtualSelectionMode = !0),
17306          o && ((T = null), (x = c.ranges[0] || x), l.removeSelectionMarker(x)),
17307          l.once('mouseup', function() {
17308            var e = c.toOrientedRange()
17309            T && e.isEmpty() && s(T.cursor, e.cursor)
17310              ? c.substractPoint(e.cursor)
17311              : (o ? c.substractPoint(x.cursor) : x && (l.removeSelectionMarker(x), c.addRange(x)), c.addRange(e)),
17312              (l.inVirtualSelectionMode = !1)
17313          })
17314      } else if (S == 'block') {
17315        e.stop(), (l.inVirtualSelectionMode = !0)
17316        var N,
17317          C = [],
17318          k = function() {
17319            var e = l.renderer.pixelToScreenCoordinates(m, g),
17320              t = b.screenToDocumentPosition(e.row, e.column, e.offsetX)
17321            if (s(E, e) && s(t, c.lead)) return
17322            ;(E = e),
17323              l.selection.moveToPosition(t),
17324              l.renderer.scrollCursorIntoView(),
17325              l.removeSelectionMarkers(C),
17326              (C = c.rectangularRangeBlock(E, w)),
17327              l.$mouseHandler.$clickSelection &&
17328                C.length == 1 &&
17329                C[0].isEmpty() &&
17330                (C[0] = l.$mouseHandler.$clickSelection.clone()),
17331              C.forEach(l.addSelectionMarker, l),
17332              l.updateSelectionMarkers()
17333          }
17334        h && !a ? c.toSingleRange() : !h && a && ((N = c.toOrientedRange()), l.addSelectionMarker(N)),
17335          o ? (w = b.documentToScreenPosition(c.lead)) : c.moveToPosition(p),
17336          (E = { row: -1, column: -1 })
17337        var L = function(e) {
17338            clearInterval(O),
17339              l.removeSelectionMarkers(C),
17340              C.length || (C = [c.toOrientedRange()]),
17341              N && (l.removeSelectionMarker(N), c.toSingleRange(N))
17342            for (var t = 0; t < C.length; t++) c.addRange(C[t])
17343            ;(l.inVirtualSelectionMode = !1), (l.$mouseHandler.$clickSelection = null)
17344          },
17345          A = k
17346        r.capture(l.container, y, L)
17347        var O = setInterval(function() {
17348          A()
17349        }, 20)
17350        return e.preventDefault()
17351      }
17352    }
17353    var r = e('../lib/event'),
17354      i = e('../lib/useragent')
17355    t.onMouseDown = o
17356  }),
17357  define('ace/commands/multi_select_commands', ['require', 'exports', 'module', 'ace/keyboard/hash_handler'], function(
17358    e,
17359    t,
17360    n
17361  ) {
17362    ;(t.defaultCommands = [
17363      {
17364        name: 'addCursorAbove',
17365        exec: function(e) {
17366          e.selectMoreLines(-1)
17367        },
17368        bindKey: { win: 'Ctrl-Alt-Up', mac: 'Ctrl-Alt-Up' },
17369        scrollIntoView: 'cursor',
17370        readOnly: !0
17371      },
17372      {
17373        name: 'addCursorBelow',
17374        exec: function(e) {
17375          e.selectMoreLines(1)
17376        },
17377        bindKey: { win: 'Ctrl-Alt-Down', mac: 'Ctrl-Alt-Down' },
17378        scrollIntoView: 'cursor',
17379        readOnly: !0
17380      },
17381      {
17382        name: 'addCursorAboveSkipCurrent',
17383        exec: function(e) {
17384          e.selectMoreLines(-1, !0)
17385        },
17386        bindKey: { win: 'Ctrl-Alt-Shift-Up', mac: 'Ctrl-Alt-Shift-Up' },
17387        scrollIntoView: 'cursor',
17388        readOnly: !0
17389      },
17390      {
17391        name: 'addCursorBelowSkipCurrent',
17392        exec: function(e) {
17393          e.selectMoreLines(1, !0)
17394        },
17395        bindKey: { win: 'Ctrl-Alt-Shift-Down', mac: 'Ctrl-Alt-Shift-Down' },
17396        scrollIntoView: 'cursor',
17397        readOnly: !0
17398      },
17399      {
17400        name: 'selectMoreBefore',
17401        exec: function(e) {
17402          e.selectMore(-1)
17403        },
17404        bindKey: { win: 'Ctrl-Alt-Left', mac: 'Ctrl-Alt-Left' },
17405        scrollIntoView: 'cursor',
17406        readOnly: !0
17407      },
17408      {
17409        name: 'selectMoreAfter',
17410        exec: function(e) {
17411          e.selectMore(1)
17412        },
17413        bindKey: { win: 'Ctrl-Alt-Right', mac: 'Ctrl-Alt-Right' },
17414        scrollIntoView: 'cursor',
17415        readOnly: !0
17416      },
17417      {
17418        name: 'selectNextBefore',
17419        exec: function(e) {
17420          e.selectMore(-1, !0)
17421        },
17422        bindKey: { win: 'Ctrl-Alt-Shift-Left', mac: 'Ctrl-Alt-Shift-Left' },
17423        scrollIntoView: 'cursor',
17424        readOnly: !0
17425      },
17426      {
17427        name: 'selectNextAfter',
17428        exec: function(e) {
17429          e.selectMore(1, !0)
17430        },
17431        bindKey: { win: 'Ctrl-Alt-Shift-Right', mac: 'Ctrl-Alt-Shift-Right' },
17432        scrollIntoView: 'cursor',
17433        readOnly: !0
17434      },
17435      {
17436        name: 'splitIntoLines',
17437        exec: function(e) {
17438          e.multiSelect.splitIntoLines()
17439        },
17440        bindKey: { win: 'Ctrl-Alt-L', mac: 'Ctrl-Alt-L' },
17441        readOnly: !0
17442      },
17443      {
17444        name: 'alignCursors',
17445        exec: function(e) {
17446          e.alignCursors()
17447        },
17448        bindKey: { win: 'Ctrl-Alt-A', mac: 'Ctrl-Alt-A' },
17449        scrollIntoView: 'cursor'
17450      },
17451      {
17452        name: 'findAll',
17453        exec: function(e) {
17454          e.findAll()
17455        },
17456        bindKey: { win: 'Ctrl-Alt-K', mac: 'Ctrl-Alt-G' },
17457        scrollIntoView: 'cursor',
17458        readOnly: !0
17459      }
17460    ]),
17461      (t.multiSelectCommands = [
17462        {
17463          name: 'singleSelection',
17464          bindKey: 'esc',
17465          exec: function(e) {
17466            e.exitMultiSelectMode()
17467          },
17468          scrollIntoView: 'cursor',
17469          readOnly: !0,
17470          isAvailable: function(e) {
17471            return e && e.inMultiSelectMode
17472          }
17473        }
17474      ])
17475    var r = e('../keyboard/hash_handler').HashHandler
17476    t.keyboardHandler = new r(t.multiSelectCommands)
17477  }),
17478  define('ace/multi_select', [
17479    'require',
17480    'exports',
17481    'module',
17482    'ace/range_list',
17483    'ace/range',
17484    'ace/selection',
17485    'ace/mouse/multi_select_handler',
17486    'ace/lib/event',
17487    'ace/lib/lang',
17488    'ace/commands/multi_select_commands',
17489    'ace/search',
17490    'ace/edit_session',
17491    'ace/editor',
17492    'ace/config'
17493  ], function(e, t, n) {
17494    function h(e, t, n) {
17495      return (c.$options.wrap = !0), (c.$options.needle = t), (c.$options.backwards = n == -1), c.find(e)
17496    }
17497    function v(e, t) {
17498      return e.row == t.row && e.column == t.column
17499    }
17500    function m(e) {
17501      if (e.$multiselectOnSessionChange) return
17502      ;(e.$onAddRange = e.$onAddRange.bind(e)),
17503        (e.$onRemoveRange = e.$onRemoveRange.bind(e)),
17504        (e.$onMultiSelect = e.$onMultiSelect.bind(e)),
17505        (e.$onSingleSelect = e.$onSingleSelect.bind(e)),
17506        (e.$multiselectOnSessionChange = t.onSessionChange.bind(e)),
17507        (e.$checkMultiselectChange = e.$checkMultiselectChange.bind(e)),
17508        e.$multiselectOnSessionChange(e),
17509        e.on('changeSession', e.$multiselectOnSessionChange),
17510        e.on('mousedown', o),
17511        e.commands.addCommands(f.defaultCommands),
17512        g(e)
17513    }
17514    function g(e) {
17515      function r(t) {
17516        n && (e.renderer.setMouseCursor(''), (n = !1))
17517      }
17518      var t = e.textInput.getElement(),
17519        n = !1
17520      u.addListener(t, 'keydown', function(t) {
17521        var i = t.keyCode == 18 && !(t.ctrlKey || t.shiftKey || t.metaKey)
17522        e.$blockSelectEnabled && i ? n || (e.renderer.setMouseCursor('crosshair'), (n = !0)) : n && r()
17523      }),
17524        u.addListener(t, 'keyup', r),
17525        u.addListener(t, 'blur', r)
17526    }
17527    var r = e('./range_list').RangeList,
17528      i = e('./range').Range,
17529      s = e('./selection').Selection,
17530      o = e('./mouse/multi_select_handler').onMouseDown,
17531      u = e('./lib/event'),
17532      a = e('./lib/lang'),
17533      f = e('./commands/multi_select_commands')
17534    t.commands = f.defaultCommands.concat(f.multiSelectCommands)
17535    var l = e('./search').Search,
17536      c = new l(),
17537      p = e('./edit_session').EditSession
17538    ;(function() {
17539      this.getSelectionMarkers = function() {
17540        return this.$selectionMarkers
17541      }
17542    }.call(p.prototype),
17543      function() {
17544        ;(this.ranges = null),
17545          (this.rangeList = null),
17546          (this.addRange = function(e, t) {
17547            if (!e) return
17548            if (!this.inMultiSelectMode && this.rangeCount === 0) {
17549              var n = this.toOrientedRange()
17550              this.rangeList.add(n), this.rangeList.add(e)
17551              if (this.rangeList.ranges.length != 2) return this.rangeList.removeAll(), t || this.fromOrientedRange(e)
17552              this.rangeList.removeAll(), this.rangeList.add(n), this.$onAddRange(n)
17553            }
17554            e.cursor || (e.cursor = e.end)
17555            var r = this.rangeList.add(e)
17556            return (
17557              this.$onAddRange(e),
17558              r.length && this.$onRemoveRange(r),
17559              this.rangeCount > 1 &&
17560                !this.inMultiSelectMode &&
17561                (this._signal('multiSelect'),
17562                (this.inMultiSelectMode = !0),
17563                (this.session.$undoSelect = !1),
17564                this.rangeList.attach(this.session)),
17565              t || this.fromOrientedRange(e)
17566            )
17567          }),
17568          (this.toSingleRange = function(e) {
17569            e = e || this.ranges[0]
17570            var t = this.rangeList.removeAll()
17571            t.length && this.$onRemoveRange(t), e && this.fromOrientedRange(e)
17572          }),
17573          (this.substractPoint = function(e) {
17574            var t = this.rangeList.substractPoint(e)
17575            if (t) return this.$onRemoveRange(t), t[0]
17576          }),
17577          (this.mergeOverlappingRanges = function() {
17578            var e = this.rangeList.merge()
17579            e.length ? this.$onRemoveRange(e) : this.ranges[0] && this.fromOrientedRange(this.ranges[0])
17580          }),
17581          (this.$onAddRange = function(e) {
17582            ;(this.rangeCount = this.rangeList.ranges.length),
17583              this.ranges.unshift(e),
17584              this._signal('addRange', { range: e })
17585          }),
17586          (this.$onRemoveRange = function(e) {
17587            this.rangeCount = this.rangeList.ranges.length
17588            if (this.rangeCount == 1 && this.inMultiSelectMode) {
17589              var t = this.rangeList.ranges.pop()
17590              e.push(t), (this.rangeCount = 0)
17591            }
17592            for (var n = e.length; n--; ) {
17593              var r = this.ranges.indexOf(e[n])
17594              this.ranges.splice(r, 1)
17595            }
17596            this._signal('removeRange', { ranges: e }),
17597              this.rangeCount === 0 &&
17598                this.inMultiSelectMode &&
17599                ((this.inMultiSelectMode = !1),
17600                this._signal('singleSelect'),
17601                (this.session.$undoSelect = !0),
17602                this.rangeList.detach(this.session)),
17603              (t = t || this.ranges[0]),
17604              t && !t.isEqual(this.getRange()) && this.fromOrientedRange(t)
17605          }),
17606          (this.$initRangeList = function() {
17607            if (this.rangeList) return
17608            ;(this.rangeList = new r()), (this.ranges = []), (this.rangeCount = 0)
17609          }),
17610          (this.getAllRanges = function() {
17611            return this.rangeCount ? this.rangeList.ranges.concat() : [this.getRange()]
17612          }),
17613          (this.splitIntoLines = function() {
17614            if (this.rangeCount > 1) {
17615              var e = this.rangeList.ranges,
17616                t = e[e.length - 1],
17617                n = i.fromPoints(e[0].start, t.end)
17618              this.toSingleRange(), this.setSelectionRange(n, t.cursor == t.start)
17619            } else {
17620              var n = this.getRange(),
17621                r = this.isBackwards(),
17622                s = n.start.row,
17623                o = n.end.row
17624              if (s == o) {
17625                if (r)
17626                  var u = n.end,
17627                    a = n.start
17628                else
17629                  var u = n.start,
17630                    a = n.end
17631                this.addRange(i.fromPoints(a, a)), this.addRange(i.fromPoints(u, u))
17632                return
17633              }
17634              var f = [],
17635                l = this.getLineRange(s, !0)
17636              ;(l.start.column = n.start.column), f.push(l)
17637              for (var c = s + 1; c < o; c++) f.push(this.getLineRange(c, !0))
17638              ;(l = this.getLineRange(o, !0)), (l.end.column = n.end.column), f.push(l), f.forEach(this.addRange, this)
17639            }
17640          }),
17641          (this.toggleBlockSelection = function() {
17642            if (this.rangeCount > 1) {
17643              var e = this.rangeList.ranges,
17644                t = e[e.length - 1],
17645                n = i.fromPoints(e[0].start, t.end)
17646              this.toSingleRange(), this.setSelectionRange(n, t.cursor == t.start)
17647            } else {
17648              var r = this.session.documentToScreenPosition(this.cursor),
17649                s = this.session.documentToScreenPosition(this.anchor),
17650                o = this.rectangularRangeBlock(r, s)
17651              o.forEach(this.addRange, this)
17652            }
17653          }),
17654          (this.rectangularRangeBlock = function(e, t, n) {
17655            var r = [],
17656              s = e.column < t.column
17657            if (s)
17658              var o = e.column,
17659                u = t.column,
17660                a = e.offsetX,
17661                f = t.offsetX
17662            else
17663              var o = t.column,
17664                u = e.column,
17665                a = t.offsetX,
17666                f = e.offsetX
17667            var l = e.row < t.row
17668            if (l)
17669              var c = e.row,
17670                h = t.row
17671            else
17672              var c = t.row,
17673                h = e.row
17674            o < 0 && (o = 0), c < 0 && (c = 0), c == h && (n = !0)
17675            var p
17676            for (var d = c; d <= h; d++) {
17677              var m = i.fromPoints(
17678                this.session.screenToDocumentPosition(d, o, a),
17679                this.session.screenToDocumentPosition(d, u, f)
17680              )
17681              if (m.isEmpty()) {
17682                if (p && v(m.end, p)) break
17683                p = m.end
17684              }
17685              ;(m.cursor = s ? m.start : m.end), r.push(m)
17686            }
17687            l && r.reverse()
17688            if (!n) {
17689              var g = r.length - 1
17690              while (r[g].isEmpty() && g > 0) g--
17691              if (g > 0) {
17692                var y = 0
17693                while (r[y].isEmpty()) y++
17694              }
17695              for (var b = g; b >= y; b--) r[b].isEmpty() && r.splice(b, 1)
17696            }
17697            return r
17698          })
17699      }.call(s.prototype))
17700    var d = e('./editor').Editor
17701    ;(function() {
17702      ;(this.updateSelectionMarkers = function() {
17703        this.renderer.updateCursor(), this.renderer.updateBackMarkers()
17704      }),
17705        (this.addSelectionMarker = function(e) {
17706          e.cursor || (e.cursor = e.end)
17707          var t = this.getSelectionStyle()
17708          return (
17709            (e.marker = this.session.addMarker(e, 'ace_selection', t)),
17710            this.session.$selectionMarkers.push(e),
17711            (this.session.selectionMarkerCount = this.session.$selectionMarkers.length),
17712            e
17713          )
17714        }),
17715        (this.removeSelectionMarker = function(e) {
17716          if (!e.marker) return
17717          this.session.removeMarker(e.marker)
17718          var t = this.session.$selectionMarkers.indexOf(e)
17719          t != -1 && this.session.$selectionMarkers.splice(t, 1),
17720            (this.session.selectionMarkerCount = this.session.$selectionMarkers.length)
17721        }),
17722        (this.removeSelectionMarkers = function(e) {
17723          var t = this.session.$selectionMarkers
17724          for (var n = e.length; n--; ) {
17725            var r = e[n]
17726            if (!r.marker) continue
17727            this.session.removeMarker(r.marker)
17728            var i = t.indexOf(r)
17729            i != -1 && t.splice(i, 1)
17730          }
17731          this.session.selectionMarkerCount = t.length
17732        }),
17733        (this.$onAddRange = function(e) {
17734          this.addSelectionMarker(e.range), this.renderer.updateCursor(), this.renderer.updateBackMarkers()
17735        }),
17736        (this.$onRemoveRange = function(e) {
17737          this.removeSelectionMarkers(e.ranges), this.renderer.updateCursor(), this.renderer.updateBackMarkers()
17738        }),
17739        (this.$onMultiSelect = function(e) {
17740          if (this.inMultiSelectMode) return
17741          ;(this.inMultiSelectMode = !0),
17742            this.setStyle('ace_multiselect'),
17743            this.keyBinding.addKeyboardHandler(f.keyboardHandler),
17744            this.commands.setDefaultHandler('exec', this.$onMultiSelectExec),
17745            this.renderer.updateCursor(),
17746            this.renderer.updateBackMarkers()
17747        }),
17748        (this.$onSingleSelect = function(e) {
17749          if (this.session.multiSelect.inVirtualMode) return
17750          ;(this.inMultiSelectMode = !1),
17751            this.unsetStyle('ace_multiselect'),
17752            this.keyBinding.removeKeyboardHandler(f.keyboardHandler),
17753            this.commands.removeDefaultHandler('exec', this.$onMultiSelectExec),
17754            this.renderer.updateCursor(),
17755            this.renderer.updateBackMarkers(),
17756            this._emit('changeSelection')
17757        }),
17758        (this.$onMultiSelectExec = function(e) {
17759          var t = e.command,
17760            n = e.editor
17761          if (!n.multiSelect) return
17762          if (!t.multiSelectAction) {
17763            var r = t.exec(n, e.args || {})
17764            n.multiSelect.addRange(n.multiSelect.toOrientedRange()), n.multiSelect.mergeOverlappingRanges()
17765          } else
17766            t.multiSelectAction == 'forEach'
17767              ? (r = n.forEachSelection(t, e.args))
17768              : t.multiSelectAction == 'forEachLine'
17769              ? (r = n.forEachSelection(t, e.args, !0))
17770              : t.multiSelectAction == 'single'
17771              ? (n.exitMultiSelectMode(), (r = t.exec(n, e.args || {})))
17772              : (r = t.multiSelectAction(n, e.args || {}))
17773          return r
17774        }),
17775        (this.forEachSelection = function(e, t, n) {
17776          if (this.inVirtualSelectionMode) return
17777          var r = n && n.keepOrder,
17778            i = n == 1 || (n && n.$byLines),
17779            o = this.session,
17780            u = this.selection,
17781            a = u.rangeList,
17782            f = (r ? u : a).ranges,
17783            l
17784          if (!f.length) return e.exec ? e.exec(this, t || {}) : e(this, t || {})
17785          var c = u._eventRegistry
17786          u._eventRegistry = {}
17787          var h = new s(o)
17788          this.inVirtualSelectionMode = !0
17789          for (var p = f.length; p--; ) {
17790            if (i) while (p > 0 && f[p].start.row == f[p - 1].end.row) p--
17791            h.fromOrientedRange(f[p]), (h.index = p), (this.selection = o.selection = h)
17792            var d = e.exec ? e.exec(this, t || {}) : e(this, t || {})
17793            !l && d !== undefined && (l = d), h.toOrientedRange(f[p])
17794          }
17795          h.detach(),
17796            (this.selection = o.selection = u),
17797            (this.inVirtualSelectionMode = !1),
17798            (u._eventRegistry = c),
17799            u.mergeOverlappingRanges()
17800          var v = this.renderer.$scrollAnimation
17801          return (
17802            this.onCursorChange(),
17803            this.onSelectionChange(),
17804            v && v.from == v.to && this.renderer.animateScrolling(v.from),
17805            l
17806          )
17807        }),
17808        (this.exitMultiSelectMode = function() {
17809          if (!this.inMultiSelectMode || this.inVirtualSelectionMode) return
17810          this.multiSelect.toSingleRange()
17811        }),
17812        (this.getSelectedText = function() {
17813          var e = ''
17814          if (this.inMultiSelectMode && !this.inVirtualSelectionMode) {
17815            var t = this.multiSelect.rangeList.ranges,
17816              n = []
17817            for (var r = 0; r < t.length; r++) n.push(this.session.getTextRange(t[r]))
17818            var i = this.session.getDocument().getNewLineCharacter()
17819            ;(e = n.join(i)), e.length == (n.length - 1) * i.length && (e = '')
17820          } else this.selection.isEmpty() || (e = this.session.getTextRange(this.getSelectionRange()))
17821          return e
17822        }),
17823        (this.$checkMultiselectChange = function(e, t) {
17824          if (this.inMultiSelectMode && !this.inVirtualSelectionMode) {
17825            var n = this.multiSelect.ranges[0]
17826            if (this.multiSelect.isEmpty() && t == this.multiSelect.anchor) return
17827            var r = t == this.multiSelect.anchor ? (n.cursor == n.start ? n.end : n.start) : n.cursor
17828            r.row != t.row || this.session.$clipPositionToDocument(r.row, r.column).column != t.column
17829              ? this.multiSelect.toSingleRange(this.multiSelect.toOr
17829ientedRange())
17830              : this.multiSelect.mergeOverlappingRanges()
17831          }
17832        }),
17833        (this.findAll = function(e, t, n) {
17834          ;(t = t || {}), (t.needle = e || t.needle)
17835          if (t.needle == undefined) {
17836            var r = this.selection.isEmpty() ? this.selection.getWordRange() : this.selection.getRange()
17837            t.needle = this.session.getTextRange(r)
17838          }
17839          this.$search.set(t)
17840          var i = this.$search.findAll(this.session)
17841          if (!i.length) return 0
17842          var s = this.multiSelect
17843          n || s.toSingleRange(i[0])
17844          for (var o = i.length; o--; ) s.addRange(i[o], !0)
17845          return r && s.rangeList.rangeAtPoint(r.start) && s.addRange(r, !0), i.length
17846        }),
17847        (this.selectMoreLines = function(e, t) {
17848          var n = this.selection.toOrientedRange(),
17849            r = n.cursor == n.end,
17850            s = this.session.documentToScreenPosition(n.cursor)
17851          this.selection.$desiredColumn && (s.column = this.selection.$desiredColumn)
17852          var o = this.session.screenToDocumentPosition(s.row + e, s.column)
17853          if (!n.isEmpty())
17854            var u = this.session.documentToScreenPosition(r ? n.end : n.start),
17855              a = this.session.screenToDocumentPosition(u.row + e, u.column)
17856          else var a = o
17857          if (r) {
17858            var f = i.fromPoints(o, a)
17859            f.cursor = f.start
17860          } else {
17861            var f = i.fromPoints(a, o)
17862            f.cursor = f.end
17863          }
17864          f.desiredColumn = s.column
17865          if (!this.selection.inMultiSelectMode) this.selection.addRange(n)
17866          else if (t) var l = n.cursor
17867          this.selection.addRange(f), l && this.selection.substractPoint(l)
17868        }),
17869        (this.transposeSelections = function(e) {
17870          var t = this.session,
17871            n = t.multiSelect,
17872            r = n.ranges
17873          for (var i = r.length; i--; ) {
17874            var s = r[i]
17875            if (s.isEmpty()) {
17876              var o = t.getWordRange(s.start.row, s.start.column)
17877              ;(s.start.row = o.start.row),
17878                (s.start.column = o.start.column),
17879                (s.end.row = o.end.row),
17880                (s.end.column = o.end.column)
17881            }
17882          }
17883          n.mergeOverlappingRanges()
17884          var u = []
17885          for (var i = r.length; i--; ) {
17886            var s = r[i]
17887            u.unshift(t.getTextRange(s))
17888          }
17889          e < 0 ? u.unshift(u.pop()) : u.push(u.shift())
17890          for (var i = r.length; i--; ) {
17891            var s = r[i],
17892              o = s.clone()
17893            t.replace(s, u[i]), (s.start.row = o.start.row), (s.start.column = o.start.column)
17894          }
17895        }),
17896        (this.selectMore = function(e, t, n) {
17897          var r = this.session,
17898            i = r.multiSelect,
17899            s = i.toOrientedRange()
17900          if (s.isEmpty()) {
17901            ;(s = r.getWordRange(s.start.row, s.start.column)),
17902              (s.cursor = e == -1 ? s.start : s.end),
17903              this.multiSelect.addRange(s)
17904            if (n) return
17905          }
17906          var o = r.getTextRange(s),
17907            u = h(r, o, e)
17908          u &&
17909            ((u.cursor = e == -1 ? u.start : u.end),
17910            this.session.unfold(u),
17911            this.multiSelect.addRange(u),
17912            this.renderer.scrollCursorIntoView(null, 0.5)),
17913            t && this.multiSelect.substractPoint(s.cursor)
17914        }),
17915        (this.alignCursors = function() {
17916          var e = this.session,
17917            t = e.multiSelect,
17918            n = t.ranges,
17919            r = -1,
17920            s = n.filter(function(e) {
17921              if (e.cursor.row == r) return !0
17922              r = e.cursor.row
17923            })
17924          if (!n.length || s.length == n.length - 1) {
17925            var o = this.selection.getRange(),
17926              u = o.start.row,
17927              f = o.end.row,
17928              l = u == f
17929            if (l) {
17930              var c = this.session.getLength(),
17931                h
17932              do h = this.session.getLine(f)
17933              while (/[=:]/.test(h) && ++f < c)
17934              do h = this.session.getLine(u)
17935              while (/[=:]/.test(h) && --u > 0)
17936              u < 0 && (u = 0), f >= c && (f = c - 1)
17937            }
17938            var p = this.session.removeFullLines(u, f)
17939            ;(p = this.$reAlignText(p, l)),
17940              this.session.insert({ row: u, column: 0 }, p.join('\n') + '\n'),
17941              l || ((o.start.column = 0), (o.end.column = p[p.length - 1].length)),
17942              this.selection.setRange(o)
17943          } else {
17944            s.forEach(function(e) {
17945              t.substractPoint(e.cursor)
17946            })
17947            var d = 0,
17948              v = Infinity,
17949              m = n.map(function(t) {
17950                var n = t.cursor,
17951                  r = e.getLine(n.row),
17952                  i = r.substr(n.column).search(/\S/g)
17953                return i == -1 && (i = 0), n.column > d && (d = n.column), i < v && (v = i), i
17954              })
17955            n.forEach(function(t, n) {
17956              var r = t.cursor,
17957                s = d - r.column,
17958                o = m[n] - v
17959              s > o
17960                ? e.insert(r, a.stringRepeat(' ', s - o))
17961                : e.remove(new i(r.row, r.column, r.row, r.column - s + o)),
17962                (t.start.column = t.end.column = d),
17963                (t.start.row = t.end.row = r.row),
17964                (t.cursor = t.end)
17965            }),
17966              t.fromOrientedRange(n[0]),
17967              this.renderer.updateCursor(),
17968              this.renderer.updateBackMarkers()
17969          }
17970        }),
17971        (this.$reAlignText = function(e, t) {
17972          function u(e) {
17973            return a.stringRepeat(' ', e)
17974          }
17975          function f(e) {
17976            return e[2] ? u(i) + e[2] + u(s - e[2].length + o) + e[4].replace(/^([=:])\s+/, '$1 ') : e[0]
17977          }
17978          function l(e) {
17979            return e[2] ? u(i + s - e[2].length) + e[2] + u(o) + e[4].replace(/^([=:])\s+/, '$1 ') : e[0]
17980          }
17981          function c(e) {
17982            return e[2] ? u(i) + e[2] + u(o) + e[4].replace(/^([=:])\s+/, '$1 ') : e[0]
17983          }
17984          var n = !0,
17985            r = !0,
17986            i,
17987            s,
17988            o
17989          return e
17990            .map(function(e) {
17991              var t = e.match(/(\s*)(.*?)(\s*)([=:].*)/)
17992              return t
17993                ? i == null
17994                  ? ((i = t[1].length), (s = t[2].length), (o = t[3].length), t)
17995                  : (i + s + o != t[1].length + t[2].length + t[3].length && (r = !1),
17996                    i != t[1].length && (n = !1),
17997                    i > t[1].length && (i = t[1].length),
17998                    s < t[2].length && (s = t[2].length),
17999                    o > t[3].length && (o = t[3].length),
18000                    t)
18001                : [e]
18002            })
18003            .map(t ? f : n ? (r ? l : f) : c)
18004        })
18005    }.call(d.prototype),
18006      (t.onSessionChange = function(e) {
18007        var t = e.session
18008        t &&
18009          !t.multiSelect &&
18010          ((t.$selectionMarkers = []), t.selection.$initRangeList(), (t.multiSelect = t.selection)),
18011          (this.multiSelect = t && t.multiSelect)
18012        var n = e.oldSession
18013        n &&
18014          (n.multiSelect.off('addRange', this.$onAddRange),
18015          n.multiSelect.off('removeRange', this.$onRemoveRange),
18016          n.multiSelect.off('multiSelect', this.$onMultiSelect),
18017          n.multiSelect.off('singleSelect', this.$onSingleSelect),
18018          n.multiSelect.lead.off('change', this.$checkMultiselectChange),
18019          n.multiSelect.anchor.off('change', this.$checkMultiselectChange)),
18020          t &&
18021            (t.multiSelect.on('addRange', this.$onAddRange),
18022            t.multiSelect.on('removeRange', this.$onRemoveRange),
18023            t.multiSelect.on('multiSelect', this.$onMultiSelect),
18024            t.multiSelect.on('singleSelect', this.$onSingleSelect),
18025            t.multiSelect.lead.on('change', this.$checkMultiselectChange),
18026            t.multiSelect.anchor.on('change', this.$checkMultiselectChange)),
18027          t &&
18028            this.inMultiSelectMode != t.selection.inMultiSelectMode &&
18029            (t.selection.inMultiSelectMode ? this.$onMultiSelect() : this.$onSingleSelect())
18030      }),
18031      (t.MultiSelect = m),
18032      e('./config').defineOptions(d.prototype, 'editor', {
18033        enableMultiselect: {
18034          set: function(e) {
18035            m(this),
18036              e
18037                ? (this.on('changeSession', this.$multiselectOnSessionChange), this.on('mousedown', o))
18038                : (this.off('changeSession', this.$multiselectOnSessionChange), this.off('mousedown', o))
18039          },
18040          value: !0
18041        },
18042        enableBlockSelect: {
18043          set: function(e) {
18044            this.$blockSelectEnabled = e
18045          },
18046          value: !0
18047        }
18048      }))
18049  }),
18050  define('ace/mode/folding/fold_mode', ['require', 'exports', 'module', 'ace/range'], function(e, t, n) {
18051    'use strict'
18052    var r = e('../../range').Range,
18053      i = (t.FoldMode = function() {})
18054    ;(function() {
18055      ;(this.foldingStartMarker = null),
18056        (this.foldingStopMarker = null),
18057        (this.getFoldWidget = function(e, t, n) {
18058          var r = e.getLine(n)
18059          return this.foldingStartMarker.test(r)
18060            ? 'start'
18061            : t == 'markbeginend' && this.foldingStopMarker && this.foldingStopMarker.test(r)
18062            ? 'end'
18063            : ''
18064        }),
18065        (this.getFoldWidgetRange = function(e, t, n) {
18066          return null
18067        }),
18068        (this.indentationBlock = function(e, t, n) {
18069          var i = /\S/,
18070            s = e.getLine(t),
18071            o = s.search(i)
18072          if (o == -1) return
18073          var u = n || s.length,
18074            a = e.getLength(),
18075            f = t,
18076            l = t
18077          while (++t < a) {
18078            var c = e.getLine(t).search(i)
18079            if (c == -1) continue
18080            if (c <= o) break
18081            l = t
18082          }
18083          if (l > f) {
18084            var h = e.getLine(l).length
18085            return new r(f, u, l, h)
18086          }
18087        }),
18088        (this.openingBracketBlock = function(e, t, n, i, s) {
18089          var o = { row: n, column: i + 1 },
18090            u = e.$findClosingBracket(t, o, s)
18091          if (!u) return
18092          var a = e.foldWidgets[u.row]
18093          return (
18094            a == null && (a = e.getFoldWidget(u.row)),
18095            a == 'start' && u.row > o.row && (u.row--, (u.column = e.getLine(u.row).length)),
18096            r.fromPoints(o, u)
18097          )
18098        }),
18099        (this.closingBracketBlock = function(e, t, n, i, s) {
18100          var o = { row: n, column: i },
18101            u = e.$findOpeningBracket(t, o)
18102          if (!u) return
18103          return u.column++, o.column--, r.fromPoints(u, o)
18104        })
18105    }.call(i.prototype))
18106  }),
18107  define('ace/theme/textmate', ['require', 'exports', 'module', 'ace/lib/dom'], function(e, t, n) {
18108    'use strict'
18109    ;(t.isDark = !1),
18110      (t.cssClass = 'ace-tm'),
18111      (t.cssText =
18112        '.ace-tm .ace_gutter {background: #f0f0f0;color: #333;}.ace-tm .ace_print-margin {width: 1px;background: #e8e8e8;}.ace-tm .ace_fold {background-color: #6B72E6;}.ace-tm {background-color: #FFFFFF;color: black;}.ace-tm .ace_cursor {color: black;}.ace-tm .ace_invisible {color: rgb(191, 191, 191);}.ace-tm .ace_storage,.ace-tm .ace_keyword {color: blue;}.ace-tm .ace_constant {color: rgb(197, 6, 11);}.ace-tm .ace_constant.ace_buildin {color: rgb(88, 72, 246);}.ace-tm .ace_constant.ace_language {color: rgb(88, 92, 246);}.ace-tm .ace_constant.ace_library {color: rgb(6, 150, 14);}.ace-tm .ace_invalid {background-color: rgba(255, 0, 0, 0.1);color: red;}.ace-tm .ace_support.ace_function {color: rgb(60, 76, 114);}.ace-tm .ace_support.ace_constant {color: rgb(6, 150, 14);}.ace-tm .ace_support.ace_type,.ace-tm .ace_support.ace_class {color: rgb(109, 121, 222);}.ace-tm .ace_keyword.ace_operator {color: rgb(104, 118, 135);}.ace-tm .ace_string {color: rgb(3, 106, 7);}.ace-tm .ace_comment {color: rgb(76, 136, 107);}.ace-tm .ace_comment.ace_doc {color: rgb(0, 102, 255);}.ace-tm .ace_comment.ace_doc.ace_tag {color: rgb(128, 159, 191);}.ace-tm .ace_constant.ace_numeric {color: rgb(0, 0, 205);}.ace-tm .ace_variable {color: rgb(49, 132, 149);}.ace-tm .ace_xml-pe {color: rgb(104, 104, 91);}.ace-tm .ace_entity.ace_name.ace_function {color: #0000A2;}.ace-tm .ace_heading {color: rgb(12, 7, 255);}.ace-tm .ace_list {color:rgb(185, 6, 144);}.ace-tm .ace_meta.ace_tag {color:rgb(0, 22, 142);}.ace-tm .ace_string.ace_regex {color: rgb(255, 0, 0)}.ace-tm .ace_marker-layer .ace_selection {background: rgb(181, 213, 255);}.ace-tm.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px white;}.ace-tm .ace_marker-layer .ace_step {background: rgb(252, 255, 0);}.ace-tm .ace_marker-layer .ace_stack {background: rgb(164, 229, 101);}.ace-tm .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgb(192, 192, 192);}.ace-tm .ace_marker-layer .ace_active-line {background: rgba(0, 0, 0, 0.07);}.ace-tm .ace_gutter-active-line {background-color : #dcdcdc;}.ace-tm .ace_marker-layer .ace_selected-word {background: rgb(250, 250, 255);border: 1px solid rgb(200, 200, 250);}.ace-tm .ace_indent-guide {background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4b
18112Lly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y;}'),
18113      (t.$id = 'ace/theme/textmate')
18114    var r = e('../lib/dom')
18115    r.importCssString(t.cssText, t.cssClass)
18116  }),
18117  define('ace/line_widgets', ['require', 'exports', 'module', 'ace/lib/oop', 'ace/lib/dom', 'ace/range'], function(
18118    e,
18119    t,
18120    n
18121  ) {
18122    'use strict'
18123    function o(e) {
18124      ;(this.session = e),
18125        (this.session.widgetManager = this),
18126        (this.session.getRowLength = this.getRowLength),
18127        (this.session.$getWidgetScreenLength = this.$getWidgetScreenLength),
18128        (this.updateOnChange = this.updateOnChange.bind(this)),
18129        (this.renderWidgets = this.renderWidgets.bind(this)),
18130        (this.measureWidgets = this.measureWidgets.bind(this)),
18131        (this.session._changedWidgets = []),
18132        (this.$onChangeEditor = this.$onChangeEditor.bind(this)),
18133        this.session.on('change', this.updateOnChange),
18134        this.session.on('changeFold', this.updateOnFold),
18135        this.session.on('changeEditor', this.$onChangeEditor)
18136    }
18137    var r = e('./lib/oop'),
18138      i = e('./lib/dom'),
18139      s = e('./range').Range
18140    ;(function() {
18141      ;(this.getRowLength = function(e) {
18142        var t
18143        return (
18144          this.lineWidgets ? (t = (this.lineWidgets[e] && this.lineWidgets[e].rowCount) || 0) : (t = 0),
18145          !this.$useWrapMode || !this.$wrapData[e] ? 1 + t : this.$wrapData[e].length + 1 + t
18146        )
18147      }),
18148        (this.$getWidgetScreenLength = function() {
18149          var e = 0
18150          return (
18151            this.lineWidgets.forEach(function(t) {
18152              t && t.rowCount && !t.hidden && (e += t.rowCount)
18153            }),
18154            e
18155          )
18156        }),
18157        (this.$onChangeEditor = function(e) {
18158          this.attach(e.editor)
18159        }),
18160        (this.attach = function(e) {
18161          e && e.widgetManager && e.widgetManager != this && e.widgetManager.detach()
18162          if (this.editor == e) return
18163          this.detach(),
18164            (this.editor = e),
18165            e &&
18166              ((e.widgetManager = this),
18167              e.renderer.on('beforeRender', this.measureWidgets),
18168              e.renderer.on('afterRender', this.renderWidgets))
18169        }),
18170        (this.detach = function(e) {
18171          var t = this.editor
18172          if (!t) return
18173          ;(this.editor = null),
18174            (t.widgetManager = null),
18175            t.renderer.off('beforeRender', this.measureWidgets),
18176            t.renderer.off('afterRender', this.renderWidgets)
18177          var n = this.session.lineWidgets
18178          n &&
18179            n.forEach(function(e) {
18180              e && e.el && e.el.parentNode && ((e._inDocument = !1), e.el.parentNode.removeChild(e.el))
18181            })
18182        }),
18183        (this.updateOnFold = function(e, t) {
18184          var n = t.lineWidgets
18185          if (!n || !e.action) return
18186          var r = e.data,
18187            i = r.start.row,
18188            s = r.end.row,
18189            o = e.action == 'add'
18190          for (var u = i + 1; u < s; u++) n[u] && (n[u].hidden = o)
18191          n[s] &&
18192            (o ? (n[i] ? (n[s].hidden = o) : (n[i] = n[s])) : (n[i] == n[s] && (n[i] = undefined), (n[s].hidden = o)))
18193        }),
18194        (this.updateOnChange = function(e) {
18195          var t = this.session.lineWidgets
18196          if (!t) return
18197          var n = e.start.row,
18198            r = e.end.row - n
18199          if (r !== 0)
18200            if (e.action == 'remove') {
18201              var i = t.splice(n + 1, r)
18202              i.forEach(function(e) {
18203                e && this.removeLineWidget(e)
18204              }, this),
18205                this.$updateRows()
18206            } else {
18207              var s = new Array(r)
18208              s.unshift(n, 0), t.splice.apply(t, s), this.$updateRows()
18209            }
18210        }),
18211        (this.$updateRows = function() {
18212          var e = this.session.lineWidgets
18213          if (!e) return
18214          var t = !0
18215          e.forEach(function(e, n) {
18216            if (e) {
18217              ;(t = !1), (e.row = n)
18218              while (e.$oldWidget) (e.$oldWidget.row = n), (e = e.$oldWidget)
18219            }
18220          }),
18221            t && (this.session.lineWidgets = null)
18222        }),
18223        (this.addLineWidget = function(e) {
18224          this.session.lineWidgets || (this.session.lineWidgets = new Array(this.session.getLength()))
18225          var t = this.session.lineWidgets[e.row]
18226          t &&
18227            ((e.$oldWidget = t), t.el && t.el.parentNode && (t.el.parentNode.removeChild(t.el), (t._inDocument = !1))),
18228            (this.session.lineWidgets[e.row] = e),
18229            (e.session = this.session)
18230          var n = this.editor.renderer
18231          e.html && !e.el && ((e.el = i.createElement('div')), (e.el.innerHTML = e.html)),
18232            e.el &&
18233              (i.addCssClass(e.el, 'ace_lineWidgetContainer'),
18234              (e.el.style.position = 'absolute'),
18235              (e.el.style.zIndex = 5),
18236              n.container.appendChild(e.el),
18237              (e._inDocument = !0)),
18238            e.coverGutter || (e.el.style.zIndex = 3),
18239            e.pixelHeight == null && (e.pixelHeight = e.el.offsetHeight),
18240            e.rowCount == null && (e.rowCount = e.pixelHeight / n.layerConfig.lineHeight)
18241          var r = this.session.getFoldAt(e.row, 0)
18242          e.$fold = r
18243          if (r) {
18244            var s = this.session.lineWidgets
18245            e.row == r.end.row && !s[r.start.row] ? (s[r.start.row] = e) : (e.hidden = !0)
18246          }
18247          return (
18248            this.session._emit('changeFold', { data: { start: { row: e.row } } }),
18249            this.$updateRows(),
18250            this.renderWidgets(null, n),
18251            this.onWidgetChanged(e),
18252            e
18253          )
18254        }),
18255        (this.removeLineWidget = function(e) {
18256          ;(e._inDocument = !1), (e.session = null), e.el && e.el.parentNode && e.el.parentNode.removeChild(e.el)
18257          if (e.editor && e.editor.destroy)
18258            try {
18259              e.editor.destroy()
18260            } catch (t) {}
18261          if (this.session.lineWidgets) {
18262            var n = this.session.lineWidgets[e.row]
18263            if (n == e)
18264              (this.session.lineWidgets[e.row] = e.$oldWidget), e.$oldWidget && this.onWidgetChanged(e.$oldWidget)
18265            else
18266              while (n) {
18267                if (n.$oldWidget == e) {
18268                  n.$oldWidget = e.$oldWidget
18269                  break
18270                }
18271                n = n.$oldWidget
18272              }
18273          }
18274          this.session._emit('changeFold', { data: { start: { row: e.row } } }), this.$updateRows()
18275        }),
18276        (this.getWidgetsAtRow = function(e) {
18277          var t = this.session.lineWidgets,
18278            n = t && t[e],
18279            r = []
18280          while (n) r.push(n), (n = n.$oldWidget)
18281          return r
18282        }),
18283        (this.onWidgetChanged = function(e) {
18284          this.session._changedWidgets.push(e), this.editor && this.editor.renderer.updateFull()
18285        }),
18286        (this.measureWidgets = function(e, t) {
18287          var n = this.session._changedWidgets,
18288            r = t.layerConfig
18289          if (!n || !n.length) return
18290          var i = Infinity
18291          for (var s = 0; s < n.length; s++) {
18292            var o = n[s]
18293            if (!o || !o.el) continue
18294            if (o.session != this.session) continue
18295            if (!o._inDocument) {
18296              if (this.session.lineWidgets[o.row] != o) continue
18297              ;(o._inDocument = !0), t.container.appendChild(o.el)
18298            }
18299            ;(o.h = o.el.offsetHeight),
18300              o.fixedWidth || ((o.w = o.el.offsetWidth), (o.screenWidth = Math.ceil(o.w / r.characterWidth)))
18301            var u = o.h / r.lineHeight
18302            o.coverLine && ((u -= this.session.getRowLineCount(o.row)), u < 0 && (u = 0)),
18303              o.rowCount != u && ((o.rowCount = u), o.row < i && (i = o.row))
18304          }
18305          i != Infinity &&
18306            (this.session._emit('changeFold', { data: { start: { row: i } } }), (this.session.lineWidgetWidth = null)),
18307            (this.session._changedWidgets = [])
18308        }),
18309        (this.renderWidgets = function(e, t) {
18310          var n = t.layerConfig,
18311            r = this.session.lineWidgets
18312          if (!r) return
18313          var i = Math.min(this.firstRow, n.firstRow),
18314            s = Math.max(this.lastRow, n.lastRow, r.length)
18315          while (i > 0 && !r[i]) i--
18316          ;(this.firstRow = n.firstRow), (this.lastRow = n.lastRow), (t.$cursorLayer.config = n)
18317          for (var o = i; o <= s; o++) {
18318            var u = r[o]
18319            if (!u || !u.el) continue
18320            if (u.hidden) {
18321              u.el.style.top = -100 - (u.pixelHeight || 0) + 'px'
18322              continue
18323            }
18324            u._inDocument || ((u._inDocument = !0), t.container.appendChild(u.el))
18325            var a = t.$cursorLayer.getPixelPosition({ row: o, column: 0 }, !0).top
18326            u.coverLine || (a += n.lineHeight * this.session.getRowLineCount(u.row)),
18327              (u.el.style.top = a - n.offset + 'px')
18328            var f = u.coverGutter ? 0 : t.gutterWidth
18329            u.fixedWidth || (f -= t.scrollLeft),
18330              (u.el.style.left = f + 'px'),
18331              u.fullWidth && u.screenWidth && (u.el.style.minWidth = n.width + 2 * n.padding + 'px'),
18332              u.fixedWidth ? (u.el.style.right = t.scrollBar.getWidth() + 'px') : (u.el.style.right = '')
18333          }
18334        })
18335    }.call(o.prototype),
18336      (t.LineWidgets = o))
18337  }),
18338  define('ace/ext/error_marker', [
18339    'require',
18340    'exports',
18341    'module',
18342    'ace/line_widgets',
18343    'ace/lib/dom',
18344    'ace/range'
18345  ], function(e, t, n) {
18346    'use strict'
18347    function o(e, t, n) {
18348      var r = 0,
18349        i = e.length - 1
18350      while (r <= i) {
18351        var s = (r + i) >> 1,
18352          o = n(t, e[s])
18353        if (o > 0) r = s + 1
18354        else {
18355          if (!(o < 0)) return s
18356          i = s - 1
18357        }
18358      }
18359      return -(r + 1)
18360    }
18361    function u(e, t, n) {
18362      var r = e.getAnnotations().sort(s.comparePoints)
18363      if (!r.length) return
18364      var i = o(r, { row: t, column: -1 }, s.comparePoints)
18365      i < 0 && (i = -i - 1), i >= r.length ? (i = n > 0 ? 0 : r.length - 1) : i === 0 && n < 0 && (i = r.length - 1)
18366      var u = r[i]
18367      if (!u || !n) return
18368      if (u.row === t) {
18369        do u = r[(i += n)]
18370        while (u && u.row === t)
18371        if (!u) return r.slice()
18372      }
18373      var a = []
18374      t = u.row
18375      do a[n < 0 ? 'unshift' : 'push'](u), (u = r[(i += n)])
18376      while (u && u.row == t)
18377      return a.length && a
18378    }
18379    var r = e('../line_widgets').LineWidgets,
18380      i = e('../lib/dom'),
18381      s = e('../range').Range
18382    ;(t.showErrorMarker = function(e, t) {
18383      var n = e.session
18384      n.widgetManager || ((n.widgetManager = new r(n)), n.widgetManager.attach(e))
18385      var s = e.getCursorPosition(),
18386        o = s.row,
18387        a = n.widgetManager.getWidgetsAtRow(o).filter(function(e) {
18388          return e.type == 'errorMarker'
18389        })[0]
18390      a ? a.destroy() : (o -= t)
18391      var f = u(n, o, t),
18392        l
18393      if (f) {
18394        var c = f[0]
18395        ;(s.column = (c.pos && typeof c.column != 'number' ? c.pos.sc : c.column) || 0),
18396          (s.row = c.row),
18397          (l = e.renderer.$gutterLayer.$annotations[s.row])
18398      } else {
18399        if (a) return
18400        l = { text: ['Looks good!'], className: 'ace_ok' }
18401      }
18402      e.session.unfold(s.row), e.selection.moveToPosition(s)
18403      var h = { row: s.row, fixedWidth: !0, coverGutter: !0, el: i.createElement('div'), type: 'errorMarker' },
18404        p = h.el.appendChild(i.createElement('div')),
18405        d = h.el.appendChild(i.createElement('div'))
18406      d.className = 'error_widget_arrow ' + l.className
18407      var v = e.renderer.$cursorLayer.getPixelPosition(s).left
18408      ;(d.style.left = v + e.renderer.gutterWidth - 5 + 'px'),
18409        (h.el.className = 'error_widget_wrapper'),
18410        (p.className = 'error_widget ' + l.className),
18411        (p.innerHTML = l.text.join('<br>')),
18412        p.appendChild(i.createElement('div'))
18413      var m = function(e, t, n) {
18414        if (t === 0 && (n === 'esc' || n === 'return')) return h.destroy(), { command: 'null' }
18415      }
18416      ;(h.destroy = function() {
18417        if (e.$mouseHandler.isMousePressed) return
18418        e.keyBinding.removeKeyboardHandler(m),
18419          n.widgetManager.removeLineWidget(h),
18420          e.off('changeSelection', h.destroy),
18421          e.off('changeSession', h.destroy),
18422          e.off('mouseup', h.destroy),
18423          e.off('change', h.destroy)
18424      }),
18425        e.keyBinding.addKeyboardHandler(m),
18426        e.on('changeSelection', h.destroy),
18427        e.on('changeSession', h.destroy),
18428        e.on('mouseup', h.destroy),
18429        e.on('change', h.destroy),
18430        e.session.widgetManager.addLineWidget(h),
18431        (h.el.onmousedown = e.focus.bind(e)),
18432        e.renderer.scrollCursorIntoView(null, 0.5, { bottom: h.el.offsetHeight })
18433    }),
18434      i.importCssString(
18435        '    .error_widget_wrapper {        background: inherit;        color: inherit;        border:none    }    .error_widget {        border-top: solid 2px;        border-bottom: solid 2px;        margin: 5px 0;        padding: 10px 40px;        white-space: pre-wrap;    }    .error_widget.ace_error, .error_widget_arrow.ace_error{        border-color: #ff5a5a    }    .error_widget.ace_warning, .error_widget_arrow.ace_warning{        border-color: #F1D817    }    .error_widget.ace_info, .error_widget_arrow.ace_info{        border-color: #5a5a5a    }    .error_widget.ace_ok, .error_widget_arrow.ace_ok{        border-color: #5aaa5a    }    .error_widget_arrow {        position: absolute;        border: solid 5px;        border-top-color: transparent!important;        border-right-color: transparent!important;        border-left-color: transparent!important;        top: -5px;    }',
18436        ''
18437      )
18438  }),
18439  define('ace/ace', [
18440    'require',
18441    'exports',
18442    'module',
18443    'ace/lib/fixoldbrowsers',
18444    'ace/lib/dom',
18445    'ace/lib/event',
18446    'ace/range',
18447    'ace/editor',
18448    'ace/edit_session',
18449    'ace/undomanager',
18450    'ace/virtual_renderer',
18451    'ace/worker/worker_client',
18452    'ace/keyboard/hash_handler',
18453    'ace/placeholder',
18454    'ace/multi_select',
18455    'ace/mode/folding/fold_mode',
18456    'ace/theme/textmate',
18457    'ace/ext/error_marker',
18458    'ace/config'
18459  ], function(e, t, n) {
18460    'use strict'
18461    e('./lib/fixoldbrowsers')
18462    var r = e('./lib/dom'),
18463      i = e('./lib/event'),
18464      s = e('./range').Range,
18465      o = e('./editor').Editor,
18466      u = e('./edit_session').EditSession,
18467      a = e('./undomanager').UndoManager,
18468      f = e('./virtual_renderer').VirtualRenderer
18469    e('./worker/worker_client'),
18470      e('./keyboard/hash_handler'),
18471      e('./placeholder'),
18472      e('./multi_select'),
18473      e('./mode/folding/fold_mode'),
18474      e('./theme/textmate'),
18475      e('./ext/error_marker'),
18476      (t.config = e('./config')),
18477      (t.require = e),
18478      typeof define == 'function' && (t.define = define),
18479      (t.edit = function(e, n) {
18480        if (typeof e == 'string') {
18481          var s = e
18482          e = document.getElementById(s)
18483          if (!e) throw new Error("ace.edit can't find div #" + s)
18484        }
18485        if (e && e.env && e.env.editor instanceof o) return e.env.editor
18486        var u = ''
18487        if (e && /input|textarea/i.test(e.tagName)) {
18488          var a = e
18489          ;(u = a.value), (e = r.createElement('pre')), a.parentNode.replaceChild(e, a)
18490        } else e && ((u = e.textContent), (e.innerHTML = ''))
18491        var l = t.createEditSession(u),
18492          c = new o(new f(e), l, n),
18493          h = { document: l, editor: c, onResize: c.resize.bind(c, null) }
18494        return (
18495          a && (h.textarea = a),
18496          i.addListener(window, 'resize', h.onResize),
18497          c.on('destroy', function() {
18498            i.removeListener(window, 'resize', h.onResize), (h.editor.container.env = null)
18499          }),
18500          (c.container.env = c.env = h),
18501          c
18502        )
18503      }),
18504      (t.createEditSession = function(e, t) {
18505        var n = new u(e, t)
18506        return n.setUndoManager(new a()), n
18507      }),
18508      (t.Range = s),
18509      (t.EditSession = u),
18510      (t.UndoManager = a),
18511      (t.VirtualRenderer = f),
18512      (t.version = '1.3.3')
18513  })
18514;(function() {
18515  window.require(['ace/ace'], function(a) {
18516    if (a) {
18517      a.config.init(true)
18518      a.define = window.define
18519    }
18520    if (!window.ace_rails) window.ace_rails = a
18521    for (var key in a) if (a.hasOwnProperty(key)) window.ace_rails[key] = a[key]
18522    window.ace_rails['default'] = window.ace_rails
18523    if (typeof module == 'object' && typeof exports == 'object' && module) {
18524      module.exports = window.ace_rails
18525    }
18526  })
18527})();
18528// Copy From: https://cdnjs.cloudflare.com/ajax/libs/ace/1.3.3/ext-searchbox.js
18529define('ace/ext/searchbox', [
18530  'require',
18531  'exports',
18532  'module',
18533  'ace/lib/dom',
18534  'ace/lib/lang',
18535  'ace/lib/event',
18536  'ace/keyboard/hash_handler',
18537  'ace/lib/keys'
18538], function(e, t, n) {
18539  'use strict'
18540  var r = e('../lib/dom'),
18541    i = e('../lib/lang'),
18542    s = e('../lib/event'),
18543    o =
18544      '.ace_search {background-color: #ddd;color: #666;border: 1px solid #cbcbcb;border-top: 0 none;overflow: hidden;margin: 0;padding: 4px 6px 0 4px;position: absolute;top: 0;z-index: 99;white-space: normal;}.ace_search.left {border-left: 0 none;border-radius: 0px 0px 5px 0px;left: 0;}.ace_search.right {border-radius: 0px 0px 0px 5px;border-right: 0 none;right: 0;}.ace_search_form, .ace_replace_form {margin: 0 20px 4px 0;overflow: hidden;line-height: 1.9;}.ace_replace_form {margin-right: 0;}.ace_search_form.ace_nomatch {outline: 1px solid red;}.ace_search_field {border-radius: 3px 0 0 3px;background-color: white;color: black;border: 1px solid #cbcbcb;border-right: 0 none;box-sizing: border-box!important;outline: 0;padding: 0;font-size: inherit;margin: 0;line-height: inherit;padding: 0 6px;min-width: 17em;vertical-align: top;}.ace_searchbtn {border: 1px solid #cbcbcb;line-height: inherit;display: inline-block;padding: 0 6px;background: #fff;border-right: 0 none;border-left: 1px solid #dcdcdc;cursor: pointer;margin: 0;position: relative;box-sizing: content-box!important;color: #666;}.ace_searchbtn:last-child {border-radius: 0 3px 3px 0;border-right: 1px solid #cbcbcb;}.ace_searchbtn:disabled {background: none;cursor: default;}.ace_searchbtn:hover {background-color: #eef1f6;}.ace_searchbtn.prev, .ace_searchbtn.next {padding: 0px 0.7em}.ace_searchbtn.prev:after, .ace_searchbtn.next:after {content: "";border: solid 2px #888;width: 0.5em;height: 0.5em;border-width:  2px 0 0 2px;display:inline-block;transform: rotate(-45deg);}.ace_searchbtn.next:after {border-width: 0 2px 2px 0 ;}.ace_searchbtn_close {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAcCAYAAABRVo5BAAAAZ0lEQVR42u2SUQrAMAhDvazn8OjZBilCkYVVxiis8H4CT0VrAJb4WHT3C5xU2a2IQZXJjiQIRMdkEoJ5Q2yMqpfDIo+XY4k6h+YXOyKqTIj5REaxloNAd0xiKmAtsTHqW8sR2W5f7gCu5nWFUpVjZwAAAABJRU5ErkJggg==) no-repeat 50% 0;border-radius: 50%;border: 0 none;color: #656565;cursor: pointer;font: 16px/16px Arial;padding: 0;height: 14px;width: 14px;top: 9px;right: 7px;position: absolute;}.ace_searchbtn_close:hover {background-color: #656565;background-position: 50% 100%;color: white;}.ace_button {margin-left: 2px;
18544cursor: pointer;-webkit-user-select: none;-moz-user-select: none;-o-user-select: none;-ms-user-select: none;user-select: none;overflow: hidden;opacity: 0.7;border: 1px solid rgba(100,100,100,0.23);padding: 1px;box-sizing:    border-box!important;color: black;}.ace_button:hover {background-color: #eee;opacity:1;}.ace_button:active {background-color: #ddd;}.ace_button.checked {border-color: #3399ff;opacity:1;}.ace_search_options{margin-bottom: 3px;text-align: right;-webkit-user-select: none;-moz-user-select: none;-o-user-select: none;-ms-user-select: none;user-select: none;clear: both;}.ace_search_counter {float: left;font-family: arial;padding: 0 8px;}',
18545    u = e('../keyboard/hash_handler').HashHandler,
18546    a = e('../lib/keys'),
18547    f = 999
18548  r.importCssString(o, 'ace_searchbox')
18549  var l = '<div class="ace_search right">    <span action="hide" class="ace_searchbtn_close"></span>    <div class="ace_search_form">        <input class="ace_search_field" placeholder="Search for" spellcheck="false"></input>        <span action="findPrev" class="ace_searchbtn prev"></span>        <span action="findNext" class="ace_searchbtn next"></span>        <span action="findAll" class="ace_searchbtn" title="Alt-Enter">All</span>    </div>    <div class="ace_replace_form">        <input class="ace_search_field" placeholder="Replace with" spellcheck="false"></input>        <span action="replaceAndFindNext" class="ace_searchbtn">Replace</span>        <span action="replaceAll" class="ace_searchbtn">All</span>    </div>    <div class="ace_search_options">        <span action="toggleReplace" class="ace_button" title="Toggle Replace mode"            style="float:left;margin-top:-2px;padding:0 5px;">+</span>        <span class="ace_search_counter"></span>        <span action="toggleRegexpMode" class="ace_button" title="RegExp Search">.*</span>        <span action="toggleCaseSensitive" class="ace_button" title="CaseSensitive Search">Aa</span>        <span action="toggleWholeWords" class="ace_button" title="Whole Word Search">\\b</span>        <span action="searchInSelection" class="ace_button" title="Search In Selection">S</span>    </div></div>'.replace(
18550      /> +/g,
18551      '>'
18552    ),
18553    c = function(e, t, n) {
18554      var i = r.createElement('div')
18555      ;(i.innerHTML = l),
18556        (this.element = i.firstChild),
18557        (this.setSession = this.setSession.bind(this)),
18558        this.$init(),
18559        this.setEditor(e)
18560    }
18561  ;(function() {
18562    ;(this.setEditor = function(e) {
18563      ;(e.searchBox = this), e.renderer.scroller.appendChild(this.element), (this.editor = e)
18564    }),
18565      (this.setSession = function(e) {
18566        ;(this.searchRange = null), this.$syncOptions(!0)
18567      }),
18568      (this.$initElements = function(e) {
18569        ;(this.searchBox = e.querySelector('.ace_search_form')),
18570          (this.replaceBox = e.querySelector('.ace_replace_form')),
18571          (this.searchOption = e.querySelector('[action=searchInSelection]')),
18572          (this.replaceOption = e.querySelector('[action=toggleReplace]')),
18573          (this.regExpOption = e.querySelector('[action=toggleRegexpMode]')),
18574          (this.caseSensitiveOption = e.querySelector('[action=toggleCaseSensitive]')),
18575          (this.wholeWordOption = e.querySelector('[action=toggleWholeWords]')),
18576          (this.searchInput = this.searchBox.querySelector('.ace_search_field')),
18577          (this.replaceInput = this.replaceBox.querySelector('.ace_search_field')),
18578          (this.searchCounter = e.querySelector('.ace_search_counter'))
18579      }),
18580      (this.$init = function() {
18581        var e = this.element
18582        this.$initElements(e)
18583        var t = this
18584        s.addListener(e, 'mousedown', function(e) {
18585          setTimeout(function() {
18586            t.activeInput.focus()
18587          }, 0),
18588            s.stopPropagation(e)
18589        }),
18590          s.addListener(e, 'click', function(e) {
18591            var n = e.target || e.srcElement,
18592              r = n.getAttribute('action')
18593            r && t[r] ? t[r]() : t.$searchBarKb.commands[r] && t.$searchBarKb.commands[r].exec(t), s.stopPropagation(e)
18594          }),
18595          s.addCommandKeyListener(e, function(e, n, r) {
18596            var i = a.keyCodeToString(r),
18597              o = t.$searchBarKb.findKeyCommand(n, i)
18598            o && o.exec && (o.exec(t), s.stopEvent(e))
18599          }),
18600          (this.$onChange = i.delayedCall(function() {
18601            t.find(!1, !1)
18602          })),
18603          s.addListener(this.searchInput, 'input', function() {
18604            t.$onChange.schedule(20)
18605          }),
18606          s.addListener(this.searchInput, 'focus', function() {
18607            ;(t.activeInput = t.searchInput), t.searchInput.value && t.highlight()
18608          }),
18609          s.addListener(this.replaceInput, 'focus', function() {
18610            ;(t.activeInput = t.replaceInput), t.searchInput.value && t.highlight()
18611          })
18612      }),
18613      (this.$closeSearchBarKb = new u([
18614        {
18615          bindKey: 'Esc',
18616          name: 'closeSearchBar',
18617          exec: function(e) {
18618            e.searchBox.hide()
18619          }
18620        }
18621      ])),
18622      (this.$searchBarKb = new u()),
18623      this.$searchBarKb.bindKeys({
18624        'Ctrl-f|Command-f': function(e) {
18625          var t = (e.isReplace = !e.isReplace)
18626          ;(e.replaceBox.style.display = t ? '' : 'none'),
18627            (e.replaceOption.checked = !1),
18628            e.$syncOptions(),
18629            e.searchInput.focus()
18630        },
18631        'Ctrl-H|Command-Option-F': function(e) {
18632          ;(e.replaceOption.checked = !0), e.$syncOptions(), e.replaceInput.focus()
18633        },
18634        'Ctrl-G|Command-G': function(e) {
18635          e.findNext()
18636        },
18637        'Ctrl-Shift-G|Command-Shift-G': function(e) {
18638          e.findPrev()
18639        },
18640        esc: function(e) {
18641          setTimeout(function() {
18642            e.hide()
18643          })
18644        },
18645        Return: function(e) {
18646          e.activeInput == e.replaceInput && e.replace(), e.findNext()
18647        },
18648        'Shift-Return': function(e) {
18649          e.activeInput == e.replaceInput && e.replace(), e.findPrev()
18650        },
18651        'Alt-Return': function(e) {
18652          e.activeInput == e.replaceInput && e.replaceAll(), e.findAll()
18653        },
18654        Tab: function(e) {
18655          ;(e.activeInput == e.replaceInput ? e.searchInput : e.replaceInput).focus()
18656        }
18657      }),
18658      this.$searchBarKb.addCommands([
18659        {
18660          name: 'toggleRegexpMode',
18661          bindKey: { win: 'Alt-R|Alt-/', mac: 'Ctrl-Alt-R|Ctrl-Alt-/' },
18662          exec: function(e) {
18663            ;(e.regExpOption.checked = !e.regExpOption.checked), e.$syncOptions()
18664          }
18665        },
18666        {
18667          name: 'toggleCaseSensitive',
18668          bindKey: { win: 'Alt-C|Alt-I', mac: 'Ctrl-Alt-R|Ctrl-Alt-I' },
18669          exec: function(e) {
18670            ;(e.caseSensitiveOption.checked = !e.caseSensitiveOption.checked), e.$syncOptions()
18671          }
18672        },
18673        {
18674          name: 'toggleWholeWords',
18675          bindKey: { win: 'Alt-B|Alt-W', mac: 'Ctrl-Alt-B|Ctrl-Alt-W' },
18676          exec: function(e) {
18677            ;(e.wholeWordOption.checked = !e.wholeWordOption.checked), e.$syncOptions()
18678          }
18679        },
18680        {
18681          name: 'toggleReplace',
18682          exec: function(e) {
18683            ;(e.replaceOption.checked = !e.replaceOption.checked), e.$syncOptions()
18684          }
18685        },
18686        {
18687          name: 'searchInSelection',
18688          exec: function(e) {
18689            ;(e.searchOption.checked = !e.searchRange),
18690              e.setSearchRange(e.searchOption.checked && e.editor.getSelectionRange()),
18691              e.$syncOptions()
18692          }
18693        }
18694      ]),
18695      (this.setSearchRange = function(e) {
18696        ;(this.searchRange = e),
18697          e
18698            ? (this.searchRangeMarker = this.editor.session.addMarker(e, 'ace_active-line'))
18699            : this.searchRangeMarker &&
18700              (this.editor.session.removeMarker(this.searchRangeMarker), (this.searchRangeMarker = null))
18701      }),
18702      (this.$syncOptions = function(e) {
18703        r.setCssClass(this.replaceOption, 'checked', this.searchRange),
18704          r.setCssClass(this.searchOption, 'checked', this.searchOption.checked),
18705          (this.replaceOption.textContent = this.replaceOption.checked ? '-' : '+'),
18706          r.setCssClass(this.regExpOption, 'checked', this.regExpOption.checked),
18707          r.setCssClass(this.wholeWordOption, 'checked', this.wholeWordOption.checked),
18708          r.setCssClass(this.caseSensitiveOption, 'checked', this.caseSensitiveOption.checked),
18709          (this.replaceBox.style.display = this.replaceOption.checked ? '' : 'none'),
18710          this.find(!1, !1, e)
18711      }),
18712      (this.highlight = function(e) {
18713        this.editor.session.highlight(e || this.editor.$search.$options.re), this.editor.renderer.updateBackMarkers()
18714      }),
18715      (this.find = function(e, t, n) {
18716        var i = this.editor.find(this.searchInput.value, {
18717            skipCurrent: e,
18718            backwards: t,
18719            wrap: !0,
18720            regExp: this.regExpOption.checked,
18721            caseSensitive: this.caseSensitiveOption.checked,
18722            wholeWord: this.wholeWordOption.checked,
18723            preventScroll: n,
18724            range: this.searchRange
18725          }),
18726          s = !i && this.searchInput.value
18727        r.setCssClass(this.searchBox, 'ace_nomatch', s),
18728          this.editor._emit('findSearchBox', { match: !s }),
18729          this.highlight(),
18730          this.updateCounter()
18731      }),
18732      (this.updateCounter = function() {
18733        var e = this.editor,
18734          t = e.$search.$options.re,
18735          n = 0,
18736          r = 0
18737        if (t) {
18738          var i = this.searchRange ? e.session.getTextRange(this.searchRange) : e.getValue(),
18739            s = e.session.doc.positionToIndex(e.selection.anchor)
18740          this.searchRange && (s -= e.session.doc.positionToIndex(this.searchRange.start))
18741          var o = (t.lastIndex = 0),
18742            u
18743          while ((u = t.exec(i))) {
18744            n++, (o = u.index), o <= s && r++
18745            if (n > f) break
18746            if (!u[0]) {
18747              t.lastIndex = o += 1
18748              if (o >= i.length) break
18749            }
18750          }
18751        }
18752        this.searchCounter.textContent = r + ' of ' + (n > f ? f + '+' : n)
18753      }),
18754      (this.findNext = function() {
18755        this.find(!0, !1)
18756      }),
18757      (this.findPrev = function() {
18758        this.find(!0, !0)
18759      }),
18760      (this.findAll = function() {
18761        var e = this.editor.findAll(this.searchInput.value, {
18762            regExp: this.regExpOption.checked,
18763            caseSensitive: this.caseSensitiveOption.checked,
18764            wholeWord: this.wholeWordOption.checked
18765          }),
18766          t = !e && this.searchInput.value
18767        r.setCssClass(this.searchBox, 'ace_nomatch', t),
18768          this.editor._emit('findSearchBox', { match: !t }),
18769          this.highlight(),
18770          this.hide()
18771      }),
18772      (this.replace = function() {
18773        this.editor.getReadOnly() || this.editor.replace(this.replaceInput.value)
18774      }),
18775      (this.replaceAndFindNext = function() {
18776        this.editor.getReadOnly() || (this.editor.replace(this.replaceInput.value), this.findNext(
18776))
18777      }),
18778      (this.replaceAll = function() {
18779        this.editor.getReadOnly() || this.editor.replaceAll(this.replaceInput.value)
18780      }),
18781      (this.hide = function() {
18782        ;(this.active = !1),
18783          this.setSearchRange(null),
18784          this.editor.off('changeSession', this.setSession),
18785          (this.element.style.display = 'none'),
18786          this.editor.keyBinding.removeKeyboardHandler(this.$closeSearchBarKb),
18787          this.editor.focus()
18788      }),
18789      (this.show = function(e, t) {
18790        ;(this.active = !0),
18791          this.editor.on('changeSession', this.setSession),
18792          (this.element.style.display = ''),
18793          (this.replaceOption.checked = t),
18794          e && (this.searchInput.value = e),
18795          this.searchInput.focus(),
18796          this.searchInput.select(),
18797          this.editor.keyBinding.addKeyboardHandler(this.$closeSearchBarKb),
18798          this.$syncOptions(!0)
18799      }),
18800      (this.isFocused = function() {
18801        var e = document.activeElement
18802        return e == this.searchInput || e == this.replaceInput
18803      })
18804  }.call(c.prototype),
18805    (t.SearchBox = c),
18806    (t.Search = function(e, t) {
18807      var n = e.searchBox || new c(e)
18808      n.show(e.session.getTextRange(), t)
18809    }))
18810})
18811;(function() {
18812  window.require(['ace/ext/searchbox'], function(m) {
18813    if (typeof module == 'object' && typeof exports == 'object' && module) {
18814      module.exports = m
18815    }
18816  })
18817})();
18818// Copy From: https://cdnjs.cloudflare.com/ajax/libs/ace/1.3.3/mode-liquid.js
18819define('ace/mode/css_highlight_rules', [
18820  'require',
18821  'exports',
18822  'module',
18823  'ace/lib/oop',
18824  'ace/lib/lang',
18825  'ace/mode/text_highlight_rules'
18826], function(e, t, n) {
18827  'use strict'
18828  var r = e('../lib/oop'),
18829    i = e('../lib/lang'),
18830    s = e('./text_highlight_rules').TextHighlightRules,
18831    o = (t.supportType =
18832      'align-content|align-items|align-self|all|animation|animation-delay|animation-direction|animation-duration|animation-fill-mode|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|backface-visibility|background|background-attachment|background-blend-mode|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|border|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|bottom|box-shadow|box-sizing|caption-side|clear|clip|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|cursor|direction|display|empty-cells|filter|flex|flex-basis|flex-direction|flex-flow|flex-grow|flex-shrink|flex-wrap|float|font|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|hanging-punctuation|height|justify-content|left|letter-spacing|line-height|list-style|list-style-image|list-style-position|list-style-type|margin|margin-bottom|margin-left|margin-right|margin-top|max-height|max-width|max-zoom|min-height|min-width|min-zoom|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|order|outline|outline-color|outline-offset|outline-style|outline-width|overflow|overflow-x|overflow-y|padding|padding-bottom|padding-left|padding-right|padding-top|page-break-after|page-break-before|page-break-inside|perspective|perspective-origin|position|quotes|resize|right|tab-size|table-layout|text-align|text-align-last|text-decoration|text-decoration-color|text-decoration-line|text-decoration-style|text-indent|text-justify|text-overflow|text-shadow|text-transform|top|transform|transform-origin|transform-style|transition|transition-delay|transition-duration|transition-property|transition-timing-function|unicode
18832-bidi|user-select|user-zoom|vertical-align|visibility|white-space|width|word-break|word-spacing|word-wrap|z-index'),
18833    u = (t.supportFunction = 'rgb|rgba|url|attr|counter|counters'),
18834    a = (t.supportConstant =
18835      'absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero|zoom'),
18836    f = (t.supportConstantColor =
18837      'aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen'),
18838    l = (t.supportConstantFonts =
18839      'arial|century|comic|courier|cursive|fantasy|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace'),
18840    c = (t.numRe = '\\-?(?:(?:[0-9]+(?:\\.[0-9]+)?)|(?:\\.[0-9]+))'),
18841    h = (t.pseudoElements = '(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b'),
18842    p = (t.pseudoClasses =
18843      '(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b'),
18844    d = function() {
18845      var e = this.createKeywordMapper(
18846        {
18847          'support.function': u,
18848          'support.constant': a,
18849          'support.type': o,
18850          'support.constant.color': f,
18851          'support.constant.fonts': l
18852        },
18853        'text',
18854        !0
18855      )
18856      ;(this.$rules = {
18857        start: [
18858          { include: ['strings', 'url', 'comments'] },
18859          { token: 'paren.lparen', regex: '\\{', next: 'ruleset' },
18860          { token: 'paren.rparen', regex: '\\}' },
18861          { token: 'string', regex: '@(?!viewport)', next: 'media' },
18862          { token: 'keyword', regex: '#[a-z0-9-_]+' },
18863          { token: 'keyword', regex: '%' },
18864          { token: 'variable', regex: '\\.[a-z0-9-_]+' },
18865          { token: 'string', regex: ':[a-z0-9-_]+' },
18866          { token: 'constant.numeric', regex: c },
18867          { token: 'constant', regex: '[a-z0-9-_]+' },
18868          { caseInsensitive: !0 }
18869        ],
18870        media: [
18871          { include: ['strings', 'url', 'comments'] },
18872          { token: 'paren.lparen', regex: '\\{', next: 'start' },
18873          { token: 'paren.rparen', regex: '\\}', next: 'start' },
18874          { token: 'string', regex: ';', next: 'start' },
18875          {
18876            token: 'keyword',
18877            regex:
18878              '(?:media|supports|document|charset|import|namespace|media|supports|document|page|font|keyframes|viewport|counter-style|font-feature-values|swash|ornaments|annotation|stylistic|styleset|character-variant)'
18879          }
18880        ],
18881        comments: [
18882          {
18883            token: 'comment',
18884            regex: '\\/\\*',
18885            push: [{ token: 'comment', regex: '\\*\\/', next: 'pop' }, { defaultToken: 'comment' }]
18886          }
18887        ],
18888        ruleset: [
18889          { regex: '-(webkit|ms|moz|o)-', token: 'text' },
18890          { token: 'punctuation.operator', regex: '[:;]' },
18891          { token: 'paren.rparen', regex: '\\}', next: 'start' },
18892          { include: ['strings', 'url', 'comments'] },
18893          {
18894            token: ['constant.numeric', 'keyword'],
18895            regex:
18896              '(' + c + ')(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vmax|vmin|vm|vw|%)'
18897          },
18898          { token: 'constant.numeric', regex: c },
18899          { token: 'constant.numeric', regex: '#[a-f0-9]{6}' },
18900          { token: 'constant.numeric', regex: '#[a-f0-9]{3}' },
18901          { token: ['punctuation', 'entity.other.attribute-name.pseudo-element.css'], regex: h },
18902          { token: ['punctuation', 'entity.other.attribute-name.pseudo-class.css'], regex: p },
18903          { include: 'url' },
18904          { token: e, regex: '\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*' },
18905          { caseInsensitive: !0 }
18906        ],
18907        url: [
18908          {
18909            token: 'support.function',
18910            regex: '(?:url(:?-prefix)?|domain|regexp)\\(',
18911            push: [{ token: 'support.function', regex: '\\)', next: 'pop' }, { defaultToken: 'string' }]
18912          }
18913        ],
18914        strings: [
18915          {
18916            token: 'string.start',
18917            regex: "'",
18918            push: [
18919              { token: 'string.end', regex: "'|$", next: 'pop' },
18920              { include: 'escapes' },
18921              { token: 'constant.language.escape', regex: /\\$/, consumeLineEnd: !0 },
18922              { defaultToken: 'string' }
18923            ]
18924          },
18925          {
18926            token: 'string.start',
18927            regex: '"',
18928            push: [
18929              { token: 'string.end', regex: '"|$', next: 'pop' },
18930              { include: 'escapes' },
18931              { token: 'constant.language.escape', regex: /\\$/, consumeLineEnd: !0 },
18932              { defaultToken: 'string' }
18933            ]
18934          }
18935        ],
18936        escapes: [{ token: 'constant.language.escape', regex: /\\([a-fA-F\d]{1,6}|[^a-fA-F\d])/ }]
18937      }),
18938        this.normalizeRules()
18939    }
18940  r.inherits(d, s), (t.CssHighlightRules = d)
18941}),
18942  define('ace/mode/doc_comment_highlight_rules', [
18943    'require',
18944    'exports',
18945    'module',
18946    'ace/lib/oop',
18947    'ace/mode/text_highlight_rules'
18948  ], function(e, t, n) {
18949    'use strict'
18950    var r = e('../lib/oop'),
18951      i = e('./text_highlight_rules').TextHighlightRules,
18952      s = function() {
18953        this.$rules = {
18954          start: [
18955            { token: 'comment.doc.tag', regex: '@[\\w\\d_]+' },
18956            s.getTagRule(),
18957            { defaultToken: 'comment.doc', caseInsensitive: !0 }
18958          ]
18959        }
18960      }
18961    r.inherits(s, i),
18962      (s.getTagRule = function(e) {
18963        return { token: 'comment.doc.tag.storage.type', regex: '\\b(?:TODO|FIXME|XXX|HACK)\\b' }
18964      }),
18965      (s.getStartRule = function(e) {
18966        return { token: 'comment.doc', regex: '\\/\\*(?=\\*)', next: e }
18967      }),
18968      (s.getEndRule = function(e) {
18969        return { token: 'comment.doc', regex: '\\*\\/', next: e }
18970      }),
18971      (t.DocCommentHighlightRules = s)
18972  }),
18973  define('ace/mode/javascript_highlight_rules', [
18974    'require',
18975    'exports',
18976    'module',
18977    'ace/lib/oop',
18978    'ace/mode/doc_comment_highlight_rules',
18979    'ace/mode/text_highlight_rules'
18980  ], function(e, t, n) {
18981    'use strict'
18982    function a() {
18983      var e = o.replace('\\d', '\\d\\-'),
18984        t = {
18985          onMatch: function(e, t, n) {
18986            var r = e.charAt(1) == '/' ? 2 : 1
18987            if (r == 1) t != this.nextState ? n.unshift(this.next, this.nextState, 0) : n.unshift(this.next), n[2]++
18988            else if (r == 2 && t == this.nextState) {
18989              n[1]--
18990              if (!n[1] || n[1] < 0) n.shift(), n.shift()
18991            }
18992            return [
18993              { type: 'meta.tag.punctuation.' + (r == 1 ? '' : 'end-') + 'tag-open.xml', value: e.slice(0, r) },
18994              { type: 'meta.tag.tag-name.xml', value: e.substr(r) }
18995            ]
18996          },
18997          regex: '</?' + e + '',
18998          next: 'jsxAttributes',
18999          nextState: 'jsx'
19000        }
19001      this.$rules.start.unshift(t)
19002      var n = { regex: '{', token: 'paren.quasi.start', push: 'start' }
19003      ;(this.$rules.jsx = [n, t, { include: 'reference' }, { defaultToken: 'string' }]),
19004        (this.$rules.jsxAttributes = [
19005          {
19006            token: 'meta.tag.punctuation.tag-close.xml',
19007            regex: '/?>',
19008            onMatch: function(e, t, n) {
19009              return (
19010                t == n[0] && n.shift(),
19011                e.length == 2 && (n[0] == this.nextState && n[1]--, (!n[1] || n[1] < 0) && n.splice(0, 2)),
19012                (this.next = n[0] || 'start'),
19013                [{ type: this.token, value: e }]
19014              )
19015            },
19016            nextState: 'jsx'
19017          },
19018          n,
19019          f('jsxAttributes'),
19020          { token: 'entity.other.attribute-name.xml', regex: e },
19021          { token: 'keyword.operator.attribute-equals.xml', regex: '=' },
19022          { token: 'text.tag-whitespace.xml', regex: '\\s+' },
19023          {
19024            token: 'string.attribute-value.xml',
19025            regex: "'",
19026            stateName: 'jsx_attr_q',
19027            push: [
19028              { token: 'string.attribute-value.xml', regex: "'", next: 'pop' },
19029              { include: 'reference' },
19030              { defaultToken: 'string.attribute-value.xml' }
19031            ]
19032          },
19033          {
19034            token: 'string.attribute-value.xml',
19035            regex: '"',
19036            stateName: 'jsx_attr_qq',
19037            push: [
19038              { token: 'string.attribute-value.xml', regex: '"', next: 'pop' },
19039              { include: 'reference' },
19040              { defaultToken: 'string.attribute-value.xml' }
19041            ]
19042          },
19043          t
19044        ]),
19045        (this.$rules.reference = [
19046          {
19047            token: 'constant.language.escape.reference.xml',
19048            regex: '(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)'
19049          }
19050        ])
19051    }
19052    function f(e) {
19053      return [
19054        {
19055          token: 'comment',
19056          regex: /\/\*/,
19057          next: [
19058            i.getTagRule(),
19059            { token: 'comment', regex: '\\*\\/', next: e || 'pop' },
19060            { defaultToken: 'comment', caseInsensitive: !0 }
19061          ]
19062        },
19063        {
19064          token: 'comment',
19065          regex: '\\/\\/',
19066          next: [
19067            i.getTagRule(),
19068            { token: 'comment', regex: '$|^', next: e || 'pop' },
19069            { defaultToken: 'comment', caseInsensitive: !0 }
19070          ]
19071        }
19072      ]
19073    }
19074    var r = e('../lib/oop'),
19075      i = e('./doc_comment_highlight_rules').DocCommentHighlightRules,
19076      s = e('./text_highlight_rules').TextHighlightRules,
19077      o = '[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*',
19078      u = function(e) {
19079        var t = this.createKeywordMapper(
19080            {
19081              'variable.language':
19082                'Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document',
19083              keyword:
19084                'const|yield|import|get|set|async|await|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static',
19085              'storage.type': 'const|let|var|function',
19086              'constant.language': 'null|Infinity|NaN|undefined',
19087              'support.function': 'alert',
19088              'constant.language.boolean': 'true|false'
19089            },
19090            'identifier'
19091          ),
19092          n = 'case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void',
19093          r = '\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|u{[0-9a-fA-F]{1,6}}|[0-2][0-7]{0,2}|3[0-7][0-7]?|[4-7][0-7]?|.)'
19094        this.$rules = {
19095          no_regex: [
19096            i.getStartRule('doc-start'),
19097            f('no_regex'),
19098            { token: 'string', regex: "'(?=.)", next: 'qstring' },
19099            { token: 'string', regex: '"(?=.)', next: 'qqstring' },
19100            { token: 'constant.numeric', regex: /0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/ },
19101            { token: 'constant.numeric', regex: /(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/ },
19102            {
19103              token: [
19104                'storage.type',
19105                'punctuation.operator',
19106                'support.function',
19107                'punctuation.operator',
19108                'entity.name.function',
19109                'text',
19110                'keyword.operator'
19111              ],
19112              regex: '(' + o + ')(\\.)(prototype)(\\.)(' + o + ')(\\s*)(=)',
19113              next: 'function_arguments'
19114            },
19115            {
19116              token: [
19117                'storage.type',
19118                'punctuation.operator',
19119                'entity.name.function',
19120                'text',
19121                'keyword.operator',
19122                'text',
19123                'storage.type',
19124                'text',
19125                'paren.lparen'
19126              ],
19127              regex: '(' + o + ')(\\.)(' + o + ')(\\s*)(=)(\\s*)(function)(\\s*)(\\()',
19128              next: 'function_arguments'
19129            },
19130            {
19131              token: [
19132                'entity.name.function',
19133                'text',
19134                'keyword.operator',
19135                'text',
19136                'storage.type',
19137                'text',
19138                'paren.lparen'
19139              ],
19140              regex: '(' + o + ')(\\s*)(=)(\\s*)(function)(\\s*)(\\()',
19141              next: 'function_arguments'
19142            },
19143            {
19144              token: [
19145                'storage.type',
19146                'punctuation.operator',
19147                'entity.name.function',
19148                'text',
19149                'keyword.operator',
19150                'text',
19151                'storage.type',
19152                'text',
19153                'entity.name.function',
19154                'text',
19155                'paren.lparen'
19156              ],
19157              regex: '(' + o + ')(\\.)(' + o + ')(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()',
19158              next: 'function_arguments'
19159            },
19160            {
19161              token: ['storage.type', 'text', 'entity.name.function', 'text', 'paren.lparen'],
19162              regex: '(function)(\\s+)(' + o + ')(\\s*)(\\()',
19163              next: 'function_arguments'
19164            },
19165            {
19166              token: [
19167                'entity.name.function',
19168                'text',
19169                'punctuation.operator',
19170                'text',
19171                'storage.type',
19172                'text',
19173                'paren.lparen'
19174              ],
19175              regex: '(' + o + ')(\\s*)(:)(\\s*)(function)(\\s*)(\\()',
19176              next: 'function_arguments'
19177            },
19178            {
19179              token: ['text', 'text', 'storage.type', 'text', 'paren.lparen'],
19180              regex: '(:)(\\s*)(function)(\\s*)(\\()',
19181              next: 'function_arguments'
19182            },
19183            { token: 'keyword', regex: 'from(?=\\s*(\'|"))' },
19184            { token: 'keyword', regex: '(?:' + n + ')\\b', next: 'start' },
19185            { token: ['support.constant'], regex: /that\b/ },
19186            {
19187              token: ['storage.type', 'punctuation.operator', 'support.function.firebug'],
19188              regex: /(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/
19189            },
19190            { token: t, regex: o },
19191            { token: 'punctuation.operator', regex: /[.](?![.])/, next: 'property' },
19192            { token: 'storage.type', regex: /=>/ },
19193            {
19194              token: 'keyword.operator',
19195              regex: /--|\+\+|\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\|\||\?:|[!$%&*+\-~\/^]=?/,
19196              next: 'start'
19197            },
19198            { token: 'punctuation.operator', regex: /[?:,;.]/, next: 'start' },
19199            { token: 'paren.lparen', regex: /[\[({]/, next: 'start' },
19200            { token: 'paren.rparen', regex: /[\])}]/ },
19201            { token: 'comment', regex: /^#!.*$/ }
19202          ],
19203          property: [
19204            { token: 'text', regex: '\\s+' },
19205            {
19206              token: [
19207                'storage.type',
19208                'punctuation.operator',
19209                'entity.name.function',
19210                'text',
19211                'keyword.operator',
19212                'text',
19213                'storage.type',
19214                'text',
19215                'entity.name.function',
19216                'text',
19217                'paren.lparen'
19218              ],
19219              regex: '(' + o + ')(\\.)(' + o + ')(\\s*)(=)(\\s*)(function)(?:(\\s+)(\\w+))?(\\s*)(\\()',
19220              next: 'function_arguments'
19221            },
19222            { token: 'punctuation.operator', regex: /[.](?![.])/ },
19223            {
19224              token: 'support.function',
19225              regex: /(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/
19226            },
19227            {
19228              token: 'support.function.dom',
19229              regex: /(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/
19230            },
19231            {
19232              token: 'support.constant',
19233              regex: /(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asse
19233s)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/
19234            },
19235            { token: 'identifier', regex: o },
19236            { regex: '', token: 'empty', next: 'no_regex' }
19237          ],
19238          start: [
19239            i.getStartRule('doc-start'),
19240            f('start'),
19241            { token: 'string.regexp', regex: '\\/', next: 'regex' },
19242            { token: 'text', regex: '\\s+|^$', next: 'start' },
19243            { token: 'empty', regex: '', next: 'no_regex' }
19244          ],
19245          regex: [
19246            { token: 'regexp.keyword.operator', regex: '\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)' },
19247            { token: 'string.regexp', regex: '/[sxngimy]*', next: 'no_regex' },
19248            { token: 'invalid', regex: /\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/ },
19249            { token: 'constant.language.escape', regex: /\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/ },
19250            { token: 'constant.language.delimiter', regex: /\|/ },
19251            { token: 'constant.language.escape', regex: /\[\^?/, next: 'regex_character_class' },
19252            { token: 'empty', regex: '$', next: 'no_regex' },
19253            { defaultToken: 'string.regexp' }
19254          ],
19255          regex_character_class: [
19256            { token: 'regexp.charclass.keyword.operator', regex: '\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)' },
19257            { token: 'constant.language.escape', regex: ']', next: 'regex' },
19258            { token: 'constant.language.escape', regex: '-' },
19259            { token: 'empty', regex: '$', next: 'no_regex' },
19260            { defaultToken: 'string.regexp.charachterclass' }
19261          ],
19262          function_arguments: [
19263            { token: 'variable.parameter', regex: o },
19264            { token: 'punctuation.operator', regex: '[, ]+' },
19265            { token: 'punctuation.operator', regex: '$' },
19266            { token: 'empty', regex: '', next: 'no_regex' }
19267          ],
19268          qqstring: [
19269            { token: 'constant.language.escape', regex: r },
19270            { token: 'string', regex: '\\\\$', consumeLineEnd: !0 },
19271            { token: 'string', regex: '"|$', next: 'no_regex' },
19272            { defaultToken: 'string' }
19273          ],
19274          qstring: [
19275            { token: 'constant.language.escape', regex: r },
19276            { token: 'string', regex: '\\\\$', consumeLineEnd: !0 },
19277            { token: 'string', regex: "'|$", next: 'no_regex' },
19278            { defaultToken: 'string' }
19279          ]
19280        }
19281        if (!e || !e.noES6)
19282          this.$rules.no_regex.unshift(
19283            {
19284              regex: '[{}]',
19285              onMatch: function(e, t, n) {
19286                this.next = e == '{' ? this.nextState : ''
19287                if (e == '{' && n.length) n.unshift('start', t)
19288                else if (e == '}' && n.length) {
19289                  n.shift(), (this.next = n.shift())
19290                  if (this.next.indexOf('string') != -1 || this.next.indexOf('jsx') != -1) return 'paren.quasi.end'
19291                }
19292                return e == '{' ? 'paren.lparen' : 'paren.rparen'
19293              },
19294              nextState: 'start'
19295            },
19296            {
19297              token: 'string.quasi.start',
19298              regex: /`/,
19299              push: [
19300                { token: 'constant.language.escape', regex: r },
19301                { token: 'paren.quasi.start', regex: /\${/, push: 'start' },
19302                { token: 'string.quasi.end', regex: /`/, next: 'pop' },
19303                { defaultToken: 'string.quasi' }
19304              ]
19305            }
19306          ),
19307            (!e || e.jsx != 0) && a.call(this)
19308        this.embedRules(i, 'doc-', [i.getEndRule('no_regex')]), this.normalizeRules()
19309      }
19310    r.inherits(u, s), (t.JavaScriptHighlightRules = u)
19311  }),
19312  define('ace/mode/xml_highlight_rules', [
19313    'require',
19314    'exports',
19315    'module',
19316    'ace/lib/oop',
19317    'ace/mode/text_highlight_rules'
19318  ], function(e, t, n) {
19319    'use strict'
19320    var r = e('../lib/oop'),
19321      i = e('./text_highlight_rules').TextHighlightRules,
19322      s = function(e) {
19323        var t = '[_:a-zA-Z\u00c0-\uffff][-_:.a-zA-Z0-9\u00c0-\uffff]*'
19324        ;(this.$rules = {
19325          start: [
19326            { token: 'string.cdata.xml', regex: '<\\!\\[CDATA\\[', next: 'cdata' },
19327            {
19328              token: ['punctuation.instruction.xml', 'keyword.instruction.xml'],
19329              regex: '(<\\?)(' + t + ')',
19330              next: 'processing_instruction'
19331            },
19332            { token: 'comment.start.xml', regex: '<\\!--', next: 'comment' },
19333            {
19334              token: ['xml-pe.doctype.xml', 'xml-pe.doctype.xml'],
19335              regex: '(<\\!)(DOCTYPE)(?=[\\s])',
19336              next: 'doctype',
19337              caseInsensitive: !0
19338            },
19339            { include: 'tag' },
19340            { token: 'text.end-tag-open.xml', regex: '</' },
19341            { token: 'text.tag-open.xml', regex: '<' },
19342            { include: 'reference' },
19343            { defaultToken: 'text.xml' }
19344          ],
19345          processing_instruction: [
19346            { token: 'entity.other.attribute-name.decl-attribute-name.xml', regex: t },
19347            { token: 'keyword.operator.decl-attribute-equals.xml', regex: '=' },
19348            { include: 'whitespace' },
19349            { include: 'string' },
19350            { token: 'punctuation.xml-decl.xml', regex: '\\?>', next: 'start' }
19351          ],
19352          doctype: [
19353            { include: 'whitespace' },
19354            { include: 'string' },
19355            { token: 'xml-pe.doctype.xml', regex: '>', next: 'start' },
19356            { token: 'xml-pe.xml', regex: '[-_a-zA-Z0-9:]+' },
19357            { token: 'punctuation.int-subset', regex: '\\[', push: 'int_subset' }
19358          ],
19359          int_subset: [
19360            { token: 'text.xml', regex: '\\s+' },
19361            { token: 'punctuation.int-subset.xml', regex: ']', next: 'pop' },
19362            {
19363              token: ['punctuation.markup-decl.xml', 'keyword.markup-decl.xml'],
19364              regex: '(<\\!)(' + t + ')',
19365              push: [
19366                { token: 'text', regex: '\\s+' },
19367                { token: 'punctuation.markup-decl.xml', regex: '>', next: 'pop' },
19368                { include: 'string' }
19369              ]
19370            }
19371          ],
19372          cdata: [
19373            { token: 'string.cdata.xml', regex: '\\]\\]>', next: 'start' },
19374            { token: 'text.xml', regex: '\\s+' },
19375            { token: 'text.xml', regex: '(?:[^\\]]|\\](?!\\]>))+' }
19376          ],
19377          comment: [{ token: 'comment.end.xml', regex: '-->', next: 'start' }, { defaultToken: 'comment.xml' }],
19378          reference: [
19379            {
19380              token: 'constant.language.escape.reference.xml',
19381              regex: '(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)'
19382            }
19383          ],
19384          attr_reference: [
19385            {
19386              token: 'constant.language.escape.reference.attribute-value.xml',
19387              regex: '(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)'
19388            }
19389          ],
19390          tag: [
19391            {
19392              token: [
19393                'meta.tag.punctuation.tag-open.xml',
19394                'meta.tag.punctuation.end-tag-open.xml',
19395                'meta.tag.tag-name.xml'
19396              ],
19397              regex: '(?:(<)|(</))((?:' + t + ':)?' + t + ')',
19398              next: [
19399                { include: 'attributes' },
19400                { token: 'meta.tag.punctuation.tag-close.xml', regex: '/?>', next: 'start' }
19401              ]
19402            }
19403          ],
19404          tag_whitespace: [{ token: 'text.tag-whitespace.xml', regex: '\\s+' }],
19405          whitespace: [{ token: 'text.whitespace.xml', regex: '\\s+' }],
19406          string: [
19407            {
19408              token: 'string.xml',
19409              regex: "'",
19410              push: [{ token: 'string.xml', regex: "'", next: 'pop' }, { defaultToken: 'string.xml' }]
19411            },
19412            {
19413              token: 'string.xml',
19414              regex: '"',
19415              push: [{ token: 'string.xml', regex: '"', next: 'pop' }, { defaultToken: 'string.xml' }]
19416            }
19417          ],
19418          attributes: [
19419            { token: 'entity.other.attribute-name.xml', regex: t },
19420            { token: 'keyword.operator.attribute-equals.xml', regex: '=' },
19421            { include: 'tag_whitespace' },
19422            { include: 'attribute_value' }
19423          ],
19424          attribute_value: [
19425            {
19426              token: 'string.attribute-value.xml',
19427              regex: "'",
19428              push: [
19429                { token: 'string.attribute-value.xml', regex: "'", next: 'pop' },
19430                { include: 'attr_reference' },
19431                { defaultToken: 'string.attribute-value.xml' }
19432              ]
19433            },
19434            {
19435              token: 'string.attribute-value.xml',
19436              regex: '"',
19437              push: [
19438                { token: 'string.attribute-value.xml', regex: '"', next: 'pop' },
19439                { include: 'attr_reference' },
19440                { defaultToken: 'string.attribute-value.xml' }
19441              ]
19442            }
19443          ]
19444        }),
19445          this.constructor === s && this.normalizeRules()
19446      }
19447    ;(function() {
19448      this.embedTagRules = function(e, t, n) {
19449        this.$rules.tag.unshift({
19450          token: ['meta.tag.punctuation.tag-open.xml', 'meta.tag.' + n + '.tag-name.xml'],
19451          regex: '(<)(' + n + '(?=\\s|>|$))',
19452          next: [
19453            { include: 'attributes' },
19454            { token: 'meta.tag.punctuation.tag-close.xml', regex: '/?>', next: t + 'start' }
19455          ]
19456        }),
19457          (this.$rules[n + '-end'] = [
19458            { include: 'attributes' },
19459            {
19460              token: 'meta.tag.punctuation.tag-close.xml',
19461              regex: '/?>',
19462              next: 'start',
19463              onMatch: function(e, t, n) {
19464                return n.splice(0), this.token
19465              }
19466            }
19467          ]),
19468          this.embedRules(e, t, [
19469            {
19470              token: ['meta.tag.punctuation.end-tag-open.xml', 'meta.tag.' + n + '.tag-name.xml'],
19471              regex: '(</)(' + n + '(?=\\s|>|$))',
19472              next: n + '-end'
19473            },
19474            { token: 'string.cdata.xml', regex: '<\\!\\[CDATA\\[' },
19475            { token: 'string.cdata.xml', regex: '\\]\\]>' }
19476          ])
19477      }
19478    }.call(i.prototype),
19479      r.inherits(s, i),
19480      (t.XmlHighlightRules = s))
19481  }),
19482  define('ace/mode/html_highlight_rules', [
19483    'require',
19484    'exports',
19485    'module',
19486    'ace/lib/oop',
19487    'ace/lib/lang',
19488    'ace/mode/css_highlight_rules',
19489    'ace/mode/javascript_highlight_rules',
19490    'ace/mode/xml_highlight_rules'
19491  ], function(e, t, n) {
19492    'use strict'
19493    var r = e('../lib/oop'),
19494      i = e('../lib/lang'),
19495      s = e('./css_highlight_rules').CssHighlightRules,
19496      o = e('./javascript_highlight_rules').JavaScriptHighlightRules,
19497      u = e('./xml_highlight_rules').XmlHighlightRules,
19498      a = i.createMap({
19499        a: 'anchor',
19500        button: 'form',
19501        form: 'form',
19502        img: 'image',
19503        input: 'form',
19504        label: 'form',
19505        option: 'form',
19506        script: 'script',
19507        select: 'form',
19508        textarea: 'form',
19509        style: 'style',
19510        table: 'table',
19511        tbody: 'table',
19512        td: 'table',
19513        tfoot: 'table',
19514        th: 'table',
19515        tr: 'table'
19516      }),
19517      f = function() {
19518        u.call(this),
19519          this.addRules({
19520            attributes: [
19521              { include: 'tag_whitespace' },
19522              { token: 'entity.other.attribute-name.xml', regex: '[-_a-zA-Z0-9:.]+' },
19523              {
19524                token: 'keyword.operator.attribute-equals.xml',
19525                regex: '=',
19526                push: [
19527                  { include: 'tag_whitespace' },
19528                  { token: 'string.unquoted.attribute-value.html', regex: '[^<>=\'"`\\s]+', next: 'pop' },
19529                  { token: 'empty', regex: '', next: 'pop' }
19530                ]
19531              },
19532              { include: 'attribute_value' }
19533            ],
19534            tag: [
19535              {
19536                token: function(e, t) {
19537                  var n = a[t]
19538                  return [
19539                    'meta.tag.punctuation.' + (e == '<' ? '' : 'end-') + 'tag-open.xml',
19540                    'meta.tag' + (n ? '.' + n : '') + '.tag-name.xml'
19541                  ]
19542                },
19543                regex: '(</?)([-_a-zA-Z0-9:.]+)',
19544                next: 'tag_stuff'
19545              }
19546            ],
19547            tag_stuff: [
19548              { include: 'attributes' },
19549              { token: 'meta.tag.punctuation.tag-close.xml', regex: '/?>', next: 'start' }
19550            ]
19551          }),
19552          this.embedTagRules(s, 'css-', 'style'),
19553          this.embedTagRules(new o({ jsx: !1 }).getRules(), 'js-', 'script'),
19554          this.constructor === f && this.normalizeRules()
19555      }
19556    r.inherits(f, u), (t.HtmlHighlightRules = f)
19557  }),
19558  define('ace/mode/liquid_highlight_rules', [
19559    'require',
19560    'exports',
19561    'module',
19562    'ace/lib/oop',
19563    'ace/mode/text_highlight_rules',
19564    'ace/mode/html_highlight_rules'
19565  ], function(e, t, n) {
19566    'use strict'
19567    var r = e('../lib/oop'),
19568      i = e('./text_highlight_rules').TextHighlightRules,
19569      s = e('./html_highlight_rules').HtmlHighlightRules,
19570      o = function() {
19571        s.call(this)
19572        var e =
19573            'date|capitalize|downcase|upcase|first|last|join|sort|map|size|escape|escape_once|strip_html|strip_newlines|newline_to_br|replace|replace_first|truncate|truncatewords|prepend|append|minus|plus|times|divided_by|split',
19574          t =
19575            'capture|endcapture|case|endcase|when|comment|endcomment|cycle|for|endfor|in|reversed|if|endif|else|elsif|include|endinclude|unless|endunless|style|text|image|widget|plugin|marker|endmarker|tablerow|endtablerow',
19576          n = 'forloop|tablerowloop',
19577          r = 'assign',
19578          i = this.createKeywordMapper(
19579            { 'variable.language': n, keyword: t, 'support.function': e, 'keyword.definition': r },
19580            'identifier'
19581          )
19582        for (var o in this.$rules)
19583          this.$rules[o].unshift(
19584            { token: 'variable', regex: '{%', push: 'liquid-start' },
19585            { token: 'variable', regex: '{{', push: 'liquid-start' }
19586          )
19587        this.addRules({
19588          'liquid-start': [
19589            { token: 'variable', regex: '}}', next: 'pop' },
19590            { token: 'variable', regex: '%}', next: 'pop' },
19591            { token: 'string', regex: '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' },
19592            { token: 'string', regex: "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']" },
19593            { token: 'constant.numeric', regex: '0[xX][0-9a-fA-F]+\\b' },
19594            { token: 'constant.numeric', regex: '[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b' },
19595            { token: 'constant.language.boolean', regex: '(?:true|false)\\b' },
19596            { token: i, regex: '[a-zA-Z_$][a-zA-Z0-9_$]*\\b' },
19597            { token: 'keyword.operator', regex: '/|\\*|\\-|\\+|=|!=|\\?\\:' },
19598            { token: 'paren.lparen', regex: /[\[\({]/ },
19599            { token: 'paren.rparen', regex: /[\])}]/ },
19600            { token: 'text', regex: '\\s+' }
19601          ]
19602        }),
19603          this.normalizeRules()
19604      }
19605    r.inherits(o, i), (t.LiquidHighlightRules = o)
19606  }),
19607  define('ace/mode/matching_brace_outdent', ['require', 'exports', 'module', 'ace/range'], function(e, t, n) {
19608    'use strict'
19609    var r = e('../range').Range,
19610      i = function() {}
19611    ;(function() {
19612      ;(this.checkOutdent = function(e, t) {
19613        return /^\s+$/.test(e) ? /^\s*\}/.test(t) : !1
19614      }),
19615        (this.autoOutdent = function(e, t) {
19616          var n = e.getLine(t),
19617            i = n.match(/^(\s*\})/)
19618          if (!i) return 0
19619          var s = i[1].length,
19620            o = e.findMatchingBracket({ row: t, column: s })
19621          if (!o || o.row == t) return 0
19622          var u = this.$getIndent(e.getLine(o.row))
19623          e.replace(new r(t, 0, t, s - 1), u)
19624        }),
19625        (this.$getIndent = function(e) {
19626          return e.match(/^\s*/)[0]
19627        })
19628    }.call(i.prototype),
19629      (t.MatchingBraceOutdent = i))
19630  }),
19631  define('ace/mode/liquid', [
19632    'require',
19633    'exports',
19634    'module',
19635    'ace/lib/oop',
19636    'ace/mode/text',
19637    'ace/mode/liquid_highlight_rules',
19638    'ace/mode/matching_brace_outdent'
19639  ], function(e, t, n) {
19640    var r = e('../lib/oop'),
19641      i = e('./text').Mode,
19642      s = e('./liquid_highlight_rules').LiquidHighlightRules,
19643      o = e('./matching_brace_outdent').MatchingBraceOutdent,
19644      u = function() {
19645        ;(this.HighlightRules = s), (this.$outdent = new o()), (this.$behaviour = this.$defaultBehaviour)
19646      }
19647    r.inherits(u, i),
19648      function() {
19649        ;(this.blockComment = { start: '<!--', end: '-->' }),
19650          (this.getNextLineIndent = function(e, t, n) {
19651            var r = this.$getIndent(t),
19652              i = this.getTokenizer().getLineTokens(t, e),
19653              s = i.tokens,
19654              o = i.state
19655            if (s.length && s[s.length - 1].type == 'comment') return r
19656            if (e == 'start') {
19657              var u = t.match(/^.*[\{\(\[]\s*$/)
19658              u && (r += n)
19659            }
19660            return r
19661          }),
19662          (this.checkOutdent = function(e, t, n) {
19663            return this.$outdent.checkOutdent(t, n)
19664          }),
19665          (this.autoOutdent = function(e, t, n) {
19666            this.$outdent.autoOutdent(t, n)
19667          }),
19668          (this.$id = 'ace/mode/liquid')
19669      }.call(u.prototype),
19670      (t.Mode = u)
19671  })
19672;(function() {
19673  window.require(['ace/mode/liquid'], function(m) {
19674    if (typeof module == 'object' && typeof exports == 'object' && module) {
19675      module.exports = m
19676    }
19677  })
19678})();
19679// Copy From: https://cdnjs.cloudflare.com/ajax/libs/ace/1.3.3/theme-merbivore.js
19680define('ace/theme/merbivore', ['require', 'exports', 'module', 'ace/lib/dom'], function(e, t, n) {
19681  ;(t.isDark = !0),
19682    (t.cssClass = 'ace-merbivore'),
19683    (t.cssText =
19684      '.ace-merbivore .ace_gutter {background: #202020;color: #E6E1DC}.ace-merbivore .ace_print-margin {width: 1px;background: #555651}.ace-merbivore {background-color: #161616;color: #E6E1DC}.ace-merbivore .ace_cursor {color: #FFFFFF}.ace-merbivore .ace_marker-layer .ace_selection {background: #454545}.ace-merbivore.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #161616;}.ace-merbivore .ace_marker-layer .ace_step {background: rgb(102, 82, 0)}.ace-merbivore .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #404040}.ace-merbivore .ace_marker-layer .ace_active-line {background: #333435}.ace-merbivore .ace_gutter-active-line {background-color: #333435}.ace-merbivore .ace_marker-layer .ace_selected-word {border: 1px solid #454545}.ace-merbivore .ace_invisible {color: #404040}.ace-merbivore .ace_entity.ace_name.ace_tag,.ace-merbivore .ace_keyword,.ace-merbivore .ace_meta,.ace-merbivore .ace_meta.ace_tag,.ace-merbivore .ace_storage,.ace-merbivore .ace_support.ace_function {color: #FC6F09}.ace-merbivore .ace_constant,.ace-merbivore .ace_constant.ace_character,.ace-merbivore .ace_constant.ace_character.ace_escape,.ace-merbivore .ace_constant.ace_other,.ace-merbivore .ace_support.ace_type {color: #1EDAFB}.ace-merbivore .ace_constant.ace_character.ace_escape {color: #519F50}.ace-merbivore .ace_constant.ace_language {color: #FDC251}.ace-merbivore .ace_constant.ace_library,.ace-merbivore .ace_string,.ace-merbivore .ace_support.ace_constant {color: #8DFF0A}.ace-merbivore .ace_constant.ace_numeric {color: #58C554}.ace-merbivore .ace_invalid {color: #FFFFFF;background-color: #990000}
19684.ace-merbivore .ace_fold {background-color: #FC6F09;border-color: #E6E1DC}.ace-merbivore .ace_comment {font-style: italic;color: #AD2EA4}.ace-merbivore .ace_entity.ace_other.ace_attribute-name {color: #FFFF89}.ace-merbivore .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWMQFxf3ZXB1df0PAAdsAmERTkEHAAAAAElFTkSuQmCC) right repeat-y}')
19685  var r = e('../lib/dom')
19686  r.importCssString(t.cssText, t.cssClass)
19687})
19688;(function() {
19689  window.require(['ace/theme/merbivore'], function(m) {
19690    if (typeof module == 'object' && typeof exports == 'object' && module) {
19691      module.exports = m
19692    }
19693  })
19694})();
19695/**
19696 * @license Highcharts JS v6.0.3 (2017-11-14)
19697 *
19698 * (c) 2009-2016 Torstein Honsi
19699 *
19700 * License: www.highcharts.com/license
19701 */
19702'use strict';
19703(function(root, factory) {
19704    if (typeof module === 'object' && module.exports) {
19705        module.exports = root.document ?
19706            factory(root) :
19707            factory;
19708    } else {
19709        root.Highcharts = factory(root);
19710    }
19711}(typeof window !== 'undefined' ? window : this, function(win) {
19712    var Highcharts = (function() {
19713        /**
19714         * (c) 2010-2017 Torstein Honsi
19715         *
19716         * License: www.highcharts.com/license
19717         */
19718        /* global win, window */
19719
19720        // glob is a temporary fix to allow our es-modules to work.
19721        var glob = typeof win === 'undefined' ? window : win,
19722            doc = glob.document,
19723            SVG_NS = 'http://www.w3.org/2000/svg',
19724            userAgent = (glob.navigator && glob.navigator.userAgent) || '',
19725            svg = doc && doc.createElementNS && !!doc.createElementNS(SVG_NS, 'svg').createSVGRect,
19726            isMS = /(edge|msie|trident)/i.test(userAgent) && !glob.opera,
19727            isFirefox = /Firefox/.test(userAgent),
19728            hasBidiBug = isFirefox && parseInt(userAgent.split('Firefox/')[1], 10) < 4; // issue #38;
19729
19730        var Highcharts = glob.Highcharts ? glob.Highcharts.error(16, true) : {
19731            product: 'Highcharts',
19732            version: '6.0.3',
19733            deg2rad: Math.PI * 2 / 360,
19734            doc: doc,
19735            hasBidiBug: hasBidiBug,
19736            hasTouch: doc && doc.documentElement.ontouchstart !== undefined,
19737            isMS: isMS,
19738            isWebKit: /AppleWebKit/.test(userAgent),
19739            isFirefox: isFirefox,
19740            isTouchDevice: /(Mobile|Android|Windows Phone)/.test(userAgent),
19741            SVG_NS: SVG_NS,
19742            chartCount: 0,
19743            seriesTypes: {},
19744            symbolSizes: {},
19745            svg: svg,
19746            win: glob,
19747            marginNames: ['plotTop', 'marginRight', 'marginBottom', 'plotLeft'],
19748            noop: function() {
19749                return undefined;
19750            },
19751            /**
19752             * An array containing the current chart objects in the page. A chart's
19753             * position in the array is preserved throughout the page's lifetime. When
19754             * a chart is destroyed, the array item becomes `undefined`.
19755             * @type {Array.<Highcharts.Chart>}
19756             * @memberOf Highcharts
19757             */
19758            charts: []
19759        };
19760        return Highcharts;
19761    }());
19762    (function(H) {
19763        /**
19764         * (c) 2010-2017 Torstein Honsi
19765         *
19766         * License: www.highcharts.com/license
19767         */
19768        /* eslint max-len: ["warn", 80, 4] */
19769
19770        /**
19771         * The Highcharts object is the placeholder for all other members, and various
19772         * utility functions. The most important member of the namespace would be the
19773         * chart constructor.
19774         *
19775         * @example
19776         * var chart = Highcharts.chart('container', { ... });
19777         * 
19778         * @namespace Highcharts
19779         */
19780
19781        H.timers = [];
19782
19783        var charts = H.charts,
19784            doc = H.doc,
19785            win = H.win;
19786
19787        /**
19788         * Provide error messages for debugging, with links to online explanation. This
19789         * function can be overridden to provide custom error handling.
19790         *
19791         * @function #error
19792         * @memberOf Highcharts
19793         * @param {Number|String} code - The error code. See [errors.xml]{@link 
19794         *     https://github.com/highcharts/highcharts/blob/master/errors/errors.xml}
19795         *     for available codes. If it is a string, the error message is printed
19796         *     directly in the console.
19797         * @param {Boolean} [stop=false] - Whether to throw an error or just log a 
19798         *     warning in the console.
19799         *
19800         * @sample highcharts/chart/highcharts-error/ Custom error handler
19801         */
19802        H.error = function(code, stop) {
19803            var msg = H.isNumber(code) ?
19804                'Highcharts error #' + code + ': www.highcharts.com/errors/' + code :
19805                code;
19806            if (stop) {
19807                throw new Error(msg);
19808            }
19809            // else ...
19810            if (win.console) {
19811                console.log(msg); // eslint-disable-line no-console
19812            }
19813        };
19814
19815        /**
19816         * An animator object used internally. One instance applies to one property
19817         * (attribute or style prop) on one element. Animation is always initiated
19818         * through {@link SVGElement#animate}.
19819         *
19820         * @constructor Fx
19821         * @memberOf Highcharts
19822         * @param {HTMLDOMElement|SVGElement} elem - The element to animate.
19823         * @param {AnimationOptions} options - Animation options.
19824         * @param {string} prop - The single attribute or CSS property to animate.
19825         * @private
19826         *
19827         * @example
19828         * var rect = renderer.rect(0, 0, 10, 10).add();
19829         * rect.animate({ width: 100 });
19830         */
19831        H.Fx = function(elem, options, prop) {
19832            this.options = options;
19833            this.elem = elem;
19834            this.prop = prop;
19835        };
19836        H.Fx.prototype = {
19837
19838            /**
19839             * Set the current step of a path definition on SVGElement.
19840             *
19841             * @function #dSetter
19842             * @memberOf Highcharts.Fx
19843             */
19844            dSetter: function() {
19845                var start = this.paths[0],
19846                    end = this.paths[1],
19847                    ret = [],
19848                    now = this.now,
19849                    i = start.length,
19850                    startVal;
19851
19852                // Land on the final path without adjustment points appended in the ends
19853                if (now === 1) {
19854                    ret = this.toD;
19855
19856                } else if (i === end.length && now < 1) {
19857                    while (i--) {
19858                        startVal = parseFloat(start[i]);
19859                        ret[i] =
19860                            isNaN(startVal) ? // a letter instruction like M or L
19861                            end[i] :
19862                            now * (parseFloat(end[i] - startVal)) + startVal;
19863
19864                    }
19865                    // If animation is finished or length not matching, land on right value
19866                } else {
19867                    ret = end;
19868                }
19869                this.elem.attr('d', ret, null, true);
19870            },
19871
19872            /**
19873             * Update the element with the current animation step.
19874             *
19875             * @function #update
19876             * @memberOf Highcharts.Fx
19877             */
19878            update: function() {
19879                var elem = this.elem,
19880                    prop = this.prop, // if destroyed, it is null
19881                    now = this.now,
19882                    step = this.options.step;
19883
19884                // Animation setter defined from outside
19885                if (this[prop + 'Setter']) {
19886                    this[prop + 'Setter']();
19887
19888                    // Other animations on SVGElement
19889                } else if (elem.attr) {
19890                    if (elem.element) {
19891                        elem.attr(prop, now, null, true);
19892                    }
19893
19894                    // HTML styles, raw HTML content like container size
19895                } else {
19896                    elem.style[prop] = now + this.unit;
19897                }
19898
19899                if (step) {
19900                    step.call(elem, now, this);
19901                }
19902
19903            },
19904
19905            /**
19906             * Run an animation.
19907             *
19908             * @function #run
19909             * @memberOf Highcharts.Fx
19910             * @param {Number} from - The current value, value to start from.
19911             * @param {Number} to - The end value, value to land on.
19912             * @param {String} [unit] - The property unit, for example `px`.
19913             * 
19914             */
19915            run: function(from, to, unit) {
19916                var self = this,
19917                    options = self.options,
19918                    timer = function(gotoEnd) {
19919                        return timer.stopped ? false : self.step(gotoEnd);
19920                    },
19921                    requestAnimationFrame =
19922                    win.requestAnimationFrame ||
19923                    function(step) {
19924                        setTimeout(step, 13);
19925                    },
19926                    step = function() {
19927                        H.timers = H.grep(H.timers, function(timer) {
19928                            return timer();
19929                        });
19930
19931                        if (H.timers.length) {
19932                            requestAnimationFrame(step);
19933                        }
19934                    };
19935
19936                if (from === to) {
19937                    delete options.curAnim[this.prop];
19938                    if (options.complete && H.keys(options.curAnim).length === 0) {
19939                        options.complete();
19940                    }
19941                } else { // #7166
19942                    this.startTime = +new Date();
19943                    this.start = from;
19944                    this.end = to;
19945                    this.unit = unit;
19946                    this.now = this.start;
19947                    this.pos = 0;
19948
19949                    timer.elem = this.elem;
19950                    timer.prop = this.prop;
19951
19952                    if (timer() && H.timers.push(timer) === 1) {
19953                        requestAnimationFrame(step);
19954                    }
19955                }
19956            },
19957
19958            /**
19959             * Run a single step in the animation.
19960             *
19961             * @function #step
19962             * @memberOf Highcharts.Fx
19963             * @param   {Boolean} [gotoEnd] - Whether to go to the endpoint of the
19964             *     animation after abort.
19965             * @returns {Boolean} Returns `true` if animation continues.
19966             */
19967            step: function(gotoEnd) {
19968                var t = +new Date(),
19969                    ret,
19970                    done,
19971                    options = this.options,
19972                    elem = this.elem,
19973                    complete = options.complete,
19974                    duration = options.duration,
19975                    curAnim = options.curAnim;
19976
19977                if (elem.attr && !elem.element) { // #2616, element is destroyed
19978                    ret = false;
19979
19980                } else if (gotoEnd || t >= duration + this.startTime) {
19981                    this.now = this.end;
19982                    this.pos = 1;
19983                    this.update();
19984
19985                    curAnim[this.prop] = true;
19986
19987                    done = true;
19988
19989                    H.objectEach(curAnim, function(val) {
19990                        if (val !== true) {
19991                            done = false;
19992                        }
19993                    });
19994
19995                    if (done && complete) {
19996                        complete.call(elem);
19997                    }
19998                    ret = false;
19999
20000                } else {
20001                    this.pos = options.easing((t - this.startTime) / duration);
20002                    this.now = this.start + ((this.end - this.start) * this.pos);
20003                    this.update();
20004                    ret = true;
20005                }
20006                return ret;
20007            },
20008
20009            /**
20010             * Prepare start and end values so that the path can be animated one to one.
20011             *
20012             * @function #initPath
20013             * @memberOf Highcharts.Fx
20014             * @param {SVGElement} elem - The SVGElement item.
20015             * @param {String} fromD - Starting path definition.
20016             * @param {Array} toD - Ending path definition.
20017             * @returns {Array} An array containing start and end paths in array form
20018             * so that they can be animated in parallel.
20019             */
20020            initPath: function(elem, fromD, toD) {
20021                fromD = fromD || '';
20022                var shift,
20023                    startX = elem.startX,
20024                    endX = elem.endX,
20025                    bezier = fromD.indexOf('C') > -1,
20026                    numParams = bezier ? 7 : 3,
20027                    fullLength,
20028                    slice,
20029                    i,
20030                    start = fromD.split(' '),
20031                    end = toD.slice(), // copy
20032                    isArea = elem.isArea,
20033                    positionFactor = isArea ? 2 : 1,
20034                    reverse;
20035
20036                /**
20037                 * In splines make moveTo and lineTo points have six parameters like
20038                 * bezier curves, to allow animation one-to-one.
20039                 */
20040                function sixify(arr) {
20041                    var isOperator,
20042                        nextIsOperator;
20043                    i = arr.length;
20044                    while (i--) {
20045
20046                        // Fill in dummy coordinates only if the next operator comes
20047                        // three places behind (#5788)
20048                        isOperator = arr[i] === 'M' || arr[i] === 'L';
20049                        nextIsOperator = /[a-zA-Z]/.test(arr[i + 3]);
20050                        if (isOperator && nextIsOperator) {
20051                            arr.splice(
20052                                i + 1, 0,
20053                                arr[i + 1], arr[i + 2],
20054                                arr[i + 1], arr[i + 2]
20055                            );
20056                        }
20057                    }
20058                }
20059
20060                /**
20061                 * Insert an array at the given position of another array
20062                 */
20063                function insertSlice(arr, subArr, index) {
20064                    [].splice.apply(
20065                        arr, [index, 0].concat(subArr)
20066                    );
20067                }
20068
20069                /**
20070                 * If shifting points, prepend a dummy point to the end path. 
20071                 */
20072                function prepend(arr, other) {
20073                    while (arr.length < fullLength) {
20074
20075                        // Move to, line to or curve to?
20076                        arr[0] = other[fullLength - arr.length];
20077
20078                        // Prepend a copy of the first point
20079                        insertSlice(arr, arr.slice(0, numParams), 0);
20080
20081                        // For areas, the bottom path goes back again to the left, so we
20082                        // need to append a copy of the last point.
20083                        if (isArea) {
20084                            insertSlice(
20085                                arr,
20086                                arr.slice(arr.length - numParams), arr.length
20087                            );
20088                            i--;
20089                        }
20090                    }
20091                    arr[0] = 'M';
20092                }
20093
20094                /**
20095                 * Copy and append last point until the length matches the end length
20096                 */
20097                function append(arr, other) {
20098                    var i = (fullLength - arr.length) / numParams;
20099                    while (i > 0 && i--) {
20100
20101                        // Pull out the slice that is going to be appended or inserted.
20102                        // In a line graph, the positionFactor is 1, and the last point
20103                        // is sliced out. In an area graph, the positionFactor is 2,
20104                        // causing the middle two points to be sliced out, since an area
20105                        // path starts at left, follows the upper path then turns and
20106                        // follows the bottom back. 
20107                        slice = arr.slice().splice(
20108                            (arr.length / positionFactor) - numParams,
20109                            numParams * positionFactor
20110                        );
20111
20112                        // Move to, line to or curve to?
20113                        slice[0] = other[fullLength - numParams - (i * numParams)];
20114
20115                        // Disable first control point
20116                        if (bezier) {
20117                            slice[numParams - 6] = slice[numParams - 2];
20118                            slice[numParams - 5] = slice[numParams - 1];
20119                        }
20120
20121                        // Now insert the slice, either in the middle (for areas) or at
20122                        // the end (for lines)
20123                        insertSlice(arr, slice, arr.length / positionFactor);
20124
20125                        if (isArea) {
20126                            i--;
20127                        }
20128                    }
20129                }
20130
20131                if (bezier) {
20132                    sixify(start);
20133                    sixify(end);
20134                }
20135
20136                // For sideways animation, find out how much we need to shift to get the
20137                // start path Xs to match the end path Xs.
20138                if (startX && endX) {
20139                    for (i = 0; i < startX.length; i++) {
20140                        // Moving left, new points coming in on right
20141                        if (startX[i] === endX[0]) {
20142                            shift = i;
20143                            break;
20144                            // Moving right
20145                        } else if (startX[0] ===
20146                            endX[endX.length - startX.length + i]) {
20147                            shift = i;
20148                            reverse = true;
20149                            break;
20150                        }
20151                    }
20152                    if (shift === undefined) {
20153                        start = [];
20154                    }
20155                }
20156
20157                if (start.length && H.isNumber(shift)) {
20158
20159                    // The common target length for the start and end array, where both 
20160                    // arrays are padded in opposite ends
20161                    fullLength = end.length + shift * positionFactor * numParams;
20162
20163                    if (!reverse) {
20164                        prepend(end, start);
20165                        append(start, end);
20166                    } else {
20167                        prepend(start, end);
20168                        append(end, start);
20169                    }
20170                }
20171
20172                return [start, end];
20173            }
20174        }; // End of Fx prototype
20175
20176        /**
20177         * Handle animation of the color attributes directly.
20178         */
20179        H.Fx.prototype.fillSetter =
20180            H.Fx.prototype.strokeSetter = function() {
20181                this.elem.attr(
20182                    this.prop,
20183                    H.color(this.start).tweenTo(H.color(this.end), this.pos),
20184                    null,
20185                    true
20186                );
20187            };
20188
20189        /**
20190         * Utility function to extend an object with the members of another.
20191         *
20192         * @function #extend
20193         * @memberOf Highcharts
20194         * @param {Object} a - The object to be extended.
20195         * @param {Object} b - The object to add to the first one.
20196         * @returns {Object} Object a, the original object.
20197         */
20198        H.extend = function(a, b) {
20199            var n;
20200            if (!a) {
20201                a = {};
20202            }
20203            for (n in b) {
20204                a[n] = b[n];
20205            }
20206            return a;
20207        };
20208
20209        /**
20210         * Utility function to deep merge two or more objects and return a third object.
20211         * If the first argument is true, the contents of the second object is copied
20212         * into the first object. The merge function can also be used with a single 
20213         * object argument to create a deep copy of an object.
20214         *
20215         * @function #merge
20216         * @memberOf Highcharts
20217         * @param {Boolean} [extend] - Whether to extend the left-side object (a) or
20218                  return a whole new object.
20219         * @param {Object} a - The first object to extend. When only this is given, the
20220                  function returns a deep copy.
20221         * @param {...Object} [n] - An object to merge into the previous one.
20222         * @returns {Object} - The merged object. If the first argument is true, the 
20223         * return is the same as the second argument.
20224         */
20225        H.merge = function() {
20226            var i,
20227                args = arguments,
20228                len,
20229                ret = {},
20230                doCopy = function(copy, original) {
20231                    // An object is replacing a primitive
20232                    if (typeof copy !== 'object') {
20233                        copy = {};
20234                    }
20235
20236                    H.objectEach(original, function(value, key) {
20237
20238                        // Copy the contents of objects, but not arrays or DOM nodes
20239                        if (
20240                            H.isObject(value, true) &&
20241                            !H.isClass(value) &&
20242                            !H.isDOMElement(value)
20243                        ) {
20244                            copy[key] = doCopy(copy[key] || {}, value);
20245
20246                            // Primitives and arrays are copied over directly
20247                        } else {
20248                            copy[key] = original[key];
20249                        }
20250                    });
20251                    return copy;
20252                };
20253
20254            // If first argument is true, copy into the existing object. Used in
20255            // setOptions.
20256            if (args[0] === true) {
20257                ret = args[1];
20258                args = Array.prototype.slice.call(args, 2);
20259            }
20260
20261            // For each argument, extend the return
20262            len = args.length;
20263            for (i = 0; i < len; i++) {
20264                ret = doCopy(ret, args[i]);
20265            }
20266
20267            return ret;
20268        };
20269
20270        /**
20271         * Shortcut for parseInt
20272         * @ignore
20273         * @param {Object} s
20274         * @param {Number} mag Magnitude
20275         */
20276        H.pInt = function(s, mag) {
20277            return parseInt(s, mag || 10);
20278        };
20279
20280        /**
20281         * Utility function to check for string type.
20282         *
20283         * @function #isString
20284         * @memberOf Highcharts
20285         * @param {Object} s - The item to check.
20286         * @returns {Boolean} - True if the argument is a string.
20287         */
20288        H.isString = function(s) {
20289            return typeof s === 'string';
20290        };
20291
20292        /**
20293         * Utility function to check if an item is an array.
20294         *
20295         * @function #isArray
20296         * @memberOf Highcharts
20297         * @param {Object} obj - The item to check.
20298         * @returns {Boolean} - True if the argument is an array.
20299         */
20300        H.isArray = function(obj) {
20301            var str = Object.prototype.toString.call(obj);
20302            return str === '[object Array]' || str === '[object Array Iterator]';
20303        };
20304
20305        /**
20306         * Utility function to check if an item is of type object.
20307         *
20308         * @function #isObject
20309         * @memberOf Highcharts
20310         * @param {Object} obj - The item to check.
20311         * @param {Boolean} [strict=false] - Also checks that the object is not an
20312         *    array.
20313         * @returns {Boolean} - True if the argument is an object.
20314         */
20315        H.isObject = function(obj, strict) {
20316            return !!obj && typeof obj === 'object' && (!strict || !H.isArray(obj));
20317        };
20318
20319        /**
20320         * Utility function to check if an Object is a HTML Element.
20321         *
20322         * @function #isDOMElement
20323         * @memberOf Highcharts
20324         * @param {Object} obj - The item to check.
20325         * @returns {Boolean} - True if the argument is a HTML Element.
20326         */
20327        H.isDOMElement = function(obj) {
20328            return H.isObject(obj) && typeof obj.nodeType === 'number';
20329        };
20330
20331        /**
20332         * Utility function to check if an Object is an class.
20333         *
20334         * @function #isClass
20335         * @memberOf Highcharts
20336         * @param {Object} obj - The item to check.
20337         * @returns {Boolean} - True if the argument is an class.
20338         */
20339        H.isClass = function(obj) {
20340            var c = obj && obj.constructor;
20341            return !!(
20342                H.isObject(obj, true) &&
20343                !H.isDOMElement(obj) &&
20344                (c && c.name && c.name !== 'Object')
20345            );
20346        };
20347
20348        /**
20349         * Utility function to check if an item is of type number.
20350         *
20351         * @function #isNumber
20352         * @memberOf Highcharts
20353         * @param {Object} n - The item to check.
20354         * @returns {Boolean} - True if the item is a number and is not NaN.
20355         */
20356        H.isNumber = function(n) {
20357            return typeof n === 'number' && !isNaN(n);
20358        };
20359
20360        /**
20361         * Remove the last occurence of an item from an array.
20362         *
20363         * @function #erase
20364         * @memberOf Highcharts
20365         * @param {Array} arr - The array.
20366         * @param {*} item - The item to remove.
20367         */
20368        H.erase = function(arr, item) {
20369            var i = arr.length;
20370            while (i--) {
20371                if (arr[i] === item) {
20372                    arr.splice(i, 1);
20373                    break;
20374                }
20375            }
20376        };
20377
20378        /**
20379         * Check if an object is null or undefined.
20380         *
20381         * @function #defined
20382         * @memberOf Highcharts
20383         * @param {Object} obj - The object to check.
20384         * @returns {Boolean} - False if the object is null or undefined, otherwise
20385         *        true.
20386         */
20387        H.defined = function(obj) {
20388            return obj !== undefined && obj !== null;
20389        };
20390
20391        /**
20392         * Set or get an attribute or an object of attributes. To use as a setter, pass
20393         * a key and a value, or let the second argument be a collection of keys and
20394         * values. To use as a getter, pass only a string as the second argument.
20395         *
20396         * @function #attr
20397         * @memberOf Highcharts
20398         * @param {Object} elem - The DOM element to receive the attribute(s).
20399         * @param {String|Object} [prop] - The property or an object of key-value pairs.
20400         * @param {String} [value] - The value if a single property is set.
20401         * @returns {*} When used as a getter, return the value.
20402         */
20403        H.attr = function(elem, prop, value) {
20404            var ret;
20405
20406            // if the prop is a string
20407            if (H.isString(prop)) {
20408                // set the value
20409                if (H.defined(value)) {
20410                    elem.setAttribute(prop, value);
20411
20412                    // get the value
20413                } else if (elem && elem.getAttribute) {
20414                    ret = elem.getAttribute(prop);
20415                }
20416
20417                // else if prop is defined, it is a hash of key/value pairs
20418            } else if (H.defined(prop) && H.isObject(prop)) {
20419                H.objectEach(prop, function(val, key) {
20420                    elem.setAttribute(key, val);
20421                });
20422            }
20423            return ret;
20424        };
20425
20426        /**
20427         * Check if an element is an array, and if not, make it into an array.
20428         *
20429         * @function #splat
20430         * @memberOf Highcharts
20431         * @param obj {*} - The object to splat.
20432         * @returns {Array} The produced or original array.
20433         */
20434        H.splat = function(obj) {
20435            return H.isArray(obj) ? obj : [obj];
20436        };
20437
20438        /**
20439         * Set a timeout if the delay is given, otherwise perform the function
20440         * synchronously.
20441         *
20442         * @function #syncTimeout
20443         * @memberOf Highcharts
20444         * @param   {Function} fn - The function callback.
20445         * @param   {Number}   delay - Delay in milliseconds.
20446         * @param   {Object}   [context] - The context.
20447         * @returns {Number} An identifier for the timeout that can later be cleared
20448         * with clearTimeout.
20449         */
20450        H.syncTimeout = function(fn, delay, context) {
20451            if (delay) {
20452                return setTimeout(fn, delay, context);
20453            }
20454            fn.call(0, context);
20455        };
20456
20457
20458        /**
20459         * Return the first value that is not null or undefined.
20460         *
20461         * @function #pick
20462         * @memberOf Highcharts
20463         * @param {...*} items - Variable number of arguments to inspect.
20464         * @returns {*} The value of the first argument that is not null or undefined.
20465         */
20466        H.pick = function() {
20467            var args = arguments,
20468                i,
20469                arg,
20470                length = args.length;
20471            for (i = 0; i < length; i++) {
20472                arg = args[i];
20473                if (arg !== undefined && arg !== null) {
20474                    return arg;
20475                }
20476            }
20477        };
20478
20479        /**
20480         * @typedef {Object} CSSObject - A style object with camel case property names.
20481         * The properties can be whatever styles are supported on the given SVG or HTML
20482         * element.
20483         * @example
20484         * {
20485         *    fontFamily: 'monospace',
20486         *    fontSize: '1.2em'
20487         * }
20488         */
20489        /**
20490         * Set CSS on a given element.
20491         *
20492         * @function #css
20493         * @memberOf Highcharts
20494         * @param {HTMLDOMElement} el - A HTML DOM element.
20495         * @param {CSSObject} styles - Style object with camel case property names.
20496         * 
20497         */
20498        H.css = function(el, styles) {
20499            if (H.isMS && !H.svg) { // #2686
20500                if (styles && styles.opacity !== undefined) {
20501                    styles.filter = 'alpha(opacity=' + (styles.opacity * 100) + ')';
20502                }
20503            }
20504            H.extend(el.style, styles);
20505        };
20506
20507        /**
20508         * A HTML DOM element.
20509         * @typedef {Object} HTMLDOMElement
20510         */
20511
20512        /**
20513         * Utility function to create an HTML element with attributes and styles.
20514         *
20515         * @function #createElement
20516         * @memberOf Highcharts
20517         * @param {String} tag - The HTML tag.
20518         * @param {Object} [attribs] - Attributes as an object of key-value pairs.
20519         * @param {CSSObject} [styles] - Styles as an object of key-value pairs.
20520         * @param {Object} [parent] - The parent HTML object.
20521         * @param {Boolean} [nopad=false] - If true, remove all padding, border and
20522         *    margin.
20523         * @returns {HTMLDOMElement} The created DOM element.
20524         */
20525        H.createElement = function(tag, attribs, styles, parent, nopad) {
20526            var el = doc.createElement(tag),
20527                css = H.css;
20528            if (attribs) {
20529                H.extend(el, attribs);
20530            }
20531            if (nopad) {
20532                css(el, {
20533                    padding: 0,
20534                    border: 'none',
20535                    margin: 0
20536                });
20537            }
20538            if (styles) {
20539                css(el, styles);
20540            }
20541            if (parent) {
20542                parent.appendChild(el);
20543            }
20544            return el;
20545        };
20546
20547        /**
20548         * Extend a prototyped class by new members.
20549         *
20550         * @function #extendClass
20551         * @memberOf Highcharts
20552         * @param {Object} parent - The parent prototype to inherit.
20553         * @param {Object} members - A collection of prototype members to add or
20554         *        override compared to the parent prototype.
20555         * @returns {Object} A new prototype.
20556         */
20557        H.extendClass = function(parent, members) {
20558            var object = function() {};
20559            object.prototype = new parent(); // eslint-disable-line new-cap
20560            H.extend(object.prototype, members);
20561            return object;
20562        };
20563
20564        /**
20565         * Left-pad a string to a given length by adding a character repetetively.
20566         *
20567         * @function #pad
20568         * @memberOf Highcharts
20569         * @param {Number} number - The input string or number.
20570         * @param {Number} length - The desired string length.
20571         * @param {String} [padder=0] - The character to pad with.
20572         * @returns {String} The padded string.
20573         */
20574        H.pad = function(number, length, padder) {
20575            return new Array((length || 2) + 1 -
20576                String(number).length).join(padder || 0) + number;
20577        };
20578
20579        /**
20580         * @typedef {Number|String} RelativeSize - If a number is given, it defines the
20581         *    pixel length. If a percentage string is given, like for example `'50%'`,
20582         *    the setting defines a length relative to a base size, for example the size
20583         *    of a container.
20584         */
20585        /**
20586         * Return a length based on either the integer value, or a percentage of a base.
20587         *
20588         * @function #relativeLength
20589         * @memberOf Highcharts
20590         * @param  {RelativeSize} value
20591         *         A percentage string or a number.
20592         * @param  {number} base
20593         *         The full length that represents 100%.
20594         * @param  {number} [offset=0]
20595         *         A pixel offset to apply for percentage values. Used internally in 
20596         *         axis positioning.
20597         * @return {number}
20598         *         The computed length.
20599         */
20600        H.relativeLength = function(value, base, offset) {
20601            return (/%$/).test(value) ?
20602                (base * parseFloat(value) / 100) + (offset || 0) :
20603                parseFloat(value);
20604        };
20605
20606        /**
20607         * Wrap a method with extended functionality, preserving the original function.
20608         *
20609         * @function #wrap
20610         * @memberOf Highcharts
20611         * @param {Object} obj - The context object that the method belongs to. In real
20612         *        cases, this is often a prototype.
20613         * @param {String} method - The name of the method to extend.
20614         * @param {Function} func - A wrapper function callback. This function is called
20615         *        with the same arguments as the original function, except that the
20616         *        original function is unshifted and passed as the first argument.
20617         * 
20618         */
20619        H.wrap = function(obj, method, func) {
20620            var proceed = obj[method];
20621            obj[method] = function() {
20622                var args = Array.prototype.slice.call(arguments),
20623                    outerArgs = arguments,
20624                    ctx = this,
20625                    ret;
20626                ctx.proceed = function() {
20627                    proceed.apply(ctx, arguments.length ? arguments : outerArgs);
20628                };
20629                args.unshift(proceed);
20630                ret = func.apply(this, args);
20631                ctx.proceed = null;
20632                return ret;
20633            };
20634        };
20635
20636        /**
20637         * Get the time zone offset based on the current timezone information as set in
20638         * the global options.
20639         *
20640         * @function #getTZOffset
20641         * @memberOf Highcharts
20642         * @param  {Number} timestamp - The JavaScript timestamp to inspect.
20643         * @return {Number} - The timezone offset in minutes compared to UTC.
20644         */
20645        H.getTZOffset = function(timestamp) {
20646            var d = H.Date;
20647            return ((d.hcGetTimezoneOffset && d.hcGetTimezoneOffset(timestamp)) ||
20648                d.hcTimezoneOffset || 0) * 60000;
20649        };
20650
20651        /**
20652         * Formats a JavaScript date timestamp (milliseconds since Jan 1st 1970) into a
20653         * human readable date string. The format is a subset of the formats for PHP's
20654         * [strftime]{@link
20655         * http://www.php.net/manual/en/function.strftime.php} function. Additional
20656         * formats can be given in the {@link Highcharts.dateFormats} hook.
20657         *
20658         * @function #dateFormat
20659         * @memberOf Highcharts
20660         * @param {String} format - The desired format where various time
20661         *        representations are prefixed with %.
20662         * @param {Number} timestamp - The JavaScript timestamp.
20663         * @param {Boolean} [capitalize=false] - Upper case first letter in the return.
20664         * @returns {String} The formatted date.
20665         */
20666        H.dateFormat = function(format, timestamp, capitalize) {
20667            if (!H.defined(timestamp) || isNaN(timestamp)) {
20668                return H.defaultOptions.lang.invalidDate || '';
20669            }
20670            format = H.pick(format, '%Y-%m-%d %H:%M:%S');
20671
20672            var D = H.Date,
20673                date = new D(timestamp - H.getTZOffset(timestamp)),
20674                // get the basic time values
20675                hours = date[D.hcGetHours](),
20676                day = date[D.hcGetDay](),
20677                dayOfMonth = date[D.hcGetDate](),
20678                month = date[D.hcGetMonth](),
20679                fullYear = date[D.hcGetFullYear](),
20680                lang = H.defaultOptions.lang,
20681                langWeekdays = lang.weekdays,
20682                shortWeekdays = lang.shortWeekdays,
20683                pad = H.pad,
20684
20685                // List all format keys. Custom formats can be added from the outside. 
20686                replacements = H.extend({
20687
20688                        // Day
20689                        // Short weekday, like 'Mon'
20690                        'a': shortWeekdays ?
20691                            shortWeekdays[day] : langWeekdays[day].substr(0, 3),
20692                        // Long weekday, like 'Monday'
20693                        'A': langWeekdays[day],
20694                        // Two digit day of the month, 01 to 31
20695                        'd': pad(dayOfMonth),
20696                        // Day of the month, 1 through 31
20697                        'e': pad(dayOfMonth, 2, ' '),
20698                        'w': day,
20699
20700                        // Week (none implemented)
20701                        // 'W': weekNumber(),
20702
20703                        // Month
20704                        // Short month, like 'Jan'
20705                        'b': lang.shortMonths[month],
20706                        // Long month, like 'January'
20707                        'B': lang.months[month],
20708                        // Two digit month number, 01 through 12
20709                        'm': pad(month + 1),
20710
20711                        // Year
20712                        // Two digits year, like 09 for 2009
20713                        'y': fullYear.toString().substr(2, 2),
20714                        // Four digits year, like 2009
20715                        'Y': fullYear,
20716
20717                        // Time
20718                        // Two digits hours in 24h format, 00 through 23
20719                        'H': pad(hours),
20720                        // Hours in 24h format, 0 through 23
20721                        'k': hours,
20722                        // Two digits hours in 12h format, 00 through 11
20723                        'I': pad((hours % 12) || 12),
20724                        // Hours in 12h format, 1 through 12
20725                        'l': (hours % 12) || 12,
20726                        // Two digits minutes, 00 through 59
20727                        'M': pad(date[D.hcGetMinutes]()),
20728                        // Upper case AM or PM
20729                        'p': hours < 12 ? 'AM' : 'PM',
20730                        // Lower case AM or PM
20731                        'P': hours < 12 ? 'am' : 'pm',
20732                        // Two digits seconds, 00 through  59
20733                        'S': pad(date.getSeconds()),
20734                        // Milliseconds (naming from Ruby)
20735                        'L': pad(Math.round(timestamp % 1000), 3)
20736                    },
20737
20738                    /**
20739                     * A hook for defining additional date format specifiers. New
20740                     * specifiers are defined as key-value pairs by using the specifier
20741                     * as key, and a function which takes the timestamp as value. This
20742                     * function returns the formatted portion of the date.
20743                     *
20744                     * @type {Object}
20745                     * @name dateFormats
20746                     * @memberOf Highcharts
20747                     * @sample highcharts/global/dateformats/ Adding support for week
20748                     * number
20749                     */
20750                    H.dateFormats
20751                );
20752
20753
20754            // Do the replaces
20755            H.objectEach(replacements, function(val, key) {
20756                // Regex would do it in one line, but this is faster
20757                while (format.indexOf('%' + key) !== -1) {
20758                    format = format.replace(
20759                        '%' + key,
20760                        typeof val === 'function' ? val(timestamp) : val
20761                    );
20762                }
20763
20764            });
20765
20766            // Optionally capitalize the string and return
20767            return capitalize ?
20768                format.substr(0, 1).toUpperCase() + format.substr(1) :
20769                format;
20770        };
20771
20772        /**
20773         * Format a single variable. Similar to sprintf, without the % prefix.
20774         *
20775         * @example
20776         * formatSingle('.2f', 5); // => '5.00'.
20777         *
20778         * @function #formatSingle
20779         * @memberOf Highcharts
20780         * @param {String}
20780 format The format string.
20781         * @param {*} val The value.
20782         * @returns {String} The formatted representation of the value.
20783         */
20784        H.formatSingle = function(format, val) {
20785            var floatRegex = /f$/,
20786                decRegex = /\.([0-9])/,
20787                lang = H.defaultOptions.lang,
20788                decimals;
20789
20790            if (floatRegex.test(format)) { // float
20791                decimals = format.match(decRegex);
20792                decimals = decimals ? decimals[1] : -1;
20793                if (val !== null) {
20794                    val = H.numberFormat(
20795                        val,
20796                        decimals,
20797                        lang.decimalPoint,
20798                        format.indexOf(',') > -1 ? lang.thousandsSep : ''
20799                    );
20800                }
20801            } else {
20802                val = H.dateFormat(format, val);
20803            }
20804            return val;
20805        };
20806
20807        /**
20808         * Format a string according to a subset of the rules of Python's String.format
20809         * method.
20810         *
20811         * @function #format
20812         * @memberOf Highcharts
20813         * @param {String} str The string to format.
20814         * @param {Object} ctx The context, a collection of key-value pairs where each
20815         *        key is replaced by its value.
20816         * @returns {String} The formatted string.
20817         *
20818         * @example
20819         * var s = Highcharts.format(
20820         *     'The {color} fox was {len:.2f} feet long',
20821         *     { color: 'red', len: Math.PI }
20822         * );
20823         * // => The red fox was 3.14 feet long
20824         */
20825        H.format = function(str, ctx) {
20826            var splitter = '{',
20827                isInside = false,
20828                segment,
20829                valueAndFormat,
20830                path,
20831                i,
20832                len,
20833                ret = [],
20834                val,
20835                index;
20836
20837            while (str) {
20838                index = str.indexOf(splitter);
20839                if (index === -1) {
20840                    break;
20841                }
20842
20843                segment = str.slice(0, index);
20844                if (isInside) { // we're on the closing bracket looking back
20845
20846                    valueAndFormat = segment.split(':');
20847                    path = valueAndFormat.shift().split('.'); // get first and leave
20848                    len = path.length;
20849                    val = ctx;
20850
20851                    // Assign deeper paths
20852                    for (i = 0; i < len; i++) {
20853                        if (val) {
20854                            val = val[path[i]];
20855                        }
20856                    }
20857
20858                    // Format the replacement
20859                    if (valueAndFormat.length) {
20860                        val = H.formatSingle(valueAndFormat.join(':'), val);
20861                    }
20862
20863                    // Push the result and advance the cursor
20864                    ret.push(val);
20865
20866                } else {
20867                    ret.push(segment);
20868
20869                }
20870                str = str.slice(index + 1); // the rest
20871                isInside = !isInside; // toggle
20872                splitter = isInside ? '}' : '{'; // now look for next matching bracket
20873            }
20874            ret.push(str);
20875            return ret.join('');
20876        };
20877
20878        /**
20879         * Get the magnitude of a number.
20880         *
20881         * @function #getMagnitude
20882         * @memberOf Highcharts
20883         * @param {Number} number The number.
20884         * @returns {Number} The magnitude, where 1-9 are magnitude 1, 10-99 magnitude 2
20885         *        etc.
20886         */
20887        H.getMagnitude = function(num) {
20888            return Math.pow(10, Math.floor(Math.log(num) / Math.LN10));
20889        };
20890
20891        /**
20892         * Take an interval and normalize it to multiples of round numbers.
20893         *
20894         * @todo  Move this function to the Axis prototype. It is here only for
20895         *        historical reasons.
20896         * @function #normalizeTickInterval
20897         * @memberOf Highcharts
20898         * @param {Number} interval - The raw, un-rounded interval.
20899         * @param {Array} [multiples] - Allowed multiples.
20900         * @param {Number} [magnitude] - The magnitude of the number.
20901         * @param {Boolean} [allowDecimals] - Whether to allow decimals.
20902         * @param {Boolean}
20902 [hasTickAmount] - If it has tickAmount, avoid landing
20903         *        on tick intervals lower than original.
20904         * @returns {Number} The normalized interval.
20905         */
20906        H.normalizeTickInterval = function(interval, multiples, magnitude,
20907            allowDecimals, hasTickAmount) {
20908            var normalized,
20909                i,
20910                retInterval = interval;
20911
20912            // round to a tenfold of 1, 2, 2.5 or 5
20913            magnitude = H.pick(magnitude, 1);
20914            normalized = interval / magnitude;
20915
20916            // multiples for a linear scale
20917            if (!multiples) {
20918                multiples = hasTickAmount ?
20919                    // Finer grained ticks when the tick amount is hard set, including
20920                    // when alignTicks is true on multiple axes (#4580).
20921                    [1, 1.2, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10] :
20922
20923                    // Else, let ticks fall on rounder numbers
20924                    [1, 2, 2.5, 5, 10];
20925
20926
20927                // the allowDecimals option
20928                if (allowDecimals === false) {
20929                    if (magnitude === 1) {
20930                        multiples = H.grep(multiples, function(num) {
20931                            return num % 1 === 0;
20932                        });
20933                    } else if (magnitude <= 0.1) {
20934                        multiples = [1 / magnitude];
20935                    }
20936                }
20937            }
20938
20939            // normalize the interval to the nearest multiple
20940            for (i = 0; i < multiples.length; i++) {
20941                retInterval = multiples[i];
20942                // only allow tick amounts smaller than natural
20943                if ((hasTickAmount && retInterval * magnitude >= interval) ||
20944                    (!hasTickAmount && (normalized <= (multiples[i] +
20945                        (multiples[i + 1] || multiples[i])) / 2))) {
20946                    break;
20947                }
20948            }
20949
20950            // Multiply back to the correct magnitude. Correct floats to appropriate 
20951            // precision (#6085).
20952            retInterval = H.correctFloat(
20953                retInterval * magnitude, -Math.round(Math.log(0.001) / Math.LN10)
20954            );
20955
20956            return retInterval;
20957        };
20958
20959
20960        /**
20961         * Sort an object array and keep the order of equal items. The ECMAScript
20962         * standard does not specify the behaviour when items are equal.
20963         *
20964         * @function #stableSort
20965         * @memberOf Highcharts
20966         * @param {Array} arr - The array to sort.
20967         * @param {Function} sortFunction - The function to sort it with, like with 
20968         *        regular Array.prototype.sort.
20969         * 
20970         */
20971        H.stableSort = function(arr, sortFunction) {
20972            var length = arr.length,
20973                sortValue,
20974                i;
20975
20976            // Add index to each item
20977            for (i = 0; i < length; i++) {
20978                arr[i].safeI = i; // stable sort index
20979            }
20980
20981            arr.sort(function(a, b) {
20982                sortValue = sortFunction(a, b);
20983                return sortValue === 0 ? a.safeI - b.safeI : sortValue;
20984            });
20985
20986            // Remove index from items
20987            for (i = 0; i < length; i++) {
20988                delete arr[i].safeI; // stable sort index
20989            }
20990        };
20991
20992        /**
20993         * Non-recursive method to find the lowest member of an array. `Math.min` raises
20994         * a maximum call stack size exceeded error in Chrome when trying to apply more
20995         * than 150.000 points. This method is slightly slower, but safe.
20996         *
20997         * @function #arrayMin
20998         * @memberOf  Highcharts
20999         * @param {Array} data An array of numbers.
21000         * @returns {Number} The lowest number.
21001         */
21002        H.arrayMin = function(data) {
21003            var i = data.length,
21004                min = data[0];
21005
21006            while (i--) {
21007                if (data[i] < min) {
21008                    min = data[i];
21009                }
21010            }
21011            return min;
21012        };
21013
21014        /**
21015         * Non-recursive method to find the lowest member of an array. `Math.max` raises
21016         * a maximum call stack size exceeded error in Chrome when trying to apply more
21017         * than 150.000 points. This method is slightly slower, but safe.
21018         *
21019         * @function #arrayMax
21020         * @memberOf  Highcharts
21021         * @param {Array} data - An array of numbers.
21022         * @returns {Number} The highest number.
21023         */
21024        H.arrayMax = function(data) {
21025            var i = data.length,
21026                max = data[0];
21027
21028            while (i--) {
21029                if (data[i] > max) {
21030                    max = data[i];
21031                }
21032            }
21033            return max;
21034        };
21035
21036        /**
21037         * Utility method that destroys any SVGElement instances that are properties on
21038         * the given object. It loops all properties and invokes destroy if there is a
21039         * destroy method. The property is then delete.
21040         *
21041         * @function #destroyObjectProperties
21042         * @memberOf Highcharts
21043         * @param {Object} obj - The object to destroy properties on.
21044         * @param {Object} [except] - Exception, do not destroy this property, only
21045         *    delete it.
21046         * 
21047         */
21048        H.destroyObjectProperties = function(obj, except) {
21049            H.objectEach(obj, function(val, n) {
21050                // If the object is non-null and destroy is defined
21051                if (val && val !== except && val.destroy) {
21052                    // Invoke the destroy
21053                    val.destroy();
21054                }
21055
21056                // Delete the property from the object.
21057                delete obj[n];
21058            });
21059        };
21060
21061
21062        /**
21063         * Discard a HTML element by moving it to the bin and delete.
21064         *
21065         * @function #discardElement
21066         * @memberOf Highcharts
21067         * @param {HTMLDOMElement} element - The HTML node to discard.
21068         * 
21069         */
21070        H.discardElement = function(element) {
21071            var garbageBin = H.garbageBin;
21072            // create a garbage bin element, not part of the DOM
21073            if (!garbageBin) {
21074                garbageBin = H.createElement('div');
21075            }
21076
21077            // move the node and empty bin
21078            if (element) {
21079                garbageBin.appendChild(element);
21080            }
21081            garbageBin.innerHTML = '';
21082        };
21083
21084        /**
21085         * Fix JS round off float errors.
21086         *
21087         * @function #correctFloat
21088         * @memberOf Highcharts
21089         * @param {Number} num - A float number to fix.
21090         * @param {Number} [prec=14] - The precision.
21091         * @returns {Number} The corrected float number.
21092         */
21093        H.correctFloat = function(num, prec) {
21094            return parseFloat(
21095                num.toPrecision(prec || 14)
21096            );
21097        };
21098
21099        /**
21100         * Set the global animation to either a given value, or fall back to the given
21101         * chart's animation option.
21102         *
21103         * @function #setAnimation
21104         * @memberOf Highcharts
21105         * @param {Boolean|Animation} animation - The animation object.
21106         * @param {Object} chart - The chart instance.
21107         * 
21108         * @todo This function always relates to a chart, and sets a property on the
21109         *        renderer, so it should be moved to the SVGRenderer.
21110         */
21111        H.setAnimation = function(animation, chart) {
21112            chart.renderer.globalAnimation = H.pick(
21113                animation,
21114                chart.options.chart.animation,
21115                true
21116            );
21117        };
21118
21119        /**
21120         * Get the animation in object form, where a disabled animation is always
21121         * returned as `{ duration: 0 }`.
21122         *
21123         * @function #animObject
21124         * @memberOf Highcharts
21125         * @param {Boolean|AnimationOptions} animation - An animation setting. Can be an
21126         *        object with duration, complete and easing properties, or a boolean to
21127         *        enable or disable.
21128         * @returns {AnimationOptions} An object with at least a duration property.
21129         */
21130        H.animObject = function(animation) {
21131            return H.isObject(animation) ?
21132                H.merge(animation) : {
21133                    duration: animation ? 500 : 0
21134                };
21135        };
21136
21137        /**
21138         * The time unit lookup
21139         */
21140        H.timeUnits = {
21141            millisecond: 1,
21142            second: 1000,
21143            minute: 60000,
21144            hour: 3600000,
21145            day: 24 * 3600000,
21146            week: 7 * 24 * 3600000,
21147            month: 28 * 24 * 3600000,
21148            year: 364 * 24 * 3600000
21149        };
21150
21151        /**
21152         * Format a number and return a string based on input settings.
21153         *
21154         * @function #numberFormat
21155         * @memberOf Highcharts
21156         * @param {Number} number - The input number to format.
21157         * @param {Number} decimals - The amount of decimals. A value of -1 preserves
21158         *        the amount in the input number.
21159         * @param {String} [decimalPoint] - The decimal point, defaults to the one given
21160         *        in the lang options, or a dot.
21161         * @param {String} [thousandsSep] - The thousands separator, defaults to the one
21162         *        given in the lang options, or a space character.
21163         * @returns {String} The formatted number.
21164         *
21165         * @sample highcharts/members/highcharts-numberformat/ Custom number format
21166         */
21167        H.numberFormat = function(number, decimals, decimalPoint, thousandsSep) {
21168            number = +number || 0;
21169            decimals = +decimals;
21170
21171            var lang = H.defaultOptions.lang,
21172                origDec = (number.toString().split('.')[1] || '').split('e')[0].length,
21173                strinteger,
21174                thousands,
21175                ret,
21176                roundedNumber,
21177                exponent = number.toString().split('e');
21178
21179            if (decimals === -1) {
21180                // Preserve decimals. Not huge numbers (#3793).
21181                decimals = Math.min(origDec, 20);
21182            } else if (!H.isNumber(decimals)) {
21183                decimals = 2;
21184            }
21185
21186            // Add another decimal to avoid rounding errors of float numbers. (#4573)
21187            // Then use toFixed to handle rounding.
21188            roundedNumber = (
21189                Math.abs(exponent[1] ? exponent[0] : number) +
21190                Math.pow(10, -Math.max(decimals, origDec) - 1)
21191            ).toFixed(decimals);
21192
21193            // A string containing the positive integer component of the number
21194            strinteger = String(H.pInt(roundedNumber));
21195
21196            // Leftover after grouping into thousands. Can be 0, 1 or 3.
21197            thousands = strinteger.length > 3 ? strinteger.length % 3 : 0;
21198
21199            // Language
21200            decimalPoint = H.pick(decimalPoint, lang.decimalPoint);
21201            thousandsSep = H.pick(thousandsSep, lang.thousandsSep);
21202
21203            // Start building the return
21204            ret = number < 0 ? '-' : '';
21205
21206            // Add the leftover after grouping into thousands. For example, in the
21207            // number 42 000 000, this line adds 42.
21208            ret += thousands ? strinteger.substr(0, thousands) + thousandsSep : '';
21209
21210            // Add the remaining thousands groups, joined by the thousands separator
21211            ret += strinteger
21212                .substr(thousands)
21213                .replace(/(\d{3})(?=\d)/g, '$1' + thousandsSep);
21214
21215            // Add the decimal point and the decimal component
21216            if (decimals) {
21217                // Get the decimal component
21218                ret += decimalPoint + roundedNumber.slice(-decimals);
21219            }
21220
21221            if (exponent[1]) {
21222                ret += 'e' + exponent[1];
21223            }
21224
21225            return ret;
21226        };
21227
21228        /**
21229         * Easing definition
21230         * @ignore
21231         * @param   {Number} pos Current position, ranging from 0 to 1.
21232         */
21233        Math.easeInOutSine = function(pos) {
21234            return -0.5 * (Math.cos(Math.PI * pos) - 1);
21235        };
21236
21237        /**
21238         * Get the computed CSS value for given element and property, only for numerical
21239         * properties. For width and height, the dimension of the inner box (excluding
21240         * padding) is returned. Used for fitting the chart within the container.
21241         *
21242         * @function #getStyle
21243         * @memberOf Highcharts
21244         * @param {HTMLDOMElement} el - A HTML element.
21245         * @param {String} prop - The property name.
21246         * @param {Boolean} [toInt=true] - Parse to integer.
21247         * @returns {Number} - The numeric value.
21248         */
21249        H.getStyle = function(el, prop, toInt) {
21250
21251            var style;
21252
21253            // For width and height, return the actual inner pixel size (#4913)
21254            if (prop === 'width') {
21255                return Math.min(el.offsetWidth, el.scrollWidth) -
21256                    H.getStyle(el, 'padding-left') -
21257                    H.getStyle(el, 'padding-right');
21258            } else if (prop === 'height') {
21259                return Math.min(el.offsetHeight, el.scrollHeight) -
21260                    H.getStyle(el, 'padding-top') -
21261                    H.getStyle(el, 'padding-bottom');
21262            }
21263
21264            if (!win.getComputedStyle) {
21265                // SVG not supported, forgot to load oldie.js?
21266                H.error(27, true);
21267            }
21268
21269            // Otherwise, get the computed style
21270            style = win.getComputedStyle(el, undefined);
21271            if (style) {
21272                style = style.getPropertyValue(prop);
21273                if (H.pick(toInt, prop !== 'opacity')) {
21274                    style = H.pInt(style);
21275                }
21276            }
21277            return style;
21278        };
21279
21280        /**
21281         * Search for an item in an array.
21282         *
21283         * @function #inArray
21284         * @memberOf Highcharts
21285         * @param {*} item - The item to search for.
21286         * @param {arr} arr - The array or node collection to search in.
21287         * @returns {Number} - The index within the array, or -1 if not found.
21288         */
21289        H.inArray = function(item, arr) {
21290            return (H.indexOfPolyfill || Array.prototype.indexOf).call(arr, item);
21291        };
21292
21293        /**
21294         * Filter an array by a callback.
21295         *
21296         * @function #grep
21297         * @memberOf Highcharts
21298         * @param {Array} arr - The array to filter.
21299         * @param {Function} callback - The callback function. The function receives the
21300         *        item as the first argument. Return `true` if the item is to be
21301         *        preserved.
21302         * @returns {Array} - A new, filtered array.
21303         */
21304        H.grep = function(arr, callback) {
21305            return (H.filterPolyfill || Array.prototype.filter).call(arr, callback);
21306        };
21307
21308        /**
21309         * Return the value of the first element in the array that satisfies the 
21310         * provided testing function.
21311         *
21312         * @function #find
21313         * @memberOf Highcharts
21314         * @param {Array} arr - The array to test.
21315         * @param {Function} callback - The callback function. The function receives the
21316         *        item as the first argument. Return `true` if this item satisfies the
21317         *        condition.
21318         * @returns {Mixed} - The value of the element.
21319         */
21320        H.find = Array.prototype.find ?
21321            function(arr, callback) {
21322                return arr.find(callback);
21323            } :
21324            // Legacy implementation. PhantomJS, IE <= 11 etc. #7223.
21325            function(arr, fn) {
21326                var i,
21327                    length = arr.length;
21328
21329                for (i = 0; i < length; i++) {
21330                    if (fn(arr[i], i)) {
21331                        return arr[i];
21332                    }
21333                }
21334            };
21335
21336        /**
21337         * Map an array by a callback.
21338         *
21339         * @function #map
21340         * @memberOf Highcharts
21341         * @param {Array} arr - The array to map.
21342         * @param {Function} fn - The callback function. Return the new value for the 
21343         *        new array.
21344         * @returns {Array} - A new array item with modified items.
21345         */
21346        H.map = function(arr, fn) {
21347            var results = [],
21348                i = 0,
21349                len = arr.length;
21350
21351            for (; i < len; i++) {
21352                results[i] = fn.call(arr[i], arr[i], i, arr);
21353            }
21354
21355            return results;
21356        };
21357
21358        /**
21359         * Returns an array of a given object's own properties.
21360         *
21361         * @function #keys
21362         * @memberOf highcharts
21363         * @param {Object} obj - The object of which the properties are to be returned.
21364         * @returns {Array}
21364 - An array of strings that represents all the properties.
21365         */
21366        H.keys = function(obj) {
21367            return (H.keysPolyfill || Object.keys).call(undefined, obj);
21368        };
21369
21370        /**
21371         * Reduce an array to a single value.
21372         *
21373         * @function #reduce
21374         * @memberOf Highcharts
21375         * @param {Array} arr - The array to reduce.
21376         * @param {Function} fn - The callback function. Return the reduced value. 
21377         *  Receives 4 arguments: Accumulated/reduced value, current value, current 
21378         *  array index, and the array.
21379         * @param {Mixed} initialValue - The initial value of the accumulator.
21380         * @returns {Mixed} - The reduced value.
21381         */
21382        H.reduce = function(arr, func, initialValue) {
21383            return (H.reducePolyfill || Array.prototype.reduce).call(
21384                arr,
21385                func,
21386                initialValue
21387            );
21388        };
21389
21390        /**
21391         * Get the element's offset position, corrected for `overflow: auto`.
21392         *
21393         * @function #offset
21394         * @memberOf Highcharts
21395         * @param {HTMLDOMElement} el - The HTML element.
21396         * @returns {Object} An object containing `left` and `top` properties for the
21397         * position in the page.
21398         */
21399        H.offset = function(el) {
21400            var docElem = doc.documentElement,
21401                box = el.parentElement ? // IE11 throws Unspecified error in test suite
21402                el.getBoundingClientRect() : {
21403                    top: 0,
21404                    left: 0
21405                };
21406
21407            return {
21408                top: box.top + (win.pageYOffset || docElem.scrollTop) -
21409                    (docElem.clientTop || 0),
21410                left: box.left + (win.pageXOffset || docElem.scrollLeft) -
21411                    (docElem.clientLeft || 0)
21412            };
21413        };
21414
21415        /**
21416         * Stop running animation.
21417         *
21418         * @todo A possible extension to this would be to stop a single property, when
21419         * we want to continue animating others. Then assign the prop to the timer
21420         * in the Fx.run method, and check for the prop here. This would be an
21421         * improvement in all cases where we stop the animation from .attr. Instead of
21422         * stopping everything, we can just stop the actual attributes we're setting.
21423         *
21424         * @function #stop
21425         * @memberOf Highcharts
21426         * @param {SVGElement} el - The SVGElement to stop animation on.
21427         * @param {string} [prop] - The property to stop animating. If given, the stop
21428         *    method will stop a single property from animating, while others continue.
21429         * 
21430         */
21431        H.stop = function(el, prop) {
21432
21433            var i = H.timers.length;
21434
21435            // Remove timers related to this element (#4519)
21436            while (i--) {
21437                if (H.timers[i].elem === el && (!prop || prop === H.timers[i].prop)) {
21438                    H.timers[i].stopped = true; // #4667
21439                }
21440            }
21441        };
21442
21443        /**
21444         * Iterate over an array.
21445         *
21446         * @function #each
21447         * @memberOf Highcharts
21448         * @param {Array} arr - The array to iterate over.
21449         * @param {Function} fn - The iterator callback. It passes three arguments:
21450         * * item - The array item.
21451         * * index - The item's index in the array.
21452         * * arr - The array that each is being applied to.
21453         * @param {Object} [ctx] The context.
21454         */
21455        H.each = function(arr, fn, ctx) { // modern browsers
21456            return (H.forEachPolyfill || Array.prototype.forEach).call(arr, fn, ctx);
21457        };
21458
21459        /**
21460         * Iterate over object key pairs in an object.
21461         *
21462         * @function #objectEach
21463         * @memberOf Highcharts
21464         * @param  {Object}   obj - The object to iterate over.
21465         * @param  {Function} fn  - The iterator callback. It passes three arguments:
21466         * * value - The property value.
21467         * * key - The property key.
21468         * * obj - The object that objectEach is being applied to.
21469         * @param  {Object}   ctx The context
21470         */
21471        H.objectEach = function(obj, fn, ctx) {
21472            for (var key in obj) {
21473                if (obj.hasOwnProperty(key)) {
21474                    fn.call(ctx, obj[key], key, obj);
21475                }
21476            }
21477        };
21478
21479        /**
21480         * Add an event listener.
21481         *
21482         * @function #addEvent
21483         * @memberOf Highcharts
21484         * @param {Object} el - The element or object to add a listener to. It can be a
21485         *        {@link HTMLDOMElement}, an {@link SVGElement} or any other object.
21486         * @param {String} type - The event type.
21487         * @param {Function} fn - The function callback to execute when the event is 
21488         *        fired.
21489         * @returns {Function} A callback function to remove the added event.
21490         */
21491        H.addEvent = function(el, type, fn) {
21492
21493            var events,
21494                itemEvents,
21495                addEventListener = el.addEventListener || H.addEventListenerPolyfill;
21496
21497            // If events are previously set directly on the prototype, pick them up 
21498            // and copy them over to the instance. Otherwise instance handlers would
21499            // be set on the prototype and apply to multiple charts in the page.
21500            if (el.hcEvents && !el.hasOwnProperty('hcEvents')) {
21501                itemEvents = {};
21502                H.objectEach(el.hcEvents, function(handlers, eventType) {
21503                    itemEvents[eventType] = handlers.slice(0);
21504                });
21505                el.hcEvents = itemEvents;
21506            }
21507
21508            events = el.hcEvents = el.hcEvents || {};
21509
21510            // Handle DOM events
21511            if (addEventListener) {
21512                addEventListener.call(el, type, fn, false);
21513            }
21514
21515            if (!events[type]) {
21516                events[type] = [];
21517            }
21518
21519            events[type].push(fn);
21520
21521            // Return a function that can be called to remove this event.
21522            return function() {
21523                H.removeEvent(el, type, fn);
21524            };
21525        };
21526
21527        /**
21528         * Remove an event that was added with {@link Highcharts#addEvent}.
21529         *
21530         * @function #removeEvent
21531         * @memberOf Highcharts
21532         * @param {Object} el - The element to remove events on.
21533         * @param {String} [type] - The type of events to remove. If undefined, all
21534         *        events are removed from the element.
21535         * @param {Function}
21535 [fn] - The specific callback to remove. If undefined, all
21536         *        events that match the element and optionally the type are removed.
21537         * 
21538         */
21539        H.removeEvent = function(el, type, fn) {
21540
21541            var events,
21542                hcEvents = el.hcEvents,
21543                index;
21544
21545            function removeOneEvent(type, fn) {
21546                var removeEventListener =
21547                    el.removeEventListener || H.removeEventListenerPolyfill;
21548
21549                if (removeEventListener) {
21550                    removeEventListener.call(el, type, fn, false);
21551                }
21552            }
21553
21554            function removeAllEvents() {
21555                var types,
21556                    len;
21557
21558                if (!el.nodeName) {
21559                    return; // break on non-DOM events
21560                }
21561
21562                if (type) {
21563                    types = {};
21564                    types[type] = true;
21565                } else {
21566                    types = hcEvents;
21567                }
21568
21569                H.objectEach(types, function(val, n) {
21570                    if (hcEvents[n]) {
21571                        len = hcEvents[n].length;
21572                        while (len--) {
21573                            removeOneEvent(n, hcEvents[n][len]);
21574                        }
21575                    }
21576                });
21577            }
21578
21579            if (hcEvents) {
21580                if (type) {
21581                    events = hcEvents[type] || [];
21582                    if (fn) {
21583                        index = H.inArray(fn, events);
21584                        if (index > -1) {
21585                            events.splice(index, 1);
21586                            hcEvents[type] = events;
21587                        }
21588                        removeOneEvent(type, fn);
21589
21590                    } else {
21591                        removeAllEvents();
21592                        hcEvents[type] = [];
21593                    }
21594                } else {
21595                    removeAllEvents();
21596                    el.hcEvents = {};
21597                }
21598            }
21599        };
21600
21601        /**
21602         * Fire an event that was registered with {@link Highcharts#addEvent}.
21603         *
21604         * @function #fireEvent
21605         * @memberOf Highcharts
21606         * @param {Object} el - The object to fire the event on. It can be a
21607         *        {@link HTMLDOMElement}, an {@link SVGElement} or any other object.
21608         * @param {String} type - The type of event.
21609         * @param {Object} [eventArguments] - Custom event arguments that are passed on
21610         *        as an argument to the event handler.
21611         * @param {Function} [defaultFunction] - The default function to execute if the 
21612         *        other listeners haven't returned false.
21613         * 
21614         */
21615        H.fireEvent = function(el, type, eventArguments, defaultFunction) {
21616            var e,
21617                hcEvents = el.hcEvents,
21618                events,
21619                len,
21620                i,
21621                fn;
21622
21623            eventArguments = eventArguments || {};
21624
21625            if (doc.createEvent && (el.dispatchEvent || el.fireEvent)) {
21626                e = doc.createEvent('Events');
21627                e.initEvent(type, true, true);
21628
21629                H.extend(e, eventArguments);
21630
21631                if (el.dispatchEvent) {
21632                    el.dispatchEvent(e);
21633                } else {
21634                    el.fireEvent(type, e);
21635                }
21636
21637            } else if (hcEvents) {
21638
21639                events = hcEvents[type] || [];
21640                len = events.length;
21641
21642                if (!eventArguments.target) { // We're running a custom event
21643
21644                    H.extend(eventArguments, {
21645                        // Attach a simple preventDefault function to skip default
21646                        // handler if called. The built-in defaultPrevented property is
21647                        // not overwritable (#5112)
21648                        preventDefault: function() {
21649                            eventArguments.defaultPrevented = true;
21650                        },
21651                        // Setting target to native events fails with clicking the
21652                        // zoom-out button in Chrome.
21653                        target: el,
21654                        // If the type is not set, we're running a custom event (#2297).
21655                        // If it is set, we're running a browser event, and setting it
21656                        // will cause en error in IE8 (#2465).		
21657                        type: type
21658                    });
21659                }
21660
21661
21662                for (i = 0; i < len; i++) {
21663                    fn = events[i];
21664
21665                    // If the event handler return false, prevent the default handler
21666                    // from executing
21667                    if (fn && fn.call(el, eventArguments) === false) {
21668                        eventArguments.preventDefault();
21669                    }
21670                }
21671            }
21672
21673            // Run the default if not prevented
21674            if (defaultFunction && !eventArguments.defaultPrevented) {
21675                defaultFunction(eventArguments);
21676            }
21677        };
21678
21679        /**
21680         * An animation configuration. Animation configurations can also be defined as
21681         * booleans, where `false` turns off animation and `true` defaults to a duration
21682         * of 500ms.
21683         * @typedef {Object} AnimationOptions
21684         * @property {Number} duration - The animation duration in milliseconds.
21685         * @property {String} [easing] - The name of an easing function as defined on
21686         *     the `Math` object.
21687         * @property {Function} [complete] - A callback function to exectute when the
21688         *     animation finishes.
21689         * @property {Function} [step] - A callback function to execute on each step of
21690         *     each attribute or CSS property that's being animated. The first argument
21691         *     contains information about the animation and progress.
21692         */
21693
21694
21695        /**
21696         * The global animate method, which uses Fx to create individual animators.
21697         *
21698         * @function #animate
21699         * @memberOf Highcharts
21700         * @param {HTMLDOMElement|SVGElement} el - The element to animate.
21701         * @param {Object}
21701 params - An object containing key-value pairs of the
21702         *        properties to animate. Supports numeric as pixel-based CSS properties
21703         *        for HTML objects and attributes for SVGElements.
21704         * @param {AnimationOptions} [opt] - Animation options.
21705         */
21706        H.animate = function(el, params, opt) {
21707            var start,
21708                unit = '',
21709                end,
21710                fx,
21711                args;
21712
21713            if (!H.isObject(opt)) { // Number or undefined/null
21714                args = arguments;
21715                opt = {
21716                    duration: args[2],
21717                    easing: args[3],
21718                    complete: args[4]
21719                };
21720            }
21721            if (!H.isNumber(opt.duration)) {
21722                opt.duration = 400;
21723            }
21724            opt.easing = typeof opt.easing === 'function' ?
21725                opt.easing :
21726                (Math[opt.easing] || Math.easeInOutSine);
21727            opt.curAnim = H.merge(params);
21728
21729            H.objectEach(params, function(val, prop) {
21730                // Stop current running animation of this property
21731                H.stop(el, prop);
21732
21733                fx = new H.Fx(el, opt, prop);
21734                end = null;
21735
21736                if (prop === 'd') {
21737                    fx.paths = fx.initPath(
21738                        el,
21739                        el.d,
21740                        params.d
21741                    );
21742                    fx.toD = params.d;
21743                    start = 0;
21744                    end = 1;
21745                } else if (el.attr) {
21746                    start = el.attr(prop);
21747                } else {
21748                    start = parseFloat(H.getStyle(el, prop)) || 0;
21749                    if (prop !== 'opacity') {
21750                        unit = 'px';
21751                    }
21752                }
21753
21754                if (!end) {
21755                    end = val;
21756                }
21757                if (end && end.match && end.match('px')) {
21758                    end = end.replace(/px/g, ''); // #4351
21759                }
21760                fx.run(start, end, unit);
21761            });
21762        };
21763
21764        /**
21765         * Factory to create new series prototypes.
21766         *
21767         * @function #seriesType
21768         * @memberOf Highcharts
21769         *
21770         * @param {String} type - The series type name.
21771         * @param {String} parent - The parent series type name. Use `line` to inherit
21772         *        from the basic {@link Series} object.
21773         * @param {Object} options - The additional default options that is merged with
21774         *        the parent's options.
21775         * @param {Object} props - The properties (functions and primitives) to set on
21776         *        the new prototype.
21777         * @param {Object} [pointProps] - Members for a series-specific extension of the
21778         *        {@link Point} prototype if needed.
21779         * @returns {*} - The newly created prototype as extended from {@link Series}
21780         * or its derivatives.
21781         */
21782        // docs: add to API + extending Highcharts
21783        H.seriesType = function(type, parent, options, props, pointProps) {
21784            var defaultOptions = H.getOptions(),
21785                seriesTypes = H.seriesTypes;
21786
21787            // Merge the options
21788            defaultOptions.plotOptions[type] = H.merge(
21789                defaultOptions.plotOptions[parent],
21790                options
21791            );
21792
21793            // Create the class
21794            seriesTypes[type] = H.extendClass(seriesTypes[parent] ||
21795                function() {}, props);
21796            seriesTypes[type].prototype.type = type;
21797
21798            // Create the point class if needed
21799            if (pointProps) {
21800                seriesTypes[type].prototype.pointClass =
21801                    H.extendClass(H.Point, pointProps);
21802            }
21803
21804            return seriesTypes[type];
21805        };
21806
21807        /**
21808         * Get a unique key for using in internal element id's and pointers. The key
21809         * is composed of a random hash specific to this Highcharts instance, and a 
21810         * counter.
21811         * @function #uniqueKey
21812         * @memberOf Highcharts
21813         * @return {string} The key.
21814         * @example
21815         * var id = H.uniqueKey(); // => 'highcharts-x45f6hp-0'
21816         */
21817        H.uniqueKey = (function() {
21818
21819            var uniqueKeyHash = Math.random().toString(36).substring(2, 9),
21820                idCounter = 0;
21821
21822            return function() {
21823                return 'highcharts-' + uniqueKeyHash + '-' + idCounter++;
21824            };
21825        }());
21826
21827        /**
21828         * Register Highcharts as a plugin in jQuery
21829         */
21830        if (win.jQuery) {
21831            win.jQuery.fn.highcharts = function() {
21832                var args = [].slice.call(arguments);
21833
21834                if (this[0]) { // this[0] is the renderTo div
21835
21836                    // Create the chart
21837                    if (args[0]) {
21838                        new H[ // eslint-disable-line no-new
21839                            // Constructor defaults to Chart
21840                            H.isString(args[0]) ? args.shift() : 'Chart'
21841                        ](this[0], args[0], args[1]);
21842                        return this;
21843                    }
21844
21845                    // When called without parameters or with the return argument,
21846                    // return an existing chart
21847                    return charts[H.attr(this[0], 'data-highcharts-chart')];
21848                }
21849            };
21850        }
21851
21852    }
21852(Highcharts));
21853    (function(H) {
21854        /**
21855         * (c) 2010-2017 Torstein Honsi
21856         *
21857         * License: www.highcharts.com/license
21858         */
21859        var each = H.each,
21860            isNumber = H.isNumber,
21861            map = H.map,
21862            merge = H.merge,
21863            pInt = H.pInt;
21864
21865        /**
21866         * @typedef {string} ColorString
21867         * A valid color to be parsed and handled by Highcharts. Highcharts internally 
21868         * supports hex colors like `#ffffff`, rgb colors like `rgb(255,255,255)` and
21869         * rgba colors like `rgba(255,255,255,1)`. Other colors may be supported by the
21870         * browsers and displayed correctly, but Highcharts is not able to process them
21871         * and apply concepts like opacity and brightening.
21872         */
21873        /**
21874         * Handle color operations. The object methods are chainable.
21875         * @param {String} input The input color in either rbga or hex format
21876         */
21877        H.Color = function(input) {
21878            // Backwards compatibility, allow instanciation without new
21879            if (!(this instanceof H.Color)) {
21880                return new H.Color(input);
21881            }
21882            // Initialize
21883            this.init(input);
21884        };
21885        H.Color.prototype = {
21886
21887            // Collection of parsers. This can be extended from the outside by pushing parsers
21888            // to Highcharts.Color.prototype.parsers.
21889            parsers: [{
21890                // RGBA color
21891                regex: /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]?(?:\.[0-9]+)?)\s*\)/,
21892                parse: function(result) {
21893                    return [pInt(result[1]), pInt(result[2]), pInt(result[3]), parseFloat(result[4], 10)];
21894                }
21895            }, {
21896                // RGB color
21897                regex: /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/,
21898                parse: function(result) {
21899                    return [pInt(result[1]), pInt(result[2]), pInt(result[3]), 1];
21900                }
21901            }],
21902
21903            // Collection of named colors. Can be extended from the outside by adding
21904            // colors to Highcharts.Color.prototype.names.
21905            names: {
21906                none: 'rgba(255,255,255,0)',
21907                white: '#ffffff',
21908                black: '#000000'
21909            },
21910
21911            /**
21912             * Parse the input color to rgba array
21913             * @param {String} input
21914             */
21915            init: function(input) {
21916                var result,
21917                    rgba,
21918                    i,
21919                    parser,
21920                    len;
21921
21922                this.input = input = this.names[
21923                    input && input.toLowerCase ?
21924                    input.toLowerCase() :
21925                    ''
21926                ] || input;
21927
21928                // Gradients
21929                if (input && input.stops) {
21930                    this.stops = map(input.stops, function(stop) {
21931                        return new H.Color(stop[1]);
21932                    });
21933
21934                    // Solid colors
21935                } else {
21936
21937                    // Bitmasking as input[0] is not working for legacy IE.
21938                    if (input && input.charAt && input.charAt() === '#') {
21939
21940                        len = input.length;
21941                        input = parseInt(input.substr(1), 16);
21942
21943                        // Handle long-form, e.g. #AABBCC
21944                        if (len === 7) {
21945
21946                            rgba = [
21947                                (input & 0xFF0000) >> 16,
21948                                (input & 0xFF00) >> 8,
21949                                (input & 0xFF),
21950                                1
21951                            ];
21952
21953                            // Handle short-form, e.g. #ABC
21954                            // In short form, the value is assumed to be the same 
21955                            // for both nibbles for each component. e.g. #ABC = #AABBCC
21956                        } else if (len === 4) {
21957
21958                            rgba = [
21959                                ((input & 0xF00) >> 4) | (input & 0xF00) >> 8,
21960                                ((input & 0xF0) >> 4) | (input & 0xF0),
21961                                ((input & 0xF) << 4) | (input & 0xF),
21962                                1
21963                            ];
21964                        }
21965                    }
21966
21967                    // Otherwise, check regex parsers
21968                    if (!rgba) {
21969                        i = this.parsers.length;
21970                        while (i-- && !rgba) {
21971                            parser = this.parsers[i];
21972                            result = parser.regex.exec(input);
21973                            if (result) {
21974                                rgba = parser.parse(result);
21975                            }
21976                        }
21977                    }
21978                }
21979                this.rgba = rgba || [];
21980            },
21981
21982            /**
21983             * Return the color a specified format
21984             * @param {String} format
21985             */
21986            get: function(format) {
21987                var input = this.input,
21988                    rgba = this.rgba,
21989                    ret;
21990
21991                if (this.stops) {
21992                    ret = merge(input);
21993                    ret.stops = [].concat(ret.stops);
21994                    each(this.stops, function(stop, i) {
21995                        ret.stops[i] = [ret.stops[i][0], stop.get(format)];
21996                    });
21997
21998                    // it's NaN if gradient colors on a column chart
21999                } else if (rgba && isNumber(rgba[0])) {
22000                    if (format === 'rgb' || (!format && rgba[3] === 1)) {
22001                        ret = 'rgb(' + rgba[0] + ',' + rgba[1] + ',' + rgba[2] + ')';
22002                    } else if (format === 'a') {
22003                        ret = rgba[3];
22004                    } else {
22005                        ret = 'rgba(' + rgba.join(',') + ')';
22006                    }
22007                } else {
22008                    ret = input;
22009                }
22010                return ret;
22011            },
22012
22013            /**
22014             * Brighten the color
22015             * @param {Number} alpha
22016             */
22017            brighten: function(alpha) {
22018                var i,
22019                    rgba = this.rgba;
22020
22021                if (this.stops) {
22022                    each(this.stops, function(stop) {
22023                        stop.brighten(alpha);
22024                    });
22025
22026                } else if (isNumber(alpha) && alpha !== 0) {
22027                    for (i = 0; i < 3; i++) {
22028                        rgba[i] += pInt(alpha * 255);
22029
22030                        if (rgba[i] < 0) {
22031                            rgba[i] = 0;
22032                        }
22033                        if (rgba[i] > 255) {
22034                            rgba[i] = 255;
22035                        }
22036                    }
22037                }
22038                return this;
22039            },
22040
22041            /**
22042             * Set the color's opacity to a given alpha value
22043             * @param {Number} alpha
22044             */
22045            setOpacity: function(alpha) {
22046                this.rgba[3] = alpha;
22047                return this;
22048            },
22049
22050            /*
22051             * Return an intermediate color between two colors.
22052             *
22053             * @param  {Highcharts.Color} to
22054             *         The color object to tween to.
22055             * @param  {Number} pos
22056             *         The intermediate position, where 0 is the from color (current
22057             *         color item), and 1 is the `to` color.
22058             *
22059             * @return {String}
22060             *         The intermediate color in rgba notation.
22061             */
22062            tweenTo: function(to, pos) {
22063                // Check for has alpha, because rgba colors perform worse due to lack of
22064                // support in WebKit.
22065                var fromRgba = this.rgba,
22066                    toRgba = to.rgba,
22067                    hasAlpha,
22068                    ret;
22069
22070                // Unsupported color, return to-color (#3920, #7034)
22071                if (!toRgba.length || !fromRgba || !fromRgba.length) {
22072                    ret = to.input || 'none';
22073
22074                    // Interpolate
22075                } else {
22076                    hasAlpha = (toRgba[3] !== 1 || fromRgba[3] !== 1);
22077                    ret = (hasAlpha ? 'rgba(' : 'rgb(') +
22078                        Math.round(toRgba[0] + (fromRgba[0] - toRgba[0]) * (1 - pos)) +
22079                        ',' +
22080                        Math.round(toRgba[1] + (fromRgba[1] - toRgba[1]) * (1 - pos)) +
22081                        ',' +
22082                        Math.round(toRgba[2] + (fromRgba[2] - toRgba[2]) * (1 - pos)) +
22083                        (
22084                            hasAlpha ?
22085                            (
22086                                ',' +
22087                                (toRgba[3] + (fromRgba[3] - toRgba[3]) * (1 - pos))
22088                            ) :
22089                            ''
22090                        ) +
22091                        ')';
22092                }
22093                return ret;
22094            }
22095        };
22096        H.color = function(input) {
22097            return new H.Color(input);
22098        };
22099
22100    }
22100(Highcharts));
22101    (function(H) {
22102        /**
22103         * (c) 2010-2017 Torstein Honsi
22104         *
22105         * License: www.highcharts.com/license
22106         */
22107        var SVGElement,
22108            SVGRenderer,
22109
22110            addEvent = H.addEvent,
22111            animate = H.animate,
22112            attr = H.attr,
22113            charts = H.charts,
22114            color = H.color,
22115            css = H.css,
22116            createElement = H.createElement,
22117            defined = H.defined,
22118            deg2rad = H.deg2rad,
22119            destroyObjectProperties = H.destroyObjectProperties,
22120            doc = H.doc,
22121            each = H.each,
22122            extend = H.extend,
22123            erase = H.erase,
22124            grep = H.grep,
22125            hasTouch = H.hasTouch,
22126            inArray = H.inArray,
22127            isArray = H.isArray,
22128            isFirefox = H.isFirefox,
22129            isMS = H.isMS,
22130            isObject = H.isObject,
22131            isString = H.isString,
22132            isWebKit = H.isWebKit,
22133            merge = H.merge,
22134            noop = H.noop,
22135            objectEach = H.objectEach,
22136            pick = H.pick,
22137            pInt = H.pInt,
22138            removeEvent = H.removeEvent,
22139            splat = H.splat,
22140            stop = H.stop,
22141            svg = H.svg,
22142            SVG_NS = H.SVG_NS,
22143            symbolSizes = H.symbolSizes,
22144            win = H.win;
22145
22146        /**
22147         * @typedef {Object} SVGDOMElement - An SVG DOM element.
22148         */
22149        /**
22150         * The SVGElement prototype is a JavaScript wrapper for SVG elements used in the
22151         * rendering layer of Highcharts. Combined with the {@link
22152         * Highcharts.SVGRenderer} object, these prototypes allow freeform annotation
22153         * in the charts or even in HTML pages without instanciating a chart. The
22154         * SVGElement can also wrap HTML labels, when `text` or `label` elements are
22155         * created with the `useHTML` parameter.
22156         *
22157         * The SVGElement instances are created through factory functions on the 
22158         * {@link Highcharts.SVGRenderer} object, like
22159         * [rect]{@link Highcharts.SVGRenderer#rect}, [path]{@link
22160         * Highcharts.SVGRenderer#path}, [text]{@link Highcharts.SVGRenderer#text},
22161         * [label]{@link Highcharts.SVGRenderer#label}, [g]{@link
22162         * Highcharts.SVGRenderer#g} and more.
22163         *
22164         * @class Highcharts.SVGElement
22165         */
22166        SVGElement = H.SVGElement = function() {
22167            return this;
22168        };
22169        extend(SVGElement.prototype, /** @lends Highcharts.SVGElement.prototype */ {
22170
22171            // Default base for animation
22172            opacity: 1,
22173            SVG_NS: SVG_NS,
22174
22175            /**
22176             * For labels, these CSS properties are applied to the `text` node directly.
22177             *
22178             * @private
22179             * @type {Array.<string>}
22180             */
22181            textProps: ['direction', 'fontSize', 'fontWeight', 'fontFamily',
22182                'fontStyle', 'color', 'lineHeight', 'width', 'textAlign',
22183                'textDecoration', 'textOverflow', 'textOutline'
22184            ],
22185
22186            /**
22187             * Initialize the SVG renderer. This function only exists to make the
22188             * initiation process overridable. It should not be called directly.
22189             *
22190             * @param  {SVGRenderer} renderer
22191             *         The SVGRenderer instance to initialize to.
22192             * @param  {String} nodeName
22193             *         The SVG node name.
22194             * 
22195             */
22196            init: function(renderer, nodeName) {
22197
22198                /** 
22199                 * The primary DOM node. Each `SVGElement` instance wraps a main DOM
22200                 * node, but may also represent more nodes.
22201                 *
22202                 * @name  element
22203                 * @memberOf SVGElement
22204                 * @type {SVGDOMNode|HTMLDOMNode}
22205                 */
22206                this.element = nodeName === 'span' ?
22207                    createElement(nodeName) :
22208                    doc.createElementNS(this.SVG_NS, nodeName);
22209
22210                /**
22211                 * The renderer that the SVGElement belongs to.
22212                 *
22213                 * @name renderer
22214                 * @memberOf SVGElement
22215                 * @type {SVGRenderer}
22216                 */
22217                this.renderer = renderer;
22218            },
22219
22220            /**
22221             * Animate to given attributes or CSS properties.
22222             * 
22223             * @param {SVGAttributes} params SVG attributes or CSS to animate.
22224             * @param {AnimationOptions} [options] Animation options.
22225             * @param {Function} [complete] Function to perform at the end of animation.
22226             *
22227             * @sample highcharts/members/element-on/
22228             *         Setting some attributes by animation
22229             * 
22230             * @returns {SVGElement} Returns the SVGElement for chaining.
22231             */
22232            animate: function(params, options, complete) {
22233                var animOptions = H.animObject(
22234                    pick(options, this.renderer.globalAnimation, true)
22235                );
22236                if (animOptions.duration !== 0) {
22237                    // allows using a callback with the global animation without
22238                    // overwriting it
22239                    if (complete) {
22240                        animOptions.complete = complete;
22241                    }
22242                    animate(this, params, animOptions);
22243                } else {
22244                    this.attr(params, null, complete);
22245                    if (animOptions.step) {
22246                        animOptions.step.call(this);
22247                    }
22248                }
22249                return this;
22250            },
22251
22252            /**
22253             * @typedef {Object} GradientOptions
22254             * @property {Object} linearGradient Holds an object that defines the start
22255             *    position and the end position relative to the shape.
22256             * @property {Number} linearGradient.x1 Start horizontal position of the
22257             *    gradient. Ranges 0-1.
22258             * @property {Number} linearGradient.x2 End horizontal position of the
22259             *    gradient. Ranges 0-1.
22260             * @property {Number} linearGradient.y1 Start vertical position of the
22261             *    gradient. Ranges 0-1.
22262             * @property {Number} linearGradient.y2 End vertical position of the
22263             *    gradient. Ranges 0-1.
22264             * @property {Object} radialGradient Holds an object that defines the center
22265             *    position and the radius.
22266             * @property {Number} radialGradient.cx Center horizontal position relative
22267             *    to the shape. Ranges 0-1.
22268             * @property {Number} radialGradient.cy Center vertical position relative
22269             *    to the shape. Ranges 0-1.
22270             * @property {Number} radialGradient.r Radius relative to the shape. Ranges
22271             *    0-1.
22272             * @property {Array.<Array>} stops The first item in each tuple is the
22273             *    position in the gradient, where 0 is the start of the gradient and 1
22274             *    is the end of the gradient. Multiple stops can be applied. The second
22275             *    item is the color for each stop. This color can also be given in the
22276             *    rgba format.
22277             *
22278             * @example
22279             * // Linear gradient used as a color option
22280             * color: {
22281             *     linearGradient: { x1: 0, x2: 0, y1: 0, y2: 1 },
22282             *         stops: [
22283             *             [0, '#003399'], // start
22284             *             [0.5, '#ffffff'], // middle
22285             *             [1, '#3366AA'] // end
22286             *         ]
22287             *     }
22288             * }
22289             */
22290            /**
22291             * Build and apply an SVG gradient out of a common JavaScript configuration
22292             * object. This function is called from the attribute setters.
22293             *
22294             * @private
22295             * @param {GradientOptions} color The gradient options structure.
22296             * @param {string} prop The property to apply, can either be `fill` or
22297             * `stroke`. 
22298             * @param {SVGDOMElement} elem SVG DOM element to apply the gradient on.
22299             */
22300            colorGradient: function(color, prop, elem) {
22301                var renderer = this.renderer,
22302                    colorObject,
22303                    gradName,
22304                    gradAttr,
22305                    radAttr,
22306                    gradients,
22307                    gradientObject,
22308                    stops,
22309                    stopColor,
22310                    stopOpacity,
22311                    radialReference,
22312                    id,
22313                    key = [],
22314                    value;
22315
22316                // Apply linear or radial gradients
22317                if (color.radialGradient) {
22318                    gradName = 'radialGradient';
22319                } else if (color.linearGradient) {
22320                    gradName = 'linearGradient';
22321                }
22322
22323                if (gradName) {
22324                    gradAttr = color[gradName];
22325                    gradients = renderer.gradients;
22326                    stops = color.stops;
22327                    radialReference = elem.radialReference;
22328
22329                    // Keep < 2.2 kompatibility
22330                    if (isArray(gradAttr)) {
22331                        color[gradName] = gradAttr = {
22332                            x1: gradAttr[0],
22333                            y1: gradAttr[1],
22334                            x2: gradAttr[2],
22335                            y2: gradAttr[3],
22336                            gradientUnits: 'userSpaceOnUse'
22337                        };
22338                    }
22339
22340                    // Correct the radial gradient for the radial reference system
22341                    if (
22342                        gradName === 'radialGradient' &&
22343                        radialReference &&
22344                        !defined(gradAttr.gradientUnits)
22345                    ) {
22346                        radAttr = gradAttr; // Save the radial attributes for updating
22347                        gradAttr = merge(
22348                            gradAttr,
22349                            renderer.getRadialAttr(radialReference, radAttr), {
22350                                gradientUnits: 'userSpaceOnUse'
22351                            }
22352                        );
22353                    }
22354
22355                    // Build the unique key to detect whether we need to create a new
22356                    // element (#1282)
22357                    objectEach(gradAttr, function(val, n) {
22358                        if (n !== 'id') {
22359                            key.push(n, val);
22360                        }
22361                    });
22362                    objectEach(stops, function(val) {
22363                        key.push(val);
22364                    });
22365                    key = key.join(',');
22366
22367                    // Check if a gradient object with the same config object is created
22368                    // within this renderer
22369                    if (gradients[key]) {
22370                        id = gradients[key].attr('id');
22371
22372                    } else {
22373
22374                        // Set the id and create the element
22375                        gradAttr.id = id = H.uniqueKey();
22376                        gradients[key] = gradientObject =
22377                            renderer.createElement(gradName)
22378                            .attr(gradAttr)
22379                            .add(renderer.defs);
22380
22381                        gradientObject.radAttr = radAttr;
22382
22383                        // The gradient needs to keep a list of stops to be able to
22384                        // destroy them
22385                        gradientObject.stops = [];
22386                        each(stops, function(stop) {
22387                            var stopObject;
22388                            if (stop[1].indexOf('rgba') === 0) {
22389                                colorObject = H.color(stop[1]);
22390                                stopColor = colorObject.get('rgb');
22391                                stopOpacity = colorObject.get('a');
22392                            } else {
22393                                stopColor = stop[1];
22394                                stopOpacity = 1;
22395                            }
22396                            stopObject = renderer.createElement('stop').attr({
22397                                offset: stop[0],
22398                                'stop-color': stopColor,
22399                                'stop-opacity': stopOpacity
22400                            }).add(gradientObject);
22401
22402                            // Add the stop element to the gradient
22403                            gradientObject.stops.push(stopObject);
22404                        });
22405                    }
22406
22407                    // Set the reference to the gradient object
22408                    value = 'url(' + renderer.url + '#' + id + ')';
22409                    elem.setAttribute(prop, value);
22410                    elem.gradient = key;
22411
22412                    // Allow the color to be concatenated into tooltips formatters etc.
22413                    // (#2995)
22414                    color.toString = function() {
22415                        return value;
22416                    };
22417                }
22418            },
22419
22420            /**
22421             * Apply a text outline through a custom CSS property, by copying the text
22422             * element and apply stroke to the copy. Used internally. Contrast checks
22423             * at http://jsfiddle.net/highcharts/43soe9m1/2/ .
22424             *
22425             * @private
22426             * @param {String} textOutline A custom CSS `text-outline` setting, defined
22427             *    by `width color`. 
22428             * @example
22429             * // Specific color
22430             * text.css({
22431             *    textOutline: '1px black'
22432             * });
22433             * // Automatic contrast
22434             * text.css({
22435             *    color: '#000000', // black text
22436             *    textOutline: '1px contrast' // => white outline
22437             * });
22438             */
22439            applyTextOutline: function(textOutline) {
22440                var elem = this.element,
22441                    tspans,
22442                    tspan,
22443                    hasContrast = textOutline.indexOf('contrast') !== -1,
22444                    styles = {},
22445                    color,
22446                    strokeWidth,
22447                    firstRealChild,
22448                    i;
22449
22450                // When the text shadow is set to contrast, use dark stroke for light
22451                // text and vice versa.
22452                if (hasContrast) {
22453                    styles.textOutline = textOutline = textOutline.replace(
22454                        /contrast/g,
22455                        this.renderer.getContrast(elem.style.fill)
22456                    );
22457                }
22458
22459                // Extract the stroke width and color
22460                textOutline = textOutline.split(' ');
22461                color = textOutline[textOutline.length - 1];
22462                strokeWidth = textOutline[0];
22463
22464                if (strokeWidth && strokeWidth !== 'none' && H.svg) {
22465
22466                    this.fakeTS = true; // Fake text shadow
22467
22468                    tspans = [].slice.call(elem.getElementsByTagName('tspan'));
22469
22470                    // In order to get the right y position of the clone,
22471                    // copy over the y setter
22472                    this.ySetter = this.xSetter;
22473
22474                    // Since the stroke is applied on center of the actual outline, we
22475                    // need to double it to get the correct stroke-width outside the 
22476                    // glyphs.
22477                    strokeWidth = strokeWidth.replace(
22478                        /(^[\d\.]+)(.*?)$/g,
22479                        function(match, digit, unit) {
22480                            return (2 * digit) + unit;
22481                        }
22482                    );
22483
22484                    // Remove shadows from previous runs. Iterate from the end to
22485                    // support removing items inside the cycle (#6472).
22486                    i = tspans.length;
22487                    while (i--) {
22488                        tspan = tspans[i];
22489                        if (tspan.getAttribute('class') === 'highcharts-text-outline') {
22490                            // Remove then erase
22491                            erase(tspans, elem.removeChild(tspan));
22492                        }
22493                    }
22494
22495                    // For each of the tspans, create a stroked copy behind it
22495.
22496                    firstRealChild = elem.firstChild;
22497                    each(tspans, function(tspan, y) {
22498                        var clone;
22499
22500                        // Let the first line start at the correct X position
22501                        if (y === 0) {
22502                            tspan.setAttribute('x', elem.getAttribute('x'));
22503                            y = elem.getAttribute('y');
22504                            tspan.setAttribute('y', y || 0);
22505                            if (y === null) {
22506                                elem.setAttribute('y', 0);
22507                            }
22508                        }
22509
22510                        // Create the clone and apply outline properties
22511                        clone = tspan.cloneNode(1);
22512                        attr(clone, {
22513                            'class': 'highcharts-text-outline',
22514                            'fill': color,
22515                            'stroke': color,
22516                            'stroke-width': strokeWidth,
22517                            'stroke-linejoin': 'round'
22518                        });
22519                        elem.insertBefore(clone, firstRealChild);
22520                    });
22521                }
22522            },
22523
22524            /**
22525             *
22526             * @typedef {Object} SVGAttributes An object of key-value pairs for SVG
22527             *   attributes. Attributes in Highcharts elements for the most parts
22528             *   correspond to SVG, but some are specific to Highcharts, like `zIndex`,
22529             *   `rotation`, `rotationOriginX`, `rotationOriginY`, `translateX`,
22530             *   `translateY`, `scaleX` and `scaleY`. SVG attributes containing a hyphen
22531             *   are _not_ camel-cased, they should be quoted to preserve the hyphen.
22532             *   
22533             * @example
22534             * {
22535             *     'stroke': '#ff0000', // basic
22536             *     'stroke-width': 2, // hyphenated
22537             *     'rotation': 45 // custom
22538             *     'd': ['M', 10, 10, 'L', 30, 30, 'z'] // path definition, note format
22539             * }
22540             */
22541            /**
22542             * Apply native and custom attributes to the SVG elements.
22543             * 
22544             * In order to set the rotation center for rotation, set x and y to 0 and
22545             * use `translateX` and `translateY` attributes to position the element
22546             * instead.
22547             *
22548             * Attributes frequently used in Highcharts are `fill`, `stroke`,
22549             * `stroke-width`.
22550             *
22551             * @param {SVGAttributes|String} hash - The native and custom SVG
22552             *    attributes. 
22553             * @param {string} [val] - If the type of the first argument is `string`, 
22554             *    the second can be a value, which will serve as a single attribute
22555             *    setter. If the first argument is a string and the second is undefined,
22556             *    the function serves as a getter and the current value of the property
22557             *    is returned.
22558             * @param {Function} [complete] - A callback function to execute after
22559             *    setting the attributes. This makes the function compliant and
22560             *    interchangeable with the {@link SVGElement#animate} function.
22561             * @param {boolean} [continueAnimation=true] Used internally when `.attr` is
22562             *    called as part of an animation step. Otherwise, calling `.attr` for an
22563             *    attribute will stop animation for that attribute.
22564             *    
22565             * @returns {SVGElement|string|number} If used as a setter, it returns the 
22566             *    current {@link SVGElement} so the calls can be chained. If used as a 
22567             *    getter, the current value of the attribute is returned.
22568             *
22569             * @sample highcharts/members/renderer-rect/
22570             *         Setting some attributes
22571             * 
22572             * @example
22573             * // Set multiple attributes
22574             * element.attr({
22575             *     stroke: 'red',
22576             *     fill: 'blue',
22577             *     x: 10,
22578             *     y: 10
22579             * });
22580             *
22581             * // Set a single attribute
22582             * element.attr('stroke', 'red');
22583             *
22584             * // Get an attribute
22585             * element.attr('stroke'); // => 'red'
22586             * 
22587             */
22588            attr: function(hash, val, complete, continueAnimation) {
22589                var key,
22590                    element = this.element,
22591                    hasSetSymbolSize,
22592                    ret = this,
22593                    skipAttr,
22594                    setter;
22595
22596                // single key-value pair
22597                if (typeof hash === 'string' && val !== undefined) {
22598                    key = hash;
22599                    hash = {};
22600                    hash[key] = val;
22601                }
22602
22603                // used as a getter: first argument is a string, second is undefined
22604                if (typeof hash === 'string') {
22605                    ret = (this[hash + 'Getter'] || this._defaultGetter).call(
22606                        this,
22607                        hash,
22608                        element
22609                    );
22610
22611                    // setter
22612                } else {
22613
22614                    objectEach(hash, function eachAttribute(val, key) {
22615                        skipAttr = false;
22616
22617                        // Unless .attr is from the animator update, stop current
22618                        // running animation of this property
22619                        if (!continueAnimation) {
22620                            stop(this, key);
22621                        }
22622
22623                        // Special handling of symbol attributes
22624                        if (
22625                            this.symbolName &&
22626                            /^(x|y|width|height|r|start|end|innerR|anchorX|anchorY)$/
22627                            .test(key)
22628                        ) {
22629                            if (!hasSetSymbolSize) {
22630                                this.symbolAttr(hash);
22631                                hasSetSymbolSize = true;
22632                            }
22633                            skipAttr = true;
22634                        }
22635
22636                        if (this.rotation && (key === 'x' || key === 'y')) {
22637                            this.doTransform = true;
22638                        }
22639
22640                        if (!skipAttr) {
22641                            setter = this[key + 'Setter'] || this._defaultSetter;
22642                            setter.call(this, val, key, element);
22643
22644
22645                            // Let the shadow follow the main element
22646                            if (
22647                                this.shadows &&
22648                                /^(width|height|visibility|x|y|d|transform|cx|cy|r)$/
22649                                .test(key)
22650                            ) {
22651                                this.updateShadows(key, val, setter);
22652                            }
22653
22654                        }
22655                    }, this);
22656
22657                    this.afterSetters();
22658                }
22659
22660                // In accordance with animate, run a complete callback
22661                if (complete) {
22662                    complete();
22663                }
22664
22665                return ret;
22666            },
22667
22668            /**
22669             * This method is executed in the end of `attr()`, after setting all
22670             * attributes in the hash. In can be used to efficiently consolidate
22671             * multiple attributes in one SVG property -- e.g., translate, rotate and
22672             * scale are merged in one "transform" attribute in the SVG node.
22673             *
22674             * @private
22675             */
22676            afterSetters: function() {
22677                // Update transform. Do this outside the loop to prevent redundant
22678                // updating for batch setting of attributes.
22679                if (this.doTransform) {
22680                    this.updateTransform();
22681                    this.doTransform = false;
22682                }
22683            },
22684
22685
22686            /**
22687             * Update the shadow elements with new attributes.
22688             *
22689             * @private
22690             * @param {String} key - The attribute name.
22691             * @param {String|Number} value - The value of the attribute.
22692             * @param {Function} setter - The setter function, inherited from the
22693             *   parent wrapper
22694             * 
22695             */
22696            updateShadows: function(key, value, setter) {
22697                var shadows = this.shadows,
22698                    i = shadows.length;
22699
22700                while (i--) {
22701                    setter.call(
22702                        shadows[i],
22703                        key === 'height' ?
22704                        Math.max(value - (shadows[i].cutHeight || 0), 0) :
22705                        key === 'd' ? this.d : value,
22706                        key,
22707                        shadows[i]
22708                    );
22709                }
22710            },
22711
22712
22713            /**
22714             * Add a class name to an element.
22715             *
22716             * @param {string}
22716 className - The new class name to add.
22717             * @param {boolean} [replace=false] - When true, the existing class name(s)
22718             *    will be overwritten with the new one. When false, the new one is
22719             *    added.
22720             * @returns {SVGElement} Return the SVG element for chainability.
22721             */
22722            addClass: function(className, replace) {
22723                var currentClassName = this.attr('class') || '';
22724                if (currentClassName.indexOf(className) === -1) {
22725                    if (!replace) {
22726                        className =
22727                            (currentClassName + (currentClassName ? ' ' : '') +
22728                                className).replace('  ', ' ');
22729                    }
22730                    this.attr('class', className);
22731                }
22732
22733                return this;
22734            },
22735
22736            /**
22737             * Check if an element has the given class name.
22738             * @param  {string} className
22739             *         The class name to check for.
22740             * @return {Boolean}
22741             *         Whether the class name is found.
22742             */
22743            hasClass: function(className) {
22744                return inArray(
22745                    className,
22746                    (this.attr('class') || '').split(' ')
22747                ) !== -1;
22748            },
22749
22750            /**
22751             * Remove a class name from the element.
22752             * @param  {String|RegExp} className The class name to remove.
22753             * @return {SVGElement} Returns the SVG element for chainability.
22754             */
22755            removeClass: function(className) {
22756                return this.attr(
22757                    'class',
22758                    (this.attr('class') || '').replace(className, '')
22759                );
22760            },
22761
22762            /**
22763             * If one of the symbol size affecting parameters are changed,
22764             * check all the others only once for each call to an element's
22765             * .attr() method
22766             * @param {Object} hash - The attributes to set.
22767             * @private
22768             */
22769            symbolAttr: function(hash) {
22770                var wrapper = this;
22771
22772                each([
22773                    'x',
22774                    'y',
22775                    'r',
22776                    'start',
22777                    'end',
22778                    'width',
22779                    'height',
22780                    'innerR',
22781                    'anchorX',
22782                    'anchorY'
22783                ], function(key) {
22784                    wrapper[key] = pick(hash[key], wrapper[key]);
22785                });
22786
22787                wrapper.attr({
22788                    d: wrapper.renderer.symbols[wrapper.symbolName](
22789                        wrapper.x,
22790                        wrapper.y,
22791                        wrapper.width,
22792                        wrapper.height,
22793                        wrapper
22794                    )
22795                });
22796            },
22797
22798            /**
22799             * Apply a clipping rectangle to this element.
22800             * 
22801             * @param {ClipRect} [clipRect] - The clipping rectangle. If skipped, the
22802             *    current clip is removed.
22803             * @returns {SVGElement} Returns the SVG element to allow chaining.
22804             */
22805            clip: function(clipRect) {
22806                return this.attr(
22807                    'clip-path',
22808                    clipRect ?
22809                    'url(' + this.renderer.url + '#' + clipRect.id + ')' :
22810                    'none'
22811                );
22812            },
22813
22814            /**
22815             * Calculate the coordinates needed for drawing a rectangle crisply and
22816             * return the calculated attributes.
22817             * 
22818             * @param {Object} rect - A rectangle.
22819             * @param {number} rect.x - The x position.
22820             * @param {number} rect.y - The y position.
22821             * @param {number} rect.width - The width.
22822             * @param {number} rect.height - The height.
22823             * @param {number} [strokeWidth] - The stroke width to consider when
22824             *    computing crisp positioning. It can also be set directly on the rect
22825             *    parameter.
22826             *
22827             * @returns {{x: Number, y: Number, width: Number, height: Number}} The
22828             *    modified rectangle arguments.
22829             */
22830            crisp: function(rect, strokeWidth) {
22831
22832                var wrapper = this,
22833                    attribs = {},
22834                    normalizer;
22835
22836                strokeWidth = strokeWidth || rect.strokeWidth || 0;
22837                // Math.round because strokeWidth can sometimes have roundoff errors
22838                normalizer = Math.round(strokeWidth) % 2 / 2;
22839
22840                // normalize for crisp edges
22841                rect.x = Math.floor(rect.x || wrapper.x || 0) + normalizer;
22842                rect.y = Math.floor(rect.y || wrapper.y || 0) + normalizer;
22843                rect.width = Math.floor(
22844                    (rect.width || wrapper.width || 0) - 2 * normalizer
22845                );
22846                rect.height = Math.floor(
22847                    (rect.height || wrapper.height || 0) - 2 * normalizer
22848                );
22849                if (defined(rect.strokeWidth)) {
22850                    rect.strokeWidth = strokeWidth;
22851                }
22852
22853                objectEach(rect, function(val, key) {
22854                    if (wrapper[key] !== val) { // only set attribute if changed
22855                        wrapper[key] = attribs[key] = val;
22856                    }
22857                });
22858
22859                return attribs;
22860            },
22861
22862            /**
22863             * Set styles for the element. In addition to CSS styles supported by 
22864             * native SVG and HTML elements, there are also some custom made for 
22865             * Highcharts, like `width`, `ellipsis` and `textOverflow` for SVG text
22866             * elements.
22867             * @param {CSSObject} styles The new CSS styles.
22868             * @returns {SVGElement} Return the SVG element for chaining.
22869             *
22870             * @sample highcharts/members/renderer-text-on-chart/
22871             *         Styled text
22872             */
22873            css: function(styles) {
22874                var oldStyles = this.styles,
22875                    newStyles = {},
22876                    elem = this.element,
22877                    textWidth,
22878                    serializedCss = '',
22879                    hyphenate,
22880                    hasNew = !oldStyles,
22881                    // These CSS properties are interpreted internally by the SVG
22882                    // renderer, but are not supported by SVG and should not be added to
22883                    // the DOM. In styled mode, no CSS should find its way to the DOM
22884                    // whatsoever (#6173, #6474).
22885                    svgPseudoProps = ['textOutline', 'textOverflow', 'width'];
22886
22887                // convert legacy
22888                if (styles && styles.color) {
22889                    styles.fill = styles.color;
22890                }
22891
22892                // Filter out existing styles to increase performance (#2640)
22893                if (oldStyles) {
22894                    objectEach(styles, function(style, n) {
22895                        if (style !== oldStyles[n]) {
22896                            newStyles[n] = style;
22897                            hasNew = true;
22898                        }
22899                    });
22900                }
22901                if (hasNew) {
22902
22903                    // Merge the new styles with the old ones
22904                    if (oldStyles) {
22905                        styles = extend(
22906                            oldStyles,
22907                            newStyles
22908                        );
22909                    }
22910
22911                    // Get the text width from style
22912                    textWidth = this.textWidth = (
22913                        styles &&
22914                        styles.width &&
22915                        styles.width !== 'auto' &&
22916                        elem.nodeName.toLowerCase() === 'text' &&
22917                        pInt(styles.width)
22918                    );
22919
22920                    // store object
22921                    this.styles = styles;
22922
22923                    if (textWidth && (!svg && this.renderer.forExport)) {
22924                        delete styles.width;
22925                    }
22926
22927                    // serialize and set style attribute
22928                    if (isMS && !svg) {
22929                        css(this.element, styles);
22930                    } else {
22931                        hyphenate = function(a, b) {
22932                            return '-' + b.toLowerCase();
22933                        };
22934                        objectEach(styles, function(style, n) {
22935                            if (inArray(n, svgPseudoProps) === -1) {
22936                                serializedCss +=
22937                                    n.replace(/([A-Z])/g, hyphenate) + ':' +
22938                                    style + ';';
22939                            }
22940                        });
22941                        if (serializedCss) {
22942                            attr(elem, 'style', serializedCss); // #1881
22943                        }
22944                    }
22945
22946
22947                    if (this.added) {
22948
22949                        // Rebuild text after added. Cache mechanisms in the buildText
22950                        // will prevent building if there are no significant changes.
22951                        if (this.element.nodeName === 'text') {
22952                            this.renderer.buildText(this);
22953                        }
22954
22955                        // Apply text outline after added
22956                        if (styles && styles.textOutline) {
22957                            this.applyTextOutline(styles.textOutline);
22958                        }
22959                    }
22960                }
22961
22962                return this;
22963            },
22964
22965
22966            /**
22967             * Get the current stroke width. In classic mode, the setter registers it 
22968             * directly on the element.
22969             * @returns {number} The stroke width in pixels.
22970             * @ignore
22971             */
22972            strokeWidth: function() {
22973                return this['stroke-width'] || 0;
22974            },
22975
22976
22977            /**
22978             * Add an event listener. This is a simple setter that replaces all other
22979             * events of the same type, opposed to the {@link Highcharts#addEvent}
22980             * function.
22981             * @param {string} eventType - The event type. If the type is `click`, 
22982             *    Highcharts will internally translate it to a `touchstart` event on 
22983             *    touch devices, to prevent the browser from waiting for a click event
22984             *    from firing.
22985             * @param {Function} handler - The handler callback.
22986             * @returns {SVGElement} The SVGElement for chaining.
22987             *
22988             * @sample highcharts/members/element-on/
22989             *         A clickable rectangle
22990             */
22991            on: function(eventType, handler) {
22992                var svgElement = this,
22993                    element = svgElement.element;
22994
22995                // touch
22996                if (hasTouch && eventType === 'click') {
22997                    element.ontouchstart = function(e) {
22998                        svgElement.touchEventFired = Date.now(); // #2269
22999                        e.preventDefault();
23000                        handler.call(element, e);
23001                    };
23002                    element.onclick = function(e) {
23003                        if (win.navigator.userAgent.indexOf('Android') === -1 ||
23004                            Date.now() - (svgElement.touchEventFired || 0) > 1100) {
23005                            handler.call(element, e);
23006                        }
23007                    };
23008                } else {
23009                    // simplest possible event model for internal use
23010                    element['on' + eventType] = handler;
23011                }
23012                return this;
23013            },
23014
23015            /**
23016             * Set the coordinates needed to draw a consistent radial gradient across
23017             * a shape regardless of positioning inside the chart. Used on pie slices
23018             * to make all the slices have the same radial reference point.
23019             *
23020             * @param {Array} coordinates The center reference. The format is
23021             *    `[centerX, centerY, diameter]` in pixels.
23022             * @returns {SVGElement} Returns the SVGElement for chaining.
23023             */
23024            setRadialReference: function(coordinates) {
23025                var existingGradient = this.renderer.gradients[this.element.gradient];
23026
23027                this.element.radialReference = coordinates;
23028
23029                // On redrawing objects with an existing gradient, the gradient needs
23030                // to be repositioned (#3801)
23031                if (existingGradient && existingGradient.radAttr) {
23032                    existingGradient.animate(
23033                        this.renderer.getRadialAttr(
23034                            coordinates,
23035                            existingGradient.radAttr
23036                        )
23037                    );
23038                }
23039
23040                return this;
23041            },
23042
23043            /**
23044             * Move an object and its children by x and y values.
23045             * 
23046             * @param {number} x - The x value.
23047             * @param {number} y - The y value.
23048             */
23049            translate: function(x, y) {
23050                return this.attr({
23051                    translateX: x,
23052                    translateY: y
23053                });
23054            },
23055
23056            /**
23057             * Invert a group, rotate and flip. This is used internally on inverted 
23058             * charts, where the points and graphs are drawn as if not inverted, then
23059             * the series group elements are inverted.
23060             *
23061             * @param  {boolean} inverted
23062             *         Whether to invert or not. An inverted shape can be un-inverted by
23063             *         setting it to false.
23064             * @return {SVGElement}
23065             *         Return the SVGElement for chaining.
23066             */
23067            invert: function(inverted) {
23068                var wrapper = this;
23069                wrapper.inverted = inverted;
23070                wrapper.updateTransform();
23071                return wrapper;
23072            },
23073
23074            /**
23075             * Update the transform attribute based on internal properties. Deals with
23076             * the custom `translateX`, `translateY`, `rotation`, `scaleX` and `scaleY`
23077             * attributes and updates the SVG `transform` attribute.
23078             * @private
23079             * 
23080             */
23081            updateTransform: function() {
23082                var wrapper = this,
23083                    translateX = wrapper.translateX || 0,
23084                    translateY = wrapper.translateY || 0,
23085                    scaleX = wrapper.scaleX,
23086                    scaleY = wrapper.scaleY,
23087                    inverted = wrapper.inverted,
23088                    rotation = wrapper.rotation,
23089                    matrix = wrapper.matrix,
23090                    element = wrapper.element,
23091                    transform;
23092
23093                // Flipping affects translate as adjustment for flipping around the
23094                // group's axis
23095                if (inverted) {
23096                    translateX += wrapper.width;
23097                    translateY += wrapper.height;
23098                }
23099
23100                // Apply translate. Nearly all transformed elements have translation,
23101                // so instead of checking for translate = 0, do it always (#1767,
23102                // #1846).
23103                transform = ['translate(' + translateX + ',' + translateY + ')'];
23104
23105                // apply matrix
23106                if (defined(matrix)) {
23107                    transform.push(
23108                        'matrix(' + matrix.join(',') + ')'
23109                    );
23110                }
23111
23112                // apply rotation
23113                if (inverted) {
23114                    transform.push('rotate(90) scale(-1,1)');
23115                } else if (rotation) { // text rotation
23116                    transform.push(
23117                        'rotate(' + rotation + ' ' +
23118                        pick(this.rotationOriginX, element.getAttribute('x'), 0) +
23119                        ' ' +
23120                        pick(this.rotationOriginY, element.getAttribute('y') || 0) + ')'
23121                    );
23122                }
23123
23124                // apply scale
23125                if (defined(scaleX) || defined(scaleY)) {
23126                    transform.push(
23127                        'scale(' + pick(scaleX, 1) + ' ' + pick(scaleY, 1) + ')'
23128                    );
23129                }
23130
23131                if (transform.length) {
23132                    element.setAttribute('transform', transform.join(' '));
23133                }
23134            },
23135
23136            /**
23137             * Bring the element to the front. Alternatively, a new zIndex can be set.
23138             *
23139             * @returns {SVGElement} Returns the SVGElement for chaining.
23140             *
23141             * @sample highcharts/members/element-tofront/
23142             *         Click an element to bring it to front
23143             */
23144            toFront: function() {
23145                var element = this.element;
23146                element.parentNode.appendChild(element);
23147                return this;
23148            },
23149
23150
23151            /**
23152             * Align the element relative to the chart or another box.
23153             * 
23154             * @param {Object} [alignOptions] The alignment options. The function can be
23155             *   called without this parameter in order to re-align an element after the
23156             *   box has been updated.
23157             * @param {string} [alignOptions.align=left] Horizontal alignment. Can be
23158             *   one of `left`, `center` and `right`.
23159             * @param {string} [alignOptions.verticalAlign=top] Vertical alignment. Can
23160             *   be one of `top`, `middle` and `bottom`.
23161             * @param {number} [alignOptions.x=0] Horizontal pixel offset from
23162             *   alignment.
23163             * @param {number} [alignOptions.y=0] Vertical pixel offset from alignment.
23164             * @param {Boolean} [alignByTranslate=false] Use the `transform` attribute
23165             *   with translateX and translateY custom attributes to align this elements
23166             *   rather than `x` and `y` attributes.
23167             * @param {String|Object} box The box to align to, needs a width and height.
23168             *   When the box is a string, it refers to an object in the Renderer. For
23169             *   example, when box is `spacingBox`, it refers to `Renderer.spacingBox`
23170             *   which holds `width`, `height`, `x` and `y` properties.
23171             * @returns {SVGElement} Returns the SVGElement for chaining.
23172             */
23173            align: function(alignOptions, alignByTranslate, box) {
23174                var align,
23175                    vAlign,
23176                    x,
23177                    y,
23178                    attribs = {},
23179                    alignTo,
23180                    renderer = this.renderer,
23181                    alignedObjects = renderer.alignedObjects,
23182                    alignFactor,
23183                    vAlignFactor;
23184
23185                // First call on instanciate
23186                if (alignOptions) {
23187                    this.alignOptions = alignOptions;
23188                    this.alignByTranslate = alignByTranslate;
23189                    if (!box || isString(box)) {
23190                        this.alignTo = alignTo = box || 'renderer';
23191                        // prevent duplicates, like legendGroup after resize
23192                        erase(alignedObjects, this);
23193                        alignedObjects.push(this);
23194                        box = null; // reassign it below
23195                    }
23196
23197                    // When called on resize, no arguments are supplied
23198                } else {
23199                    alignOptions = this.alignOptions;
23200                    alignByTranslate = this.alignByTranslate;
23201                    alignTo = this.alignTo;
23202                }
23203
23204                box = pick(box, renderer[alignTo], renderer);
23205
23206                // Assign variables
23207                align = alignOptions.align;
23208                vAlign = alignOptions.verticalAlign;
23209                x = (box.x || 0) + (alignOptions.x || 0); // default: left align
23210                y = (box.y || 0) + (alignOptions.y || 0); // default: top align
23211
23212                // Align
23213                if (align === 'right') {
23214                    alignFactor = 1;
23215                } else if (align === 'center') {
23216                    alignFactor = 2;
23217                }
23218                if (alignFactor) {
23219                    x += (box.width - (alignOptions.width || 0)) / alignFactor;
23220                }
23221             
23221   attribs[alignByTranslate ? 'translateX' : 'x'] = Math.round(x);
23222
23223
23224                // Vertical align
23225                if (vAlign === 'bottom') {
23226                    vAlignFactor = 1;
23227                } else if (vAlign === 'middle') {
23228                    vAlignFactor = 2;
23229                }
23230                if (vAlignFactor) {
23231                    y += (box.height - (alignOptions.height || 0)) / vAlignFactor;
23232                }
23233                attribs[alignByTranslate ? 'translateY' : 'y'] = Math.round(y);
23234
23235                // Animate only if already placed
23236                this[this.placed ? 'animate' : 'attr'](attribs);
23237                this.placed = true;
23238                this.alignAttr = attribs;
23239
23240                return this;
23241            },
23242
23243            /**
23244             * Get the bounding box (width, height, x and y) for the element. Generally
23245             * used to get rendered text size. Since this is called a lot in charts,
23246             * the results are cached based on text properties, in order to save DOM
23247             * traffic. The returned bounding box includes the rotation, so for example
23248             * a single text line of rotation 90 will report a greater height, and a
23249             * width corresponding to the line-height.
23250             *
23251             * @param {boolean} [reload] Skip the cache and get the updated DOM bouding
23252             *   box.
23253             * @param {number} [rot] Override the element's rotation. This is internally
23254             *   used on axis labels with a value of 0 to find out what the bounding box
23255             *   would be have been if it were not rotated.
23256             * @returns {Object} The bounding box with `x`, `y`, `width` and `height`
23257             * properties.
23258             *
23259             * @sample highcharts/members/renderer-on-chart/
23260             *         Draw a rectangle based on a text's bounding box
23261             */
23262            getBBox: function(reload, rot) {
23263                var wrapper = this,
23264                    bBox, // = wrapper.bBox,
23265                    renderer = wrapper.renderer,
23266                    width,
23267                    height,
23268                    rotation,
23269                    rad,
23270                    element = wrapper.element,
23271                    styles = wrapper.styles,
23272                    fontSize,
23273                    textStr = wrapper.textStr,
23274                    toggleTextShadowShim,
23275                    cache = renderer.cache,
23276                    cacheKeys = renderer.cacheKeys,
23277                    cacheKey;
23278
23279                rotation = pick(rot, wrapper.rotation);
23280                rad = rotation * deg2rad;
23281
23282
23283                fontSize = styles && styles.fontSize;
23284
23285
23286                // Avoid undefined and null (#7316)
23287                if (defined(textStr)) {
23288
23289                    cacheKey = textStr.toString();
23290
23291                    // Since numbers are monospaced, and numerical labels appear a lot
23292                    // in a chart, we assume that a label of n characters has the same
23293                    // bounding box as others of the same length. Unless there is inner
23294                    // HTML in the label. In that case, leave the numbers as is (#5899).
23295                    if (cacheKey.indexOf('<') === -1) {
23296                        cacheKey = cacheKey.replace(/[0-9]/g, '0');
23297                    }
23298
23299                    // Properties that affect bounding box
23300                    cacheKey += [
23301                            '',
23302                            rotation || 0,
23303                            fontSize,
23304                            styles && styles.width,
23305                            styles && styles.textOverflow // #5968
23306                        ]
23307                        .join(',');
23308
23309                }
23310
23311                if (cacheKey && !reload) {
23312                    bBox = cache[cacheKey];
23313                }
23314
23315                // No cache found
23316                if (!bBox) {
23317
23318                    // SVG elements
23319                    if (element.namespaceURI === wrapper.SVG_NS || renderer.forExport) {
23320                        try { // Fails in Firefox if the container has display: none.
23321
23322                            // When the text shadow shim is used, we need to hide the
23323                            // fake shadows to get the correct bounding box (#3872)
23324                            toggleTextShadowShim = this.fakeTS && function(display) {
23325                                each(
23326                                    element.querySelectorAll(
23327                                        '.highcharts-text-outline'
23328                                    ),
23329                                    function(tspan) {
23330                                        tspan.style.display = display;
23331                                    }
23332                                );
23333                            };
23334
23335                            // Workaround for #3842, Firefox reporting wrong bounding
23336                            // box for shadows
23337                            if (toggleTextShadowShim) {
23338                                toggleTextShadowShim('none');
23339                            }
23340
23341                            bBox = element.getBBox ?
23342                                // SVG: use extend because IE9 is not allowed to change
23343                                // width and height in case of rotation (below)
23344                                extend({}, element.getBBox()) : {
23345
23346                                    // Legacy IE in export mode
23347                                    width: element.offsetWidth,
23348                                    height: element.offsetHeight
23349                                };
23350
23351                            // #3842
23352                            if (toggleTextShadowShim) {
23353                                toggleTextShadowShim('');
23354                            }
23355                        } catch (e) {}
23356
23357                        // If the bBox is not set, the try-catch block above failed. The
23358                        // other condition is for Opera that returns a width of
23359                        // -Infinity on hidden elements.
23360                        if (!bBox || bBox.width < 0) {
23361                            bBox = {
23362                                width: 0,
23363                                height: 0
23364                            };
23365                        }
23366
23367
23368                        // VML Renderer or useHTML within SVG
23369                    } else {
23370
23371                        bBox = wrapper.htmlGetBBox();
23372
23373                    }
23374
23375                    // True SVG elements as well as HTML elements in modern browsers
23376                    // using the .useHTML option need to compensated for rotation
23377                    if (renderer.isSVG) {
23378                        width = bBox.width;
23379                        height = bBox.height;
23380
23381                        // Workaround for wrong bounding box in IE, Edge and Chrome on
23382                        // Windows. With Highcharts' default font, IE and Edge report
23383                        // a box height of 16.899 and Chrome rounds it to 17. If this 
23384                        // stands uncorrected, it results in more padding added below
23385                        // the text than above when adding a label border or background.
23386                        // Also vertical positioning is affected.
23387                        // http://jsfiddle.net/highcharts/em37nvuj/
23388                        // (#1101, #1505, #1669, #2568, #6213).
23389                        if (
23390                            styles &&
23391                            styles.fontSize === '11px' &&
23392                            Math.round(height) === 17
23393                        ) {
23394                            bBox.height = height = 14;
23395                        }
23396
23397                        // Adjust for rotated text
23398                        if (rotation) {
23399                            bBox.width = Math.abs(height * Math.sin(rad)) +
23400                                Math.abs(width * Math.cos(rad));
23401                            bBox.height = Math.abs(height * Math.cos(rad)) +
23402                                Math.abs(width * Math.sin(rad));
23403                        }
23404                    }
23405
23406                    // Cache it. When loading a chart in a hidden iframe in Firefox and
23407                    // IE/Edge, the bounding box height is 0, so don't cache it (#5620).
23408                    if (cacheKey && bBox.height > 0) {
23409
23410                        // Rotate (#4681)
23411                        while (cacheKeys.length > 250) {
23412                            delete cache[cacheKeys.shift()];
23413                        }
23414
23415                        if (!cache[cacheKey]) {
23416                            cacheKeys.push(cacheKey);
23417                        }
23418                        cache[cacheKey] = bBox;
23419                    }
23420                }
23421                return bBox;
23422            },
23423
23424            /**
23425             * Show the element after it has been hidden. 
23426             *
23427             * @param {boolean} [inherit=false] Set the visibility attribute to
23428             * `inherit` rather than `visible`. The difference is that an element with
23429             * `visibility="visible"` will be visible even if the parent is hidden.
23430             *
23431             * @returns {SVGElement} Returns the SVGElement for chaining.
23432             */
23433            show: function(inherit) {
23434                return this.attr({
23435                    visibility: inherit ? 'inherit' : 'visible'
23436                });
23437            },
23438
23439            /**
23440             * Hide the element, equivalent to setting the `visibility` attribute to
23441             * `hidden`.
23442             *
23443             * @returns {SVGElement} Returns the SVGElement for chaining.
23444             */
23445            hide: function() {
23446                return this.attr({
23447                    visibility: 'hidden'
23448                });
23449            },
23450
23451            /**
23452             * Fade out an element by animating its opacity down to 0, and hide it on
23453             * complete. Used internally for the tooltip.
23454             * 
23455             * @param {number} [duration=150] The fade duration in milliseconds.
23456             */
23457            fadeOut: function(duration) {
23458                var elemWrapper = this;
23459                elemWrapper.animate({
23460                    opacity: 0
23461                }, {
23462                    duration: duration || 150,
23463                    complete: function() {
23464                        // #3088, assuming we're only using this for tooltips
23465                        elemWrapper.attr({
23466                            y: -9999
23467                        });
23468                    }
23469                });
23470            },
23471
23472            /**
23473             * Add the element to the DOM. All elements must be added this way.
23474             * 
23475             * @param {SVGElement|SVGDOMElement} [parent] The parent item to add it to.
23476             *   If undefined, the element is added to the {@link
23477             *   Highcharts.SVGRenderer.box}.
23478             *
23479             * @returns {SVGElement} Returns the SVGElement for chaining.
23480             *
23481             * @sample highcharts/members/renderer-g - Elements added to a group
23482             */
23483            add: function(parent) {
23484
23485                var renderer = this.renderer,
23486                    element = this.element,
23487                    inserted;
23488
23489                if (parent) {
23490                    this.parentGroup = parent;
23491                }
23492
23493                // mark as inverted
23494                this.parentInverted = parent && parent.inverted;
23495
23496                // build formatted text
23497                if (this.textStr !== undefined) {
23498                    renderer.buildText(this);
23499                }
23500
23501                // Mark as added
23502                this.added = true;
23503
23504                // If we're adding to renderer root, or other elements in the group
23505                // have a z index, we need to handle it
23506                if (!parent || parent.handleZ || this.zIndex) {
23507                    inserted = this.zIndexSetter();
23508                }
23509
23510                // If zIndex is not handled, append at the end
23511                if (!inserted) {
23512                    (parent ? parent.element : renderer.box).appendChild(element);
23513                }
23514
23515                // fire an event for internal hooks
23516                if (this.onAdd) {
23517                    this.onAdd();
23518                }
23519
23520                return this;
23521            },
23522
23523            /**
23524             * Removes an element from the DOM.
23525             *
23526             * @private
23527             * @param {SVGDOMElement|HTMLDOMElement} element The DOM node to remove.
23528             */
23529            safeRemoveChild: function(element) {
23530                var parentNode = element.parentNode;
23531                if (parentNode) {
23532                    parentNode.removeChild(element);
23533                }
23534            },
23535
23536            /**
23537             * Destroy the element and element wrapper and clear up the DOM and event
23538             * hooks.
23539             *
23540             * 
23541             */
23542            destroy: function() {
23543                var wrapper = this,
23544                    element = wrapper.element || {},
23545                    parentToClean =
23546                    wrapper.renderer.isSVG &&
23547                    element.nodeName === 'SPAN' &&
23548                    wrapper.parentGroup,
23549                    grandParent,
23550                    ownerSVGElement = element.ownerSVGElement,
23551                    i;
23552
23553                // remove events
23554                element.onclick = element.onmouseout = element.onmouseover =
23555                    element.onmousemove = element.point = null;
23556                stop(wrapper); // stop running animations
23557
23558                if (wrapper.clipPath && ownerSVGElement) {
23559                    // Look for existing references to this clipPath and remove them
23560                    // before destroying the element (#6196).
23561                    each(
23562                        // The upper case version is for Edge
23563                        ownerSVGElement.querySelectorAll('[clip-path],[CLIP-PATH]'),
23564                        function(el) {
23565                            // Include the closing paranthesis in the test to rule out
23566                            // id's from 10 and above (#6550)
23567                            if (el
23568                                .getAttribute('clip-path')
23569                                .match(RegExp(
23570                                    // Edge puts quotes inside the url, others not
23571                                    '[\("]#' + wrapper.clipPath.element.id + '[\)"]'
23572                                ))
23573                            ) {
23574                                el.removeAttribute('clip-path');
23575                            }
23576                        }
23577                    );
23578                    wrapper.clipPath = wrapper.clipPath.destroy();
23579                }
23580
23581                // Destroy stops in case this is a gradient object
23582                if (wrapper.stops) {
23583                    for (i = 0; i < wrapper.stops.length; i++) {
23584                        wrapper.stops[i] = wrapper.stops[i].destroy();
23585                    }
23586                    wrapper.stops = null;
23587                }
23588
23589                // remove element
23590                wrapper.safeRemoveChild(element);
23591
23592
23593                wrapper.destroyShadows();
23594
23595
23596                // In case of useHTML, clean up empty containers emulating SVG groups
23597                // (#1960, #2393, #2697).
23598                while (
23599                    parentToClean &&
23600                    parentToClean.div &&
23601                    parentToClean.div.childNodes.length === 0
23602                ) {
23603                    grandParent = parentToClean.parentGroup;
23604                    wrapper.safeRemoveChild(parentToClean.div);
23605                    delete parentToClean.div;
23606                    parentToClean = grandParent;
23607                }
23608
23609                // remove from alignObjects
23610                if (wrapper.alignTo) {
23611                    erase(wrapper.renderer.alignedObjects, wrapper);
23612                }
23613
23614                objectEach(wrapper, function(val, key) {
23615                    delete wrapper[key];
23616                });
23617
23618                return null;
23619            },
23620
23621
23622            /**
23623             * @typedef {Object} ShadowOptions
23624             * @property {string} [color=#000000] The shadow color.
23625             * @property {number} [offsetX=1] The horizontal offset from the element.
23626             * @property {number} [offsetY=1] The vertical offset from the element.
23627             * @property {number} [opacity=0.15] The shadow opacity.
23628             * @property {number} [width=3] The shadow width or distance from the
23629             *    element.
23630             */
23631            /**
23632             * Add a shadow to the element. Must be called after the element is added to
23633             * the DOM. In styled mode, this method is not used, instead use `defs` and
23634             * filters.
23635             * 
23636             * @param {boolean|ShadowOptions} shadowOptions The shadow options. If
23637             *    `true`, the default options are applied. If `false`, the current
23638             *    shadow will be removed.
23639             * @param {SVGElement} [group] The SVG group element where the shadows will 
23640             *    be applied. The default is to add it to the same parent as the current
23641             *    element. Internally, this is ised for pie slices, where all the
23642             *    shadows are added to an element behind all the slices.
23643             * @param {boolean} [cutOff] Used internally for column shadows.
23644             *
23645             * @returns {SVGElement} Returns the SVGElement for chaining.
23646             *
23647             * @example
23648             * renderer.rect(10, 100, 100, 100)
23649             *     .attr({ fill: 'red' })
23650             *     .shadow(true);
23651             */
23652            shadow: function(shadowOptions, group, cutOff) {
23653                var shadows = [],
23654                    i,
23655                    shadow,
23656                    element = this.element,
23657                    strokeWidth,
23658                    shadowWidth,
23659                    shadowElementOpacity,
23660
23661                    // compensate for inverted plot area
23662                    transform;
23663
23664                if (!shadowOptions) {
23665                    this.destroyShadows();
23666
23667                } else if (!this.shadows) {
23668                    shadowWidth = pick(shadowOptions.width, 3);
23669                    shadowElementOpacity = (shadowOptions.opacity || 0.15) /
23670                        shadowWidth;
23671                    transform = this.parentInverted ?
23672                        '(-1,-1)' :
23673                        '(' + pick(shadowOptions.offsetX, 1) + ', ' +
23674                        pick(shadowOptions.offsetY, 1) + ')';
23675                    for (i = 1; i <= shadowWidth; i++) {
23676                        shadow = element.cloneNode(0);
23677                        strokeWidth = (shadowWidth * 2) + 1 - (2 * i);
23678                        attr(shadow, {
23679                            'isShadow': 'true',
23680                            'stroke': shadowOptions.color || '#000000',
23681                            'stroke-opacity': shadowElementOpacity * i,
23682                            'stroke-width': strokeWidth,
23683                            'transform': 'translate' + transform,
23684                            'fill': 'none'
23685                        });
23686                        if (cutOff) {
23687                            attr(
23688                                shadow,
23689                                'height',
23690                                Math.max(attr(shadow, 'height') - strokeWidth, 0)
23691                            );
23692                            shadow.cutHeight = strokeWidth;
23693                        }
23694
23695                        if (group) {
23696                            group.element.appendChild(shadow);
23697                        } else if (element.parentNode) {
23698                            element.parentNode.insertBefore(shadow, element);
23699                        }
23700
23701                        shadows.push(shadow);
23702                    }
23703
23704                    this.shadows = shadows;
23705                }
23706                return this;
23707
23708            },
23709
23710            /**
23711             * Destroy shadows on the element.
23712             * @private
23713             */
23714            destroyShadows: function() {
23715                each(this.shadows || [], function(shadow) {
23716                    this.safeRemoveChild(shadow);
23717                }, this);
23718                this.shadows = undefined;
23719            },
23720
23721
23722
23723            xGetter: function(key) {
23724                if (this.element.nodeName === 'circle') {
23725                    if (key === 'x') {
23726                        key = 'cx';
23727                    } else if (key === 'y') {
23728                        key = 'cy';
23729                    }
23730                }
23731                return this._defaultGetter(key);
23732            },
23733
23734            /**
23735             * Get the current value of an attribute or pseudo attribute, used mainly
23736             * for animation. Called internally from the {@link
23737             * Highcharts.SVGRenderer#attr}
23738             * function.
23739             *
23740             * @private
23741             */
23742            _defaultGetter: function(key) {
23743                var ret = pick(
23744                    this[key],
23745                    this.element ? this.element.getAttribute(key) : null,
23746                    0
23747                );
23748
23749                if (/^[\-0-9\.]+$/.test(ret)) { // is numerical
23750                    ret = parseFloat(ret);
23751                }
23752                return ret;
23753            },
23754
23755
23756            dSetter: function(value, key, element) {
23757                if (value && value.join) { // join path
23758                    value = value.join(' ');
23759                }
23760                if (/(NaN| {2}|^$)/.test(value)) {
23761                    value = 'M 0 0';
23762                }
23763
23764                // Check for cache before resetting. Resetting causes disturbance in the
23765                // DOM, causing flickering in some cases in Edge/IE (#6747). Also
23766                // possible performance gain.
23767                if (this[key] !== value) {
23768                    element.setAttribute(key, value);
23769                    this[key] = value;
23770                }
23771
23772            },
23773
23774            dashstyleSetter: function(value) {
23775                var i,
23776                    strokeWidth = this['stroke-width'];
23777
23778                // If "inherit", like maps in IE, assume 1 (#4981). With HC5 and the new
23779                // strokeWidth function, we should be able to use that instead.
23780                if (strokeWidth === 'inherit') {
23781                    strokeWidth = 1;
23782                }
23783                value = value && value.toLowerCase();
23784                if (value) {
23785                    value = value
23786                        .replace('shortdashdotdot', '3,1,1,1,1,1,')
23787                        .replace('shortdashdot', '3,1,1,1')
23788                        .replace('shortdot', '1,1,')
23789                        .replace('shortdash', '3,1,')
23790                        .replace('longdash', '8,3,')
23791                        .replace(/dot/g, '1,3,')
23792                        .replace('dash', '4,3,')
23793                        .replace(/,$/, '')
23794                        .split(','); // ending comma
23795
23796                    i = value.length;
23797                    while (i--) {
23798                        value[i] = pInt(value[i]) * strokeWidth;
23799                    }
23800                    value = value.join(',')
23801                        .replace(/NaN/g, 'none'); // #3226
23802                    this.element.setAttribute('stroke-dasharray', value);
23803                }
23804            },
23805
23806            alignSetter: function(value) {
23807                var convert = {
23808                    left: 'start',
23809                    center: 'middle',
23810                    right: 'end'
23811                };
23812                this.element.setAttribute('text-anchor', convert[value]);
23813            },
23814            opacitySetter: function(value, key, element) {
23815                this[key] = value;
23816                element.setAttribute(key, value);
23817            },
23818            titleSetter: function(value) {
23819                var titleNode = this.element.getElementsByTagName('title')[0];
23820                if (!titleNode) {
23821                    titleNode = doc.createElementNS(this.SVG_NS, 'title');
23822                    this.element.appendChild(titleNode);
23823                }
23824
23825                // Remove text content if it exists
23826                if (titleNode.firstChild) {
23827                    titleNode.removeChild(titleNode.firstChild);
23828                }
23829
23830                titleNode.appendChild(
23831                    doc.createTextNode(
23832                        // #3276, #3895
23833                        (String(pick(value), '')).replace(/<[^>]*>/g, '')
23834                    )
23835                );
23836            },
23837            textSetter: function(value) {
23838                if (value !== this.textStr) {
23839                    // Delete bBox memo when the text changes
23840                    delete this.bBox;
23841
23842                    this.textStr = value;
23843                    if (this.added) {
23844                        this.renderer.buildText(this);
23845                    }
23846                }
23847            },
23848            fillSetter: function(value, key, element) {
23849                if (typeof value === 'string') {
23850                    element.setAttribute(key, value);
23851                } else if (value) {
23852                    this.colorGradient(value, key, element);
23853                }
23854            },
23855            visibilitySetter: function(value, key, element) {
23856                // IE9-11 doesn't handle visibilty:inherit well, so we remove the
23857                // attribute instead (#2881, #3909)
23858                if (value === 'inherit') {
23859                    element.removeAttribute(key);
23860                } else if (this[key] !== value) { // #6747
23861                    element.setAttribute(key, value);
23862                }
23863                this[key] = value;
23864            },
23865            zIndexSetter: function(value, key) {
23866                var renderer = this.renderer,
23867                    parentGroup = this.parentGroup,
23868                    parentWrapper = parentGroup || renderer,
23869                    parentNode = parentWrapper.element || renderer.box,
23870                    childNodes,
23871                    otherElement,
23872                    otherZIndex,
23873                    element = this.element,
23874                    inserted,
23875                    undefinedOtherZIndex,
23876                    svgParent = parentNode === renderer.box,
23877                    run = this.added,
23878                    i;
23879
23880                if (defined(value)) {
23881                    // So we can read it for other elements in the group
23882                    element.zIndex = value;
23883
23884                    value = +value;
23885                    if (this[key] === value) { // Only update when needed (#3865)
23886                        run = false;
23887                    }
23888                    this[key] = value;
23889                }
23890
23891                // Insert according to this and other elements' zIndex. Before .add() is
23892                // called, nothing is done. Then on add, or by later calls to
23893                // zIndexSetter, the node is placed on the right place in the DOM.
23894                if (run) {
23895                    value = this.zIndex;
23896
23897                    if (value && parentGroup) {
23898                        parentGroup.handleZ = true;
23899                    }
23900
23901                    childNodes = parentNode.childNodes;
23902                    for (i = childNodes.length - 1; i >= 0 && !inserted; i--) {
23903                        otherElement = childNodes[i];
23904                        otherZIndex = otherElement.zIndex;
23905                        undefinedOtherZIndex = !defined(otherZIndex);
23906
23907                        if (otherElement !== element) {
23908                            if (
23909                                // Negative zIndex versus no zIndex:
23910                                // On all levels except the highest. If the parent is <svg>,
23911                                // then we don't want to put items before <desc> or <defs>
23912                                (value < 0 && undefinedOtherZIndex && !svgParent && !i)
23913                            ) {
23914                                parentNode.insertBefore(element, childNodes[i]);
23915                                inserted = true;
23916                            } else if (
23917                                // Insert after the first element with a lower zIndex
23918                                pInt(otherZIndex) <= value ||
23919                                // If negative zIndex, add this before first undefined zIndex element
23920                                (undefinedOtherZIndex && (!defined(value) || value >= 0))
23921                            ) {
23922                                parentNode.insertBefore(
23923                                    element,
23924                                    childNodes[i + 1] || null // null for oldIE export
23925                                );
23926                                inserted = true;
23927                            }
23928                        }
23929                    }
23930
23931                    if (!inserted) {
23932                        parentNode.insertBefore(
23933                            element,
23934                            childNodes[svgParent ? 3 : 0] || null // null for oldIE
23935                        );
23936                        inserted = true;
23937                    }
23938                }
23939                return inserted;
23940            },
23941            _defaultSetter: function(value, key, element) {
23942                element.setAttribute(key, value);
23943            }
23944        });
23945
23946        // Some shared setters and getters
23947        SVGElement.prototype.yGetter =
23948            SVGElement.prototype.xGetter;
23949        SVGElement.prototype.translateXSetter =
23950            SVGElement.prototype.translateYSetter =
23951            SVGElement.prototype.rotationSetter =
23952            SVGElement.prototype.verticalAlignSetter =
23953            SVGElement.prototype.rotationOriginXSetter =
23954            SVGElement.prototype.rotationOriginYSetter =
23955            SVGElement.prototype.scaleXSetter =
23956            SVGElement.prototype.scaleYSetter =
23957            SVGElement.prototype.matrixSetter = function(value, key) {
23958                this[key] = value;
23959                this.doTransform = true;
23960            };
23961
23962
23963        // WebKit and Batik have problems with a stroke-width of zero, so in this case
23964        // we remove the stroke attribute altogether. #1270, #1369, #3065, #3072.
23965        SVGElement.prototype['stroke-widthSetter'] =
23966            SVGElement.prototype.strokeSetter = function(value, key, element) {
23967                this[key] = value;
23968                // Only apply the stroke attribute if the stroke width is defined and larger
23969                // than 0
23970                if (this.stroke && this['stroke-width']) {
23971                    // Use prototype as instance may be overridden
23972                    SVGElement.prototype.fillSetter.call(
23973                        this,
23974                        this.stroke,
23975                        'stroke',
23976                        element
23977                    );
23978
23979                    element.setAttribute('stroke-width', this['stroke-width']);
23980                    this.hasStroke = true;
23981                } else if (key === 'stroke-width' && value === 0 && this.hasStroke) {
23982                    element.removeAttribute('stroke');
23983                    this.hasStroke = false;
23984                }
23985            };
23986
23987
23988        /**
23989         * Allows direct access to the Highcharts rendering layer in order to draw
23990         * primitive shapes like circles, rectangles, paths or text directly on a chart,
23991         * or independent from any chart. The SVGRenderer represents a wrapper object
23992         * for SVG in modern browsers. Through the VMLRenderer, part of the `oldie.js`
23993         * module, it also brings vector graphics to IE <= 8.
23994         *
23995         * An existing chart's renderer can be accessed through {@link Chart.renderer}.
23996         * The renderer can also be used completely decoupled from a chart.
23997         *
23998         * @param {HTMLDOMElement} container - Where to put the SVG in the web page.
23999         * @param {number} width - The width of the SVG.
24000         * @param {number} height - The height of the SVG.
24001         * @param {boolean} [forExport=false] - Whether the rendered content is intended
24002         *   for export.
24003         * @param {boolean} [allowHTML=true] - Whether the renderer is allowed to
24004         *   include HTML text, which will be projected on top of the SVG.
24005         *
24006         * @example
24007         * // Use directly without a chart object.
24008         * var renderer = new Highcharts.Renderer(parentNode, 600, 400);
24009         *
24010         * @sample highcharts/members/renderer-on-chart
24011         *         Annotating a chart programmatically.
24012         * @sample highcharts/members/renderer-basic
24013         *         Independent SVG drawing.
24014         *
24015         * @class Highcharts.SVGRenderer
24016         */
24017        SVGRenderer = H.SVGRenderer = function() {
24018            this.init.apply(this, arguments);
24019        };
24020        extend(SVGRenderer.prototype, /** @lends Highcharts.SVGRenderer.prototype */ {
24021            /**
24022             * A pointer to the renderer's associated Element class. The VMLRenderer
24023             * will have a pointer to VMLElement here.
24024             * @type {SVGElement}
24025             */
24026            Element: SVGElement,
24027            SVG_NS: SVG_NS,
24028            /**
24029             * Initialize the SVGRenderer. Overridable initiator function that takes
24030             * the same parameters as the constructor.
24031             */
24032            init: function(container, width, height, style, forExport, allowHTML) {
24033                var renderer = this,
24034                    boxWrapper,
24035                    element,
24036                    desc;
24037
24038                boxWrapper = renderer.createElement('svg')
24039                    .attr({
24040                        'version': '1.1',
24041                        'class': 'highcharts-root'
24042                    })
24043
24044                    .css(this.getStyle(style));
24045                element = boxWrapper.element;
24046                container.appendChild(element);
24047
24048                // Always use ltr on the container, otherwise text-anchor will be
24049                // flipped and text appear outside labels, buttons, tooltip etc (#3482)
24050                attr(container, 'dir', 'ltr');
24051
24052                // For browsers other than IE, add the namespace attribute (#1978)
24053                if (container.innerHTML.indexOf('xmlns') === -1) {
24054                    attr(element, 'xmlns', this.SVG_NS);
24055                }
24056
24057                // object properties
24058                renderer.isSVG = true;
24059
24060                /** 
24061                 * The root `svg` node of the renderer.
24062                 * @name box
24063                 * @memberOf SVGRenderer
24064                 * @type {SVGDOMElement}
24065                 */
24066                this.box = element;
24067                /** 
24068                 * The wrapper for the root `svg` node of the renderer.
24069                 *
24070                 * @name boxWrapper
24071                 * @memberOf SVGRenderer
24072                 * @type {SVGElement}
24073                 */
24074                this.boxWrapper = boxWrapper;
24075                renderer.alignedObjects = [];
24076
24077                /**
24078                 * Page url used for internal references.
24079                 * @type {string}
24080                 */
24081                // #24, #672, #1070
24082                this.url = (
24083                        (isFirefox || isWebKit) &&
24084                        doc.getElementsByTagName('base').length
24085                    ) ?
24086                    win.location.href
24087                    .replace(/#.*?$/, '') // remove the hash
24088                    .replace(/<[^>]*>/g, '') // wing cut HTML
24089                    // escape parantheses and quotes
24090                    .replace(/([\('\)])/g, '\\$1')
24091                    // replace spaces (needed for Safari only)
24092                    .replace(/ /g, '%20') :
24093                    '';
24094
24095                // Add description
24096                desc = this.createElement('desc').add();
24097                desc.element.appendChild(
24098                    doc.createTextNode('Created with Highcharts 6.0.3')
24099                );
24100
24101                /**
24102                 * A pointer to the `defs` node of the root SVG.
24103                 * @type {SVGElement}
24104                 * @name defs
24105                 * @memberOf SVGRenderer
24106                 */
24107                renderer.defs = this.createElement('defs').add();
24108                renderer.allowHTML = allowHTML;
24109                renderer.forExport = forExport;
24110                renderer.gradients = {}; // Object where gradient SvgElements are stored
24111                renderer.cache = {}; // Cache for numerical bounding boxes
24112                renderer.cacheKeys = [];
24113                renderer.imgCount = 0;
24114
24115                renderer.setSize(width, height, false);
24116
24117
24118
24119                // Issue 110 workaround:
24120                // In Firefox, if a div is positioned by percentage, its pixel position
24121                // may land between pixels. The container itself doesn't display this,
24122                // but an SVG element inside this container will be drawn at subpixel
24123                // precision. In order to draw sharp lines, this must be compensated
24124                // for. This doesn't seem to work inside iframes though (like in
24125                // jsFiddle).
24126                var subPixelFix, rect;
24127                if (isFirefox && container.getBoundingClientRect) {
24128                    subPixelFix = function() {
24129                        css(container, {
24130                            left: 0,
24131                            top: 0
24132                        });
24133                        rect = container.getBoundingClientRect();
24134                        css(container, {
24135                            left: (Math.ceil(rect.left) - rect.left) + 'px',
24136                            top: (Math.ceil(rect.top) - rect.top) + 'px'
24137                        });
24138                    };
24139
24140                    // run the fix now
24141                    subPixelFix();
24142
24143                    // run it on resize
24144                    renderer.unSubPixelFix = addEvent(win, 'resize', subPixelFix);
24145                }
24146            },
24147
24148
24149
24150            /**
24151             * Get the global style setting for the renderer.
24152             * @private
24153             * @param  {CSSObject} style - Style settings.
24154             * @return {CSSObject} The style settings mixed with defaults.
24155             */
24156            getStyle: function(style) {
24157                this.style = extend({
24158
24159                    fontFamily: '"Lucida Grande", "Lucida Sans Unicode", ' +
24160                        'Arial, Helvetica, sans-serif',
24161                    fontSize: '12px'
24162
24163                }, style);
24164                return this.style;
24165            },
24166            /**
24167             * Apply the global style on the renderer, mixed with the default styles.
24168             * 
24169             * @param {CSSObject} style - CSS to apply.
24170             */
24171            setStyle: function(style) {
24172                this.boxWrapper.css(this.getStyle(style));
24173            },
24174
24175
24176            /**
24177             * Detect whether the renderer is hidden. This happens when one of the
24178             * parent elements has `display: none`. Used internally to detect when we
24179             * needto render preliminarily in another div to get the text bounding boxes
24180             * right.
24181             *
24182             * @returns {boolean} True if it is hidden.
24183             */
24184            isHidden: function() { // #608
24185                return !this.boxWrapper.getBBox().width;
24186            },
24187
24188            /**
24189             * Destroys the renderer and its allocated members.
24190             */
24191            destroy: function() {
24192                var renderer = this,
24193                    rendererDefs = renderer.defs;
24194                renderer.box = null;
24195                renderer.boxWrapper = renderer.boxWrapper.destroy();
24196
24197                // Call destroy on all gradient elements
24198                destroyObjectProperties(renderer.gradients || {});
24199                renderer.gradients = null;
24200
24201                // Defs are null in VMLRenderer
24202                // Otherwise, destroy them here.
24203                if (rendererDefs) {
24204                    renderer.defs = rendererDefs.destroy();
24205                }
24206
24207                // Remove sub pixel fix handler (#982)
24208                if (renderer.unSubPixelFix) {
24209                    renderer.unSubPixelFix();
24210                }
24211
24212                renderer.alignedObjects = null;
24213
24214                return null;
24215            },
24216
24217            /**
24218             * Create a wrapper for an SVG element. Serves as a factory for 
24219             * {@link SVGElement}, but this function is itself mostly called from 
24220             * primitive factories like {@link SVGRenderer#path}, {@link
24221             * SVGRenderer#rect} or {@link SVGRenderer#text}.
24222             * 
24223             * @param {string}
24223 nodeName - The node name, for example `rect`, `g` etc.
24224             * @returns {SVGElement} The generated SVGElement.
24225             */
24226            createElement: function(nodeName) {
24227                var wrapper = new this.Element();
24228                wrapper.init(this, nodeName);
24229                return wrapper;
24230            },
24231
24232            /**
24233             * Dummy function for plugins, called every time the renderer is updated.
24234             * Prior to Highcharts 5, this was used for the canvg renderer.
24235             * @function
24236             */
24237            draw: noop,
24238
24239            /**
24240             * Get converted radial gradient attributes according to the radial
24241             * reference. Used internally from the {@link SVGElement#colorGradient}
24242             * function.
24243             *
24244             * @private
24245             */
24246            getRadialAttr: function(radialReference, gradAttr) {
24247                return {
24248                    cx: (radialReference[0] - radialReference[2] / 2) +
24249                        gradAttr.cx * radialReference[2],
24250                    cy: (radialReference[1] - radialReference[2] / 2) +
24251                        gradAttr.cy * radialReference[2],
24252                    r: gradAttr.r * radialReference[2]
24253                };
24254            },
24255
24256            getSpanWidth: function(wrapper, tspan) {
24257                var renderer = this,
24258                    bBox = wrapper.getBBox(true),
24259                    actualWidth = bBox.width;
24260
24261                // Old IE cannot measure the actualWidth for SVG elements (#2314)
24262                if (!svg && renderer.forExport) {
24263                    actualWidth = renderer.measureSpanWidth(
24264                        tspan.firstChild.data,
24265                        wrapper.styles
24266                    );
24267                }
24268                return actualWidth;
24269            },
24270
24271            applyEllipsis: function(wrapper, tspan, text, width) {
24272                var renderer = this,
24273                    rotation = wrapper.rotation,
24274                    str = text,
24275                    currentIndex,
24276                    minIndex = 0,
24277                    maxIndex = text.length,
24278                    updateTSpan = function(s) {
24279                        tspan.removeChild(tspan.firstChild);
24280                        if (s) {
24281                            tspan.appendChild(doc.createTextNode(s));
24282                        }
24283                    },
24284                    actualWidth,
24285                    wasTooLong;
24286                wrapper.rotation = 0; // discard rotation when computing box
24287                actualWidth = renderer.getSpanWidth(wrapper, tspan);
24288                wasTooLong = actualWidth > width;
24289                if (wasTooLong) {
24290                    while (minIndex <= maxIndex) {
24291                        currentIndex = Math.ceil((minIndex + maxIndex) / 2);
24292                        str = text.substring(0, currentIndex) + '\u2026';
24293                        updateTSpan(str);
24294                        actualWidth = renderer.getSpanWidth(wrapper, tspan);
24295                        if (minIndex === maxIndex) {
24296                            // Complete
24297                            minIndex = maxIndex + 1;
24298                        } else if (actualWidth > width) {
24299                            // Too large. Set max index to current.
24300                            maxIndex = currentIndex - 1;
24301                        } else {
24302                            // Within width. Set min index to current.
24303                            minIndex = currentIndex;
24304                        }
24305                    }
24306                    // If max index was 0 it means just ellipsis was also to large.
24307                    if (maxIndex === 0) {
24308                        // Remove ellipses.
24309                        updateTSpan('');
24310                    }
24311                }
24312                wrapper.rotation = rotation; // Apply rotation again.
24313                return wasTooLong;
24314            },
24315
24316            /**
24317             * A collection of characters mapped to HTML entities. When `useHTML` on an
24318             * element is true, these entities will be rendered correctly by HTML. In 
24319             * the SVG pseudo-HTML, they need to be unescaped back to simple characters,
24320             * so for example `&lt;` will render as `<`.
24321             *
24322             * @example
24323             * // Add support for unescaping quotes
24324             * Highcharts.SVGRenderer.prototype.escapes['"'] = '&quot;';
24325             * 
24326             * @type {Object}
24327             */
24328            escapes: {
24329                '&': '&amp;',
24330                '<': '&lt;',
24331                '>': '&gt;',
24332                "'": '&#39;', // eslint-disable-line quotes
24333                '"': '&quot'
24334            },
24335
24336            /**
24337             * Parse a simple HTML string into SVG tspans. Called internally when text
24338             *   is set on an SVGElement. The function supports a subset of HTML tags,
24339             *   CSS text features like `width`, `text-overflow`, `white-space`, and
24340             *   also attributes like `href` and `style`.
24341             * @private
24342             * @param {SVGElement} wrapper The parent SVGElement.
24343             */
24344            buildText: function(wrapper) {
24345                var textNode = wrapper.element,
24346                    renderer = this,
24347                    forExport = renderer.forExport,
24348                    textStr = pick(wrapper.textStr, '').toString(),
24349                    hasMarkup = textStr.indexOf('<') !== -1,
24350                    lines,
24351                    childNodes = textNode.childNodes,
24352                    clsRegex,
24353                    styleRegex,
24354                    hrefRegex,
24355                    wasTooLong,
24356                    parentX = attr(textNode, 'x'),
24357                    textStyles = wrapper.styles,
24358                    width = wrapper.textWidth,
24359                    textLineHeight = textStyles && textStyles.lineHeight,
24360                    textOutline = textStyles && textStyles.textOutline,
24361                    ellipsis = textStyles && textStyles.textOverflow === 'ellipsis',
24362                    noWrap = textStyles && textStyles.whiteSpace === 'nowrap',
24363                    fontSize = textStyles && textStyles.fontSize,
24364                    textCache,
24365                    isSubsequentLine,
24366                    i = childNodes.length,
24367                    tempParent = width && !wrapper.added && this.box,
24368                    getLineHeight = function(tspan) {
24369                        var fontSizeStyle;
24370
24371                        fontSizeStyle = /(px|em)$/.test(tspan && tspan.style.fontSize) ?
24372                            tspan.style.fontSize :
24373                            (fontSize || renderer.style.fontSize || 12);
24374
24375
24376                        return textLineHeight ?
24377                            pInt(textLineHeight) :
24378                            renderer.fontMetrics(
24379                                fontSizeStyle,
24380                                // Get the computed size from parent if not explicit
24381                                tspan.getAttribute('style') ? tspan : textNode
24382                            ).h;
24383                    },
24384                    unescapeEntities = function(inputStr) {
24385                        objectEach(renderer.escapes, function(value, key) {
24386                            inputStr = inputStr.replace(
24387                                new RegExp(value, 'g'),
24388                                key
24389                            );
24390                        });
24391                        return inputStr;
24392                    };
24393
24394                // The buildText code is quite heavy, so if we're not changing something
24395                // that affects the text, skip it (#6113).
24396                textCache = [
24397                    textStr,
24398                    ellipsis,
24399                    noWrap,
24400                    textLineHeight,
24401                    textOutline,
24402                    fontSize,
24403                    width
24404                ].join(',');
24405                if (textCache === wrapper.textCache) {
24406                    return;
24407                }
24408                wrapper.textCache = textCache;
24409
24410                // Remove old text
24411                while (i--) {
24412                    textNode.removeChild(childNodes[i]);
24413                }
24414
24415                // Skip tspans, add text directly to text node. The forceTSpan is a hook
24416                // used in text outline hack.
24417                if (!hasMarkup &&
24418                    !textOutline &&
24419                    !ellipsis &&
24420                    !width &&
24421                    textStr.indexOf(' ') === -1
24422                ) {
24423                    textNode.appendChild(doc.createTextNode(unescapeEntities(textStr)));
24424
24425                    // Complex strings, add more logic
24426                } else {
24427
24428                    clsRegex = /<.*class="([^"]+)".*>/;
24429                    styleRegex = /<.*style="([^"]+)".*>/;
24430                    hrefRegex = /<.*href="([^"]+)".*>/;
24431
24432                    if (tempParent) {
24433                        // attach it to the DOM to read offset width
24434                        tempParent.appendChild(textNode);
24435                    }
24436
24437                    if (hasMarkup) {
24438                        lines = textStr
24439
24440                            .replace(/<(b|strong)>/g, '<span style="font-weight:bold">')
24441                            .replace(/<(i|em)>/g, '<span style="font-style:italic">')
24442
24443                            .replace(/<a/g, '<span')
24444                            .replace(/<\/(b|strong|i|em|a)>/g, '</span>')
24445                            .split(/<br.*?>/g);
24446
24447                    } else {
24448                        lines = [textStr];
24449                    }
24450
24451
24452                    // Trim empty lines (#5261)
24453                    lines = grep(lines, function(line) {
24454                        return line !== '';
24455                    });
24456
24457
24458                    // build the lines
24459                    each(lines, function buildTextLines(line, lineNo) {
24460                        var spans,
24461                            spanNo = 0;
24462                        line = line
24463                            // Trim to prevent useless/costly process on the spaces
24464                            // (#5258)
24465                            .replace(/^\s+|\s+$/g, '')
24466                            .replace(/<span/g, '|||<span')
24467                            .replace(/<\/span>/g, '</span>|||');
24468                        spans = line.split('|||');
24469
24470                        each(spans, function buildTextSpans(span) {
24471                            if (span !== '' || spans.length === 1) {
24472                                var attributes = {},
24473                                    tspan = doc.createElementNS(
24474                                        renderer.SVG_NS,
24475                                        'tspan'
24476                                    ),
24477                                    spanCls,
24478                                    spanStyle; // #390
24479                                if (clsRegex.test(span)) {
24480                                    spanCls = span.match(clsRegex)[1];
24481                                    attr(tspan, 'class', spanCls);
24482                                }
24483                                if (styleRegex.test(span)) {
24484                                    spanStyle = span.match(styleRegex)[1].replace(
24485                                        /(;| |^)color([ :])/,
24486                                        '$1fill$2'
24487                                    );
24488                                    attr(tspan, 'style', spanStyle);
24489                                }
24490
24491                                // Not for export - #1529
24492                                if (hrefRegex.test(span) && !forExport) {
24493                                    attr(
24494                                        tspan,
24495                                        'onclick',
24496                                        'location.href=\"' +
24497                                        span.match(hrefRegex)[1] + '\"'
24498                                    );
24499                                    attr(tspan, 'class', 'highcharts-anchor');
24500
24501                                    css(tspan, {
24502                                        cursor: 'pointer'
24503                                    });
24504
24505                                }
24506
24507                                // Strip away unsupported HTML tags (#7126)
24508                                span = unescapeEntities(
24509                                    span.replace(/<[a-zA-Z\/](.|\n)*?>/g, '') || ' '
24510                                );
24511
24512                                // Nested tags aren't supported, and cause crash in
24513                                // Safari (#1596)
24514                                if (span !== ' ') {
24515
24516                                    // add the text node
24517                                    tspan.appendChild(doc.createTextNode(span));
24518
24519                                    // First span in a line, align it to the left
24520                                    if (!spanNo) {
24521                                        if (lineNo && parentX !== null) {
24522                                            attributes.x = parentX;
24523                                        }
24524                                    } else {
24525                                        attributes.dx = 0; // #16
24526                                    }
24527
24528                                    // add attributes
24529                                    attr(tspan, attributes);
24530
24531                                    // Append it
24532                                    textNode.appendChild(tspan);
24533
24534                                    // first span on subsequent line, add the line
24535                                    // height
24536                                    if (!spanNo && isSubsequentLine) {
24537
24538                                        // allow getting the right offset height in
24539                                        // exporting in IE
24540                                        if (!svg && forExport) {
24541                                            css(tspan, {
24542                                                display: 'block'
24543                                            });
24544                                        }
24545
24546                                        // Set the line height based on the font size of
24547                                        // either the text element or the tspan element
24548                                        attr(
24549                                            tspan,
24550                                            'dy',
24551                                            getLineHeight(tspan)
24552                                        );
24553                                    }
24554
24555                                    /* 
24556                                    if (width) {
24557                                    	renderer.breakText(wrapper, width);
24558                                    }
24559                                    */
24560
24561                                    // Check width and apply soft breaks or ellipsis
24562                                    if (width) {
24563                                        var words = span.replace(
24564                                                /([^\^])-/g,
24565                                                '$1- '
24566                                            ).split(' '), // #1273
24567                                            hasWhiteSpace = (
24568                                                spans.length > 1 ||
24569                                                lineNo ||
24570                                                (words.length > 1 && !noWrap)
24571                                            ),
24572                                            tooLong,
24573                                            rest = [],
24574                                            actualWidth,
24575                                            dy = getLineHeight(tspan),
24576                                            rotation = wrapper.rotation;
24577
24578                                        if (ellipsis) {
24579                                            wasTooLong = renderer.applyEllipsis(
24580                                                wrapper,
24581                                                tspan,
24582                                                span,
24583                                                width
24584                                            );
24585                                        }
24586
24587                                        while (!ellipsis &&
24588                                            hasWhiteSpace &&
24589                                            (words.length || rest.length)
24590                                        ) {
24591                                            // discard rotation when computing box
24592                                            wrapper.rotation = 0;
24593                                            actualWidth = renderer.getSpanWidth(
24594                                                wrapper,
24595                                                tspan
24596                                            );
24597                                            tooLong = actualWidth > width;
24598
24599                                            // For ellipsis, do a binary search for the 
24600                                            // correct string length
24601                                            if (wasTooLong === undefined) {
24602                                                wasTooLong = tooLong; // First time
24603                                            }
24604
24605                                            // Looping down, this is the first word
24606                                            // sequence that is not too long, so we can
24607                                            // move on to build the next line.
24608                                            if (!tooLong || words.length === 1) {
24609                                                words = rest;
24610                                                rest = [];
24611
24612                                                if (words.length && !noWrap) {
24613                                                    tspan = doc.createElementNS(
24614                                                        SVG_NS,
24615                                                        'tspan'
24616                                                    );
24617                                                    attr(tspan, {
24618                                                        dy: dy,
24619                                                        x: parentX
24620                                                    });
24621                                                    if (spanStyle) { // #390
24622                                                        attr(tspan, 'style', spanStyle);
24623                                                    }
24624                                                    textNode.appendChild(tspan);
24625                                                }
24626
24627                                                // a single word is pressing it out
24628                                                if (actualWidth > width) {
24629                                                    width = actualWidth;
24630                                                }
24631                                            } else { // append to existing line tspan
24632                                                tspan.removeChild(tspan.firstChild);
24633                                                rest.unshift(words.pop());
24634                                            }
24635                                            if (words.length) {
24636                                                tspan.appendChild(
24637                                                    doc.createTextNode(
24638                                                        words.join(' ')
24639                                                        .replace(/- /g, '-')
24640                                                    )
24641                                                );
24642         
24642                                   }
24643                                        }
24644                                        wrapper.rotation = rotation;
24645                                    }
24646
24647                                    spanNo++;
24648                                }
24649                            }
24650                        });
24651                        // To avoid beginning lines that doesn't add to the textNode
24652                        // (#6144)
24653                        isSubsequentLine = (
24654                            isSubsequentLine ||
24655                            textNode.childNodes.length
24656                        );
24657                    });
24658
24659                    if (wasTooLong) {
24660                        wrapper.attr('title', wrapper.textStr);
24661                    }
24662                    if (tempParent) {
24663                        tempParent.removeChild(textNode);
24664                    }
24665
24666                    // Apply the text outline
24667                    if (textOutline && wrapper.applyTextOutline) {
24668                        wrapper.applyTextOutline(textOutline);
24669                    }
24670                }
24671            },
24672
24673
24674
24675            /*
24676            breakText: function (wrapper, width) {
24677            	var bBox = wrapper.getBBox(),
24678            		node = wrapper.element,
24679            		textLength = node.textContent.length,
24680            		// try this position first, based on average character width
24681            		pos = Math.round(width * textLength / bBox.width),
24682            		increment = 0,
24683            		finalPos;
24684
24685            	if (bBox.width > width) {
24686            		while (finalPos === undefined) {
24687            			textLength = node.getSubStringLength(0, pos);
24688
24689            			if (textLength <= width) {
24690            				if (increment === -1) {
24691            					finalPos = pos;
24692            				} else {
24693            					increment = 1;
24694            				}
24695            			} else {
24696            				if (increment === 1) {
24697            					finalPos = pos - 1;
24698            				} else {
24699            					increment = -1;
24700            				}
24701            			}
24702            			pos += increment;
24703            		}
24704            	}
24705            	console.log(
24706            		'width',
24707            		width,
24708            		'stringWidth',
24709            		node.getSubStringLength(0, finalPos)
24710            	)
24711            },
24712            */
24713
24714            /**
24715             * Returns white for dark colors and black for bright colors.
24716             *
24717             * @param {ColorString} rgba - The color to get the contrast for.
24718             * @returns {string} The contrast color, either `#000000` or `#FFFFFF`.
24719             */
24720            getContrast: function(rgba) {
24721                rgba = color(rgba).rgba;
24722
24723                // The threshold may be discussed. Here's a proposal for adding
24724                // different weight to the color channels (#6216)
24725                /*
24726        rgba[0] *= 1; // red
24727        rgba[1] *= 1.2; // green
24728        rgba[2] *= 0.7; // blue
24729        */
24730
24731                return rgba[0] + rgba[1] + rgba[2] > 2 * 255 ? '#000000' : '#FFFFFF';
24732            },
24733
24734            /**
24735             * Create a button with preset states.
24736             * @param {string} text - The text or HTML to draw.
24737             * @param {number} x - The x position of the button's left side.
24738             * @param {number} y - The y position of the button's top side.
24739             * @param {Function} callback - The function to execute on button click or 
24740             *    touch.
24741             * @param {SVGAttributes} [normalState] - SVG attributes for the normal
24742             *    state.
24743             * @param {SVGAttributes} [hoverState] - SVG attributes for the hover state.
24744             * @param {SVGAttributes} [pressedState] - SVG attributes for the pressed
24745             *    state.
24746             * @param {SVGAttributes} [disabledState] - SVG attributes for the disabled
24747             *    state.
24748             * @param {Symbol} [shape=rect] - The shape type.
24749             * @returns {SVGRenderer} The button element.
24750             */
24751            button: function(
24752                text,
24753                x,
24754                y,
24755                callback,
24756                normalState,
24757                hoverState,
24758                pressedState,
24759                disabledState,
24760                shape
24761            ) {
24762                var label = this.label(
24763                        text,
24764                        x,
24765                        y,
24766                        shape,
24767                        null,
24768                        null,
24769                        null,
24770                        null,
24771                        'button'
24772                    ),
24773                    curState = 0;
24774
24775                // Default, non-stylable attributes
24776                label.attr(merge({
24777                    'padding': 8,
24778                    'r': 2
24779                }, normalState));
24780
24781
24782                // Presentational
24783                var normalStyle,
24784                    hoverStyle,
24785                    pressedStyle,
24786                    disabledStyle;
24787
24788                // Normal state - prepare the attributes
24789                normalState = merge({
24790                    fill: '#f7f7f7',
24791                    stroke: '#cccccc',
24792                    'stroke-width': 1,
24793                    style: {
24794                        color: '#333333',
24795                        cursor: 'pointer',
24796                        fontWeight: 'normal'
24797                    }
24798                }, normalState);
24799                normalStyle = normalState.style;
24800                delete normalState.style;
24801
24802                // Hover state
24803                hoverState = merge(normalState, {
24804                    fill: '#e6e6e6'
24805                }, hoverState);
24806                hoverStyle = hoverState.style;
24807                delete hoverState.style;
24808
24809                // Pressed state
24810                pressedState = merge(normalState, {
24811                    fill: '#e6ebf5',
24812                    style: {
24813                        color: '#000000',
24814                        fontWeight: 'bold'
24815                    }
24816                }, pressedState);
24817                pressedStyle = pressedState.style;
24818                delete pressedState.style;
24819
24820                // Disabled state
24821                disabledState = merge(normalState, {
24822                    style: {
24823                        color: '#cccccc'
24824                    }
24825                }, disabledState);
24826                disabledStyle = disabledState.style;
24827                delete disabledState.style;
24828
24829
24830                // Add the events. IE9 and IE10 need mouseover and mouseout to funciton
24831                // (#667).
24832                addEvent(label.element, isMS ? 'mouseover' : 'mouseenter', function() {
24833                    if (curState !== 3) {
24834                        label.setState(1);
24835                    }
24836                });
24837                addEvent(label.element, isMS ? 'mouseout' : 'mouseleave', function() {
24838                    if (curState !== 3) {
24839                        label.setState(curState);
24840                    }
24841                });
24842
24843                label.setState = function(state) {
24844                    // Hover state is temporary, don't record it
24845                    if (state !== 1) {
24846                        label.state = curState = state;
24847                    }
24848                    // Update visuals
24849                    label.removeClass(
24850                            /highcharts-button-(normal|hover|pressed|disabled)/
24851                        )
24852                        .addClass(
24853                            'highcharts-button-' + ['normal', 'hover', 'pressed', 'disabled'][state || 0]
24854                        );
24855
24856
24857                    label.attr([
24858                            normalState,
24859                            hoverState,
24860                            pressedState,
24861                            disabledState
24862                        ][state || 0])
24863                        .css([
24864                            normalStyle,
24865                            hoverStyle,
24866                            pressedStyle,
24867                            disabledStyle
24868                        ][state || 0]);
24869
24870                };
24871
24872
24873
24874                // Presentational attributes
24875                label
24876                    .attr(normalState)
24877                    .css(extend({
24878                        cursor: 'default'
24879                    }, normalStyle));
24880
24881
24882                return label
24883                    .on('click', function(e) {
24884                        if (curState !== 3) {
24885                            callback.call(label, e);
24886                        }
24887                    });
24888            },
24889
24890            /**
24891             * Make a straight line crisper by not spilling out to neighbour pixels.
24892             * 
24893             * @param {Array} points - The original points on the format `['M', 0, 0,
24894             *    'L', 100, 0]`.
24895             * @param {number} width - The width of the line.
24896             * @returns {Array} The original points array, but modified to render
24897             * crisply.
24898             */
24899            crispLine: function(points, width) {
24900                // normalize to a crisp line
24901                if (points[1] === points[4]) {
24902                    // Substract due to #1129. Now bottom and left axis gridlines behave
24903                    // the same.
24904                    points[1] = points[4] = Math.round(points[1]) - (width % 2 / 2);
24905                }
24906                if (points[2] === points[5]) {
24907                    points[2] = points[5] = Math.round(points[2]) + (width % 2 / 2);
24908                }
24909                return points;
24910            },
24911
24912
24913            /**
24914             * Draw a path, wraps the SVG `path` element.
24915             * 
24916             * @param {Array} [path] An SVG path definition in array form.
24917             * 
24918             * @example
24919             * var path = renderer.path(['M', 10, 10, 'L', 30, 30, 'z'])
24920             *     .attr({ stroke: '#ff00ff' })
24921             *     .add();
24922             * @returns {SVGElement} The generated wrapper element.
24923             *
24924             * @sample highcharts/members/renderer-path-on-chart/
24925             *         Draw a path in a chart
24926             * @sample highcharts/members/renderer-path/
24927             *         Draw a path independent from a chart
24928             *
24929             */
24930            /**
24931             * Draw a path, wraps the SVG `path` element.
24932             * 
24933             * @param {SVGAttributes} [attribs] The initial attributes.
24934             * @returns {SVGElement} The generated wrapper element.
24935             */
24936            path: function(path) {
24937                var attribs = {
24938
24939                    fill: 'none'
24940
24941                };
24942                if (isArray(path)) {
24943                    attribs.d = path;
24944                } else if (isObject(path)) { // attributes
24945                    extend(attribs, path);
24946                }
24947                return this.createElement('path').attr(attribs);
24948            },
24949
24950            /**
24951             * Draw a circle, wraps the SVG `circle` element.
24952             * 
24953             * @param {number} [x] The center x position.
24954             * @param {number} [y] The center y position.
24955             * @param {number} [r] The radius.
24956             * @returns {SVGElement}
24956 The generated wrapper element.
24957             *
24958             * @sample highcharts/members/renderer-circle/ Drawing a circle
24959             */
24960            /**
24961             * Draw a circle, wraps the SVG `circle` element.
24962             * 
24963             * @param {SVGAttributes} [attribs] The initial attributes.
24964             * @returns {SVGElement} The generated wrapper element.
24965             */
24966            circle: function(x, y, r) {
24967                var attribs = isObject(x) ? x : {
24968                        x: x,
24969                        y: y,
24970                        r: r
24971                    },
24972                    wrapper = this.createElement('circle');
24973
24974                // Setting x or y translates to cx and cy
24975                wrapper.xSetter = wrapper.ySetter = function(value, key, element) {
24976                    element.setAttribute('c' + key, value);
24977                };
24978
24979                return wrapper.attr(attribs);
24980            },
24981
24982            /**
24983             * Draw and return an arc.
24984             * @param {number} [x=0] Center X position.
24985             * @param {number} [y=0] Center Y position.
24986             * @param {number} [r=0] The outer radius of the arc.
24987             * @param {number} [innerR=0] Inner radius like used in donut charts.
24988             * @param {number} [start=0] The starting angle of the arc in radians, where
24989             *    0 is to the right and `-Math.PI/2` is up.
24990             * @param {number} [end=0] The ending angle of the arc in radians, where 0
24991             *    is to the right and `-Math.PI/2` is up.
24992             * @returns {SVGElement} The generated wrapper element.
24993             *
24994             * @sample highcharts/members/renderer-arc/
24995             *         Drawing an arc
24996             */
24997            /**
24998             * Draw and return an arc. Overloaded function that takes arguments object.
24999             * @param {SVGAttributes} attribs Initial SVG attributes.
25000             * @returns {SVGElement} The generated wrapper element.
25001             */
25002            arc: function(x, y, r, innerR, start, end) {
25003                var arc,
25004                    options;
25005
25006                if (isObject(x)) {
25007                    options = x;
25008                    y = options.y;
25009                    r = options.r;
25010                    innerR = options.innerR;
25011                    start = options.start;
25012                    end = options.end;
25013                    x = options.x;
25014                } else {
25015                    options = {
25016                        innerR: innerR,
25017                        start: start,
25018                        end: end
25019                    };
25020                }
25021
25022                // Arcs are defined as symbols for the ability to set
25023                // attributes in attr and animate
25024                arc = this.symbol('arc', x, y, r, r, options);
25025                arc.r = r; // #959
25026                return arc;
25027            },
25028
25029            /**
25030             * Draw and return a rectangle.
25031             * @param {number} [x] Left position.
25032             * @param {number} [y] Top position.
25033             * @param {number} [width] Width of the rectangle.
25034             * @param {number} [height] Height of the rectangle.
25035             * @param {number} [r] Border corner radius.
25036             * @param {number} [strokeWidth] A stroke width can be supplied to allow
25037             *    crisp drawing.
25038             * @returns {SVGElement} The generated wrapper element.
25039             */
25040            /**
25041             * Draw and return a rectangle.
25042             * @param  {SVGAttributes} [attributes]
25043             *         General SVG attributes for the rectangle.
25044             * @return {SVGElement}
25045             *         The generated wrapper element.
25046             *
25047             * @sample highcharts/members/renderer-rect-on-chart/
25048             *         Draw a rectangle in a chart
25049             * @sample highcharts/members/renderer-rect/
25050             *         Draw a rectangle independent from a chart
25051             */
25052            rect: function(x, y, width, height, r, strokeWidth) {
25053
25054                r = isObject(x) ? x.r : r;
25055
25056                var wrapper = this.createElement('rect'),
25057                    attribs = isObject(x) ? x : x === undefined ? {} : {
25058                        x: x,
25059                        y: y,
25060                        width: Math.max(width, 0),
25061                        height: Math.max(height, 0)
25062                    };
25063
25064
25065                if (strokeWidth !== undefined) {
25066                    attribs.strokeWidth = strokeWidth;
25067                    attribs = wrapper.crisp(attribs);
25068                }
25069                attribs.fill = 'none';
25070
25071
25072                if (r) {
25073                    attribs.r = r;
25074                }
25075
25076                wrapper.rSetter = function(value, key, element) {
25077                    attr(element, {
25078                        rx: value,
25079                        ry: value
25080                    });
25081                };
25082
25083                return wrapper.attr(attribs);
25084            },
25085
25086            /**
25087             * Resize the {@link SVGRenderer#box} and re-align all aligned child
25088             * elements.
25089             * @param  {number} width
25090             *         The new pixel width.
25091             * @param  {number} height
25092             *         The new pixel height.
25093             * @param  {Boolean|AnimationOptions} [animate=true]
25094             *         Whether and how to animate.
25095             */
25096            setSize: function(width, height, animate) {
25097                var renderer = this,
25098                    alignedObjects = renderer.alignedObjects,
25099                    i = alignedObjects.length;
25100
25101                renderer.width = width;
25102                renderer.height = height;
25103
25104                renderer.boxWrapper.animate({
25105                    width: width,
25106                    height: height
25107                }, {
25108                    step: function() {
25109                        this.attr({
25110                            viewBox: '0 0 ' + this.attr('width') + ' ' +
25111                                this.attr('height')
25112                        });
25113                    },
25114                    duration: pick(animate, true) ? undefined : 0
25115                });
25116
25117                while (i--) {
25118                    alignedObjects[i].align();
25119                }
25120            },
25121
25122            /**
25123             * Create and return an svg group element. Child
25124             * {@link Highcharts.SVGElement} objects are added to the group by using the
25125             * group as the first parameter
25126             * in {@link Highcharts.SVGElement#add|add()}.
25127             * 
25128             * @param {string} [name] The group will be given a class name of
25129             * `highcharts-{name}`. This can be used for styling and scripting.
25130             * @returns {SVGElement} The generated wrapper element.
25131             *
25132             * @sample highcharts/members/renderer-g/
25133             *         Show and hide grouped objects
25134             */
25135            g: function(name) {
25136                var elem = this.createElement('g');
25137                return name ? elem.attr({
25138                    'class': 'highcharts-' + name
25139                }) : elem;
25140            },
25141
25142            /**
25143             * Display an image.
25144             * @param {string} src The image source.
25145             * @param {number} [x] The X position.
25146             * @param {number} [y] The Y position.
25147             * @param {number} [width] The image width. If omitted, it defaults to the 
25148             *    image file width.
25149             * @param {number} [height] The image height. If omitted it defaults to the
25150             *    image file height.
25151             * @returns {SVGElement} The generated wrapper element.
25152             *
25153             * @sample highcharts/members/renderer-image-on-chart/
25154             *         Add an image in a chart
25155             * @sample highcharts/members/renderer-image/
25156             *         Add an image independent of a chart
25157             */
25158            image: function(src, x, y, width, height) {
25159                var attribs = {
25160                        preserveAspectRatio: 'none'
25161                    },
25162                    elemWrapper;
25163
25164                // optional properties
25165                if (arguments.length > 1) {
25166                    extend(attribs, {
25167                        x: x,
25168                        y: y,
25169                        width: width,
25170                        height: height
25171                    });
25172                }
25173
25174                elemWrapper = this.createElement('image').attr(attribs);
25175
25176                // set the href in the xlink namespace
25177                if (elemWrapper.element.setAttributeNS) {
25178                    elemWrapper.element.setAttributeNS('http://www.w3.org/1999/xlink',
25179                        'href', src);
25180                } else {
25181                    // could be exporting in IE
25182                    // using href throws "not supported" in ie7 and under, requries
25183                    // regex shim to fix later
25184                    elemWrapper.element.setAttribute('hc-svg-href', src);
25185                }
25186                return elemWrapper;
25187            },
25188
25189            /**
25190             * Draw a symbol out of pre-defined shape paths from
25191             * {@link SVGRenderer#symbols}.
25192             * It is used in Highcharts for point makers, which cake a `symbol` option,
25193             * and label and button backgrounds like in the tooltip and stock flags.
25194             *
25195             * @param {Symbol} symbol - The symbol name.
25196             * @param {number} x - The X coordinate for the top left position.
25197             * @param {number} y - The Y coordinate for the top left position.
25198             * @param {number} width - The pixel width.
25199             * @param {number} height - The pixel height.
25200             * @param {Object} [options] - Additional options, depending on the actual
25201             *    symbol drawn. 
25202             * @param {number} [options.anchorX] - The anchor X position for the
25203             *    `callout` symbol. This is where the chevron points to.
25204             * @param {number} [options.anchorY] - The anchor Y position for the
25205             *    `callout` symbol. This is where the chevron points to.
25206             * @param {number} [options.end] - The end angle of an `arc` symbol.
25207             * @param {boolean} [options.open] - Whether to draw `arc` symbol open or
25208             *    closed.
25209             * @param {number} [options.r] - The radius of an `arc` symbol, or the
25210             *    border radius for the `callout` symbol.
25211             * @param {number} [options.start] - The start angle of an `arc` symbol.
25212             */
25213            symbol: function(symbol, x, y, width, height, options) {
25214
25215                var ren = this,
25216                    obj,
25217                    imageRegex = /^url\((.*?)\)$/,
25218                    isImage = imageRegex.test(symbol),
25219                    sym = !isImage && (this.symbols[symbol] ? symbol : 'circle'),
25220
25221
25222                    // get the symbol definition function
25223                    symbolFn = sym && this.symbols[sym],
25224
25225                    // check if there's a path defined for this symbol
25226                    path = defined(x) && symbolFn && symbolFn.call(
25227                        this.symbols,
25228                        Math.round(x),
25229                        Math.round(y),
25230                        width,
25231                        height,
25232                        options
25233                    ),
25234                    imageSrc,
25235                    centerImage;
25236
25237                if (symbolFn) {
25238                    obj = this.path(path);
25239
25240
25241                    obj.attr('fill', 'none');
25242
25243
25244                    // expando properties for use in animate and attr
25245                    extend(obj, {
25246                        symbolName: sym,
25247                        x: x,
25248                        y: y,
25249                        width: width,
25250                        height: height
25251                    });
25252                    if (options) {
25253                        extend(obj, options);
25254                    }
25255
25256
25257                    // Image symbols
25258                } else if (isImage) {
25259
25260
25261                    imageSrc = symbol.match(imageRegex)[1];
25262
25263                    // Create the image synchronously, add attribs async
25264                    obj = this.image(imageSrc);
25265
25266                    // The image width is not always the same as the symbol width. The
25267                    // image may be centered within the symbol, as is the case when
25268                    // image shapes are used as label backgrounds, for example in flags.
25269                    obj.imgwidth = pick(
25270                        symbolSizes[imageSrc] && symbolSizes[imageSrc].width,
25271                        options && options.width
25272                    );
25273                    obj.imgheight = pick(
25274                        symbolSizes[imageSrc] && symbolSizes[imageSrc].height,
25275                        options && options.height
25276                    );
25277                    /**
25278                     * Set the size and position
25279                     */
25280                    centerImage = function() {
25281                        obj.attr({
25282                            width: obj.width,
25283                            height: obj.height
25284                        });
25285                    };
25286
25287                    /**
25288                     * Width and height setters that take both the image's physical size
25289                     * and the label size into consideration, and translates the image
25290                     * to center within the label.
25291                     */
25292                    each(['width', 'height'], function(key) {
25293                        obj[key + 'Setter'] = function(value, key) {
25294                            var attribs = {},
25295                                imgSize = this['img' + key],
25296                                trans = key === 'width' ? 'translateX' : 'translateY';
25297                            this[key] = value;
25298                            if (defined(imgSize)) {
25299                                if (this.element) {
25300                                    this.element.setAttribute(key, imgSize);
25301                                }
25302                                if (!this.alignByTranslate) {
25303                                    attribs[trans] = ((this[key] || 0) - imgSize) / 2;
25304                                    this.attr(attribs);
25305                                }
25306                            }
25307                        };
25308                    });
25309
25310
25311                    if (defined(x)) {
25312                        obj.attr({
25313                            x: x,
25314                            y: y
25315                        });
25316                    }
25317                    obj.isImg = true;
25318
25319                    if (defined(obj.imgwidth) && defined(obj.imgheight)) {
25320                        centerImage();
25321                    } else {
25322                        // Initialize image to be 0 size so export will still function
25323                        // if there's no cached sizes.
25324                        obj.attr({
25325                            width: 0,
25326                            height: 0
25327                        });
25328
25329                        // Create a dummy JavaScript image to get the width and height. 
25330                        createElement('img', {
25331                            onload: function() {
25332
25333                                var chart = charts[ren.chartIndex];
25334
25335                                // Special case for SVGs on IE11, the width is not
25336                                // accessible until the image is part of the DOM
25337                                // (#2854).
25338                                if (this.width === 0) {
25339                                    css(this, {
25340                                        position: 'absolute',
25341                                        top: '-999em'
25342                                    });
25343                                    doc.body.appendChild(this);
25344                                }
25345
25346                                // Center the image
25347                                symbolSizes[imageSrc] = { // Cache for next	
25348                                    width: this.width,
25349                                    height: this.height
25350                                };
25351                                obj.imgwidth = this.width;
25352                                obj.imgheight = this.height;
25353
25354                                if (obj.element) {
25355                                    centerImage();
25356                                }
25357
25358                                // Clean up after #2854 workaround.
25359                                if (this.parentNode) {
25360                                    this.parentNode.removeChild(this);
25361                                }
25362
25363                                // Fire the load event when all external images are
25364                                // loaded
25365                                ren.imgCount--;
25366                                if (!ren.imgCount && chart && chart.onload) {
25367                                    chart.onload();
25368                                }
25369                            },
25370                            src: imageSrc
25371                        });
25372                        this.imgCount++;
25373                    }
25374                }
25375
25376                return obj;
25377            },
25378
25379            /**
25380             * @typedef {string} Symbol
25381             * 
25382             * Can be one of `arc`, `callout`, `circle`, `diamond`, `square`,
25383             * `triangle`, `triangle-down`. Symbols are used internally for point
25384             * markers, button and label borders and backgrounds, or custom shapes.
25385             * Extendable by adding to {@link SVGRenderer#symbols}.
25386             */
25387            /**
25388             * An extendable collection of functions for defining symbol paths.
25389             */
25390            symbols: {
25391                'circle': function(x, y, w, h) {
25392                    // Return a full arc
25393                    return this.arc(x + w / 2, y + h / 2, w / 2, h / 2, {
25394                        start: 0,
25395                        end: Math.PI * 2,
25396                        open: false
25397                    });
25398                },
25399
25400                'square': function(x, y, w, h) {
25401                    return [
25402                        'M', x, y,
25403                        'L', x + w, y,
25404                        x + w, y + h,
25405                        x, y + h,
25406                        'Z'
25407                    ];
25408                },
25409
25410                'triangle': function(x, y, w, h) {
25411                    return [
25412                        'M', x + w / 2, y,
25413                        'L', x + w, y + h,
25414                        x, y + h,
25415                        'Z'
25416                    ];
25417                },
25418
25419                'triangle-down': function(x, y, w, h) {
25420                    return [
25421                        'M', x, y,
25422                        'L', x + w, y,
25423                        x + w / 2, y + h,
25424                        'Z'
25425                    ];
25426                },
25427                'diamond': function(x, y, w, h) {
25428                    return [
25429                        'M', x + w / 2, y,
25430                        'L', x + w, y + h / 2,
25431                        x + w / 2, y + h,
25432                        x, y + h / 2,
25433                        'Z'
25434                    ];
25435                },
25436                'arc': function(x, y, w, h, options) {
25437                    var start = options.start,
25438                        rx = options.r || w,
25439                        ry = options.r || h || w,
25440                        proximity = 0.001,
25441                        fullCircle =
25442                        Math.abs(options.end - options.start - 2 * Math.PI) <
25443                        proximity,
25444                        // Substract a small number to prevent cos and sin of start and
25445                        // end from becoming equal on 360 arcs (related: #1561)
25446                        end = options.end - proximity,
25447                        innerRadius = options.innerR,
25448                        open = pick(options.open, fullCircle),
25449                        cosStart = Math.cos(start),
25450                        sinStart = Math.sin(start),
25451                        cosEnd = Math.cos(end),
25452                        sinEnd = Math.sin(end),
25453                        // Proximity takes care of rounding errors around PI (#6971)
25454                        longArc = options.end - start - Math.PI < proximity ? 0 : 1,
25455                        arc;
25456
25457                    arc = [
25458                        'M',
25459                        x + rx * cosStart,
25460                        y + ry * sinStart,
25461                        'A', // arcTo
25462                        rx, // x radius
25463                        ry, // y radius
25464                        0, // slanting
25465                        longArc, // long or short arc
25466                        1, // clockwise
25467                        x + rx * cosEnd,
25468                        y + ry * sinEnd
25469                    ];
25470
25471                    if (defined(innerRadius)) {
25472                        arc.push(
25473                            open ? 'M' : 'L',
25474                            x + innerRadius * cosEnd,
25475                            y + innerRadius * sinEnd,
25476                            'A', // arcTo
25477                            innerRadius, // x radius
25478                            innerRadius, // y radius
25479                            0, // slanting
25480                            longArc, // long or short arc
25481                            0, // clockwise
25482                            x + innerRadius * cosStart,
25483                            y + innerRadius * sinStart
25484                        );
25485                    }
25486
25487                    arc.push(open ? '' : 'Z'); // close
25488                    return arc;
25489                },
25490
25491                /**
25492                 * Callout shape used for default tooltips, also used for rounded
25493                 * rectangles in VML
25494                 */
25495                callout: function(x, y, w, h, options) {
25496                    var arrowLength = 6,
25497                        halfDistance = 6,
25498                        r = Math.min((options && options.r) || 0, w, h),
25499                        safeDistance = r + halfDistance,
25500                        anchorX = options && options.anchorX,
25501                        anchorY = options && options.anchorY,
25502                        path;
25503
25504                    path = [
25505                        'M', x + r, y,
25506                        'L', x + w - r, y, // top side
25507                        'C', x + w, y, x + w, y, x + w, y + r, // top-right corner
25508                        'L', x + w, y + h - r, // right side
25509                        'C', x + w, y + h, x + w, y + h, x + w - r, y + h, // bottom-rgt
25510                        'L', x + r, y + h, // bottom side
25511                        'C', x, y + h, x, y + h, x, y + h - r, // bottom-left corner
25512                        'L', x, y + r, // left side
25513                        'C', x, y, x, y, x + r, y // top-left corner
25514                    ];
25515
25516                    // Anchor on right side
25517                    if (anchorX && anchorX > w) {
25518
25519                        // Chevron
25520                        if (
25521                            anchorY > y + safeDistance &&
25522                            anchorY < y + h - safeDistance
25523                        ) {
25524                            path.splice(13, 3,
25525                                'L', x + w, anchorY - halfDistance,
25526                                x + w + arrowLength, anchorY,
25527                                x + w, anchorY + halfDistance,
25528                                x + w, y + h - r
25529                            );
25530
25531                            // Simple connector
25532                        } else {
25533                            path.splice(13, 3,
25534                                'L', x + w, h / 2,
25535                                anchorX, anchorY,
25536                                x + w, h / 2,
25537                                x + w, y + h - r
25538                            );
25539                        }
25540
25541                        // Anchor on left side
25542                    } else if (anchorX && anchorX < 0) {
25543
25544                        // Chevron
25545                        if (
25546                            anchorY > y + safeDistance &&
25547                            anchorY < y + h - safeDistance
25548                        ) {
25549                            path.splice(33, 3,
25550                                'L', x, anchorY + halfDistance,
25551                                x - arrowLength, anchorY,
25552                                x, anchorY - halfDistance,
25553                                x, y + r
25554                            );
25555
25556                            // Simple connector
25557                        } else {
25558                            path.splice(33, 3,
25559                                'L', x, h / 2,
25560                                anchorX, anchorY,
25561                                x, h / 2,
25562                                x, y + r
25563                            );
25564                        }
25565
25566                    } else if ( // replace bottom
25567                        anchorY &&
25568                        anchorY > h &&
25569                        anchorX > x + safeDistance &&
25570                        anchorX < x + w - safeDistance
25571                    ) {
25572                        path.splice(23, 3,
25573                            'L', anchorX + halfDistance, y + h,
25574                            anchorX, y + h + arrowLength,
25575                            anchorX - halfDistance, y + h,
25576                            x + r, y + h
25577                        );
25578
25579                    } else if ( // replace top
25580                        anchorY &&
25581                        anchorY < 0 &&
25582                        anchorX > x + safeDistance &&
25583                        anchorX < x + w - safeDistance
25584                    ) {
25585                        path.splice(3, 3,
25586                            'L', anchorX - halfDistance, y,
25587                            anchorX, y - arrowLength,
25588                            anchorX + halfDistance, y,
25589                            w - r, y
25590                        );
25591                    }
25592
25593                    return path;
25594                }
25595            },
25596
25597            /**
25598             * @typedef {SVGElement} ClipRect - A clipping rectangle that can be applied
25599             * to one or more {@link SVGElement} instances. It is instanciated with the
25600             * {@link SVGRenderer#clipRect} function and applied with the {@link 
25601             * SVGElement#clip} function.
25602             *
25603             * @example
25604             * var circle = renderer.circle(100, 100, 100)
25605             *     .attr({ fill: 'red' })
25606             *     .add();
25607             * var clipRect = renderer.clipRect(100, 100, 100, 100);
25608             *
25609             * // Leave only the lower right quarter visible
25610             * circle.clip(clipRect);
25611             */
25612            /**
25613             * Define a clipping rectangle. The clipping rectangle is later applied
25614             * to {@link SVGElement} objects through the {@link SVGElement#clip}
25615             * function.
25616             * 
25617             * @param {String} id
25618             * @param {number} x
25619             * @param {number} y
25620             * @param {number} width
25621             * @param {number} height
25622             * @returns {ClipRect} A clipping rectangle.
25623             *
25624             * @example
25625             * var circle = renderer.circle(100, 100, 100)
25626             *     .attr({ fill: 'red' })
25627             *     .add();
25628             * var clipRect = renderer.clipRect(100, 100, 100, 100);
25629             *
25630             * // Leave only the lower right quarter visible
25631             * circle.clip(clipRect);
25632             */
25633            clipRect: function(x, y, width, height) {
25634                var wrapper,
25635                    id = H.uniqueKey(),
25636
25637                    clipPath = this.createElement('clipPath').attr({
25638                        id: id
25639                    }).add(this.defs);
25640
25641                wrapper = this.rect(x, y, width, height, 0).add(clipPath);
25642                wrapper.id = id;
25643                wrapper.clipPath = clipPath;
25644                wrapper.count = 0;
25645
25646                return wrapper;
25647            },
25648
25649
25650
25651
25652
25653            /**
25654             * Draw text. The text can contain a subset of HTML, like spans and anchors
25655             * and some basic text styling of these. For more advanced features like
25656             * border and background, use {@link Highcharts.SVGRenderer#label} instead.
25657             * To update the text after render, run `text.attr({ text: 'New text' })`.
25658             * @param  {String} str
25659             *         The text of (subset) HTML to draw.
25660             * @param  {number} x
25661             *         The x position of the text's lower left corner.
25662             * @param  {number} y
25663             *         The y position of the text's lower left corner.
25664             * @param  {Boolean} [useHTML=false]
25665             *         Use HTML to render the text.
25666             *
25667             * @return {SVGElement} The text object.
25668             *
25669             * @sample highcharts/members/renderer-text-on-chart/
25670             *         Annotate the chart freely
25671             * @sample highcharts/members/renderer-on-chart/
25672             *         Annotate with a border and in response to the data
25673             * @sample highcharts/members/renderer-text/
25674             *         Formatted text
25675             */
25676            text: function(str, x, y, useHTML) {
25677
25678                // declare variables
25679                var renderer = this,
25680                    wrapper,
25681                    attribs = {};
25682
25683                if (useHTML && (renderer.allowHTML || !renderer.forExport)) {
25684                    return renderer.html(str, x, y);
25685                }
25686
25687                attribs.x = Math.round(x || 0); // X always needed for line-wrap logic
25688                if (y) {
25689                    attribs.y = Math.round(y);
25690                }
25691                if (str || str === 0) {
25692                    attribs.text = str;
25693                }
25694
25695                wrapper = renderer.createElement('text')
25696                    .attr(attribs);
25697
25698                if (!useHTML) {
25699                    wrapper.xSetter = function(value, key, element) {
25700                        var tspans = element.getElementsByTagName('tspan'),
25701                            tspan,
25702                            parentVal = element.getAttribute(key),
25703                            i;
25704                        for (i = 0; i < tspans.length; i++) {
25705                            tspan = tspans[i];
25706                            // If the x values are equal, the tspan represents a
25707                            // linebreak
25708                            if (tspan.getAttribute(key) === parentVal) {
25709                                tspan.setAttribute(key, value);
25710                            }
25711                        }
25712                        element.setAttribute(key, value);
25713                    };
25714                }
25715
25716                return wrapper;
25717            },
25718
25719            /**
25720             * Utility to return the baseline offset and total line height from the font
25721             * size.
25722             *
25723             * @param {?string} fontSize The current font size to inspect. If not given,
25724             *   the font size will be found from the DOM element.
25725             * @param {SVGElement|SVGDOMElement} [elem] The element to inspect for a
25726             *   current font size.
25727             * @returns {Object}
25727 An object containing `h`: the line height, `b`: the
25728             * baseline relative to the top of the box, and `f`: the font size.
25729             */
25730            fontMetrics: function(fontSize, elem) {
25731                var lineHeight,
25732                    baseline;
25733
25734
25735                fontSize = fontSize ||
25736                    // When the elem is a DOM element (#5932)
25737                    (elem && elem.style && elem.style.fontSize) ||
25738                    // Fall back on the renderer style default
25739                    (this.style && this.style.fontSize);
25740
25741
25742
25743                // Handle different units
25744                if (/px/.test(fontSize)) {
25745                    fontSize = pInt(fontSize);
25746                } else if (/em/.test(fontSize)) {
25747                    // The em unit depends on parent items
25748                    fontSize = parseFloat(fontSize) *
25749                        (elem ? this.fontMetrics(null, elem.parentNode).f : 16);
25750                } else {
25751                    fontSize = 12;
25752                }
25753
25754                // Empirical values found by comparing font size and bounding box
25755                // height. Applies to the default font family.
25756                // http://jsfiddle.net/highcharts/7xvn7/
25757                lineHeight = fontSize < 24 ? fontSize + 3 : Math.round(fontSize * 1.2);
25758                baseline = Math.round(lineHeight * 0.8);
25759
25760                return {
25761                    h: lineHeight,
25762                    b: baseline,
25763                    f: fontSize
25764                };
25765            },
25766
25767            /**
25768             * Correct X and Y positioning of a label for rotation (#1764).
25769             *
25770             * @private
25771             */
25772            rotCorr: function(baseline, rotation, alterY) {
25773                var y = baseline;
25774                if (rotation && alterY) {
25775                    y = Math.max(y * Math.cos(rotation * deg2rad), 4);
25776                }
25777                return {
25778                    x: (-baseline / 3) * Math.sin(rotation * deg2rad),
25779                    y: y
25780                };
25781            },
25782
25783            /**
25784             * Draw a label, which is an extended text element with support for border
25785             * and background. Highcharts creates a `g` element with a text and a `path`
25786             * or `rect` inside, to make it behave somewhat like a HTML div. Border and
25787             * background are set through `stroke`, `stroke-width` and `fill` attributes
25788             * using the {@link Highcharts.SVGElement#attr|attr} method. To update the
25789             * text after render, run `label.attr({ text: 'New text' })`.
25790             * 
25791             * @param  {string} str
25792             *         The initial text string or (subset) HTML to render.
25793             * @param  {number} x
25794             *         The x position of the label's left side.
25795             * @param  {number} y
25796             *         The y position of the label's top side or baseline, depending on
25797             *         the `baseline` parameter.
25798             * @param  {String} shape
25799             *         The shape of the label's border/background, if any. Defaults to
25800             *         `rect`. Other possible values are `callout` or other shapes
25801             *         defined in {@link Highcharts.SVGRenderer#symbols}.
25802             * @param  {number} anchorX
25803             *         In case the `shape` has a pointer, like a flag, this is the
25804             *         coordinates it should be pinned to.
25805             * @param  {number} anchorY
25806             *         In case the `shape` has a pointer, like a flag, this is the
25807             *         coordinates it should be pinned to.
25808             * @param  {Boolean} baseline
25809             *         Whether to position the label relative to the text baseline,
25810             *	       like {@link Highcharts.SVGRenderer#text|renderer.text}, or to the
25811             *	       upper border of the rectangle.
25812             * @param  {String} className
25813             *         Class name for the group.
25814             *
25815             * @return {SVGElement}
25816             *         The generated label.
25817             *
25818             * @sample highcharts/members/renderer-label-on-chart/
25819             *         A label on the chart
25820             */
25821            label: function(
25822                str,
25823                x,
25824                y,
25825                shape,
25826                anchorX,
25827                anchorY,
25828                useHTML,
25829                baseline,
25830                className
25831            ) {
25832
25833                var renderer = this,
25834                    wrapper = renderer.g(className !== 'button' && 'label'),
25835                    text = wrapper.text = renderer.text('', 0, 0, useHTML)
25836                    .attr({
25837                        zIndex: 1
25838                    }),
25839                    box,
25840                    bBox,
25841                    alignFactor = 0,
25842                    padding = 3,
25843                    paddingLeft = 0,
25844                    width,
25845                    height,
25846                    wrapperX,
25847                    wrapperY,
25848                    textAlign,
25849                    deferredAttr = {},
25850                    strokeWidth,
25851                    baselineOffset,
25852                    hasBGImage = /^url\((.*?)\)$/.test(shape),
25853                    needsBox = hasBGImage,
25854                    getCrispAdjust,
25855                    updateBoxSize,
25856                    updateTextPadding,
25857                    boxAttr;
25858
25859                if (className) {
25860                    wrapper.addClass('highcharts-' + className);
25861                }
25862
25863
25864                needsBox = hasBGImage;
25865                getCrispAdjust = function() {
25866                    return (strokeWidth || 0) % 2 / 2;
25867                };
25868
25869
25870
25871                /**
25872                 * This function runs after the label is added to the DOM (when the
25873                 * bounding box is available), and after the text of the label is
25874                 * updated to detect the new bounding box and reflect it in the border
25875                 * box.
25876                 */
25877                updateBoxSize = function() {
25878                    var style = text.element.style,
25879                        crispAdjust,
25880                        attribs = {};
25881
25882                    bBox = (
25883                        (width === undefined || height === undefined || textAlign) &&
25884                        defined(text.textStr) &&
25885                        text.getBBox()
25886                    ); // #3295 && 3514 box failure when string equals 0
25887                    wrapper.width = (
25888                        (width || bBox.width || 0) +
25889                        2 * padding +
25890                        paddingLeft
25891                    );
25892                    wrapper.height = (height || bBox.height || 0) + 2 * padding;
25893
25894                    // Update the label-scoped y offset
25895                    baselineOffset = padding +
25896                        renderer.fontMetrics(style && style.fontSize, text).b;
25897
25898
25899                    if (needsBox) {
25900
25901                        // Create the border box if it is not already present
25902                        if (!box) {
25903                            // Symbol definition exists (#5324)
25904                            wrapper.box = box = renderer.symbols[shape] || hasBGImage ?
25905                                renderer.symbol(shape) :
25906                                renderer.rect();
25907
25908                            box.addClass( // Don't use label className for buttons
25909                                (className === 'button' ? '' : 'highcharts-label-box') +
25910                                (className ? ' highcharts-' + className + '-box' : '')
25911                            );
25912
25913                            box.add(wrapper);
25914
25915                            crispAdjust = getCrispAdjust();
25916                            attribs.x = crispAdjust;
25917                            attribs.y = (baseline ? -baselineOffset : 0) + crispAdjust;
25918                        }
25919
25920                        // Apply the box attributes
25921                        attribs.width = Math.round(wrapper.width);
25922                        attribs.height = Math.round(wrapper.height);
25923
25924                        box.attr(extend(attribs, deferredAttr));
25925                        deferredAttr = {};
25926                    }
25927                };
25928
25929                /**
25930                 * This function runs after setting text or padding, but only if padding
25931                 * is changed
25932                 */
25933                updateTextPadding = function() {
25934                    var textX = paddingLeft + padding,
25935                        textY;
25936
25937                    // determin y based on the baseline
25938                    textY = baseline ? 0 : baselineOffset;
25939
25940                    // compensate for alignment
25941                    if (
25942                        defined(width) &&
25943                        bBox &&
25944                        (textAlign === 'center' || textAlign === 'right')
25945                    ) {
25946                        textX += {
25947                                center: 0.5,
25948                                right: 1
25949                            }[textAlign] *
25950                            (width - bBox.width);
25951                    }
25952
25953                    // update if anything changed
25954                    if (textX !== text.x || textY !== text.y) {
25955                        text.attr('x', textX);
25956                        if (textY !== undefined) {
25957                            text.attr('y', textY);
25958                        }
25959                    }
25960
25961                    // record current values
25962                    text.x = textX;
25963                    text.y = textY;
25964                };
25965
25966                /**
25967                 * Set a box attribute, or defer it if the box is not yet created
25968                 * @param {Object} key
25969                 * @param {Object} value
25970                 */
25971                boxAttr = function(key, value) {
25972                    if (box) {
25973                        box.attr(key, value);
25974                    } else {
25975                        deferredAttr[key] = value;
25976                    }
25977                };
25978
25979                /**
25980                 * After the text element is added, get the desired size of the border
25981                 * box and add it before the text in the DOM.
25982                 */
25983                wrapper.onAdd = function() {
25984                    text.add(wrapper);
25985                    wrapper.attr({
25986                        // Alignment is available now  (#3295, 0 not rendered if given
25987                        // as a value)
25988                        text: (str || str === 0) ? str : '',
25989                        x: x,
25990                        y: y
25991                    });
25992
25993                    if (box && defined(anchorX)) {
25994                        wrapper.attr({
25995                            anchorX: anchorX,
25996                            anchorY: anchorY
25997                        });
25998                    }
25999                };
26000
26001                /*
26002                 * Add specific attribute setters.
26003                 */
26004
26005                // only change local variables
26006                wrapper.widthSetter = function(value) {
26007                    width = H.isNumber(value) ? value : null; // width:auto => null
26008                };
26009                wrapper.heightSetter = function(value) {
26010                    height = value;
26011                };
26012                wrapper['text-alignSetter'] = function(value) {
26013                    textAlign = value;
26014                };
26015                wrapper.paddingSetter = function(value) {
26016                    if (defined(value) && value !== padding) {
26017                        padding = wrapper.padding = value;
26018                        updateTextPadding();
26019                    }
26020                };
26021                wrapper.paddingLeftSetter = function(value) {
26022                    if (defined(value) && value !== paddingLeft) {
26023                        paddingLeft = value;
26024                        updateTextPadding();
26025                    }
26026                };
26027
26028
26029                // change local variable and prevent setting attribute on the group
26030                wrapper.alignSetter = function(value) {
26031                    value = {
26032                        left: 0,
26033                        center: 0.5,
26034                        right: 1
26035                    }[value];
26036                    if (value !== alignFactor) {
26037                        alignFactor = value;
26038                        // Bounding box exists, means we're dynamically changing
26039                        if (bBox) {
26040                            wrapper.attr({
26041                                x: wrapperX
26042                            }); // #5134
26043                        }
26044                    }
26045                };
26046
26047                // apply these to the box and the text alike
26048                wrapper.textSetter = function(value) {
26049                    if (value !== undefined) {
26050                        text.textSetter(value);
26051                    }
26052                    updateBoxSize();
26053                    updateTextPadding();
26054                };
26055
26056                // apply these to the box but not to the text
26057                wrapper['stroke-widthSetter'] = function(value, key) {
26058                    if (value) {
26059                        needsBox = true;
26060                    }
26061                    strokeWidth = this['stroke-width'] = value;
26062                    boxAttr(key, value);
26063                };
26064
26065                wrapper.strokeSetter =
26066                    wrapper.fillSetter =
26067                    wrapper.rSetter = function(value, key) {
26068                        if (key !== 'r') {
26069                            if (key === 'fill' && value) {
26070                                needsBox = true;
26071                            }
26072                            // for animation getter (#6776)
26073                            wrapper[key] = value;
26074                        }
26075                        boxAttr(key, value);
26076                    };
26077
26078                wrapper.anchorXSetter = function(value, key) {
26079                    anchorX = wrapper.anchorX = value;
26080                    boxAttr(key, Math.round(value) - getCrispAdjust() - wrapperX);
26081                };
26082                wrapper.anchorYSetter = function(value, key) {
26083                    anchorY = wrapper.anchorY = value;
26084                    boxAttr(key, value - wrapperY);
26085                };
26086
26087                // rename attributes
26088                wrapper.xSetter = function(value) {
26089                    wrapper.x = value; // for animation getter
26090                    if (alignFactor) {
26091                        value -= alignFactor * ((width || bBox.width) + 2 * padding);
26092                    }
26093                    wrapperX = Math.round(value);
26094                    wrapper.attr('translateX', wrapperX);
26095                };
26096                wrapper.ySetter = function(value) {
26097                    wrapperY = wrapper.y = Math.round(value);
26098                    wrapper.attr('translateY', wrapperY);
26099                };
26100
26101                // Redirect certain methods to either the box or the text
26102                var baseCss = wrapper.css;
26103                return extend(wrapper, {
26104                    /**
26105                     * Pick up some properties and apply them to the text instead of the
26106                     * wrapper.
26107                     * @ignore
26108                     */
26109                    css: function(styles) {
26110                        if (styles) {
26111                            var textStyles = {};
26112                            // Create a copy to avoid altering the original object
26113                            // (#537)
26114                            styles = merge(styles);
26115                            each(wrapper.textProps, function(prop) {
26116                                if (styles[prop] !== undefined) {
26117                                    textStyles[prop] = styles[prop];
26118                                    delete styles[prop];
26119                                }
26120                            });
26121                            text.css(textStyles);
26122                        }
26123                        return baseCss.call(wrapper, styles);
26124                    },
26125                    /**
26126                     * Return the bounding box of the box, not the group.
26127                     * @ignore
26128                     */
26129                    getBBox: function() {
26130                        return {
26131                            width: bBox.width + 2 * padding,
26132                            height: bBox.height + 2 * padding,
26133                            x: bBox.x - padding,
26134                            y: bBox.y - padding
26135                        };
26136                    },
26137
26138                    /**
26139                     * Apply the shadow to the box.
26140                     * @ignore
26141                     */
26142                    shadow: function(b) {
26143                        if (b) {
26144                            updateBoxSize();
26145                            if (box) {
26146                                box.shadow(b);
26147                            }
26148                        }
26149                        return wrapper;
26150                    },
26151
26152                    /**
26153                     * Destroy and release memory.
26154                     * @ignore
26155                     */
26156                    destroy: function() {
26157
26158                        // Added by button implementation
26159                        removeEvent(wrapper.element, 'mouseenter');
26160                        removeEvent(wrapper.element, 'mouseleave');
26161
26162                        if (text) {
26163                            text = text.destroy();
26164                        }
26165                        if (box) {
26166                            box = box.destroy();
26167                        }
26168                        // Call base implementation to destroy the rest
26169                        SVGElement.prototype.destroy.call(wrapper);
26170
26171                        // Release local pointers (#1298)
26172                        wrapper =
26173                            renderer =
26174                            updateBoxSize =
26175                            updateTextPadding =
26176                            boxAttr = null;
26177                    }
26178                });
26179            }
26180        }); // end SVGRenderer
26181
26182
26183        // general renderer
26184        H.Renderer = SVGRenderer;
26185
26186    }
26186(Highcharts));
26187    (function(H) {
26188        /**
26189         * (c) 2010-2017 Torstein Honsi
26190         *
26191         * License: www.highcharts.com/license
26192         */
26193        /* eslint max-len: ["warn", 80, 4] */
26194        var attr = H.attr,
26195            createElement = H.createElement,
26196            css = H.css,
26197            defined = H.defined,
26198            each = H.each,
26199            extend = H.extend,
26200            isFirefox = H.isFirefox,
26201            isMS = H.isMS,
26202            isWebKit = H.isWebKit,
26203            pick = H.pick,
26204            pInt = H.pInt,
26205            SVGElement = H.SVGElement,
26206            SVGRenderer = H.SVGRenderer,
26207            win = H.win,
26208            wrap = H.wrap;
26209
26210        // Extend SvgElement for useHTML option
26211        extend(SVGElement.prototype, /** @lends SVGElement.prototype */ {
26212            /**
26213             * Apply CSS to HTML elements. This is used in text within SVG rendering and
26214             * by the VML renderer
26215             */
26216            htmlCss: function(styles) {
26217                var wrapper = this,
26218                    element = wrapper.element,
26219                    textWidth = styles && element.tagName === 'SPAN' && styles.width;
26220
26221                if (textWidth) {
26222                    delete styles.width;
26223                    wrapper.textWidth = textWidth;
26224                    wrapper.updateTransform();
26225                }
26226                if (styles && styles.textOverflow === 'ellipsis') {
26227                    styles.whiteSpace = 'nowrap';
26228                    styles.overflow = 'hidden';
26229                }
26230                wrapper.styles = extend(wrapper.styles, styles);
26231                css(wrapper.element, styles);
26232
26233                return wrapper;
26234            },
26235
26236            /**
26237             * VML and useHTML method for calculating the bounding box based on offsets
26238             * @param {Boolean} refresh Whether to force a fresh value from the DOM or
26239             * to use the cached value.
26240             *
26241             * @return {Object} A hash containing values for x, y, width and height
26242             */
26243
26244            htmlGetBBox: function() {
26245                var wrapper = this,
26246                    element = wrapper.element;
26247
26248                return {
26249                    x: element.offsetLeft,
26250                    y: element.offsetTop,
26251                    width: element.offsetWidth,
26252                    height: element.offsetHeight
26253                };
26254            },
26255
26256            /**
26257             * VML override private method to update elements based on internal
26258             * properties based on SVG transform
26259             */
26260            htmlUpdateTransform: function() {
26261                // aligning non added elements is expensive
26262                if (!this.added) {
26263                    this.alignOnAdd = true;
26264                    return;
26265                }
26266
26267                var wrapper = this,
26268                    renderer = wrapper.renderer,
26269                    elem = wrapper.element,
26270                    translateX = wrapper.translateX || 0,
26271                    translateY = wrapper.translateY || 0,
26272                    x = wrapper.x || 0,
26273                    y = wrapper.y || 0,
26274                    align = wrapper.textAlign || 'left',
26275                    alignCorrection = {
26276                        left: 0,
26277                        center: 0.5,
26278                        right: 1
26279                    }[align],
26280                    styles = wrapper.styles;
26281
26282                // apply translate
26283                css(elem, {
26284                    marginLeft: translateX,
26285                    marginTop: translateY
26286                });
26287
26288
26289                if (wrapper.shadows) { // used in labels/tooltip
26290                    each(wrapper.shadows, function(shadow) {
26291                        css(shadow, {
26292                            marginLeft: translateX + 1,
26293                            marginTop: translateY + 1
26294                        });
26295                    });
26296                }
26297
26298
26299                // apply inversion
26300                if (wrapper.inverted) { // wrapper is a group
26301                    each(elem.childNodes, function(child) {
26302                        renderer.invertChild(child, elem);
26303                    });
26304                }
26305
26306                if (elem.tagName === 'SPAN') {
26307
26308                    var rotation = wrapper.rotation,
26309                        baseline,
26310                        textWidth = pInt(wrapper.textWidth),
26311                        whiteSpace = styles && styles.whiteSpace,
26312                        currentTextTransform = [
26313                            rotation,
26314                            align,
26315                            elem.innerHTML,
26316                            wrapper.textWidth,
26317                            wrapper.textAlign
26318                        ].join(',');
26319
26320                    // Do the calculations and DOM access only if properties changed
26321                    if (currentTextTransform !== wrapper.cTT) {
26322
26323
26324                        baseline = renderer.fontMetrics(elem.style.fontSize).b;
26325
26326                        // Renderer specific handling of span rotation
26327                        if (defined(rotation)) {
26328                            wrapper.setSpanRotation(
26329                                rotation,
26330                                alignCorrection,
26331                                baseline
26332                            );
26333                        }
26334
26335                        // Reset multiline/ellipsis in order to read width (#4928,
26336                        // #5417)
26337                        css(elem, {
26338                            width: '',
26339                            whiteSpace: whiteSpace || 'nowrap'
26340                        });
26341
26342                        // Update textWidth
26343                        if (
26344                            elem.offsetWidth > textWidth &&
26345                            /[ \-]/.test(elem.textContent || elem.innerText)
26346                        ) { // #983, #1254
26347                            css(elem, {
26348                                width: textWidth + 'px',
26349                                display: 'block',
26350                                whiteSpace: whiteSpace || 'normal' // #3331
26351                            });
26352                        }
26353
26354
26355                        wrapper.getSpanCorrection(
26356                            elem.offsetWidth,
26357                            baseline,
26358                            alignCorrection,
26359                            rotation,
26360                            align
26361                        );
26362                    }
26363
26364                    // apply position with correction
26365                    css(elem, {
26366                        left: (x + (wrapper.xCorr || 0)) + 'px',
26367                        top: (y + (wrapper.yCorr || 0)) + 'px'
26368                    });
26369
26370                    // Force reflow in webkit to apply the left and top on useHTML
26371                    // element (#1249)
26372                    if (isWebKit) {
26373                        // Assigned to baseline for lint purpose
26374                        baseline = elem.offsetHeight;
26375                    }
26376
26377                    // record current text transform
26378                    wrapper.cTT = currentTextTransform;
26379                }
26380            },
26381
26382            /**
26383             * Set the rotation of an individual HTML span
26384             */
26385            setSpanRotation: function(rotation, alignCorrection, baseline) {
26386                var rotationStyle = {},
26387                    cssTransformKey = this.renderer.getTransformKey();
26388
26389                rotationStyle[cssTransformKey] = rotationStyle.transform =
26390                    'rotate(' + rotation + 'deg)';
26391                rotationStyle[cssTransformKey + (isFirefox ? 'Origin' : '-origin')] =
26392                    rotationStyle.transformOrigin =
26393                    (alignCorrection * 100) + '% ' + baseline + 'px';
26394                css(this.element, rotationStyle);
26395            },
26396
26397            /**
26398             * Get the correction in X and Y positioning as the element is rotated.
26399             */
26400            getSpanCorrection: function(width, baseline, alignCorrection) {
26401                this.xCorr = -width * alignCorrection;
26402                this.yCorr = -baseline;
26403            }
26404        });
26405
26406        // Extend SvgRenderer for useHTML option.
26407        extend(SVGRenderer.prototype, /** @lends SVGRenderer.prototype */ {
26408
26409            getTransformKey: function() {
26410                return isMS && !/Edge/.test(win.navigator.userAgent) ?
26411                    '-ms-transform' :
26412                    isWebKit ?
26413                    '-webkit-transform' :
26414                    isFirefox ?
26415                    'MozTransform' :
26416                    win.opera ?
26417                    '-o-transform' :
26418                    '';
26419            },
26420
26421            /**
26422             * Create HTML text node. This is used by the VML renderer as well as the
26423             * SVG renderer through the useHTML option.
26424             *
26425             * @param {String} str
26426             * @param {Number} x
26427             * @param {Number} y
26428             */
26429            html: function(str, x, y) {
26430                var wrapper = this.createElement('span'),
26431                    element = wrapper.element,
26432                    renderer = wrapper.renderer,
26433                    isSVG = renderer.isSVG,
26434                    addSetters = function(element, style) {
26435                        // These properties are set as attributes on the SVG group, and
26436                        // as identical CSS properties on the div. (#3542)
26437                        each(['opacity', 'visibility'], function(prop) {
26438                            wrap(element, prop + 'Setter', function(
26439                                proceed,
26440                                value,
26441                                key,
26442                                elem
26443                            ) {
26444                                proceed.call(this, value, key, elem);
26445                                style[key] = value;
26446                            });
26447                        });
26448                    };
26449
26450                // Text setter
26451                wrapper.textSetter = function(value) {
26452                    if (value !== element.innerHTML) {
26453                        delete this.bBox;
26454                    }
26455                    this.textStr = value;
26456                    element.innerHTML = pick(value, '');
26457                    wrapper.htmlUpdateTransform();
26458                };
26459
26460                // Add setters for the element itself (#4938)
26461                if (isSVG) { // #4938, only for HTML within SVG
26462                    addSetters(wrapper, wrapper.element.style);
26463                }
26464
26465                // Various setters which rely on update transform
26466                wrapper.xSetter =
26467                    wrapper.ySetter =
26468                    wrapper.alignSetter =
26469                    wrapper.rotationSetter =
26470                    function(value, key) {
26471                        if (key === 'align') {
26472                            // Do not overwrite the SVGElement.align method. Same as VML.
26473                            key = 'textAlign';
26474                        }
26475                        wrapper[key] = value;
26476                        wrapper.htmlUpdateTransform();
26477                    };
26478
26479                // Set the default attributes
26480                wrapper
26481                    .attr({
26482                        text: str,
26483                        x: Math.round(x),
26484                        y: Math.round(y)
26485                    })
26486                    .css({
26487
26488                        fontFamily: this.style.fontFamily,
26489                        fontSize: this.style.fontSize,
26490
26491                        position: 'absolute'
26492                    });
26493
26494                // Keep the whiteSpace style outside the wrapper.styles collection
26495                element.style.whiteSpace = 'nowrap';
26496
26497                // Use the HTML specific .css method
26498                wrapper.css = wrapper.htmlCss;
26499
26500                // This is specific for HTML within SVG
26501                if (isSVG) {
26502                    wrapper.add = function(svgGroupWrapper) {
26503
26504                        var htmlGroup,
26505                            container = renderer.box.parentNode,
26506                            parentGroup,
26507                            parents = [];
26508
26509                        this.parentGroup = svgGroupWrapper;
26510
26511                        // Create a mock group to hold the HTML elements
26512                        if (svgGroupWrapper) {
26513                            htmlGroup = svgGroupWrapper.div;
26514                            if (!htmlGroup) {
26515
26516                                // Read the parent chain into an array and read from top
26517                                // down
26518                                parentGroup = svgGroupWrapper;
26519                                while (parentGroup) {
26520
26521                                    parents.push(parentGroup);
26522
26523                                    // Move up to the next parent group
26524                                    parentGroup = parentGroup.parentGroup;
26525                                }
26526
26527                                // Ensure dynamically updating position when any parent
26528                                // is translated
26529                                each(parents.reverse(), function(parentGroup) {
26530                                    var htmlGroupStyle,
26531                                        cls = attr(parentGroup.element, 'class');
26532
26533                                    // Common translate setter for X and Y on the HTML
26534                                    // group. Using CSS transform instead of left and
26535                                    // right prevents flickering in IE and Edge when 
26536                                    // moving tooltip (#6957).
26537                                    function translateSetter(value, key) {
26538                                        parentGroup[key] = value;
26539
26540                                        // In IE and Edge, use translate because items
26541                                        // would flicker below a HTML tooltip (#6957)
26542                                        if (isMS) {
26543                                            htmlGroupStyle[renderer.getTransformKey()] =
26544                                                'translate(' + (
26545                                                    parentGroup.x ||
26546                                                    parentGroup.translateX
26547                                                ) + 'px,' + (
26548                                                    parentGroup.y ||
26549                                                    parentGroup.translateY
26550                                                ) + 'px)';
26551
26552                                            // Otherwise, use left and top. Using translate
26553                                            // doesn't work well with offline export (#7254,
26554                                            // #7280)
26555                                        } else {
26556                                            if (key === 'translateX') {
26557                                                htmlGroupStyle.left = value + 'px';
26558                                            } else {
26559                                                htmlGroupStyle.top = value + 'px';
26560                                            }
26561                                        }
26562
26563                                        parentGroup.doTransform = true;
26564                                    }
26565
26566                                    if (cls) {
26567                                        cls = {
26568                                            className: cls
26569                                        };
26570                                    } // else null
26571
26572                                    // Create a HTML div and append it to the parent div
26573                                    // to emulate the SVG group structure
26574                                    htmlGroup =
26575                                        parentGroup.div =
26576                                        parentGroup.div || createElement('div', cls, {
26577                                            position: 'absolute',
26578                                            left: (parentGroup.translateX || 0) + 'px',
26579                                            top: (parentGroup.translateY || 0) + 'px',
26580                                            display: parentGroup.display,
26581                                            opacity: parentGroup.opacity, // #5075
26582                                            pointerEvents: (
26583                                                parentGroup.styles &&
26584                                                parentGroup.styles.pointerEvents
26585                                            ) // #5595
26586
26587                                            // the top group is appended to container
26588                                        }, htmlGroup || container);
26589
26590                                    // Shortcut
26591                                    htmlGroupStyle = htmlGroup.style;
26592
26593                                    // Set listeners to update the HTML div's position
26594                                    // whenever the SVG group position is changed.
26595                                    extend(parentGroup, {
26596                                        classSetter: function(value) {
26597                                            this.element.setAttribute('class', value);
26598                                            htmlGroup.className = value;
26599                                        },
26600                                        on: function() {
26601                                            if (parents[0].div) { // #6418
26602                                                wrapper.on.apply({
26603                                                        element: parents[0].div
26604                                                    },
26605                                                    arguments
26606                                                );
26607                                            }
26608                                            return parentGroup;
26609                                        },
26610                                        translateXSetter: translateSetter,
26611                                        translateYSetter: translateSetter
26612                                    });
26613                                    addSetters(parentGroup, htmlGroupStyle);
26614                                });
26615
26616                            }
26617                        } else {
26618                            htmlGroup = container;
26619                        }
26620
26621                        htmlGroup.appendChild(element);
26622
26623                        // Shared with VML:
26624                        wrapper.added = true;
26625                        if (wrapper.alignOnAdd) {
26626                            wrapper.htmlUpdateTransform();
26627                        }
26628
26629                        return wrapper;
26630                    };
26631                }
26632                return wrapper;
26633            }
26634        });
26635
26636    }
26636(Highcharts));
26637    (function(H) {
26638        /**
26639         * (c) 2010-2017 Torstein Honsi
26640         *
26641         * License: www.highcharts.com/license
26642         */
26643        var color = H.color,
26644            getTZOffset = H.getTZOffset,
26645            isTouchDevice = H.isTouchDevice,
26646            merge = H.merge,
26647            pick = H.pick,
26648            svg = H.svg,
26649            win = H.win;
26650
26651        /* ****************************************************************************
26652         * Handle the options                                                         *
26653         *****************************************************************************/
26654        /** 	 
26655         * @optionparent
26656         */
26657        H.defaultOptions = {
26658
26659
26660            /**
26661             * An array containing the default colors for the chart's series. When
26662             * all colors are used, new colors are pulled from the start again.
26663             * 
26664             * Default colors can also be set on a series or series.type basis,
26665             * see [column.colors](#plotOptions.column.colors), [pie.colors](#plotOptions.
26666             * pie.colors).
26667             * 
26668             * In styled mode, the colors option doesn't exist. Instead, colors
26669             * are defined in CSS and applied either through series or point class
26670             * names, or through the [chart.colorCount](#chart.colorCount) option.
26671             * 
26672             * 
26673             * ### Legacy
26674             * 
26675             * In Highcharts 3.x, the default colors were:
26676             * 
26677             * <pre>colors: ['#2f7ed8', '#0d233a', '#8bbc21', '#910000', '#1aadce', 
26678             *     '#492970', '#f28f43', '#77a1e5', '#c42525', '#a6c96a']</pre> 
26679             * 
26680             * In Highcharts 2.x, the default colors were:
26681             * 
26682             * <pre>colors: ['#4572A7', '#AA4643', '#89A54E', '#80699B', '#3D96AE', 
26683             *    '#DB843D', '#92A8CD', '#A47D7C', '#B5CA92']</pre>
26684             * 
26685             * @type {Array<Color>}
26686             * @sample {highcharts} highcharts/chart/colors/ Assign a global color theme
26687             * @default ["#7cb5ec", "#434348", "#90ed7d", "#f7a35c", "#8085e9",
26688             *          "#f15c80", "#e4d354", "#2b908f", "#f45b5b", "#91e8e1"]
26689             */
26690            colors: '#7cb5ec #434348 #90ed7d #f7a35c #8085e9 #f15c80 #e4d354 #2b908f #f45b5b #91e8e1'.split(' '),
26691
26692
26693
26694            /**
26695             * Styled mode only. Configuration object for adding SVG definitions for
26696             * reusable elements. See [gradients, shadows and patterns](http://www.
26697             * highcharts.com/docs/chart-design-and-style/gradients-shadows-and-
26698             * patterns) for more information and code examples.
26699             * 
26700             * @type {Object}
26701             * @since 5.0.0
26702             * @apioption defs
26703             */
26704
26705            /**
26706             * @ignore
26707             */
26708            symbols: ['circle', 'diamond', 'square', 'triangle', 'triangle-down'],
26709            lang: {
26710
26711                /**
26712                 * The loading text that appears when the chart is set into the loading
26713                 * state following a call to `chart.showLoading`.
26714                 * 
26715                 * @type {String}
26716                 * @default Loading...
26717                 */
26718                loading: 'Loading...',
26719
26720                /**
26721                 * An array containing the months names. Corresponds to the `%B` format
26722                 * in `Highcharts.dateFormat()`.
26723                 * 
26724                 * @type {Array<String>}
26725                 * @default [ "January" , "February" , "March" , "April" , "May" ,
26726                 *          "June" , "July" , "August" , "September" , "October" ,
26727                 *          "November" , "December"]
26728                 */
26729                months: [
26730                    'January', 'February', 'March', 'April', 'May', 'June', 'July',
26731                    'August', 'September', 'October', 'November', 'December'
26732                ],
26733
26734                /**
26735                 * An array containing the months names in abbreviated form. Corresponds
26736                 * to the `%b` format in `Highcharts.dateFormat()`.
26737                 * 
26738                 * @type {Array<String>}
26739                 * @default [ "Jan" , "Feb" , "Mar" , "Apr" , "May" , "Jun" ,
26740                 *          "Jul" , "Aug" , "Sep" , "Oct" , "Nov" , "Dec"]
26741                 */
26742                shortMonths: [
26743                    'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul',
26744                    'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
26745                ],
26746
26747                /**
26748                 * An array containing the weekday names.
26749                 * 
26750                 * @type {Array<String>}
26751                 * @default ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
26752                 *          "Friday", "Saturday"]
26753                 */
26754                weekdays: [
26755                    'Sunday', 'Monday', 'Tuesday', 'Wednesday',
26756                    'Thursday', 'Friday', 'Saturday'
26757                ],
26758
26759                /**
26760                 * Short week days, starting Sunday. If not specified, Highcharts uses
26761                 * the first three letters of the `lang.weekdays` option.
26762                 * 
26763                 * @type {Array<String>}
26764                 * @sample highcharts/lang/shortweekdays/
26765                 *         Finnish two-letter abbreviations
26766                 * @since 4.2.4
26767                 * @apioption lang.shortWeekdays
26768                 */
26769
26770                /**
26771                 * What to show in a date field for invalid dates. Defaults to an empty
26772                 * string.
26773                 * 
26774                 * @type {String}
26775                 * @since 4.1.8
26776                 * @product highcharts highstock
26777                 * @apioption lang.invalidDate
26778                 */
26779
26780                /**
26781                 * The default decimal point used in the `Highcharts.numberFormat`
26782                 * method unless otherwise specified in the function arguments.
26783                 * 
26784                 * @type {String}
26785                 * @default .
26786                 * @since 1.2.2
26787                 */
26788                decimalPoint: '.',
26789
26790                /**
26791                 * [Metric prefixes](http://en.wikipedia.org/wiki/Metric_prefix) used
26792                 * to shorten high numbers in axis labels. Replacing any of the positions
26793                 * with `null` causes the full number to be written. Setting `numericSymbols`
26794                 * to `null` disables shortening altogether.
26795                 * 
26796                 * @type {Array<String>}
26797                 * @sample {highcharts} highcharts/lang/numericsymbols/
26798                 *         Replacing the symbols with text
26799                 * @sample {highstock} highcharts/lang/numericsymbols/
26800                 *         Replacing the symbols with text
26801                 * @default [ "k" , "M" , "G" , "T" , "P" , "E"]
26802                 * @since 2.3.0
26803                 */
26804                numericSymbols: ['k', 'M', 'G', 'T', 'P', 'E'],
26805
26806                /**
26807                 * The magnitude of [numericSymbols](#lang.numericSymbol) replacements.
26808                 * Use 10000 for Japanese, Korean and various Chinese locales, which
26809                 * use symbols for 10^4, 10^8 and 10^12.
26810                 * 
26811                 * @type {Number}
26812                 * @sample highcharts/lang/numericsymbolmagnitude/
26813                 *         10000 magnitude for Japanese
26814                 * @default 1000
26815                 * @since 5.0.3
26816                 * @apioption lang.numericSymbolMagnitude
26817                 */
26818
26819                /**
26820                 * The text for the label appearing when a chart is zoomed.
26821                 * 
26822                 * @type {String}
26823                 * @default Reset zoom
26824                 * @since 1.2.4
26825                 */
26826                resetZoom: 'Reset zoom',
26827
26828                /**
26829                 * The tooltip title for the label appearing when a chart is zoomed.
26830                 * 
26831                 * @type {String}
26832                 * @default Reset zoom level 1:1
26833                 * @since 1.2.4
26834                 */
26835                resetZoomTitle: 'Reset zoom level 1:1',
26836
26837                /**
26838                 * The default thousands separator used in the `Highcharts.numberFormat`
26839                 * method unless otherwise specified in the function arguments. Since
26840                 * Highcharts 4.1 it defaults to a single space character, which is
26841                 * compatible with ISO and works across Anglo-American and continental
26842                 * European languages.
26843                 * 
26844                 * The default is a single space.
26845                 * 
26846                 * @type {String}
26847                 * @default  
26848                 * @since 1.2.2
26849                 */
26850                thousandsSep: ' '
26851            },
26852
26853            /**
26854             * Global options that don't apply to each chart. These options, like
26855             * the `lang` options, must be set using the `Highcharts.setOptions`
26856             * method.
26857             * 
26858             * <pre>Highcharts.setOptions({
26859             *     global: {
26860             *         useUTC: false
26861             *     }
26862             * });</pre>
26863             *
26864             */
26865            global: {
26866
26867                /**
26868                 * Whether to use UTC time for axis scaling, tickmark placement and
26869                 * time display in `Highcharts.dateFormat`. Advantages of using UTC
26870                 * is that the time displays equally regardless of the user agent's
26871                 * time zone settings. Local time can be used when the data is loaded
26872                 * in real time or when correct Daylight Saving Time transitions are
26873                 * required.
26874                 * 
26875                 * @type {Boolean}
26876                 * @sample {highcharts}
26876 highcharts/global/useutc-true/ True by default
26877                 * @sample {highcharts} highcharts/global/useutc-false/ False
26878                 * @default true
26879                 */
26880                useUTC: true
26881
26882                /**
26883                 * A custom `Date` class for advanced date handling. For example,
26884                 * [JDate](https://githubcom/tahajahangir/jdate) can be hooked in to
26885                 * handle Jalali dates.
26886                 * 
26887                 * @type {Object}
26888                 * @since 4.0.4
26889                 * @product highcharts highstock
26890                 * @apioption global.Date
26891                 */
26892
26893                /**
26894                 * _Canvg rendering for Android 2.x is removed as of Highcharts 5.0\.
26895                 * Use the [libURL](#exporting.libURL) option to configure exporting._
26896                 * 
26897                 * The URL to the additional file to lazy load for Android 2.x devices.
26898                 * These devices don't support SVG, so we download a helper file that
26899                 * contains [canvg](http://code.google.com/p/canvg/), its dependency
26900                 * rbcolor, and our own CanVG Renderer class. To avoid hotlinking to
26901                 * our site, you can install canvas-tools.js on your own server and
26902                 * change this option accordingly.
26903                 * 
26904                 * @type {String}
26905                 * @deprecated
26906                 * @default http://code.highcharts.com/{version}/modules/canvas-tools.js
26907                 * @product highcharts highmaps
26908                 * @apioption global.canvasToolsURL
26909                 */
26910
26911                /**
26912                 * A callback to return the time zone offset for a given datetime. It
26913                 * takes the timestamp in terms of milliseconds since January 1 1970,
26914                 * and returns the timezone offset in minutes. This provides a hook
26915                 * for drawing time based charts in specific time zones using their
26916                 * local DST crossover dates, with the help of external libraries.
26917                 * 
26918                 * @type {Function}
26919                 * @see [global.timezoneOffset](#global.timezoneOffset)
26920                 * @sample {highcharts} highcharts/global/gettimezoneoffset/
26921                 *         Use moment.js to draw Oslo time regardless of browser locale
26922                 * @sample {highstock} highcharts/global/gettimezoneoffset/
26923                 *         Use moment.js to draw Oslo time regardless of browser locale
26924                 * @since 4.1.0
26925                 * @product highcharts highstock
26926                 * @apioption global.getTimezoneOffset
26927                 */
26928
26929                /**
26930                 * Requires [moment.js](http://momentjs.com/). If the timezone option
26931                 * is specified, it creates a default
26932                 * [getTimezoneOffset](#global.getTimezoneOffset) function that looks
26933                 * up the specified timezone in moment.js. If moment.js is not included,
26934                 * this throws a Highcharts error in the console, but does not crash the
26935                 * chart.
26936                 * 
26937                 * @type {String}
26938                 * @see [getTimezoneOffset](#global.getTimezoneOffset)
26939                 * @sample {highcharts} highcharts/global/timezone/ Europe/Oslo
26940                 * @sample {highstock} highcharts/global/timezone/ Europe/Oslo
26941                 * @default undefined
26942                 * @since 5.0.7
26943                 * @product highcharts highstock
26944                 * @apioption global.timezone
26945                 */
26946
26947                /**
26948                 * The timezone offset in minutes. Positive values are west, negative
26949                 * values are east of UTC, as in the ECMAScript [getTimezoneOffset](https://developer.
26950                 * mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset)
26951                 * method. Use this to display UTC based data in a predefined time zone.
26952                 * 
26953                 * @type {Number}
26954                 * @see [global.getTimezoneOffset](#global.getTimezoneOffset)
26955                 * @sample {highcharts} highcharts/global/timezoneoffset/
26956                 *         Timezone offset
26957                 * @sample {highstock} highcharts/global/timezoneoffset/
26958                 *         Timezone offset
26959                 * @default 0
26960                 * @since 3.0.8
26961                 * @product highcharts highstock
26962                 * @apioption global.timezoneOffset
26963                 */
26964            },
26965            chart: {
26966
26967                /**
26968                 * When using multiple axis, the ticks of two or more opposite axes
26969                 * will automatically be aligned by adding ticks to the axis or axes
26970                 * with the least ticks, as if `tickAmount` were specified.
26971                 * 
26972                 * This can be prevented by setting `alignTicks` to false. If the grid
26973                 * lines look messy, it's a good idea to hide them for the secondary
26974                 * axis by setting `gridLineWidth` to 0.
26975                 * 
26976                 * @type {Boolean}
26977                 * @sample {highcharts}
26977 highcharts/chart/alignticks-true/ True by default
26978                 * @sample {highcharts} highcharts/chart/alignticks-false/ False
26979                 * @sample {highstock} stock/chart/alignticks-true/
26980                 *         True by default
26981                 * @sample {highstock} stock/chart/alignticks-false/
26982                 *         False
26983                 * @default true
26984                 * @product highcharts highstock
26985                 * @apioption chart.alignTicks
26986                 */
26987
26988
26989                /**
26990                 * Set the overall animation for all chart updating. Animation can be
26991                 * disabled throughout the chart by setting it to false here. It can
26992                 * be overridden for each individual API method as a function parameter.
26993                 * The only animation not affected by this option is the initial series
26994                 * animation, see [plotOptions.series.animation](#plotOptions.series.
26995                 * animation).
26996                 * 
26997                 * The animation can either be set as a boolean or a configuration
26998                 * object. If `true`, it will use the 'swing' jQuery easing and a
26999                 * duration of 500 ms. If used as a configuration object, the following
27000                 * properties are supported:
27001                 * 
27002                 * <dl>
27003                 * 
27004                 * <dt>duration</dt>
27005                 * 
27006                 * <dd>The duration of the animation in milliseconds.</dd>
27007                 * 
27008                 * <dt>easing</dt>
27009                 * 
27010                 * <dd>A string reference to an easing function set on the `Math` object.
27011                 * See [the easing demo](http://jsfiddle.net/gh/get/library/pure/
27012                 * highcharts/highcharts/tree/master/samples/highcharts/plotoptions/
27013                 * series-animation-easing/).</dd>
27014                 * 
27015                 * </dl>
27016                 * 
27017                 * @type {Boolean|Object}
27018                 * @sample {highcharts} highcharts/chart/animation-none/
27019                 *         Updating with no animation
27020                 * @sample {highcharts} highcharts/chart/animation-duration/
27021                 *         With a longer duration
27022                 * @sample {highcharts} highcharts/chart/animation-easing/
27023                 *         With a jQuery UI easing
27024                 * @sample {highmaps} maps/chart/animation-none/
27025                 *         Updating with no animation
27026                 * @sample {highmaps} maps/chart/animation-duration/
27027                 *         With a longer duration
27028                 * @default true
27029                 * @apioption chart.animation
27030                 */
27031
27032                /**
27033                 * A CSS class name to apply to the charts container `div`, allowing
27034                 * unique CSS styling for each chart.
27035                 * 
27036                 * @type {String}
27037                 * @apioption chart.className
27038                 */
27039
27040                /**
27041                 * Event listeners for the chart.
27042                 * 
27043                 * @apioption chart.events
27044                 */
27045
27046                /**
27047                 * Fires when a series is added to the chart after load time, using
27048                 * the `addSeries` method. One parameter, `event`, is passed to the
27049                 * function, containing common event information.
27050                 * Through `event.options` you can access the series options that was
27051                 * passed to the `addSeries` method. Returning false prevents the series
27052                 * from being added.
27053                 * 
27054                 * @type {Function}
27055                 * @context Chart
27056                 * @sample {highcharts} highcharts/chart/events-addseries/ Alert on add series
27057                 * @sample {highstock} stock/chart/events-addseries/ Alert on add series
27058                 * @since 1.2.0
27059                 * @apioption chart.events.addSeries
27060                 */
27061
27062                /**
27063                 * Fires when clicking on the plot background. One parameter, `event`,
27064                 * is passed to the function, containing common event information.
27065                 * 
27066                 * Information on the clicked spot can be found through `event.xAxis`
27067                 * and `event.yAxis`, which are arrays containing the axes of each dimension
27068                 * and each axis' value at the clicked spot. The primary axes are `event.
27069                 * xAxis[0]` and `event.yAxis[0]`. Remember the unit of a datetime axis
27070                 * is milliseconds since 1970-01-01 00:00:00.
27071                 * 
27072                 * <pre>click: function(e) {
27073                 *     console.log(
27074                 *         Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', e.xAxis[0].value),
27075                 *         e.yAxis[0].value
27076                 *     )
27077                 * }</pre>
27078                 * 
27079                 * @type {Function}
27080                 * @context Chart
27081                 * @sample {highcharts} highcharts/chart/events-click/
27082                 *         Alert coordinates on click
27083                 * @sample {highcharts} highcharts/chart/events-container/
27084                 *         Alternatively, attach event to container
27085                 * @sample {highstock} stock/chart/events-click/
27086                 *         Alert coordinates on click
27087                 * @sample {highstock} highcharts/chart/events-container/
27088                 *         Alternatively, attach event to container
27089                 * @sample {highmaps} maps/chart/events-click/
27090                 *         Record coordinates on click
27091                 * @sample {highmaps} highcharts/chart/events-container/
27092                 *         Alternatively, attach event to container
27093                 * @since 1.2.0
27094                 * @apioption chart.events.click
27095                 */
27096
27097
27098                /**
27099                 * Fires when the chart is finished loading. Since v4.2.2, it also waits
27100                 * for images to be loaded, for example from point markers. One parameter,
27101                 * `event`, is passed to the function, containing common event information.
27102                 * 
27103                 * There is also a second parameter to the chart constructor where a
27104                 * callback function can be passed to be executed on chart.load.
27105                 * 
27106                 * @type {Function}
27107                 * @context Chart
27108                 * @sample {highcharts} highcharts/chart/events-load/
27109                 *         Alert on chart load
27110                 * @sample {highstock} stock/chart/events-load/
27111                 *         Alert on chart load
27112                 * @sample {highmaps} maps/chart/events-load/
27113                 *         Add series on chart load
27114                 * @apioption chart.events.load
27115                 */
27116
27117                /**
27118                 * Fires when the chart is redrawn, either after a call to chart.redraw()
27119                 * or after an axis, series or point is modified with the `redraw` option
27120                 * set to true. One parameter, `event`, is passed to the function, containing common event information.
27121                 * 
27122                 * @type {Function}
27123                 * @context Chart
27124                 * @sample {highcharts} highcharts/chart/events-redraw/
27125                 *         Alert on chart redraw
27126                 * @sample {highstock} stock/chart/events-redraw/
27127                 *         Alert on chart redraw when adding a series or moving the
27128                 *         zoomed range
27129                 * @sample {highmaps} maps/chart/events-redraw/
27130                 *         Set subtitle on chart redraw
27131                 * @since 1.2.0
27132                 * @apioption chart.events.redraw
27133                 */
27134
27135                /**
27136                 * Fires after initial load of the chart (directly after the `load`
27137                 * event), and after each redraw (directly after the `redraw` event).
27138                 * 
27139                 * @type {Function}
27140                 * @context Chart
27141                 * @since 5.0.7
27142                 * @apioption chart.events.render
27143                 */
27144
27145                /**
27146                 * Fires when an area of the chart has been selected. Selection is enabled
27147                 * by setting the chart's zoomType. One parameter, `event`, is passed
27148                 * to the function, containing common event information. The default action for the selection event is to
27149                 * zoom the chart to the selected area. It can be prevented by calling
27150                 * `event.preventDefault()`.
27151                 * 
27152                 * Information on the selected area can be found through `event.xAxis`
27153                 * and `event.yAxis`, which are arrays containing the axes of each dimension
27154                 * and each axis' min and max values. The primary axes are `event.xAxis[0]`
27155                 * and `event.yAxis[0]`. Remember the unit of a datetime axis is milliseconds
27156                 * since 1970-01-01 00:00:00.
27157                 * 
27158                 * <pre>selection: function(event) {
27159                 *     // log the min and max of the primary, datetime x-axis
27160                 *     console.log(
27161                 *         Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', event.xAxis[0].min),
27162                 *         Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', event.xAxis[0].max)
27163                 *     );
27164                 *     // log the min and max of the y axis
27165                 *     console.log(event.yAxis[0].min, event.yAxis[0].max);
27166                 * }</pre>
27167                 * 
27168                 * @type {Function}
27169                 * @sample {highcharts} highcharts/chart/events-selection/
27170                 *         Report on selection and reset
27171                 * @sample {highcharts} highcharts/chart/events-selection-points/
27172                 *         Select a range of points through a drag selection
27173                 * @sample {highstock} stock/chart/events-selection/
27174                 *         Report on selection and reset
27175                 * @sample {highstock} highcharts/chart/events-selection-points/
27176                 *         Select a range of points through a drag selection (Highcharts)
27177                 * @apioption chart.events.selection
27178                 */
27179
27180                /**
27181                 * The margin between the outer edge of the chart and the plot area.
27182                 * The numbers in the array designate top, right, bottom and left
27183                 * respectively. Use the options `marginTop`, `marginRight`,
27184                 * `marginBottom` and `marginLeft` for shorthand setting of one option.
27185                 * 
27186                 * By default there is no margin. The actual space is dynamically calculated
27187                 * from the offset of axis labels, axis title, title, subtitle and legend
27188                 * in addition to the `spacingTop`, `spacingRight`, `spacingBottom`
27189                 * and `spacingLeft` options.
27190                 * 
27191                 * @type {Array}
27192                 * @sample {highcharts} highcharts/chart/margins-zero/
27193                 *         Zero margins
27194                 * @sample {highstock} stock/chart/margin-zero/
27195                 *         Zero margins
27196                 *
27197                 * @defaults {all} null
27198                 * @apioption chart.margin
27199                 */
27200
27201                /**
27202                 * The margin between the bottom outer edge of the chart and the plot
27203                 * area. Use this to set a fixed pixel value for the margin as opposed
27204                 * to the default dynamic margin. See also `spacingBottom`.
27205                 * 
27206                 * @type {Number}
27207                 * @sample {highcharts} highcharts/chart/marginbottom/
27208                 *         100px bottom margin
27209                 * @sample {highstock} stock/chart/marginbottom/
27210                 *         100px bottom margin
27211                 * @sample {highmaps} maps/chart/margin/
27212                 *         100px margins
27213                 * @since 2.0
27214                 * @apioption chart.marginBottom
27215                 */
27216
27217                /**
27218                 * The margin between the left outer edge of the chart and the plot
27219                 * area. Use this to set a fixed pixel value for the margin as opposed
27220                 * to the default dynamic margin. See also `spacingLeft`.
27221                 * 
27222                 * @type {Number}
27223                 * @sample {highcharts} highcharts/chart/marginleft/
27224                 *         150px left margin
27225                 * @sample {highstock} stock/chart/marginleft/
27226                 *         150px left margin
27227                 * @sample {highmaps} maps/chart/margin/
27228                 *         100px margins
27229                 * @default null
27230                 * @since 2.0
27231                 * @apioption chart.marginLeft
27232                 */
27233
27234                /**
27235                 * The margin between the right outer edge of the chart and the plot
27236                 * area. Use this to set a fixed pixel value for the margin as opposed
27237                 * to the default dynamic margin. See also `spacingRight`.
27238                 * 
27239                 * @type {Number}
27240                 * @sample {highcharts} highcharts/chart/marginright/
27241                 *         100px right margin
27242                 * @sample {highstock} stock/chart/marginright/
27243                 *         100px right margin
27244                 * @sample {highmaps} maps/chart/margin/
27245                 *         100px margins
27246                 * @default null
27247                 * @since 2.0
27248                 * @apioption chart.marginRight
27249                 */
27250
27251                /**
27252                 * The margin between the top outer edge of the chart and the plot area.
27253                 * Use this to set a fixed pixel value for the margin as opposed to
27254                 * the default dynamic margin. See also `spacingTop`.
27255                 * 
27256                 * @type {Number}
27257                 * @sample {highcharts} highcharts/chart/margintop/ 100px top margin
27258                 * @sample {highstock} stock/chart/margintop/
27259                 *         100px top margin
27260                 * @sample {highmaps} maps/chart/margin/
27261                 *         100px margins
27262                 * @default null
27263                 * @since 2.0
27264                 * @apioption chart.marginTop
27265                 */
27266
27267                /**
27268                 * Allows setting a key to switch between zooming and panning. Can be
27269                 * one of `alt`, `ctrl`, `meta` (the command key on Mac and Windows
27270                 * key on Windows) or `shift`. The keys are mapped directly to the key
27271                 * properties of the click event argument (`event.altKey`, `event.ctrlKey`,
27272                 * `event.metaKey` and `event.shiftKey`).
27273                 * 
27274                 * @validvalue [null, "alt", "ctrl", "meta", "shift"]
27275                 * @type {String}
27276                 * @since 4.0.3
27277                 * @product highcharts
27278                 * @apioption chart.panKey
27279                 */
27280
27281                /**
27282                 * Allow panning in a chart. Best used with [panKey](#chart.panKey)
27283                 * to combine zooming and panning.
27284                 * 
27285                 * On touch devices, when the [tooltip.followTouchMove](#tooltip.followTouchMove)
27286                 * option is `true` (default), panning requires two fingers. To allow
27287                 * panning with one finger, set `followTouchMove` to `false`.
27288                 * 
27289                 * @type {Boolean}
27290                 * @sample {highcharts} highcharts/chart/pankey/ Zooming and panning
27291                 * @default {highcharts} false
27292                 * @default {highstock} true
27293                 * @since 4.0.3
27294                 * @product highcharts highstock
27295                 * @apioption chart.panning
27296                 */
27297
27298
27299                /**
27300                 * Equivalent to [zoomType](#chart.zoomType), but for multitouch gestures
27301                 * only. By default, the `pinchType` is the same as the `zoomType` setting.
27302                 * However, pinching can be enabled separately in some cases, for example
27303                 * in stock charts where a mouse drag pans the chart, while pinching
27304                 * is enabled. When [tooltip.followTouchMove](#tooltip.followTouchMove)
27305                 * is true, pinchType only applies to two-finger touches.
27306                 * 
27307                 * @validvalue ["x", "y", "xy"]
27308                 * @type {String}
27309                 * @default {highcharts} null
27310                 * @default {highstock} x
27311                 * @since 3.0
27312                 * @product highcharts highstock
27313                 * @apioption chart.pinchType
27314                 */
27315
27316                /**
27317                 * The corner radius of the outer chart border.
27318                 * 
27319                 * @type {Number}
27320                 * @sample {highcharts}
27320 highcharts/chart/borderradius/ 20px radius
27321                 * @sample {highstock} stock/chart/border/ 10px radius
27322                 * @sample {highmaps} maps/chart/border/ Border options
27323                 * @default 0
27324                 */
27325                borderRadius: 0,
27326
27327
27328                /**
27329                 * Alias of `type`.
27330                 * 
27331                 * @validvalue ["line", "spline", "column", "area", "areaspline", "pie"]
27332                 * @type {String}
27333                 * @deprecated
27334                 * @sample {highcharts} highcharts/chart/defaultseriestype/ Bar
27335                 * @default line
27336                 * @product highcharts
27337                 */
27338                defaultSeriesType: 'line',
27339
27340                /**
27341                 * If true, the axes will scale to the remaining visible series once
27342                 * one series is hidden. If false, hiding and showing a series will
27343                 * not affect the axes or the other series. For stacks, once one series
27344                 * within the stack is hidden, the rest of the stack will close in
27345                 * around it even if the axis is not affected.
27346                 * 
27347                 * @type {Boolean}
27348                 * @sample {highcharts} highcharts/chart/ignorehiddenseries-true/
27349                 *         True by default
27350                 * @sample {highcharts} highcharts/chart/ignorehiddenseries-false/
27351                 *         False
27352                 * @sample {highcharts} highcharts/chart/ignorehiddenseries-true-stacked/
27353                 *         True with stack
27354                 * @sample {highstock} stock/chart/ignorehiddenseries-true/
27355                 *         True by default
27356                 * @sample {highstock} stock/chart/ignorehiddenseries-false/
27357                 *         False
27358                 * @default true
27359                 * @since 1.2.0
27360                 * @product highcharts highstock
27361                 */
27362                ignoreHiddenSeries: true,
27363
27364
27365                /**
27366                 * Whether to invert the axes so that the x axis is vertical and y axis
27367                 * is horizontal. When `true`, the x axis is [reversed](#xAxis.reversed)
27368                 * by default.
27369                 *
27370                 * @productdesc {highcharts}
27371                 * If a bar series is present in the chart, it will be inverted
27372                 * automatically. Inverting the chart doesn't have an effect if there
27373                 * are no cartesian series in the chart, or if the chart is
27374                 * [polar](#chart.polar).
27375                 * 
27376                 * @type {Boolean}
27377                 * @sample {highcharts} highcharts/chart/inverted/
27378                 *         Inverted line
27379                 * @sample {highstock} stock/navigator/inverted/
27380                 *         Inverted stock chart
27381                 * @default false
27382                 * @product highcharts highstock
27383                 * @apioption chart.inverted
27384                 */
27385
27386                /**
27387                 * The distance between the outer edge of the chart and the content,
27388                 * like title or legend, or axis title and labels if present. The
27389                 * numbers in the array designate top, right, bottom and left respectively.
27390                 * Use the options spacingTop, spacingRight, spacingBottom and spacingLeft
27391                 * options for shorthand setting of one option.
27392                 * 
27393                 * @type {Array<Number>}
27394                 * @see [chart.margin](#chart.margin)
27395                 * @default [10, 10, 15, 10]
27396                 * @since 3.0.6
27397                 */
27398                spacing: [10, 10, 15, 10],
27399
27400                /**
27401                 * The button that appears after a selection zoom, allowing the user
27402                 * to reset zoom.
27403                 *
27404                 */
27405                resetZoomButton: {
27406
27407                    /**
27408                     * A collection of attributes for the button. The object takes SVG
27409                     * attributes like `fill`, `stroke`, `stroke-width` or `r`, the border
27410                     * radius. The theme also supports `style`, a collection of CSS properties
27411                     * for the text. Equivalent attributes for the hover state are given
27412                     * in `theme.states.hover`.
27413                     * 
27414                     * @type {Object}
27415                     * @sample {highcharts} highcharts/chart/resetzoombutton-theme/
27416                     *         Theming the button
27417                     * @sample {highstock} highcharts/chart/resetzoombutton-theme/
27418                     *         Theming the button
27419                     * @since 2.2
27420                     */
27421                    theme: {
27422
27423                        /**
27424                         * The Z index for the reset zoom button.
27425                         */
27426                        zIndex: 20
27427                    },
27428
27429                    /**
27430                     * The position of the button.
27431                     * 
27432                     * @type {Object}
27433                     * @sample {highcharts} highcharts/chart/resetzoombutton-position/
27434                     *         Above the plot area
27435                     * @sample {highstock} highcharts/chart/resetzoombutton-position/
27436                     *         Above the plot area
27437                     * @sample {highmaps} highcharts/chart/resetzoombutton-position/
27438                     *         Above the plot area
27439                     * @since 2.2
27440                     */
27441                    position: {
27442
27443                        /**
27444                         * The horizontal alignment of the button.
27445                         * 
27446                         * @type {String}
27447                         */
27448                        align: 'right',
27449
27450                        /**
27451                         * The horizontal offset of the button.
27452                         * 
27453                         * @type {Number}
27454                         */
27455                        x: -10,
27456
27457                        /**
27458                         * The vertical alignment of the button.
27459                         * 
27460                         * @validvalue ["top", "middle", "bottom"]
27461                         * @type {String}
27462                         * @default top
27463                         * @apioption chart.resetZoomButton.position.verticalAlign
27464                         */
27465
27466                        /**
27467                         * The vertical offset of the button.
27468                         * 
27469                         * @type {Number}
27470                         */
27471                        y: 10
27472                    }
27473
27474                    /**
27475                     * What frame the button should be placed related to. Can be either
27476                     * `plot` or `chart`
27477                     * 
27478                     * @validvalue ["plot", "chart"]
27479                     * @type {String}
27480                     * @sample {highcharts} highcharts/chart/resetzoombutton-relativeto/
27481                     *         Relative to the chart
27482                     * @sample {highstock} highcharts/chart/resetzoombutton-relativeto/
27483                     *         Relative to the chart
27484                     * @default plot
27485                     * @since 2.2
27486                     * @apioption chart.resetZoomButton.relativeTo
27487                     */
27488                },
27489
27490                /**
27491                 * An explicit width for the chart. By default (when `null`) the width
27492                 * is calculated from the offset width of the containing element.
27493                 * 
27494                 * @type {Number}
27495                 * @sample {highcharts} highcharts/chart/width/ 800px wide
27496                 * @sample {highstock} stock/chart/width/ 800px wide
27497                 * @sample {highmaps} maps/chart/size/ Chart with explicit size
27498                 * @default null
27499                 */
27500                width: null,
27501
27502                /**
27503                 * An explicit height for the chart. If a _number_, the height is
27504                 * given in pixels. If given a _percentage string_ (for example `'56%'`),
27505                 * the height is given as the percentage of the actual chart width.
27506                 * This allows for preserving the aspect ratio across responsive
27507                 * sizes.
27508                 * 
27509                 * By default (when `null`) the height is calculated from the offset
27510                 * height of the containing element, or 400 pixels if the containing
27511                 * element's height is 0.
27512                 * 
27513                 * @type {Number|String}
27514                 * @sample {highcharts} highcharts/chart/height/
27515                 *         500px height
27516                 * @sample {highstock} stock/chart/height/
27517                 *         300px height
27518                 * @sample {highmaps} maps/chart/size/
27519                 *         Chart with explicit size
27520                 * @sample highcharts/chart/height-percent/
27521                 *         Highcharts with percentage height
27522                 * @default null
27523                 */
27524                height: null,
27525
27526
27527
27528                /**
27529                 * The color of the outer chart border.
27530                 * 
27531                 * @type {Color}
27532                 * @see In styled mode, the stroke is set with the `.highcharts-background`
27533                 * class.
27534                 * @sample {highcharts} highcharts/chart/bordercolor/ Brown border
27535                 * @sample {highstock} stock/chart/border/ Brown border
27536                 * @sample {highmaps} maps/chart/border/ Border options
27537                 * @default #335cad
27538                 */
27539                borderColor: '#335cad',
27540
27541                /**
27542                 * The pixel width of the outer chart border.
27543                 * 
27544                 * @type {Number}
27545                 * @see In styled mode, the stroke is set with the `.highcharts-background`
27546                 * class.
27547                 * @sample {highcharts} highcharts/chart/borderwidth/ 5px border
27548                 * @sample {highstock} stock/chart/border/
27549                 *         2px border
27550                 * @sample {highmaps} maps/chart/border/
27551                 *         Border options
27552                 * @default 0
27553                 * @apioption chart.borderWidth
27554                 */
27555
27556                /**
27557                 * The background color or gradient for the outer chart area.
27558                 * 
27559                 * @type {Color}
27560                 * @see In styled mode, the background is set with the `.highcharts-background` class.
27561                 * @sample {highcharts} highcharts/chart/backgroundcolor-color/ Color
27562                 * @sample {highcharts} highcharts/chart/backgroundcolor-gradient/ Gradient
27563                 * @sample {highstock} stock/chart/backgroundcolor-color/
27564                 *         Color
27565                 * @sample {highstock} stock/chart/backgroundcolor-gradient/
27566                 *         Gradient
27567                 * @sample {highmaps} maps/chart/backgroundcolor-color/
27568                 *         Color
27569                 * @sample {highmaps} maps/chart/backgroundcolor-gradient/
27570                 *         Gradient
27571                 * @default #FFFFFF
27572                 */
27573                backgroundColor: '#ffffff',
27574
27575                /**
27576                 * The background color or gradient for the plot area.
27577                 * 
27578                 * @type {Color}
27579                 * @see In styled mode, the plot background is set with the `.highcharts-plot-background` class.
27580                 * @sample {highcharts} highcharts/chart/plotbackgroundcolor-color/
27581                 *         Color
27582                 * @sample {highcharts} highcharts/chart/plotbackgroundcolor-gradient/
27583                 *         Gradient
27584                 * @sample {highstock} stock/chart/plotbackgroundcolor-color/
27585                 *         Color
27586                 * @sample {highstock} stock/chart/plotbackgroundcolor-gradient/
27587                 *         Gradient
27588                 * @sample {highmaps} maps/chart/plotbackgroundcolor-color/
27589                 *         Color
27590                 * @sample {highmaps} maps/chart/plotbackgroundcolor-gradient/
27591                 *         Gradient
27592                 * @default null
27593                 * @apioption chart.plotBackgroundColor
27594                 */
27595
27596
27597                /**
27598                 * The URL for an image to use as the plot background. To set an image
27599                 * as the background for the entire chart, set a CSS background image
27600                 * to the container element. Note that for the image to be applied to
27601                 * exported charts, its URL needs to be accessible by the export server.
27602                 * 
27603                 * @type {String}
27604                 * @see In styled mode, a plot background image can be set with the
27605                 * `.highcharts-plot-background` class and a [custom pattern](http://www.
27606                 * highcharts.com/docs/chart-design-and-style/gradients-shadows-and-
27607                 * patterns).
27608                 * @sample {highcharts} highcharts/chart/plotbackgroundimage/ Skies
27609                 * @sample {highstock} stock/chart/plotbackgroundimage/ Skies
27610                 * @default null
27611                 * @apioption chart.plotBackgroundImage
27612                 */
27613
27614                /**
27615                 * The color of the inner chart or plot area border.
27616                 * 
27617                 * @type {Color}
27618                 * @see In styled mode, a plot border stroke can be set with the `.
27619                 * highcharts-plot-border` class.
27620                 * @sample {highcharts} highcharts/chart/plotbordercolor/ Blue border
27621                 * @sample {highstock} stock/chart/plotborder/ Blue border
27622                 * @sample {highmaps} maps/chart/plotborder/ Plot border options
27623                 * @default #cccccc
27624                 */
27625                plotBorderColor: '#cccccc'
27626
27627
27628                /**
27629                 * The pixel width of the plot area border.
27630                 * 
27631                 * @type {Number}
27632                 * @sample {highcharts} highcharts/chart/plotborderwidth/ 1px border
27633                 * @sample {highstock} stock/chart/plotborder/
27634                 *         2px border
27635                 * @sample {highmaps} maps/chart/plotborder/
27636                 *         Plot border options
27637                 * @default 0
27638                 * @apioption chart.plotBorderWidth
27639                 */
27640
27641                /**
27642                 * Whether to apply a drop shadow to the plot area. Requires that
27643                 * plotBackgroundColor be set. The shadow can be an object configuration
27644                 * containing `color`, `offsetX`, `offsetY`, `opacity` and `width`.
27645                 * 
27646                 * @type {Boolean|Object}
27647                 * @sample {highcharts} highcharts/chart/plotshadow/ Plot shadow
27648                 * @sample {highstock} stock/chart/plotshadow/
27649                 *         Plot shadow
27650                 * @sample {highmaps} maps/chart/plotborder/
27651                 *         Plot border options
27652                 * @default false
27653                 * @apioption chart.plotShadow
27654                 */
27655
27656                /**
27657                 * When true, cartesian charts like line, spline, area and column are
27658                 * transformed into the polar coordinate system. Requires `highcharts-
27659                 * more.js`.
27660                 * 
27661                 * @type {Boolean}
27662                 * @default false
27663                 * @since 2.3.0
27664                 * @product highcharts
27665                 * @apioption chart.polar
27666                 */
27667
27668                /**
27669                 * Whether to reflow the chart to fit the width of the container div
27670                 * on resizing the window.
27671                 * 
27672                 * @type {Boolean}
27673                 * @sample {highcharts} highcharts/chart/reflow-true/ True by default
27674                 * @sample {highcharts} highcharts/chart/reflow-false/ False
27675                 * @sample {highstock} stock/chart/reflow-true/
27676                 *         True by default
27677                 * @sample {highstock} stock/chart/reflow-false/
27678                 *         False
27679                 * @sample {highmaps} maps/chart/reflow-true/
27680                 *         True by default
27681                 * @sample {highmaps} maps/chart/reflow-false/
27682                 *         False
27683                 * @default true
27684                 * @since 2.1
27685                 * @apioption chart.reflow
27686                 */
27687
27688
27689
27690
27691                /**
27692                 * The HTML element where the chart will be rendered. If it is a string,
27693                 * the element by that id is used. The HTML element can also be passed
27694                 * by direct reference, or as the first argument of the chart constructor,
27695                 *  in which case the option is not needed.
27696                 * 
27697                 * @type {String|Object}
27698                 * @sample {highcharts} highcharts/chart/reflow-true/
27699                 *         String
27700                 * @sample {highcharts} highcharts/chart/renderto-object/
27701                 *         Object reference
27702                 * @sample {highcharts} highcharts/chart/renderto-jquery/
27703                 *         Object reference through jQuery
27704                 * @sample {highstock} stock/chart/renderto-string/
27705                 *         String
27706                 * @sample {highstock} stock/chart/renderto-object/
27707                 *         Object reference
27708                 * @sample {highstock} stock/chart/renderto-jquery/
27709                 *         Object reference through jQuery
27710                 * @apioption chart.renderTo
27711                 */
27712
27713                /**
27714                 * The background color of the marker square when selecting (zooming
27715                 * in on) an area of the chart.
27716                 * 
27717                 * @type {Color}
27718                 * @see In styled mode, the selection marker fill is set with the
27719                 * `.highcharts-selection-marker` class.
27720                 * @default rgba(51,92,173,0.25)
27721                 * @since 2.1.7
27722                 * @apioption chart.selectionMarkerFill
27723                 */
27724
27725                /**
27726                 * Whether to apply a drop shadow to the outer chart area. Requires
27727                 * that backgroundColor be set. The shadow can be an object configuration
27728                 * containing `color`, `offsetX`, `offsetY`, `opacity` and `width`.
27729                 * 
27730                 * @type {Boolean|Object}
27731                 * @sample {highcharts} highcharts/chart/shadow/ Shadow
27732                 * @sample {highstock} stock/chart/shadow/
27733                 *         Shadow
27734                 * @sample {highmaps} maps/chart/border/
27735                 *         Chart border and shadow
27736                 * @default false
27737                 * @apioption chart.shadow
27738                 */
27739
27740                /**
27741                 * Whether to show the axes initially. This only applies to empty charts
27742                 * where series are added dynamically, as axes are automatically added
27743                 * to cartesian series.
27744                 * 
27745                 * @type {Boolean}
27746                 * @sample {highcharts} highcharts/chart/showaxes-false/ False by default
27747                 * @sample {highcharts} highcharts/chart/showaxes-true/ True
27748                 * @since 1.2.5
27749                 * @product highcharts
27750                 * @apioption chart.showAxes
27751                 */
27752
27753                /**
27754                 * The space between the bottom edge of the chart and the content (plot
27755                 * area, axis title and labels, title, subtitle or legend in top position).
27756                 * 
27757                 * @type {Number}
27758                 * @sample {highcharts} highcharts/chart/spacingbottom/
27759                 *         Spacing bottom set to 100
27760                 * @sample {highstock} stock/chart/spacingbottom/
27761                 *         Spacing bottom set to 100
27762                 * @sample {highmaps} maps/chart/spacing/
27763                 *         Spacing 100 all around
27764                 * @default 15
27765                 * @since 2.1
27766                 * @apioption chart.spacingBottom
27767                 */
27768
27769                /**
27770                 * The space between the left edge of the chart and the content (plot
27771                 * area, axis title and labels, title, subtitle or legend in top position).
27772                 * 
27773                 * @type {Number}
27774                 * @sample {highcharts} highcharts/chart/spacingleft/
27775                 *         Spacing left set to 100
27776                 * @sample {highstock} stock/chart/spacingleft/
27777                 *         Spacing left set to 100
27778                 * @sample {highmaps} maps/chart/spacing/
27779                 *         Spacing 100 all around
27780                 * @default 10
27781                 * @since 2.1
27782                 * @apioption chart.spacingLeft
27783                 */
27784
27785                /**
27786                 * The space between the right edge of the chart and the content (plot
27787                 * area, axis title and labels, title, subtitle or legend in top
27788                 * position).
27789                 * 
27790                 * @type {Number}
27791                 * @sample {highcharts} highcharts/chart/spacingright-100/
27792                 *         Spacing set to 100
27793                 * @sample {highcharts} highcharts/chart/spacingright-legend/
27794                 *         Legend in right position with default spacing
27795                 * @sample {highstock} stock/chart/spacingright/
27796                 *         Spacing set to 100
27797                 * @sample {highmaps} maps/chart/spacing/
27798                 *         Spacing 100 all around
27799                 * @default 10
27800                 * @since 2.1
27801                 * @apioption chart.spacingRight
27802                 */
27803
27804                /**
27805                 * The space between the top edge of the chart and the content (plot
27806                 * area, axis title and labels, title, subtitle or legend in top
27807                 * position).
27808                 * 
27809                 * @type {Number}
27810                 * @sample {highcharts} highcharts/chart/spacingtop-100/
27811                 *         A top spacing of 100
27812                 * @sample {highcharts} highcharts/chart/spacingtop-10/
27813                 *         Floating chart title makes the plot area align to the default
27814                 *         spacingTop of 10.
27815                 * @sample {highstock} stock/chart/spacingtop/
27816                 *         A top spacing of 100
27817                 * @sample {highmaps} maps/chart/spacing/
27818                 *         Spacing 100 all around
27819                 * @default 10
27820                 * @since 2.1
27821                 * @apioption chart.spacingTop
27822                 */
27823
27824                /**
27825                 * Additional CSS styles to apply inline to the container `div`. Note
27826                 * that since the default font styles are applied in the renderer, it
27827                 * is ignorant of the individual chart options and must be set globally.
27828                 * 
27829                 * @type {CSSObject}
27830                 * @see In styled mode, general chart styles can be set with the `.highcharts-root` class.
27831                 * @sample {highcharts} highcharts/chart/style-serif-font/
27832                 *         Using a serif type font
27833                 * @sample {highcharts} highcharts/css/em/
27834                 *         Styled mode with relative font sizes
27835                 * @sample {highstock} stock/chart/style/
27836                 *         Using a serif type font
27837                 * @sample {highmaps} maps/chart/style-serif-font/
27838                 *         Using a serif type font
27839                 * @default {"fontFamily":"\"Lucida Grande\", \"Lucida Sans Unicode\", Verdana, Arial, Helvetica, sans-serif","fontSize":"12px"}
27840                 * @apioption chart.style
27841                 */
27842
27843                /**
27844                 * The default series type for the chart. Can be any of the chart types
27845                 * listed under [plotOptions](#plotOptions).
27846                 * 
27847                 * @validvalue ["line", "spline", "column", "bar", "area", "areaspline", "pie", "arearange", "areasplinerange", "boxplot", "bubble", "columnrange", "errorbar", "funnel", "gauge", "heatmap", "polygon", "pyramid", "scatter", "solidgauge", "treemap", "waterfall"]
27848                 * @type {String}
27849                 * @sample {highcharts} highcharts/chart/type-bar/ Bar
27850                 * @sample {highstock} stock/chart/type/
27851                 *         Areaspline
27852                 * @sample {highmaps} maps/chart/type-mapline/
27853                 *         Mapline
27854                 * @default {highcharts} line
27855                 * @default {highstock} line
27856                 * @default {highmaps} map
27857                 * @since 2.1.0
27858                 * @apioption chart.type
27859                 */
27860
27861                /**
27862                 * Decides in what dimensions the user can zoom by dragging the mouse.
27863                 * Can be one of `x`, `y` or `xy`.
27864                 * 
27865                 * @validvalue [null, "x", "y", "xy"]
27866                 * @type {String}
27867                 * @see [panKey](#chart.panKey)
27868                 * @sample {highcharts} highcharts/chart/zoomtype-none/ None by default
27869                 * @sample {highcharts} highcharts/chart/zoomtype-x/ X
27870                 * @sample {highcharts} highcharts/chart/zoomtype-y/ Y
27871                 * @sample {highcharts} highcharts/chart/zoomtype-xy/ Xy
27872                 * @sample {highstock} stock/demo/basic-line/ None by default
27873                 * @sample {highstock} stock/chart/zoomtype-x/ X
27874                 * @sample {highstock} stock/chart/zoomtype-y/ Y
27875                 * @sample {highstock} stock/chart/zoomtype-xy/ Xy
27876                 * @product highcharts highstock
27877                 * @apioption chart.zoomType
27878                 */
27879            },
27880
27881            /**
27882             * The chart's main title.
27883             * 
27884             * @sample {highmaps} maps/title/title/ Title options demonstrated
27885             */
27886            title: {
27887
27888                /**
27889                 * The title of the chart. To disable the title, set the `text` to
27890                 * `null`.
27891                 * 
27892                 * @type {String}
27893                 * @sample {highcharts} highcharts/title/text/ Custom title
27894                 * @sample {highstock} stock/chart/title-text/ Custom title
27895                 * @default {highcharts|highmaps} Chart title
27896                 * @default {highstock} null
27897                 */
27898                text: 'Chart title',
27899
27900                /**
27901                 * The horizontal alignment of the title. Can be one of "left", "center"
27902                 * and "right".
27903                 * 
27904                 * @validvalue ["left", "center", "right"]
27905                 * @type {String}
27906                 * @sample {highcharts} highcharts/title/align/ Aligned to the plot area (x = 70px     = margin left - spacing left)
27907                 * @sample {highstock} stock/chart/title-align/ Aligned to the plot area (x = 50px     = margin left - spacing left)
27908                 * @default center
27909                 * @since 2.0
27910                 */
27911                align: 'center',
27912
27913                /**
27914                 * The margin between the title and the plot area, or if a subtitle
27915                 * is present, the margin between the subtitle and the plot area.
27916                 * 
27917                 * @type {Number}
27918                 * @sample {highcharts} highcharts/title/margin-50/ A chart title margin of 50
27919                 * @sample {highcharts} highcharts/title/margin-subtitle/ The same margin applied with a subtitle
27920                 * @sample {highstock} stock/chart/title-margin/ A chart title margin of 50
27921                 * @default 15
27922                 * @since 2.1
27923                 */
27924                margin: 15,
27925
27926                /**
27927                 * Adjustment made to the title width, normally to reserve space for
27928                 * the exporting burger menu.
27929                 * 
27930                 * @type {Number}
27931                 * @sample {highcharts} highcharts/title/widthadjust/ Wider menu, greater padding
27932                 * @sample {highstock} highcharts/title/widthadjust/ Wider menu, greater padding
27933                 * @sample {highmaps} highcharts/title/widthadjust/ Wider menu, greater padding
27934                 * @default -44
27935                 * @since 4.2.5
27936                 */
27937                widthAdjust: -44
27938
27939                /**
27940                 * When the title is floating, the plot area will not move to make space
27941                 * for it.
27942                 * 
27943                 * @type {Boolean}
27944                 * @sample {highcharts} highcharts/chart/zoomtype-none/ False by default
27945                 * @sample {highcharts} highcharts/title/floating/
27946                 *         True - title on top of the plot area
27947                 * @sample {highstock} stock/chart/title-floating/
27948                 *         True - title on top of the plot area
27949                 * @default false
27950                 * @since 2.1
27951                 * @apioption title.floating
27952                 */
27953
27954                /**
27955                 * CSS styles for the title. Use this for font styling, but use `align`,
27956                 * `x` and `y` for text alignment.
27957                 * 
27958                 * In styled mode, the title style is given in the `.highcharts-title` class.
27959                 * 
27960                 * @type {CSSObject}
27961                 * @sample {highcharts} highcharts/title/style/ Custom color and weight
27962                 * @sample {highstock} stock/chart/title-style/ Custom color and weight
27963                 * @sample highcharts/css/titles/ Styled mode
27964                 * @default {highcharts|highmaps} { "color": "#333333", "fontSize": "18px" }
27965                 * @default {highstock} { "color": "#333333", "fontSize": "16px" }
27966                 * @apioption title.style
27967                 */
27968
27969                /**
27970                 * Whether to [use HTML](http://www.highcharts.com/docs/chart-concepts/labels-
27971                 * and-string-formatting#html) to render the text.
27972                 * 
27973                 * @type {Boolean}
27974                 * @default false
27975                 * @apioption title.useHTML
27976                 */
27977
27978                /**
27979                 * The vertical alignment of the title. Can be one of `"top"`, `"middle"`
27980                 * and `"bottom"`. When a value is given, the title behaves as if [floating](#title.
27981                 * floating) were `true`.
27982                 * 
27983                 * @validvalue ["top", "middle", "bottom"]
27984                 * @type {String}
27985                 * @sample {highcharts} highcharts/title/verticalalign/
27986                 *         Chart title in bottom right corner
27987                 * @sample {highstock} stock/chart/title-verticalalign/
27988                 *         Chart title in bottom right corner
27989                 * @since 2.1
27990                 * @apioption title.verticalAlign
27991                 */
27992
27993                /**
27994                 * The x position of the title relative to the alignment within chart.
27995                 * spacingLeft and chart.spacingRight.
27996                 * 
27997                 * @type {Number}
27998                 * @sample {highcharts} highcharts/title/align/
27999                 *         Aligned to the plot area (x = 70px = margin left - spacing left)
28000                 * @sample {highstock} stock/chart/title-align/
28001                 *         Aligned to the plot area (x = 50px = margin left - spacing left)
28002                 * @default 0
28003                 * @since 2.0
28004                 * @apioption title.x
28005                 */
28006
28007                /**
28008                 * The y position of the title relative to the alignment within [chart.
28009                 * spacingTop](#chart.spacingTop) and [chart.spacingBottom](#chart.spacingBottom).
28010                 *  By default it depends on the font size.
28011                 * 
28012                 * @type {Number}
28013                 * @sample {highcharts} highcharts/title/y/
28014                 *         Title inside the plot area
28015                 * @sample {highstock} stock/chart/title-verticalalign/
28016                 *         Chart title in bottom right corner
28017                 * @since 2.0
28018                 * @apioption title.y
28019                 */
28020
28021            },
28022
28023            /**
28024             * The chart's subtitle. This can be used both to display a subtitle below
28025             * the main title, and to display random text anywhere in the chart. The
28026             * subtitle can be updated after chart initialization through the 
28027             * `Chart.setTitle` method.
28028             * 
28029             * @sample {highmaps} maps/title/subtitle/ Subtitle options demonstrated
28030             */
28031            subtitle: {
28032
28033                /**
28034                 * The subtitle of the chart.
28035                 * 
28036                 * @type {String}
28037                 * @sample {highcharts} highcharts/subtitle/text/ Custom subtitle
28038                 * @sample {highcharts} highcharts/subtitle/text-formatted/ Formatted and linked text.
28039                 * @sample {highstock} stock/chart/subtitle-text Custom subtitle
28040                 * @sample {highstock} stock/chart/subtitle-text-formatted Formatted and linked text.
28041                 */
28042                text: '',
28043
28044                /**
28045                 * The horizontal alignment of the subtitle. Can be one of "left",
28046                 *  "center" and "right".
28047                 * 
28048                 * @validvalue ["left", "center", "right"]
28049                 * @type {String}
28050                 * @sample {highcharts} highcharts/subtitle/align/ Footnote at right of plot area
28051                 * @sample {highstock} stock/chart/subtitle-footnote Footnote at bottom right of plot area
28052                 * @default center
28053                 * @since 2.0
28054                 */
28055                align: 'center',
28056
28057                /**
28058                 * Adjustment made to the subtitle width, normally to reserve space
28059                 * for the exporting burger menu.
28060                 * 
28061                 * @type {Number}
28062                 * @see [title.widthAdjust](#title.widthAdjust)
28063                 * @sample {highcharts} highcharts/title/widthadjust/ Wider menu, greater padding
28064                 * @sample {highstock} highcharts/title/widthadjust/ Wider menu, greater padding
28065                 * @sample {highmaps} highcharts/title/widthadjust/ Wider menu, greater padding
28066                 * @default -44
28067                 * @since 4.2.5
28068                 */
28069                widthAdjust: -44
28070
28071                /**
28072                 * When the subtitle is floating, the plot area will not move to make
28073                 * space for it.
28074                 * 
28075                 * @type {Boolean}
28076                 * @sample {highcharts} highcharts/subtitle/floating/
28077                 *         Floating title and subtitle
28078                 * @sample {highstock} stock/chart/subtitle-footnote
28079                 *         Footnote floating at bottom right of plot area
28080                 * @default false
28081                 * @since 2.1
28082                 * @apioption subtitle.floating
28083                 */
28084
28085                /**
28086                 * CSS styles for the title.
28087                 * 
28088                 * In styled mode, the subtitle style is given in the `.highcharts-subtitle` class.
28089                 * 
28090                 * @type {CSSObject}
28091                 * @sample {highcharts} highcharts/subtitle/style/
28092                 *         Custom color and weight
28093                 * @sample {highcharts} highcharts/css/titles/
28094                 *         Styled mode
28095                 * @sample {highstock} stock/chart/subtitle-style
28096                 *         Custom color and weight
28097                 * @sample {highstock} highcharts/css/titles/
28098                 *         Styled mode
28099                 * @sample {highmaps} highcharts/css/titles/
28100                 *         Styled mode
28101                 * @default { "color": "#666666" }
28102                 * @apioption subtitle.style
28103                 */
28104
28105                /**
28106                 * Whether to [use HTML](http://www.highcharts.com/docs/chart-concepts/labels-
28107                 * and-string-formatting#html) to render the text.
28108                 * 
28109                 * @type {Boolean}
28110                 * @default false
28111                 * @apioption subtitle.useHTML
28112                 */
28113
28114                /**
28115                 * The vertical alignment of the title. Can be one of "top", "middle"
28116                 * and "bottom". When a value is given, the title behaves as floating.
28117                 * 
28118                 * @validvalue ["top", "middle", "bottom"]
28119                 * @type {String}
28120                 * @sample {highcharts} highcharts/subtitle/verticalalign/
28121                 *         Footnote at the bottom right of plot area
28122                 * @sample {highstock} stock/chart/subtitle-footnote
28123                 *         Footnote at the bottom right of plot area
28124                 * @default  
28125                 * @since 2.1
28126                 * @apioption subtitle.verticalAlign
28127                 */
28128
28129                /**
28130                 * The x position of the subtitle relative to the alignment within chart.
28131                 * spacingLeft and chart.spacingRight.
28132                 * 
28133                 * @type {Number}
28134                 * @sample {highcharts} highcharts/subtitle/align/
28135                 *         Footnote at right of plot area
28136                 * @sample {highstock} stock/chart/subtitle-footnote
28137                 *         Footnote at the bottom right of plot area
28138                 * @default 0
28139                 * @since 2.0
28140                 * @apioption subtitle.x
28141                 */
28142
28143                /**
28144                 * The y position of the subtitle relative to the alignment within chart.
28145                 * spacingTop and chart.spacingBottom. By default the subtitle is laid
28146                 * out below the title unless the title is floating.
28147                 * 
28148                 * @type {Number}
28149                 * @sample {highcharts} highcharts/subtitle/verticalalign/
28150                 *         Footnote at the bottom right of plot area
28151                 * @sample {highstock} stock/chart/subtitle-footnote
28152                 *         Footnote at the bottom right of plot area
28153                 * @default {highcharts}  null
28154                 * @default {highstock}  null
28155                 * @default {highmaps}  
28156                 * @since 2.0
28157                 * @apioption subtitle.y
28158                 */
28159            },
28160
28161            /**
28162             * The plotOptions is a wrapper object for config objects for each series
28163             * type. The config objects for each series can also be overridden for
28164             * each series item as given in the series array.
28165             * 
28166             * Configuration options for the series are given in three levels. Options
28167             * for all series in a chart are given in the [plotOptions.series](#plotOptions.
28168             * series) object. Then options for all series of a specific type are
28169             * given in the plotOptions of that type, for example plotOptions.line.
28170             * Next, options for one single series are given in [the series array](#series).
28171             *
28172             */
28173            plotOptions: {},
28174
28175            /**
28176             * HTML labels that can be positioned anywhere in the chart area.
28177             *
28178             */
28179            labels: {
28180
28181                /**
28182                 * A HTML label that can be positioned anywhere in the chart area.
28183                 * 
28184                 * @type {Array<Object>}
28185                 * @apioption labels.items
28186                 */
28187
28188                /**
28189                 * Inner HTML or text for the label.
28190                 * 
28191                 * @type {String}
28192                 * @apioption labels.items.html
28193                 */
28194
28195                /**
28196                 * CSS styles for each label. To position the label, use left and top
28197                 * like this:
28198                 * 
28199                 * <pre>style: {
28200                 *     left: '100px',
28201                 *     top: '100px'
28202                 * }</pre>
28203                 * 
28204                 * @type {CSSObject}
28205                 * @apioption labels.items.style
28206                 */
28207
28208                /**
28209                 * Shared CSS styles for all labels.
28210                 * 
28211                 * @type {CSSObject}
28212                 * @default { "color": "#333333" }
28213                 */
28214                style: {
28215                    position: 'absolute',
28216                    color: '#333333'
28217                }
28218            },
28219
28220            /**
28221             * The legend is a box containing a symbol and name for each series
28222             * item or point item in the chart. Each series (or points in case
28223             * of pie charts) is represented by a symbol and its name in the legend.
28224             *  
28225             * It is possible to override the symbol creator function and
28226             * create [custom legend symbols](http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/studies/legend-
28227             * custom-symbol/).
28228             * 
28229             * @productdesc {highmaps}
28230             * A Highmaps legend by default contains one legend item per series, but if
28231             * a `colorAxis` is defined, the axis will be displayed in the legend.
28232             * Either as a gradient, or as multiple legend items for `dataClasses`.
28233             */
28234            legend: {
28235
28236                /**
28237                 * The background color of the legend.
28238                 * 
28239                 * @type {Color}
28240                 * @see In styled mode, the legend background fill can be applied with
28241                 * the `.highcharts-legend-box` class.
28242                 * @sample {highcharts} highcharts/legend/backgroundcolor/ Yellowish background
28243                 * @sample {highstock} stock/legend/align/ Various legend options
28244                 * @sample {highmaps} maps/legend/border-background/ Border and background options
28245                 * @apioption legend.backgroundColor
28246                 */
28247
28248                /**
28249                 * The width of the drawn border around the legend.
28250                 * 
28251                 * @type {Number}
28252                 * @see In styled mode, the legend border stroke width can be applied
28253                 * with the `.highcharts-legend-box` class.
28254                 * @sample {highcharts} highcharts/legend/borderwidth/ 2px border width
28255                 * @sample {highstock} stock/legend/align/ Various legend options
28256                 * @sample {highmaps} maps/legend/border-background/ Border and background options
28257                 * @default 0
28258                 * @apioption legend.borderWidth
28259                 */
28260
28261                /**
28262                 * Enable or disable the legend.
28263                 * 
28264                 * @type {Boolean}
28265                 * @sample {highcharts} highcharts/legend/enabled-false/ Legend disabled
28266                 * @sample {highstock} stock/legend/align/ Various legend options
28267                 * @sample {highmaps} maps/legend/enabled-false/ Legend disabled
28268                 * @default {highstock} false
28269                 * @default {highmaps} true
28270                 */
28271                enabled: true,
28272
28273                /**
28274                 * The horizontal alignment of the legend box within the chart area.
28275                 * Valid values are `left`, `center` and `right`.
28276                 * 
28277                 * In the case that the legend is aligned in a corner position, the
28278                 * `layout` option will determine whether to place it above/below
28279                 * or on the side of the plot area.
28280                 * 
28281                 * @validvalue ["left", "center", "right"]
28282                 * @type {String}
28283                 * @sample {highcharts} highcharts/legend/align/
28284                 *         Legend at the right of the chart
28285                 * @sample {highstock} stock/legend/align/
28286                 *         Various legend options
28287                 * @sample {highmaps} maps/legend/alignment/
28288                 *         Legend alignment
28289                 * @since 2.0
28290                 */
28291                align: 'center',
28292
28293                /**
28294                 * When the legend is floating, the plot area ignores it and is allowed
28295                 * to be placed below it.
28296                 * 
28297                 * @type {Boolean}
28298                 * @sample {highcharts} highcharts/legend/floating-false/ False by default
28299                 * @sample {highcharts} highcharts/legend/floating-true/ True
28300                 * @sample {highmaps} maps/legend/alignment/ Floating legend
28301                 * @default false
28302                 * @since 2.1
28303                 * @apioption legend.floating
28304                 */
28305
28306                /**
28307                 * The layout of the legend items. Can be one of "horizontal" or "vertical".
28308                 * 
28309                 * @validvalue ["horizontal", "vertical"]
28310                 * @type {String}
28311                 * @sample {highcharts} highcharts/legend/layout-horizontal/ Horizontal by default
28312                 * @sample {highcharts} highcharts/legend/layout-vertical/ Vertical
28313                 * @sample {highstock} stock/legend/layout-horizontal/ Horizontal by default
28314                 * @sample {highmaps} maps/legend/padding-itemmargin/ Vertical with data classes
28315                 * @sample {highmaps} maps/legend/layout-vertical/ Vertical with color axis gradient
28316                 * @default horizontal
28317                 */
28318                layout: 'horizontal',
28319
28320                /**
28321                 * In a legend with horizontal layout, the itemDistance defines the
28322                 * pixel distance between each item.
28323                 * 
28324                 * @type {Number}
28325                 * @sample {highcharts} highcharts/legend/layout-horizontal/ 50px item distance
28326                 * @sample {highstock} highcharts/legend/layout-horizontal/ 50px item distance
28327                 * @default {highcharts} 20
28328                 * @default {highstock} 20
28329                 * @default {highmaps} 8
28330                 * @since 3.0.3
28331                 * @apioption legend.itemDistance
28332                 */
28333
28334                /**
28335                 * The pixel bottom margin for each legend item.
28336                 * 
28337                 * @type {Number}
28338                 * @sample {highcharts} highcharts/legend/padding-itemmargin/ Padding and item margins demonstrated
28339                 * @sample {highstock} highcharts/legend/padding-itemmargin/ Padding and item margins demonstrated
28340                 * @sample {highmaps} maps/legend/padding-itemmargin/ Padding and item margins demonstrated
28341                 * @default 0
28342                 * @since 2.2.0
28343                 * @apioption legend.itemMarginBottom
28344                 */
28345
28346                /**
28347                 * The pixel top margin for each legend item.
28348                 * 
28349                 * @type {Number}
28350                 * @sample {highcharts} highcharts/legend/padding-itemmargin/ Padding and item margins demonstrated
28351                 * @sample {highstock} highcharts/legend/padding-itemmargin/ Padding and item margins demonstrated
28352                 * @sample {highmaps} maps/legend/padding-itemmargin/ Padding and item margins demonstrated
28353                 * @default 0
28354                 * @since 2.2.0
28355                 * @apioption legend.itemMarginTop
28356                 */
28357
28358                /**
28359                 * The width for each legend item. This is useful in a horizontal layout
28360                 * with many items when you want the items to align vertically. .
28361                 * 
28362                 * @type {Number}
28363                 * @sample {highcharts} highcharts/legend/itemwidth-default/ Null by default
28364                 * @sample {highcharts} highcharts/legend/itemwidth-80/ 80 for aligned legend items
28365                 * @default null
28366                 * @since 2.0
28367                 * @apioption legend.itemWidth
28368                 */
28369
28370                /**
28371                 * A [format string](http://www.highcharts.com/docs/chart-concepts/labels-
28372                 * and-string-formatting) for each legend label. Available variables
28373                 * relates to properties on the series, or the point in case of pies.
28374                 * 
28375                 * @type {String}
28376                 * @default {name}
28377                 * @since 1.3
28378                 * @apioption legend.labelFormat
28379                 */
28380
28381                /**
28382                 * Callback function to format each of the series' labels. The `this`
28383                 * keyword refers to the series object, or the point object in case
28384                 * of pie charts. By default the series or point name is printed.
28385                 *
28386                 * @productdesc {highmaps}
28387                 *              In Highmaps the context can also be a data class in case
28388                 *              of a `colorAxis`.
28389                 * 
28390                 * @type {Function}
28391                 * @sample {highcharts} highcharts/legend/labelformatter/ Add text
28392                 * @sample {highmaps} maps/legend/labelformatter/ Data classes with label formatter
28393                 * @context {Series|Point}
28394                 */
28395                labelFormatter: function() {
28396                    return this.name;
28397                },
28398
28399                /**
28400                 * Line height for the legend items. Deprecated as of 2.1\. Instead,
28401                 * the line height for each item can be set using itemStyle.lineHeight,
28402                 * and the padding between items using itemMarginTop and itemMarginBottom.
28403                 * 
28404                 * @type {Number}
28405                 * @sample {highcharts} highcharts/legend/lineheight/ Setting padding
28406                 * @default 16
28407                 * @since 2.0
28408                 * @product highcharts
28409                 * @apioption legend.lineHeight
28410                 */
28411
28412                /**
28413                 * If the plot area sized is calculated automatically and the legend
28414                 * is not floating, the legend margin is the space between the legend
28415                 * and the axis labels or plot area.
28416                 * 
28417                 * @type {Number}
28418                 * @sample {highcharts} highcharts/legend/margin-default/ 12 pixels by default
28419                 * @sample {highcharts} highcharts/legend/margin-30/ 30 pixels
28420                 * @default 12
28421                 * @since 2.1
28422                 * @apioption legend.margin
28423                 */
28424
28425                /**
28426                 * Maximum pixel height for the legend. When the maximum height is extended,
28427                 *  navigation will show.
28428                 * 
28429                 * @type {Number}
28430                 * @default undefined
28431                 * @since 2.3.0
28432                 * @apioption legend.maxHeight
28433                 */
28434
28435                /**
28436                 * The color of the drawn border around the legend.
28437                 * 
28438                 * @type {Color}
28439                 * @see In styled mode, the legend border stroke can be applied with
28440                 * the `.highcharts-legend-box` class.
28441                 * @sample {highcharts} highcharts/legend/bordercolor/ Brown border
28442                 * @sample {highstock} stock/legend/align/ Various legend options
28443                 * @sample {highmaps} maps/legend/border-background/ Border and background options
28444                 * @default #999999
28445                 */
28446                borderColor: '#999999',
28447
28448                /**
28449                 * The border corner radius of the legend.
28450                 * 
28451                 * @type {Number}
28452                 * @sample {highcharts} highcharts/legend/borderradius-default/ Square by default
28453                 * @sample {highcharts} highcharts/legend/borderradius-round/ 5px rounded
28454                 * @sample {highmaps} maps/legend/border-background/ Border and background options
28455                 * @default 0
28456                 */
28457                borderRadius: 0,
28458
28459                /**
28460                 * Options for the paging or navigation appearing when the legend
28461                 * is overflown. Navigation works well on screen, but not in static
28462                 * exported images. One way of working around that is to [increase
28463                 * the chart height in export](http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/legend/navigation-
28464                 * enabled-false/).
28465                 *
28466                 */
28467                navigation: {
28468
28469
28470                    /**
28471                     * The color for the active up or down arrow in the legend page navigation.
28472                     * 
28473                     * @type {Color}
28474                     * @see In styled mode, the active arrow be styled with the `.highcharts-legend-nav-active` class.
28475                     * @sample {highcharts} highcharts/legend/navigation/ Legend page navigation demonstrated
28476                     * @sample {highstock} highcharts/legend/navigation/ Legend page navigation demonstrated
28477                     * @default #003399
28478                     * @since 2.2.4
28479                     */
28480                    activeColor: '#003399',
28481
28482                    /**
28483                     * The color of the inactive up or down arrow in the legend page
28484                     * navigation. .
28485                     * 
28486                     * @type {Color}
28487                     * @see In styled mode, the inactive arrow be styled with the
28488                     *      `.highcharts-legend-nav-inactive` class.
28489                     * @sample {highcharts} highcharts/legend/navigation/
28490                     *         Legend page navigation demonstrated
28491                     * @sample {highstock} highcharts/legend/navigation/
28492                     *         Legend page navigation demonstrated
28493                     * @default {highcharts} #cccccc
28494                     * @default {highstock} #cccccc
28495                     * @default {highmaps} ##cccccc
28496                     * @since 2.2.4
28497                     */
28498                    inactiveColor: '#cccccc'
28499
28500
28501                    /**
28502                     * How to animate the pages when navigating up or down. A value of `true`
28503                     * applies the default navigation given in the chart.animation option.
28504                     * Additional options can be given as an object c
28504ontaining values for
28505                     * easing and duration.
28506                     * 
28507                     * @type {Boolean|Object}
28508                     * @sample {highcharts} highcharts/legend/navigation/
28509                     *         Legend page navigation demonstrated
28510                     * @sample {highstock} highcharts/legend/navigation/
28511                     *         Legend page navigation demonstrated
28512                     * @default true
28513                     * @since 2.2.4
28514                     * @apioption legend.navigation.animation
28515                     */
28516
28517                    /**
28518                     * The pixel size of the up and down arrows in the legend paging
28519                     * navigation.
28520                     * 
28521                     * @type {Number}
28522                     * @sample {highcharts} highcharts/legend/navigation/
28523                     *         Legend page navigation demonstrated
28524                     * @sample {highstock} highcharts/legend/navigation/
28525                     *         Legend page navigation demonstrated
28526                     * @default 12
28527                     * @since 2.2.4
28528                     * @apioption legend.navigation.arrowSize
28529                     */
28530
28531                    /**
28532                     * Whether to enable the legend navigation. In most cases, disabling
28533                     * the navigation results in an unwanted overflow.
28534                     * 
28535                     * See also the [adapt chart to legend](http://www.highcharts.com/plugin-
28536                     * registry/single/8/Adapt-Chart-To-Legend) plugin for a solution to
28537                     * extend the chart height to make room for the legend, optionally in
28538                     * exported charts only.
28539                     * 
28540                     * @type {Boolean}
28541                     * @default true
28542                     * @since 4.2.4
28543                     * @apioption legend.navigation.enabled
28544                     */
28545
28546                    /**
28547                     * Text styles for the legend page navigation.
28548                     * 
28549                     * @type {CSSObject}
28550                     * @see In styled mode, the navigation items are styled with the
28551                     * `.highcharts-legend-navigation` class.
28552                     * @sample {highcharts} highcharts/legend/navigation/
28553                     *         Legend page navigation demonstrated
28554                     * @sample {highstock} highcharts/legend/navigation/
28555                     *         Legend page navigation demonstrated
28556                     * @since 2.2.4
28557                     * @apioption legend.navigation.style
28558                     */
28559                },
28560
28561                /**
28562                 * The inner padding of the legend box.
28563                 * 
28564                 * @type {Number}
28565                 * @sample {highcharts} highcharts/legend/padding-itemmargin/
28566                 *         Padding and item margins demonstrated
28567                 * @sample {highstock} highcharts/legend/padding-itemmargin/
28568                 *         Padding and item margins demonstrated
28569                 * @sample {highmaps} maps/legend/padding-itemmargin/
28570                 *         Padding and item margins demonstrated
28571                 * @default 8
28572                 * @since 2.2.0
28573                 * @apioption legend.padding
28574                 */
28575
28576                /**
28577                 * Whether to reverse the order of the legend items compared to the
28578                 * order of the series or points as defined in the configuration object.
28579                 * 
28580                 * @type {Boolean}
28581                 * @see [yAxis.reversedStacks](#yAxis.reversedStacks),
28582                 *      [series.legendIndex](#series.legendIndex)
28583                 * @sample {highcharts} highcharts/legend/reversed/
28584                 *         Stacked bar with reversed legend
28585                 * @default false
28586                 * @since 1.2.5
28587                 * @apioption legend.reversed
28588                 */
28589
28590                /**
28591                 * Whether to show the symbol on the right side of the text rather than
28592                 * the left side. This is common in Arabic and Hebraic.
28593                 * 
28594                 * @type {Boolean}
28595                 * @sample {highcharts} highcharts/legend/rtl/ Symbol to the right
28596                 * @default false
28597                 * @since 2.2
28598                 * @apioption legend.rtl
28599                 */
28600
28601                /**
28602                 * CSS styles for the legend area. In the 1.x versions the position
28603                 * of the legend area was determined by CSS. In 2.x, the position is
28604                 * determined by properties like `align`, `verticalAlign`, `x` and `y`,
28605                 *  but the styles are still parsed for backwards compatibility.
28606                 * 
28607                 * @type {CSSObject}
28608                 * @deprecated
28609                 * @product highcharts highstock
28610                 * @apioption legend.style
28611                 */
28612
28613
28614
28615                /**
28616                 * CSS styles for each legend item. Only a subset of CSS is supported,
28617                 * notably those options related to text. The default `textOverflow`
28618                 * property makes long texts truncate. Set it to `null` to wrap text
28619                 * instead. A `width` property can be added to control the text width.
28620                 * 
28621                 * @type {CSSObject}
28622                 * @see In styled mode, the legend items can be styled with the `.
28623                 * highcharts-legend-item` class.
28624                 * @sample {highcharts} highcharts/legend/itemstyle/ Bold black text
28625                 * @sample {highmaps} maps/legend/itemstyle/ Item text styles
28626                 * @default { "color": "#333333", "cursor": "pointer", "fontSize": "12px", "fontWeight": "bold", "textOverflow": "ellipsis" }
28627                 */
28628                itemStyle: {
28629                    color: '#333333',
28630                    fontSize: '12px',
28631                    fontWeight: 'bold',
28632                    textOverflow: 'ellipsis'
28633                },
28634
28635                /**
28636                 * CSS styles for each legend item in hover mode. Only a subset of
28637                 * CSS is supported, notably those options related to text. Properties
28638                 * are inherited from `style` unless overridden here.
28639                 * 
28640                 * @type {CSSObject}
28641                 * @see In styled mode, the hovered legend items can be styled with
28642                 * the `.highcharts-legend-item:hover` pesudo-class.
28643                 * @sample {highcharts} highcharts/legend/itemhoverstyle/ Red on hover
28644                 * @sample {highmaps} maps/legend/itemstyle/ Item text styles
28645                 * @default { "color": "#000000" }
28646                 */
28647                itemHoverStyle: {
28648                    color: '#000000'
28649                },
28650
28651                /**
28652                 * CSS styles for each legend item when the corresponding series or
28653                 * point is hidden. Only a subset of CSS is supported, notably those
28654                 * options related to text. Properties are inherited from `style`
28655                 * unless overridden here.
28656                 * 
28657                 * @type {CSSObject}
28658                 * @see In styled mode, the hidden legend items can be styled with
28659                 * the `.highcharts-legend-item-hidden` class.
28660                 * @sample {highcharts} highcharts/legend/itemhiddenstyle/ Darker gray color
28661                 * @default { "color": "#cccccc" }
28662                 */
28663                itemHiddenStyle: {
28664                    color: '#cccccc'
28665                },
28666
28667                /**
28668                 * Whether to apply a drop shadow to the legend. A `backgroundColor`
28669                 * also needs to be applied for this to take effect. The shadow can be
28670                 * an object configuration containing `color`, `offsetX`, `offsetY`,
28671                 * `opacity` and `width`.
28672                 * 
28673                 * @type {Boolean|Object}
28674                 * @sample {highcharts} highcharts/legend/shadow/
28675                 *         White background and drop shadow
28676                 * @sample {highstock} stock/legend/align/
28677                 *         Various legend options
28678                 * @sample {highmaps} maps/legend/border-background/
28679                 *         Border and background options
28680                 * @default false
28681                 */
28682                shadow: false,
28683
28684
28685                /**
28686                 * Default styling for the checkbox next to a legend item when
28687                 * `showCheckbox` is true.
28688                 */
28689                itemCheckboxStyle: {
28690                    position: 'absolute',
28691                    width: '13px', // for IE precision
28692                    height: '13px'
28693                },
28694                // itemWidth: undefined,
28695
28696                /**
28697                 * When this is true, the legend symbol width will be the same as
28698                 * the symbol height, which in turn defaults to the font size of the
28699                 * legend items.
28700                 * 
28701                 * @type {Boolean}
28702                 * @default true
28703                 * @since 5.0.0
28704                 */
28705                squareSymbol: true,
28706
28707                /**
28708                 * The pixel height of the symbol for series types that use a rectangle
28709                 * in the legend. Defaults to the font size of legend items.
28710                 *
28711                 * @productdesc {highmaps}
28712                 * In Highmaps, when the symbol is the gradient of a vertical color
28713                 * axis, the height defaults to 200.
28714                 * 
28715                 * @type {Number}
28716                 * @sample {highmaps} maps/legend/layout-vertical-sized/
28717                 *         Sized vertical gradient
28718                 * @sample {highmaps} maps/legend/padding-itemmargin/
28719                 *         No distance between data classes
28720                 * @since 3.0.8
28721                 * @apioption legend.symbolHeight
28722                 */
28723
28724                /**
28725                 * The border radius of the symbol for series types that use a rectangle
28726                 * in the legend. Defaults to half the `symbolHeight`.
28727                 * 
28728                 * @type {Number}
28729                 * @sample {highcharts} highcharts/legend/symbolradius/ Round symbols
28730                 * @sample {highstock} highcharts/legend/symbolradius/ Round symbols
28731                 * @sample {highmaps} highcharts/legend/symbolradius/ Round symbols
28732                 * @since 3.0.8
28733                 * @apioption legend.symbolRadius
28734                 */
28735
28736                /**
28737                 * The pixel width of the legend item symbol. When the `squareSymbol`
28738                 * option is set, this defaults to the `symbolHeight`, otherwise 16.
28739                 * 
28740                 * @productdesc {highmaps}
28741                 * In Highmaps, when the symbol is the gradient of a horizontal color
28742                 * axis, the width defaults to 200.
28743                 * 
28744                 * @type {Number}
28745                 * @sample {highcharts} highcharts/legend/symbolwidth/
28746                 *         Greater symbol width and padding
28747                 * @sample {highmaps} maps/legend/padding-itemmargin/
28748                 *         Padding and item margins demonstrated
28749                 * @sample {highmaps} maps/legend/layout-vertical-sized/
28750                 *         Sized vertical gradient
28751                 * @apioption legend.symbolWidth
28752                 */
28753
28754                /**
28755                 * Whether to [use HTML](http://www.highcharts.com/docs/chart-concepts/labels-
28756                 * and-string-formatting#html) to render the legend item texts. Prior
28757                 * to 4.1.7, when using HTML, [legend.navigation](#legend.navigation)
28758                 * was disabled.
28759                 * 
28760                 * @type {Boolean}
28761                 * @default false
28762                 * @apioption legend.useHTML
28763                 */
28764
28765                /**
28766                 * The width of the legend box.
28767                 * 
28768                 * @type {Number}
28769                 * @sample {highcharts} highcharts/legend/width/ Aligned to the plot area
28770                 * @default null
28771                 * @since 2.0
28772                 * @apioption legend.width
28773                 */
28774
28775                /**
28776                 * The pixel padding between the legend item symbol and the legend
28777                 * item text.
28778                 * 
28779                 * @type {Number}
28780                 * @sample {highcharts} highcharts/legend/symbolpadding/ Greater symbol width and padding
28781                 * @default 5
28782                 */
28783                symbolPadding: 5,
28784
28785                /**
28786                 * The vertical alignment of the legend box. Can be one of `top`,
28787                 * `middle` or `bottom`. Vertical position can be further determined
28788                 * by the `y` option.
28789                 * 
28790                 * In the case that the legend is aligned in a corner position, the
28791                 * `layout` option will determine whether to place it above/below
28792                 * or on the side of the plot area.
28793                 * 
28794                 * @validvalue ["top", "middle", "bottom"]
28795                 * @type {String}
28796                 * @sample {highcharts} highcharts/legend/verticalalign/ Legend 100px from the top of the chart
28797                 * @sample {highstock} stock/legend/align/ Various legend options
28798                 * @sample {highmaps} maps/legend/alignment/ Legend alignment
28799                 * @default bottom
28800                 * @since 2.0
28801                 */
28802                verticalAlign: 'bottom',
28803                // width: undefined,
28804
28805                /**
28806                 * The x offset of the legend relative to its horizontal alignment
28807                 * `align` within chart.spacingLeft and chart.spacingRight. Negative
28808                 * x moves it to the left, positive x moves it to the right.
28809                 * 
28810                 * @type {Number}
28811                 * @sample {highcharts} highcharts/legend/width/ Aligned to the plot area
28812                 * @default 0
28813                 * @since 2.0
28814                 */
28815                x: 0,
28816
28817                /**
28818                 * The vertical offset of the legend relative to it's vertical alignment
28819                 * `verticalAlign` within chart.spacingTop and chart.spacingBottom.
28820                 *  Negative y moves it up, positive y moves it down.
28821                 * 
28822                 * @type {Number}
28823                 * @sample {highcharts} highcharts/legend/verticalalign/ Legend 100px from the top of the chart
28824                 * @sample {highstock} stock/legend/align/ Various legend options
28825                 * @sample {highmaps} maps/legend/alignment/ Legend alignment
28826                 * @default 0
28827                 * @since 2.0
28828                 */
28829                y: 0,
28830
28831                /**
28832                 * A title to be added on top of the legend.
28833                 * 
28834                 * @sample {highcharts} highcharts/legend/title/ Legend title
28835                 * @sample {highmaps} maps/legend/alignment/ Legend with title
28836                 * @since 3.0
28837                 */
28838                title: {
28839                    /**
28840                     * A text or HTML string for the title.
28841                     * 
28842                     * @type {String}
28843                     * @default null
28844                     * @since 3.0
28845                     * @apioption legend.title.text
28846                     */
28847
28848
28849
28850                    /**
28851                     * Generic CSS styles for the legend title.
28852                     * 
28853                     * @type {CSSObject}
28854                     * @see In styled mode, the legend title is styled with the
28855                     * `.highcharts-legend-title` class.
28856                     * @default {"fontWeight":"bold"}
28857                     * @since 3.0
28858                     */
28859                    style: {
28860                        fontWeight: 'bold'
28861                    }
28862
28863                }
28864            },
28865
28866
28867            /**
28868             * The loading options control the appearance of the loading screen
28869             * that covers the plot area on chart operations. This screen only
28870             * appears after an explicit call to `chart.showLoading()`. It is a
28871             * utility for developers to communicate to the end user that something
28872             * is going on, for example while retrieving new data via an XHR connection.
28873             * The "Loading..." text itself is not part of this configuration
28874             * object, but part of the `lang` object.
28875             *
28876             */
28877            loading: {
28878
28879                /**
28880                 * The duration in milliseconds of the fade out effect.
28881                 * 
28882                 * @type {Number}
28883                 * @sample highcharts/loading/hideduration/ Fade in and out over a second
28884                 * @default 100
28885                 * @since 1.2.0
28886                 * @apioption loading.hideDuration
28887                 */
28888
28889                /**
28890                 * The duration in milliseconds of the fade in effect.
28891                 * 
28892                 * @type {Number}
28893                 * @sample highcharts/loading/hideduration/ Fade in and out over a second
28894                 * @default 100
28895                 * @since 1.2.0
28896                 * @apioption loading.showDuration
28897                 */
28898
28899
28900                /**
28901                 * CSS styles for the loading label `span`.
28902                 * 
28903                 * @type {CSSObject}
28904                 * @see In styled mode, the loading label is styled with the
28905                 * `.highcharts-legend-loading-inner` class.
28906                 * @sample {highcharts|highmaps} highcharts/loading/labelstyle/ Vertically centered
28907                 * @sample {highstock} stock/loading/general/ Label styles
28908                 * @default { "fontWeight": "bold", "position": "relative", "top": "45%" }
28909                 * @since 1.2.0
28910                 */
28911                labelStyle: {
28912                    fontWeight: 'bold',
28913                    position: 'relative',
28914                    top: '45%'
28915                },
28916
28917                /**
28918                 * CSS styles for the loading screen that covers the plot area.
28919                 * 
28920                 * @type {CSSObject}
28921                 * @see In styled mode, the loading label is styled with the `.highcharts-legend-loading` class.
28922                 * @sample {highcharts|highmaps} highcharts/loading/style/ Gray plot area, white text
28923                 * @sample {highstock} stock/loading/general/ Gray plot area, white text
28924                 * @default { "position": "absolute", "backgroundColor": "#ffffff", "opacity": 0.5, "textAlign": "center" }
28925                 * @since 1.2.0
28926                 */
28927                style: {
28928                    position: 'absolute',
28929                    backgroundColor: '#ffffff',
28930                    opacity: 0.5,
28931                    textAlign: 'center'
28932                }
28933
28934            },
28935
28936
28937            /**
28938             * Options for the tooltip that appears when the user hovers over a
28939             * series or point.
28940             *
28941             */
28942            tooltip: {
28943
28944                /**
28945                 * Enable or disable the tooltip.
28946                 * 
28947                 * @type {Boolean}
28948                 * @sample {highcharts} highcharts/tooltip/enabled/ Disabled
28949                 * @sample {highcharts} highcharts/plotoptions/series-point-events-mouseover/ Disable tooltip and show values on chart instead
28950                 * @default true
28951                 */
28952                enabled: true,
28953
28954                /**
28955                 * Enable or disable animation of the tooltip. In slow legacy IE browsers
28956                 * the animation is disabled by default.
28957                 * 
28958                 * @type {Boolean}
28959                 * @default true
28960                 * @since 2.3.0
28961                 */
28962                animation: svg,
28963
28964                /**
28965                 * The radius of the rounded border corners.
28966                 * 
28967                 * @type {Number}
28968                 * @sample {highcharts} highcharts/tooltip/bordercolor-default/ 5px by default
28969                 * @sample {highcharts}
28969 highcharts/tooltip/borderradius-0/ Square borders
28970                 * @sample {highmaps} maps/tooltip/background-border/ Background and border demo
28971                 * @default 3
28972                 */
28973                borderRadius: 3,
28974
28975                /**
28976                 * For series on a datetime axes, the date format in the tooltip's
28977                 * header will by default be guessed based on the closest data points.
28978                 * This member gives the default string representations used for
28979                 * each unit. For an overview of the replacement codes, see [dateFormat](#Highcharts.
28980                 * dateFormat).
28981                 * 
28982                 * Defaults to:
28983                 * 
28984                 * <pre>{
28985                 *     millisecond:"%A, %b %e, %H:%M:%S.%L",
28986                 *     second:"%A, %b %e, %H:%M:%S",
28987                 *     minute:"%A, %b %e, %H:%M",
28988                 *     hour:"%A, %b %e, %H:%M",
28989                 *     day:"%A, %b %e, %Y",
28990                 *     week:"Week from %A, %b %e, %Y",
28991                 *     month:"%B %Y",
28992                 *     year:"%Y"
28993                 * }</pre>
28994                 * 
28995                 * @type {Object}
28996                 * @see [xAxis.dateTimeLabelFormats](#xAxis.dateTimeLabelFormats)
28997                 * @product highcharts highstock
28998                 */
28999                dateTimeLabelFormats: {
29000                    millisecond: '%A, %b %e, %H:%M:%S.%L',
29001                    second: '%A, %b %e, %H:%M:%S',
29002                    minute: '%A, %b %e, %H:%M',
29003                    hour: '%A, %b %e, %H:%M',
29004                    day: '%A, %b %e, %Y',
29005                    week: 'Week from %A, %b %e, %Y',
29006                    month: '%B %Y',
29007                    year: '%Y'
29008                },
29009
29010                /**
29011                 * A string to append to the tooltip format.
29012                 * 
29013                 * @type {String}
29014                 * @sample {highcharts} highcharts/tooltip/footerformat/ A table for value alignment
29015                 * @sample {highmaps} maps/tooltip/format/ Format demo
29016                 * @default false
29017                 * @since 2.2
29018                 */
29019                footerFormat: '',
29020
29021                /**
29022                 * Padding inside the tooltip, in pixels.
29023                 * 
29024                 * @type {Number}
29025                 * @default 8
29026                 * @since 5.0.0
29027                 */
29028                padding: 8,
29029
29030                /**
29031                 * Proximity snap for graphs or single points. It defaults to 10 for
29032                 * mouse-powered devices and 25 for touch devices.
29033                 * 
29034                 * Note that in most cases the whole plot area captures the mouse
29035                 * movement, and in these cases `tooltip.snap` doesn't make sense.
29036                 * This applies when [stickyTracking](#plotOptions.series.stickyTracking)
29037                 * is `true` (default) and when the tooltip is [shared](#tooltip.shared)
29038                 * or [split](#tooltip.split).
29039                 * 
29040                 * @type {Number}
29041                 * @sample {highcharts} highcharts/tooltip/bordercolor-default/ 10 px by default
29042                 * @sample {highcharts} highcharts/tooltip/snap-50/ 50 px on graph
29043                 * @default 10/25
29044                 * @since 1.2.0
29045                 * @product highcharts highstock
29046                 */
29047                snap: isTouchDevice ? 25 : 10,
29048
29049
29050                /**
29051                 * The background color or gradient for the tooltip.
29052                 * 
29053                 * In styled mode, the stroke width is set in the `.highcharts-tooltip-box` class.
29054                 * 
29055                 * @type {Color}
29056                 * @sample {highcharts} highcharts/tooltip/backgroundcolor-solid/ Yellowish background
29057                 * @sample {highcharts} highcharts/tooltip/backgroundcolor-gradient/ Gradient
29058                 * @sample {highcharts} highcharts/css/tooltip-border-background/ Tooltip in styled mode
29059                 * @sample {highstock} stock/tooltip/general/ Custom tooltip
29060                 * @sample {highstock} highcharts/css/tooltip-border-background/ Tooltip in styled mode
29061                 * @sample {highmaps}
29061 maps/tooltip/background-border/ Background and border demo
29062                 * @sample {highmaps} highcharts/css/tooltip-border-background/ Tooltip in styled mode
29063                 * @default rgba(247,247,247,0.85)
29064                 */
29065                backgroundColor: color('#f7f7f7').setOpacity(0.85).get(),
29066
29067                /**
29068                 * The pixel width of the tooltip border.
29069                 * 
29070                 * In styled mode, the stroke width is set in the `.highcharts-tooltip-box` class.
29071                 * 
29072                 * @type {Number}
29073                 * @sample {highcharts} highcharts/tooltip/bordercolor-default/ 2px by default
29074                 * @sample {highcharts} highcharts/tooltip/borderwidth/ No border (shadow only)
29075                 * @sample {highcharts} highcharts/css/tooltip-border-background/ Tooltip in styled mode
29076                 * @sample {highstock} stock/tooltip/general/ Custom tooltip
29077                 * @sample {highstock} highcharts/css/tooltip-border-background/ Tooltip in styled mode
29078                 * @sample {highmaps} maps/tooltip/background-border/ Background and border demo
29079                 * @sample {highmaps} highcharts/css/tooltip-border-background/ Tooltip in styled mode
29080                 * @default 1
29081                 */
29082                borderWidth: 1,
29083
29084                /**
29085                 * The HTML of the tooltip header line. Variables are enclosed by
29086                 * curly brackets. Available variables are `point.key`, `series.name`,
29087                 * `series.color` and other members from the `point` and `series`
29088                 * objects. The `point.key` variable contains the category name, x
29089                 * value or datetime string depending on the type of axis. For datetime
29090                 * axes, the `point.key` date format can be set using tooltip.xDateFormat.
29091                 * 
29092                 * @type {String}
29093                 * @sample {highcharts} highcharts/tooltip/footerformat/
29094                 *         A HTML table in the tooltip
29095                 * @sample {highstock} highcharts/tooltip/footerformat/
29096                 *         A HTML table in the tooltip
29097                 * @sample {highmaps} maps/tooltip/format/ Format demo
29098                 */
29099                headerFormat: '<span style="font-size: 10px">{point.key}</span><br/>',
29100
29101                /**
29102                 * The HTML of the point's line in the tooltip. Variables are enclosed
29103                 * by curly brackets. Available variables are point.x, point.y, series.
29104                 * name and series.color and other properties on the same form. Furthermore,
29105                 * point.y can be extended by the `tooltip.valuePrefix` and `tooltip.
29106                 * valueSuffix` variables. This can also be overridden for each series,
29107                 * which makes it a good hook for displaying units.
29108                 * 
29109                 * In styled mode, the dot is colored by a class name rather
29110                 * than the point color.
29111                 * 
29112                 * @type {String}
29113                 * @sample {highcharts} highcharts/tooltip/pointformat/ A different point format with value suffix
29114                 * @sample {highmaps} maps/tooltip/format/ Format demo
29115                 * @default <span style="color:{point.color}">\u25CF</span> {series.name}: <b>{point.y}</b><br/>
29116                 * @since 2.2
29117                 */
29118                pointFormat: '<span style="color:{point.color}">\u25CF</span> {series.name}: <b>{point.y}</b><br/>',
29119
29120                /**
29121                 * Whether to apply a drop shadow to the tooltip.
29122                 * 
29123                 * @type {Boolean}
29124                 * @sample {highcharts} highcharts/tooltip/bordercolor-default/ True by default
29125                 * @sample {highcharts} highcharts/tooltip/shadow/ False
29126                 * @sample {highmaps} maps/tooltip/positioner/ Fixed tooltip position, border and shadow disabled
29127                 * @default true
29128                 */
29129                shadow: true,
29130
29131                /**
29132                 * CSS styles for the tooltip. The tooltip can also be styled through
29133                 * the CSS class `.highcharts-tooltip`.
29134                 * 
29135                 * @type {CSSObject}
29136                 * @sample {highcharts} highcharts/tooltip/style/ Greater padding, bold text
29137                 * @default { "color": "#333333", "cursor": "default", "fontSize": "12px", "pointerEvents": "none", "whiteSpace": "nowrap" }
29138                 */
29139                style: {
29140                    color: '#333333',
29141                    cursor: 'default',
29142                    fontSize: '12px',
29143                    pointerEvents: 'none', // #1686 http://caniuse.com/#feat=pointer-events
29144                    whiteSpace: 'nowrap'
29145                }
29146
29147
29148
29149                /**
29150                 * The color of the tooltip border. When `null`, the border takes the
29151                 * color of the corresponding series or point.
29152                 * 
29153                 * @type {Color}
29154                 * @sample {highcharts} highcharts/tooltip/bordercolor-default/
29155                 *         Follow series by default
29156                 * @sample {highcharts} highcharts/tooltip/bordercolor-black/
29157                 *         Black border
29158                 * @sample {highstock} stock/tooltip/general/
29159                 *         Styled tooltip
29160                 * @sample {highmaps} maps/tooltip/background-border/
29161                 *         Background and border demo
29162                 * @default null
29163                 * @apioption tooltip.borderColor
29164                 */
29165
29166                /**
29167                 * Since 4.1, the crosshair definitions are moved to the Axis object
29168                 * in order for a better separation from the tooltip. See [xAxis.crosshair](#xAxis.
29169                 * crosshair)<a>.</a>
29170                 * 
29171                 * @type {Mixed}
29172                 * @deprecated
29173                 * @sample {highcharts} highcharts/tooltip/crosshairs-x/
29174                 *         Enable a crosshair for the x value
29175                 * @default true
29176                 * @apioption tooltip.crosshairs
29177                 */
29178
29179                /**
29180                 * Whether the tooltip should follow the mouse as it moves across columns,
29181                 * pie slices and other point types with an extent. By default it behaves
29182                 * this way for scatter, bubble and pie series by override in the `plotOptions`
29183                 * for those series types.
29184                 * 
29185                 * For touch moves to behave the same way, [followTouchMove](#tooltip.
29186                 * followTouchMove) must be `true` also.
29187                 * 
29188                 * @type {Boolean}
29189                 * @default {highcharts} false
29190                 * @default {highstock} false
29191                 * @default {highmaps} true
29192                 * @since 3.0
29193                 * @apioption tooltip.followPointer
29194                 */
29195
29196                /**
29197                 * Whether the tooltip should follow the finger as it moves on a touch
29198                 * device. If this is `true` and [chart.panning](#chart.panning) is
29199                 * set,`followTouchMove` will take over one-finger touches, so the user
29200                 * needs to use two fingers for zooming and panning.
29201                 * 
29202                 * @type {Boolean}
29203                 * @default {highcharts} true
29204                 * @default {highstock} true
29205                 * @default {highmaps} false
29206                 * @since 3.0.1
29207                 * @apioption tooltip.followTouchMove
29208                 */
29209
29210                /**
29211                 * Callback function to format the text of the tooltip from scratch. Return
29212                 * `false` to disable tooltip for a specific point on series.
29213                 * 
29214                 * A subset of HTML is supported. Unless `useHTML` is true, the HTML of the
29215                 * tooltip is parsed and converted to SVG, therefore this isn't a complete HTML
29216                 * renderer. The following tags are supported: `<b>`, `<strong>`, `<i>`, `<em>`,
29217                 * `<br/>`, `<span>`. Spans can be styled with a `style` attribute,
29218                 * but only text-related CSS that is shared with SVG is handled.
29219                 * 
29220                 * Since version 2.1 the tooltip can be shared between multiple series
29221                 * through the `shared` option. The available data in the formatter
29222                 * differ a bit depending on whether the tooltip is shared or not. In
29223                 * a shared tooltip, all properties except `x`, which is common for
29224                 * all points, are kept in an array, `this.points`.
29225                 * 
29226                 * Available data are:
29227                 * 
29228                 * <dl>
29229                 * 
29230                 * <dt>this.percentage (not shared) / this.points[i].percentage (shared)</dt>
29231                 * 
29232                 * <dd>Stacked series and pies only. The point's percentage of the total.
29233                 * </dd>
29234                 * 
29235                 * <dt>this.point (not shared) / this.points[i].point (shared)</dt>
29236                 * 
29237                 * <dd>The point object. The point name, if defined, is available through
29238                 * `this.point.name`.</dd>
29239                 * 
29240                 * <dt>this.points</dt>
29241                 * 
29242                 * <dd>In a shared tooltip, this is an array containing all other properties
29243                 * for each point.</dd>
29244                 * 
29245                 * <dt>this.series (not shared) / this.points[i].series (shared)</dt>
29246                 * 
29247                 * <dd>
29247The series object. The series name is available through
29248                 * `this.series.name`.</dd>
29249                 * 
29250                 * <dt>this.total (not shared) / this.points[i].total (shared)</dt>
29251                 * 
29252                 * <dd>Stacked series only. The total value at this point's x value.
29253                 * </dd>
29254                 * 
29255                 * <dt>this.x</dt>
29256                 * 
29257                 * <dd>The x value. This property is the same regardless of the tooltip
29258                 * being shared or not.</dd>
29259                 * 
29260                 * <dt>this.y (not shared) / this.points[i].y (shared)</dt>
29261                 * 
29262                 * <dd>The y value.</dd>
29263                 * 
29264                 * </dl>
29265                 * 
29266                 * @type {Function}
29267                 * @sample {highcharts} highcharts/tooltip/formatter-simple/
29268                 *         Simple string formatting
29269                 * @sample {highcharts} highcharts/tooltip/formatter-shared/
29270                 *         Formatting with shared tooltip
29271                 * @sample {highstock} stock/tooltip/formatter/
29272                 *         Formatting with shared tooltip
29273                 * @sample {highmaps} maps/tooltip/formatter/
29274                 *         String formatting
29275                 * @apioption tooltip.formatter
29276                 */
29277
29278                /**
29279                 * The number of milliseconds to wait until the tooltip is hidden when
29280                 * mouse out from a point or chart.
29281                 * 
29282                 * @type {Number}
29283                 * @default 500
29284                 * @since 3.0
29285                 * @apioption tooltip.hideDelay
29286                 */
29287
29288                /**
29289                 * A callback function for formatting the HTML output for a single point
29290                 * in the tooltip. Like the `pointFormat` string, but with more flexibility.
29291                 * 
29292                 * @type {Function}
29293                 * @context Point
29294                 * @since 4.1.0
29295                 * @apioption tooltip.pointFormatter
29296                 */
29297
29298                /**
29299                 * A callback function to place the tooltip in a default position. The
29300                 * callback receives three parameters: `labelWidth`, `labelHeight` and
29301                 * `point`, where point contains values for `plotX` and `plotY` telling
29302                 * where the reference point is in the plot area. Add `chart.plotLeft`
29303                 * and `chart.plotTop` to get the full coordinates.
29304                 * 
29305                 * The return should be an object containing x and y values, for example
29306                 * `{ x: 100, y: 100 }`.
29307                 * 
29308                 * @type {Function}
29309                 * @sample {highcharts} highcharts/tooltip/positioner/ A fixed tooltip position
29310                 * @sample {highstock} stock/tooltip/positioner/ A fixed tooltip position on top of the chart
29311                 * @sample {highmaps} maps/tooltip/positioner/ A fixed tooltip position
29312                 * @since 2.2.4
29313                 * @apioption tooltip.positioner
29314                 */
29315
29316                /**
29317                 * The name of a symbol to use for the border around the tooltip.
29318                 * 
29319                 * @type {String}
29320                 * @default callout
29321                 * @validvalue ["callout", "square"]
29322                 * @since 4.0
29323                 * @apioption tooltip.shape
29324                 */
29325
29326                /**
29327                 * When the tooltip is shared, the entire plot area will capture mouse
29328                 * movement or touch events. Tooltip texts for series types with ordered
29329                 * data (not pie, scatter, flags etc) will be shown in a single bubble.
29330                 * This is recommended for single series charts and for tablet/mobile
29331                 * optimized charts.
29332                 * 
29333                 * See also [tooltip.split](#tooltip.split), that is better suited for
29334                 * charts with many series, especially line-type series.
29335                 * 
29336                 * @type {Boolean}
29337                 * @sample {highcharts} highcharts/tooltip/shared-false/ False by default
29338                 * @sample {highcharts} highcharts/tooltip/shared-true/ True
29339                 * @sample {highcharts} highcharts/tooltip/shared-x-crosshair/ True with x axis crosshair
29340                 * @sample {highcharts} highcharts/tooltip/shared-true-mixed-types/ True with mixed series types
29341                 * @default false
29342                 * @since 2.1
29343                 * @product highcharts highstock
29344                 * @apioption tooltip.shared
29345                 */
29346
29347                /**
29348                 * Split the tooltip into one label per series, with the header close
29349                 * to the axis. This is recommended over [shared](#tooltip.shared) tooltips
29350                 * for charts with multiple line series, generally making them easier
29351                 * to read.
29352                 *
29353                 * @productdesc {highstock} In Highstock, tooltips are split by default
29354                 * since v6.0.0. Stock charts typically contain multi-dimension points
29355                 * and multiple panes, making split tooltips the preferred layout over
29356                 * the previous `shared` tooltip.
29357                 * 
29358                 * @type {Boolean}
29359                 * @sample {highcharts} highcharts/tooltip/split/ Split tooltip
29360                 * @sample {highstock} highcharts/tooltip/split/ Split tooltip
29361                 * @sample {highmaps} highcharts/tooltip/split/ Split tooltip
29362                 * @default {highcharts} false
29363                 * @default {highstock} true
29364                 * @product highcharts highstock
29365                 * @since 5.0.0
29366                 * @apioption tooltip.split
29367                 */
29368
29369                /**
29370                 * Use HTML to render the contents of the tooltip instead of SVG. Using
29371                 * HTML allows advanced formatting like tables and images in the tooltip.
29372                 * It is also recommended for rtl languages as it works around rtl
29373                 * bugs in early Firefox.
29374                 * 
29375                 * @type {Boolean}
29376                 * @sample {highcharts}
29376 highcharts/tooltip/footerformat/ A table for value alignment
29377                 * @sample {highcharts} highcharts/tooltip/fullhtml/ Full HTML tooltip
29378                 * @sample {highstock} highcharts/tooltip/footerformat/ A table for value alignment
29379                 * @sample {highstock} highcharts/tooltip/fullhtml/ Full HTML tooltip
29380                 * @sample {highmaps} maps/tooltip/usehtml/ Pure HTML tooltip
29381                 * @default false
29382                 * @since 2.2
29383                 * @apioption tooltip.useHTML
29384                 */
29385
29386                /**
29387                 * How many decimals to show in each series' y value. This is overridable
29388                 * in each series' tooltip options object. The default is to preserve
29389                 * all decimals.
29390                 * 
29391                 * @type {Number}
29392                 * @sample {highcharts} highcharts/tooltip/valuedecimals/ Set decimals, prefix and suffix for the value
29393                 * @sample {highstock} highcharts/tooltip/valuedecimals/ Set decimals, prefix and suffix for the value
29394                 * @sample {highmaps} maps/tooltip/valuedecimals/ Set decimals, prefix and suffix for the value
29395                 * @since 2.2
29396                 * @apioption tooltip.valueDecimals
29397                 */
29398
29399                /**
29400                 * A string to prepend to each series' y value. Overridable in each
29401                 * series' tooltip options object.
29402                 * 
29403                 * @type {String}
29404                 * @sample {highcharts} highcharts/tooltip/valuedecimals/ Set decimals, prefix and suffix for the value
29405                 * @sample {highstock} highcharts/tooltip/valuedecimals/ Set decimals, prefix and suffix for the value
29406                 * @sample {highmaps} maps/tooltip/valuedecimals/ Set decimals, prefix and suffix for the value
29407                 * @since 2.2
29408                 * @apioption tooltip.valuePrefix
29409                 */
29410
29411                /**
29412                 * A string to append to each series' y value. Overridable in each series'
29413                 * tooltip options object.
29414                 * 
29415                 * @type {String}
29416                 * @sample {highcharts} highcharts/tooltip/valuedecimals/ Set decimals, prefix and suffix for the value
29417                 * @sample {highstock} highcharts/tooltip/valuedecimals/ Set decimals, prefix and suffix for the value
29418                 * @sample {highmaps} maps/tooltip/valuedecimals/ Set decimals, prefix and suffix for the value
29419                 * @since 2.2
29420                 * @apioption tooltip.valueSuffix
29421                 */
29422
29423                /**
29424                 * The format for the date in the tooltip header if the X axis is a
29425                 * datetime axis. The default is a best guess based on the smallest
29426                 * distance between points in the chart.
29427                 * 
29428                 * @type {String}
29429                 * @sample {highcharts} highcharts/tooltip/xdateformat/ A different format
29430                 * @product highcharts highstock
29431                 * @apioption tooltip.xDateFormat
29432                 */
29433            },
29434
29435
29436            /**
29437             * Highchart by default puts a credits label in the lower right corner
29438             * of the chart. This can be changed using these options.
29439             */
29440            credits: {
29441
29442                /**
29443                 * Whether to show the credits text.
29444                 * 
29445                 * @type {Boolean}
29446                 * @sample {highcharts} highcharts/credits/enabled-false/ Credits disabled
29447                 * @sample {highstock} stock/credits/enabled/ Credits disabled
29448                 * @sample {highmaps} maps/credits/enabled-false/ Credits disabled
29449                 * @default true
29450                 */
29451                enabled: true,
29452
29453                /**
29454                 * The URL for the credits label.
29455                 * 
29456                 * @type {String}
29457                 * @sample {highcharts} highcharts/credits/href/ Custom URL and text
29458                 * @sample {highmaps} maps/credits/customized/ Custom URL and text
29459                 * @default {highcharts} http://www.highcharts.com
29460                 * @default {highstock} "http://www.highcharts.com"
29461                 * @default {highmaps} http://www.highcharts.com
29462                 */
29463                href: 'http://www.highcharts.com',
29464
29465                /**
29466                 * Position configuration for the credits label.
29467                 * 
29468                 * @type {Object}
29469                 * @sample {highcharts} highcharts/credits/position-left/ Left aligned
29470                 * @sample {highcharts} highcharts/credits/position-left/ Left aligned
29471                 * @sample {highmaps} maps/credits/customized/ Left aligned
29472                 * @sample {highmaps} maps/credits/customized/ Left aligned
29473                 * @since 2.1
29474                 */
29475                position: {
29476
29477                    /**
29478                     * Horizontal alignment of the credits.
29479                     * 
29480                     * @validvalue ["left", "center", "right"]
29481                     * @type {String}
29482                     * @default right
29483                     */
29484                    align: 'right',
29485
29486                    /**
29487                     * Horizontal pixel offset of the credits.
29488                     * 
29489                     * @type {Number}
29490                     * @default -10
29491                     */
29492                    x: -10,
29493
29494                    /**
29495                     * Vertical alignment of the credits.
29496                     * 
29497                     * @validvalue ["top", "middle", "bottom"]
29498                     * @type {String}
29499                     * @default bottom
29500                     */
29501                    verticalAlign: 'bottom',
29502
29503                    /**
29504                     * Vertical pixel offset of the credits.
29505                     * 
29506                     * @type {Number}
29507                     * @default -5
29508                     */
29509                    y: -5
29510                },
29511
29512
29513                /**
29514                 * CSS styles for the credits label.
29515                 * 
29516                 * @type {CSSObject}
29517                 * @see In styled mode, credits styles can be set with the
29518                 * `.highcharts-credits` class.
29519                 * @default { "cursor": "pointer", "color": "#999999", "fontSize": "10px" }
29520                 */
29521                style: {
29522                    cursor: 'pointer',
29523                    color: '#999999',
29524                    fontSize: '9px'
29525                },
29526
29527
29528                /**
29529                 * The text for the credits label.
29530                 *
29531                 * @productdesc {highmaps}
29532                 * If a map is loaded as GeoJSON, the text defaults to `Highcharts @
29533                 * {map-credits}`. Otherwise, it defaults to `Highcharts.com`.
29534                 * 
29535                 * @type {String}
29536                 * @sample {highcharts} highcharts/credits/href/ Custom URL and text
29537                 * @sample {highmaps} maps/credits/customized/ Custom URL and text
29538                 * @default {highcharts|highstock} Highcharts.com
29539                 */
29540                text: 'Highcharts.com'
29541            }
29542        };
29543
29544
29545
29546        /**
29547         * Sets the getTimezoneOffset function. If the timezone option is set, a default
29548         * getTimezoneOffset function with that timezone is returned. If not, the
29549         * specified getTimezoneOffset function is returned. If neither are specified,
29550         * undefined is returned.
29551         * @return {function} a getTimezoneOffset function or undefined
29552         */
29553        function getTimezoneOffsetOption() {
29554            var globalOptions = H.defaultOptions.global,
29555                moment = win.moment;
29556
29557            if (globalOptions.timezone) {
29558                if (!moment) {
29559                    // getTimezoneOffset-function stays undefined because it depends on
29560                    // Moment.js
29561                    H.error(25);
29562
29563                } else {
29564                    return function(timestamp) {
29565                        return -moment.tz(
29566                            timestamp,
29567                            globalOptions.timezone
29568                        ).utcOffset();
29569                    };
29570                }
29571            }
29572
29573            // If not timezone is set, look for the getTimezoneOffset callback
29574            return globalOptions.useUTC && globalOptions.getTimezoneOffset;
29575        }
29576
29577        /**
29578         * Set the time methods globally based on the useUTC option. Time method can be
29579         *   either local time or UTC (default). It is called internally on initiating
29580         *   Highcharts and after running `Highcharts.setOptions`.
29581         *
29582         * @private
29583         */
29584        function setTimeMethods() {
29585            var globalOptions = H.defaultOptions.global,
29586                Date,
29587                useUTC = globalOptions.useUTC,
29588                GET = useUTC ? 'getUTC' : 'get',
29589                SET = useUTC ? 'setUTC' : 'set',
29590                setters = ['Minutes', 'Hours', 'Day', 'Date', 'Month', 'FullYear'],
29591                getters = setters.concat(['Milliseconds', 'Seconds']),
29592                n;
29593
29594            H.Date = Date = globalOptions.Date || win.Date; // Allow using a different Date class
29595            Date.hcTimezoneOffset = useUTC && globalOptions.timezoneOffset;
29596            Date.hcGetTimezoneOffset = getTimezoneOffsetOption();
29597            Date.hcMakeTime = function(year, month, date, hours, minutes, seconds) {
29598                var d;
29599                if (useUTC) {
29600                    d = Date.UTC.apply(0, arguments);
29601                    d += getTZOffset(d);
29602                } else {
29603                    d = new Date(
29604                        year,
29605                        month,
29606                        pick(date, 1),
29607                        pick(hours, 0),
29608                        pick(minutes, 0),
29609                        pick(seconds, 0)
29610                    ).getTime();
29611                }
29612                return d;
29613            };
29614
29615            // Dynamically set setters and getters. Use for loop, H.each is not yet 
29616            // overridden in oldIE.
29617            for (n = 0; n < setters.length; n++) {
29618                Date['hcGet' + setters[n]] = GET + setters[n];
29619            }
29620            for (n = 0; n < getters.length; n++) {
29621                Date['hcSet' + getters[n]] = SET + getters[n];
29622            }
29623        }
29624
29625        /**
29626         * Merge the default options with custom options and return the new options
29627         * structure. Commonly used for defining reusable templates.
29628         *
29629         * @function #setOptions
29630         * @memberOf  Highcharts
29631         * @sample highcharts/global/useutc-false Setting a global option
29632         * @sample highcharts/members/setoptions Applying a global theme
29633         * @param {Object} options The new custom chart options.
29634         * @returns {Object} Updated options.
29635         */
29636        H.setOptions = function(options) {
29637
29638            // Copy in the default options
29639            H.defaultOptions = merge(true, H.defaultOptions, options);
29640
29641            // Apply UTC
29642            setTimeMethods();
29643
29644            return H.defaultOptions;
29645        };
29646
29647        /**
29648         * Get the updated default options. Until 3.0.7, merely exposing defaultOptions for outside modules
29649         * wasn't enough because the setOptions method created a new object.
29650         */
29651        H.getOptions = function() {
29652            return H.defaultOptions;
29653        };
29654
29655
29656        // Series defaults
29657        H.defaultPlotOptions = H.defaultOptions.plotOptions;
29658
29659        // set the default time methods
29660        setTimeMethods();
29661
29662    }(Highcharts));
29663    (function(H) {
29664        /**
29665         * (c) 2010-2017 Torstein Honsi
29666         *
29667         * License: www.highcharts.com/license
29668         */
29669        var correctFloat = H.correctFloat,
29670            defined = H.defined,
29671            destroyObjectProperties = H.destroyObjectProperties,
29672            isNumber = H.isNumber,
29673            merge = H.merge,
29674            pick = H.pick,
29675            deg2rad = H.deg2rad;
29676
29677        /**
29678         * The Tick class
29679         */
29680        H.Tick = function(axis, pos, type, noLabel) {
29681            this.axis = axis;
29682            this.pos = pos;
29683            this.type = type || '';
29684            this.isNew = true;
29685            this.isNewLabel = true;
29686
29687            if (!type && !noLabel) {
29688                this.addLabel();
29689            }
29690        };
29691
29692        H.Tick.prototype = {
29693            /**
29694             * Write the tick label
29695             */
29696            addLabel: function() {
29697                var tick = this,
29698                    axis = tick.axis,
29699                    options = axis.options,
29700                    chart = axis.chart,
29701                    categories = axis.categories,
29702                    names = axis.names,
29703                    pos = tick.pos,
29704                    labelOptions = options.labels,
29705                    str,
29706                    tickPositions = axis.tickPositions,
29707                    isFirst = pos === tickPositions[0],
29708                    isLast = pos === tickPositions[tickPositions.length - 1],
29709                    value = categories ?
29710                    pick(categories[pos], names[pos], pos) :
29711                    pos,
29712                    label = tick.label,
29713                    tickPositionInfo = tickPositions.info,
29714                    dateTimeLabelFormat;
29715
29716                // Set the datetime label format. If a higher rank is set for this
29717                // position, use that. If not, use the general format.
29718                if (axis.isDatetimeAxis && tickPositionInfo) {
29719                    dateTimeLabelFormat =
29720                        options.dateTimeLabelFormats[
29721                            tickPositionInfo.higherRanks[pos] ||
29722                            tickPositionInfo.unitName
29723                        ];
29724                }
29725                // set properties for access in render method
29726                tick.isFirst = isFirst;
29727                tick.isLast = isLast;
29728
29729                // get the string
29730                str = axis.labelFormatter.call({
29731                    axis: axis,
29732                    chart: chart,
29733                    isFirst: isFirst,
29734                    isLast: isLast,
29735                    dateTimeLabelFormat: dateTimeLabelFormat,
29736                    value: axis.isLog ? correctFloat(axis.lin2log(value)) : value,
29737                    pos: pos
29738                });
29739
29740                // first call
29741                if (!defined(label)) {
29742
29743                    tick.label = label =
29744                        defined(str) && labelOptions.enabled ?
29745                        chart.renderer.text(
29746                            str,
29747                            0,
29748                            0,
29749                            labelOptions.useHTML
29750                        )
29751
29752                        // without position absolute, IE export sometimes is
29753                        // wrong.
29754                        .css(merge(labelOptions.style))
29755
29756                        .add(axis.labelGroup) :
29757                        null;
29758
29759                    // Un-rotated length
29760                    tick.labelLength = label && label.getBBox().width;
29761                    // Base value to detect change for new calls to getBBox
29762                    tick.rotation = 0;
29763
29764                    // update
29765                } else if (label) {
29766                    label.attr({
29767                        text: str
29768                    });
29769                }
29770            },
29771
29772            /**
29773             * Get the offset height or width of the label
29774             */
29775            getLabelSize: function() {
29776                return this.label ?
29777                    this.label.getBBox()[this.axis.horiz ? 'height' : 'width'] :
29778                    0;
29779            },
29780
29781            /**
29782             * Handle the label overflow by adjusting the labels to the left and right
29783             * edge, or hide them if they collide into the neighbour label.
29784             */
29785            handleOverflow: function(xy) {
29786                var axis = this.axis,
29787                    pxPos = xy.x,
29788                    chartWidth = axis.chart.chartWidth,
29789                    spacing = axis.chart.spacing,
29790                    leftBound = pick(axis.labelLeft, Math.min(axis.pos, spacing[3])),
29791                    rightBound = pick(
29792                        axis.labelRight,
29793                        Math.max(axis.pos + axis.len, chartWidth - spacing[1])
29794                    ),
29795                    label = this.label,
29796                    rotation = this.rotation,
29797                    factor = {
29798                        left: 0,
29799                        center: 0.5,
29800                        right: 1
29801                    }[axis.labelAlign],
29802                    labelWidth = label.getBBox().width,
29803                    slotWidth = axis.getSlotWidth(),
29804                    modifiedSlotWidth = slotWidth,
29805                    xCorrection = factor,
29806                    goRight = 1,
29807                    leftPos,
29808                    rightPos,
29809                    textWidth,
29810                    css = {};
29811
29812                // Check if the label overshoots the chart spacing box. If it does, move
29813                // it. If it now overshoots the slotWidth, add ellipsis.
29814                if (!rotation) {
29815                    leftPos = pxPos - factor * labelWidth;
29816                    rightPos = pxPos + (1 - factor) * labelWidth;
29817
29818                    if (leftPos < leftBound) {
29819                        modifiedSlotWidth = xy.x + modifiedSlotWidth * (1 - factor) - leftBound;
29820                    } else if (rightPos > rightBound) {
29821                        modifiedSlotWidth =
29822                            rightBound - xy.x + modifiedSlotWidth * factor;
29823                        goRight = -1;
29824                    }
29825
29826                    modifiedSlotWidth = Math.min(slotWidth, modifiedSlotWidth); // #4177
29827                    if (modifiedSlotWidth < slotWidth && axis.labelAlign === 'center') {
29828                        xy.x += (
29829                            goRight *
29830                            (
29831                                slotWidth -
29832                                modifiedSlotWidth -
29833                                xCorrection * (
29834                                    slotWidth - Math.min(labelWidth, modifiedSlotWidth)
29835                                )
29836                            )
29837                        );
29838                    }
29839                    // If the label width exceeds the available space, set a text width
29840                    // to be picked up below. Also, if a width has been set before, we
29841                    // need to set a new one because the reported labelWidth will be
29842                    // limited by the box (#3938).
29843                    if (
29844                        labelWidth > modifiedSlotWidth ||
29845                        (axis.autoRotation && (label.styles || {}).width)
29846                    ) {
29847                        textWidth = modifiedSlotWidth;
29848                    }
29849
29850                    // Add ellipsis to prevent rotated labels to be clipped against the edge
29851                    // of the chart
29852                } else if (rotation < 0 && pxPos - factor * labelWidth < leftBound) {
29853                    textWidth = Math.round(
29854                        pxPos / Math.cos(rotation * deg2rad) - leftBound
29855                    );
29856                } else if (rotation > 0 && pxPos + factor * labelWidth > rightBound) {
29857                    textWidth = Math.round(
29858                        (chartWidth - pxPos) / Math.cos(rotation * deg2rad)
29859                    );
29860                }
29861
29862                if (textWidth) {
29863                    css.width = textWidth;
29864                    if (!(axis.options.labels.style || {}).textOverflow) {
29865                        css.textOverflow = 'ellipsis';
29866                    }
29867                    label.css(css);
29868                }
29869            },
29870
29871            /**
29872             * Get the x and y position for ticks and labels
29873             */
29874            getPosition: function(horiz, pos, tickmarkOffset, old) {
29875                var axis = this.axis,
29876                    chart = axis.chart,
29877                    cHeight = (old && chart.oldChartHeight) || chart.chartHeight;
29878
29879                return {
29880                    x: horiz ?
29881                        (
29882                            axis.translate(pos + tickmarkOffset, null, null, old) +
29883                            axis.transB
29884                        ) :
29885                        (
29886                            axis.left +
29887                            axis.offset +
29888                            (
29889                                axis.opposite ?
29890                                (
29891                                    (
29892                                        (old && chart.oldChartWidth) ||
29893                                        chart.chartWidth
29894                                    ) -
29895                                    axis.right -
29896                                    axis.left
29897                                ) :
29898                                0
29899                            )
29900                        ),
29901
29902                    y: horiz ?
29903                        (
29904                            cHeight -
29905                            axis.bottom +
29906                            axis.offset -
29907                            (axis.opposite ? axis.height : 0)
29908                        ) :
29909                        (
29910                            cHeight -
29911                            axis.translate(pos + tickmarkOffset, null, null, old) -
29912                            axis.transB
29913                        )
29914                };
29915
29916            },
29917
29918            /**
29919             * Get the x, y position of the tick label
29920             */
29921            getLabelPosition: function(
29922                x,
29923                y,
29924                label,
29925                horiz,
29926                labelOptions,
29927                tickmarkOffset,
29928                index,
29929                step
29930            ) {
29931                var axis = this.axis,
29932                    transA = axis.transA,
29933                    reversed = axis.reversed,
29934                    staggerLines = axis.staggerLines,
29935                    rotCorr = axis.tickRotCorr || {
29936                        x: 0,
29937                        y: 0
29938                    },
29939                    yOffset = labelOptions.y,
29940                    line;
29941
29942                if (!defined(yOffset)) {
29943                    if (axis.side === 0) {
29944                        yOffset = label.rotation ? -8 : -label.getBBox().height;
29945                    } else if (axis.side === 2) {
29946                        yOffset = rotCorr.y + 8;
29947                    } else {
29948                        // #3140, #3140
29949                        yOffset = Math.cos(label.rotation * deg2rad) *
29950                            (rotCorr.y - label.getBBox(false, 0).height / 2);
29951                    }
29952                }
29953
29954                x = x + labelOptions.x + rotCorr.x - (tickmarkOffset && horiz ?
29955                    tickmarkOffset * transA * (reversed ? -1 : 1) : 0);
29956                y = y + yOffset - (tickmarkOffset && !horiz ?
29957                    tickmarkOffset * transA * (reversed ? 1 : -1) : 0);
29958
29959                // Correct for staggered labels
29960                if (staggerLines) {
29961                    line = (index / (step || 1) % staggerLines);
29962                    if (axis.opposite) {
29963                        line = staggerLines - line - 1;
29964                    }
29965                    y += line * (axis.labelOffset / staggerLines);
29966                }
29967
29968                return {
29969                    x: x,
29970                    y: Math.round(y)
29971                };
29972            },
29973
29974            /**
29975             * Extendible method to return the path of the marker
29976             */
29977            getMarkPath: function(x, y, tickLength, tickWidth, horiz, renderer) {
29978                return renderer.crispLine([
29979                    'M',
29980                    x,
29981                    y,
29982                    'L',
29983                    x + (horiz ? 0 : -tickLength),
29984                    y + (horiz ? tickLength : 0)
29985                ], tickWidth);
29986            },
29987
29988            /**
29989             * Renders the gridLine.
29990             * @param  {Boolean} old         Whether or not the tick is old
29991             * @param  {number} opacity      The opacity of the grid line
29992             * @param  {number} reverseCrisp Modifier for avoiding overlapping 1 or -1
29993             * @return {undefined}
29994             */
29995            renderGridLine: function(old, opacity, reverseCrisp) {
29996                var tick = this,
29997                    axis = tick.axis,
29998                    options = axis.options,
29999                    gridLine = tick.gridLine,
30000                    gridLinePath,
30001                    attribs = {},
30002                    pos = tick.pos,
30003                    type = tick.type,
30004                    tickmarkOffset = axis.tickmarkOffset,
30005                    renderer = axis.chart.renderer;
30006
30007
30008                var gridPrefix = type ? type + 'Grid' : 'grid',
30009                    gridLineWidth = options[gridPrefix + 'LineWidth'],
30010                    gridLineColor = options[gridPrefix + 'LineColor'],
30011                    dashStyle = options[gridPrefix + 'LineDashStyle'];
30012
30013
30014                if (!gridLine) {
30015
30016                    attribs.stroke = gridLineColor;
30017                    attribs['stroke-width'] = gridLineWidth;
30018                    if (dashStyle) {
30019                        attribs.dashstyle = dashStyle;
30020                    }
30021
30022                    if (!type) {
30023                        attribs.zIndex = 1;
30024                    }
30025                    if (old) {
30026                        attribs.opacity = 0;
30027                    }
30028                    tick.gridLine = gridLine = renderer.path()
30029                        .attr(attribs)
30030                        .addClass(
30031                            'highcharts-' + (type ? type + '-' : '') + 'grid-line'
30032                        )
30033                        .add(axis.gridGroup);
30034                }
30035
30036                // If the parameter 'old' is set, the current call will be followed
30037                // by another call, therefore do not do any animations this time
30038                if (!old && gridLine) {
30039                    gridLinePath = axis.getPlotLinePath(
30040                        pos + tickmarkOffset,
30041                        gridLine.strokeWidth() * reverseCrisp,
30042                        old, true
30043                    );
30044                    if (gridLinePath) {
30045                        gridLine[tick.isNew ? 'attr' : 'animate']({
30046                            d: gridLinePath,
30047                            opacity: opacity
30048                        });
30049                    }
30050                }
30051            },
30052
30053            /**
30054             * Renders the tick mark.
30055             * @param  {Object} xy           The position vector of the mark
30056             * @param  {number} xy.x         The x position of the mark
30057             * @param  {number} xy.y         The y position of the mark
30058             * @param  {number} opacity      The opacity of the mark
30059             * @param  {number} reverseCrisp Modifier for avoiding overlapping 1 or -1
30060             * @return {undefined}
30061             */
30062            renderMark: function(xy, opacity, reverseCrisp) {
30063                var tick = this,
30064                    axis = tick.axis,
30065                    options = axis.options,
30066                    renderer = axis.chart.renderer,
30067                    type = tick.type,
30068                    tickPrefix = type ? type + 'Tick' : 'tick',
30069                    tickSize = axis.tickSize(tickPrefix),
30070                    mark = tick.mark,
30071                    isNewMark = !mark,
30072                    x = xy.x,
30073                    y = xy.y;
30074
30075
30076                var tickWidth = pick(
30077                        options[tickPrefix + 'Width'], !type && axis.isXAxis ? 1 : 0
30078                    ), // X axis defaults to 1
30079                    tickColor = options[tickPrefix + 'Color'];
30080
30081
30082                if (tickSize) {
30083
30084                    // negate the length
30085                    if (axis.opposite) {
30086                        tickSize[0] = -tickSize[0];
30087                    }
30088
30089                    // First time, create it
30090                    if (isNewMark) {
30091                        tick.mark = mark = renderer.path()
30092                            .addClass('highcharts-' + (type ? type + '-' : '') + 'tick')
30093                            .add(axis.axisGroup);
30094
30095
30096                        mark.attr({
30097                            stroke: tickColor,
30098                            'stroke-width': tickWidth
30099                        });
30100
30101                    }
30102                    mark[isNewMark ? 'attr' : 'animate']({
30103                        d: tick.getMarkPath(
30104                            x,
30105                            y,
30106                            tickSize[0],
30107                            mark.strokeWidth() * reverseCrisp,
30108                            axis.horiz,
30109                            renderer),
30110                        opacity: opacity
30111                    });
30112
30113                }
30114            },
30115
30116            /**
30117             * Renders the tick label.
30118             * Note: The label should already be created in init(), so it should only
30119             * have to be moved into place.
30120             * @param  {Object} xy      The position vector of the label
30121             * @param  {number} xy.x    The x position of the label
30122             * @param  {number} xy.y    The y position of the label
30123             * @param  {Boolean} old    Whether or not the tick is old
30124             * @param  {number} opacity The opacity of the label
30125             * @param  {number} index   The index of the tick
30126             * @return {undefined}
30127             */
30128            renderLabel: function(xy, old, opacity, index) {
30129                var tick = this,
30130                    axis = tick.axis,
30131                    horiz = axis.horiz,
30132                    options = axis.options,
30133                    label = tick.label,
30134                    labelOptions = options.labels,
30135                    step = labelOptions.step,
30136                    tickmarkOffset = axis.tickmarkOffset,
30137                    show = true,
30138                    x = xy.x,
30139                    y = xy.y;
30140                if (label && isNumber(x)) {
30141                    label.xy = xy = tick.getLabelPosition(
30142                        x,
30143                        y,
30144                        label,
30145                        horiz,
30146                        labelOptions,
30147                        tickmarkOffset,
30148                        index,
30149                        step
30150                    );
30151
30152                    // Apply show first and show last. If the tick is both first and
30153                    // last, it is a single centered tick, in which case we show the
30154                    // label anyway (#2100).
30155                    if (
30156                        (
30157                            tick.isFirst &&
30158                            !tick.isLast &&
30159                            !pick(options.showFirstLabel, 1)
30160                        ) ||
30161                        (
30162                            tick.isLast &&
30163                            !tick.isFirst &&
30164                            !pick(options.showLastLabel, 1)
30165                        )
30166                    ) {
30167                        show = false;
30168
30169                        // Handle label overflow and show or hide accordingly
30170                    } else if (horiz && !axis.isRadial && !labelOptions.step &&
30171                        !labelOptions.rotation && !old && opacity !== 0) {
30172                        tick.handleOverflow(xy);
30173                    }
30174
30175                    // apply step
30176                    if (step && index % step) {
30177                        // show those indices dividable by step
30178                        show = false;
30179                    }
30180
30181                    // Set the new position, and show or hide
30182                    if (show && isNumber(xy.y)) {
30183                        xy.opacity = opacity;
30184                        label[tick.isNewLabel ? 'attr' : 'animate'](xy);
30185                        tick.isNewLabel = false;
30186                    } else {
30187                        label.attr('y', -9999); // #1338
30188                        tick.isNewLabel = true;
30189                    }
30190                }
30191            },
30192
30193            /**
30194             * Put everything in place
30195             *
30196             * @param index {Number}
30197             * @param old {Boolean} Use old coordinates to prepare an animation into new
30198             *                      position
30199             */
30200            render: function(index, old, opacity) {
30201                var tick = this,
30202                    axis = tick.axis,
30203                    horiz = axis.horiz,
30204                    pos = tick.pos,
30205                    tickmarkOffset = axis.tickmarkOffset,
30206                    xy = tick.getPosition(horiz, pos, tickmarkOffset, old),
30207                    x = xy.x,
30208                    y = xy.y,
30209                    reverseCrisp = ((horiz && x === axis.pos + axis.len) ||
30210                        (!horiz && y === axis.pos)) ? -1 : 1; // #1480, #1687
30211
30212                opacity = pick(opacity, 1);
30213                this.isActive = true;
30214
30215                // Create the grid line
30216                this.renderGridLine(old, opacity, reverseCrisp);
30217
30218                // create the tick mark
30219                this.renderMark(xy, opacity, reverseCrisp);
30220
30221                // the label is created on init - now move it into place
30222                this.renderLabel(xy, old, opacity, index);
30223
30224                tick.isNew = false;
30225            },
30226
30227            /**
30228             * Destructor for the tick prototype
30229             */
30230            destroy: function() {
30231                destroyObjectProperties(this, this.axis);
30232            }
30233        };
30234
30235    }(Highcharts));
30236    var Axis = (function(H) {
30237        /**
30238         * (c) 2010-2017 Torstein Honsi
30239         *
30240         * License: www.highcharts.com/license
30241         */
30242
30243        var addEvent = H.addEvent,
30244            animObject = H.animObject,
30245            arrayMax = H.arrayMax,
30246            arrayMin = H.arrayMin,
30247            color = H.color,
30248            correctFloat = H.correctFloat,
30249            defaultOptions = H.defaultOptions,
30250            defined = H.defined,
30251            deg2rad = H.deg2rad,
30252            destroyObjectProperties = H.destroyObjectProperties,
30253            each = H.each,
30254            extend = H.extend,
30255            fireEvent = H.fireEvent,
30256            format = H.format,
30257            getMagnitude = H.getMagnitude,
30258            grep = H.grep,
30259            inArray = H.inArray,
30260            isArray = H.isArray,
30261            isNumber = H.isNumber,
30262            isString = H.isString,
30263            merge = H.merge,
30264            normalizeTickInterval = H.normalizeTickInterval,
30265            objectEach = H.objectEach,
30266            pick = H.pick,
30267            removeEvent = H.removeEvent,
30268            splat = H.splat,
30269            syncTimeout = H.syncTimeout,
30270            Tick = H.Tick;
30271
30272        /**
30273         * Create a new axis object. Called internally when instanciating a new chart or
30274         * adding axes by {@link Highcharts.Chart#addAxis}.
30275         *
30276         * A chart can have from 0 axes (pie chart) to multiples. In a normal, single
30277         * series cartesian chart, there is one X axis and one Y axis.
30278         * 
30279         * The X axis or axes are referenced by {@link Highcharts.Chart.xAxis}, which is
30280         * an array of Axis objects. If there is only one axis, it can be referenced
30281         * through `chart.xAxis[0]`, and multiple axes have increasing indices. The same
30282         * pattern goes for Y axes.
30283         * 
30284         * If you need to get the axes from a series object, use the `series.xAxis` and
30285         * `series.yAxis` properties. These are not arrays, as one series can only be
30286         * associated to one X and one Y axis.
30287         * 
30288         * A third way to reference the axis programmatically is by `id`. Add an `id` in
30289         * the axis configuration options, and get the axis by
30290         * {@link Highcharts.Chart#get}.
30291         * 
30292         * Configuration options for the axes are given in options.xAxis and
30293         * options.yAxis.
30294         * 
30295         * @class Highcharts.Axis
30296         * @memberOf Highcharts
30297         * @param {Highcharts.Chart} chart - The Chart instance to apply the axis on.
30298         * @param {Object} options - Axis options
30299         */
30300        var Axis = function() {
30301            this.init.apply(this, arguments);
30302        };
30303
30304        H.extend(Axis.prototype, /** @lends Highcharts.Axis.prototype */ {
30305
30306            /**
30307             * The X axis or category axis. Normally this is the horizontal axis,
30308             * though if the chart is inverted this is the vertical axis. In case of
30309             * multiple axes, the xAxis node is an array of configuration objects.
30310             * 
30311             * See [the Axis object](#Axis) for programmatic access to the axis.
30312             *
30313             * @productdesc {highmaps}
30314             * In Highmaps, the axis is hidden, but it is used behind the scenes to
30315             * control features like zooming and panning. Zooming is in effect the same
30316             * as setting the extremes of one of the exes.
30317             * 
30318             * @optionparent xAxis
30319             */
30320            defaultOptions: {
30321                /**
30322                 * Whether to allow decimals in this axis' ticks. When counting
30323                 * integers, like persons or hits on a web page, decimals should
30324                 * be avoided in the labels.
30325                 *
30326                 * @type      {Boolean}
30327                 * @see       [minTickInterval](#xAxis.minTickInterval)
30328                 * @sample    {highcharts|highstock}
30329                 *            highcharts/yaxis/allowdecimals-true/
30330                 *            True by default
30331                 * @sample    {highcharts|highstock}
30332                 *            highcharts/yaxis/allowdecimals-false/
30333                 *            False
30334                 * @default   true
30335                 * @since     2.0
30336                 * @apioption xAxis.allowDecimals
30337                 */
30338                // allowDecimals: null,
30339
30340
30341                /**
30342                 * When using an alternate grid color, a band is painted across the
30343                 * plot area between every other grid line.
30344                 *
30345                 * @type      {Color}
30346                 * @sample    {highcharts} highcharts/yaxis/alternategridcolor/
30347                 *            Alternate grid color on the Y axis
30348                 * @sample    {highstock} stock/xaxis/alternategridcolor/
30349                 *            Alternate grid color on the Y axis
30350                 * @default   null
30351                 * @apioption xAxis.alternateGridColor
30352                 */
30353                // alternateGridColor: null,
30354
30355                /**
30356                 * An array defining breaks in the axis, the sections defined will be
30357                 * left out and all the points shifted closer to each other.
30358                 *
30359                 * @productdesc {highcharts}
30360                 * Requires that the broken-axis.js module is loaded.
30361                 *
30362                 * @type      {Array}
30363                 * @sample    {highcharts}
30364                 *            highcharts/axisbreak/break-simple/
30365                 *            Simple break
30366                 * @sample    {highcharts|highstock}
30367                 *            highcharts/axisbreak/break-visualized/
30368                 *            Advanced with callback
30369                 * @sample    {highstock}
30370                 *            stock/demo/intraday-breaks/
30371                 *            Break on nights and weekends
30372                 * @since     4.1.0
30373                 * @product   highcharts highstock
30374                 * @apioption xAxis.breaks
30375                 */
30376
30377                /**
30378                 * A number indicating how much space should be left between the start
30379                 * and the end of the break. The break size is given in axis units,
30380                 * so for instance on a `datetime` axis, a break size of 3600000 would
30381                 * indicate the equivalent of an hour.
30382                 *
30383                 * @type      {Number}
30384                 * @default   0
30385                 * @since     4.1.0
30386                 * @product   highcharts highstock
30387                 * @apioption xAxis.breaks.breakSize
30388                 */
30389
30390                /**
30391                 * The point where the break starts.
30392                 *
30393                 * @type      {Number}
30394                 * @since     4.1.0
30395                 * @product   highcharts highstock
30396                 * @apioption xAxis.breaks.from
30397                 */
30398
30399                /**
30400                 * Defines an interval after which the break appears again. By default
30401                 * the breaks do not repeat.
30402                 *
30403                 * @type      {Number}
30404                 * @default   0
30405                 * @since     4.1.0
30406                 * @product   highcharts highstock
30407                 * @apioption xAxis.breaks.repeat
30408                 */
30409
30410                /**
30411                 * The point where the break ends.
30412                 *
30413                 * @type      {Number}
30414                 * @since     4.1.0
30415                 * @product   highcharts highstock
30416                 * @apioption xAxis.breaks.to
30417                 */
30418
30419                /**
30420                 * If categories are present for the xAxis, names are used instead of
30421                 * numbers for that axis. Since Highcharts 3.0, categories can also
30422                 * be extracted by giving each point a [name](#series.data) and setting
30423                 * axis [type](#xAxis.type) to `category`. However, if you have multiple
30424                 * series, best practice remains defining the `categories` array.
30425                 *
30426                 * Example:
30427                 *
30428                 * <pre>categories: ['Apples', 'Bananas', 'Oranges']</pre>
30429                 *
30430                 * @type      {Array<String>}
30431                 * @sample    {highcharts} highcharts/chart/reflow-true/
30432                 *            With
30433                 * @sample    {highcharts} highcharts/xaxis/categories/
30434                 *            Without
30435                 * @product   highcharts
30436                 * @default   null
30437                 * @apioption xAxis.categories
30438                 */
30439                // categories: [],
30440
30441                /**
30442                 * The highest allowed value for automatically computed axis extremes.
30443                 *
30444                 * @type      {Number}
30445                 * @see       [floor](#xAxis.floor)
30446                 * @sample    {highcharts|highstock} highcharts/yaxis/floor-ceiling/
30447                 *            Floor and ceiling
30448                 * @since     4.0
30449                 * @product   highcharts highstock
30450                 * @apioption xAxis.ceiling
30451                 */
30452
30453                /**
30454                 * A class name that opens for styling the axis by CSS, especially in
30455                 * Highcharts styled mode. The class name is applied to group elements
30456                 * for the grid, axis elements and labels.
30457                 *
30458                 * @type      {String}
30459                 * @sample    {highcharts|highstock|highmaps}
30460                 *            highcharts/css/axis/
30461                 *            Multiple axes with separate styling
30462                 * @since     5.0.0
30463                 * @apioption xAxis.className
30464                 */
30465
30466                /**
30467                 * Configure a crosshair that follows either the mouse pointer or the
30468                 * hovered point.
30469                 *
30470                 * In styled mode, the crosshairs are styled in the
30471                 * `.highcharts-crosshair`, `.highcharts-crosshair-thin` or
30472                 * `.highcharts-xaxis-category` classes.
30473                 *
30474                 * @productdesc {highstock}
30475                 * In Highstock, bu default, the crosshair is enabled on the X axis and
30476                 * disabled on the Y axis.
30477                 *
30478                 * @type      {Boolean|Object}
30479                 * @sample    {highcharts} highcharts/xaxis/crosshair-both/
30480                 *            Crosshair on both axes
30481                 * @sample    {highstock} stock/xaxis/crosshairs-xy/
30482                 *            Crosshair on both axes
30483                 * @sample    {highmaps} highcharts/xaxis/crosshair-both/
30484                 *            Crosshair on both axes
30485                 * @default   false
30486                 * @since     4.1
30487                 * @apioption xAxis.crosshair
30488                 */
30489
30490                /**
30491                 * A class name for the crosshair, especially as a hook for styling.
30492                 *
30493                 * @type      {String}
30494                 * @since     5.0.0
30495                 * @apioption xAxis.crosshair.className
30496                 */
30497
30498                /**
30499                 * The color of the crosshair. Defaults to `#cccccc` for numeric and
30500                 * datetime axes, and `rgba(204,214,235,0.25)` for category axes, where
30501                 * the crosshair by default highlights the whole category.
30502                 *
30503                 * @type      {Color}
30504                 * @sample    {highcharts|highstock|highmaps}
30505                 *            highcharts/xaxis/crosshair-customized/
30506                 *            Customized crosshairs
30507                 * @default   #cccccc
30508                 * @since     4.1
30509                 * @apioption xAxis.crosshair.color
30510                 */
30511
30512                /**
30513                 * The dash style for the crosshair. See
30514                 * [series.dashStyle](#plotOptions.series.dashStyle)
30515                 * for possible values.
30516                 *
30517                 * @validvalue ["Solid", "ShortDash", "ShortDot", "ShortDashDot",
30518                 *              "ShortDashDotDot", "Dot", "Dash" ,"LongDash",
30519                 *              "DashDot", "LongDashDot", "LongDashDotDot"]
30520                 * @type       {String}
30521                 * @sample     {highcharts|highmaps} highcharts/xaxis/crosshair-dotted/
30522                 *             Dotted crosshair
30523                 * @sample     {highstock} stock/xaxis/crosshair-dashed/
30524                 *             Dashed X axis crosshair
30525                 * @default    Solid
30526                 * @since      4.1
30527                 * @apioption  xAxis.crosshair.dashStyle
30528                 */
30529
30530                /**
30531                 * Whether the crosshair should snap to the point or follow the pointer
30532                 * independent of points.
30533                 *
30534                 * @type      {Boolean}
30535                 * @sample    {highcharts|highstock}
30536                 *            highcharts/xaxis/crosshair-snap-false/
30537                 *            True by default
30538                 * @sample    {highmaps}
30539                 *            maps/demo/latlon-advanced/
30540                 *            Snap is false
30541                 * @default   true
30542                 * @since     4.1
30543                 * @apioption xAxis.crosshair.snap
30544                 */
30545
30546                /**
30547                 * The pixel width of the crosshair. Defaults to 1 for numeric or
30548                 * datetime axes, and for one category width for category axes.
30549                 *
30550                 * @type      {Number}
30551                 * @sample    {highcharts} highcharts/xaxis/crosshair-customized/
30552                 *            Customized crosshairs
30553                 * @sample    {highstock} highcharts/xaxis/crosshair-customized/
30554                 *            Customized crosshairs
30555                 * @sample    {highmaps} highcharts/xaxis/crosshair-customized/
30556                 *            Customized crosshairs
30557                 * @default   1
30558                 * @since     4.1
30559                 * @apioption xAxis.crosshair.width
30560                 */
30561
30562                /**
30563                 * The Z index of the crosshair. Higher Z indices allow drawing the
30564                 * crosshair on top of the series or behind the grid lines.
30565                 *
30566                 * @type      {Number}
30567                 * @default   2
30568                 * @since     4.1
30569                 * @apioption xAxis.crosshair.zIndex
30570                 */
30571
30572                /**
30573                 * For a datetime axis, the scale will automatically adjust to the
30574                 * appropriate unit. This member gives the default string
30575                 * representations used for each unit. For intermediate values,
30576                 * different units may be used, for example the `day` unit can be used
30577                 * on midnight and `hour` unit be used for intermediate values on the
30578                 * same axis. For an overview of the replacement codes, see
30579                 * [dateFormat](#Highcharts.dateFormat). Defaults to:
30580                 * 
30581                 * <pre>{
30582                 *     millisecond: '%H:%M:%S.%L',
30583                 *     second: '%H:%M:%S',
30584                 *     minute: '%H:%M',
30585                 *     hour: '%H:%M',
30586                 *     day: '%e. %b',
30587                 *     week: '%e. %b',
30588                 *     month: '%b \'%y',
30589                 *     year: '%Y'
30590                 * }</pre>
30591                 * 
30592                 * @type    {Object}
30593                 * @sample  {highcharts} highcharts/xaxis/datetimelabelformats/
30594                 *          Different day format on X axis
30595                 * @sample  {highstock} stock/xaxis/datetimelabelformats/
30596                 *          More information in x axis labels
30597                 * @product highcharts highstock
30598                 */
30599                dateTimeLabelFormats: {
30600                    millisecond: '%H:%M:%S.%L',
30601                    second: '%H:%M:%S',
30602                    minute: '%H:%M',
30603                    hour: '%H:%M',
30604                    day: '%e. %b',
30605                    week: '%e. %b',
30606                    month: '%b \'%y',
30607                    year: '%Y'
30608                },
30609
30610                /**
30611                 * _Requires Accessibility module_
30612                 *
30613                 * Description of the axis to screen reader users.
30614                 *
30615                 * @type      {String}
30616                 * @default   undefined
30617                 * @since     5.0.0
30618                 * @apioption xAxis.description
30619                 */
30620
30621                /**
30622                 * Whether to force the axis to end on a tick. Use this option with
30623                 * the `maxPadding` option to control the axis end.
30624                 *
30625                 * @productdesc {highstock}
30626                 * In Highstock, `endOnTick` is always false when the navigator is
30627                 * enabled, to prevent jumpy scrolling.
30628                 * 
30629                 * @sample {highcharts} highcharts/chart/reflow-true/
30630                 *         True by default
30631                 * @sample {highcharts} highcharts/yaxis/endontick/
30632                 *         False
30633                 * @sample {highstock} stock/demo/basic-line/
30634                 *         True by default
30635                 * @sample {highstock} stock/xaxis/endontick/
30636                 *         False
30637                 * @since  1.2.0
30638                 */
30639                endOnTick: false,
30640
30641                /**
30642                 * Event handlers for the axis.
30643                 *
30644                 * @apioption xAxis.events
30645                 */
30646
30647                /**
30648                 * An event fired after the breaks have rendered.
30649                 *
30650                 * @type      {Function}
30651                 * @see       [breaks](#xAxis.breaks)
30652                 * @sample    {highcharts} highcharts/axisbreak/break-event/
30653                 *            AfterBreak Event
30654                 * @since     4.1.0
30655                 * @product   highcharts
30656                 * @apioption xAxis.events.afterBreaks
30657                 */
30658
30659                /**
30660                 * As opposed to the `setExtremes` event, this event fires after the
30661                 * final min and max values are computed and corrected for `minRange`.
30662                 *
30663                 *
30664                 * Fires when the minimum and maximum is set for the axis, either by
30665                 * calling the `.setExtremes()` method or by selecting an area in the
30666                 * chart. One parameter, `event`, is passed to the function, containing
30667                 * common event information.
30668                 *
30669                 * The new user set minimum and maximum values can be found by `event.
30670                 * min` and `event.max`. These reflect the axis minimum and maximum
30671                 * in axis values. The actual data extremes are found in `event.dataMin`
30672                 * and `event.dataMax`.
30673                 *
30674                 * @type      {Function}
30675                 * @context   Axis
30676                 * @since     2.3
30677                 * @apioption xAxis.events.afterSetExtremes
30678                 */
30679
30680                /**
30681                 * An event fired when a break from this axis occurs on a point.
30682                 *
30683                 * @type      {Function}
30684                 * @see       [breaks](#xAxis.breaks)
30685                 * @context   Axis
30686                 * @sample    {highcharts} highcharts/axisbreak/break-visualized/
30687                 *            Visualization of a Break
30688                 * @since     4.1.0
30689                 * @product   highcharts
30690                 * @apioption xAxis.events.pointBreak
30691                 */
30692
30693                /**
30694                 * An event fired when a point falls inside a break from this axis.
30695                 *
30696                 * @type      {Function}
30697                 * @context   Axis
30698                 * @product   highcharts highstock
30699                 * @apioption xAxis.events.pointInBreak
30700                 */
30701
30702                /**
30703                 * Fires when the minimum and maximum is set for the axis, either by
30704                 * calling the `.setExtremes()` method or by selecting an area in the
30705                 * chart. One parameter, `event`, is passed to the function,
30706                 * containing common event information.
30707                 *
30708                 * The new user set minimum and maximum values can be found by `event.
30709                 * min` and `event.max`. These reflect the axis minimum and maximum
30710                 * in data values. When an axis is zoomed all the way out from the 
30711                 * "Reset zoom" button, `event.min` and `event.max` are null, and
30712                 * the new extremes are set based on `this.dataMin` and `this.dataMax`.
30713                 *
30714                 * @type      {Function}
30715                 * @context   Axis
30716                 * @sample    {highstock} stock/xaxis/events-setextremes/
30717                 *            Log new extremes on x axis
30718                 * @since     1.2.0
30719                 * @apioption xAxis.events.setExtremes
30720                 */
30721
30722                /**
30723                 * The lowest allowed value for automatically computed axis extremes.
30724                 *
30725                 * @type      {Number}
30726                 * @see       [ceiling](#yAxis.ceiling)
30727                 * @sample    {highcharts} highcharts/yaxis/floor-ceiling/
30728                 *            Floor and ceiling
30729                 * @sample    {highstock} stock/demo/lazy-loading/
30730                 *            Prevent negative stock price on Y axis
30731                 * @default   null
30732                 * @since     4.0
30733                 * @product   highcharts highstock
30734                 * @apioption xAxis.floor
30735                 */
30736
30737                /**
30738                 * The dash or dot style of the grid lines. For possible values, see
30739                 * [this demonstration](http://jsfiddle.net/gh/get/library/pure/
30740                 *highcharts/highcharts/tree/master/samples/highcharts/plotoptions/
30741                 *series-dashstyle-all/).
30742                 *
30743                 * @validvalue ["Solid", "ShortDash", "ShortDot", "ShortDashDot",
30744                 *              "ShortDashDotDot", "Dot", "Dash" ,"LongDash",
30745                 *              "DashDot", "LongDashDot", "LongDashDotDot"]
30746                 * @type       {String}
30747                 * @sample     {highcharts} highcharts/yaxis/gridlinedashstyle/
30748                 *             Long dashes
30749                 * @sample     {highstock} stock/xaxis/gridlinedashstyle/
30750                 *             Long dashes
30751                 * @default    Solid
30752                 * @since      1.2
30753                 * @apioption  xAxis.gridLineDashStyle
30754                 */
30755
30756                /**
30757                 * The Z index of the grid lines.
30758                 *
30759                 * @type      {Number}
30760                 * @sample    {highcharts|highstock} highcharts/xaxis/gridzindex/
30761                 *            A Z index of 4 renders the grid above the graph
30762                 * @default   1
30763                 * @product   highcharts highstock
30764                 * @apioption xAxis.gridZIndex
30765                 */
30766
30767                /**
30768                 * An id for the axis. This can be used after render time to get
30769                 * a pointer to the axis object through `chart.get()`.
30770                 *
30771                 * @type      {String}
30772                 * @sample    {highcharts} highcharts/xaxis/id/
30773                 *            Get the object
30774                 * @sample    {highstock} stock/xaxis/id/
30775                 *            Get the object
30776                 * @default   null
30777                 * @since     1.2.0
30778                 * @apioption xAxis.id
30779                 */
30780
30781                /**
30782                 * The axis labels show the number or category for each tick.
30783                 *
30784                 * @productdesc {highmaps}
30785                 * X and Y axis labels are by default disabled in Highmaps, but the
30786                 * functionality is inherited from Highcharts and used on `colorAxis`,
30787                 * and can be enabled on X and Y axes too.
30788                 */
30789                labels: {
30790                    /**
30791                     * What part of the string the given position is anchored to.
30792                     * If `left`, the left side of the string is at the axis position.
30793                     * Can be one of `"left"`, `"center"` or `"right"`. Defaults to
30794                     * an intelligent guess based on which side of the chart the axis
30795                     * is on and the rotation of the label.
30796                     *
30797                     * @validvalue ["left", "center", "right"]
30798                     * @type       {String}
30799                     * @sample     {highcharts} highcharts/xaxis/labels-align-left/
30800                     *             Left
30801                     * @sample     {highcharts} highcharts/xaxis/labels-align-right/
30802                     *             Right
30803                     * @apioption  xAxis.labels.align
30804                     */
30805                    // align: 'center',
30806
30807                    /**
30808                     * For horizontal axes, the allowed degrees of label rotation
30809                     * to prevent overlapping labels. If there is enough space,
30810                     * labels are not rotated. As the chart gets narrower, it
30811                     * will start rotating the labels -45 degrees, then remove
30812                     * every second label and try again with rotations 0 and -45 etc.
30813                     * Set it to `false` to disable rotation, which will
30814                     * cause the labels to word-wrap if possible.
30815                     *
30816                     * @type      {Array<Number>}
30817                     * @sample    {highcharts|highstock}
30818                     *            highcharts/xaxis/labels-autorotation-default/
30819                     *            Default auto rotation of 0 or -45
30820                     * @sample    {highcharts|highstock}
30821                     *            highcharts/xaxis/labels-autorotation-0-90/
30822                     *            Custom graded auto rotation
30823                     * @default   [-45]
30824                     * @since     4.1.0
30825                     * @product   highcharts highstock
30826                     * @apioption xAxis.labels.autoRotation
30827                     */
30828
30829                    /**
30830                     * When each category width is more than this many pixels, we don't
30831                     * apply auto rotation. Instead, we lay out the axis label with word
30832                     * wrap. A lower limit makes sense when the label contains multiple
30833                     * short words that don't extend the available horizontal space for
30834                     * each label.
30835                     *
30836                     * @type      {Number}
30837                     * @sample    {highcharts}
30838                     *            highcharts/xaxis/labels-autorotationlimit/
30839                     *            Lower limit
30840                     * @default   80
30841                     * @since     4.1.5
30842                     * @product   highcharts
30843                     * @apioption xAxis.labels.autoRotationLimit
30844                     */
30845
30846                    /**
30847                     * Polar charts only. The label's pixel distance from the perimeter
30848                     * of the plot area.
30849                     *
30850                     * @type      {Number}
30851                     * @default   15
30852                     * @product   highcharts
30853                     * @apioption xAxis.labels.distance
30854                     */
30855
30856                    /**
30857                     * Enable or disable the axis labels.
30858                     * 
30859                     * @sample  {highcharts} highcharts/xaxis/labels-enabled/
30860                     *          X axis labels disabled
30861                     * @sample  {highstock} stock/xaxis/labels-enabled/
30862                     *          X axis labels disabled
30863                     * @default {highcharts|highstock} true
30864                     * @default {highmaps} false
30865                     */
30866                    enabled: true,
30867
30868                    /**
30869                     * A [format string](http://www.highcharts.com/docs/chart-
30870                     * concepts/labels-and-string-formatting) for the axis label.
30871                     *
30872                     * @type      {String}
30873                     * @sample    {highcharts|highstock} highcharts/yaxis/labels-format/
30874                     *            Add units to Y axis label
30875                     * @default   {value}
30876                     * @since     3.0
30877                     * @apioption xAxis.labels.format
30878                     */
30879
30880                    /**
30881                     * Callback JavaScript function to format the label. The value
30882                     * is given by `this.value`. Additional properties for `this` are
30883                     * `axis`, `chart`, `isFirst` and `isLast`. The value of the default
30884                     * label formatter can be retrieved by calling
30885                     * `this.axis.defaultLabelFormatter.call(this)` within the function.
30886                     *
30887                     * Defaults to:
30888                     *
30889                     * <pre>function() {
30890                     *     return this.value;
30891                     * }</pre>
30892                     *
30893                     * @type      {Function}
30894                     * @sample    {highcharts}
30895                     *            highcharts/xaxis/labels-formatter-linked/
30896                     *            Linked category names
30897                     * @sample    {highcharts}
30898                     *            highcharts/xaxis/labels-formatter-extended/
30899                     *            Modified numeric labels
30900                     * @sample    {highstock}
30901                     *            stock/xaxis/labels-formatter/
30902                     *            Added units on Y axis
30903                     * @apioption xAxis.labels.formatter
30904                     */
30905
30906                    /**
30907                     * How to handle overflowing labels on horizontal axis. Can be
30908                     * undefined, `false` or `"justify"`. By default it aligns 
30908inside
30909                     * the chart area. If "justify", labels will not render outside
30910                     * the plot area. If `false`, it will not be aligned at all.
30911                     * If there is room to move it, it will be aligned to the edge,
30912                     * else it will be removed.
30913                     *
30914                     * @deprecated
30915                     * @validvalue [null, "justify"]
30916                     * @type       {String}
30917                     * @since      2.2.5
30918                     * @apioption  xAxis.labels.overflow
30919                     */
30920
30921                    /**
30922                     * The pixel padding for axis labels, to ensure white space between
30923                     * them.
30924                     *
30925                     * @type      {Number}
30926                     * @default   5
30927                     * @product   highcharts
30928                     * @apioption xAxis.labels.padding
30929                     */
30930
30931                    /**
30932                     * Whether to reserve space for the labels. This can be turned off
30933                     * when for example the labels are rendered inside the plot area
30934                     * instead of outside.
30935                     *
30936                     * @type      {Boolean}
30937                     * @sample    {highcharts} highcharts/xaxis/labels-reservespace/
30938                     *            No reserved space, labels inside plot
30939                     * @default   true
30940                     * @since     4.1.10
30941                     * @product   highcharts
30942                     * @apioption xAxis.labels.reserveSpace
30943                     */
30944
30945                    /**
30946                     * Rotation of the labels in degrees.
30947                     *
30948                     * @type      {Number}
30949                     * @sample    {highcharts} highcharts/xaxis/labels-rotation/
30950                     *            X axis labels rotated 90°
30951                     * @default   0
30952                     * @apioption xAxis.labels.rotation
30953                     */
30954                    // rotation: 0,
30955
30956                    /**
30957                     * Horizontal axes only. The number of lines to spread the labels
30958                     * over to make room or tighter labels.
30959                     *
30960                     * @type      {Number}
30961                     * @sample    {highcharts} highcharts/xaxis/labels-staggerlines/
30962                     *            Show labels over two lines
30963                     * @sample    {highstock} stock/xaxis/labels-staggerlines/
30964                     *            Show labels over two lines
30965                     * @default   null
30966                     * @since     2.1
30967                     * @apioption xAxis.labels.staggerLines
30968                     */
30969
30970                    /**
30971                     * To show only every _n_'th label on the axis, set the step to _n_.
30972                     * Setting the step to 2 shows every other label.
30973                     *
30974                     * By default, the step is calculated automatically to avoid
30975                     * overlap. To prevent this, set it to 1\. This usually only
30976                     * happens on a category axis, and is often a sign that you have
30977                     * chosen the wrong axis type.
30978                     *
30979                     * Read more at
30980                     * [Axis docs](http://www.highcharts.com/docs/chart-concepts/axes)
30981                     * => What axis should I use?
30982                     *
30983                     * @type      {Number}
30984                     * @sample    {highcharts} highcharts/xaxis/labels-step/
30985                     *            Showing only every other axis label on a categorized
30986                     *            x axis
30987                     * @sample    {highcharts} highcharts/xaxis/labels-step-auto/
30988                     *            Auto steps on a category axis
30989                     * @default   null
30990                     * @since     2.1
30991                     * @apioption xAxis.labels.step
30992                     */
30993                    // step: null,
30994
30995
30996
30997                    /**
30998                     * CSS styles for the label. Use `whiteSpace: 'nowrap'` to prevent
30999                     * wrapping of category labels. Use `textOverflow: 'none'` to
31000                     * prevent ellipsis (dots).
31001                     * 
31002                     * In styled mode, the labels are styled with the
31003                     * `.highcharts-axis-labels` class.
31004                     * 
31005                     * @type   {CSSObject}
31006                     * @sample {highcharts} highcharts/xaxis/labels-style/
31007                     *         Red X axis labels
31008                     */
31009                    style: {
31010                        color: '#666666',
31011                        cursor: 'default',
31012                        fontSize: '11px'
31013                    },
31014
31015
31016                    /**
31017                     * Whether to [use HTML](http://www.highcharts.com/docs/chart-
31018                     * concepts/labels-and-string-formatting#html) to render the labels.
31019                     *
31020                     * @type      {Boolean}
31021                     * @default   false
31022                     * @apioption xAxis.labels.useHTML
31023                     */
31024
31025                    /**
31026                     * The x position offset of the label relative to the tick position
31027                     * on the axis.
31028                     * 
31029                     * @sample {highcharts} highcharts/xaxis/labels-x/
31030                     *         Y axis labels placed on grid lines
31031                     */
31032                    x: 0
31033
31034                    /**
31035                     * The y position offset of the label relative to the tick position
31036                     * on the axis. The default makes it adapt to the font size on
31037                     * bottom axis.
31038                     *
31039                     * @type      {Number}
31040                     * @sample    {highcharts} highcharts/xaxis/labels-x/
31041                     *            Y axis labels placed on grid lines
31042                     * @default   null
31043                     * @apioption xAxis.labels.y
31044                     */
31045
31046                    /**
31047                     * The Z index for the axis labels.
31048                     *
31049                     * @type {Number}
31050                     * @default 7
31051                     * @apioption xAxis.labels.zIndex
31052                     */
31053                },
31054
31055                /**
31056                 * Index of another axis that this axis is linked to. When an axis is
31057                 * linked to a master axis, it will take the same extremes as
31058                 * the master, but as assigned by min or max or by setExtremes.
31059                 * It can be used to show additional info, or to ease reading the
31060                 * chart by duplicating the scales.
31061                 *
31062                 * @type      {Number}
31063                 * @sample    {highcharts} highcharts/xaxis/linkedto/
31064                 *            Different string formats of the same date
31065                 * @sample    {highcharts} highcharts/yaxis/linkedto/
31066                 *            Y values on both sides
31067                 * @default   null
31068                 * @since     2.0.2
31069                 * @product   highcharts highstock
31070                 * @apioption xAxis.linkedTo
31071                 */
31072
31073                /**
31074                 * The maximum value of the axis. If `null`, the max value is
31075                 * automatically calculated.
31076                 *
31077                 * If the `endOnTick` option is true, the `max` value might
31078                 * be rounded up.
31079                 *
31080                 * If a [tickAmount](#yAxis.tickAmount) is set, the axis may be extended
31081                 * beyond the set max in order to reach the given number of ticks. The
31082                 * same may happen in a chart with multiple axes, determined by [chart.
31083                 * alignTicks](#chart), where a `tickAmount` is applied internally.
31084                 *
31085                 * @type      {Number}
31086                 * @sample    {highcharts} highcharts/yaxis/max-200/
31087                 *            Y axis max of 200
31088                 * @sample    {highcharts} highcharts/yaxis/max-logarithmic/
31089                 *            Y axis max on logarithmic axis
31090                 * @sample    {highstock} stock/xaxis/min-max/
31091                 *            Fixed min and max on X axis
31092                 * @sample    {highmaps} maps/axis/min-max/
31093                 *            Pre-zoomed to a specific area
31094                 * @apioption xAxis.max
31095                 */
31096
31097                /**
31098                 * Padding of the max value relative to the length of the axis. A
31099                 * padding of 0.05 will make a 100px axis 5px longer. This is useful
31100                 * when you don't want the highest data value to appear on the edge
31101                 * of the plot area. When the axis' `max` option is set or a max extreme
31102                 * is set using `axis.setExtremes()`, the maxPadding will be ignored.
31103                 * 
31104                 * @sample  {highcharts} highcharts/yaxis/maxpadding/
31105                 *          Max padding of 0.25 on y axis
31106                 * @sample  {highstock} stock/xaxis/minpadding-maxpadding/
31107                 *          Greater min- and maxPadding
31108                 * @sample  {highmaps} maps/chart/plotbackgroundcolor-gradient/
31109                 *          Add some padding
31110                 * @default {highcharts} 0.01
31111                 * @default {highstock|highmaps} 0
31112                 * @since   1.2.0
31113                 */
31114                maxPadding: 0.01,
31115
31116                /**
31117                 * Deprecated. Use `minRange` instead.
31118                 *
31119                 * @deprecated
31120                 * @type       {Number}
31121                 * @product    highcharts highstock
31122                 * @apioption  xAxis.maxZoom
31123                 */
31124
31125                /**
31126                 * The minimum value of the axis. If `null` the min value is 
31127                 * automatically calculated.
31128                 *
31129                 * If the `startOnTick` option is true (default), the `min` value might
31130                 * be rounded down.
31131                 *
31132                 * The automatically calculated minimum value is also affected by
31133                 * [floor](#yAxis.floor), [softMin](#yAxis.softMin),
31134                 * [minPadding](#yAxis.minPadding), [minRange](#yAxis.minRange)
31135                 * as well as [series.threshold](#plotOptions.series.threshold)
31136                 * and [series.softThreshold](#plotOptions.series.softThreshold).
31137                 *
31138                 * @type      {Number}
31139                 * @sample    {highcharts} highcharts/yaxis/min-startontick-false/
31140                 *            -50 with startOnTick to false
31141                 * @sample    {highcharts} highcharts/yaxis/min-startontick-true/
31142                 *            -50 with startOnTick true by default
31143                 * @sample    {highstock} stock/xaxis/min-max/
31144                 *            Set min and max on X axis
31145                 * @sample    {highmaps} maps/axis/min-max/
31146                 *            Pre-zoomed to a specific area
31147                 * @apioption xAxis.min
31148                 */
31149
31150                /**
31151                 * The dash or dot style of the minor grid lines. For possible values,
31152                 * see [this demonstration](http://jsfiddle.net/gh/get/library/pure/
31153                 * highcharts/highcharts/tree/master/samples/highcharts/plotoptions/
31154                 * series-dashstyle-all/).
31155                 *
31156                 * @validvalue ["Solid", "ShortDash", "ShortDot", "ShortDashDot",
31157                 *              "ShortDashDotDot", "Dot", "Dash" ,"LongDash",
31158                 *              "DashDot", "LongDashDot", "LongDashDotDot"]
31159                 * @type       {String}
31160                 * @sample     {highcharts} highcharts/yaxis/minorgridlinedashstyle/
31161                 *             Long dashes on minor grid lines
31162                 * @sample     {highstock} stock/xaxis/minorgridlinedashstyle/
31163                 *             Long dashes on minor grid lines
31164                 * @default    Solid
31165                 * @since      1.2
31166                 * @apioption  xAxis.minorGridLineDashStyle
31167                 */
31168
31169                /**
31170                 * Specific tick interval in axis units for the minor ticks.
31171                 * On a linear axis, if `"auto"`, the minor tick interval is
31172                 * calculated as a fifth of the tickInterval. If `null`, minor
31173                 * ticks are not shown.
31174                 *
31175                 * On logarithmic axes, the unit is the power of the value. For example,
31176                 * setting the minorTickInterval to 1 puts one tick on each of 0.1,
31177                 * 1, 10, 100 etc. Setting the minorTickInterval to 0.1 produces 9
31178                 * ticks between 1 and 10, 10 and 100 etc.
31179                 *
31180                 * If user settings dictate minor ticks to become too dense, they don't
31181                 * make sense, and will be ignored to prevent performance problems.
31182                 *
31183                 * @type      {Number|String}
31184                 * @sample    {highcharts} highcharts/yaxis/minortickinterval-null/
31185                 *            Null by default
31186                 * @sample    {highcharts} highcharts/yaxis/minortickinterval-5/
31187                 *            5 units
31188                 * @sample    {highcharts} highcharts/yaxis/minortickinterval-log-auto/
31189                 *            "auto"
31190                 * @sample    {highcharts} highcharts/yaxis/minortickinterval-log/
31191                 *            0.1
31192                 * @sample    {highstock} stock/demo/basic-line/
31193                 *            Null by default
31194                 * @sample    {highstock} stock/xaxis/minortickinterval-auto/
31195                 *            "auto"
31196                 * @apioption xAxis.minorTickInterval
31197                 */
31198
31199                /**
31200                 * The pixel length of the minor tick marks.
31201                 * 
31202                 * @sample {highcharts} highcharts/yaxis/minorticklength/
31203                 *         10px on Y axis
31204                 * @sample {highstock} stock/xaxis/minorticks/
31205                 *         10px on Y axis
31206                 */
31207                minorTickLength: 2,
31208
31209                /**
31210                 * The position of the minor tick marks relative to the axis line.
31211                 *  Can be one of `inside` and `outside`.
31212                 * 
31213                 * @validvalue ["inside", "outside"]
31214                 * @sample     {highcharts} highcharts/yaxis/minortickposition-outside/
31215                 *             Outside by default
31216                 * @sample     {highcharts} highcharts/yaxis/minortickposition-inside/
31217                 *             Inside
31218                 * @sample     {highstock} stock/xaxis/minorticks/
31219                 *             Inside
31220                 */
31221                minorTickPosition: 'outside',
31222
31223                /**
31224                 * Enable or disable minor ticks. Unless
31225                 * [minorTickInterval](#xAxis.minorTickInterval) is set, the tick
31226                 * interval is calculated as a fifth of the `tickInterval`.
31227                 *
31228                 * On a logarithmic axis, minor ticks are laid out based on a best
31229                 * guess, attempting to enter approximately 5 minor ticks between
31230                 * each major tick.
31231                 *
31232                 * Prior to v6.0.0, ticks were unabled in auto layout by setting
31233                 * `minorTickInterval` to `"auto"`.
31234                 *
31235                 * @productdesc {highcharts}
31236                 * On axes using [categories](#xAxis.categories), minor ticks are not
31237                 * supported.
31238                 *
31239                 * @type      {Boolean}
31240                 * @default   false
31241                 * @since     6.0.0
31242                 * @sample    {highcharts} highcharts/yaxis/minorticks-true/
31243                 *            Enabled on linear Y axis
31244                 * @apioption xAxis.minorTicks
31245                 */
31246
31247                /**
31248                 * The pixel width of the minor tick mark.
31249                 *
31250                 * @type      {Number}
31251                 * @sample    {highcharts} highcharts/yaxis/minortickwidth/
31252                 *            3px width
31253                 * @sample    {highstock} stock/xaxis/minorticks/
31254                 *            1px width
31255                 * @default   0
31256                 * @apioption xAxis.minorTickWidth
31257                 */
31258
31259                /**
31260                 * Padding of the min value relative to the length of the axis. A
31261                 * padding of 0.05 will make a 100px axis 5px longer. This is useful
31262                 * when you don't want the lowest data value to appear on the edge
31263                 * of the plot area. When the axis' `min` option is set or a min extreme
31264                 * is set using `axis.setExtremes()`, the minPadding will be ignored.
31265                 * 
31266                 * @sample  {highcharts} highcharts/yaxis/minpadding/
31267                 *          Min padding of 0.2
31268                 * @sample  {highstock} stock/xaxis/minpadding-maxpadding/
31269                 *          Greater min- and maxPadding
31270                 * @sample  {highmaps} maps/chart/plotbackgroundcolor-gradient/
31271                 *          Add some padding
31272                 * @default {highcharts} 0.01
31273                 * @default {highstock|highmaps} 0
31274                 * @since   1.2.0
31275                 */
31276                minPadding: 0.01,
31277
31278                /**
31279                 * The minimum range to display on this axis. The entire axis will not
31280                 * be allowed to span over a smaller interval than this. For example,
31281                 * for a datetime axis the main unit is milliseconds. If minRange is
31282                 * set to 3600000, you can't zoom in more than to one hour.
31283                 *
31284                 * The default minRange for the x axis is five times the smallest
31285                 * interval between any of the data points.
31286                 *
31287                 * On a logarithmic axis, the unit for the minimum range is the power.
31288                 * So a minRange of 1 means that the axis can be zoomed to 10-100,
31289                 * 100-1000, 1000-10000 etc.
31290                 *
31291                 * Note that the `minPadding`, `maxPadding`, `startOnTick` and
31292                 * `endOnTick` settings also affect how the extremes of the axis
31293                 * are computed.
31294                 *
31295                 * @type      {Number}
31296                 * @sample    {highcharts} highcharts/xaxis/minrange/
31297                 *            Minimum range of 5
31298                 * @sample    {highstock} stock/xaxis/minrange/
31299                 *            Max zoom of 6 months overrides user selections
31300                 * @sample    {highmaps} maps/axis/minrange/
31301                 *            Minimum range of 1000
31302                 * @apioption xAxis.minRange
31303                 */
31304
31305                /**
31306                 * The minimum tick interval allowed in axis values. For example on
31307                 * zooming in on an axis with daily data, this can be used to prevent
31308                 * the axis from showing hours. Defaults to the closest distance between
31309                 * two points on the axis.
31310                 *
31311                 * @type      {Number}
31312                 * @since     2.3.0
31313                 * @apioption xAxis.minTickInterval
31314                 */
31315
31316                /**
31317                 * The distance in pixels from the plot area to the axis line.
31318                 * A positive offset moves the axis with it's line, labels and ticks
31319                 * away from the plot area. This is typically used when two or more
31320                 * axes are displayed on the same side of the plot. With multiple
31321                 * axes the offset is dynamically adjusted to avoid collision, this
31322                 * can be overridden by setting offset explicitly.
31323                 *
31324                 * @type      {Number}
31325                 * @sample    {highcharts} highcharts/yaxis/offset/
31326                 *            Y axis offset of 70
31327                 * @sample    {highcharts} highcharts/yaxis/offset-centered/
31328                 *            Axes positioned in the center of the plot
31329                 * @sample    {highstock} stock/xaxis/offset/
31330                 *            Y axis offset by 70 px
31331                 * @default   0
31332                 * @apioption xAxis.offset
31333                 */
31334
31335                /**
31336                 * Whether to display the axis on the opposite side of the normal. The
31337                 * normal is on the left side for vertical axes and bottom for
31338                 * horizontal, so the opposite sides will be right and top respectively.
31339                 * This is typically used with dual or multiple axes.
31340                 *
31341                 * @type      {Boolean}
31342                 * @sample    {highcharts} highcharts/yaxis/opposite/
31343                 *            Secondary Y axis opposite
31344                 * @sample    {highstock} stock/xaxis/opposite/
31345                 *            Y axis on left side
31346                 * @default   false
31347                 * @apioption xAxis.opposite
31348                 */
31349
31350                /**
31351                 * Whether to reverse the axis so that the highest number is closest
31352                 * to the origin. If the chart is inverted, the x axis is reversed by
31353                 * default.
31354                 *
31355                 * @type      {Boolean}
31356                 * @sample    {highcharts} highcharts/yaxis/reversed/
31357                 *            Reversed Y axis
31358                 * @sample    {highstock} stock/xaxis/reversed/
31359                 *            Reversed Y axis
31360                 * @default   false
31361                 * @apioption xAxis.reversed
31362                 */
31363                // reversed: false,
31364
31365                /**
31366                 * Whether to show the last tick label. Defaults to `true` on cartesian
31367                 * charts, and `false` on polar charts.
31368                 *
31369                 * @type      {Boolean}
31370                 * @sample    {highcharts} highcharts/xaxis/showlastlabel-true/
31371                 *            Set to true on X axis
31372                 * @sample    {highstock} stock/xaxis/showfirstlabel/
31373                 *            Labels below plot lines on Y axis
31374                 * @default   true
31375                 * @product   highcharts highstock
31376                 * @apioption xAxis.showLastLabel
31377                 */
31378
31379                /**
31380                 * For datetime axes, this decides where to put the tick between weeks.
31381                 *  0 = Sunday, 1 = Monday.
31382                 * 
31383                 * @sample  {highcharts} highcharts/xaxis/startofweek-monday/
31384                 *          Monday by default
31385                 * @sample  {highcharts} highcharts/xaxis/startofweek-sunday/
31386                 *          Sunday
31387                 * @sample  {highstock} stock/xaxis/startofweek-1
31388                 *          Monday by default
31389                 * @sample  {highstock} stock/xaxis/startofweek-0
31390                 *          Sunday
31391                 * @product highcharts highstock
31392                 */
31393                startOfWeek: 1,
31394
31395                /**
31396                 * Whether to force the axis to start on a tick. Use this option with
31397                 * the `minPadding` option to control the axis start.
31398                 *
31399                 * @productdesc {highstock}
31400                 * In Highstock, `startOnTick` is always false when the navigator is
31401                 * enabled, to prevent jumpy scrolling.
31402                 * 
31403                 * @sample  {highcharts} highcharts/xaxis/startontick-false/
31404                 *          False by default
31405                 * @sample  {highcharts} highcharts/xaxis/startontick-true/
31406                 *          True
31407                 * @sample  {highstock} stock/xaxis/endontick/
31408                 *          False for Y axis
31409                 * @since   1.2.0
31410                 */
31411                startOnTick: false,
31412
31413                /**
31414                 * The pixel length of the main tick marks.
31415                 * 
31416                 * @sample {highcharts} highcharts/xaxis/ticklength/
31417                 *         20 px tick length on the X axis
31418                 * @sample {highstock} stock/xaxis/ticks/
31419                 *         Formatted ticks on X axis
31420                 */
31421                tickLength: 10,
31422
31423                /**
31424                 * For categorized axes only. If `on` the tick mark is placed in the
31425                 * center of the category, if `between` the tick mark is placed between
31426                 * categories. The default is `between` if the `tickInterval` is 1,
31427                 *  else `on`.
31428                 * 
31429                 * @validvalue [null, "on", "between"]
31430                 * @sample     {highcharts} highcharts/xaxis/tickmarkplacement-between/
31431                 *             "between" by default
31432                 * @sample     {highcharts} highcharts/xaxis/tickmarkplacement-on/
31433                 *             "on"
31434                 * @product    highcharts
31435                 */
31436                tickmarkPlacement: 'between',
31437
31438                /**
31439                 * If tickInterval is `null` this option sets the approximate pixel
31440                 * interval of the tick marks. Not applicable to categorized axis.
31441                 * 
31442                 * The tick interval is also influenced by the [minTickInterval](#xAxis.
31443                 * minTickInterval) option, that, by default prevents ticks from being
31444                 * denser than the data points.
31445                 * 
31446                 * @see    [tickInterval](#xAxis.tickInterval),
31447                 *         [tickPositioner](#xAxis.tickPositioner),
31448                 *         [tickPositions](#xAxis.tickPositions).
31449                 * @sample {highcharts} highcharts/xaxis/tickpixelinterval-50/
31450                 *         50 px on X axis
31451                 * @sample {highstock} stock/xaxis/tickpixelinterval/
31452                 *         200 px on X axis
31453                 */
31454                tickPixelInterval: 100,
31455
31456                /**
31457                 * The position of the major tick marks relative to the axis line.
31458                 * Can be one of `inside` and `outside`.
31459                 * 
31460                 * @validvalue ["inside", "outside"]
31461      
31461           * @sample     {highcharts} highcharts/xaxis/tickposition-outside/
31462                 *             "outside" by default
31463                 * @sample     {highcharts} highcharts/xaxis/tickposition-inside/
31464                 *             "inside"
31465                 * @sample     {highstock} stock/xaxis/ticks/
31466                 *             Formatted ticks on X axis
31467                 */
31468                tickPosition: 'outside',
31469
31470                /**
31471                 * The axis title, showing next to the axis line.
31472                 *
31473                 * @productdesc {highmaps}
31474                 * In Highmaps, the axis is hidden by default, but adding an axis title
31475                 * is still possible. X axis and Y axis titles will appear at the bottom
31476                 * and left by default.
31477                 */
31478                title: {
31479
31480                    /**
31481                     * Alignment of the title relative to the axis values. Possible
31482                     * values are "low", "middle" or "high".
31483                     * 
31484                     * @validvalue ["low", "middle", "high"]
31485                     * @sample     {highcharts} highcharts/xaxis/title-align-low/
31486                     *             "low"
31487                     * @sample     {highcharts} highcharts/xaxis/title-align-center/
31488                     *             "middle" by default
31489                     * @sample     {highcharts} highcharts/xaxis/title-align-high/
31490                     *             "high"
31491                     * @sample     {highcharts} highcharts/yaxis/title-offset/
31492                     *             Place the Y axis title on top of the axis
31493                     * @sample     {highstock} stock/xaxis/title-align/
31494                     *             Aligned to "high" value
31495                     */
31496                    align: 'middle',
31497
31498
31499
31500                    /**
31501                     * CSS styles for the title. If the title text is longer than the
31502                     * axis length, it will wrap to multiple lines by default. This can
31503                     * be customized by setting `textOverflow: 'ellipsis'`, by 
31504                     * setting a specific `width` or by setting `wordSpace: 'nowrap'`.
31505                     * 
31506                     * In styled mode, the stroke width is given in the
31507                     * `.highcharts-axis-title` class.
31508                     * 
31509                     * @type    {CSSObject}
31510                     * @sample  {highcharts} highcharts/xaxis/title-style/
31511                     *          Red
31512                     * @sample  {highcharts} highcharts/css/axis/
31513                     *          Styled mode
31514                     * @default { "color": "#666666" }
31515                     */
31516                    style: {
31517                        color: '#666666'
31518                    }
31519
31520                },
31521
31522                /**
31523                 * The type of axis. Can be one of `linear`, `logarithmic`, `datetime`
31524                 * or `category`. In a datetime axis, the numbers are given in
31525                 * milliseconds, and tick marks are placed on appropriate values like
31526                 * full hours or days. In a category axis, the 
31527                 * [point names](#series.line.data.name) of the chart's series are used
31528                 * for categories, if not a [categories](#xAxis.categories) array is
31529                 * defined.
31530                 * 
31531                 * @validvalue ["linear", "logarithmic", "datetime", "category"]
31532                 * @sample     {highcharts} highcharts/xaxis/type-linear/
31533                 *             Linear
31534                 * @sample     {highcharts} highcharts/yaxis/type-log/
31535                 *             Logarithmic
31536                 * @sample     {highcharts} highcharts/yaxis/type-log-minorgrid/
31537                 *             Logarithmic with minor grid lines
31538                 * @sample     {highcharts} highcharts/xaxis/type-log-both/
31539                 *             Logarithmic on two axes
31540                 * @sample     {highcharts} highcharts/yaxis/type-log-negative/
31541                 *             Logarithmic with extension to emulate negative values
31542                 * @product    highcharts
31543                 */
31544                type: 'linear',
31545
31546
31547
31548                /**
31549                 * Color of the minor, secondary grid lines.
31550                 * 
31551                 * In styled mode, the stroke width is given in the
31552                 * `.highcharts-minor-grid-line` class.
31553                 * 
31554                 * @type    {Color}
31555                 * @sample  {highcharts} highcharts/yaxis/minorgridlinecolor/
31556                 *          Bright grey lines from Y axis
31557                 * @sample  {highcharts|highstock} highcharts/css/axis-grid/
31558                 *          Styled mode
31559                 * @sample  {highstock} stock/xaxis/minorgridlinecolor/
31560                 *          Bright grey lines from Y axis
31561                 * @default #f2f2f2
31562                 */
31563                minorGridLineColor: '#f2f2f2',
31564                // minorGridLineDashStyle: null,
31565
31566                /**
31567                 * Width of the minor, secondary grid lines.
31568                 * 
31569                 * In styled mode, the stroke width is given in the
31570                 * `.highcharts-grid-line` class.
31571                 * 
31572                 * @sample {highcharts} highcharts/yaxis/minorgridlinewidth/
31573                 *         2px lines from Y axis
31574                 * @sample {highcharts|highstock} highcharts/css/axis-grid/
31575                 *         Styled mode
31576                 * @sample {highstock} stock/xaxis/minorgridlinewidth/
31577                 *         2px lines from Y axis
31578                 */
31579                minorGridLineWidth: 1,
31580
31581                /**
31582                 * Color for the minor tick marks.
31583                 * 
31584                 * @type    {Color}
31585                 * @sample  {highcharts} highcharts/yaxis/minortickcolor/
31586                 *          Black tick marks on Y axis
31587                 * @sample  {highstock} stock/xaxis/minorticks/
31588                 *          Black tick marks on Y axis
31589                 * @default #999999
31590                 */
31591                minorTickColor: '#999999',
31592
31593                /**
31594                 * The color of the line marking the axis itself.
31595                 * 
31596                 * In styled mode, the line stroke is given in the
31597                 * `.highcharts-axis-line` or `.highcharts-xaxis-line` class.
31598                 * 
31599                 * @productdesc {highmaps}
31600                 * In Highmaps, the axis line is hidden by default, because the axis is
31601                 * not visible by default.
31602                 * 
31603                 * @type    {Color}
31604                 * @sample  {highcharts} highcharts/yaxis/linecolor/
31605                 *          A red line on Y axis
31606                 * @sample  {highcharts|highstock} highcharts/css/axis/
31607                 *          Axes in styled mode
31608                 * @sample  {highstock} stock/xaxis/linecolor/
31609                 *          A red line on X axis
31610                 * @default #ccd6eb
31611                 */
31612                lineColor: '#ccd6eb',
31613
31614                /**
31615                 * The width of the line marking the axis itself.
31616                 * 
31617                 * In styled mode, the stroke width is given in the
31618                 * `.highcharts-axis-line` or `.highcharts-xaxis-line` class.
31619                 * 
31620                 * @sample  {highcharts} highcharts/yaxis/linecolor/
31621                 *          A 1px line on Y axis
31622                 * @sample  {highcharts|highstock} highcharts/css/axis/
31623                 *          Axes in styled mode
31624                 * @sample  {highstock} stock/xaxis/linewidth/
31625                 *          A 2px line on X axis
31626                 * @default {highcharts|highstock} 1
31627                 * @default {highmaps} 0
31628                 */
31629                lineWidth: 1,
31630
31631                /**
31632                 * Color of the grid lines extending the ticks across the plot area.
31633                 * 
31634                 * In styled mode, the stroke is given in the `.highcharts-grid-line`
31635                 * class.
31636                 *
31637                 * @productdesc {highmaps}
31638                 * In Highmaps, the grid lines are hidden by default.
31639                 * 
31640                 * @type    {Color}
31641                 * @sample  {highcharts} highcharts/yaxis/gridlinecolor/
31642                 *          Green lines
31643                 * @sample  {highcharts|highstock}
31643 highcharts/css/axis-grid/
31644                 *          Styled mode
31645                 * @sample  {highstock} stock/xaxis/gridlinecolor/
31646                 *          Green lines
31647                 * @default #e6e6e6
31648                 */
31649                gridLineColor: '#e6e6e6',
31650                // gridLineDashStyle: 'solid',
31651
31652
31653                /**
31654                 * The width of the grid lines extending the ticks across the plot area.
31655                 *
31656                 * In styled mode, the stroke width is given in the
31657                 * `.highcharts-grid-line` class.
31658                 *
31659                 * @type      {Number}
31660                 * @sample    {highcharts} highcharts/yaxis/gridlinewidth/
31661                 *            2px lines
31662                 * @sample    {highcharts|highstock} highcharts/css/axis-grid/
31663                 *            Styled mode
31664                 * @sample    {highstock} stock/xaxis/gridlinewidth/
31665                 *            2px lines
31666                 * @default   0
31667                 * @apioption xAxis.gridLineWidth
31668                 */
31669                // gridLineWidth: 0,
31670
31671                /**
31672                 * Color for the main tick marks.
31673                 * 
31674                 * In styled mode, the stroke is given in the `.highcharts-tick`
31675                 * class.
31676                 * 
31677                 * @type    {Color}
31678                 * @sample  {highcharts} highcharts/xaxis/tickcolor/
31679                 *          Red ticks on X axis
31680                 * @sample  {highcharts|highstock} highcharts/css/axis-grid/
31681                 *          Styled mode
31682                 * @sample  {highstock} stock/xaxis/ticks/
31683                 *          Formatted ticks on X axis
31684                 * @default #ccd6eb
31685                 */
31686                tickColor: '#ccd6eb'
31687                // tickWidth: 1
31688
31689            },
31690
31691            /**
31692             * The Y axis or value axis. Normally this is the vertical axis,
31693             * though if the chart is inverted this is the horizontal axis.
31694             * In case of multiple axes, the yAxis node is an array of
31695             * configuration objects.
31696             *
31697             * See [the Axis object](#Axis) for programmatic access to the axis.
31698             *
31699             * @extends      xAxis
31700             * @excluding    ordinal,overscroll
31701             * @optionparent yAxis
31702             */
31703            defaultYAxisOptions: {
31704                /**
31705                 * @productdesc {highstock}
31706                 * In Highstock, `endOnTick` is always false when the navigator is
31707                 * enabled, to prevent jumpy scrolling.
31708                 */
31709                endOnTick: true,
31710
31711                /**
31712                 * @productdesc {highstock}
31713                 * In Highstock 1.x, the Y axis was placed on the left side by default.
31714                 *
31715                 * @sample    {highcharts} highcharts/yaxis/opposite/
31716                 *            Secondary Y axis opposite
31717                 * @sample    {highstock} stock/xaxis/opposite/
31718                 *            Y axis on left side
31719                 * @default   {highstock} true
31720                 * @default   {highcharts} false
31721                 * @product   highstock highcharts
31722                 * @apioption yAxis.opposite
31723                 */
31724
31725                /**
31726                 * @see [tickInterval](#xAxis.tickInterval),
31727                 *      [tickPositioner](#xAxis.tickPositioner),
31728                 *      [tickPositions](#xAxis.tickPositions).
31729                 */
31730                tickPixelInterval: 72,
31731
31732                showLastLabel: true,
31733
31734                /**
31735                 * @extends xAxis.labels
31736                 */
31737                labels: {
31738                    /**
31739                     * What part of the string the given position is anchored to. Can
31740                     * be one of `"left"`, `"center"` or `"right"`. The exact position
31741                     * also depends on the `labels.x` setting.
31742                     *
31743                     * Angular gauges and solid gauges defaults to `center`.
31744                     *
31745                     * @validvalue ["left", "center", "right"]
31746                     * @type       {String}
31747                     * @sample     {highcharts} highcharts/yaxis/labels-align-left/
31748                     *             Left
31749                     * @default    {highcharts|highmaps} right
31750                     * @default    {highstock} left
31751                     * @apioption  yAxis.labels.align
31752                     */
31753
31754                    /**
31755                     * The x position offset of the label relative to the tick position
31756                     * on the axis. Defaults to -15 for left axis, 15 for right axis.
31757                     * 
31758                     * @sample {highcharts} highcharts/xaxis/labels-x/
31759                     *         Y axis labels placed on grid lines
31760                     */
31761                    x: -8
31762                },
31763
31764                /**
31765                 * @productdesc {highmaps}
31766                 * In Highmaps, the axis line is hidden by default, because the axis is
31767                 * not visible by default.
31768                 * 
31769                 * @apioption yAxis.lineColor
31770                 */
31771
31772                /**
31773                 * @sample    {highcharts} highcharts/yaxis/min-startontick-false/
31774                 *            -50 with startOnTick to false
31775                 * @sample    {highcharts} highcharts/yaxis/min-startontick-true/
31776                 *            -50 with startOnTick true by default
31777                 * @sample    {highstock} stock/yaxis/min-max/
31778                 *            Fixed min and max on Y axis
31779                 * @sample    {highmaps} maps/axis/min-max/
31780                 *            Pre-zoomed to a specific area
31781                 * @apioption yAxis.min
31782                 */
31783
31784                /**
31785                 * @sample    {highcharts} highcharts/yaxis/max-200/
31786                 *            Y axis max of 200
31787                 * @sample    {highcharts} highcharts/yaxis/max-logarithmic/
31788                 *            Y axis max on logarithmic axis
31789                 * @sample    {highstock} stock/yaxis/min-max/
31790                 *            Fixed min and max on Y axis
31791                 * @sample    {highmaps} maps/axis/min-max/
31792                 *            Pre-zoomed to a specific area
31793                 * @apioption yAxis.max
31794                 */
31795
31796                /**
31797                 * Padding of the max value relative to the length of the axis. A
31798                 * padding of 0.05 will make a 100px axis 5px longer. This is useful
31799                 * when you don't want the highest data value to appear on the edge
31800                 * of the plot area. When the axis' `max` option is set or a max extreme
31801                 * is set using `axis.setExtremes()`, the maxPadding will be ignored.
31802                 * 
31803                 * @sample  {highcharts} highcharts/yaxis/maxpadding-02/
31804                 *          Max padding of 0.2
31805                 * @sample  {highstock} stock/xaxis/minpadding-maxpadding/
31806                 *          Greater min- and maxPadding
31807                 * @since   1.2.0
31808                 * @product highcharts highstock
31809                 */
31810                maxPadding: 0.05,
31811
31812                /**
31813                 * Padding of the min value relative to the length of the axis. A
31814                 * padding of 0.05 will make a 100px axis 5px longer. This is useful
31815                 * when you don't want the lowest data value to appear on the edge
31816                 * of the plot area. When the axis' `min` option is set or a max extreme
31817                 * is set using `axis.setExtremes()`, the maxPadding will be ignored.
31818                 * 
31819                 * @sample  {highcharts} highcharts/yaxis/minpadding/
31820                 *          Min padding of 0.2
31821                 * @sample  {highstock} stock/xaxis/minpadding-maxpadding/
31822                 *          Greater min- and maxPadding
31823                 * @since   1.2.0
31824                 * @product highcharts highstock
31825                 */
31826                minPadding: 0.05,
31827
31828                /**
31829                 * Whether to force the axis to start on a tick. Use this option with
31830                 * the `maxPadding` option to control the axis start.
31831                 * 
31832                 * @sample  {highcharts} highcharts/xaxis/startontick-false/
31833                 *          False by default
31834                 * @sample  {highcharts} highcharts/xaxis/startontick-true/
31835                 *          True
31836                 * @sample  {highstock} stock/xaxis/endontick/
31837                 *          False for Y axis
31838                 * @since   1.2.0
31839                 * @product highcharts highstock
31840                 */
31841                startOnTick: true,
31842
31843                /**
31844                 * @extends xAxis.title
31845                 */
31846                title: {
31847
31848                    /**
31849                     * The rotation of the text in degrees. 0 is horizontal, 270 is
31850                     * vertical reading from bottom to top.
31851                     * 
31852                     * @sample {highcharts} highcharts/yaxis/title-offset/
31853                     *         Horizontal
31854                     */
31855                    rotation: 270,
31856
31857                    /**
31858                     * The actual text of the axis title. Horizontal texts can contain
31859                     * HTML, but rotated texts are painted using vector techniques and
31860                     * must be clean text. The Y axis title is disabled by setting the
31861                     * `text` option to `null`.
31862                     * 
31863                     * @sample  {highcharts} highcharts/xaxis/title-text/
31864                     *          Custom HTML
31865                     * @default {highcharts} Values
31866                     * @default {highstock} null
31867                     * @product highcharts highstock
31868                     */
31869                    text: 'Values'
31870                },
31871
31872                /**
31873                 * The stack labels show the total value for each bar in a stacked
31874                 * column or bar chart. The label will be placed on top of positive
31875                 * columns and below negative columns. In case of an inverted column
31876                 * chart or a bar chart the label is placed to the right of positive
31877                 * bars and to the left of negative bars.
31878                 * 
31879                 * @product highcharts
31880                 */
31881                stackLabels: {
31882
31883                    /**
31884                     * Allow the stack labels to overlap.
31885                     * 
31886                     * @sample  {highcharts}
31887                     *          highcharts/yaxis/stacklabels-allowoverlap-false/
31888                     *          Default false
31889                     * @since   5.0.13
31890                     * @product highcharts
31891                     */
31892                    allowOverlap: false,
31893
31894                    /**
31895                     * Enable or disable the stack total labels.
31896                     * 
31897                     * @sample  {highcharts} highcharts/yaxis/stacklabels-enabled/
31898                     *          Enabled stack total labels
31899                     * @since   2.1.5
31900                     * @product highcharts
31901                     */
31902                    enabled: false,
31903
31904                    /**
31905                     * Callback JavaScript function to format the label. The value is
31906                     * given by `this.total`.
31907                     *
31908                     * @default function() { return this.total; }
31909                     * 
31910                     * @type    {Function}
31911                     * @sample  {highcharts} highcharts/yaxis/stacklabels-formatter/
31912                     *          Added units to stack total value
31913                     * @since   2.1.5
31914                     * @product highcharts
31915                     */
31916                    formatter: function() {
31917                        return H.numberFormat(this.total, -1);
31918                    },
31919
31920
31921                    /**
31922                     * CSS styles for the label.
31923                     * 
31924                     * In styled mode, the styles are set in the
31925                     * `.highcharts-stack-label` class.
31926                     * 
31927                     * @type    {CSSObject}
31928                     * @sample  {highcharts} highcharts/yaxis/stacklabels-style/
31929                     *          Red stack total labels
31930                     * @since   2.1.5
31931                     * @product highcharts
31932                     */
31933                    style: {
31934                        fontSize: '11px',
31935                        fontWeight: 'bold',
31936                        color: '#000000',
31937                        textOutline: '1px contrast'
31938                    }
31939
31940                },
31941
31942                gridLineWidth: 1,
31943                lineWidth: 0
31944                // tickWidth: 0
31945
31946            },
31947
31948            /**
31949             * These options extend the defaultOptions for left axes.
31950             * 
31951             * @private
31952             * @type {Object}
31953             */
31954            defaultLeftAxisOptions: {
31955                labels: {
31956                    x: -15
31957                },
31958                title: {
31959                    rotation: 270
31960                }
31961            },
31962
31963            /**
31964             * These options extend the defaultOptions for right axes.
31965             *
31966             * @private
31967             * @type {Object}
31968             */
31969            defaultRightAxisOptions: {
31970                labels: {
31971                    x: 15
31972                },
31973                title: {
31974                    rotation: 90
31975                }
31976            },
31977
31978            /**
31979             * These options extend the defaultOptions for bottom axes.
31980             *
31981             * @private
31982             * @type {Object}
31983             */
31984            defaultBottomAxisOptions: {
31985                labels: {
31986                    autoRotation: [-45],
31987                    x: 0
31988                    // overflow: undefined,
31989                    // staggerLines: null
31990                },
31991                title: {
31992                    rotation: 0
31993                }
31994            },
31995            /**
31996             * These options extend the defaultOptions for top axes.
31997             *
31998             * @private
31999             * @type {Object}
32000             */
32001            defaultTopAxisOptions: {
32002                labels: {
32003                    autoRotation: [-45],
32004                    x: 0
32005                    // overflow: undefined
32006                    // staggerLines: null
32007                },
32008                title: {
32009                    rotation: 0
32010                }
32011            },
32012
32013            /**
32014             * Overrideable function to initialize the axis. 
32015             *
32016             * @see {@link Axis}
32017             */
32018            init: function(chart, userOptions) {
32019
32020
32021                var isXAxis = userOptions.isX,
32022                    axis = this;
32023
32024
32025                /**
32026                 * The Chart that the axis belongs to.
32027                 *
32028                 * @name     chart
32029                 * @memberOf Axis
32030                 * @type     {Chart}
32031                 */
32032                axis.chart = chart;
32033
32034                /**
32035                 * Whether the axis is horizontal.
32036                 *
32037                 * @name     horiz
32038                 * @memberOf Axis
32039                 * @type     {Boolean}
32040                 */
32041                axis.horiz = chart.inverted && !axis.isZAxis ? !isXAxis : isXAxis;
32042
32043                // Flag, isXAxis
32044                axis.isXAxis = isXAxis;
32045
32046                /**
32047                 * The collection where the axis belongs, for example `xAxis`, `yAxis`
32048                 * or `colorAxis`. Corresponds to properties on Chart, for example
32049                 * {@link Chart.xAxis}.
32050                 *
32051                 * @name     coll
32052                 * @memberOf Axis
32053                 * @type     {String}
32054                 */
32055                axis.coll = axis.coll || (isXAxis ? 'xAxis' : 'yAxis');
32056
32057
32058                axis.opposite = userOptions.opposite; // needed in setOptions
32059
32060                /**
32061                 * The side on which the axis is rendered. 0 is top, 1 is right, 2 is
32062                 * bottom and 3 is left.
32063                 *
32064                 * @name     side
32065                 * @memberOf Axis
32066                 * @type     {Number}
32067                 */
32068                axis.side = userOptions.side || (axis.horiz ?
32069                    (axis.opposite ? 0 : 2) : // top : bottom
32070                    (axis.opposite ? 1 : 3)); // right : left
32071
32072                axis.setOptions(userOptions);
32073
32074
32075                var options = this.options,
32076                    type = options.type,
32077                    isDatetimeAxis = type === 'datetime';
32078
32079                axis.labelFormatter = options.labels.formatter ||
32080                    axis.defaultLabelFormatter; // can be overwritten by dynamic format
32081
32082
32083                // Flag, stagger lines or not
32084                axis.userOptions = userOptions;
32085
32086                axis.minPixelPadding = 0;
32087
32088
32089                /**
32090                 * Whether the axis is reversed. Based on the `axis.reversed`,
32091                 * option, but inverted charts have reversed xAxis by default.
32092                 *
32093                 * @name     reversed
32094                 * @memberOf Axis
32095                 * @type     {Boolean}
32096                 */
32097                axis.reversed = options.reversed;
32098                axis.visible = options.visible !== false;
32099                axis.zoomEnabled = options.zoomEnabled !== false;
32100
32101                // Initial categories
32102                axis.hasNames = type === 'category' || options.categories === true;
32103                axis.categories = options.categories || axis.hasNames;
32104                axis.names = axis.names || []; // Preserve on update (#3830)
32105
32106                // Placeholder for plotlines and plotbands groups
32107                axis.plotLinesAndBandsGroups = {};
32108
32109                // Shorthand types
32110                axis.isLog = type === 'logarithmic';
32111                axis.isDatetimeAxis = isDatetimeAxis;
32112                axis.positiveValuesOnly = axis.isLog && !axis.allowNegativeLog;
32113
32114                // Flag, if axis is linked to another axis
32115                axis.isLinked = defined(options.linkedTo);
32116
32117                // Major ticks
32118                axis.ticks = {};
32119                axis.labelEdge = [];
32120                // Minor ticks
32121                axis.minorTicks = {};
32122
32123                // List of plotLines/Bands
32124                axis.plotLinesAndBands = [];
32125
32126                // Alternate bands
32127                axis.alternateBands = {};
32128
32129                // Axis metrics
32130                axis.len = 0;
32131                axis.minRange = axis.userMinRange = options.minRange || options.maxZoom;
32132                axis.range = options.range;
32133                axis.offset = options.offset || 0;
32134
32135
32136                // Dictionary for stacks
32137                axis.stacks = {};
32138                axis.oldStacks = {};
32139                axis.stacksTouched = 0;
32140
32141
32142                /**
32143                 * The maximum value of the axis. In a logarithmic axis, this is the
32144                 * logarithm of the real value, and the real value can be obtained from
32145                 * {@link Axis#getExtremes}.
32146                 *
32147                 * @name     max
32148                 * @memberOf Axis
32149                 * @type     {Number}
32150                 */
32151                axis.max = null;
32152                /**
32153                 * The minimum value of the axis. In a logarithmic axis, this is the
32154                 * logarithm of the real value, and the real value can be obtained from
32155                 * {@link Axis#getExtremes}.
32156                 *
32157                 * @name     min
32158                 * @memberOf Axis
32159                 * @type     {Number}
32160                 */
32161                axis.min = null;
32162
32163
32164                /**
32165                 * The processed crosshair options.
32166                 *
32167                 * @name     crosshair
32168                 * @memberOf Axis
32169                 * @type     {AxisCrosshairOptions}
32170                 */
32171                axis.crosshair = pick(
32172                    options.crosshair,
32173                    splat(chart.options.tooltip.crosshairs)[isXAxis ? 0 : 1],
32174                    false
32175                );
32176
32177                var events = axis.options.events;
32178
32179                // Register. Don't add it again on Axis.update().
32180                if (inArray(axis, chart.axes) === -1) { // 
32181                    if (isXAxis) { // #2713
32182                        chart.axes.splice(chart.xAxis.length, 0, axis);
32183                    } else {
32184                        chart.axes.push(axis);
32185                    }
32186
32187                    chart[axis.coll].push(axis);
32188                }
32189
32190                /**
32191                 * All series associated to the axis.
32192                 *
32193                 * @name     series
32194                 * @memberOf Axis
32195                 * @type     {Array.<Series>}
32196                 */
32197                axis.series = axis.series || []; // populated by Series
32198
32199                // Reversed axis
32200                if (
32201                    chart.inverted &&
32202                    !axis.isZAxis &&
32203                    isXAxis &&
32204                    axis.reversed === undefined
32205                ) {
32206                    axis.reversed = true;
32207                }
32208
32209                // register event listeners
32210                objectEach(events, function(event, eventType) {
32211                    addEvent(axis, eventType, event);
32212                });
32213
32214                // extend logarithmic axis
32215                axis.lin2log = options.linearToLogConverter || axis.lin2log;
32216                if (axis.isLog) {
32217                    axis.val2lin = axis.log2lin;
32218                    axis.lin2val = axis.lin2log;
32219                }
32220            },
32221
32222            /**
32223             * Merge and set options.
32224             *
32225             * @private
32226             */
32227            setOptions: function(userOptions) {
32228                this.options = merge(
32229                    this.defaultOptions,
32230                    this.coll === 'yAxis' && this.defaultYAxisOptions, [
32231                        this.defaultTopAxisOptions,
32232                        this.defaultRightAxisOptions,
32233                        this.defaultBottomAxisOptions,
32234                        this.defaultLeftAxisOptions
32235                    ][this.side],
32236                    merge(
32237                        defaultOptions[this.coll], // if set in setOptions (#1053)
32238                        userOptions
32239                    )
32240                );
32241            },
32242
32243            /**
32244             * The default label formatter. The context is a special config object for
32245             * the label. In apps, use the {@link
32246             * https://api.highcharts.com/highcharts/xAxis.labels.formatter|
32247             * labels.formatter} instead except when a modification is needed.
32248             *
32249             * @private
32250             */
32251            defaultLabelFormatter: function() {
32252                var axis = this.axis,
32253                    value = this.value,
32254                    categories = axis.categories,
32255                    dateTimeLabelFormat = this.dateTimeLabelFormat,
32256                    lang = defaultOptions.lang,
32257                    numericSymbols = lang.numericSymbols,
32258                    numSymMagnitude = lang.numericSymbolMagnitude || 1000,
32259                    i = numericSymbols && numericSymbols.length,
32260                    multi,
32261                    ret,
32262                    formatOption = axis.options.labels.format,
32263
32264                    // make sure the same symbol is added for all labels on a linear
32265                    // axis
32266                    numericSymbolDetector = axis.isLog ?
32267                    Math.abs(value) :
32268                    axis.tickInterval;
32269
32270                if (formatOption) {
32271                    ret = format(formatOption, this);
32272
32273                } else if (categories) {
32274                    ret = value;
32275
32276                } else if (dateTimeLabelFormat) { // datetime axis
32277                    ret = H.dateFormat(dateTimeLabelFormat, value);
32278
32279                } else if (i && numericSymbolDetector >= 1000) {
32280                    // Decide whether we should add a numeric symbol like k (thousands)
32281                    // or M (millions). If we are to enable this in tooltip or other
32282                    // places as well, we can move this logic to the numberFormatter and
32283                    // enable it by a parameter.
32284                    while (i-- && ret === undefined) {
32285                        multi = Math.pow(numSymMagnitude, i + 1);
32286                        if (
32287                            // Only accept a numeric symbol when the distance is more 
32288                            // than a full unit. So for example if the symbol is k, we
32289                            // don't accept numbers like 0.5k.
32290                            numericSymbolDetector >= multi &&
32291                            // Accept one decimal before the symbol. Accepts 0.5k but
32292                            // not 0.25k. How does this work with the previous?
32293                            (value * 10) % multi === 0 &&
32294                            numericSymbols[i] !== null &&
32295                            value !== 0
32296                        ) { // #5480
32297                            ret = H.numberFormat(value / multi, -1) + numericSymbols[i];
32298                        }
32299                    }
32300                }
32301
32302                if (ret === undefined) {
32303                    if (Math.abs(value) >= 10000) { // add thousands separators
32304                        ret = H.numberFormat(value, -1);
32305                    } else { // small numbers
32306                        ret = H.numberFormat(value, -1, undefined, ''); // #2466
32307                    }
32308                }
32309
32310                return ret;
32311            },
32312
32313            /**
32314             * Get the minimum and maximum for the series of each axis. The function
32315             * analyzes the axis series and updates `this.dataMin` and `this.dataMax`.
32316             *
32317             * @private
32318             */
32319            getSeriesExtremes: function() {
32320                var axis = this,
32321                    chart = axis.chart;
32322                axis.hasVisibleSeries = false;
32323
32324                // Reset properties in case we're redrawing (#3353)
32325                axis.dataMin = axis.dataMax = axis.threshold = null;
32326                axis.softThreshold = !axis.isXAxis;
32327
32328                if (axis.buildStacks) {
32329                    axis.buildStacks();
32330                }
32331
32332                // loop through this axis' series
32333                each(axis.series, function(series) {
32334
32335                    if (series.visible || !chart.options.chart.ignoreHiddenSeries) {
32336
32337                        var seriesOptions = series.options,
32338                            xData,
32339                            threshold = seriesOptions.threshold,
32340                            seriesDataMin,
32341                            seriesDataMax;
32342
32343                        axis.hasVisibleSeries = true;
32344
32345                        // Validate threshold in logarithmic axes
32346                        if (axis.positiveValuesOnly && threshold <= 0) {
32347                            threshold = null;
32348                        }
32349
32350                        // Get dataMin and dataMax for X axes
32351                        if (axis.isXAxis) {
32352                            xData = series.xData;
32353                            if (xData.length) {
32354                                // If xData contains values which is not numbers, then
32355                                // filter them out. To prevent performance hit, we only
32356                                // do this after we have already found seriesDataMin
32357                                // because in most cases all data is valid. #5234.
32358                                seriesDataMin = arrayMin(xData);
32359                                seriesDataMax = arrayMax(xData);
32360
32361                                if (!isNumber(seriesDataMin) &&
32362                                    !(seriesDataMin instanceof Date) // #5010
32363                                ) {
32364                                    xData = grep(xData, isNumber);
32365                                    // Do it again with valid data
32366                                    seriesDataMin = arrayMin(xData);
32367                                }
32368
32369                                axis.dataMin = Math.min(
32370                                    pick(axis.dataMin, xData[0], seriesDataMin),
32371                                    seriesDataMin
32372                                );
32373                                axis.dataMax = Math.max(
32374                                    pick(axis.dataMax, xData[0], seriesDataMax),
32375                                    seriesDataMax
32376                                );
32377                            }
32378
32379                            // Get dataMin and dataMax for Y axes, as well as handle
32380                            // stacking and processed data
32381                        } else {
32382
32383                            // Get this particular series extremes
32384                            series.getExtremes();
32385                            seriesDataMax = series.dataMax;
32386                            seriesDataMin = series.dataMin;
32387
32388                            // Get the dataMin and dataMax so far. If percentage is
32389                            // used, the min and max are always 0 and 100. If
32390                            // seriesDataMin and seriesDataMax is null, then series
32391                            // doesn't have active y data, we continue with nulls
32392                            if (defined(seriesDataMin) && defined(seriesDataMax)) {
32393                                axis.dataMin = Math.min(
32394                                    pick(axis.dataMin, seriesDataMin),
32395                                    seriesDataMin
32396                                );
32397                                axis.dataMax = Math.max(
32398                                    pick(axis.dataMax, seriesDataMax),
32399                                    seriesDataMax
32400                                );
32401                            }
32402
32403                            // Adjust to threshold
32404                            if (defined(threshold)) {
32405                                axis.threshold = threshold;
32406                            }
32407                            // If any series has a hard threshold, it takes precedence
32408                            if (!seriesOptions.softThreshold ||
32409                                axis.positiveValuesOnly
32410                            ) {
32411                                axis.softThreshold = false;
32412                            }
32413                        }
32414                    }
32415                });
32416            },
32417
32418            /**
32419             * Translate from axis value to pixel position on the chart, or back. Use
32420             * the `toPixels` and `toValue` functions in applications.
32421             *
32422             * @private
32423             */
32424            translate: function(
32425                val,
32426                backwards,
32427                cvsCoord,
32428                old,
32429                handleLog,
32430                pointPlacement
32431            ) {
32432                var axis = this.linkedParent || this, // #1417
32433                    sign = 1,
32434                    cvsOffset = 0,
32435                    localA = old ? axis.oldTransA : axis.transA,
32436                    localMin = old ? axis.oldMin : axis.min,
32437                    returnValue,
32438                    minPixelPadding = axis.minPixelPadding,
32439                    doPostTranslate = (
32440                        axis.isOrdinal ||
32441                        axis.isBroken ||
32442                        (axis.isLog && handleLog)
32443                    ) && axis.lin2val;
32444
32445                if (!localA) {
32446                    localA = axis.transA;
32447                }
32448
32449                // In vertical axes, the canvas coordinates start from 0 at the top like
32450                // in SVG.
32451                if (cvsCoord) {
32452                    sign *= -1; // canvas coordinates inverts the value
32453                    cvsOffset = axis.len;
32454                }
32455
32456                // Handle reversed axis
32457                if (axis.reversed) {
32458                    sign *= -1;
32459                    cvsOffset -= sign * (axis.sector || axis.len);
32460                }
32461
32462                // From pixels to value
32463                if (backwards) { // reverse translation
32464
32465                    val = val * sign + cvsOffset;
32466                    val -= minPixelPadding;
32467                    returnValue = val / localA + localMin; // from chart pixel to value
32468                    if (doPostTranslate) { // log and ordinal axes
32469                        returnValue = axis.lin2val(returnValue);
32470                    }
32471
32472                    // From value to pixels
32473                } else {
32474                    if (doPostTranslate) { // log and ordinal axes
32475                        val = axis.val2lin(val);
32476                    }
32477                    returnValue = isNumber(localMin) ?
32478                        (
32479                            sign * (val - localMin) * localA +
32480                            cvsOffset +
32481                            (sign * minPixelPadding) +
32482                            (isNumber(pointPlacement) ? localA * pointPlacement : 0)
32483                        ) :
32484                        undefined;
32485                }
32486
32487                return returnValue;
32488            },
32489
32490            /**
32491             * Translate a value in terms of axis units into pixels within the chart.
32492             * 
32493             * @param  {Number} value
32494             *         A value in terms of axis units.
32495             * @param  {Boolean} paneCoordinates
32496             *         Whether to return the pixel coordinate relative to the chart or
32497             *         just the axis/pane itself.
32498             * @return {Number} Pixel position of the value on the chart or axis.
32499             */
32500            toPixels: function(value, paneCoordinates) {
32501                return this.translate(value, false, !this.horiz, null, true) +
32502                    (paneCoordinates ? 0 : this.pos);
32503            },
32504
32505            /**
32506             * Translate a pixel position along the axis to a value in terms of axis
32507             * units.
32508             * @param  {Number} pixel
32509             *         The pixel value coordinate.
32510             * @param  {Boolean} paneCoordiantes
32511             *         Whether the input pixel is relative to the chart or just the
32512             *         axis/pane itself.
32513             * @return {Number} The axis value.
32514             */
32515            toValue: function(pixel, paneCoordinates) {
32516                return this.translate(
32517                    pixel - (paneCoordinates ? 0 : this.pos),
32518                    true, !this.horiz,
32519                    null,
32520                    true
32521                );
32522            },
32523
32524            /**
32525             * Create the path for a plot line that goes from the given value on
32526             * this axis, across the plot to the opposite side. Also used internally for
32527             * grid lines and crosshairs.
32528             * 
32529             * @param  {Number} value
32530             *         Axis value.
32531             * @param  {Number} [lineWidth=1]
32532             *         Used for calculation crisp line coordinates.
32533             * @param  {Boolean} [old=false]
32534             *         Use old coordinates (for resizing and rescaling).
32535             * @param  {Boolean} [force=false]
32536             *         If `false`, the function will return null when it falls outside
32537             *         the axis bounds.
32538             * @param  {Number} [translatedValue]
32539             *         If given, return the plot line path of a pixel position on the
32540             *         axis.
32541             *
32542             * @return {Array.<String|Number>}
32543             *         The SVG path definition for the plot line.
32544             */
32545            getPlotLinePath: function(value, lineWidth, old, force, translatedValue) {
32546                var axis = this,
32547                    chart = axis.chart,
32548                    axisLeft = axis.left,
32549                    axisTop = axis.top,
32550                    x1,
32551                    y1,
32552                    x2,
32553                    y2,
32554                    cHeight = (old && chart.oldChartHeight) || chart.chartHeight,
32555                    cWidth = (old && chart.oldChartWidth) || chart.chartWidth,
32556                    skip,
32557                    transB = axis.transB,
32558                    /**
32559                     * Check if x is between a and b. If not, either move to a/b
32560                     * or skip, depending on the force parameter.
32561                     */
32562                    between = function(x, a, b) {
32563                        if (x < a || x > b) {
32564                            if (force) {
32565                                x = Math.min(Math.max(a, x), b);
32566                            } else {
32567                                skip = true;
32568                            }
32569                        }
32570                        return x;
32571                    };
32572
32573                translatedValue = pick(
32574                    translatedValue,
32575                    axis.translate(value, null, null, old)
32576                );
32577                x1 = x2 = Math.round(translatedValue + transB);
32578                y1 = y2 = Math.round(cHeight - translatedValue - transB);
32579                if (!isNumber(translatedValue)) { // no min or max
32580                    skip = true;
32581                    force = false; // #7175, don't force it when path is invalid
32582                } else if (axis.horiz) {
32583                    y1 = axisTop;
32584                    y2 = cHeight - axis.bottom;
32585                    x1 = x2 = between(x1, axisLeft, axisLeft + axis.width);
32586                } else {
32587                    x1 = axisLeft;
32588                    x2 = cWidth - axis.right;
32589                    y1 = y2 = between(y1, axisTop, axisTop + axis.height);
32590                }
32591                return skip && !force ?
32592                    null :
32593                    chart.renderer.crispLine(
32594                        ['M', x1, y1, 'L', x2, y2],
32595                        lineWidth || 1
32596                    );
32597            },
32598
32599            /**
32600             * Internal function to et the tick positions of a linear axis to round
32601             * values like whole tens or every five.
32602             *
32603             * @param  {Number} tickInterval
32604             *         The normalized tick interval
32605             * @param  {Number} min
32606             *         Axis minimum.
32607             * @param  {Number} max
32608             *         Axis maximum.
32609             *
32610             * @return {Array.<Number>}
32611             *         An array of axis values where ticks should be placed.
32612             */
32613            getLinearTickPositions: function(tickInterval, min, max) {
32614                var pos,
32615                    lastPos,
32616                    roundedMin =
32617                    correctFloat(Math.floor(min / tickInterval) * tickInterval),
32618                    roundedMax =
32619                    correctFloat(Math.ceil(max / tickInterval) * tickInterval),
32620                    tickPositions = [],
32621                    precision;
32622
32623                // When the precision is higher than what we filter out in
32624                // correctFloat, skip it (#6183).			
32625                if (correctFloat(roundedMin + tickInterval) === roundedMin) {
32626                    precision = 20;
32627                }
32628
32629                // For single points, add a tick regardless of the relative position
32630                // (#2662, #6274)
32631                if (this.single) {
32632                    return [min];
32633                }
32634
32635                // Populate the intermediate values
32636                pos = roundedMin;
32637                while (pos <= roundedMax) {
32638
32639                    // Place the tick on the rounded value
32640                    tickPositions.push(pos);
32641
32642                    // Always add the raw tickInterval, not the corrected one.
32643                    pos = correctFloat(
32644                        pos + tickInterval,
32645                        precision
32646                    );
32647
32648                    // If the interval is not big enough in the current min - max range
32649                    // to actually increase the loop variable, we need to break out to
32650                    // prevent endless loop. Issue #619
32651                    if (pos === lastPos) {
32652                        break;
32653                    }
32654
32655                    // Record the last value
32656                    lastPos = pos;
32657                }
32658                return tickPositions;
32659            },
32660
32661            /**
32662             * Resolve the new minorTicks/minorTickInterval options into the legacy
32663             * loosely typed minorTickInterval option.
32664             */
32665            getMinorTickInterval: function() {
32666                var options = this.options;
32667
32668                if (options.minorTicks === true) {
32669                    return pick(options.minorTickInterval, 'auto');
32670                }
32671                if (options.minorTicks === false) {
32672                    return null;
32673                }
32674                return options.minorTickInterval;
32675            },
32676
32677            /**
32678             * Internal function to return the minor tick positions. For logarithmic
32679             * axes, the same logic as for major ticks is reused.
32680             *
32681             * @return {Array.<Number>}
32682             *         An array of axis values where ticks should be placed.
32683             */
32684            getMinorTickPositions: function() {
32685                var axis = this,
32686                    options = axis.options,
32687                    tickPositions = axis.tickPositions,
32688                    minorTickInterval = axis.minorTickInterval,
32689                    minorTickPositions = [],
32690                    pos,
32691                    pointRangePadding = axis.pointRangePadding || 0,
32692                    min = axis.min - pointRangePadding, // #1498
32693                    max = axis.max + pointRangePadding, // #1498
32694                    range = max - min;
32695
32696                // If minor ticks get too dense, they are hard to read, and may cause
32697                // long running script. So we don't draw them.
32698                if (range && range / minorTickInterval < axis.len / 3) { // #3875
32699
32700                    if (axis.isLog) {
32701                        // For each interval in the major ticks, compute the minor ticks
32702                        // separately.
32703                        each(this.paddedTicks, function(pos, i, paddedTicks) {
32704                            if (i) {
32705                                minorTickPositions.push.apply(
32706                                    minorTickPositions,
32707                                    axis.getLogTickPositions(
32708                                        minorTickInterval,
32709                                        paddedTicks[i - 1],
32710                                        paddedTicks[i],
32711                                        true
32712                                    )
32713                                );
32714                            }
32715                        });
32716
32717                    } else if (
32718                        axis.isDatetimeAxis &&
32719                        this.getMinorTickInterval() === 'auto'
32720                    ) { // #1314
32721                        minorTickPositions = minorTickPositions.concat(
32722                            axis.getTimeTicks(
32723                                axis.normalizeTimeTickInterval(minorTickInterval),
32724                                min,
32725                                max,
32726                                options.startOfWeek
32727                            )
32728                        );
32729                    } else {
32730                        for (
32731                            pos = min + (tickPositions[0] - min) % minorTickInterval; pos <= max; pos += minorTickInterval
32732                        ) {
32733                            // Very, very, tight grid lines (#5771)
32734                            if (pos === minorTickPositions[0]) {
32735                                break;
32736                            }
32737                            minorTickPositions.push(pos);
32738                        }
32739                    }
32740                }
32741
32742                if (minorTickPositions.length !== 0) {
32743                    axis.trimTicks(minorTickPositions); // #3652 #3743 #1498 #6330
32744                }
32745                return minorTickPositions;
32746            },
32747
32748            /**
32749             * Adjust the min and max for the minimum range. Keep in mind that the
32750             * series data is not yet processed, so we don't have information on data
32751             * cropping and grouping, or updated axis.pointRange or series.pointRange.
32752             * The data can't be processed until we have finally established min and
32753             * max.
32754             *
32755             * @private
32756             */
32757            adjustForMinRange: function() {
32758                var axis = this,
32759                    options = axis.options,
32760                    min = axis.min,
32761                    max = axis.max,
32762                    zoomOffset,
32763                    spaceAvailable,
32764                    closestDataRange,
32765                    i,
32766                    distance,
32767                    xData,
32768                    loopLength,
32769                    minArgs,
32770                    maxArgs,
32771                    minRange;
32772
32773                // Set the automatic minimum range based on the closest point distance
32774                if (axis.isXAxis && axis.minRange === undefined && !axis.isLog) {
32775
32776                    if (defined(options.min) || defined(options.max)) {
32777                        axis.minRange = null; // don't do this again
32778
32779                    } else {
32780
32781                        // Find the closest distance between raw data points, as opposed
32782                        // to closestPointRange that applies to processed points
32783                        // (cropped and grouped)
32784                        each(axis.series, function(series) {
32785                            xData = series.xData;
32786                            loopLength = series.xIncrement ? 1 : xData.length - 1;
32787                            for (i = loopLength; i > 0; i--) {
32788                                distance = xData[i] - xData[i - 1];
32789                                if (
32790                                    closestDataRange === undefined ||
32791                                    distance < closestDataRange
32792                                ) {
32793                                    closestDataRange = distance;
32794                                }
32795                            }
32796                        });
32797                        axis.minRange = Math.min(
32798                            closestDataRange * 5,
32799                            axis.dataMax - axis.dataMin
32800                        );
32801                    }
32802                }
32803
32804                // if minRange is exceeded, adjust
32805                if (max - min < axis.minRange) {
32806
32807                    spaceAvailable = axis.dataMax - axis.dataMin >= axis.minRange;
32808                    minRange = axis.minRange;
32809                    zoomOffset = (minRange - max + min) / 2;
32810
32811                    // if min and max options have been set, don't go beyond it
32812                    minArgs = [min - zoomOffset, pick(options.min, min - zoomOffset)];
32813                    // If space is available, stay within the data range
32814                    if (spaceAvailable) {
32815                        minArgs[2] = axis.isLog ?
32816                            axis.log2lin(axis.dataMin) :
32817                            axis.dataMin;
32818                    }
32819                    min = arrayMax(minArgs);
32820
32821                    maxArgs = [min + minRange, pick(options.max, min + minRange)];
32822                    // If space is availabe, stay within the data range
32823                    if (spaceAvailable) {
32824                        maxArgs[2] = axis.isLog ?
32825                            axis.log2lin(axis.dataMax) :
32826                            axis.dataMax;
32827                    }
32828
32829                    max = arrayMin(maxArgs);
32830
32831                    // now if the max is adjusted, adjust the min back
32832                    if (max - min < minRange) {
32833                        minArgs[0] = max - minRange;
32834                        minArgs[1] = pick(options.min, max - minRange);
32835                        min = arrayMax(minArgs);
32836                    }
32837                }
32838
32839                // Record modified extremes
32840                axis.min = min;
32841                axis.max = max;
32842            },
32843
32844            /**
32845             * Find the closestPointRange across all series.
32846             *
32847             * @private
32848             */
32849            getClosest: function() {
32850                var ret;
32851
32852                if (this.categories) {
32853                    ret = 1;
32854                } else {
32855                    each(this.series, function(series) {
32856                        var seriesClosest = series.closestPointRange,
32857                            visible = series.visible ||
32858                            !series.chart.options.chart.ignoreHiddenSeries;
32859
32860                        if (!series.noSharedTooltip &&
32861                            defined(seriesClosest) &&
32862                            visible
32863                        ) {
32864                            ret = defined(ret) ?
32865                                Math.min(ret, seriesClosest) :
32866                                seriesClosest;
32867                        }
32868                    });
32869                }
32870                return ret;
32871            },
32872
32873            /**
32874             * When a point name is given and no x, search for the name in the existing
32875             * categories, or if categories aren't provided, search names or create a
32876             * new category (#2522).
32877             *
32878             * @private
32879             *
32880             * @param  {Point}
32881             *         The point to inspect.
32882             *
32883             * @return {Number}
32884             *         The X value that the point is given.
32885             */
32886            nameToX: function(point) {
32887                var explicitCategories = isArray(this.categories),
32888                    names = explicitCategories ? this.categories : this.names,
32889                    nameX = point.options.x,
32890                    x;
32891
32892                point.series.requireSorting = false;
32893
32894                if (!defined(nameX)) {
32895                    nameX = this.options.uniqueNames === false ?
32896                        point.series.autoIncrement() :
32897                        inArray(point.name, names);
32898                }
32899                if (nameX === -1) { // The name is not found in currenct categories
32900                    if (!explicitCategories) {
32901                        x = names.length;
32902                    }
32903                } else {
32904                    x = nameX;
32905                }
32906
32907                // Write the last point's name to the names array
32908                if (x !== undefined) {
32909                    this.names[x] = point.name;
32910                }
32911
32912                return x;
32913            },
32914
32915            /**
32916             * When changes have been done to series data, update the axis.names.
32917             *
32918             * @private
32919             */
32920            updateNames: function() {
32921                var axis = this;
32922
32923                if (this.names.length > 0) {
32924                    this.names.length = 0;
32925                    this.minRange = this.userMinRange; // Reset
32926                    each(this.series || [], function(series) {
32927
32928                        // Reset incrementer (#5928)
32929                        series.xIncrement = null;
32930
32931                        // When adding a series, points are not yet generated
32932                        if (!series.points || series.isDirtyData) {
32933                            series.processData();
32934                            series.generatePoints();
32935                        }
32936
32937                        each(series.points, function(point, i) {
32938                            var x;
32939                            if (point.options) {
32940                                x = axis.nameToX(point);
32941                                if (x !== undefined && x !== point.x) {
32942                                    point.x = x;
32943                                    series.xData[i] = x;
32944                                }
32945                            }
32946                        });
32947                    });
32948                }
32949            },
32950
32951            /**
32952             * Update translation information.
32953             *
32954             * @private
32955             */
32956            setAxisTranslation: function(saveOld) {
32957                var axis = this,
32958                    range = axis.max - axis.min,
32959                    pointRange = axis.axisPointRange || 0,
32960                    closestPointRange,
32961                    minPointOffset = 0,
32962                    pointRangePadding = 0,
32963                    linkedParent = axis.linkedParent,
32964                    ordinalCorrection,
32965                    hasCategories = !!axis.categories,
32966                    transA = axis.transA,
32967                    isXAxis = axis.isXAxis;
32968
32969                // Adjust translation for padding. Y axis with categories need to go
32970                // through the same (#1784).
32971                if (isXAxis || hasCategories || pointRange) {
32972
32973                    // Get the closest points
32974                    closestPointRange = axis.getClosest();
32975
32976                    if (linkedParent) {
32977                        minPointOffset = linkedParent.minPointOffset;
32978                        pointRangePadding = linkedParent.pointRangePadding;
32979                    } else {
32980                        each(axis.series, function(series) {
32981                            var seriesPointRange = hasCategories ?
32982                                1 :
32983                                (
32984                                    isXAxis ?
32985                                    pick(
32986                                        series.options.pointRange,
32987                                        closestPointRange,
32988                                        0
32989                                    ) :
32990                                    (axis.axisPointRange || 0)
32991                                ), // #2806
32992                                pointPlacement = series.options.pointPlacement;
32993
32994                            pointRange = Math.max(pointRange, seriesPointRange);
32995
32996                            if (!axis.single) {
32997                                // minPointOffset is the value padding to the left of
32998                                // the axis in order to make room for points with a
32999                                // pointRange, typically columns. When the
33000                                // pointPlacement option is 'between' or 'on', this
33001                                // padding does not apply.
33002                                minPointOffset = Math.max(
33003                                    minPointOffset,
33004                                    isString(pointPlacement) ? 0 : seriesPointRange / 2
33005                                );
33006
33007                                // Determine the total padding needed to the length of
33008                                // the axis to make room for the pointRange. If the
33009                                // series' pointPlacement is 'on', no padding is added.
33010                                pointRangePadding = Math.max(
33011                                    pointRangePadding,
33012                                    pointPlacement === 'on' ? 0 : seriesPointRange
33013                                );
33014                            }
33015                        });
33016                    }
33017
33018                    // Record minPointOffset and pointRangePadding
33019                    ordinalCorrection = axis.ordinalSlope && closestPointRange ?
33020                        axis.ordinalSlope / closestPointRange :
33021                        1; // #988, #1853
33022                    axis.minPointOffset = minPointOffset =
33023                        minPointOffset * ordinalCorrection;
33024                    axis.pointRangePadding =
33025                        pointRangePadding = pointRangePadding * ordinalCorrection;
33026
33027                    // pointRange means the width reserved for each point, like in a
33028                    // column chart
33029                    axis.pointRange = Math.min(pointRange, range);
33030
33031                    // closestPointRange means the closest distance between points. In
33032                    // columns it is mostly equal to pointRange, but in lines pointRange
33033                    // is 0 while closestPointRange is some other value
33034                    if (isXAxis) {
33035                        axis.closestPointRange = closestPointRange;
33036                    }
33037                }
33038
33039                // Secondary values
33040                if (saveOld) {
33041                    axis.oldTransA = transA;
33042                }
33043                axis.translationSlope = axis.transA = transA =
33044                    axis.options.staticScale ||
33045                    axis.len / ((range + pointRangePadding) || 1);
33046
33047                // Translation addend
33048                axis.transB = axis.horiz ? axis.left : axis.bottom;
33049                axis.minPixelPadding = transA * minPointOffset;
33050            },
33051
33052            minFromRange: function() {
33053                return this.max - this.range;
33054            },
33055
33056            /**
33057             * Set the tick positions to round values and optionally extend the extremes
33058             * to the nearest tick.
33059             *
33060             * @private
33061             */
33062            setTickInterval: function(secondPass) {
33063                var axis = this,
33064                    chart = axis.chart,
33065                    options = axis.options,
33066                    isLog = axis.isLog,
33067                    log2lin = axis.log2lin,
33068                    isDatetimeAxis = axis.isDatetimeAxis,
33069                    isXAxis = axis.isXAxis,
33070                    isLinked = axis.isLinked,
33071                    maxPadding = options.maxPadding,
33072                    minPadding = options.minPadding,
33073                    length,
33074                    linkedParentExtremes,
33075                    tickIntervalOption = options.tickInterval,
33076                    minTickInterval,
33077                    tickPixelIntervalOption = options.tickPixelInterval,
33078                    categories = axis.categories,
33079                    threshold = axis.threshold,
33080                    softThreshold = axis.softThreshold,
33081                    thresholdMin,
33082                    thresholdMax,
33083                    hardMin,
33084                    hardMax;
33085
33086                if (!isDatetimeAxis && !categories && !isLinked) {
33087                    this.getTickAmount();
33088                }
33089
33090                // Min or max set either by zooming/setExtremes or initial options
33091                hardMin = pick(axis.userMin, options.min);
33092                hardMax = pick(axis.userMax, options.max);
33093
33094                // Linked axis gets the extremes from the parent axis
33095                if (isLinked) {
33096                    axis.linkedParent = chart[axis.coll][options.linkedTo];
33097                    linkedParentExtremes = axis.linkedParent.getExtremes();
33098                    axis.min = pick(
33099                        linkedParentExtremes.min,
33100                        linkedParentExtremes.dataMin
33101                    );
33102                    axis.max = pick(
33103                        linkedParentExtremes.max,
33104                        linkedParentExtremes.dataMax
33105                    );
33106                    if (options.type !== axis.linkedParent.options.type) {
33107                        H.error(11, 1); // Can't link axes of different type
33108                    }
33109
33110                    // Initial min and max from the extreme data values
33111                } else {
33112
33113                    // Adjust to hard threshold
33114                    if (!softThreshold && defined(threshold)) {
33115                        if (axis.dataMin >= threshold) {
33116                            thresholdMin = threshold;
33117                            minPadding = 0;
33118                        } else if (axis.dataMax <= threshold) {
33119                            thresholdMax = threshold;
33120                            maxPadding = 0;
33121                        }
33122                    }
33123
33124                    axis.min = pick(hardMin, thresholdMin, axis.dataMin);
33125                    axis.max = pick(hardMax, thresholdMax, axis.dataMax);
33126
33127                }
33128
33129                if (isLog) {
33130                    if (
33131                        axis.positiveValuesOnly &&
33132                        !secondPass &&
33133                        Math.min(axis.min, pick(axis.dataMin, axis.min)) <= 0
33134                    ) { // #978
33135                        H.error(10, 1); // Can't plot negative values on log axis
33136                    }
33137                    // The correctFloat cures #934, float errors on full tens. But it
33138                    // was too aggressive for #4360 because of conversion back to lin,
33139                    // therefore use precision 15.
33140                    axis.min = correctFloat(log2lin(axis.min), 15);
33141                    axis.max = correctFloat(log2lin(axis.max), 15);
33142                }
33143
33144                // handle zoomed range
33145                if (axis.range && defined(axis.max)) {
33146                    axis.userMin = axis.min = hardMin =
33147                        Math.max(axis.dataMin, axis.minFromRange()); // #618, #6773
33148                    axis.userMax = hardMax = axis.max;
33149
33150                    axis.range = null; // don't use it when running setExtremes
33151                }
33152
33153                // Hook for Highstock Scroller. Consider combining with beforePadding.
33154                fireEvent(axis, 'foundExtremes');
33155
33156                // Hook for adjusting this.min and this.max. Used by bubble series.
33157                if (axis.beforePadding) {
33158                    axis.beforePadding();
33159                }
33160
33161                // adjust min and max for the minimum range
33162                axis.adjustForMinRange();
33163
33164                // Pad the values to get clear of the chart's edges. To avoid
33165                // tickInterval taking the padding into account, we do this after
33166                // computing tick interval (#1337).
33167                if (!categories &&
33168                    !axis.axisPointRange &&
33169                    !axis.usePercentage &&
33170                    !isLinked &&
33171                    defined(axis.min) &&
33172                    defined(axis.max)
33173                ) {
33174                    length = axis.max - axis.min;
33175                    if (length) {
33176                        if (!defined(hardMin) && minPadding) {
33177                            axis.min -= length * minPadding;
33178                        }
33179                        if (!defined(hardMax) && maxPadding) {
33180                            axis.max += length * maxPadding;
33181                        }
33182                    }
33183                }
33184
33185                // Handle options for floor, ceiling, softMin and softMax (#6359)
33186                if (isNumber(options.softMin)) {
33187                    axis.min = Math.min(axis.min, options.softMin);
33188                }
33189                if (isNumber(options.softMax)) {
33190                    axis.max = Math.max(axis.max, options.softMax);
33191                }
33192                if (isNumber(options.floor)) {
33193                    axis.min = Math.max(axis.min, options.floor);
33194                }
33195                if (isNumber(options.ceiling)) {
33196                    axis.max = Math.min(axis.max, options.ceiling);
33197                }
33198
33199
33200                // When the threshold is soft, adjust the extreme value only if the data
33201                // extreme and the padded extreme land on either side of the threshold.
33202                // For example, a series of [0, 1, 2, 3] would make the yAxis add a tick
33203                // for -1 because of the default minPadding and startOnTick options.
33204                // This is prevented by the softThreshold option.
33205                if (softThreshold && defined(axis.dataMin)) {
33206                    threshold = threshold || 0;
33207                    if (!defined(hardMin) &&
33208                        axis.min < threshold &&
33209                        axis.dataMin >= threshold
33210                    ) {
33211                        axis.min = threshold;
33212
33213                    } else if (!defined(hardMax) &&
33214                        axis.max > threshold &&
33215                        axis.dataMax <= threshold
33216                    ) {
33217                        axis.max = threshold;
33218                    }
33219                }
33220
33221
33222                // get tickInterval
33223                if (
33224                    axis.min === axis.max ||
33225                    axis.min === undefined ||
33226                    axis.max === undefined
33227                ) {
33228                    axis.tickInterval = 1;
33229
33230                } else if (
33231                    isLinked &&
33232                    !tickIntervalOption &&
33233                    tickPixelIntervalOption ===
33234                    axis.linkedParent.options.tickPixelInterval
33235                ) {
33236                    axis.tickInterval = tickIntervalOption =
33237                        axis.linkedParent.tickInterval;
33238
33239                } else {
33240                    axis.tickInterval = pick(
33241                        tickIntervalOption,
33242                        this.tickAmount ?
33243                        ((axis.max - axis.min) / Math.max(this.tickAmount - 1, 1)) :
33244                        undefined,
33245                        // For categoried axis, 1 is default, for linear axis use
33246                        // tickPix
33247                        categories ?
33248                        1 :
33249                        // don't let it be more than the data range
33250                        (axis.max - axis.min) * tickPixelIntervalOption /
33251                        Math.max(axis.len, tickPixelIntervalOption)
33252                    );
33253                }
33254
33255                /**
33256                 * Now we're finished detecting min and max, crop and group series data.
33257                 * This is in turn needed in order to find tick positions in
33258                 * ordinal axes.
33259                 */
33260                if (isXAxis && !secondPass) {
33261                    each(axis.series, function(series) {
33262                        series.processData(
33263                            axis.min !== axis.oldMin || axis.max !== axis.oldMax
33264                        );
33265                    });
33266                }
33267
33268                // set the translation factor used in translate function
33269                axis.setAxisTranslation(true);
33270
33271                // hook for ordinal axes and radial axes
33272                if (axis.beforeSetTickPositions) {
33273                    axis.beforeSetTickPositions();
33274                }
33275
33276                // hook for extensions, used in Highstock ordinal axes
33277                if (axis.postProcessTickInterval) {
33278                    axis.tickInterval = axis.postProcessTickInterval(axis.tickInterval);
33279                }
33280
33281                // In column-like charts, don't cramp in more ticks than there are
33282                // points (#1943, #4184)
33283                if (axis.pointRange && !tickIntervalOption) {
33284                    axis.tickInterval = Math.max(axis.pointRange, axis.tickInterval);
33285                }
33286
33287                // Before normalizing the tick interval, handle minimum tick interval.
33288                // This applies only if tickInterval is not defined.
33289                minTickInterval = pick(
33290                    options.minTickInterval,
33291                    axis.isDatetimeAxis && axis.closestPointRange
33292                );
33293                if (!tickIntervalOption && axis.tickInterval < minTickInterval) {
33294                    axis.tickInterval = minTickInterval;
33295                }
33296
33297                // for linear axes, get magnitude and normalize the interval
33298                if (!isDatetimeAxis && !isLog && !tickIntervalOption) {
33299                    axis.tickInterval = normalizeTickInterval(
33300                        axis.tickInterval,
33301                        null,
33302                        getMagnitude(axis.tickInterval),
33303                        // If the tick interval is between 0.5 and 5 and the axis max is
33304                        // in the order of thousands, chances are we are dealing with
33305                        // years. Don't allow decimals. #3363.
33306                        pick(
33307                            options.allowDecimals, !(
33308                                axis.tickInterval > 0.5 &&
33309                                axis.tickInterval < 5 &&
33310                                axis.max > 1000 &&
33311                                axis.max < 9999
33312                            )
33313                        ), !!this.tickAmount
33314                    );
33315                }
33316
33317                // Prevent ticks from getting so close that we can't draw the labels
33318                if (!this.tickAmount) {
33319                    axis.tickInterval = axis.unsquish();
33320                }
33321
33322                this.setTickPositions();
33323            },
33324
33325            /**
33326             * Now we have computed the normalized tickInterval, get the tick positions
33327             */
33328            setTickPositions: function() {
33329
33330                var options = this.options,
33331                    tickPositions,
33332                    tickPositionsOption = options.tickPositions,
33333                    minorTickIntervalOption = this.getMinorTickInterval(),
33334                    tickPositioner = options.tickPositioner,
33335                    startOnTick = options.startOnTick,
33336                    endOnTick = options.endOnTick;
33337
33338                // Set the tickmarkOffset
33339                this.tickmarkOffset = (
33340                    this.categories &&
33341                    options.tickmarkPlacement === 'between' &&
33342                    this.tickInterval === 1
33343                ) ? 0.5 : 0; // #3202
33344
33345
33346                // get minorTickInterval
33347                this.minorTickInterval =
33348                    minorTickIntervalOption === 'auto' &&
33349                    this.tickInterval ?
33350                    this.tickInterval / 5 :
33351                    minorTickIntervalOption;
33352
33353                // When there is only one point, or all points have the same value on
33354                // this axis, then min and max are equal and tickPositions.length is 0
33355                // or 1. In this case, add some padding in order to center the point,
33356                // but leave it with one tick. #1337.
33357                this.single =
33358                    this.min === this.max &&
33359                    defined(this.min) &&
33360                    !this.tickAmount &&
33361                    (
33362                        // Data is on integer (#6563)
33363                        parseInt(this.min, 10) === this.min ||
33364
33365                        // Between integers and decimals are not allowed (#6274)
33366                        options.allowDecimals !== false
33367                    );
33368
33369                // Find the tick positions. Work on a copy (#1565)
33370                this.tickPositions = tickPositions =
33371                    tickPositionsOption && tickPositionsOption.slice();
33372                if (!tickPositions) {
33373
33374                    if (this.isDatetimeAxis) {
33375                        tickPositions = this.getTimeTicks(
33376                            this.normalizeTimeTickInterval(
33377                                this.tickInterval,
33378                                options.units
33379                            ),
33380                            this.min,
33381                            this.max,
33382                            options.startOfWeek,
33383                            this.ordinalPositions,
33384                            this.closestPointRange,
33385                            true
33386                        );
33387                    } else if (this.isLog) {
33388                        tickPositions = this.getLogTickPositions(
33389                            this.tickInterval,
33390                            this.min,
33391                            this.max
33392                        );
33393                    } else {
33394                        tickPositions = this.getLinearTickPositions(
33395                            this.tickInterval,
33396                            this.min,
33397                            this.max
33398                        );
33399                    }
33400
33401                    // Too dense ticks, keep only the first and last (#4477)
33402                    if (tickPositions.length > this.len) {
33403                        tickPositions = [tickPositions[0], tickPositions.pop()];
33404                        // Reduce doubled value (#7339)
33405                        if (tickPositions[0] === tickPositions[1]) {
33406                            tickPositions.length = 1;
33407                        }
33408                    }
33409
33410                    this.tickPositions = tickPositions;
33411
33412                    // Run the tick positioner callback, that allows modifying auto tick
33413                    // positions.
33414                    if (tickPositioner) {
33415                        tickPositioner = tickPositioner.apply(
33416                            this, [this.min, this.max]
33417                        );
33418                        if (tickPositioner) {
33419                            this.tickPositions = tickPositions = tickPositioner;
33420                        }
33421                    }
33422
33423                }
33424
33425                // Reset min/max or remove extremes based on start/end on tick
33426                this.paddedTicks = tickPositions.slice(0); // Used for logarithmic minor
33427                this.trimTicks(tickPositions, startOnTick, endOnTick);
33428                if (!this.isLinked) {
33429
33430                    // Substract half a unit (#2619, #2846, #2515, #3390),
33431                    // but not in case of multiple ticks (#6897)
33432                    if (this.single && tickPositions.length < 2) {
33433                        this.min -= 0.5;
33434                        this.max += 0.5;
33435                    }
33436                    if (!tickPositionsOption && !tickPositioner) {
33437                        this.adjustTickAmount();
33438                    }
33439                }
33440            },
33441
33442            /**
33443             * Handle startOnTick and endOnTick by either adapting to padding min/max or
33444             * rounded min/max. Also handle single data points.
33445             *
33446             * @private
33447             */
33448            trimTicks: function(tickPositions, startOnTick, endOnTick) {
33449                var roundedMin = tickPositions[0],
33450                    roundedMax = tickPositions[tickPositions.length - 1],
33451                    minPointOffset = this.minPointOffset || 0;
33452
33453                if (!this.isLinked) {
33454                    if (startOnTick && roundedMin !== -Infinity) { // #6502
33455                        this.min = roundedMin;
33456                    } else {
33457                        while (this.min - minPointOffset > tickPositions[0]) {
33458                            tickPositions.shift();
33459                        }
33460                    }
33461
33462                    if (endOnTick) {
33463                        this.max = roundedMax;
33464                    } else {
33465                        while (this.max + minPointOffset <
33466                            tickPositions[tickPositions.length - 1]) {
33467                            tickPositions.pop();
33468                        }
33469                    }
33470
33471                    // If no tick are left, set one tick in the middle (#3195)
33472                    if (tickPositions.length === 0 && defined(roundedMin)) {
33473                        tickPositions.push((roundedMax + roundedMin) / 2);
33474                    }
33475                }
33476            },
33477
33478            /**
33479             * Check if there are multiple axes in the same pane.
33480             *
33481             * @private
33482             * @return {Boolean}
33483             *         True if there are other axes.
33484             */
33485            alignToOthers: function() {
33486                var others = {}, // Whether there is another axis to pair with this one
33487                    hasOther,
33488                    options = this.options;
33489
33490                if (
33491                    // Only if alignTicks is true
33492                    this.chart.options.chart.alignTicks !== false &&
33493                    options.alignTicks !== false &&
33494
33495                    // Don't try to align ticks on a log axis, they are not evenly
33496                    // spaced (#6021)
33497                    !this.isLog
33498                ) {
33499                    each(this.chart[this.coll], function(axis) {
33500                        var otherOptions = axis.options,
33501                            horiz = axis.horiz,
33502                            key = [
33503                                horiz ? otherOptions.left : otherOptions.top,
33504                                otherOptions.width,
33505                                otherOptions.height,
33506                                otherOptions.pane
33507                            ].join(',');
33508
33509
33510                        if (axis.series.length) { // #4442
33511                            if (others[key]) {
33512                                hasOther = true; // #4201
33513                            } else {
33514                                others[key] = 1;
33515                            }
33516                        }
33517                    });
33518                }
33519                return hasOther;
33520            },
33521
33522            /**
33523             * Find the max ticks of either the x and y axis collection, and record it
33524             * in `this.tickAmount`.
33525             *
33526             * @private
33527             */
33528            getTickAmount: function() {
33529                var options = this.options,
33530                    tickAmount = options.tickAmount,
33531                    tickPixelInterval = options.tickPixelInterval;
33532
33533                if (!defined(options.tickInterval) &&
33534                    this.len < tickPixelInterval &&
33535                    !this.isRadial &&
33536                    !this.isLog &&
33537                    options.startOnTick &&
33538                    options.endOnTick
33539                ) {
33540                    tickAmount = 2;
33541                }
33542
33543                if (!tickAmount && this.alignToOthers()) {
33544                    // Add 1 because 4 tick intervals require 5 ticks (including first
33545                    // and last)
33546                    tickAmount = Math.ceil(this.len / tickPixelInterval) + 1;
33547                }
33548
33549                // For tick amounts of 2 and 3, compute five ticks and remove the
33550                // intermediate ones. This prevents the axis from adding ticks that are
33551                // too far away from the data extremes.
33552                if (tickAmount < 4) {
33553                    this.finalTickAmt = tickAmount;
33554                    tickAmount = 5;
33555                }
33556
33557                this.tickAmount = tickAmount;
33558            },
33559
33560            /**
33561             * When using multiple axes, adjust the number of ticks to match the highest
33562             * number of ticks in that group.
33563             *
33564             * @private
33565             */
33566            adjustTickAmount: function() {
33567                var tickInterval = this.tickInterval,
33568                    tickPositions = this.tickPositions,
33569                    tickAmount = this.tickAmount,
33570                    finalTickAmt = this.finalTickAmt,
33571                    currentTickAmount = tickPositions && tickPositions.length,
33572                    i,
33573                    len;
33574
33575                if (currentTickAmount < tickAmount) {
33576                    while (tickPositions.length < tickAmount) {
33577                        tickPositions.push(correctFloat(
33578                            tickPositions[tickPositions.length - 1] + tickInterval
33579                        ));
33580                    }
33581                    this.transA *= (currentTickAmount - 1) / (tickAmount - 1);
33582                    this.max = tickPositions[tickPositions.length - 1];
33583
33584                    // We have too many ticks, run second pass to try to reduce ticks
33585                } else if (currentTickAmount > tickAmount) {
33586                    this.tickInterval *= 2;
33587                    this.setTickPositions();
33588                }
33589
33590                // The finalTickAmt property is set in getTickAmount
33591                if (defined(finalTickAmt)) {
33592                    i = len = tickPositions.length;
33593                    while (i--) {
33594                        if (
33595                            // Remove every other tick
33596                            (finalTickAmt === 3 && i % 2 === 1) ||
33597                            // Remove all but first and last
33598                            (finalTickAmt <= 2 && i > 0 && i < len - 1)
33599                        ) {
33600                            tickPositions.splice(i, 1);
33601                        }
33602                    }
33603                    this.finalTickAmt = undefined;
33604                }
33605            },
33606
33607            /**
33608             * Set the scale based on data min and max, user set min and max or options.
33609             * 
33610             * @private
33611             */
33612            setScale: function() {
33613                var axis = this,
33614                    isDirtyData,
33615                    isDirtyAxisLength;
33616
33617                axis.oldMin = axis.min;
33618                axis.oldMax = axis.max;
33619                axis.oldAxisLength = axis.len;
33620
33621                // set the new axisLength
33622                axis.setAxisSize();
33623                isDirtyAxisLength = axis.len !== axis.oldAxisLength;
33624
33625                // is there new data?
33626                each(axis.series, function(series) {
33627                    if (
33628                        series.isDirtyData ||
33629                        series.isDirty ||
33630                        // When x axis is dirty, we need new data extremes for y as well
33631                        series.xAxis.isDirty
33632                    ) {
33633                        isDirtyData = true;
33634                    }
33635                });
33636
33637                // do we really need to go through all this?
33638                if (
33639                    isDirtyAxisLength ||
33640                    isDirtyData ||
33641                    axis.isLinked ||
33642                    axis.forceRedraw ||
33643                    axis.userMin !== axis.oldUserMin ||
33644                    axis.userMax !== axis.oldUserMax ||
33645                    axis.alignToOthers()
33646                ) {
33647
33648                    if (axis.resetStacks) {
33649                        axis.resetStacks();
33650                    }
33651
33652                    axis.forceRedraw = false;
33653
33654                    // get data extremes if needed
33655                    axis.getSeriesExtremes();
33656
33657                    // get fixed positions based on tickInterval
33658                    axis.setTickInterval();
33659
33660                    // record old values to decide whether a rescale is necessary later
33661                    // on (#540)
33662                    axis.oldUserMin = axis.userMin;
33663                    axis.oldUserMax = axis.userMax;
33664
33665                    // Mark as dirty if it is not already set to dirty and extremes have
33666                    // changed. #595.
33667                    if (!axis.isDirty) {
33668                        axis.isDirty =
33669                            isDirtyAxisLength ||
33670                            axis.min !== axis.oldMin ||
33671                            axis.max !== axis.oldMax;
33672                    }
33673                } else if (axis.cleanStacks) {
33674                    axis.cleanStacks();
33675                }
33676            },
33677
33678            /**
33679             * Set the minimum and maximum of the axes after render time. If the
33680             * `startOnTick` and `endOnTick` options are true, the minimum and maximum
33681             * values are rounded off to the nearest tick. To prevent this, these
33682             * options can be set to false before calling setExtremes. Also, setExtremes
33683             * will not allow a range lower than the `minRange` option, which by default
33684             * is the range of five points.
33685             * 
33686             * @param  {Number} [newMin]
33687             *         The new minimum value.
33688             * @param  {Number} [newMax]
33689             *         The new maximum value.
33690             * @param  {Boolean} [redraw=true]
33691             *         Whether to redraw the chart or wait for an explicit call to 
33692             *         {@link Highcharts.Chart#redraw}
33693             * @param  {AnimationOptions} [animation=true]
33694             *         Enable or modify animations.
33695             * @param  {Object} [eventArguments]
33696             *         Arguments to be accessed in event handler.
33697             *
33698             * @sample highcharts/members/axis-setextremes/
33699             *         Set extremes from a button
33700             * @sample highcharts/members/axis-setextremes-datetime/
33701             *         Set extremes on a datetime axis
33702             * @sample highcharts/members/axis-setextremes-off-ticks/
33703             *         Set extremes off ticks
33704             * @sample stock/members/axis-setextremes/
33705             *         Set extremes in Highstock
33706             * @sample maps/members/axis-setextremes/
33707             *         Set extremes in Highmaps
33708             */
33709            setExtremes: function(newMin, newMax, redraw, animation, eventArguments) {
33710                var axis = this,
33711                    chart = axis.chart;
33712
33713                redraw = pick(redraw, true); // defaults to true
33714
33715                each(axis.series, function(serie) {
33716                    delete serie.kdTree;
33717                });
33718
33719                // Extend the arguments with min and max
33720                eventArguments = extend(eventArguments, {
33721                    min: newMin,
33722                    max: newMax
33723                });
33724
33725                // Fire the event
33726                fireEvent(axis, 'setExtremes', eventArguments, function() {
33727
33728                    axis.userMin = newMin;
33729                    axis.userMax = newMax;
33730                    axis.eventArgs = eventArguments;
33731
33732                    if (redraw) {
33733                        chart.redraw(animation);
33734                    }
33735                });
33736            },
33737
33738            /**
33739             * Overridable method for zooming chart. Pulled out in a separate method to
33740             * allow overriding in stock charts.
33741             *
33742             * @private
33743             */
33744            zoom: function(newMin, newMax) {
33745                var dataMin = this.dataMin,
33746                    dataMax = this.dataMax,
33747                    options = this.options,
33748                    min = Math.min(dataMin, pick(options.min, dataMin)),
33749                    max = Math.max(dataMax, pick(options.max, dataMax));
33750
33751                if (newMin !== this.min || newMax !== this.max) { // #5790
33752
33753                    // Prevent pinch zooming out of range. Check for defined is for
33754                    // #1946. #1734.
33755                    if (!this.allowZoomOutside) {
33756                        // #6014, sometimes newMax will be smaller than min (or newMin
33757                        // will be larger than max).
33758                        if (defined(dataMin)) {
33759                            if (newMin < min) {
33760                                newMin = min;
33761                            }
33762                            if (newMin > max) {
33763                                newMin = max;
33764                            }
33765                        }
33766                        if (defined(dataMax)) {
33767                            if (newMax < min) {
33768                                newMax = min;
33769                            }
33770                            if (newMax > max) {
33771                                newMax = max;
33772                            }
33773                        }
33774                    }
33775
33776                    // In full view, displaying the reset zoom button is not required
33777                    this.displayBtn = newMin !== undefined || newMax !== undefined;
33778
33779                    // Do it
33780                    this.setExtremes(
33781                        newMin,
33782                        newMax,
33783                        false,
33784                        undefined, {
33785                            trigger: 'zoom'
33786                        }
33787                    );
33788                }
33789
33790                return true;
33791            },
33792
33793            /**
33794             * Update the axis metrics.
33795             *
33796             * @private
33797             */
33798            setAxisSize: function() {
33799                var chart = this.chart,
33800                    options = this.options,
33801                    // [top, right, bottom, left]
33802                    offsets = options.offsets || [0, 0, 0, 0],
33803                    horiz = this.horiz,
33804
33805                    // Check for percentage based input values. Rounding fixes problems
33806                    // with column overflow and plot line filtering (#4898, #4899)
33807                    width = this.width = Math.round(H.relativeLength(
33808                        pick(
33809                            options.width,
33810                            chart.plotWidth - offsets[3] + offsets[1]
33811                        ),
33812                        chart.plotWidth
33813                    )),
33814                    height = this.height = Math.round(H.relativeLength(
33815                        pick(
33816                            options.height,
33817                            chart.plotHeight - offsets[0] + offsets[2]
33818                        ),
33819                        chart.plotHeight
33820                    )),
33821                    top = this.top = Math.round(H.relativeLength(
33822                        pick(options.top, chart.plotTop + offsets[0]),
33823                        chart.plotHeight,
33824                        chart.plotTop
33825                    )),
33826                    left = this.left = Math.round(H.relativeLength(
33827                        pick(options.left, chart.plotLeft + offsets[3]),
33828                        chart.plotWidth,
33829                        chart.plotLeft
33830                    ));
33831
33832                // Expose basic values to use in Series object and navigator
33833                this.bottom = chart.chartHeight - height - top;
33834                this.right = chart.chartWidth - width - left;
33835
33836                // Direction agnostic properties
33837                this.len = Math.max(horiz ? width : height, 0); // Math.max fixes #905
33838                this.pos = horiz ? left : top; // distance from SVG origin
33839            },
33840
33841            /**
33842             * The returned object literal from the {@link Highcharts.Axis#getExtremes}
33843             * function.
33844             *
33845             * @typedef  {Object} Extremes
33846             * @property {Number} dataMax
33847             *           The maximum value of the axis' associated series.
33848             * @property {Number} dataMin
33849             *           The minimum value of the axis' associated series.
33850             * @property {Number} max
33851             *           The maximum axis value, either automatic or set manually. If
33852             *           the `max` option is not set, `maxPadding` is 0 and `endOnTick`
33853             *           is false, this value will be the same as `dataMax`.
33854             * @property {Number} min
33855             *           The minimum axis value, either automatic or set manually. If
33856             *           the `min` option is not set, `minPadding` is 0 and
33857             *           `startOnTick` is false, this value will be the same
33858             *           as `dataMin`.
33859             */
33860            /**
33861             * Get the current extremes for the axis.
33862             *
33863             * @returns {Extremes}
33864             *          An object containing extremes information.
33865             * 
33866             * @sample  highcharts/members/axis-getextremes/
33867             *          Report extremes by click on a button
33868             * @sample  maps/members/axis-getextremes/
33869             *          Get extremes in Highmaps
33870             */
33871            getExtremes: function() {
33872                var axis = this,
33873                    isLog = axis.isLog,
33874                    lin2log = axis.lin2log;
33875
33876                return {
33877                    min: isLog ? correctFloat(lin2log(axis.min)) : axis.min,
33878                    max: isLog ? correctFloat(lin2log(axis.max)) : axis.max,
33879                    dataMin: axis.dataMin,
33880                    dataMax: axis.dataMax,
33881                    userMin: axis.userMin,
33882                    userMax: axis.userMax
33883                };
33884            },
33885
33886            /**
33887             * Get the zero plane either based on zero or on the min or max value.
33888             * Used in bar and area plots.
33889             *
33890             * @param  {Number} threshold
33891             *         The threshold in axis values.
33892             *
33893             * @return {Number}
33894             *         The translated threshold position in terms of pixels, and
33895             *         corrected to stay within the axis bounds.
33896             */
33897            getThreshold: function(threshold) {
33898                var axis = this,
33899                    isLog = axis.isLog,
33900                    lin2log = axis.lin2log,
33901                    realMin = isLog ? lin2log(axis.min) : axis.min,
33902                    realMax = isLog ? lin2log(axis.max) : axis.max;
33903
33904                if (threshold === null) {
33905                    threshold = realMin;
33906                } else if (realMin > threshold) {
33907                    threshold = realMin;
33908                } else if (realMax < threshold) {
33909                    threshold = realMax;
33910                }
33911
33912                return axis.translate(threshold, 0, 1, 0, 1);
33913            },
33914
33915            /**
33916             * Compute auto alignment for the axis label based on which side the axis is
33917             * on and the given rotation for the label.
33918             *
33919             * @param  {Number} rotation
33920             *         The rotation in degrees as set by either the `rotation` or 
33921             *         `autoRotation` options.
33922             * @private
33923             */
33924            autoLabelAlign: function(rotation) {
33925                var ret,
33926                    angle = (pick(rotation, 0) - (this.side * 90) + 720) % 360;
33927
33928                if (angle > 15 && angle < 165) {
33929                    ret = 'right';
33930                } else if (angle > 195 && angle < 345) {
33931                    ret = 'left';
33932                } else {
33933                    ret = 'center';
33934                }
33935                return ret;
33936            },
33937
33938            /**
33939             * Get the tick length and width for the axis based on axis options.
33940             *
33941             * @private
33942             * 
33943             * @param  {String} prefix
33944             *         'tick' or 'minorTick'
33945             * @return {Array.<Number>}
33946             *         An array of tickLength and tickWidth
33947             */
33948            tickSize: function(prefix) {
33949                var options = this.options,
33950                    tickLength = options[prefix + 'Length'],
33951                    tickWidth = pick(
33952                        options[prefix + 'Width'],
33953                        prefix === 'tick' && this.isXAxis ? 1 : 0 // X axis default 1
33954                    );
33955
33956                if (tickWidth && tickLength) {
33957                    // Negate the length
33958                    if (options[prefix + 'Position'] === 'inside') {
33959                        tickLength = -tickLength;
33960                    }
33961                    return [tickLength, tickWidth];
33962                }
33963
33964            },
33965
33966            /**
33967             * Return the size of the labels.
33968             *
33969             * @private
33970             */
33971            labelMetrics: function() {
33972                var index = this.tickPositions && this.tickPositions[0] || 0;
33973                return this.chart.renderer.fontMetrics(
33974                    this.options.labels.style && this.options.labels.style.fontSize,
33975                    this.ticks[index] && this.ticks[index].label
33976                );
33977            },
33978
33979            /**
33980             * Prevent the ticks from getting so close we can't draw the labels. On a
33981             * horizontal axis, this is handled by rotating the labels, removing ticks
33982             * and adding ellipsis. On a vertical axis remove ticks and add ellipsis.
33983             *
33984             * @private
33985             */
33986            unsquish: function() {
33987                var labelOptions = this.options.labels,
33988                    horiz = this.horiz,
33989                    tickInterval = this.tickInterval,
33990                    newTickInterval = tickInterval,
33991                    slotSize = this.len / (
33992                        ((this.categories ? 1 : 0) + this.max - this.min) / tickInterval
33993                    ),
33994                    rotation,
33995                    rotationOption = labelOptions.rotation,
33996                    labelMetrics = this.labelMetrics(),
33997                    step,
33998                    bestScore = Number.MAX_VALUE,
33999                    autoRotation,
34000                    // Return the multiple of tickInterval that is needed to avoid
34001                    // collision
34002                    getStep = function(spaceNeeded) {
34003                        var step = spaceNeeded / (slotSize || 1);
34004                        step = step > 1 ? Math.ceil(step) : 1;
34005                        return step * tickInterval;
34006                    };
34007
34008                if (horiz) {
34009                    autoRotation = !labelOptions.staggerLines &&
34010                        !labelOptions.step &&
34011                        ( // #3971
34012                            defined(rotationOption) ? [rotationOption] :
34013                            slotSize < pick(labelOptions.autoRotationLimit, 80) &&
34014                            labelOptions.autoRotation
34015                        );
34016
34017                    if (autoRotation) {
34018
34019                        // Loop over the given autoRotation options, and determine 
34020                        // which gives the best score. The best score is that with
34021                        // the lowest number of steps and a rotation closest
34022                        // to horizontal.
34023                        each(autoRotation, function(rot) {
34024                            var score;
34025
34026                            if (
34027                                rot === rotationOption ||
34028                                (rot && rot >= -90 && rot <= 90)
34029                            ) { // #3891
34030
34031                                step = getStep(
34032                                    Math.abs(labelMetrics.h / Math.sin(deg2rad * rot))
34033                                );
34034
34035                                score = step + Math.abs(rot / 360);
34036
34037                                if (score < bestScore) {
34038                                    bestScore = score;
34039                                    rotation = rot;
34040                                    newTickInterval = step;
34041                                }
34042                            }
34043                        });
34044                    }
34045
34046                } else if (!labelOptions.step) { // #4411
34047                    newTickInterval = getStep(labelMetrics.h);
34048                }
34049
34050                this.autoRotation = autoRotation;
34051                this.labelRotation = pick(rotation, rotationOption);
34052
34053                return newTickInterval;
34054            },
34055
34056            /**
34057             * Get the general slot width for labels/categories on this axis. This may
34058             * change between the pre-render (from Axis.getOffset) and the final tick
34059             * rendering and placement.
34060             *
34061             * @private
34062             * @return {Number}
34063             *         The pixel width allocated to each axis label.
34064             */
34065            getSlotWidth: function() {
34066                // #5086, #1580, #1931
34067                var chart = this.chart,
34068                    horiz = this.horiz,
34069                    labelOptions = this.options.labels,
34070                    slotCount = Math.max(
34071                        this.tickPositions.length - (this.categories ? 0 : 1),
34072                        1
34073                    ),
34074                    marginLeft = chart.margin[3];
34075
34076                return (
34077                    horiz &&
34078                    (labelOptions.step || 0) < 2 &&
34079                    !labelOptions.rotation && // #4415
34080                    ((this.staggerLines || 1) * this.len) / slotCount
34081                ) || (!horiz && (
34082                    // #7028
34083                    (
34084                        labelOptions.style &&
34085                        parseInt(labelOptions.style.width, 10)
34086                    ) ||
34087                    (
34088                        marginLeft &&
34089                        (marginLeft - chart.spacing[3])
34090                    ) ||
34091                    chart.chartWidth * 0.33
34092                ));
34093
34094            },
34095
34096            /**
34097             * Render the axis labels and determine whether ellipsis or rotation need
34098             * to be applied.
34099             *
34100             * @private
34101             */
34102            renderUnsquish: function() {
34103                var chart = this.chart,
34104                    renderer = chart.renderer,
34105                    tickPositions = this.tickPositions,
34106                    ticks = this.ticks,
34107                    labelOptions = this.options.labels,
34108                    horiz = this.horiz,
34109                    slotWidth = this.getSlotWidth(),
34110                    innerWidth = Math.max(
34111                        1,
34112                        Math.round(slotWidth - 2 * (labelOptions.padding || 5))
34113                    ),
34114                    attr = {},
34115                    labelMetrics = this.labelMetrics(),
34116                    textOverflowOption = labelOptions.style &&
34117                    labelOptions.style.textOverflow,
34118                    css,
34119                    maxLabelLength = 0,
34120                    label,
34121                    i,
34122                    pos;
34123
34124                // Set rotation option unless it is "auto", like in gauges
34125                if (!isString(labelOptions.rotation)) {
34126                    attr.rotation = labelOptions.rotation || 0; // #4443
34127                }
34128
34129                // Get the longest label length
34130                each(tickPositions, function(tick) {
34131                    tick = ticks[tick];
34132                    if (tick && tick.labelLength > maxLabelLength) {
34133                        maxLabelLength = tick.labelLength;
34134                    }
34135                });
34136                this.maxLabelLength = maxLabelLength;
34137
34138
34139                // Handle auto rotation on horizontal axis
34140                if (this.autoRotation) {
34141
34142                    // Apply rotation only if the label is too wide for the slot, and
34143                    // the label is wider than its height.
34144                    if (
34145                        maxLabelLength > innerWidth &&
34146                        maxLabelLength > labelMetrics.h
34147                    ) {
34148                        attr.rotation = this.labelRotation;
34149                    } else {
34150                        this.labelRotation = 0;
34151                    }
34152
34153                    // Handle word-wrap or ellipsis on vertical axis
34154                } else if (slotWidth) {
34155                    // For word-wrap or ellipsis
34156                    css = {
34157                        width: innerWidth + 'px'
34158                    };
34159
34160                    if (!textOverflowOption) {
34161                        css.textOverflow = 'clip';
34162
34163                        // On vertical axis, only allow word wrap if there is room
34164                        // for more lines.
34165                        i = tickPositions.length;
34166                        while (!horiz && i--) {
34167                            pos = tickPositions[i];
34168                            label = ticks[pos].label;
34169                            if (label) {
34170                                // Reset ellipsis in order to get the correct
34171                                // bounding box (#4070)
34172                                if (
34173                                    label.styles &&
34174                                    label.styles.textOverflow === 'ellipsis'
34175                                ) {
34176                                    label.css({
34177                                        textOverflow: 'clip'
34178                                    });
34179
34180                                    // Set the correct width in order to read
34181                                    // the bounding box height (#4678, #5034)
34182                                } else if (ticks[pos].labelLength > slotWidth) {
34183                                    label.css({
34184                                        width: slotWidth + 'px'
34185                                    });
34186                                }
34187
34188                                if (
34189                                    label.getBBox().height > (
34190                                        this.len / tickPositions.length -
34191                                        (labelMetrics.h - labelMetrics.f)
34192                                    )
34193                                ) {
34194                                    label.specCss = {
34195                                        textOverflow: 'ellipsis'
34196                                    };
34197                                }
34198                            }
34199                        }
34200                    }
34201                }
34202
34203
34204                // Add ellipsis if the label length is significantly longer than ideal
34205                if (attr.rotation) {
34206                    css = {
34207                        width: (
34208                            maxLabelLength > chart.chartHeight * 0.5 ?
34209                            chart.chartHeight * 0.33 :
34210                            chart.chartHeight
34211                        ) + 'px'
34212                    };
34213                    if (!textOverflowOption) {
34214                        css.textOverflow = 'ellipsis';
34215                    }
34216                }
34217
34218                // Set the explicit or automatic label alignment
34219                this.labelAlign = labelOptions.align ||
34220                    this.autoLabelAlign(this.labelRotation);
34221                if (this.labelAlign) {
34222                    attr.align = this.labelAlign;
34223                }
34224
34225                // Apply general and specific CSS
34226                each(tickPositions, function(pos) {
34227                    var tick = ticks[pos],
34228                        label = tick && tick.label;
34229                    if (label) {
34230                        // This needs to go before the CSS in old IE (#4502)
34231                        label.attr(attr);
34232
34233                        if (css) {
34234                            label.css(merge(css, label.specCss));
34235                        }
34236                        delete label.specCss;
34237                        tick.rotation = attr.rotation;
34238                    }
34239                });
34240
34241                // Note: Why is this not part of getLabelPosition?
34242                this.tickRotCorr = renderer.rotCorr(
34243                    labelMetrics.b,
34244                    this.labelRotation || 0,
34245                    this.side !== 0
34246                );
34247            },
34248
34249            /**
34250             * Return true if the axis has associated data.
34251             *
34252             * @return {Boolean}
34253             *         True if the axis has associated visible series and those series
34254             *         have either valid data points or explicit `min` and `max`
34255             *         settings.
34256             */
34257            hasData: function() {
34258                return (
34259                    this.hasVisibleSeries ||
34260                    (
34261                        defined(this.min) &&
34262                        defined(this.max) &&
34263                        this.tickPositions &&
34264                        this.tickPositions.length > 0
34265                    )
34266                );
34267            },
34268
34269            /**
34270             * Adds the title defined in axis.options.title.
34271             * @param {Boolean} display - whether or not to display the title
34272             */
34273            addTitle: function(display) {
34274                var axis = this,
34275                    renderer = axis.chart.renderer,
34276                    horiz = axis.horiz,
34277                    opposite = axis.opposite,
34278                    options = axis.options,
34279                    axisTitleOptions = options.title,
34280                    textAlign;
34281
34282                if (!axis.axisTitle) {
34283                    textAlign = axisTitleOptions.textAlign;
34284                    if (!textAlign) {
34285                        textAlign = (horiz ? {
34286                            low: 'left',
34287                            middle: 'center',
34288                            high: 'right'
34289                        } : {
34290                            low: opposite ? 'right' : 'left',
34291                            middle: 'center',
34292                            high: opposite ? 'left' : 'right'
34293                        })[axisTitleOptions.align];
34294                    }
34295                    axis.axisTitle = renderer.text(
34296                            axisTitleOptions.text,
34297                            0,
34298                            0,
34299                            axisTitleOptions.useHTML
34300                        )
34301                        .attr({
34302                            zIndex: 7,
34303                            rotation: axisTitleOptions.rotation || 0,
34304                            align: textAlign
34305                        })
34306                        .addClass('highcharts-axis-title')
34307
34308                        .css(axisTitleOptions.style)
34309
34310                        .add(axis.axisGroup);
34311                    axis.axisTitle.isNew = true;
34312                }
34313
34314                // Max width defaults to the length of the axis
34315
34316                if (!axisTitleOptions.style.width && !axis.isRadial) {
34317
34318                    axis.axisTitle.css({
34319                        width: axis.len
34320                    });
34321
34322                }
34323
34324
34325
34326                // hide or show the title depending on whether showEmpty is set
34327                axis.axisTitle[display ? 'show' : 'hide'](true);
34328            },
34329
34330            /**
34331             * Generates a tick for initial positioning.
34332             *
34333             * @private
34334             * @param {number} pos
34335             *        The tick position in axis values.
34336             * @param {number} i
34337             *        The index of the tick in {@link Axis.tickPositions}.
34338             */
34339            generateTick: function(pos) {
34340                var ticks = this.ticks;
34341
34342                if (!ticks[pos]) {
34343                    ticks[pos] = new Tick(this, pos);
34344                } else {
34345                    ticks[pos].addLabel(); // update labels depending on tick interval
34346                }
34347            },
34348
34349            /**
34350             * Render the tick labels to a preliminary position to get their sizes.
34351             *
34352             * @private
34353             */
34354            getOffset: function() {
34355                var axis = this,
34356                    chart = axis.chart,
34357                    renderer = chart.renderer,
34358                    options = axis.options,
34359                    tickPositions = axis.tickPositions,
34360                    ticks = axis.ticks,
34361                    horiz = axis.horiz,
34362                    side = axis.side,
34363                    invertedSide = chart.inverted &&
34364                    !axis.isZAxis ? [1, 0, 3, 2][side] : side,
34365                    hasData,
34366                    showAxis,
34367                    titleOffset = 0,
34368                    titleOffsetOption,
34369                    titleMargin = 0,
34370                    axisTitleOptions = options.title,
34371                    labelOptions = options.labels,
34372                    labelOffset = 0, // reset
34373                    labelOffsetPadded,
34374                    axisOffset = chart.axisOffset,
34375                    clipOffset = chart.clipOffset,
34376                    clip,
34377                    directionFactor = [-1, 1, 1, -1][side],
34378                    className = options.className,
34379                    axisParent = axis.axisParent, // Used in color axis
34380                    lineHeightCorrection,
34381                    tickSize = this.tickSize('tick');
34382
34383                // For reuse in Axis.render
34384                hasData = axis.hasData();
34385                axis.showAxis = showAxis = hasData || pick(options.showEmpty, true);
34386
34387                // Set/reset staggerLines
34388                axis.staggerLines = axis.horiz && labelOptions.staggerLines;
34389
34390                // Create the axisGroup and gridGroup elements on first iteration
34391                if (!axis.axisGroup) {
34392                    axis.gridGroup = renderer.g('grid')
34393                        .attr({
34394                            zIndex: options.gridZIndex || 1
34395                        })
34396                        .addClass(
34397                            'highcharts-' + this.coll.toLowerCase() + '-grid ' +
34398                            (className || '')
34399                        )
34400                        .add(axisParent);
34401                    axis.axisGroup = renderer.g('axis')
34402                        .attr({
34403                            zIndex: options.zIndex || 2
34404                        })
34405                        .addClass(
34406                            'highcharts-' + this.coll.toLowerCase() + ' ' +
34407                            (className || '')
34408                        )
34409                        .add(axisParent);
34410                    axis.labelGroup = renderer.g('axis-labels')
34411                        .attr({
34412                            zIndex: labelOptions.zIndex || 7
34413                        })
34414                        .addClass(
34415                            'highcharts-' + axis.coll.toLowerCase() + '-labels ' +
34416                            (className || '')
34417                        )
34418                        .add(axisParent);
34419                }
34420
34421                if (hasData || axis.isLinked) {
34422
34423                    // Generate ticks
34424                    each(tickPositions, function(pos, i) {
34425                        // i is not used here, but may be used in overrides
34426                        axis.generateTick(pos, i);
34427                    });
34428
34429                    axis.renderUnsquish();
34430
34431
34432                    // Left side must be align: right and right side must
34433                    // have align: left for labels
34434                    if (
34435                        labelOptions.reserveSpace !== false &&
34436                        (
34437                            side === 0 ||
34438                            side === 2 || {
34439                                1: 'left',
34440                                3: 'right'
34441                            }[side] === axis.labelAlign ||
34442                            axis.labelAlign === 'center'
34443                        )
34444                    ) {
34445                        each(tickPositions, function(pos) {
34446                            // get the highest offset
34447                            labelOffset = Math.max(
34448                                ticks[pos].getLabelSize(),
34449                                labelOffset
34450                            );
34451                        });
34452                    }
34453
34454                    if (axis.staggerLines) {
34455                        labelOffset *= axis.staggerLines;
34456                        axis.labelOffset = labelOffset * (axis.opposite ? -1 : 1);
34457                    }
34458
34459                } else { // doesn't have data
34460                    objectEach(ticks, function(tick, n) {
34461                        tick.destroy();
34462                        delete ticks[n];
34463                    });
34464                }
34465
34466                if (
34467                    axisTitleOptions &&
34468                    axisTitleOptions.text &&
34469                    axisTitleOptions.enabled !== false
34470                ) {
34471                    axis.addTitle(showAxis);
34472
34473                    if (showAxis && axisTitleOptions.reserveSpace !== false) {
34474                        axis.titleOffset = titleOffset =
34475                            axis.axisTitle.getBBox()[horiz ? 'height' : 'width'];
34476                        titleOffsetOption = axisTitleOptions.offset;
34477                        titleMargin = defined(titleOffsetOption) ?
34478                            0 :
34479                            pick(axisTitleOptions.margin, horiz ? 5 : 10);
34480                    }
34481                }
34482
34483                // Render the axis line
34484                axis.renderLine();
34485
34486                // handle automatic or user set offset
34487                axis.offset = directionFactor * pick(options.offset, axisOffset[side]);
34488
34489                axis.tickRotCorr = axis.tickRotCorr || {
34490                    x: 0,
34491                    y: 0
34492                }; // polar
34493                if (side === 0) {
34494                    lineHeightCorrection = -axis.labelMetrics().h;
34495                } else if (side === 2) {
34496                    lineHeightCorrection = axis.tickRotCorr.y;
34497                } else {
34498                    lineHeightCorrection = 0;
34499                }
34500
34501                // Find the padded label offset
34502                labelOffsetPadded = Math.abs(labelOffset) + titleMargin;
34503                if (labelOffset) {
34504                    labelOffsetPadded -= lineHeightCorrection;
34505                    labelOffsetPadded += directionFactor * (
34506                        horiz ?
34507                        pick(
34508                            labelOptions.y,
34509                            axis.tickRotCorr.y + directionFactor * 8
34510                        ) :
34511                        labelOptions.x
34512                    );
34513                }
34514
34515                axis.axisTitleMargin = pick(titleOffsetOption, labelOffsetPadded);
34516
34517                axisOffset[side] = Math.max(
34518                    axisOffset[side],
34519                    axis.axisTitleMargin + titleOffset + directionFactor * axis.offset,
34520                    labelOffsetPadded, // #3027
34521                    hasData && tickPositions.length && tickSize ?
34522                    tickSize[0] + directionFactor * axis.offset :
34523                    0 // #4866
34524                );
34525
34526                // Decide the clipping needed to keep the graph inside
34527                // the plot area and axis lines
34528                clip = options.offset ?
34529                    0 :
34530                    Math.floor(axis.axisLine.strokeWidth() / 2) * 2; // #4308, #4371
34531                clipOffset[invertedSide] = Math.max(clipOffset[invertedSide], clip);
34532            },
34533
34534            /**
34535             * Internal function to get the path for the axis line. Extended for polar
34536             * charts.
34537             *
34538             * @param  {Number} lineWidth
34539             *         The line width in pixels.
34540             * @return {Array}
34541             *         The SVG path definition in array form.
34542             */
34543            getLinePath: function(lineWidth) {
34544                var chart = this.chart,
34545                    opposite = this.opposite,
34546                    offset = this.offset,
34547                    horiz = this.horiz,
34548                    lineLeft = this.left + (opposite ? this.width : 0) + offset,
34549                    lineTop = chart.chartHeight - this.bottom -
34550                    (opposite ? this.height : 0) + offset;
34551
34552                if (opposite) {
34553                    lineWidth *= -1; // crispify the other way - #1480, #1687
34554                }
34555
34556                return chart.renderer
34557                    .crispLine([
34558                        'M',
34559                        horiz ?
34560                        this.left :
34561                        lineLeft,
34562                        horiz ?
34563                        lineTop :
34564                        this.top,
34565                        'L',
34566                        horiz ?
34567                        chart.chartWidth - this.right :
34568                        lineLeft,
34569                        horiz ?
34570                        lineTop :
34571                        chart.chartHeight - this.bottom
34572                    ], lineWidth);
34573            },
34574
34575            /**
34576             * Render the axis line. Called internally when rendering and redrawing the
34577             * axis.
34578             */
34579            renderLine: function() {
34580                if (!this.axisLine) {
34581                    this.axisLine = this.chart.renderer.path()
34582                        .addClass('highcharts-axis-line')
34583                        .add(this.axisGroup);
34584
34585
34586                    this.axisLine.attr({
34587                        stroke: this.options.lineColor,
34588                        'stroke-width': this.options.lineWidth,
34589                        zIndex: 7
34590                    });
34591
34592                }
34593            },
34594
34595            /**
34596             * Position the axis title.
34597             *
34598             * @private
34599             *
34600             * @return {Object}
34601             *         X and Y positions for the title.
34602             */
34603            getTitlePosition: function() {
34604                // compute anchor points for each of the title align options
34605                var horiz = this.horiz,
34606                    axisLeft = this.left,
34607                    axisTop = this.top,
34608                    axisLength = this.len,
34609                    axisTitleOptions = this.options.title,
34610                    margin = horiz ? axisLeft : axisTop,
34611                    opposite = this.opposite,
34612                    offset = this.offset,
34613                    xOption = axisTitleOptions.x || 0,
34614                    yOption = axisTitleOptions.y || 0,
34615                    axisTitle = this.axisTitle,
34616                    fontMetrics = this.chart.renderer.fontMetrics(
34617                        axisTitleOptions.style && axisTitleOptions.style.fontSize,
34618                        axisTitle
34619                    ),
34620                    // The part of a multiline text that is below the baseline of the
34621                    // first line. Subtract 1 to preserve pixel-perfectness from the 
34622                    // old behaviour (v5.0.12), where only one line was allowed.
34623                    textHeightOvershoot = Math.max(
34624                        axisTitle.getBBox(null, 0).height - fontMetrics.h - 1,
34625                        0
34626                    ),
34627
34628                    // the position in the length direction of the axis
34629                    alongAxis = {
34630                        low: margin + (horiz ? 0 : axisLength),
34631                        middle: margin + axisLength / 2,
34632                        high: margin + (horiz ? axisLength : 0)
34633                    }[axisTitleOptions.align],
34634
34635                    // the position in the perpendicular direction of the axis
34636                    offAxis = (horiz ? axisTop + this.height : axisLeft) +
34637                    (horiz ? 1 : -1) * // horizontal axis reverses the margin
34638                    (opposite ? -1 : 1) * // so does opposite axes
34639                    this.axisTitleMargin + [-textHeightOvershoot, // top
34640                        textHeightOvershoot, // right
34641                        fontMetrics.f, // bottom
34642                        -textHeightOvershoot // left
34643                    ][this.side];
34644
34645
34646                return {
34647                    x: horiz ?
34648                        alongAxis + xOption : offAxis + (opposite ? this.width : 0) + offset + xOption,
34649                    y: horiz ?
34650                        offAxis + yOption - (opposite ? this.height : 0) + offset : alongAxis + yOption
34651                };
34652            },
34653
34654            /**
34655             * Render a minor tick into the given position. If a minor tick already 
34656             * exists in this position, move it.
34657             * 
34658             * @param  {number} pos
34659             *         The position in axis values.
34660             */
34661            renderMinorTick: function(pos) {
34662                var slideInTicks = this.chart.hasRendered && isNumber(this.oldMin),
34663                    minorTicks = this.minorTicks;
34664
34665                if (!minorTicks[pos]) {
34666                    minorTicks[pos] = new Tick(this, pos, 'minor');
34667                }
34668
34669                // Render new ticks in old position
34670                if (slideInTicks && minorTicks[pos].isNew) {
34671                    minorTicks[pos].render(null, true);
34672                }
34673
34674                minorTicks[pos].render(null, false, 1);
34675            },
34676
34677            /**
34678             * Render a major tick into the given position. If a tick already exists
34679             * in this position, move it.
34680             * 
34681             * @param  {number} pos
34682             *         The position in axis values.
34683             * @param  {number} i
34684             *         The tick index.
34685             */
34686            renderTick: function(pos, i) {
34687                var isLinked = this.isLinked,
34688                    ticks = this.ticks,
34689                    slideInTicks = this.chart.hasRendered && isNumber(this.oldMin);
34690
34691                // Linked axes need an extra check to find out if
34692                if (!isLinked || (pos >= this.min && pos <= this.max)) {
34693
34694                    if (!ticks[pos]) {
34695                        ticks[pos] = new Tick(this, pos);
34696                    }
34697
34698                    // render new ticks in old position
34699                    if (slideInTicks && ticks[pos].isNew) {
34700                        ticks[pos].render(i, true, 0.1);
34701                    }
34702
34703                    ticks[pos].render(i);
34704                }
34705            },
34706
34707            /**
34708             * Render the axis.
34709             *
34710             * @private
34711             */
34712            render: function() {
34713                var axis = this,
34714                    chart = axis.chart,
34715                    renderer = chart.renderer,
34716                    options = axis.options,
34717                    isLog = axis.isLog,
34718                    lin2log = axis.lin2log,
34719                    isLinked = axis.isLinked,
34720                    tickPositions = axis.tickPositions,
34721                    axisTitle = axis.axisTitle,
34722                    ticks = axis.ticks,
34723                    minorTicks = axis.minorTicks,
34724                    alternateBands = axis.alternateBands,
34725                    stackLabelOptions = options.stackLabels,
34726                    alternateGridColor = options.alternateGridColor,
34727                    tickmarkOffset = axis.tickmarkOffset,
34728                    axisLine = axis.axisLine,
34729                    showAxis = axis.showAxis,
34730                    animation = animObject(renderer.globalAnimation),
34731                    from,
34732                    to;
34733
34734                // Reset
34735                axis.labelEdge.length = 0;
34736                axis.overlap = false;
34737
34738                // Mark all elements inActive before we go over and mark the active ones
34739                each([ticks, minorTicks, alternateBands], function(coll) {
34740                    objectEach(coll, function(tick) {
34741                        tick.isActive = false;
34742                    });
34743                });
34744
34745                // If the series has data draw the ticks. Else only the line and title
34746                if (axis.hasData() || isLinked) {
34747
34748                    // minor ticks
34749                    if (axis.minorTickInterval && !axis.categories) {
34750                        each(axis.getMinorTickPositions(), function(pos) {
34751                            axis.renderMinorTick(pos);
34752                        });
34753                    }
34754
34755                    // Major ticks. Pull out the first item and render it last so that
34756                    // we can get the position of the neighbour label. #808.
34757                    if (tickPositions.length) { // #1300
34758                        each(tickPositions, function(pos, i) {
34759                            axis.renderTick(pos, i);
34760                        });
34761                        // In a categorized axis, the tick marks are displayed
34762                        // between labels. So we need to add a tick mark and
34763                        // grid line at the left edge of the X axis.
34764                        if (tickmarkOffset && (axis.min === 0 || axis.single)) {
34765                            if (!ticks[-1]) {
34766                                ticks[-1] = new Tick(axis, -1, null, true);
34767                            }
34768                            ticks[-1].render(-1);
34769                        }
34770
34771                    }
34772
34773                    // alternate grid color
34774                    if (alternateGridColor) {
34775                        each(tickPositions, function(pos, i) {
34776                            to = tickPositions[i + 1] !== undefined ?
34777                                tickPositions[i + 1] + tickmarkOffset :
34778                                axis.max - tickmarkOffset;
34779
34780                            if (
34781                                i % 2 === 0 &&
34782                                pos < axis.max &&
34783                                to <= axis.max + (
34784                                    chart.polar ?
34785                                    -tickmarkOffset :
34786                                    tickmarkOffset
34787                                )
34788                            ) { // #2248, #4660
34789                                if (!alternateBands[pos]) {
34790                                    alternateBands[pos] = new H.PlotLineOrBand(axis);
34791                                }
34792                                from = pos + tickmarkOffset; // #949
34793                                alternateBands[pos].options = {
34794                                    from: isLog ? lin2log(from) : from,
34795                                    to: isLog ? lin2log(to) : to,
34796                                    color: alternateGridColor
34797                                };
34798                                alternateBands[pos].render();
34799                                alternateBands[pos].isActive = true;
34800                            }
34801                        });
34802                    }
34803
34804                    // custom plot lines and bands
34805                    if (!axis._addedPlotLB) { // only first time
34806                        each(
34807                            (options.plotLines || []).concat(options.plotBands || []),
34808                            function(plotLineOptions) {
34809                                axis.addPlotBandOrLine(plotLineOptions);
34810                            }
34811                        );
34812                        axis._addedPlotLB = true;
34813                    }
34814
34815                } // end if hasData
34816
34817                // Remove inactive ticks
34818                each([ticks, minorTicks, alternateBands], function(coll) {
34819                    var i,
34820                        forDestruction = [],
34821                        delay = animation.duration,
34822                        destroyInactiveItems = function() {
34823                            i = forDestruction.length;
34824                            while (i--) {
34825                                // When resizing rapidly, the same items
34826                                // may be destroyed in different timeouts,
34827                                // or the may be reactivated
34828                                if (
34829                                    coll[forDestruction[i]] &&
34830                                    !coll[forDestruction[i]].isActive
34831                                ) {
34832                                    coll[forDestruction[i]].destroy();
34833                                    delete coll[forDestruction[i]];
34834                                }
34835                            }
34836
34837                        };
34838
34839                    objectEach(coll, function(tick, pos) {
34840                        if (!tick.isActive) {
34841                            // Render to zero opacity
34842                            tick.render(pos, false, 0);
34843                            tick.isActive = false;
34844                            forDestruction.push(pos);
34845                        }
34846                    });
34847
34848                    // When the objects are finished fading out, destroy them
34849                    syncTimeout(
34850                        destroyInactiveItems,
34851                        coll === alternateBands ||
34852                        !chart.hasRendered ||
34853                        !delay ?
34854                        0 :
34855                        delay
34856                    );
34857                });
34858
34859                // Set the axis line path
34860                if (axisLine) {
34861                    axisLine[axisLine.isPlaced ? 'animate' : 'attr']({
34862                        d: this.getLinePath(axisLine.strokeWidth())
34863                    });
34864                    axisLine.isPlaced = true;
34865
34866                    // Show or hide the line depending on options.showEmpty
34867                    axisLine[showAxis ? 'show' : 'hide'](true);
34868                }
34869
34870                if (axisTitle && showAxis) {
34871                    var titleXy = axis.getTitlePosition();
34872                    if (isNumber(titleXy.y)) {
34873                        axisTitle[axisTitle.isNew ? 'attr' : 'animate'](titleXy);
34874                        axisTitle.isNew = false;
34875                    } else {
34876                        axisTitle.attr('y', -9999);
34877                        axisTitle.isNew = true;
34878                    }
34879                }
34880
34881                // Stacked totals:
34882                if (stackLabelOptions && stackLabelOptions.enabled) {
34883                    axis.renderStackTotals();
34884                }
34885                // End stacked totals
34886
34887                axis.isDirty = false;
34888            },
34889
34890            /**
34891             * Redraw the axis to reflect changes in the data or axis extremes. Called
34892             * internally from {@link Chart#redraw}.
34893             *
34894             * @private
34895             */
34896            redraw: function() {
34897
34898                if (this.visible) {
34899                    // render the axis
34900                    this.render();
34901
34902                    // move plot lines and bands
34903                    each(this.plotLinesAndBands, function(plotLine) {
34904                        plotLine.render();
34905                    });
34906                }
34907
34908                // mark associated series as dirty and ready for redraw
34909                each(this.series, function(series) {
34910                    series.isDirty = true;
34911                });
34912
34913            },
34914
34915            // Properties to survive after destroy, needed for Axis.update (#4317,
34916            // #5773, #5881).
34917            keepProps: ['extKey', 'hcEvents', 'names', 'series', 'userMax', 'userMin'],
34918
34919            /**
34920             * Destroys an Axis instance. See {@link Axis#remove} for the API endpoint
34921             * to fully remove the axis.
34922             *
34923             * @private
34924             * @param  {Boolean} keepEvents
34925             *         Whether to preserve events, used internally in Axis.update.
34926             */
34927            destroy: function(keepEvents) {
34928                var axis = this,
34929                    stacks = axis.stacks,
34930                    plotLinesAndBands = axis.plotLinesAndBands,
34931                    plotGroup,
34932                    i;
34933
34934                // Remove the events
34935                if (!keepEvents) {
34936                    removeEvent(axis);
34937                }
34938
34939                // Destroy each stack total
34940                objectEach(stacks, function(stack, stackKey) {
34941                    destroyObjectProperties(stack);
34942
34943                    stacks[stackKey] = null;
34944                });
34945
34946                // Destroy collections
34947                each(
34948                    [axis.ticks, axis.minorTicks, axis.alternateBands],
34949                    function(coll) {
34950                        destroyObjectProperties(coll);
34951                    }
34952                );
34953                if (plotLinesAndBands) {
34954                    i = plotLinesAndBands.length;
34955                    while (i--) { // #1975
34956                        plotLinesAndBands[i].destroy();
34957                    }
34958                }
34959
34960                // Destroy local variables
34961                each(
34962                    ['stackTotalGroup', 'axisLine', 'axisTitle', 'axisGroup',
34963                        'gridGroup', 'labelGroup', 'cross'
34964                    ],
34965                    function(prop) {
34966                        if (axis[prop]) {
34967                            axis[prop] = axis[prop].destroy();
34968                        }
34969                    }
34970                );
34971
34972                // Destroy each generated group for plotlines and plotbands
34973                for (plotGroup in axis.plotLinesAndBandsGroups) {
34974                    axis.plotLinesAndBandsGroups[plotGroup] =
34975                        axis.plotLinesAndBandsGroups[plotGroup].destroy();
34976                }
34977
34978                // Delete all properties and fall back to the prototype.
34979                objectEach(axis, function(val, key) {
34980                    if (inArray(key, axis.keepProps) === -1) {
34981                        delete axis[key];
34982                    }
34983                });
34984            },
34985
34986            /**
34987             * Internal function to draw a crosshair.
34988             *
34989             * @param  {PointerEvent} [e]
34990             *         The event arguments from the modified pointer event, extended 
34991             *         with `chartX` and `chartY`
34992             * @param  {Point} [point]
34993             *         The Point object if the crosshair snaps to points.
34994             */
34995            drawCrosshair: function(e, point) {
34996
34997                var path,
34998                    options = this.crosshair,
34999                    snap = pick(options.snap, true),
35000                    pos,
35001                    categorized,
35002                    graphic = this.cross;
35003
35004                // Use last available event when updating non-snapped crosshairs without
35005                // mouse interaction (#5287)
35006                if (!e) {
35007                    e = this.cross && this.cross.e;
35008                }
35009
35010                if (
35011                    // Disabled in options
35012                    !this.crosshair ||
35013                    // Snap
35014                    ((defined(point) || !snap) === false)
35015                ) {
35016                    this.hideCrosshair();
35017                } else {
35018
35019                    // Get the path
35020                    if (!snap) {
35021                        pos = e &&
35022                            (
35023                                this.horiz ?
35024                                e.chartX - this.pos :
35025                                this.len - e.chartY + this.pos
35026                            );
35027                    } else if (defined(point)) {
35028                        // #3834
35029                        pos = this.isXAxis ? point.plotX : this.len - point.plotY;
35030                    }
35031
35032                    if (defined(pos)) {
35033                        path = this.getPlotLinePath(
35034                            // First argument, value, only used on radial
35035                            point && (this.isXAxis ?
35036                                point.x :
35037                                pick(point.stackY, point.y)
35038                            ),
35039                            null,
35040                            null,
35041                            null,
35042                            pos // Translated position
35043                        ) || null; // #3189
35044                    }
35045
35046                    if (!defined(path)) {
35047                        this.hideCrosshair();
35048                        return;
35049                    }
35050
35051                    categorized = this.categories && !this.isRadial;
35052
35053                    // Draw the cross
35054                    if (!graphic) {
35055                        this.cross = graphic = this.chart.renderer
35056                            .path()
35057                            .addClass(
35058                                'highcharts-crosshair highcharts-crosshair-' +
35059                                (categorized ? 'category ' : 'thin ') +
35060                                options.className
35061                            )
35062                            .attr({
35063                                zIndex: pick(options.zIndex, 2)
35064                            })
35065                            .add();
35066
35067
35068                        // Presentational attributes
35069                        graphic.attr({
35070                            'stroke': options.color ||
35071                                (
35072                                    categorized ?
35073                                    color('#ccd6eb')
35074                                    .setOpacity(0.25).get() :
35075                                    '#cccccc'
35076                                ),
35077                            'stroke-width': pick(options.width, 1)
35078                        }).css({
35079                            'pointer-events': 'none'
35080                        });
35081                        if (options.dashStyle) {
35082                            graphic.attr({
35083                                dashstyle: options.dashStyle
35084                            });
35085                        }
35086
35087
35088                    }
35089
35090                    graphic.show().attr({
35091                        d: path
35092                    });
35093
35094                    if (categorized && !options.width) {
35095                        graphic.attr({
35096                            'stroke-width': this.transA
35097                        });
35098                    }
35099                    this.cross.e = e;
35100                }
35101            },
35102
35103            /**
35104             *	Hide the crosshair if visible.
35105             */
35106            hideCrosshair: function() {
35107                if (this.cross) {
35108                    this.cross.hide();
35109                }
35110            }
35111        }); // end Axis
35112
35113        H.Axis = Axis;
35114        return Axis;
35115    }(Highcharts));
35116    (function(H) {
35117        /**
35118         * (c) 2010-2017 Torstein Honsi
35119         *
35120         * License: www.highcharts.com/license
35121         */
35122        var Axis = H.Axis,
35123            Date = H.Date,
35124            dateFormat = H.dateFormat,
35125            defaultOptions = H.defaultOptions,
35126            defined = H.defined,
35127            each = H.each,
35128            extend = H.extend,
35129            getMagnitude = H.getMagnitude,
35130            getTZOffset = H.getTZOffset,
35131            normalizeTickInterval = H.normalizeTickInterval,
35132            pick = H.pick,
35133            timeUnits = H.timeUnits;
35134        /**
35135         * Set the tick positions to a time unit that makes sense, for example
35136         * on the first of each month or on every Monday. Return an array
35137         * with the time positions. Used in datetime axes as well as for grouping
35138         * data on a datetime axis.
35139         *
35140         * @param {Object} normalizedInterval The interval in axis values (ms) and the count
35141         * @param {Number} min The minimum in axis values
35142         * @param {Number} max The maximum in axis values
35143         * @param {Number} startOfWeek
35144         */
35145        Axis.prototype.getTimeTicks = function(normalizedInterval, min, max, startOfWeek) {
35146            var tickPositions = [],
35147                i,
35148                higherRanks = {},
35149                useUTC = defaultOptions.global.useUTC,
35150                minYear, // used in months and years as a basis for Date.UTC()
35151                // When crossing DST, use the max. Resolves #6278.
35152                minDate = new Date(min - Math.max(getTZOffset(min), getTZOffset(max))),
35153                makeTime = Date.hcMakeTime,
35154                interval = normalizedInterval.unitRange,
35155                count = normalizedInterval.count,
35156                baseOffset, // #6797
35157                variableDayLength;
35158
35159            if (defined(min)) { // #1300
35160                minDate[Date.hcSetMilliseconds](interval >= timeUnits.second ? 0 : // #3935
35161                    count * Math.floor(minDate.getMilliseconds() / count)); // #3652, #3654
35162
35163                if (interval >= timeUnits.second) { // second
35164                    minDate[Date.hcSetSeconds](interval >= timeUnits.minute ? 0 : // #3935
35165                        count * Math.floor(minDate.getSeconds() / count));
35166                }
35167
35168                if (interval >= timeUnits.minute) { // minute
35169                    minDate[Date.hcSetMinutes](interval >= timeUnits.hour ? 0 :
35170                        count * Math.floor(minDate[Date.hcGetMinutes]() / count));
35171                }
35172
35173                if (interval >= timeUnits.hour) { // hour
35174                    minDate[Date.hcSetHours](interval >= timeUnits.day ? 0 :
35175                        count * Math.floor(minDate[Date.hcGetHours]() / count));
35176                }
35177
35178                if (interval >= timeUnits.day) { // day
35179                    minDate[Date.hcSetDate](interval >= timeUnits.month ? 1 :
35180                        count * Math.floor(minDate[Date.hcGetDate]() / count));
35181                }
35182
35183                if (interval >= timeUnits.month) { // month
35184                    minDate[Date.hcSetMonth](interval >= timeUnits.year ? 0 :
35185                        count * Math.floor(minDate[Date.hcGetMonth]() / count));
35186                    minYear = minDate[Date.hcGetFullYear]();
35187                }
35188
35189                if (interval >= timeUnits.year) { // year
35190                    minYear -= minYear % count;
35191                    minDate[Date.hcSetFullYear](minYear);
35192                }
35193
35194                // week is a special case that runs outside the hierarchy
35195                if (interval === timeUnits.week) {
35196                    // get start of current week, independent of count
35197                    minDate[Date.hcSetDate](minDate[Date.hcGetDate]() - minDate[Date.hcGetDay]() +
35198                        pick(startOfWeek, 1));
35199                }
35200
35201
35202                // Get basics for variable time spans
35203                minYear = minDate[Date.hcGetFullYear]();
35204                var minMonth = minDate[Date.hcGetMonth](),
35205                    minDateDate = minDate[Date.hcGetDate](),
35206                    minHours = minDate[Date.hcGetHours]();
35207
35208
35209                // Handle local timezone offset
35210                if (Date.hcTimezoneOffset || Date.hcGetTimezoneOffset) {
35211
35212                    // Detect whether we need to take the DST crossover into
35213                    // consideration. If we're crossing over DST, the day length may be
35214                    // 23h or 25h and we need to compute the exact clock t
35214ime for each
35215                    // tick instead of just adding hours. This comes at a cost, so first
35216                    // we found out if it is needed. #4951.
35217                    variableDayLength =
35218                        (!useUTC || !!Date.hcGetTimezoneOffset) &&
35219                        (
35220                            // Long range, assume we're crossing over.
35221                            max - min > 4 * timeUnits.month ||
35222                            // Short range, check if min and max are in different time 
35223                            // zones.
35224                            getTZOffset(min) !== getTZOffset(max)
35225                        );
35226
35227                    // Adjust minDate to the offset date
35228                    minDate = minDate.getTime();
35229                    baseOffset = getTZOffset(minDate);
35230                    minDate = new Date(minDate + baseOffset);
35231                }
35232
35233
35234                // Iterate and add tick positions at appropriate values
35235                var time = minDate.getTime();
35236                i = 1;
35237                while (time < max) {
35238                    tickPositions.push(time);
35239
35240                    // if the interval is years, use Date.UTC to increase years
35241                    if (interval === timeUnits.year) {
35242                        time = makeTime(minYear + i * count, 0);
35243
35244                        // if the interval is months, use Date.UTC to increase months
35245                    } else if (interval === timeUnits.month) {
35246                        time = makeTime(minYear, minMonth + i * count);
35247
35248                        // if we're using global time, the interval is not fixed as it jumps
35249                        // one hour at the DST crossover
35250                    } else if (
35251                        variableDayLength &&
35252                        (interval === timeUnits.day || interval === timeUnits.week)
35253                    ) {
35254                        time = makeTime(minYear, minMonth, minDateDate +
35255                            i * count * (interval === timeUnits.day ? 1 : 7));
35256
35257                    } else if (variableDayLength && interval === timeUnits.hour) {
35258                        // corrected by the start date time zone offset (baseOffset)
35259                        // to hide duplicated label (#6797)
35260                        time = makeTime(minYear, minMonth, minDateDate, minHours +
35261                            i * count, 0, 0, baseOffset) - baseOffset;
35262
35263                        // else, the interval is fixed and we use simple addition
35264                    } else {
35265                        time += interval * count;
35266                    }
35267
35268                    i++;
35269                }
35270
35271                // push the last time
35272                tickPositions.push(time);
35273
35274
35275                // Handle higher ranks. Mark new days if the time is on midnight
35276                // (#950, #1649, #1760, #3349). Use a reasonable dropout threshold to 
35277                // prevent looping over dense data grouping (#6156).
35278                if (interval <= timeUnits.hour && tickPositions.length < 10000) {
35279                    each(tickPositions, function(time) {
35280                        if (
35281                            // Speed optimization, no need to run dateFormat unless
35282                            // we're on a full or half hour
35283                            time % 1800000 === 0 &&
35284                            // Check for local or global midnight
35285                            dateFormat('%H%M%S%L', time) === '000000000'
35286                        ) {
35287                            higherRanks[time] = 'day';
35288                        }
35289                    });
35290                }
35291            }
35292
35293
35294            // record information on the chosen unit - for dynamic label formatter
35295            tickPositions.info = extend(normalizedInterval, {
35296                higherRanks: higherRanks,
35297                totalRange: interval * count
35298            });
35299
35300            return tickPositions;
35301        };
35302
35303        /**
35304         * Get a normalized tick interval for dates. Returns a configuration object with
35305         * unit range (interval), count and name. Used to prepare data for getTimeTicks.
35306         * Previously this logic was part of getTimeTicks, but as getTimeTicks now runs
35307         * of segments in stock charts, the normalizing logic was extracted in order to
35308         * prevent it for running over again for each segment having the same interval.
35309         * #662, #697.
35310         */
35311        Axis.prototype.normalizeTimeTickInterval = function(tickInterval, unitsOption) {
35312            var units = unitsOption || [
35313                    [
35314                        'millisecond', // unit name
35315                        [1, 2, 5, 10, 20, 25, 50, 100, 200, 500] // allowed multiples
35316                    ],
35317                    [
35318                        'second', [1, 2, 5, 10, 15, 30]
35319                    ],
35320                    [
35321                        'minute', [1, 2, 5, 10, 15, 30]
35322                    ],
35323                    [
35324                        'hour', [1, 2, 3, 4, 6, 8, 12]
35325                    ],
35326                    [
35327                        'day', [1, 2]
35328                    ],
35329                    [
35330                        'week', [1, 2]
35331                    ],
35332                    [
35333                        'month', [1, 2, 3, 4, 6]
35334                    ],
35335                    [
35336                        'year',
35337                        null
35338                    ]
35339                ],
35340                unit = units[units.length - 1], // default unit is years
35341                interval = timeUnits[unit[0]],
35342                multiples = unit[1],
35343                count,
35344                i;
35345
35346            // loop through the units to find the one that best fits the tickInterval
35347            for (i = 0; i < units.length; i++) {
35348                unit = units[i];
35349                interval = timeUnits[unit[0]];
35350                multiples = unit[1];
35351
35352
35353                if (units[i + 1]) {
35354                    // lessThan is in the middle between the highest multiple and the next unit.
35355                    var lessThan = (interval * multiples[multiples.length - 1] +
35356                        timeUnits[units[i + 1][0]]) / 2;
35357
35358                    // break and keep the current unit
35359                    if (tickInterval <= lessThan) {
35360                        break;
35361                    }
35362                }
35363            }
35364
35365            // prevent 2.5 years intervals, though 25, 250 etc. are allowed
35366            if (interval === timeUnits.year && tickInterval < 5 * interval) {
35367                multiples = [1, 2, 5];
35368            }
35369
35370            // get the count
35371            count = normalizeTickInterval(
35372                tickInterval / interval,
35373                multiples,
35374                unit[0] === 'year' ? Math.max(getMagnitude(tickInterval / interval), 1) : 1 // #1913, #2360
35375            );
35376
35377            return {
35378                unitRange: interval,
35379                count: count,
35380                unitName: unit[0]
35381            };
35382        };
35383
35384    }
35384(Highcharts));
35385    (function(H) {
35386        /**
35387         * (c) 2010-2017 Torstein Honsi
35388         *
35389         * License: www.highcharts.com/license
35390         */
35391        var Axis = H.Axis,
35392            getMagnitude = H.getMagnitude,
35393            map = H.map,
35394            normalizeTickInterval = H.normalizeTickInterval,
35395            pick = H.pick;
35396        /**
35397         * Methods defined on the Axis prototype
35398         */
35399
35400        /**
35401         * Set the tick positions of a logarithmic axis
35402         */
35403        Axis.prototype.getLogTickPositions = function(interval, min, max, minor) {
35404            var axis = this,
35405                options = axis.options,
35406                axisLength = axis.len,
35407                lin2log = axis.lin2log,
35408                log2lin = axis.log2lin,
35409                // Since we use this method for both major and minor ticks,
35410                // use a local variable and return the result
35411                positions = [];
35412
35413            // Reset
35414            if (!minor) {
35415                axis._minorAutoInterval = null;
35416            }
35417
35418            // First case: All ticks fall on whole logarithms: 1, 10, 100 etc.
35419            if (interval >= 0.5) {
35420                interval = Math.round(interval);
35421                positions = axis.getLinearTickPositions(interval, min, max);
35422
35423                // Second case: We need intermediary ticks. For example
35424                // 1, 2, 4, 6, 8, 10, 20, 40 etc.
35425            } else if (interval >= 0.08) {
35426                var roundedMin = Math.floor(min),
35427                    intermediate,
35428                    i,
35429                    j,
35430                    len,
35431                    pos,
35432                    lastPos,
35433                    break2;
35434
35435                if (interval > 0.3) {
35436                    intermediate = [1, 2, 4];
35437                } else if (interval > 0.15) { // 0.2 equals five minor ticks per 1, 10, 100 etc
35438                    intermediate = [1, 2, 4, 6, 8];
35439                } else { // 0.1 equals ten minor ticks per 1, 10, 100 etc
35440                    intermediate = [1, 2, 3, 4, 5, 6, 7, 8, 9];
35441                }
35442
35443                for (i = roundedMin; i < max + 1 && !break2; i++) {
35444                    len = intermediate.length;
35445                    for (j = 0; j < len && !break2; j++) {
35446                        pos = log2lin(lin2log(i) * intermediate[j]);
35447                        if (pos > min && (!minor || lastPos <= max) && lastPos !== undefined) { // #1670, lastPos is #3113
35448                            positions.push(lastPos);
35449                        }
35450
35451                        if (lastPos > max) {
35452                            break2 = true;
35453                        }
35454                        lastPos = pos;
35455                    }
35456                }
35457
35458                // Third case: We are so deep in between whole logarithmic values that
35459                // we might as well handle the tick positions like a linear axis. For
35460                // example 1.01, 1.02, 1.03, 1.04.
35461            } else {
35462                var realMin = lin2log(min),
35463                    realMax = lin2log(max),
35464                    tickIntervalOption = minor ?
35465                    this.getMinorTickInterval() :
35466                    options.tickInterval,
35467                    filteredTickIntervalOption = tickIntervalOption === 'auto' ? null : tickIntervalOption,
35468                    tickPixelIntervalOption = options.tickPixelInterval / (minor ? 5 : 1),
35469                    totalPixelLength = minor ? axisLength / axis.tickPositions.length : axisLength;
35470
35471                interval = pick(
35472                    filteredTickIntervalOption,
35473                    axis._minorAutoInterval,
35474                    (realMax - realMin) * tickPixelIntervalOption / (totalPixelLength || 1)
35475                );
35476
35477                interval = normalizeTickInterval(
35478                    interval,
35479                    null,
35480                    getMagnitude(interval)
35481                );
35482
35483                positions = map(axis.getLinearTickPositions(
35484                    interval,
35485                    realMin,
35486                    realMax
35487                ), log2lin);
35488
35489                if (!minor) {
35490                    axis._minorAutoInterval = interval / 5;
35491                }
35492            }
35493
35494            // Set the axis-level tickInterval variable
35495            if (!minor) {
35496                axis.tickInterval = interval;
35497            }
35498            return positions;
35499        };
35500
35501        Axis.prototype.log2lin = function(num) {
35502            return Math.log(num) / Math.LN10;
35503        };
35504
35505        Axis.prototype.lin2log = function(num) {
35506            return Math.pow(10, num);
35507        };
35508
35509    }
35509(Highcharts));
35510    (function(H, Axis) {
35511        /**
35512         * (c) 2010-2017 Torstein Honsi
35513         *
35514         * License: www.highcharts.com/license
35515         */
35516        var arrayMax = H.arrayMax,
35517            arrayMin = H.arrayMin,
35518            defined = H.defined,
35519            destroyObjectProperties = H.destroyObjectProperties,
35520            each = H.each,
35521            erase = H.erase,
35522            merge = H.merge,
35523            pick = H.pick;
35524        /*
35525         * The object wrapper for plot lines and plot bands
35526         * @param {Object} options
35527         */
35528        H.PlotLineOrBand = function(axis, options) {
35529            this.axis = axis;
35530
35531            if (options) {
35532                this.options = options;
35533                this.id = options.id;
35534            }
35535        };
35536
35537        H.PlotLineOrBand.prototype = {
35538
35539            /**
35540             * Render the plot line or plot band. If it is already existing,
35541             * move it.
35542             */
35543            render: function() {
35544                var plotLine = this,
35545                    axis = plotLine.axis,
35546                    horiz = axis.horiz,
35547                    options = plotLine.options,
35548                    optionsLabel = options.label,
35549                    label = plotLine.label,
35550                    to = options.to,
35551                    from = options.from,
35552                    value = options.value,
35553                    isBand = defined(from) && defined(to),
35554                    isLine = defined(value),
35555                    svgElem = plotLine.svgElem,
35556                    isNew = !svgElem,
35557                    path = [],
35558                    color = options.color,
35559                    zIndex = pick(options.zIndex, 0),
35560                    events = options.events,
35561                    attribs = {
35562                        'class': 'highcharts-plot-' + (isBand ? 'band ' : 'line ') +
35563                            (options.className || '')
35564                    },
35565                    groupAttribs = {},
35566                    renderer = axis.chart.renderer,
35567                    groupName = isBand ? 'bands' : 'lines',
35568                    group,
35569                    log2lin = axis.log2lin;
35570
35571                // logarithmic conversion
35572                if (axis.isLog) {
35573                    from = log2lin(from);
35574                    to = log2lin(to);
35575                    value = log2lin(value);
35576                }
35577
35578
35579                // Set the presentational attributes
35580                if (isLine) {
35581                    attribs = {
35582                        stroke: color,
35583                        'stroke-width': options.width
35584                    };
35585                    if (options.dashStyle) {
35586                        attribs.dashstyle = options.dashStyle;
35587                    }
35588
35589                } else if (isBand) { // plot band
35590                    if (color) {
35591                        attribs.fill = color;
35592                    }
35593                    if (options.borderWidth) {
35594                        attribs.stroke = options.borderColor;
35595                        attribs['stroke-width'] = options.borderWidth;
35596                    }
35597                }
35598
35599
35600                // Grouping and zIndex
35601                groupAttribs.zIndex = zIndex;
35602                groupName += '-' + zIndex;
35603
35604                group = axis.plotLinesAndBandsGroups[groupName];
35605                if (!group) {
35606                    axis.plotLinesAndBandsGroups[groupName] = group =
35607                        renderer.g('plot-' + groupName)
35608                        .attr(groupAttribs).add();
35609                }
35610
35611                // Create the path
35612                if (isNew) {
35613                    plotLine.svgElem = svgElem =
35614                        renderer
35615                        .path()
35616                        .attr(attribs).add(group);
35617                }
35618
35619
35620                // Set the path or return
35621                if (isLine) {
35622                    path = axis.getPlotLinePath(value, svgElem.strokeWidth());
35623                } else if (isBand) { // plot band
35624                    path = axis.getPlotBandPath(from, to, options);
35625                } else {
35626                    return;
35627                }
35628
35629
35630                // common for lines and bands
35631                if (isNew && path && path.length) {
35632                    svgElem.attr({
35633                        d: path
35634                    });
35635
35636                    // events
35637                    if (events) {
35638                        H.objectEach(events, function(event, eventType) {
35639                            svgElem.on(eventType, function(e) {
35640                                events[eventType].apply(plotLine, [e]);
35641                            });
35642                        });
35643                    }
35644                } else if (svgElem) {
35645                    if (path) {
35646                        svgElem.show();
35647                        svgElem.animate({
35648                            d: path
35649                        });
35650                    } else {
35651                        svgElem.hide();
35652                        if (label) {
35653                            plotLine.label = label = label.destroy();
35654                        }
35655                    }
35656                }
35657
35658                // the plot band/line label
35659                if (
35660                    optionsLabel &&
35661                    defined(optionsLabel.text) &&
35662                    path &&
35663                    path.length &&
35664                    axis.width > 0 &&
35665                    axis.height > 0 &&
35666                    !path.flat
35667                ) {
35668                    // apply defaults
35669                    optionsLabel = merge({
35670                        align: horiz && isBand && 'center',
35671                        x: horiz ? !isBand && 4 : 10,
35672                        verticalAlign: !horiz && isBand && 'middle',
35673                        y: horiz ? isBand ? 16 : 10 : isBand ? 6 : -4,
35674                        rotation: horiz && !isBand && 90
35675                    }, optionsLabel);
35676
35677                    this.renderLabel(optionsLabel, path, isBand, zIndex);
35678
35679                } else if (label) { // move out of sight
35680                    label.hide();
35681                }
35682
35683                // chainable
35684                return plotLine;
35685            },
35686
35687            /**
35688             * Render and align label for plot line or band.
35689             */
35690            renderLabel: function(optionsLabel, path, isBand, zIndex) {
35691                var plotLine = this,
35692                    label = plotLine.label,
35693                    renderer = plotLine.axis.chart.renderer,
35694                    attribs,
35695                    xBounds,
35696                    yBounds,
35697                    x,
35698                    y;
35699
35700                // add the SVG element
35701                if (!label) {
35702                    attribs = {
35703                        align: optionsLabel.textAlign || optionsLabel.align,
35704                        rotation: optionsLabel.rotation,
35705                        'class': 'highcharts-plot-' + (isBand ? 'band' : 'line') +
35706                            '-label ' + (optionsLabel.className || '')
35707                    };
35708
35709                    attribs.zIndex = zIndex;
35710
35711                    plotLine.label = label = renderer.text(
35712                            optionsLabel.text,
35713                            0,
35714                            0,
35715                            optionsLabel.useHTML
35716                        )
35717                        .attr(attribs)
35718                        .add();
35719
35720
35721                    label.css(optionsLabel.style);
35722
35723                }
35724
35725                // get the bounding box and align the label
35726                // #3000 changed to better handle choice between plotband or plotline
35727                xBounds = path.xBounds || [path[1], path[4], (isBand ? path[6] : path[1])];
35728                yBounds = path.yBounds || [path[2], path[5], (isBand ? path[7] : path[2])];
35729
35730                x = arrayMin(xBounds);
35731                y = arrayMin(yBounds);
35732
35733                label.align(optionsLabel, false, {
35734                    x: x,
35735                    y: y,
35736                    width: arrayMax(xBounds) - x,
35737                    height: arrayMax(yBounds) - y
35738                });
35739                label.show();
35740            },
35741
35742            /**
35743             * Remove the plot line or band
35744             */
35745            destroy: function() {
35746                // remove it from the lookup
35747                erase(this.axis.plotLinesAndBands, this);
35748
35749                delete this.axis;
35750                destroyObjectProperties(this);
35751            }
35752        };
35753
35754        /**
35755         * Object with members for extending the Axis prototype
35756         * @todo Extend directly instead of adding object to Highcharts first
35757         */
35758
35759        H.extend(Axis.prototype, /** @lends Highcharts.Axis.prototype */ {
35760
35761            /**
35762             * Internal function to create the SVG path definition for a plot band.
35763             *
35764             * @param  {Number} from
35765             *         The axis value to start from.
35766             * @param  {Number} to
35767             *         The axis value to end on.
35768             *
35769             * @return {Array.<String|Number>}
35770             *         The SVG path definition in array form.
35771             */
35772            getPlotBandPath: function(from, to) {
35773                var toPath = this.getPlotLinePath(to, null, null, true),
35774                    path = this.getPlotLinePath(from, null, null, true),
35775                    result = [],
35776                    i,
35777                    // #4964 check if chart is inverted or plotband is on yAxis 
35778                    horiz = this.horiz,
35779                    plus = 1,
35780                    flat,
35781                    outside =
35782                    (from < this.min && to < this.min) ||
35783                    (from > this.max && to > this.max);
35784
35785                if (path && toPath) {
35786
35787                    // Flat paths don't need labels (#3836)
35788                    if (outside) {
35789                        flat = path.toString() === toPath.toString();
35790                        plus = 0;
35791                    }
35792
35793                    // Go over each subpath - for panes in Highstock
35794                    for (i = 0; i < path.length; i += 6) {
35795
35796                        // Add 1 pixel when coordinates are the same
35797                        if (horiz && toPath[i + 1] === path[i + 1]) {
35798                            toPath[i + 1] += plus;
35799                            toPath[i + 4] += plus;
35800                        } else if (!horiz && toPath[i + 2] === path[i + 2]) {
35801                            toPath[i + 2] += plus;
35802                            toPath[i + 5] += plus;
35803                        }
35804
35805                        result.push(
35806                            'M',
35807                            path[i + 1],
35808                            path[i + 2],
35809                            'L',
35810                            path[i + 4],
35811                            path[i + 5],
35812                            toPath[i + 4],
35813                            toPath[i + 5],
35814                            toPath[i + 1],
35815                            toPath[i + 2],
35816                            'z'
35817                        );
35818                        result.flat = flat;
35819                    }
35820
35821                } else { // outside the axis area
35822                    path = null;
35823                }
35824
35825                return result;
35826            },
35827
35828            /**
35829             * Add a plot band after render time.
35830             *
35831             * @param  {AxisPlotBandsOptions} options
35832             *         A configuration object for the plot band, as defined in {@link
35833             *         https://api.highcharts.com/highcharts/xAxis.plotBands|
35834             *         xAxis.plotBands}.
35835             * @return {Object}
35836             *         The added plot band.
35837             * @sample highcharts/members/axis-addplotband/
35838             *         Toggle the plot band from a button
35839             */
35840            addPlotBand: function(options) {
35841                return this.addPlotBandOrLine(options, 'plotBands');
35842            },
35843
35844            /**
35845             * Add a plot line after render time.
35846             * 
35847             * @param  {AxisPlotLinesOptions} options
35848             *         A configuration object for the plot line, as defined in {@link
35849             *         https://api.highcharts.com/highcharts/xAxis.plotLines|
35850             *         xAxis.plotLines}.
35851             * @return {Object}
35852             *         The added plot line.
35853             * @sample highcharts/members/axis-addplotline/
35854             *         Toggle the plot line from a button
35855             */
35856            addPlotLine: function(options) {
35857                return this.addPlotBandOrLine(options, 'plotLines');
35858            },
35859
35860            /**
35861             * Add a plot band or plot line after render time. Called from addPlotBand
35862             * and addPlotLine internally.
35863             *
35864             * @private
35865             * @param  options {AxisPlotLinesOptions|AxisPlotBandsOptions}
35866             *         The plotBand or plotLine configuration object.
35867             */
35868            addPlotBandOrLine: function(options, coll) {
35869                var obj = new H.PlotLineOrBand(this, options).render(),
35870                    userOptions = this.userOptions;
35871
35872                if (obj) { // #2189
35873                    // Add it to the user options for exporting and Axis.update
35874                    if (coll) {
35875                        userOptions[coll] = userOptions[coll] || [];
35876                        userOptions[coll].push(options);
35877                    }
35878                    this.plotLinesAndBands.push(obj);
35879                }
35880
35881                return obj;
35882            },
35883
35884            /**
35885             * Remove a plot band or plot line from the chart by id. Called internally
35886             * from `removePlotBand` and `removePlotLine`.
35887             *
35888             * @private
35889             * @param {String} id
35890             */
35891            removePlotBandOrLine: function(id) {
35892                var plotLinesAndBands = this.plotLinesAndBands,
35893                    options = this.options,
35894                    userOptions = this.userOptions,
35895                    i = plotLinesAndBands.length;
35896                while (i--) {
35897                    if (plotLinesAndBands[i].id === id) {
35898                        plotLinesAndBands[i].destroy();
35899                    }
35900                }
35901                each([
35902                    options.plotLines || [],
35903                    userOptions.plotLines || [],
35904                    options.plotBands || [],
35905                    userOptions.plotBands || []
35906                ], function(arr) {
35907                    i = arr.length;
35908                    while (i--) {
35909                        if (arr[i].id === id) {
35910                            erase(arr, arr[i]);
35911                        }
35912                    }
35913                });
35914            },
35915
35916            /**
35917             * Remove a plot band by its id.
35918             * 
35919             * @param  {String} id
35920             *         The plot band's `id` as given in the original configuration
35921             *         object or in the `addPlotBand` option.
35922             * @sample highcharts/members/axis-removeplotband/
35923             *         Remove plot band by id
35924             * @sample highcharts/members/axis-addplotband/
35925             *         Toggle the plot band from a button
35926             */
35927            removePlotBand: function(id) {
35928                this.removePlotBandOrLine(id);
35929            },
35930
35931            /**
35932             * Remove a plot line by its id.
35933             * @param  {String} id
35934             *         The plot line's `id` as given in the original configuration
35935             *         object or in the `addPlotLine` option.
35936             * @sample highcharts/xaxis/plotlines-id/
35937             *         Remove plot line by id
35938             * @sample highcharts/members/axis-addplotline/
35939             *         Toggle the plot line from a button
35940             */
35941            removePlotLine: function(id) {
35942                this.removePlotBandOrLine(id);
35943            }
35944        });
35945
35946    }(Highcharts, Axis));
35947    (function(H) {
35948        /**
35949         * (c) 2010-2017 Torstein Honsi
35950         *
35951         * License: www.highcharts.com/license
35952         */
35953        var dateFormat = H.dateFormat,
35954            each = H.each,
35955            extend = H.extend,
35956            format = H.format,
35957            isNumber = H.isNumber,
35958            map = H.map,
35959            merge = H.merge,
35960            pick = H.pick,
35961            splat = H.splat,
35962            syncTimeout = H.syncTimeout,
35963            timeUnits = H.timeUnits;
35964        /**
35965         * The tooltip object
35966         * @param {Object} chart The chart instance
35967         * @param {Object} options Tooltip options
35968         */
35969        H.Tooltip = function() {
35970            this.init.apply(this, arguments);
35971        };
35972
35973        H.Tooltip.prototype = {
35974
35975            init: function(chart, options) {
35976
35977                // Save the chart and options
35978                this.chart = chart;
35979                this.options = options;
35980
35981                // List of crosshairs
35982                this.crosshairs = [];
35983
35984                // Current values of x and y when animating
35985                this.now = {
35986                    x: 0,
35987                    y: 0
35988                };
35989
35990                // The tooltip is initially hidden
35991                this.isHidden = true;
35992
35993
35994
35995                // Public property for getting the shared state.
35996                this.split = options.split && !chart.inverted;
35997                this.shared = options.shared || this.split;
35998
35999            },
36000
36001            /**
36002             * Destroy the single tooltips in a split tooltip.
36003             * If the tooltip is active then it is not destroyed, unless forced to.
36004             * @param  {boolean} force Force destroy all tooltips.
36005             * @return {undefined}
36006             */
36007            cleanSplit: function(force) {
36008                each(this.chart.series, function(series) {
36009                    var tt = series && series.tt;
36010                    if (tt) {
36011                        if (!tt.isActive || force) {
36012                            series.tt = tt.destroy();
36013                        } else {
36014                            tt.isActive = false;
36015                        }
36016                    }
36017                });
36018            },
36019
36020
36021
36022
36023            /**
36024             * Create the Tooltip label element if it doesn't exist, then return the
36025             * label.
36026             */
36027            getLabel: function() {
36028
36029                var renderer = this.chart.renderer,
36030                    options = this.options;
36031
36032                if (!this.label) {
36033                    // Create the label
36034                    if (this.split) {
36035                        this.label = renderer.g('tooltip');
36036                    } else {
36037                        this.label = renderer.label(
36038                                '',
36039                                0,
36040                                0,
36041                                options.shape || 'callout',
36042                                null,
36043                                null,
36044                                options.useHTML,
36045                                null,
36046                                'tooltip'
36047                            )
36048                            .attr({
36049                                padding: options.padding,
36050                                r: options.borderRadius
36051                            });
36052
36053
36054                        this.label
36055                            .attr({
36056                                'fill': options.backgroundColor,
36057                                'stroke-width': options.borderWidth
36058                            })
36059                            // #2301, #2657
36060                            .css(options.style)
36061                            .shadow(options.shadow);
36062
36063                    }
36064
36065
36066
36067                    this.label
36068                        .attr({
36069                            zIndex: 8
36070                        })
36071                        .add();
36072                }
36073                return this.label;
36074            },
36075
36076            update: function(options) {
36077                this.destroy();
36078                // Update user options (#6218)
36079                merge(true, this.chart.options.tooltip.userOptions, options);
36080                this.init(this.chart, merge(true, this.options, options));
36081            },
36082
36083            /**
36084             * Destroy the tooltip and its elements.
36085             */
36086            destroy: function() {
36087                // Destroy and clear local variables
36088                if (this.label) {
36089                    this.label = this.label.destroy();
36090                }
36091                if (this.split && this.tt) {
36092                    this.cleanSplit(this.chart, true);
36093                    this.tt = this.tt.destroy();
36094                }
36095                clearTimeout(this.hideTimer);
36096                clearTimeout(this.tooltipTimeout);
36097            },
36098
36099            /**
36100             * Provide a soft movement for the tooltip
36101             *
36102             * @param {Number} x
36103             * @param {Number} y
36104             * @private
36105             */
36106            move: function(x, y, anchorX, anchorY) {
36107                var tooltip = this,
36108                    now = tooltip.now,
36109                    animate = tooltip.options.animation !== false &&
36110                    !tooltip.isHidden &&
36111                    // When we get close to the target position, abort animation and
36112                    // land on the right place (#3056)
36113                    (Math.abs(x - now.x) > 1 || Math.abs(y - now.y) > 1),
36114                    skipAnchor = tooltip.followPointer || tooltip.len > 1;
36115
36116                // Get intermediate values for animation
36117                extend(now, {
36118                    x: animate ? (2 * now.x + x) / 3 : x,
36119                    y: animate ? (now.y + y) / 2 : y,
36120                    anchorX: skipAnchor ?
36121                        undefined : animate ? (2 * now.anchorX + anchorX) / 3 : anchorX,
36122                    anchorY: skipAnchor ?
36123                        undefined : animate ? (now.anchorY + anchorY) / 2 : anchorY
36124                });
36125
36126                // Move to the intermediate value
36127                tooltip.getLabel().attr(now);
36128
36129
36130                // Run on next tick of the mouse tracker
36131                if (animate) {
36132
36133                    // Never allow two timeouts
36134                    clearTimeout(this.tooltipTimeout);
36135
36136                    // Set the fixed interval ticking for the smooth tooltip
36137                    this.tooltipTimeout = setTimeout(function() {
36138                        // The interval function may still be running during destroy,
36139                        // so check that the chart is really there before calling.
36140                        if (tooltip) {
36141                            tooltip.move(x, y, anchorX, anchorY);
36142                        }
36143                    }, 32);
36144
36145                }
36146            },
36147
36148            /**
36149             * Hide the tooltip
36150             */
36151            hide: function(delay) {
36152                var tooltip = this;
36153                // disallow duplicate timers (#1728, #1766)
36154                clearTimeout(this.hideTimer);
36155                delay = pick(delay, this.options.hideDelay, 500);
36156                if (!this.isHidden) {
36157                    this.hideTimer = syncTimeout(function() {
36158                        tooltip.getLabel()[delay ? 'fadeOut' : 'hide']();
36159                        tooltip.isHidden = true;
36160                    }, delay);
36161                }
36162            },
36163
36164            /**
36165             * Extendable method to get the anchor position of the tooltip
36166             * from a point or set of points
36167             */
36168            getAnchor: function(points, mouseEvent) {
36169                var ret,
36170                    chart = this.chart,
36171                    inverted = chart.inverted,
36172                    plotTop = chart.plotTop,
36173                    plotLeft = chart.plotLeft,
36174                    plotX = 0,
36175                    plotY = 0,
36176                    yAxis,
36177                    xAxis;
36178
36179                points = splat(points);
36180
36181                // Pie uses a special tooltipPos
36182                ret = points[0].tooltipPos;
36183
36184                // When tooltip follows mouse, relate the position to the mouse
36185                if (this.followPointer && mouseEvent) {
36186                    if (mouseEvent.chartX === undefined) {
36187                        mouseEvent = chart.pointer.normalize(mouseEvent);
36188                    }
36189                    ret = [
36190                        mouseEvent.chartX - chart.plotLeft,
36191                        mouseEvent.chartY - plotTop
36192                    ];
36193                }
36194                // When shared, use the average position
36195                if (!ret) {
36196                    each(points, function(point) {
36197                        yAxis = point.series.yAxis;
36198                        xAxis = point.series.xAxis;
36199                        plotX += point.plotX +
36200                            (!inverted && xAxis ? xAxis.left - plotLeft : 0);
36201                        plotY +=
36202                            (
36203                                point.plotLow ?
36204                                (point.plotLow + point.plotHigh) / 2 :
36205                                point.plotY
36206                            ) +
36207                            (!inverted && yAxis ? yAxis.top - plotTop : 0); // #1151
36208                    });
36209
36210                    plotX /= points.length;
36211                    plotY /= points.length;
36212
36213                    ret = [
36214                        inverted ? chart.plotWidth - plotY : plotX,
36215                        this.shared && !inverted && points.length > 1 && mouseEvent ?
36216                        // place shared tooltip next to the mouse (#424)
36217                        mouseEvent.chartY - plotTop :
36218                        inverted ? chart.plotHeight - plotX : plotY
36219                    ];
36220                }
36221
36222                return map(ret, Math.round);
36223            },
36224
36225            /**
36226             * Place the tooltip in a chart without spilling over
36227             * and not covering the point it self.
36228             */
36229            getPosition: function(boxWidth, boxHeight, point) {
36230
36231                var chart = this.chart,
36232                    distance = this.distance,
36233                    ret = {},
36234                    // Don't use h if chart isn't inverted (#7242)
36235                    h = (chart.inverted && point.h) || 0, // #4117
36236                    swapped,
36237                    first = ['y', chart.chartHeight, boxHeight,
36238                        point.plotY + chart.plotTop, chart.plotTop,
36239                        chart.plotTop + chart.plotHeight
36240                    ],
36241                    second = ['x', chart.chartWidth, boxWidth,
36242                        point.plotX + chart.plotLeft, chart.plotLeft,
36243                        chart.plotLeft + chart.plotWidth
36244                    ],
36245                    // The far side is right or bottom
36246                    preferFarSide = !this.followPointer && pick(
36247                        point.ttBelow, !chart.inverted === !!point.negative
36248                    ), // #4984
36249
36250                    /**
36251                     * Handle the preferred dimension. When the preferred dimension is
36252                     * tooltip on top or bottom of the point, it will look for space
36253                     * there.
36254                     */
36255                    firstDimension = function(
36256                        dim,
36257                        outerSize,
36258                        innerSize,
36259                        point,
36260                        min,
36261                        max
36262                    ) {
36263                        var roomLeft = innerSize < point - distance,
36264                            roomRight = point + distance + innerSize < outerSize,
36265                            alignedLeft = point - distance - innerSize,
36266                            alignedRight = point + distance;
36267
36268                        if (preferFarSide && roomRight) {
36269                            ret[dim] = alignedRight;
36270                        } else if (!preferFarSide && roomLeft) {
36271                            ret[dim] = alignedLeft;
36272                        } else if (roomLeft) {
36273                            ret[dim] = Math.min(
36274                                max - innerSize,
36275                                alignedLeft - h < 0 ? alignedLeft : alignedLeft - h
36276                            );
36277                        } else if (roomRight) {
36278                            ret[dim] = Math.max(
36279                                min,
36280                                alignedRight + h + innerSize > outerSize ?
36281                                alignedRight :
36282                                alignedRight + h
36283                            );
36284                        } else {
36285                            return false;
36286                        }
36287                    },
36288                    /**
36289                     * Handle the secondary dimension. If the preferred dimension is
36290                     * tooltip on top or bottom of the point, the second dimension is to
36291                     * align the tooltip above the point, trying to align center but
36292                     * allowing left or right align within the chart box.
36293                     */
36294                    secondDimension = function(dim, outerSize, innerSize, point) {
36295                        var retVal;
36296
36297                        // Too close to the edge, return false and swap dimensions
36298                        if (point < distance || point > outerSize - distance) {
36299                            retVal = false;
36300                            // Align left/top
36301                        } else if (point < innerSize / 2) {
36302                            ret[dim] = 1;
36303                            // Align right/bottom
36304                        } else if (point > outerSize - innerSize / 2) {
36305                            ret[dim] = outerSize - innerSize - 2;
36306                            // Align center
36307                        } else {
36308                            ret[dim] = point - innerSize / 2;
36309                        }
36310                        return retVal;
36311                    },
36312                    /**
36313                     * Swap the dimensions
36314                     */
36315                    swap = function(count) {
36316                        var temp = first;
36317                        first = second;
36318                        second = temp;
36319                        swapped = count;
36320                    },
36321                    run = function() {
36322                        if (firstDimension.apply(0, first) !== false) {
36323                            if (
36324                                secondDimension.apply(0, second) === false &&
36325                                !swapped
36326                            ) {
36327                                swap(true);
36328                                run();
36329                            }
36330                        } else if (!swapped) {
36331                            swap(true);
36332                            run();
36333                        } else {
36334                            ret.x = ret.y = 0;
36335                        }
36336                    };
36337
36338                // Under these conditions, prefer the tooltip on the side of the point
36339                if (chart.inverted || this.len > 1) {
36340                    swap();
36341                }
36342                run();
36343
36344                return ret;
36345
36346            },
36347
36348            /**
36349             * In case no user defined formatter is given, this will be used. Note that
36350             * the context here is an object holding point, series, x, y etc.
36351             *
36352             * @returns {String|Array<String>}
36353             */
36354            defaultFormatter: function(tooltip) {
36355                var items = this.points || splat(this),
36356                    s;
36357
36358                // Build the header
36359                s = [tooltip.tooltipFooterHeaderFormatter(items[0])];
36360
36361                // build the values
36362                s = s.concat(tooltip.bodyFormatter(items));
36363
36364                // footer
36365                s.push(tooltip.tooltipFooterHeaderFormatter(items[0], true));
36366
36367                return s;
36368            },
36369
36370            /**
36371             * Refresh the tooltip's text and position.
36372             * @param {Object|Array} pointOrPoints Rither a point or an array of points
36373             */
36374            refresh: function(pointOrPoints, mouseEvent) {
36375                var tooltip = this,
36376                    label,
36377                    options = tooltip.options,
36378                    x,
36379                    y,
36380                    point = pointOrPoints,
36381                    anchor,
36382                    textConfig = {},
36383                    text,
36384                    pointConfig = [],
36385                    formatter = options.formatter || tooltip.defaultFormatter,
36386                    shared = tooltip.shared,
36387                    currentSeries;
36388
36389                if (!options.enabled) {
36390                    return;
36391                }
36392
36393                clearTimeout(this.hideTimer);
36394
36395                // get the reference point coordinates (pie charts use tooltipPos)
36396                tooltip.followPointer = splat(point)[0].series.tooltipOptions
36397                    .followPointer;
36398                anchor = tooltip.getAnchor(point, mouseEvent);
36399                x = anchor[0];
36400                y = anchor[1];
36401
36402                // shared tooltip, array is sent over
36403                if (shared && !(point.series && point.series.noSharedTooltip)) {
36404                    each(point, function(item) {
36405                        item.setState('hover');
36406
36407                        pointConfig.push(item.getLabelConfig());
36408                    });
36409
36410                    textConfig = {
36411                        x: point[0].category,
36412                        y: point[0].y
36413                    };
36414                    textConfig.points = pointConfig;
36415                    point = point[0];
36416
36417                    // single point tooltip
36418                } else {
36419                    textConfig = point.getLabelConfig();
36420                }
36421                this.len = pointConfig.length; // #6128
36422                text = formatter.call(textConfig, tooltip);
36423
36424                // register the current series
36425                currentSeries = point.series;
36426                this.distance = pick(currentSeries.tooltipOptions.distance, 16);
36427
36428                // update the inner HTML
36429                if (text === false) {
36430                    this.hide();
36431                } else {
36432
36433                    label = tooltip.getLabel();
36434
36435                    // show it
36436                    if (tooltip.isHidden) {
36437                        label.attr({
36438                            opacity: 1
36439                        }).show();
36440                    }
36441
36442                    // update text
36443                    if (tooltip.split) {
36444                        this.renderSplit(text, splat(pointOrPoints));
36445                    } else {
36446
36447                        // Prevent the tooltip from flowing over the chart box (#6659)
36448
36449                        if (!options.style.width) {
36450
36451                            label.css({
36452                                width: this.chart.spacingBox.width
36453                            });
36454
36455                        }
36456
36457
36458                        label.attr({
36459                            text: text && text.join ? text.join('') : text
36460                        });
36461
36462                        // Set the stroke color of the box to reflect the point
36463                        label.removeClass(/highcharts-color-[\d]+/g)
36464                            .addClass(
36465                                'highcharts-color-' +
36466                                pick(point.colorIndex, currentSeries.colorIndex)
36467                            );
36468
36469
36470                        label.attr({
36471                            stroke: (
36472                                options.borderColor ||
36473                                point.color ||
36474                                currentSeries.color ||
36475                                '#666666'
36476                            )
36477                        });
36478
36479
36480                        tooltip.updatePosition({
36481                            plotX: x,
36482                            plotY: y,
36483                            negative: point.negative,
36484                            ttBelow: point.ttBelow,
36485                            h: anchor[2] || 0
36486                        });
36487                    }
36488
36489                    this.isHidden = false;
36490                }
36491            },
36492
36493            /**
36494             * Render the split tooltip. Loops over each point's text and adds
36495             * a label next to the point, then uses the distribute function to 
36496             * find best non-overlapping positions.
36497             */
36498            renderSplit: function(labels, points) {
36499                var tooltip = this,
36500                    boxes = [],
36501                    chart = this.chart,
36502                    ren = chart.renderer,
36503                    rightAligned = true,
36504                    options = this.options,
36505                    headerHeight = 0,
36506                    tooltipLabel = this.getLabel();
36507
36508                // Graceful degradation for legacy formatters
36509                if (H.isString(labels)) {
36510                    labels = [false, labels];
36511                }
36512                // Create the individual labels for header and points, ignore footer
36513                each(labels.slice(0, points.length + 1), function(str, i) {
36514                    if (str !== false) {
36515                        var point = points[i - 1] ||
36516                            // Item 0 is the header. Instead of this, we could also
36517                            // use the crosshair label
36518                            {
36519                                isHeader: true,
36520                                plotX: points[0].plotX
36521                            },
36522                            owner = point.series || tooltip,
36523                            tt = owner.tt,
36524                            series = point.series || {},
36525                            colorClass = 'highcharts-color-' + pick(
36526                                point.colorIndex,
36527                                series.colorIndex,
36528                                'none'
36529                            ),
36530                            target,
36531                            x,
36532                            bBox,
36533                            boxWidth;
36534
36535                        // Store the tooltip referance on the series
36536                        if (!tt) {
36537                            owner.tt = tt = ren.label(
36538                                    null,
36539                                    null,
36540                                    null,
36541                                    'callout',
36542                                    null,
36543                                    null,
36544                                    options.useHTML
36545                                )
36546                                .addClass('highcharts-tooltip-box ' + colorClass)
36547                                .attr({
36548                                    'padding': options.padding,
36549                                    'r': options.borderRadius,
36550
36551                                    'fill': options.backgroundColor,
36552                                    'stroke': (
36553                                        options.borderColor ||
36554                                        point.color ||
36555                                        series.color ||
36556                                        '#333333'
36557                                    ),
36558                                    'stroke-width': options.borderWidth
36559
36560                                })
36561                                .add(tooltipLabel);
36562                        }
36563
36564                        tt.isActive = true;
36565                        tt.attr({
36566                            text: str
36567                        });
36568
36569                        tt.css(options.style)
36570                            .shadow(options.shadow);
36571
36572
36573                        // Get X position now, so we can move all to the other side in
36574                        // case of overflow
36575                        bBox = tt.getBBox();
36576                        boxWidth = bBox.width + tt.strokeWidth();
36577                        if (point.isHeader) {
36578                            headerHeight = bBox.height;
36579                            x = Math.max(
36580                                0, // No left overflow
36581                                Math.min(
36582                                    point.plotX + chart.plotLeft - boxWidth / 2,
36583                                    // No right overflow (#5794)
36584                                    chart.chartWidth - boxWidth
36585                                )
36586                            );
36587                        } else {
36588                            x = point.plotX + chart.plotLeft -
36589                                pick(options.distance, 16) - boxWidth;
36590                        }
36591
36592
36593                        // If overflow left, we don't use this x in the next loop
36594                        if (x < 0) {
36595                            rightAligned = false;
36596                        }
36597
36598                        // Prepare for distribution
36599                        target = (point.series && point.series.yAxis &&
36600                            point.series.yAxis.pos) + (point.plotY || 0);
36601                        target -= chart.plotTop;
36602                        boxes.push({
36603                            target: point.isHeader ?
36604                                chart.plotHeight + headerHeight : target,
36605                            rank: point.isHeader ? 1 : 0,
36606                            size: owner.tt.getBBox().height + 1,
36607                            point: point,
36608                            x: x,
36609                            tt: tt
36610                        });
36611                    }
36612                });
36613
36614                // Clean previous run (for missing points)
36615                this.cleanSplit();
36616
36617                // Distribute and put in place
36618                H.distribute(boxes, chart.plotHeight + headerHeight);
36619                each(boxes, function(box) {
36620                    var point = box.point,
36621                        series = point.series;
36622
36623                    // Put the label in place
36624                    box.tt.attr({
36625                        visibility: box.pos === undefined ? 'hidden' : 'inherit',
36626                        x: (rightAligned || point.isHeader ?
36627                            box.x :
36628                            point.plotX + chart.plotLeft + pick(options.distance, 16)),
36629                        y: box.pos + chart.plotTop,
36630                        anchorX: point.isHeader ?
36631                            point.plotX + chart.plotLeft : point.plotX + series.xAxis.pos,
36632                        anchorY: point.isHeader ?
36633                            box.pos + chart.plotTop - 15 : point.plotY + series.yAxis.pos
36634                    });
36635                });
36636            },
36637
36638            /**
36639             * Find the new position and perform the move
36640             */
36641            updatePosition: function(point) {
36642                var chart = this.chart,
36643                    label = this.getLabel(),
36644                    pos = (this.options.positioner || this.getPosition).call(
36645                        this,
36646                        label.width,
36647                        label.height,
36648                        point
36649                    );
36650
36651                // do the move
36652                this.move(
36653                    Math.round(pos.x),
36654                    Math.round(pos.y || 0), // can be undefined (#3977) 
36655                    point.plotX + chart.plotLeft,
36656                    point.plotY + chart.plotTop
36657                );
36658            },
36659
36660            /**
36661             * Get the optimal date format for a point, based on a range.
36662             * @param  {number} range - The time range
36663             * @param  {number|Date} date - The date of the point in question
36664             * @param  {number} startOfWeek - An integer representing the first day of
36665             * the week, where 0 is Sunday
36666             * @param  {Object} dateTimeLabelFormats - A map of time units to formats
36667             * @return {string} - the optimal date format for a point
36668             */
36669            getDateFormat: function(range, date, startOfWeek, dateTimeLabelFormats) {
36670                var dateStr = dateFormat('%m-%d %H:%M:%S.%L', date),
36671                    format,
36672                    n,
36673                    blank = '01-01 00:00:00.000',
36674                    strpos = {
36675                        millisecond: 15,
36676                        second: 12,
36677                        minute: 9,
36678                        hour: 6,
36679                        day: 3
36680                    },
36681                    lastN = 'millisecond'; // for sub-millisecond data, #4223
36682                for (n in timeUnits) {
36683
36684                    // If the range is exactly one week and we're looking at a
36685                    // Sunday/Monday, go for the week format
36686                    if (
36687                        range === timeUnits.week &&
36688                        +dateFormat('%w', date) === startOfWeek &&
36689                        dateStr.substr(6) === blank.substr(6)
36690                    ) {
36691                        n = 'week';
36692                        break;
36693                    }
36694
36695                    // The first format that is too great for the range
36696                    if (timeUnits[n] > range) {
36697                        n = lastN;
36698                        break;
36699                    }
36700
36701                    // If the point is placed every day at 23:59, we need to show
36702                    // the minutes as well. #2637.
36703                    if (
36704                        strpos[n] &&
36705                        dateStr.substr(strpos[n]) !== blank.substr(strpos[n])
36706                    ) {
36707                        break;
36708                    }
36709
36710                    // Weeks are outside the hierarchy, only apply them on
36711                    // Mondays/Sundays like in the first condition
36712                    if (n !== 'week') {
36713                        lastN = n;
36714                    }
36715                }
36716
36717                if (n) {
36718                    format = dateTimeLabelFormats[n];
36719                }
36720
36721                return format;
36722            },
36723
36724            /**
36725             * Get the best X date format based on the closest point range on the axis.
36726             */
36727            getXDateFormat: function(point, options, xAxis) {
36728                var xDateFormat,
36729                    dateTimeLabelFormats = options.dateTimeLabelFormats,
36730                    closestPointRange = xAxis && xAxis.closestPointRange;
36731
36732                if (closestPointRange) {
36733                    xDateFormat = this.getDateFormat(
36734                        closestPointRange,
36735                        point.x,
36736                        xAxis.options.startOfWeek,
36737                        dateTimeLabelFormats
36738                    );
36739                } else {
36740                    xDateFormat = dateTimeLabelFormats.day;
36741                }
36742
36743                return xDateFormat || dateTimeLabelFormats.year; // #2546, 2581
36744            },
36745
36746            /**
36747             * Format the footer/header of the tooltip
36748             * #3397: abstraction to enable formatting of footer and header
36749             */
36750            tooltipFooterHeaderFormatter: function(labelConfig, isFooter) {
36751                var footOrHead = isFooter ? 'footer' : 'header',
36752                    series = labelConfig.series,
36753                    tooltipOptions = series.tooltipOptions,
36754                    xDateFormat = tooltipOptions.xDateFormat,
36755                    xAxis = series.xAxis,
36756                    isDateTime = (
36757                        xAxis &&
36758                        xAxis.options.type === 'datetime' &&
36759                        isNumber(labelConfig.key)
36760                    ),
36761                    formatString = tooltipOptions[footOrHead + 'Format'];
36762
36763                // Guess the best date format based on the closest point distance (#568,
36764                // #3418)
36765                if (isDateTime && !xDateFormat) {
36766                    xDateFormat = this.getXDateFormat(
36767                        labelConfig,
36768                        tooltipOptions,
36769                        xAxis
36770                    );
36771                }
36772
36773                // Insert the footer date format if any
36774                if (isDateTime && xDateFormat) {
36775                    each(
36776                        (labelConfig.point && labelConfig.point.tooltipDateKeys) || ['key'],
36777                        function(key) {
36778                            formatString = formatString.replace(
36779                                '{point.' + key + '}',
36780                                '{point.' + key + ':' + xDateFormat + '}'
36781                            );
36782                        }
36783                    );
36784                }
36785
36786                return format(formatString, {
36787                    point: labelConfig,
36788                    series: series
36789                });
36790            },
36791
36792            /**
36793             * Build the body (lines) of the tooltip by iterating over the items and
36794             * returning one entry for each item, abstracting this functionality allows
36795             * to easily overwrite and extend it.
36796             */
36797            bodyFormatter: function(items) {
36798                return map(items, function(item) {
36799                    var tooltipOptions = item.series.tooltipOptions;
36800                    return (
36801                        tooltipOptions[
36802                            (item.point.formatPrefix || 'point') + 'Formatter'
36803                        ] ||
36804                        item.point.tooltipFormatter
36805                    ).call(
36806                        item.point,
36807                        tooltipOptions[(item.point.formatPrefix || 'point') + 'Format']
36808                    );
36809                });
36810            }
36811
36812        };
36813
36814    }
36814(Highcharts));
36815    (function(Highcharts) {
36816        /**
36817         * (c) 2010-2017 Torstein Honsi
36818         *
36819         * License: www.highcharts.com/license
36820         */
36821        var H = Highcharts,
36822            addEvent = H.addEvent,
36823            attr = H.attr,
36824            charts = H.charts,
36825            color = H.color,
36826            css = H.css,
36827            defined = H.defined,
36828            each = H.each,
36829            extend = H.extend,
36830            find = H.find,
36831            fireEvent = H.fireEvent,
36832            isObject = H.isObject,
36833            offset = H.offset,
36834            pick = H.pick,
36835            splat = H.splat,
36836            Tooltip = H.Tooltip;
36837
36838        /**
36839         * The mouse and touch tracker object. Each {@link Chart} item has one
36840         * assosiated Pointer item that can be accessed from the  {@link Chart.pointer}
36841         * property.
36842         *
36843         * @class
36844         * @param  {Chart} chart
36845         *         The Chart instance.
36846         * @param  {Options} options
36847         *         The root options object. The pointer uses options from the chart and
36848         *         tooltip structures.
36849         */
36850        Highcharts.Pointer = function(chart, options) {
36851            this.init(chart, options);
36852        };
36853
36854        Highcharts.Pointer.prototype = {
36855            /**
36856             * Initialize the Pointer.
36857             *
36858             * @private
36859             */
36860            init: function(chart, options) {
36861
36862                // Store references
36863                this.options = options;
36864                this.chart = chart;
36865
36866                // Do we need to handle click on a touch device?
36867                this.runChartClick = options.chart.events && !!options.chart.events.click;
36868
36869                this.pinchDown = [];
36870                this.lastValidTouch = {};
36871
36872                if (Tooltip) {
36873                    chart.tooltip = new Tooltip(chart, options.tooltip);
36874                    this.followTouchMove = pick(options.tooltip.followTouchMove, true);
36875                }
36876
36877                this.setDOMEvents();
36878            },
36879
36880            /**
36881             * Resolve the zoomType option, this is reset on all touch start and mouse
36882             * down events.
36883             *
36884             * @private
36885             */
36886            zoomOption: function(e) {
36887                var chart = this.chart,
36888                    options = chart.options.chart,
36889                    zoomType = options.zoomType || '',
36890                    inverted = chart.inverted,
36891                    zoomX,
36892                    zoomY;
36893
36894                // Look for the pinchType option
36895                if (/touch/.test(e.type)) {
36896                    zoomType = pick(options.pinchType, zoomType);
36897                }
36898
36899                this.zoomX = zoomX = /x/.test(zoomType);
36900                this.zoomY = zoomY = /y/.test(zoomType);
36901                this.zoomHor = (zoomX && !inverted) || (zoomY && inverted);
36902                this.zoomVert = (zoomY && !inverted) || (zoomX && inverted);
36903                this.hasZoom = zoomX || zoomY;
36904            },
36905
36906            /**
36907             * @typedef  {Object} PointerEvent
36908             *           A native browser mouse or touch event, extended with position
36909             *           information relative to the {@link Chart.container}.
36910             * @property {Number} chartX
36911             *           The X coordinate of the pointer interaction relative to the
36912             *           chart.
36913             * @property {Number} chartY
36914             *           The Y coordinate of the pointer interaction relative to the 
36915             *           chart.
36916             * 
36917             */
36918            /**
36919             * Takes a browser event object and extends it with custom Highcharts
36920             * properties `chartX` and `chartY` in order to work on the internal 
36921             * coordinate system.
36922             * 
36923             * @param  {Object} e
36924             *         The event object in standard browsers.
36925             *
36926             * @return {PointerEvent}
36927             *         A browser event with extended properties `chartX` and `chartY`.
36928             */
36929            normalize: function(e, chartPosition) {
36930                var ePos;
36931
36932                // iOS (#2757)
36933                ePos = e.touches ? (e.touches.length ? e.touches.item(0) : e.changedTouches[0]) : e;
36934
36935                // Get mouse position
36936                if (!chartPosition) {
36937                    this.chartPosition = chartPosition = offset(this.chart.container);
36938                }
36939
36940                return extend(e, {
36941                    chartX: Math.round(ePos.pageX - chartPosition.left),
36942                    chartY: Math.round(ePos.pageY - chartPosition.top)
36943                });
36944            },
36945
36946            /**
36947             * Get the click position in terms of axis values.
36948             *
36949             * @param  {PointerEvent} e
36950             *         A pointer event, extended with `chartX` and `chartY`
36951             *         properties.
36952             */
36953            getCoordinates: function(e) {
36954                var coordinates = {
36955                    xAxis: [],
36956                    yAxis: []
36957                };
36958
36959                each(this.chart.axes, function(axis) {
36960                    coordinates[axis.isXAxis ? 'xAxis' : 'yAxis'].push({
36961                        axis: axis,
36962                        value: axis.toValue(e[axis.horiz ? 'chartX' : 'chartY'])
36963                    });
36964                });
36965                return coordinates;
36966            },
36967            /**
36968             * Finds the closest point to a set of coordinates, using the k-d-tree
36969             * algorithm.
36970             *
36971             * @param  {Array.<Series>} series
36972             *         All the series to search in.
36973             * @param  {boolean} shared
36974             *         Whether it is a shared tooltip or not.
36975             * @param  {object} coordinates
36976             *         Chart coordinates of the pointer.
36977             * @param  {number} coordinates.chartX
36978             * @param  {number} coordinates.chartY
36979             *
36980             * @return {Point|undefined} The point closest to given coordinates.
36981             */
36982            findNearestKDPoint: function(series, shared, coordinates) {
36983                var closest,
36984                    sort = function(p1, p2) {
36985                        var isCloserX = p1.distX - p2.distX,
36986                            isCloser = p1.dist - p2.dist,
36987                            isAbove =
36988                            (p2.series.group && p2.series.group.zIndex) -
36989                            (p1.series.group && p1.series.group.zIndex),
36990                            result;
36991
36992                        // We have two points which are not in the same place on xAxis
36993                        // and shared tooltip:
36994                        if (isCloserX !== 0 && shared) { // #5721
36995                            result = isCloserX;
36996                            // Points are not exactly in the same place on x/yAxis:
36997                        } else if (isCloser !== 0) {
36998                            result = isCloser;
36999                            // The same xAxis and yAxis position, sort by z-index:
37000                        } else if (isAbove !== 0) {
37001                            result = isAbove;
37002                            // The same zIndex, sort by array index:
37003                        } else {
37004                            result = p1.series.index > p2.series.index ? -1 : 1;
37005                        }
37006                        return result;
37007                    };
37008                each(series, function(s) {
37009                    var noSharedTooltip = s.noSharedTooltip && shared,
37010                        compareX = (!noSharedTooltip &&
37011                            s.options.findNearestPointBy.indexOf('y') < 0
37012                        ),
37013                        point = s.searchPoint(
37014                            coordinates,
37015                            compareX
37016                        );
37017                    if (
37018                        // Check that we actually found a point on the series.
37019                        isObject(point, true) &&
37020                        // Use the new point if it is closer.
37021                        (!isObject(closest, true) || (sort(closest, point) > 0))
37022                    ) {
37023                        closest = point;
37024                    }
37025                });
37026                return closest;
37027            },
37028            getPointFromEvent: function(e) {
37029                var target = e.target,
37030                    point;
37031
37032                while (target && !point) {
37033                    point = target.point;
37034                    target = target.parentNode;
37035                }
37036                return point;
37037            },
37038
37039            getChartCoordinatesFromPoint: function(point, inverted) {
37040                var series = point.series,
37041                    xAxis = series.xAxis,
37042                    yAxis = series.yAxis,
37043                    plotX = pick(point.clientX, point.plotX);
37044
37045                if (xAxis && yAxis) {
37046                    return inverted ? {
37047                        chartX: xAxis.len + xAxis.pos - plotX,
37048                        chartY: yAxis.len + yAxis.pos - point.plotY
37049                    } : {
37050                        chartX: plotX + xAxis.pos,
37051                        chartY: point.plotY + yAxis.pos
37052                    };
37053                }
37054            },
37055
37056            /**
37057             * Calculates what is the current hovered point/points and series.
37058             *
37059             * @private
37060             *
37061             * @param  {undefined|Point} existingHoverPoint
37062             *         The point currrently beeing hovered.
37063             * @param  {undefined|Series} existingHoverSeries
37064             *         The series currently beeing hovered.
37065             * @param  {Array.<Series>} series
37066             *         All the series in the chart.
37067             * @param  {boolean} isDirectTouch
37068             *         Is the pointer directly hovering the point.
37069             * @param  {boolean} shared
37070             *         Whether it is a shared tooltip or not.
37071             * @param  {object} coordinates
37072             *         Chart coordinates of the pointer.
37073             * @param  {number} coordinates.chartX
37074             * @param  {number} coordinates.chartY
37075             * 
37076             * @return {object}
37077             *         Object containing resulting hover data.
37078             */
37079            getHoverData: function(
37080                existingHoverPoint,
37081                existingHoverSeries,
37082                series,
37083                isDirectTouch,
37084                shared,
37085                coordinates,
37086                params
37087            ) {
37088                var hoverPoint,
37089                    hoverPoints = [],
37090                    hoverSeries = existingHoverSeries,
37091                    isBoosting = params && params.isBoosting,
37092                    useExisting = !!(isDirectTouch && existingHoverPoint),
37093                    notSticky = hoverSeries && !hoverSeries.stickyTracking,
37094                    filter = function(s) {
37095                        return (
37096                            s.visible &&
37097                            !(!shared && s.directTouch) && // #3821
37098                            pick(s.options.enableMouseTracking, true)
37099                        );
37100                    },
37101                    // Which series to look in for the hover point
37102                    searchSeries = notSticky ?
37103                    // Only search on hovered series if it has stickyTracking false
37104                    [hoverSeries] :
37105                    // Filter what series to look in.
37106                    H.grep(series, function(s) {
37107                        return filter(s) && s.stickyTracking;
37108                    });
37109
37110                // Use existing hovered point or find the one closest to coordinates.
37111                hoverPoint = useExisting ?
37112                    existingHoverPoint :
37113                    this.findNearestKDPoint(searchSeries, shared, coordinates);
37114
37115                // Assign hover series
37116                hoverSeries = hoverPoint && hoverPoint.series;
37117
37118                // If we have a hoverPoint, assign hoverPoints.
37119                if (hoverPoint) {
37120                    // When tooltip is shared, it displays more than one point
37121                    if (shared && !hoverSeries.noSharedTooltip) {
37122                        searchSeries = H.grep(series, function(s) {
37123                            return filter(s) && !s.noSharedTooltip;
37124                        });
37125
37126                        // Get all points with the same x value as the hoverPoint
37127                        each(searchSeries, function(s) {
37128                            var point = find(s.points, function(p) {
37129                                return p.x === hoverPoint.x && !p.isNull;
37130                            });
37131                            if (isObject(point)) {
37132                                /*
37133                                 * Boost returns a minimal point. Convert it to a usable
37134                                 * point for tooltip and states.
37135                                 */
37136                                if (isBoosting) {
37137                                    point = s.getPoint(point);
37138                                }
37139                                hoverPoints.push(point);
37140                            }
37141                        });
37142                    } else {
37143                        hoverPoints.push(hoverPoint);
37144                    }
37145                }
37146                return {
37147                    hoverPoint: hoverPoint,
37148                    hoverSeries: hoverSeries,
37149                    hoverPoints: hoverPoints
37150                };
37151            },
37152            /**
37153             * With line type charts with a single tracker, get the point closest to the
37154             * mouse. Run Point.onMouseOver and display tooltip for the point or points.
37155             *
37156             * @private
37157             */
37158            runPointActions: function(e, p) {
37159                var pointer = this,
37160                    chart = pointer.chart,
37161                    series = chart.series,
37162                    tooltip = chart.tooltip && chart.tooltip.options.enabled ?
37163                    chart.tooltip :
37164                    undefined,
37165                    shared = tooltip ? tooltip.shared : false,
37166                    hoverPoint = p || chart.hoverPoint,
37167                    hoverSeries = hoverPoint && hoverPoint.series || chart.hoverSeries,
37168                    // onMouseOver or already hovering a series with directTouch
37169                    isDirectTouch = !!p || (
37170                        (hoverSeries && hoverSeries.directTouch) &&
37171                        pointer.isDirectTouch
37172                    ),
37173                    hoverData = this.getHoverData(
37174                        hoverPoint,
37175                        hoverSeries,
37176                        series,
37177                        isDirectTouch,
37178                        shared,
37179                        e, {
37180                            isBoosting: chart.isBoosting
37181                        }
37182                    ),
37183                    useSharedTooltip,
37184                    followPointer,
37185                    anchor,
37186                    points;
37187
37188                // Update variables from hoverData.
37189                hoverPoint = hoverData.hoverPoint;
37190                points = hoverData.hoverPoints;
37191                hoverSeries = hoverData.hoverSeries;
37192                followPointer = hoverSeries && hoverSeries.tooltipOptions.followPointer;
37193                useSharedTooltip = shared && hoverSeries && !hoverSeries.noSharedTooltip;
37194
37195                // Refresh tooltip for kdpoint if new hover point or tooltip was hidden
37196                // #3926, #4200
37197                if (
37198                    hoverPoint &&
37199                    // !(hoverSeries && hoverSeries.directTouch) &&
37200                    (hoverPoint !== chart.hoverPoint || (tooltip && tooltip.isHidden))
37201                ) {
37202                    each(chart.hoverPoints || [], function(p) {
37203                        if (H.inArray(p, points) === -1) {
37204                            p.setState();
37205                        }
37206                    });
37207                    // Do mouseover on all points (#3919, #3985, #4410, #5622)
37208                    each(points || [], function(p) {
37209                        p.setState('hover');
37210                    });
37211                    // set normal state to previous series
37212                    if (chart.hoverSeries !== hoverSeries) {
37213                        hoverSeries.onMouseOver();
37214                    }
37215
37216                    // If tracking is on series in stead of on each point, 
37217                    // fire mouseOver on hover point. // #4448
37218                    if (chart.hoverPoint) {
37219                        chart.hoverPoint.firePointEvent('mouseOut');
37220                    }
37221
37222                    // Hover point may have been destroyed in the event handlers (#7127)
37223                    if (!hoverPoint.series) {
37224                        return;
37225                    }
37226
37227                    hoverPoint.firePointEvent('mouseOver');
37228                    chart.hoverPoints = points;
37229                    chart.hoverPoint = hoverPoint;
37230                    // Draw tooltip if necessary
37231                    if (tooltip) {
37232                        tooltip.refresh(useSharedTooltip ? points : hoverPoint, e);
37233                    }
37234                    // Update positions (regardless of kdpoint or hoverPoint)
37235                } else if (followPointer && tooltip && !tooltip.isHidden) {
37236                    anchor = tooltip.getAnchor([{}], e);
37237                    tooltip.updatePosition({
37238                        plotX: anchor[0],
37239                        plotY: anchor[1]
37240                    });
37241                }
37242
37243                // Start the event listener to pick up the tooltip and crosshairs
37244                if (!pointer.unDocMouseMove) {
37245                    pointer.unDocMouseMove = addEvent(
37246                        chart.container.ownerDocument,
37247                        'mousemove',
37248                        function(e) {
37249                            var chart = charts[H.hoverChartIndex];
37250                            if (chart) {
37251                                chart.pointer.onDocumentMouseMove(e);
37252                            }
37253                        }
37254                    );
37255                }
37256
37257                // Issues related to crosshair #4927, #5269 #5066, #5658
37258                each(chart.axes, function drawAxisCrosshair(axis) {
37259                    var snap = pick(axis.crosshair.snap, true),
37260                        point = !snap ?
37261                        undefined :
37262                        H.find(points, function(p) {
37263                            return p.series[axis.coll] === axis;
37264                        });
37265
37266                    // Axis has snapping crosshairs, and one of the hover points belongs
37267                    // to axis. Always call drawCrosshair when it is not snap.
37268                    if (point || !snap) {
37269                        axis.drawCrosshair(e, point);
37270                        // Axis has snapping crosshairs, but no hover point belongs to axis
37271                    } else {
37272                        axis.hideCrosshair();
37273                    }
37274                });
37275            },
37276
37277            /**
37278             * Reset the tracking by hiding the tooltip, the hover series state and the
37279             * hover point
37280             *
37281             * @param allowMove {Boolean}
37282             *        Instead of destroying the tooltip altogether, allow moving it if
37283             *        possible.
37284             */
37285            reset: function(allowMove, delay) {
37286                var pointer = this,
37287                    chart = pointer.chart,
37288                    hoverSeries = chart.hoverSeries,
37289                    hoverPoint = chart.hoverPoint,
37290                    hoverPoints = chart.hoverPoints,
37291                    tooltip = chart.tooltip,
37292                    tooltipPoints = tooltip && tooltip.shared ? hoverPoints : hoverPoint;
37293
37294                // Check if the points have moved outside the plot area (#1003, #4736, #5101)
37295                if (allowMove && tooltipPoints) {
37296                    each(splat(tooltipPoints), function(point) {
37297                        if (point.series.isCartesian && point.plotX === undefined) {
37298                            allowMove = false;
37299                        }
37300                    });
37301                }
37302
37303                // Just move the tooltip, #349
37304                if (allowMove) {
37305                    if (tooltip && tooltipPoints) {
37306                        tooltip.refresh(tooltipPoints);
37307                        if (hoverPoint) { // #2500
37308                            hoverPoint.setState(hoverPoint.state, true);
37309                            each(chart.axes, function(axis) {
37310                                if (axis.crosshair) {
37311                                    axis.drawCrosshair(null, hoverPoint);
37312                                }
37313                            });
37314                        }
37315                    }
37316
37317                    // Full reset
37318                } else {
37319
37320                    if (hoverPoint) {
37321                        hoverPoint.onMouseOut();
37322                    }
37323
37324                    if (hoverPoints) {
37325                        each(hoverPoints, function(point) {
37326                            point.setState();
37327                        });
37328                    }
37329
37330                    if (hoverSeries) {
37331                        hoverSeries.onMouseOut();
37332                    }
37333
37334                    if (tooltip) {
37335                        tooltip.hide(delay);
37336                    }
37337
37338                    if (pointer.unDocMouseMove) {
37339                        pointer.unDocMouseMove = pointer.unDocMouseMove();
37340                    }
37341
37342                    // Remove crosshairs
37343                    each(chart.axes, function(axis) {
37344                        axis.hideCrosshair();
37345                    });
37346
37347                    pointer.hoverX = chart.hoverPoints = chart.hoverPoint = null;
37348                }
37349            },
37350
37351            /**
37352             * Scale series groups to a certain scale and translation.
37353             *
37354             * @private
37355             */
37356            scaleGroups: function(attribs, clip) {
37357
37358                var chart = this.chart,
37359                    seriesAttribs;
37360
37361                // Scale each series
37362                each(chart.series, function(series) {
37363                    seriesAttribs = attribs || series.getPlotBox(); // #1701
37364                    if (series.xAxis && series.xAxis.zoomEnabled && series.group) {
37365                        series.group.attr(seriesAttribs);
37366                        if (series.markerGroup) {
37367                            series.markerGroup.attr(seriesAttribs);
37368                            series.markerGroup.clip(clip ? chart.clipRect : null);
37369                        }
37370                        if (series.dataLabelsGroup) {
37371                            series.dataLabelsGroup.attr(seriesAttribs);
37372                        }
37373                    }
37374                });
37375
37376                // Clip
37377                chart.clipRect.attr(clip || chart.clipBox);
37378            },
37379
37380            /**
37381             * Start a drag operation.
37382             *
37383             * @private
37384             */
37385            dragStart: function(e) {
37386                var chart = this.chart;
37387
37388                // Record the start position
37389                chart.mouseIsDown = e.type;
37390                chart.cancelClick = false;
37391                chart.mouseDownX = this.mouseDownX = e.chartX;
37392                chart.mouseDownY = this.mouseDownY = e.chartY;
37393            },
37394
37395            /**
37396             * Perform a drag operation in response to a mousemove event while the mouse
37397             * is down.
37398             *
37399             * @private
37400             */
37401            drag: function(e) {
37402
37403                var chart = this.chart,
37404                    chartOptions = chart.options.chart,
37405                    chartX = e.chartX,
37406                    chartY = e.chartY,
37407                    zoomHor = this.zoomHor,
37408                    zoomVert = this.zoomVert,
37409                    plotLeft = chart.plotLeft,
37410                    plotTop = chart.plotTop,
37411                    plotWidth = chart.plotWidth,
37412                    plotHeight = chart.plotHeight,
37413                    clickedInside,
37414                    size,
37415                    selectionMarker = this.selectionMarker,
37416                    mouseDownX = this.mouseDownX,
37417                    mouseDownY = this.mouseDownY,
37418                    panKey = chartOptions.panKey && e[chartOptions.panKey + 'Key'];
37419
37420                // If the device supports both touch and mouse (like IE11), and we are touch-dragging
37421                // inside the plot area, don't handle the mouse event. #4339.
37422                if (selectionMarker && selectionMarker.touch) {
37423                    return;
37424                }
37425
37426                // If the mouse is outside the plot area, adjust to cooordinates
37427                // inside to prevent the selection marker from going outside
37428                if (chartX < plotLeft) {
37429                    chartX = plotLeft;
37430                } else if (chartX > plotLeft + plotWidth) {
37431                    chartX = plotLeft + plotWidth;
37432                }
37433
37434                if (chartY < plotTop) {
37435                    chartY = plotTop;
37436                } else if (chartY > plotTop + plotHeight) {
37437                    chartY = plotTop + plotHeight;
37438                }
37439
37440                // determine if the mouse has moved more than 10px
37441                this.hasDragged = Math.sqrt(
37442                    Math.pow(mouseDownX - chartX, 2) +
37443                    Math.pow(mouseDownY - chartY, 2)
37444                );
37445
37446                if (this.hasDragged > 10) {
37447                    clickedInside = chart.isInsidePlot(mouseDownX - plotLeft, mouseDownY - plotTop);
37448
37449                    // make a selection
37450                    if (chart.hasCartesianSeries && (this.zoomX || this.zoomY) && clickedInside && !panKey) {
37451                        if (!selectionMarker) {
37452                            this.selectionMarker = selectionMarker = chart.renderer.rect(
37453                                    plotLeft,
37454                                    plotTop,
37455                                    zoomHor ? 1 : plotWidth,
37456                                    zoomVert ? 1 : plotHeight,
37457                                    0
37458                                )
37459                                .attr({
37460
37461                                    fill: chartOptions.selectionMarkerFill || color('#335cad').setOpacity(0.25).get(),
37462
37463                                    'class': 'highcharts-selection-marker',
37464                                    'zIndex': 7
37465                                })
37466                                .add();
37467                        }
37468                    }
37469
37470                    // adjust the width of the selection marker
37471                    if (selectionMarker && zoomHor) {
37472                        size = chartX - mouseDownX;
37473                        selectionMarker.attr({
37474                            width: Math.abs(size),
37475                            x: (size > 0 ? 0 : size) + mouseDownX
37476                        });
37477                    }
37478                    // adjust the height of the selection marker
37479                    if (selectionMarker && zoomVert) {
37480                        size = chartY - mouseDownY;
37481                        selectionMarker.attr({
37482                            height: Math.abs(size),
37483                            y: (size > 0 ? 0 : size) + mouseDownY
37484                        });
37485                    }
37486
37487                    // panning
37488                    if (clickedInside && !selectionMarker && chartOptions.panning) {
37489                        chart.pan(e, chartOptions.panning);
37490                    }
37491                }
37492            },
37493
37494            /**
37495             * On mouse up or touch end across the entire document, drop the selection.
37496             *
37497             * @private
37498             */
37499            drop: function(e) {
37500                var pointer = this,
37501                    chart = this.chart,
37502                    hasPinched = this.hasPinched;
37503
37504                if (this.selectionMarker) {
37505                    var selectionData = {
37506                            originalEvent: e, // #4890
37507                            xAxis: [],
37508                            yAxis: []
37509                        },
37510                        selectionBox = this.selectionMarker,
37511                        selectionLeft = selectionBox.attr ? selectionBox.attr('x') : selectionBox.x,
37512                        selectionTop = selectionBox.attr ? selectionBox.attr('y') : selectionBox.y,
37513                        selectionWidth = selectionBox.attr ? selectionBox.attr('width') : selectionBox.width,
37514                        selectionHeight = selectionBox.attr ? selectionBox.attr('height') : selectionBox.height,
37515                        runZoom;
37516
37517                    // a selection has been made
37518                    if (this.hasDragged || hasPinched) {
37519
37520                        // record each axis' min and max
37521                        each(chart.axes, function(axis) {
37522                            if (axis.zoomEnabled && defined(axis.min) && (hasPinched || pointer[{
37523                                    xAxis: 'zoomX',
37524                                    yAxis: 'zoomY'
37525                                }[axis.coll]])) { // #859, #3569
37526                                var horiz = axis.horiz,
37527                                    minPixelPadding = e.type === 'touchend' ? axis.minPixelPadding : 0, // #1207, #3075
37528                                    selectionMin = axis.toValue((horiz ? selectionLeft : selectionTop) + minPixelPadding),
37529                                    selectionMax = axis.toValue((horiz ? selectionLeft + selectionWidth : selectionTop + selectionHeight) - minPixelPadding);
37530
37531                                selectionData[axis.coll].push({
37532                                    axis: axis,
37533                                    min: Math.min(selectionMin, selectionMax), // for reversed axes
37534                                    max: Math.max(selectionMin, selectionMax)
37535                                });
37536                                runZoom = true;
37537                            }
37538                        });
37539                        if (runZoom) {
37540                            fireEvent(chart, 'selection', selectionData, function(args) {
37541                                chart.zoom(extend(args, hasPinched ? {
37542                                    animation: false
37543                                } : null));
37544                            });
37545                        }
37546
37547                    }
37548                    this.selectionMarker = this.selectionMarker.destroy();
37549
37550                    // Reset scaling preview
37551                    if (hasPinched) {
37552                        this.scaleGroups();
37553                    }
37554                }
37555
37556                // Reset all
37557                if (chart) { // it may be destroyed on mouse up - #877
37558                    css(chart.container, {
37559                        cursor: chart._cursor
37560                    });
37561                    chart.cancelClick = this.hasDragged > 10; // #370
37562                    chart.mouseIsDown = this.hasDragged = this.hasPinched = false;
37563                    this.pinchDown = [];
37564                }
37565            },
37566
37567            onContainerMouseDown: function(e) {
37568
37569                e = this.normalize(e);
37570
37571                this.zoomOption(e);
37572
37573                // issue #295, dragging not always working in Firefox
37574                if (e.preventDefault) {
37575                    e.preventDefault();
37576                }
37577
37578                this.dragStart(e);
37579            },
37580
37581
37582
37583            onDocumentMouseUp: function(e) {
37584                if (charts[H.hoverChartIndex]) {
37585                    charts[H.hoverChartIndex].pointer.drop(e);
37586                }
37587            },
37588
37589            /**
37590             * Special handler for mouse move that will hide the tooltip when the mouse
37591             * leaves the plotarea. Issue #149 workaround. The mouseleave event does not
37592             * always fire.
37593             *
37594             * @private
37595             */
37596            onDocumentMouseMove: function(e) {
37597                var chart = this.chart,
37598                    chartPosition = this.chartPosition;
37599
37600                e = this.normalize(e, chartPosition);
37601
37602                // If we're outside, hide the tooltip
37603                if (chartPosition && !this.inClass(e.target, 'highcharts-tracker') &&
37604                    !chart.isInsidePlot(e.chartX - chart.plotLeft, e.chartY - chart.plotTop)) {
37605                    this.reset();
37606                }
37607            },
37608
37609            /**
37610             * When mouse leaves the container, hide the tooltip.
37611             *
37612             * @private
37613             */
37614            onContainerMouseLeave: function(e) {
37615                var chart = charts[H.hoverChartIndex];
37616                if (chart && (e.relatedTarget || e.toElement)) { // #4886, MS Touch end fires mouseleave but with no related target
37617                    chart.pointer.reset();
37618                    chart.pointer.chartPosition = null; // also reset the chart position, used in #149 fix
37619                }
37620            },
37621
37622            // The mousemove, touchmove and touchstart event handler
37623            onContainerMouseMove: function(e) {
37624
37625                var chart = this.chart;
37626
37627                if (!defined(H.hoverChartIndex) || !charts[H.hoverChartIndex] || !charts[H.hoverChartIndex].mouseIsDown) {
37628                    H.hoverChartIndex = chart.index;
37629                }
37630
37631                e = this.normalize(e);
37632                e.returnValue = false; // #2251, #3224
37633
37634                if (chart.mouseIsDown === 'mousedown') {
37635                    this.drag(e);
37636                }
37637
37638                // Show the tooltip and run mouse over events (#977)
37639                if ((this.inClass(e.target, 'highcharts-tracker') ||
37640                        chart.isInsidePlot(e.chartX - chart.plotLeft, e.chartY - chart.plotTop)) && !chart.openMenu) {
37641                    this.runPointActions(e);
37642                }
37643            },
37644
37645            /**
37646             * Utility to detect whether an element has, or has a parent with, a specific
37647             * class name. Used on detection of tracker objects and on deciding whether
37648             * hovering the tooltip should cause the active series to mouse out.
37649             *
37650             * @param  {SVGDOMElement|HTMLDOMElement} element
37651             *         The element to investigate.
37652             * @param  {String} className
37653             *         The class name to look for.
37654             *
37655             * @return {Boolean}
37656             *         True if either the element or one of its parents has the given
37657             *         class name.
37658             */
37659            inClass: function(element, className) {
37660                var elemClassName;
37661                while (element) {
37662                    elemClassName = attr(element, 'class');
37663                    if (elemClassName) {
37664                        if (elemClassName.indexOf(className) !== -1) {
37665                            return true;
37666                        }
37667                        if (elemClassName.indexOf('highcharts-container') !== -1) {
37668                            return false;
37669                        }
37670                    }
37671                    element = element.parentNode;
37672                }
37673            },
37674
37675            onTrackerMouseOut: function(e) {
37676                var series = this.chart.hoverSeries,
37677                    relatedTarget = e.relatedTarget || e.toElement;
37678
37679                this.isDirectTouch = false;
37680
37681                if (
37682                    series &&
37683                    relatedTarget &&
37684                    !series.stickyTracking &&
37685                    !this.inClass(relatedTarget, 'highcharts-tooltip') &&
37686                    (!this.inClass(
37687                            relatedTarget,
37688                            'highcharts-series-' + series.index
37689                        ) || // #2499, #4465
37690                        !this.inClass(relatedTarget, 'highcharts-tracker') // #5553
37691                    )
37692                ) {
37693                    series.onMouseOut();
37694                }
37695            },
37696
37697            onContainerClick: function(e) {
37698                var chart = this.chart,
37699                    hoverPoint = chart.hoverPoint,
37700                    plotLeft = chart.plotLeft,
37701                    plotTop = chart.plotTop;
37702
37703                e = this.normalize(e);
37704
37705                if (!chart.cancelClick) {
37706
37707                    // On tracker click, fire the series and point events. #783, #1583
37708                    if (hoverPoint && this.inClass(e.target, 'highcharts-tracker')) {
37709
37710                        // the series click event
37711                        fireEvent(hoverPoint.series, 'click', extend(e, {
37712                            point: hoverPoint
37713                        }));
37714
37715                        // the point click event
37716                        if (chart.hoverPoint) { // it may be destroyed (#1844)
37717                            hoverPoint.firePointEvent('click', e);
37718                        }
37719
37720                        // When clicking outside a tracker, fire a chart event
37721                    } else {
37722                        extend(e, this.getCoordinates(e));
37723
37724                        // fire a click event in the chart
37725                        if (chart.isInsidePlot(e.chartX - plotLeft, e.chartY - plotTop)) {
37726                            fireEvent(chart, 'click', e);
37727                        }
37728                    }
37729
37730
37731                }
37732            },
37733
37734            /**
37735             * Set the JS DOM events on the container and document. This method should contain
37736             * a one-to-one assignment between methods and their handlers. Any advanced logic should
37737             * be moved to the handler reflecting the event's name.
37738             *
37739             * @private
37740             */
37741            setDOMEvents: function() {
37742
37743                var pointer = this,
37744                    container = pointer.chart.container,
37745                    ownerDoc = container.ownerDocument;
37746
37747                container.onmousedown = function(e) {
37748                    pointer.onContainerMouseDown(e);
37749                };
37750                container.onmousemove = function(e) {
37751                    pointer.onContainerMouseMove(e);
37752                };
37753                container.onclick = function(e) {
37754                    pointer.onContainerClick(e);
37755                };
37756                this.unbindContainerMouseLeave = addEvent(
37757                    container,
37758                    'mouseleave',
37759                    pointer.onContainerMouseLeave
37760                );
37761                if (!H.unbindDocumentMouseUp) {
37762                    H.unbindDocumentMouseUp = addEvent(
37763                        ownerDoc,
37764                        'mouseup',
37765                        pointer.onDocumentMouseUp
37766                    );
37767                }
37768                if (H.hasTouch) {
37769                    container.ontouchstart = function(e) {
37770                        pointer.onContainerTouchStart(e);
37771                    };
37772                    container.ontouchmove = function(e) {
37773                        pointer.onContainerTouchMove(e);
37774                    };
37775                    if (!H.unbindDocumentTouchEnd) {
37776                        H.unbindDocumentTouchEnd = addEvent(
37777                            ownerDoc,
37778                            'touchend',
37779                            pointer.onDocumentTouchEnd
37780                        );
37781                    }
37782                }
37783
37784            },
37785
37786            /**
37787             * Destroys the Pointer object and disconnects DOM events.
37788             */
37789            destroy: function() {
37790                var pointer = this;
37791
37792                if (pointer.unDocMouseMove) {
37793                    pointer.unDocMouseMove();
37794                }
37795
37796                this.unbindContainerMouseLeave();
37797
37798                if (!H.chartCount) {
37799                    if (H.unbindDocumentMouseUp) {
37800                        H.unbindDocumentMouseUp = H.unbindDocumentMouseUp();
37801                    }
37802                    if (H.unbindDocumentTouchEnd) {
37803                        H.unbindDocumentTouchEnd = H.unbindDocumentTouchEnd();
37804                    }
37805                }
37806
37807                // memory and CPU leak
37808                clearInterval(pointer.tooltipTimeout);
37809
37810                H.objectEach(pointer, function(val, prop) {
37811                    pointer[prop] = null;
37812                });
37813            }
37814        };
37815
37816    }
37816(Highcharts));
37817    (function(H) {
37818        /**
37819         * (c) 2010-2017 Torstein Honsi
37820         *
37821         * License: www.highcharts.com/license
37822         */
37823        var charts = H.charts,
37824            each = H.each,
37825            extend = H.extend,
37826            map = H.map,
37827            noop = H.noop,
37828            pick = H.pick,
37829            Pointer = H.Pointer;
37830
37831        /* Support for touch devices */
37832        extend(Pointer.prototype, /** @lends Pointer.prototype */ {
37833
37834            /**
37835             * Run translation operations
37836             */
37837            pinchTranslate: function(
37838                pinchDown,
37839                touches,
37840                transform,
37841                selectionMarker,
37842                clip,
37843                lastValidTouch
37844            ) {
37845                if (this.zoomHor) {
37846                    this.pinchTranslateDirection(
37847                        true,
37848                        pinchDown,
37849                        touches,
37850                        transform,
37851                        selectionMarker,
37852                        clip,
37853                        lastValidTouch
37854                    );
37855                }
37856                if (this.zoomVert) {
37857                    this.pinchTranslateDirection(
37858                        false,
37859                        pinchDown,
37860                        touches,
37861                        transform,
37862                        selectionMarker,
37863                        clip,
37864                        lastValidTouch
37865                    );
37866                }
37867            },
37868
37869            /**
37870             * Run translation operations for each direction (horizontal and vertical)
37871             * independently
37872             */
37873            pinchTranslateDirection: function(horiz, pinchDown, touches, transform,
37874                selectionMarker, clip, lastValidTouch, forcedScale) {
37875                var chart = this.chart,
37876                    xy = horiz ? 'x' : 'y',
37877                    XY = horiz ? 'X' : 'Y',
37878                    sChartXY = 'chart' + XY,
37879                    wh = horiz ? 'width' : 'height',
37880                    plotLeftTop = chart['plot' + (horiz ? 'Left' : 'Top')],
37881                    selectionWH,
37882                    selectionXY,
37883                    clipXY,
37884                    scale = forcedScale || 1,
37885                    inverted = chart.inverted,
37886                    bounds = chart.bounds[horiz ? 'h' : 'v'],
37887                    singleTouch = pinchDown.length === 1,
37888                    touch0Start = pinchDown[0][sChartXY],
37889                    touch0Now = touches[0][sChartXY],
37890                    touch1Start = !singleTouch && pinchDown[1][sChartXY],
37891                    touch1Now = !singleTouch && touches[1][sChartXY],
37892                    outOfBounds,
37893                    transformScale,
37894                    scaleKey,
37895                    setScale = function() {
37896                        // Don't zoom if fingers are too close on this axis
37897                        if (!singleTouch && Math.abs(touch0Start - touch1Start) > 20) {
37898                            scale = forcedScale ||
37899                                Math.abs(touch0Now - touch1Now) /
37900                                Math.abs(touch0Start - touch1Start);
37901                        }
37902
37903                        clipXY = ((plotLeftTop - touch0Now) / scale) + touch0Start;
37904                        selectionWH = chart['plot' + (horiz ? 'Width' : 'Height')] /
37905                            scale;
37906                    };
37907
37908                // Set the scale, first pass
37909                setScale();
37910
37911                // The clip position (x or y) is altered if out of bounds, the selection
37912                // position is not
37913                selectionXY = clipXY;
37914
37915                // Out of bounds
37916                if (selectionXY < bounds.min) {
37917                    selectionXY = bounds.min;
37918                    outOfBounds = true;
37919                } else if (selectionXY + selectionWH > bounds.max) {
37920                    selectionXY = bounds.max - selectionWH;
37921                    outOfBounds = true;
37922                }
37923
37924                // Is the chart dragged off its bounds, determined by dataMin and
37925                // dataMax?
37926                if (outOfBounds) {
37927
37928                    // Modify the touchNow position in order to create an elastic drag
37929                    // movement. This indicates to the user that the chart is responsive
37930                    // but can't be dragged further.
37931                    touch0Now -= 0.8 * (touch0Now - lastValidTouch[xy][0]);
37932                    if (!singleTouch) {
37933                        touch1Now -= 0.8 * (touch1Now - lastValidTouch[xy][1]);
37934                    }
37935
37936                    // Set the scale, second pass to adapt to the modified touchNow
37937                    // positions
37938                    setScale();
37939
37940                } else {
37941                    lastValidTouch[xy] = [touch0Now, touch1Now];
37942                }
37943
37944                // Set geometry for clipping, selection and transformation
37945                if (!inverted) {
37946                    clip[xy] = clipXY - plotLeftTop;
37947                    clip[wh] = selectionWH;
37948                }
37949                scaleKey = inverted ? (horiz ? 'scaleY' : 'scaleX') : 'scale' + XY;
37950                transformScale = inverted ? 1 / scale : scale;
37951
37952                selectionMarker[wh] = selectionWH;
37953                selectionMarker[xy] = selectionXY;
37954                transform[scaleKey] = scale;
37955                transform['translate' + XY] = (transformScale * plotLeftTop) +
37956                    (touch0Now - (transformScale * touch0Start));
37957            },
37958
37959            /**
37960             * Handle touch events with two touches
37961             */
37962            pinch: function(e) {
37963
37964                var self = this,
37965                    chart = self.chart,
37966                    pinchDown = self.pinchDown,
37967                    touches = e.touches,
37968                    touchesLength = touches.length,
37969                    lastValidTouch = self.lastValidTouch,
37970                    hasZoom = self.hasZoom,
37971                    selectionMarker = self.selectionMarker,
37972                    transform = {},
37973                    fireClickEvent = touchesLength === 1 &&
37974                    ((self.inClass(e.target, 'highcharts-tracker') &&
37975                        chart.runTrackerClick) || self.runChartClick),
37976                    clip = {};
37977
37978                // Don't initiate panning until the user has pinched. This prevents us
37979                // from blocking page scrolling as users scroll down a long page
37980                // (#4210).
37981                if (touchesLength > 1) {
37982                    self.initiated = true;
37983                }
37984
37985                // On touch devices, only proceed to trigger click if a handler is
37986                // defined
37987                if (hasZoom && self.initiated && !fireClickEvent) {
37988                    e.preventDefault();
37989                }
37990
37991                // Normalize each touch
37992                map(touches, function(e) {
37993                    return self.normalize(e);
37994                });
37995
37996                // Register the touch start position
37997                if (e.type === 'touchstart') {
37998                    each(touches, function(e, i) {
37999                        pinchDown[i] = {
38000                            chartX: e.chartX,
38001                            chartY: e.chartY
38002                        };
38003                    });
38004                    lastValidTouch.x = [pinchDown[0].chartX, pinchDown[1] &&
38005                        pinchDown[1].chartX
38006                    ];
38007                    lastValidTouch.y = [pinchDown[0].chartY, pinchDown[1] &&
38008                        pinchDown[1].chartY
38009                    ];
38010
38011                    // Identify the data bounds in pixels
38012                    each(chart.axes, function(axis) {
38013                        if (axis.zoomEnabled) {
38014                            var bounds = chart.bounds[axis.horiz ? 'h' : 'v'],
38015                                minPixelPadding = axis.minPixelPadding,
38016                                min = axis.toPixels(
38017                                    pick(axis.options.min, axis.dataMin)
38018                                ),
38019                                max = axis.toPixels(
38020                                    pick(axis.options.max, axis.dataMax)
38021                                ),
38022                                absMin = Math.min(min, max),
38023                                absMax = Math.max(min, max);
38024
38025                            // Store the bounds for use in the touchmove handler
38026                            bounds.min = Math.min(axis.pos, absMin - minPixelPadding);
38027                            bounds.max = Math.max(
38028                                axis.pos + axis.len,
38029                                absMax + minPixelPadding
38030                            );
38031                        }
38032                    });
38033                    self.res = true; // reset on next move
38034
38035                    // Optionally move the tooltip on touchmove
38036                } else if (self.followTouchMove && touchesLength === 1) {
38037                    this.runPointActions(self.normalize(e));
38038
38039                    // Event type is touchmove, handle panning and pinching
38040                } else if (pinchDown.length) { // can be 0 when releasing, if touchend
38041                    // fires first
38042
38043
38044                    // Set the marker
38045                    if (!selectionMarker) {
38046                        self.selectionMarker = selectionMarker = extend({
38047                            destroy: noop,
38048                            touch: true
38049                        }, chart.plotBox);
38050                    }
38051
38052                    self.pinchTranslate(
38053                        pinchDown,
38054                        touches,
38055                        transform,
38056                        selectionMarker,
38057                        clip,
38058                        lastValidTouch
38059                    );
38060
38061                    self.hasPinched = hasZoom;
38062
38063                    // Scale and translate the groups to provide visual feedback during
38064                    // pinching
38065                    self.scaleGroups(transform, clip);
38066
38067                    if (self.res) {
38068                        self.res = false;
38069                        this.reset(false, 0);
38070                    }
38071                }
38072            },
38073
38074            /**
38075             * General touch handler shared by touchstart and touchmove.
38076             */
38077            touch: function(e, start) {
38078                var chart = this.chart,
38079                    hasMoved,
38080                    pinchDown,
38081                    isInside;
38082
38083                if (chart.index !== H.hoverChartIndex) {
38084                    this.onContainerMouseLeave({
38085                        relatedTarget: true
38086                    });
38087                }
38088                H.hoverChartIndex = chart.index;
38089
38090                if (e.touches.length === 1) {
38091
38092                    e = this.normalize(e);
38093
38094                    isInside = chart.isInsidePlot(
38095                        e.chartX - chart.plotLeft,
38096                        e.chartY - chart.plotTop
38097                    );
38098                    if (isInside && !chart.openMenu) {
38099
38100                        // Run mouse events and display tooltip etc
38101                        if (start) {
38102                            this.runPointActions(e);
38103                        }
38104
38105                        // Android fires touchmove events after the touchstart even if
38106                        // the finger hasn't moved, or moved only a pixel or two. In iOS
38107                        // however, the touchmove doesn't fire unless the finger moves
38108                        // more than ~4px. So we emulate this behaviour in Android by
38109                        // checking how much it moved, and cancelling on small
38110                        // distances. #3450.
38111                        if (e.type === 'touchmove') {
38112                            pinchDown = this.pinchDown;
38113                            hasMoved = pinchDown[0] ? Math.sqrt( // #5266
38114                                Math.pow(pinchDown[0].chartX - e.chartX, 2) +
38115                                Math.pow(pinchDown[0].chartY - e.chartY, 2)
38116                            ) >= 4 : false;
38117                        }
38118
38119                        if (pick(hasMoved, true)) {
38120                            this.pinch(e);
38121                        }
38122
38123                    } else if (start) {
38124                        // Hide the tooltip on touching outside the plot area (#1203)
38125                        this.reset();
38126                    }
38127
38128                } else if (e.touches.length === 2) {
38129                    this.pinch(e);
38130                }
38131            },
38132
38133            onContainerTouchStart: function(e) {
38134                this.zoomOption(e);
38135                this.touch(e, true);
38136            },
38137
38138            onContainerTouchMove: function(e) {
38139                this.touch(e);
38140            },
38141
38142            onDocumentTouchEnd: function(e) {
38143                if (charts[H.hoverChartIndex]) {
38144                    charts[H.hoverChartIndex].pointer.drop(e);
38145                }
38146            }
38147
38148        });
38149
38150    }(Highcharts));
38151    (function(H) {
38152        /**
38153         * (c) 2010-2017 Torstein Honsi
38154         *
38155         * License: www.highcharts.com/license
38156         */
38157        var addEvent = H.addEvent,
38158            charts = H.charts,
38159            css = H.css,
38160            doc = H.doc,
38161            extend = H.extend,
38162            hasTouch = H.hasTouch,
38163            noop = H.noop,
38164            Pointer = H.Pointer,
38165            removeEvent = H.removeEvent,
38166            win = H.win,
38167            wrap = H.wrap;
38168
38169        if (!hasTouch && (win.PointerEvent || win.MSPointerEvent)) {
38170
38171            // The touches object keeps track of the points being touched at all times
38172            var touches = {},
38173                hasPointerEvent = !!win.PointerEvent,
38174                getWebkitTouches = function() {
38175                    var fake = [];
38176                    fake.item = function(i) {
38177                        return this[i];
38178                    };
38179                    H.objectEach(touches, function(touch) {
38180                        fake.push({
38181                            pageX: touch.pageX,
38182                            pageY: touch.pageY,
38183                            target: touch.target
38184                        });
38185                    });
38186                    return fake;
38187                },
38188                translateMSPointer = function(e, method, wktype, func) {
38189                    var p;
38190                    if ((e.pointerType === 'touch' || e.pointerType === e.MSPOINTER_TYPE_TOUCH) && charts[H.hoverChartIndex]) {
38191                        func(e);
38192                        p = charts[H.hoverChartIndex].pointer;
38193                        p[method]({
38194                            type: wktype,
38195                            target: e.currentTarget,
38196                            preventDefault: noop,
38197                            touches: getWebkitTouches()
38198                        });
38199                    }
38200                };
38201
38202            /**
38203             * Extend the Pointer prototype with methods for each event handler and more
38204             */
38205            extend(Pointer.prototype, /** @lends Pointer.prototype */ {
38206                onContainerPointerDown: function(e) {
38207                    translateMSPointer(e, 'onContainerTouchStart', 'touchstart', function(e) {
38208                        touches[e.pointerId] = {
38209                            pageX: e.pageX,
38210                            pageY: e.pageY,
38211                            target: e.currentTarget
38212                        };
38213                    });
38214                },
38215                onContainerPointerMove: function(e) {
38216                    translateMSPointer(e, 'onContainerTouchMove', 'touchmove', function(e) {
38217                        touches[e.pointerId] = {
38218                            pageX: e.pageX,
38219                            pageY: e.pageY
38220                        };
38221                        if (!touches[e.pointerId].target) {
38222                            touches[e.pointerId].target = e.currentTarget;
38223                        }
38224                    });
38225                },
38226                onDocumentPointerUp: function(e) {
38227                    translateMSPointer(e, 'onDocumentTouchEnd', 'touchend', function(e) {
38228                        delete touches[e.pointerId];
38229                    });
38230                },
38231
38232                /**
38233                 * Add or remove the MS Pointer specific events
38234                 */
38235                batchMSEvents: function(fn) {
38236                    fn(this.chart.container, hasPointerEvent ? 'pointerdown' : 'MSPointerDown', this.onContainerPointerDown);
38237                    fn(this.chart.container, hasPointerEvent ? 'pointermove' : 'MSPointerMove', this.onContainerPointerMove);
38238                    fn(doc, hasPointerEvent ? 'pointerup' : 'MSPointerUp', this.onDocumentPointerUp);
38239                }
38240            });
38241
38242            // Disable default IE actions for pinch and such on chart element
38243            wrap(Pointer.prototype, 'init', function(proceed, chart, options) {
38244                proceed.call(this, chart, options);
38245                if (this.hasZoom) { // #4014
38246                    css(chart.container, {
38247                        '-ms-touch-action': 'none',
38248                        'touch-action': 'none'
38249                    });
38250                }
38251            });
38252
38253            // Add IE specific touch events to chart
38254            wrap(Pointer.prototype, 'setDOMEvents', function(proceed) {
38255                proceed.apply(this);
38256                if (this.hasZoom || this.followTouchMove) {
38257                    this.batchMSEvents(addEvent);
38258                }
38259            });
38260            // Destroy MS events also
38261            wrap(Pointer.prototype, 'destroy', function(proceed) {
38262                this.batchMSEvents(removeEvent);
38263                proceed.call(this);
38264            });
38265        }
38266
38267    }(Highcharts));
38268    (function(Highcharts) {
38269        /**
38270         * (c) 2010-2017 Torstein Honsi
38271         *
38272         * License: www.highcharts.com/license
38273         */
38274        var H = Highcharts,
38275
38276            addEvent = H.addEvent,
38277            css = H.css,
38278            discardElement = H.discardElement,
38279            defined = H.defined,
38280            each = H.each,
38281            isFirefox = H.isFirefox,
38282            marginNames = H.marginNames,
38283            merge = H.merge,
38284            pick = H.pick,
38285            setAnimation = H.setAnimation,
38286            stableSort = H.stableSort,
38287            win = H.win,
38288            wrap = H.wrap;
38289
38290        /**
38291         * The overview of the chart's series. The legend object is instanciated
38292         * internally in the chart constructor, and available from `chart.legend`. Each
38293         * chart has only one legend.
38294         * 
38295         * @class
38296         */
38297        Highcharts.Legend = function(chart, options) {
38298            this.init(chart, options);
38299        };
38300
38301        Highcharts.Legend.prototype = {
38302
38303            /**
38304             * Initialize the legend.
38305             *
38306             * @private
38307             */
38308            init: function(chart, options) {
38309
38310                this.chart = chart;
38311
38312                this.setOptions(options);
38313
38314                if (options.enabled) {
38315
38316                    // Render it
38317                    this.render();
38318
38319                    // move checkboxes
38320                    addEvent(this.chart, 'endResize', function() {
38321                        this.legend.positionCheckboxes();
38322                    });
38323                }
38324            },
38325
38326            setOptions: function(options) {
38327
38328                var padding = pick(options.padding, 8);
38329
38330                this.options = options;
38331
38332
38333                this.itemStyle = options.itemStyle;
38334                this.itemHiddenStyle = merge(this.itemStyle, options.itemHiddenStyle);
38335
38336                this.itemMarginTop = options.itemMarginTop || 0;
38337                this.padding = padding;
38338                this.initialItemY = padding - 5; // 5 is pixels above the text
38339                this.maxItemWidth = 0;
38340                this.itemHeight = 0;
38341                this.symbolWidth = pick(options.symbolWidth, 16);
38342                this.pages = [];
38343
38344            },
38345
38346            /**
38347             * Update the legend with new options. Equivalent to running `chart.update`
38348             * with a legend configuration option.
38349             * @param  {LegendOptions} options
38350             *         Legend options.
38351             * @param  {Boolean} [redraw=true]
38352             *         Whether to redraw the chart.
38353             *
38354             * @sample highcharts/legend/legend-update/
38355             *         Legend update
38356             */
38357            update: function(options, redraw) {
38358                var chart = this.chart;
38359
38360                this.setOptions(merge(true, this.options, options));
38361                this.destroy();
38362                chart.isDirtyLegend = chart.isDirtyBox = true;
38363                if (pick(redraw, true)) {
38364                    chart.redraw();
38365                }
38366            },
38367
38368            /**
38369             * Set the colors for the legend item.
38370             *
38371             * @private
38372             * @param  {Series|Point} item
38373             *         A Series or Point instance
38374             * @param  {Boolean} visible
38375             *         Dimmed or colored
38376             */
38377            colorizeItem: function(item, visible) {
38378                item.legendGroup[visible ? 'removeClass' : 'addClass'](
38379                    'highcharts-legend-item-hidden'
38380                );
38381
38382
38383                var legend = this,
38384                    options = legend.options,
38385                    legendItem = item.legendItem,
38386                    legendLine = item.legendLine,
38387                    legendSymbol = item.legendSymbol,
38388                    hiddenColor = legend.itemHiddenStyle.color,
38389                    textColor = visible ? options.itemStyle.color : hiddenColor,
38390                    symbolColor = visible ? (item.color || hiddenColor) : hiddenColor,
38391                    markerOptions = item.options && item.options.marker,
38392                    symbolAttr = {
38393                        fill: symbolColor
38394                    };
38395
38396                if (legendItem) {
38397                    legendItem.css({
38398                        fill: textColor,
38399                        color: textColor // #1553, oldIE
38400                    });
38401                }
38402                if (legendLine) {
38403                    legendLine.attr({
38404                        stroke: symbolColor
38405                    });
38406                }
38407
38408                if (legendSymbol) {
38409
38410                    // Apply marker options
38411                    if (markerOptions && legendSymbol.isMarker) { // #585
38412                        symbolAttr = item.pointAttribs();
38413                        if (!visible) {
38414                            symbolAttr.stroke = symbolAttr.fill = hiddenColor; // #6769
38415                        }
38416                    }
38417
38418                    legendSymbol.attr(symbolAttr);
38419                }
38420
38421            },
38422
38423            /**
38424             * Position the legend item.
38425             *
38426             * @private
38427             * @param {Series|Point} item
38428             *        The item to position
38429             */
38430            positionItem: function(item) {
38431                var legend = this,
38432                    options = legend.options,
38433                    symbolPadding = options.symbolPadding,
38434                    ltr = !options.rtl,
38435                    legendItemPos = item._legendItemPos,
38436                    itemX = legendItemPos[0],
38437                    itemY = legendItemPos[1],
38438                    checkbox = item.checkbox,
38439                    legendGroup = item.legendGroup;
38440
38441                if (legendGroup && legendGroup.element) {
38442                    legendGroup.translate(
38443                        ltr ?
38444                        itemX :
38445                        legend.legendWidth - itemX - 2 * symbolPadding - 4,
38446                        itemY
38447                    );
38448                }
38449
38450                if (checkbox) {
38451                    checkbox.x = itemX;
38452                    checkbox.y = itemY;
38453                }
38454            },
38455
38456            /**
38457             * Destroy a single legend item, used internally on removing series items.
38458             * 
38459             * @param {Series|Point} item
38460             *        The item to remove
38461             */
38462            destroyItem: function(item) {
38463                var checkbox = item.checkbox;
38464
38465                // destroy SVG elements
38466                each(
38467                    ['legendItem', 'legendLine', 'legendSymbol', 'legendGroup'],
38468                    function(key) {
38469                        if (item[key]) {
38470                            item[key] = item[key].destroy();
38471                        }
38472                    }
38473                );
38474
38475                if (checkbox) {
38476                    discardElement(item.checkbox);
38477                }
38478            },
38479
38480            /**
38481             * Destroy the legend. Used internally. To reflow objects, `chart.redraw`
38482             * must be called after destruction.
38483             */
38484            destroy: function() {
38485                function destroyItems(key) {
38486                    if (this[key]) {
38487                        this[key] = this[key].destroy();
38488                    }
38489                }
38490
38491                // Destroy items
38492                each(this.getAllItems(), function(item) {
38493                    each(['legendItem', 'legendGroup'], destroyItems, item);
38494                });
38495
38496                // Destroy legend elements
38497                each([
38498                    'clipRect',
38499                    'up',
38500                    'down',
38501                    'pager',
38502                    'nav',
38503                    'box',
38504                    'title',
38505                    'group'
38506                ], destroyItems, this);
38507                this.display = null; // Reset in .render on update.
38508            },
38509
38510            /**
38511             * Position the checkboxes after the width is determined.
38512             *
38513             * @private
38514             */
38515            positionCheckboxes: function() {
38516                var alignAttr = this.group && this.group.alignAttr,
38517                    translateY,
38518                    clipHeight = this.clipHeight || this.legendHeight,
38519                    titleHeight = this.titleHeight;
38520
38521                if (alignAttr) {
38522                    translateY = alignAttr.translateY;
38523                    each(this.allItems, function(item) {
38524                        var checkbox = item.checkbox,
38525                            top;
38526
38527                        if (checkbox) {
38528                            top = translateY + titleHeight + checkbox.y +
38529                                (this.scrollOffset || 0) + 3;
38530                            css(checkbox, {
38531                                left: (alignAttr.translateX + item.checkboxOffset +
38532                                    checkbox.x - 20) + 'px',
38533                                top: top + 'px',
38534                                display: top > translateY - 6 && top < translateY +
38535                                    clipHeight - 6 ? '' : 'none'
38536                            });
38537                        }
38538                    }, this);
38539                }
38540            },
38541
38542            /**
38543             * Render the legend title on top of the legend.
38544             *
38545             * @private
38546             */
38547            renderTitle: function() {
38548                var options = this.options,
38549                    padding = this.padding,
38550                    titleOptions = options.title,
38551                    titleHeight = 0,
38552                    bBox;
38553
38554                if (titleOptions.text) {
38555                    if (!this.title) {
38556                        this.title = this.chart.renderer.label(
38557                                titleOptions.text,
38558                                padding - 3,
38559                                padding - 4,
38560                                null,
38561                                null,
38562                                null,
38563                                options.useHTML,
38564                                null,
38565                                'legend-title'
38566                            )
38567                            .attr({
38568                                zIndex: 1
38569                            })
38570
38571                            .css(titleOptions.style)
38572
38573                            .add(this.group);
38574                    }
38575                    bBox = this.title.getBBox();
38576                    titleHeight = bBox.height;
38577                    this.offsetWidth = bBox.width; // #1717
38578                    this.contentGroup.attr({
38579                        translateY: titleHeight
38580                    });
38581                }
38582                this.titleHeight = titleHeight;
38583            },
38584
38585            /**
38586             * Set the legend item text.
38587             *
38588             * @param  {Series|Point} item
38589             *         The item for which to update the text in the legend.
38590             */
38591            setText: function(item) {
38592                var options = this.options;
38593                item.legendItem.attr({
38594                    text: options.labelFormat ?
38595                        H.format(options.labelFormat, item) : options.labelFormatter.call(item)
38596                });
38597            },
38598
38599            /**
38600             * Render a single specific legend item. Called internally from the `render`
38601             * function.
38602             *
38603             * @private
38604             * @param {Series|Point} item
38605             *        The item to render.
38606             */
38607            renderItem: function(item) {
38608                var legend = this,
38609                    chart = legend.chart,
38610                    renderer = chart.renderer,
38611                    options = legend.options,
38612                    horizontal = options.layout === 'horizontal',
38613                    symbolWidth = legend.symbolWidth,
38614                    symbolPadding = options.symbolPadding,
38615
38616                    itemStyle = legend.itemStyle,
38617                    itemHiddenStyle = legend.itemHiddenStyle,
38618
38619                    padding = legend.padding,
38620                    itemDistance = horizontal ? pick(options.itemDistance, 20) : 0,
38621                    ltr = !options.rtl,
38622                    itemHeight,
38623                    widthOption = options.width,
38624                    itemMarginBottom = options.itemMarginBottom || 0,
38625                    itemMarginTop = legend.itemMarginTop,
38626                    bBox,
38627                    itemWidth,
38628                    li = item.legendItem,
38629                    isSeries = !item.series,
38630                    series = !isSeries && item.series.drawLegendSymbol ?
38631                    item.series :
38632                    item,
38633                    seriesOptions = series.options,
38634                    showCheckbox = legend.createCheckboxForItem &&
38635                    seriesOptions &&
38636                    seriesOptions.showCheckbox,
38637                    // full width minus text width
38638                    itemExtraWidth = symbolWidth + symbolPadding + itemDistance +
38639                    (showCheckbox ? 20 : 0),
38640                    useHTML = options.useHTML,
38641                    fontSize = 12,
38642                    itemClassName = item.options.className;
38643
38644                if (!li) { // generate it once, later move it
38645
38646                    // Generate the group box, a group to hold the symbol and text. Text
38647                    // is to be appended in Legend class.
38648                    item.legendGroup = renderer.g('legend-item')
38649                        .addClass(
38650                            'highcharts-' + series.type + '-series ' +
38651                            'highcharts-color-' + item.colorIndex +
38652                            (itemClassName ? ' ' + itemClassName : '') +
38653                            (isSeries ? ' highcharts-series-' + item.index : '')
38654                        )
38655                        .attr({
38656                            zIndex: 1
38657                        })
38658                        .add(legend.scrollGroup);
38659
38660                    // Generate the list item text and add it to the group
38661                    item.legendItem = li = renderer.text(
38662                            '',
38663                            ltr ? symbolWidth + symbolPadding : -symbolPadding,
38664                            legend.baseline || 0,
38665                            useHTML
38666                        )
38667
38668                        // merge to prevent modifying original (#1021)
38669                        .css(merge(item.visible ? itemStyle : itemHiddenStyle))
38670
38671                        .attr({
38672                            align: ltr ? 'left' : 'right',
38673                            zIndex: 2
38674                        })
38675                        .add(item.legendGroup);
38676
38677                    // Get the baseline for the first item - the font size is equal for
38678                    // all
38679                    if (!legend.baseline) {
38680
38681                        fontSize = itemStyle.fontSize;
38682
38683                        legend.fontMetrics = renderer.fontMetrics(
38684                            fontSize,
38685                            li
38686                        );
38687                        legend.baseline = legend.fontMetrics.f + 3 + itemMarginTop;
38688                        li.attr('y', legend.baseline);
38689                    }
38690
38691                    // Draw the legend symbol inside the group box
38692                    legend.symbolHeight = options.symbolHeight || legend.fontMetrics.f;
38693                    series.drawLegendSymbol(legend, item);
38694
38695                    if (legend.setItemEvents) {
38696                        legend.setItemEvents(item, li, useHTML);
38697                    }
38698
38699                    // add the HTML checkbox on top
38700                    if (showCheckbox) {
38701                        legend.createCheckboxForItem(item);
38702                    }
38703                }
38704
38705                // Colorize the items
38706                legend.colorizeItem(item, item.visible);
38707
38708                // Take care of max width and text overflow (#6659)
38709
38710                if (!itemStyle.width) {
38711
38712                    li.css({
38713                        width: (
38714                            options.itemWidth ||
38715                            options.width ||
38716                            chart.spacingBox.width
38717                        ) - itemExtraWidth
38718                    });
38719
38720                }
38721
38722
38723                // Always update the text
38724                legend.setText(item);
38725
38726                // calculate the positions for the next line
38727                bBox = li.getBBox();
38728
38729                itemWidth = item.checkboxOffset =
38730                    options.itemWidth ||
38731                    item.legendItemWidth ||
38732                    bBox.width + itemExtraWidth;
38733                legend.itemHeight = itemHeight = Math.round(
38734                    item.legendItemHeight || bBox.height || legend.symbolHeight
38735                );
38736
38737                // If the item exceeds the width, start a new line
38738                if (
38739                    horizontal &&
38740                    legend.itemX - padding + itemWidth > (
38741                        widthOption || (
38742                            chart.spacingBox.width - 2 * padding - options.x
38743                        )
38744                    )
38745                ) {
38746                    legend.itemX = padding;
38747                    legend.itemY += itemMarginTop + legend.lastLineHeight +
38748                        itemMarginBottom;
38749                    legend.lastLineHeight = 0; // reset for next line (#915, #3976)
38750                }
38751
38752                // If the item exceeds the height, start a new column
38753                /*
38754                if (!horizontal && legend.itemY + options.y +
38755                		itemHeight > chart.chartHeight - spacingTop - spacingBottom) {
38756                	legend.itemY = legend.initialItemY;
38757                	legend.itemX += legend.maxItemWidth;
38758                	legend.maxItemWidth = 0;
38759                }
38760                */
38761
38762                // Set the edge positions
38763                legend.maxItemWidth = Math.max(legend.maxItemWidth, itemWidth);
38764                legend.lastItemY = itemMarginTop + legend.itemY + itemMarginBottom;
38765                legend.lastLineHeight = Math.max( // #915
38766                    itemHeight,
38767                    legend.lastLineHeight
38768                );
38769
38770                // cache the position of the newly generated or reordered items
38771                item._legendItemPos = [legend.itemX, legend.itemY];
38772
38773                // advance
38774                if (horizontal) {
38775                    legend.itemX += itemWidth;
38776
38777                } else {
38778                    legend.itemY += itemMarginTop + itemHeight + itemMarginBottom;
38779                    legend.lastLineHeight = itemHeight;
38780                }
38781
38782                // the width of the widest item
38783                legend.offsetWidth = widthOption || Math.max(
38784                    (
38785                        horizontal ? legend.itemX - padding - (item.checkbox ?
38786                            // decrease by itemDistance only when no checkbox #4853
38787                            0 :
38788                            itemDistance
38789                        ) : itemWidth
38790                    ) + padding,
38791                    legend.offsetWidth
38792                );
38793            },
38794
38795            /**
38796             * Get all items, which is one item per series for most series and one
38797             * item per point for pie series and its derivatives.
38798             *
38799             * @return {Array.<Series|Point>}
38800             *         The current items in the legend.
38801             */
38802            getAllItems: function() {
38803                var allItems = [];
38804                each(this.chart.series, function(series) {
38805                    var seriesOptions = series && series.options;
38806
38807                    // Handle showInLegend. If the series is linked to another series,
38808                    // defaults to false.
38809                    if (series && pick(
38810                            seriesOptions.showInLegend, !defined(seriesOptions.linkedTo) ? undefined : false, true
38811                        )) {
38812
38813                        // Use points or series for the legend item depending on
38814                        // legendType
38815                        allItems = allItems.concat(
38816                            series.legendItems ||
38817                            (
38818                                seriesOptions.legendType === 'point' ?
38819                                series.data :
38820                                series
38821                            )
38822                        );
38823                    }
38824                });
38825                return allItems;
38826            },
38827
38828            /**
38829             * Adjust the chart margins by reserving space for the legend on only one
38830             * side of the chart. If the position is set to a corner, top or bottom is
38831             * reserved for horizontal legends and left or right for vertical ones.
38832             *
38833             * @private
38834             */
38835            adjustMargins: function(margin, spacing) {
38836                var chart = this.chart,
38837                    options = this.options,
38838                    // Use the first letter of each alignment option in order to detect
38839                    // the side. (#4189 - use charAt(x) notation instead of [x] for IE7)
38840                    alignment = options.align.charAt(0) +
38841                    options.verticalAlign.charAt(0) +
38842                    options.layout.charAt(0);
38843
38844                if (!options.floating) {
38845
38846                    each([
38847                        /(lth|ct|rth)/,
38848                        /(rtv|rm|rbv)/,
38849                        /(rbh|cb|lbh)/,
38850                        /(lbv|lm|ltv)/
38851                    ], function(alignments, side) {
38852                        if (alignments.test(alignment) && !defined(margin[side])) {
38853                            // Now we have detected on which side of the chart we should
38854                            // reserve space for the legend
38855                            chart[marginNames[side]] = Math.max(
38856                                chart[marginNames[side]],
38857                                (
38858                                    chart.legend[
38859                                        (side + 1) % 2 ? 'legendHeight' : 'legendWidth'
38860                                    ] + [1, -1, -1, 1][side] * options[
38861                                        (side % 2) ? 'x' : 'y'
38862                                    ] +
38863                                    pick(options.margin, 12) +
38864                                    spacing[side]
38865                                )
38866                            );
38867                        }
38868                    });
38869                }
38870            },
38871
38872            /**
38873             * Render the legend. This method can be called both before and after
38874             * `chart.render`. If called after, it will only rearrange items instead
38875             * of creating new ones. Called internally on initial render and after
38876             * redraws.
38877             */
38878            render: function() {
38879                var legend = this,
38880                    chart = legend.chart,
38881                    renderer = chart.renderer,
38882                    legendGroup = legend.group,
38883                    allItems,
38884                    display,
38885                    legendWidth,
38886                    legendHeight,
38887                    box = legend.box,
38888                    options = legend.options,
38889                    padding = legend.padding;
38890
38891                legend.itemX = padding;
38892                legend.itemY = legend.initialItemY;
38893                legend.offsetWidth = 0;
38894                legend.lastItemY = 0;
38895
38896                if (!legendGroup) {
38897                    legend.group = legendGroup = renderer.g('legend')
38898                        .attr({
38899                            zIndex: 7
38900                        })
38901                        .add();
38902                    legend.contentGroup = renderer.g()
38903                        .attr({
38904                            zIndex: 1
38905                        }) // above background
38906                        .add(legendGroup);
38907                    legend.scrollGroup = renderer.g()
38908                        .add(legend.contentGroup);
38909                }
38910
38911                legend.renderTitle();
38912
38913                // add each series or point
38914                allItems = legend.getAllItems();
38915
38916                // sort by legendIndex
38917                stableSort(allItems, function(a, b) {
38918                    return ((a.options && a.options.legendIndex) || 0) -
38919                        ((b.options && b.options.legendIndex) || 0);
38920                });
38921
38922                // reversed legend
38923                if (options.reversed) {
38924                    allItems.reverse();
38925                }
38926
38927                legend.allItems = allItems;
38928                legend.display = display = !!allItems.length;
38929
38930                // render the items
38931                legend.lastLineHeight = 0;
38932                each(allItems, function(item) {
38933                    legend.renderItem(item);
38934                });
38935
38936                // Get the box
38937                legendWidth = (options.width || legend.offsetWidth) + padding;
38938                legendHeight = legend.lastItemY + legend.lastLineHeight +
38939                    legend.titleHeight;
38940                legendHeight = legend.handleOverflow(legendHeight);
38941                legendHeight += padding;
38942
38943                // Draw the border and/or background
38944                if (!box) {
38945                    legend.box = box = renderer.rect()
38946                        .addClass('highcharts-legend-box')
38947                        .attr({
38948                            r: options.borderRadius
38949                        })
38950                        .add(legendGroup);
38951                    box.isNew = true;
38952                }
38953
38954
38955                // Presentational
38956                box
38957                    .attr({
38958                        stroke: options.borderColor,
38959                        'stroke-width': options.borderWidth || 0,
38960                        fill: options.backgroundColor || 'none'
38961                    })
38962                    .shadow(options.shadow);
38963
38964
38965                if (legendWidth > 0 && legendHeight > 0) {
38966                    box[box.isNew ? 'attr' : 'animate'](
38967                        box.crisp.call({}, { // #7260
38968                            x: 0,
38969                            y: 0,
38970                            width: legendWidth,
38971                            height: legendHeight
38972                        }, box.strokeWidth())
38973                    );
38974                    box.isNew = false;
38975                }
38976
38977                // hide the border if no items
38978                box[display ? 'show' : 'hide']();
38979
38980
38981
38982                legend.legendWidth = legendWidth;
38983                legend.legendHeight = legendHeight;
38984
38985                // Now that the legend width and height are established, put the items
38986                // in the final position
38987                each(allItems, function(item) {
38988                    legend.positionItem(item);
38989                });
38990
38991                if (display) {
38992                    legendGroup.align(merge(options, {
38993                        width: legendWidth,
38994                        height: legendHeight
38995                    }), true, 'spacingBox');
38996                }
38997
38998                if (!chart.isResizing) {
38999                    this.positionCheckboxes();
39000                }
39001            },
39002
39003            /**
39004             * Set up the overflow handling by adding navigation with up and down arrows
39005             * below the legend.
39006             *
39007             * @private
39008             */
39009            handleOverflow: function(legendHeight) {
39010                var legend = this,
39011                    chart = this.chart,
39012                    renderer = chart.renderer,
39013                    options = this.options,
39014                    optionsY = options.y,
39015                    alignTop = options.verticalAlign === 'top',
39016                    padding = this.padding,
39017                    spaceHeight = chart.spacingBox.height +
39018                    (alignTop ? -optionsY : optionsY) - padding,
39019                    maxHeight = options.maxHeight,
39020                    clipHeight,
39021                    clipRect = this.clipRect,
39022                    navOptions = options.navigation,
39023                    animation = pick(navOptions.animation, true),
39024                    arrowSize = navOptions.arrowSize || 12,
39025                    nav = this.nav,
39026                    pages = this.pages,
39027                    lastY,
39028                    allItems = this.allItems,
39029                    clipToHeight = function(height) {
39030                        if (typeof height === 'number') {
39031                            clipRect.attr({
39032                                height: height
39033                            });
39034                        } else if (clipRect) { // Reset (#5912)
39035                            legend.clipRect = clipRect.destroy();
39036                            legend.contentGroup.clip();
39037                        }
39038
39039                        // useHTML
39040                        if (legend.contentGroup.div) {
39041                            legend.contentGroup.div.style.clip = height ?
39042                                'rect(' + padding + 'px,9999px,' +
39043                                (padding + height) + 'px,0)' :
39044                                'auto';
39045                        }
39046                    };
39047
39048
39049                // Adjust the height
39050                if (
39051                    options.layout === 'horizontal' &&
39052                    options.verticalAlign !== 'middle' &&
39053                    !options.floating
39054                ) {
39055                    spaceHeight /= 2;
39056                }
39057                if (maxHeight) {
39058                    spaceHeight = Math.min(spaceHeight, maxHeight);
39059                }
39060
39061                // Reset the legend height and adjust the clipping rectangle
39062                pages.length = 0;
39063                if (legendHeight > spaceHeight && navOptions.enabled !== false) {
39064
39065                    this.clipHeight = clipHeight =
39066                        Math.max(spaceHeight - 20 - this.titleHeight - padding, 0);
39067                    this.currentPage = pick(this.currentPage, 1);
39068                    this.fullHeight = legendHeight;
39069
39070                    // Fill pages with Y positions so that the top of each a legend item
39071                    // defines the scroll top for each page (#2098)
39072                    each(allItems, function(item, i) {
39073                        var y = item._legendItemPos[1],
39074                            h = Math.round(item.legendItem.getBBox().height),
39075                            len = pages.length;
39076
39077                        if (!len || (y - pages[len - 1] > clipHeight &&
39078                                (lastY || y) !== pages[len - 1])) {
39079                            pages.push(lastY || y);
39080                            len++;
39081                        }
39082
39083                        if (i === allItems.length - 1 &&
39084                            y + h - pages[len - 1] > clipHeight) {
39085                            pages.push(y);
39086                        }
39087                        if (y !== lastY) {
39088                            lastY = y;
39089                        }
39090                    });
39091
39092                    // Only apply clipping if needed. Clipping causes blurred legend in
39093                    // PDF export (#1787)
39094                    if (!clipRect) {
39095                        clipRect = legend.clipRect =
39096                            renderer.clipRect(0, padding, 9999, 0);
39097                        legend.contentGroup.clip(clipRect);
39098                    }
39099
39100                    clipToHeight(clipHeight);
39101
39102                    // Add navigation elements
39103                    if (!nav) {
39104                        this.nav = nav = renderer.g()
39105                            .attr({
39106                                zIndex: 1
39107                            })
39108                            .add(this.group);
39109
39110                        this.up = renderer
39111                            .symbol(
39112                                'triangle',
39113                                0,
39114                                0,
39115                                arrowSize,
39116                                arrowSize
39117                            )
39118                            .on('click', function() {
39119                                legend.scroll(-1, animation);
39120                            })
39121                            .add(nav);
39122
39123                        this.pager = renderer.text('', 15, 10)
39124                            .addClass('highcharts-legend-navigation')
39125
39126                            .css(navOptions.style)
39127
39128                            .add(nav);
39129
39130                        this.down = renderer
39131                            .symbol(
39132                                'triangle-down',
39133                                0,
39134                                0,
39135                                arrowSize,
39136                                arrowSize
39137                            )
39138                            .on('click', function() {
39139                                legend.scroll(1, animation);
39140                            })
39141                            .add(nav);
39142                    }
39143
39144                    // Set initial position
39145                    legend.scroll(0);
39146
39147                    legendHeight = spaceHeight;
39148
39149                    // Reset
39150                } else if (nav) {
39151                    clipToHeight();
39152                    this.nav = nav.destroy(); // #6322
39153                    this.scrollGroup.attr({
39154                        translateY: 1
39155                    });
39156                    this.clipHeight = 0; // #1379
39157                }
39158
39159                return legendHeight;
39160            },
39161
39162            /**
39163             * Scroll the legend by a number of pages.
39164             * @param  {Number} scrollBy
39165             *         The number of pages to scroll.
39166             * @param  {AnimationOptions} animation
39167             *         Whether and how to apply animation.
39168             */
39169            scroll: function(scrollBy, animation) {
39170                var pages = this.pages,
39171                    pageCount = pages.length,
39172                    currentPage = this.currentPage + scrollBy,
39173                    clipHeight = this.clipHeight,
39174                    navOptions = this.options.navigation,
39175                    pager = this.pager,
39176                    padding = this.padding;
39177
39178                // When resizing while looking at the last page
39179                if (currentPage > pageCount) {
39180                    currentPage = pageCount;
39181                }
39182
39183                if (currentPage > 0) {
39184
39185                    if (animation !== undefined) {
39186                        setAnimation(animation, this.chart);
39187                    }
39188
39189                    this.nav.attr({
39190                        translateX: padding,
39191                        translateY: clipHeight + this.padding + 7 + this.titleHeight,
39192                        visibility: 'visible'
39193                    });
39194                    this.up.attr({
39195                        'class': currentPage === 1 ?
39196                            'highcharts-legend-nav-inactive' : 'highcharts-legend-nav-active'
39197                    });
39198                    pager.attr({
39199                        text: currentPage + '/' + pageCount
39200                    });
39201                    this.down.attr({
39202                        'x': 18 + this.pager.getBBox().width, // adjust to text width
39203                        'class': currentPage === pageCount ?
39204                            'highcharts-legend-nav-inactive' : 'highcharts-legend-nav-active'
39205                    });
39206
39207
39208                    this.up
39209                        .attr({
39210                            fill: currentPage === 1 ?
39211                                navOptions.inactiveColor : navOptions.activeColor
39212                        })
39213                        .css({
39214                            cursor: currentPage === 1 ? 'default' : 'pointer'
39215                        });
39216                    this.down
39217                        .attr({
39218                            fill: currentPage === pageCount ?
39219                                navOptions.inactiveColor : navOptions.activeColor
39220                        })
39221                        .css({
39222                            cursor: currentPage === pageCount ? 'default' : 'pointer'
39223                        });
39224
39225
39226                    this.scrollOffset = -pages[currentPage - 1] + this.initialItemY;
39227
39228                    this.scrollGroup.animate({
39229                        translateY: this.scrollOffset
39230                    });
39231
39232                    this.currentPage = currentPage;
39233                    this.positionCheckboxes();
39234                }
39235
39236            }
39237
39238        };
39239
39240        /*
39241         * LegendSymbolMixin
39242         */
39243
39244        H.LegendSymbolMixin = {
39245
39246            /**
39247             * Get the series' symbol in the legend
39248             *
39249             * @param {Object} legend The legend object
39250             * @param {Object} item The series (this) or point
39251             */
39252            drawRectangle: function(legend, item) {
39253                var options = legend.options,
39254                    symbolHeight = legend.symbolHeight,
39255                    square = options.squareSymbol,
39256                    symbolWidth = square ? symbolHeight : legend.symbolWidth;
39257
39258                item.legendSymbol = this.chart.renderer.rect(
39259                        square ? (legend.symbolWidth - symbolHeight) / 2 : 0,
39260                        legend.baseline - symbolHeight + 1, // #3988
39261                        symbolWidth,
39262                        symbolHeight,
39263                        pick(legend.options.symbolRadius, symbolHeight / 2)
39264                    )
39265                    .addClass('highcharts-point')
39266                    .attr({
39267                        zIndex: 3
39268                    }).add(item.legendGroup);
39269
39270            },
39271
39272            /**
39273             * Get the series' symbol in the legend. This method should be overridable
39274             * to create custom symbols through
39275             * Highcharts.seriesTypes[type].prototype.drawLegendSymbols.
39276             *
39277             * @param {Object} legend The legend object
39278             */
39279            drawLineMarker: function(legend) {
39280
39281                var options = this.options,
39282                    markerOptions = options.marker,
39283                    radius,
39284                    legendSymbol,
39285                    symbolWidth = legend.symbolWidth,
39286                    symbolHeight = legend.symbolHeight,
39287                    generalRadius = symbolHeight / 2,
39288                    renderer = this.chart.renderer,
39289                    legendItemGroup = this.legendGroup,
39290                    verticalCenter = legend.baseline -
39291                    Math.round(legend.fontMetrics.b * 0.3),
39292                    attr = {};
39293
39294                // Draw the line
39295
39296                attr = {
39297                    'stroke-width': options.lineWidth || 0
39298                };
39299                if (options.dashStyle) {
39300                    attr.dashstyle = options.dashStyle;
39301                }
39302
39303
39304                this.legendLine = renderer.path([
39305                        'M',
39306                        0,
39307                        verticalCenter,
39308                        'L',
39309                        symbolWidth,
39310                        verticalCenter
39311                    ])
39312                    .addClass('highcharts-graph')
39313                    .attr(attr)
39314                    .add(legendItemGroup);
39315
39316                // Draw the marker
39317                if (markerOptions && markerOptions.enabled !== false) {
39318
39319                    // Do not allow the marker to be larger than the symbolHeight
39320                    radius = Math.min(
39321                        pick(markerOptions.radius, generalRadius),
39322                        generalRadius
39323                    );
39324
39325                    // Restrict symbol markers size
39326                    if (this.symbol.indexOf('url') === 0) {
39327                        markerOptions = merge(markerOptions, {
39328                            width: symbolHeight,
39329                            height: symbolHeight
39330                        });
39331                        radius = 0;
39332                    }
39333
39334                    this.legendSymbol = legendSymbol = renderer.symbol(
39335                            this.symbol,
39336                            (symbolWidth / 2) - radius,
39337                            verticalCenter - radius,
39338                            2 * radius,
39339                            2 * radius,
39340                            markerOptions
39341                        )
39342                        .addClass('highcharts-point')
39343                        .add(legendItemGroup);
39344                    legendSymbol.isMarker = true;
39345                }
39346            }
39347        };
39348
39349        // Workaround for #2030, horizontal legend items not displaying in IE11 Preview,
39350        // and for #2580, a similar drawing flaw in Firefox 26.
39351        // Explore if there's a general cause for this. The problem may be related
39352        // to nested group elements, as the legend item texts are within 4 group
39353        // elements.
39354        if (/Trident\/7\.0/.test(win.navigator.userAgent) || isFirefox) {
39355            wrap(Highcharts.Legend.prototype, 'positionItem', function(proceed, item) {
39356                var legend = this,
39357                    // If chart destroyed in sync, this is undefined (#2030)
39358                    runPositionItem = function() {
39359                        if (item._legendItemPos) {
39360                            proceed.call(legend, item);
39361                        }
39362                    };
39363
39364                // Do it now, for export and to get checkbox placement
39365                runPositionItem();
39366
39367                // Do it after to work around the core issue
39368                setTimeout(runPositionItem);
39369            });
39370        }
39371
39372    }
39372(Highcharts));
39373    (function(H) {
39374        /**
39375         * (c) 2010-2017 Torstein Honsi
39376         *
39377         * License: www.highcharts.com/license
39378         */
39379        var addEvent = H.addEvent,
39380            animate = H.animate,
39381            animObject = H.animObject,
39382            attr = H.attr,
39383            doc = H.doc,
39384            Axis = H.Axis, // @todo add as requirement
39385            createElement = H.createElement,
39386            defaultOptions = H.defaultOptions,
39387            discardElement = H.discardElement,
39388            charts = H.charts,
39389            css = H.css,
39390            defined = H.defined,
39391            each = H.each,
39392            extend = H.extend,
39393            find = H.find,
39394            fireEvent = H.fireEvent,
39395            grep = H.grep,
39396            isNumber = H.isNumber,
39397            isObject = H.isObject,
39398            isString = H.isString,
39399            Legend = H.Legend, // @todo add as requirement
39400            marginNames = H.marginNames,
39401            merge = H.merge,
39402            objectEach = H.objectEach,
39403            Pointer = H.Pointer, // @todo add as requirement
39404            pick = H.pick,
39405            pInt = H.pInt,
39406            removeEvent = H.removeEvent,
39407            seriesTypes = H.seriesTypes,
39408            splat = H.splat,
39409            svg = H.svg,
39410            syncTimeout = H.syncTimeout,
39411            win = H.win;
39412        /**
39413         * The Chart class. The recommended constructor is {@link Highcharts#chart}.
39414         * @class Highcharts.Chart
39415         * @param  {String|HTMLDOMElement} renderTo
39416         *         The DOM element to render to, or its id.
39417         * @param  {Options} options
39418         *         The chart options structure.
39419         * @param  {Function} [callback]
39420         *         Function to run when the chart has loaded and and all external images
39421         *         are loaded. Defining a {@link
39422         *         https://api.highcharts.com/highcharts/chart.events.load|chart.event.load}
39423         *         handler is equivalent.
39424         *
39425         * @example
39426         * var chart = Highcharts.chart('container', {
39427         * 	   title: {
39428         * 	   	   text: 'My chart'
39429         * 	   },
39430         * 	   series: [{
39431         * 	       data: [1, 3, 2, 4]
39432         * 	   }]
39433         * })
39434         */
39435        var Chart = H.Chart = function() {
39436            this.getArgs.apply(this, arguments);
39437        };
39438
39439        /**
39440         * Factory function for basic charts. 
39441         *
39442         * @function #chart
39443         * @memberOf Highcharts
39444         * @param  {String|HTMLDOMElement} renderTo - The DOM element to render to, or
39445         * its id.
39446         * @param  {Options} options - The chart options structure.
39447         * @param  {Function} [callback] - Function to run when the chart has loaded and
39448         * and all external images are loaded. Defining a {@link
39449         * https://api.highcharts.com/highcharts/chart.events.load|chart.event.load}
39450         * handler is equivalent.
39451         * @return {Highcharts.Chart} - Returns the Chart object.
39452         *
39453         * @example
39454         * // Render a chart in to div#container
39455         * var chart = Highcharts.chart('container', {
39456         *     title: {
39457         *         text: 'My chart'
39458         *     },
39459         *     series: [{
39460         *         data: [1, 3, 2, 4]
39461         *     }]
39462         * });
39463         */
39464        H.chart = function(a, b, c) {
39465            return new Chart(a, b, c);
39466        };
39467
39468        extend(Chart.prototype, /** @lends Highcharts.Chart.prototype */ {
39469
39470            // Hook for adding callbacks in modules
39471            callbacks: [],
39472
39473            /**
39474             * Handle the arguments passed to the constructor.
39475             *
39476             * @private
39477             * @returns {Array} Arguments without renderTo
39478             */
39479            getArgs: function() {
39480                var args = [].slice.call(arguments);
39481
39482                // Remove the optional first argument, renderTo, and
39483                // set it on this.
39484                if (isString(args[0]) || args[0].nodeName) {
39485                    this.renderTo = args.shift();
39486                }
39487                this.init(args[0], args[1]);
39488            },
39489
39490            /**
39491             * Overridable function that initializes the chart. The constructor's
39492             * arguments are passed on directly.
39493             */
39494            init: function(userOptions, callback) {
39495
39496                // Handle regular options
39497                var options,
39498                    type,
39499                    seriesOptions = userOptions.series, // skip merging data points to increase performance
39500                    userPlotOptions = userOptions.plotOptions || {};
39501
39502                userOptions.series = null;
39503                options = merge(defaultOptions, userOptions); // do the merge
39504
39505                // Override (by copy of user options) or clear tooltip options
39506                // in chart.options.plotOptions (#6218)
39507                for (type in options.plotOptions) {
39508                    options.plotOptions[type].tooltip = (
39509                        userPlotOptions[type] &&
39510                        merge(userPlotOptions[type].tooltip) // override by copy
39511                    ) || undefined; // or clear
39512                }
39513                // User options have higher priority than default options (#6218).
39514                // In case of exporting: path is changed
39515                options.tooltip.userOptions = (userOptions.chart &&
39516                        userOptions.chart.forExport && userOptions.tooltip.userOptions) ||
39517                    userOptions.tooltip;
39518
39519                options.series = userOptions.series = seriesOptions; // set back the series data
39520                this.userOptions = userOptions;
39521
39522                var optionsChart = options.chart;
39523
39524                var chartEvents = optionsChart.events;
39525
39526                this.margin = [];
39527                this.spacing = [];
39528
39529                this.bounds = {
39530                    h: {},
39531                    v: {}
39532                }; // Pixel data bounds for touch zoom
39533
39534                // An array of functions that returns labels that should be considered
39535                // for anti-collision
39536                this.labelCollectors = [];
39537
39538                this.callback = callback;
39539                this.isResizing = 0;
39540
39541                /**
39542                 * The options structure for the chart. It contains members for the sub
39543                 * elements like series, legend, tooltip etc.
39544                 *
39545                 * @memberof Highcharts.Chart
39546                 * @name options
39547                 * @type {Options}
39548                 */
39549                this.options = options;
39550                /**
39551                 * All the axes in the chart.
39552                 *
39553                 * @memberof Highcharts.Chart
39554                 * @name axes
39555                 * @see  Highcharts.Chart.xAxis
39556                 * @see  Highcharts.Chart.yAxis
39557                 * @type {Array.<Highcharts.Axis>}
39558                 */
39559                this.axes = [];
39560
39561                /**
39562                 * All the current series in the chart.
39563                 *
39564                 * @memberof Highcharts.Chart
39565                 * @name series
39566                 * @type {Array.<Highcharts.Series>}
39567                 */
39568                this.series = [];
39569
39570                /**
39571                 * The chart title. The title has an `update` method that allows
39572                 * modifying the options directly or indirectly via `chart.update`.
39573                 *
39574                 * @memberof Highcharts.Chart
39575                 * @name title
39576                 * @type Object
39577                 *
39578                 * @sample highcharts/members/title-update/
39579                 *         Updating titles
39580                 */
39581
39582                /**
39583                 * The chart subtitle. The subtitle has an `update` method that allows
39584                 * modifying the options directly or indirectly via `chart.update`.
39585                 *
39586                 * @memberof Highcharts.Chart
39587                 * @name subtitle
39588                 * @type Object
39589                 */
39590
39591
39592
39593                this.hasCartesianSeries = optionsChart.showAxes;
39594
39595                var chart = this;
39596
39597                // Add the chart to the global lookup
39598                chart.index = charts.length;
39599
39600                charts.push(chart);
39601                H.chartCount++;
39602
39603                // Chart event handlers
39604                if (chartEvents) {
39605                    objectEach(chartEvents, function(event, eventType) {
39606                        addEvent(chart, eventType, event);
39607                    });
39608                }
39609
39610                /**
39611                 * A collection of the X axes in the chart.
39612                 * @type {Array.<Highcharts.Axis>}
39613                 * @name xAxis
39614                 * @memberOf Highcharts.Chart
39615                 */
39616                chart.xAxis = [];
39617                /**
39618                 * A collection of the Y axes in the chart.
39619                 * @type {Array.<Highcharts.Axis>}
39620                 * @name yAxis
39621                 * @memberOf Highcharts.Chart
39622                 */
39623                chart.yAxis = [];
39624
39625                chart.pointCount = chart.colorCounter = chart.symbolCounter = 0;
39626
39627                chart.firstRender();
39628            },
39629
39630            /**
39631             * Internal function to unitialize an individual series.
39632             *
39633             * @private
39634             */
39635            initSeries: function(options) {
39636                var chart = this,
39637                    optionsChart = chart.options.chart,
39638                    type = options.type || optionsChart.type || optionsChart.defaultSeriesType,
39639                    series,
39640                    Constr = seriesTypes[type];
39641
39642                // No such series type
39643                if (!Constr) {
39644                    H.error(17, true);
39645                }
39646
39647                series = new Constr();
39648                series.init(this, options);
39649                return series;
39650            },
39651
39652            /**
39653             * Order all series above a given index. When series are added and ordered
39654             * by configuration, only the last series is handled (#248, #1123, #2456,
39655             * #6112). This function is called on series initialization and destroy.
39656             *
39657             * @private
39658             *
39659             * @param  {number} fromIndex
39660             *         If this is given, only the series above this index are handled.
39661             */
39662            orderSeries: function(fromIndex) {
39663                var series = this.series,
39664                    i = fromIndex || 0;
39665                for (; i < series.length; i++) {
39666                    if (series[i]) {
39667                        series[i].index = i;
39668                        series[i].name = series[i].name ||
39669                            'Series ' + (series[i].index + 1);
39670                    }
39671                }
39672            },
39673
39674            /**
39675             * Check whether a given point is within the plot area.
39676             *
39677             * @param  {Number} plotX
39678             *         Pixel x relative to the plot area.
39679             * @param  {Number} plotY
39680             *         Pixel y relative to the plot area.
39681             * @param  {Boolean} inverted
39682             *         Whether the chart is inverted.
39683             *
39684             * @return {Boolean}
39685             *         Returns true if the given point is inside the plot area.
39686             */
39687            isInsidePlot: function(plotX, plotY, inverted) {
39688                var x = inverted ? plotY : plotX,
39689                    y = inverted ? plotX : plotY;
39690
39691                return x >= 0 &&
39692                    x <= this.plotWidth &&
39693                    y >= 0 &&
39694                    y <= this.plotHeight;
39695            },
39696
39697            /**
39698             * Redraw the chart after changes have been done to the data, axis extremes
39699             * chart size or chart elements. All methods for updating axes, series or
39700             * points have a parameter for redrawing the chart. This is `true` by
39701             * default. But in many cases you want to do more than one operation on the
39702             * chart before redrawing, for example add a number of points. In those
39703             * cases it is a waste of resources to redraw the chart for each new point
39704             * added. So you add the points and call `chart.redraw()` after.
39705             *
39706             * @param  {AnimationOptions} animation
39707             *         If or how to apply animation to the redraw.
39708             */
39709            redraw: function(animation) {
39710                var chart = this,
39711                    axes = chart.axes,
39712                    series = chart.series,
39713                    pointer = chart.pointer,
39714                    legend = chart.legend,
39715                    redrawLegend = chart.isDirtyLegend,
39716                    hasStackedSeries,
39717                    hasDirtyStacks,
39718                    hasCartesianSeries = chart.hasCartesianSeries,
39719                    isDirtyBox = chart.isDirtyBox,
39720                    i,
39721                    serie,
39722                    renderer = chart.renderer,
39723                    isHiddenChart = renderer.isHidden(),
39724                    afterRedraw = [];
39725
39726                // Handle responsive rules, not only on resize (#6130)
39727                if (chart.setResponsive) {
39728                    chart.setResponsive(false);
39729                }
39730
39731                H.setAnimation(animation, chart);
39732
39733                if (isHiddenChart) {
39734                    chart.temporaryDisplay();
39735                }
39736
39737                // Adjust title layout (reflow multiline text)
39738                chart.layOutTitles();
39739
39740                // link stacked series
39741                i = series.length;
39742                while (i--) {
39743                    serie = series[i];
39744
39745                    if (serie.options.stacking) {
39746                        hasStackedSeries = true;
39747
39748                        if (serie.isDirty) {
39749                            hasDirtyStacks = true;
39750                            break;
39751                        }
39752                    }
39753                }
39754                if (hasDirtyStacks) { // mark others as dirty
39755                    i = series.length;
39756                    while (i--) {
39757                        serie = series[i];
39758                        if (serie.options.stacking) {
39759                            serie.isDirty = true;
39760                        }
39761                    }
39762                }
39763
39764                // Handle updated data in the series
39765                each(series, function(serie) {
39766                    if (serie.isDirty) {
39767                        if (serie.options.legendType === 'point') {
39768                            if (serie.updateTotals) {
39769                                serie.updateTotals();
39770                            }
39771                            redrawLegend = true;
39772                        }
39773                    }
39774                    if (serie.isDirtyData) {
39775                        fireEvent(serie, 'updatedData');
39776                    }
39777                });
39778
39779                // handle added or removed series
39780                if (redrawLegend && legend.options.enabled) { // series or pie points are added or removed
39781                    // draw legend graphics
39782                    legend.render();
39783
39784                    chart.isDirtyLegend = false;
39785                }
39786
39787                // reset stacks
39788                if (hasStackedSeries) {
39789                    chart.getStacks();
39790                }
39791
39792
39793                if (hasCartesianSeries) {
39794                    // set axes scales
39795                    each(axes, function(axis) {
39796                        axis.updateNames();
39797                        axis.setScale();
39798                    });
39799                }
39800
39801                chart.getMargins(); // #3098
39802
39803                if (hasCartesianSeries) {
39804                    // If one axis is dirty, all axes must be redrawn (#792, #2169)
39805                    each(axes, function(axis) {
39806                        if (axis.isDirty) {
39807                            isDirtyBox = true;
39808                        }
39809                    });
39810
39811                    // redraw axes
39812                    each(axes, function(axis) {
39813
39814                        // Fire 'afterSetExtremes' only if extremes are set
39815                        var key = axis.min + ',' + axis.max;
39816                        if (axis.extKey !== key) { // #821, #4452
39817                            axis.extKey = key;
39818                            afterRedraw.push(function() { // prevent a recursive call to chart.redraw() (#1119)
39819                                fireEvent(axis, 'afterSetExtremes', extend(axis.eventArgs, axis.getExtremes())); // #747, #751
39820                                delete axis.eventArgs;
39821                            });
39822                        }
39823                        if (isDirtyBox || hasStackedSeries) {
39824                            axis.redraw();
39825                        }
39826                    });
39827                }
39828
39829                // the plot areas size has changed
39830                if (isDirtyBox) {
39831                    chart.drawChartBox();
39832                }
39833
39834                // Fire an event before redrawing series, used by the boost module to
39835                // clear previous series renderings.
39836                fireEvent(chart, 'predraw');
39837
39838                // redraw affected series
39839                each(series, function(serie) {
39840                    if ((isDirtyBox || serie.isDirty) && serie.visible) {
39841                        serie.redraw();
39842                    }
39843                    // Set it here, otherwise we will have unlimited 'updatedData' calls
39844                    // for a hidden series after setData(). Fixes #6012
39845                    serie.isDirtyData = false;
39846                });
39847
39848                // move tooltip or reset
39849                if (pointer) {
39850                    pointer.reset(true);
39851                }
39852
39853                // redraw if canvas
39854                renderer.draw();
39855
39856                // Fire the events
39857                fireEvent(chart, 'redraw');
39858                fireEvent(chart, 'render');
39859
39860                if (isHiddenChart) {
39861                    chart.temporaryDisplay(true);
39862                }
39863
39864                // Fire callbacks that are put on hold until after the redraw
39865                each(afterRedraw, function(callback) {
39866                    callback.call();
39867                });
39868            },
39869
39870            /**
39871             * Get an axis, series or point object by `id` as given in the configuration
39872             * options. Returns `undefined` if no item is found.
39873             * @param id {String} The id as given in the configuration options.
39874             * @return {Highcharts.Axis|Highcharts.Series|Highcharts.Point|undefined}
39875             *         The retrieved item.
39876             * @sample highcharts/plotoptions/series-id/
39877             *         Get series by id
39878             */
39879            get: function(id) {
39880
39881                var ret,
39882                    series = this.series,
39883                    i;
39884
39885                function itemById(item) {
39886                    return item.id === id || (item.options && item.options.id === id);
39887                }
39888
39889                ret =
39890                    // Search axes
39891                    find(this.axes, itemById) ||
39892
39893                    // Search series
39894                    find(this.series, itemById);
39895
39896                // Search points
39897                for (i = 0; !ret && i < series.length; i++) {
39898                    ret = find(series[i].points || [], itemById);
39899                }
39900
39901                return ret;
39902            },
39903
39904            /**
39905             * Create the Axis instances based on the config options.
39906             *
39907             * @private
39908             */
39909            getAxes: function() {
39910                var chart = this,
39911                    options = this.options,
39912                    xAxisOptions = options.xAxis = splat(options.xAxis || {}),
39913                    yAxisOptions = options.yAxis = splat(options.yAxis || {}),
39914                    optionsArray;
39915
39916                // make sure the options are arrays and add some members
39917                each(xAxisOptions, function(axis, i) {
39918                    axis.index = i;
39919                    axis.isX = true;
39920                });
39921
39922                each(yAxisOptions, function(axis, i) {
39923                    axis.index = i;
39924                });
39925
39926                // concatenate all axis options into one array
39927                optionsArray = xAxisOptions.concat(yAxisOptions);
39928
39929                each(optionsArray, function(axisOptions) {
39930                    new Axis(chart, axisOptions); // eslint-disable-line no-new
39931                });
39932            },
39933
39934
39935            /**
39936             * Returns an array of all currently selected points in the chart. Points
39937             * can be selected by clicking or programmatically by the {@link
39938             * Highcharts.Point#select} function.
39939             *
39940             * @return {Array.<Highcharts.Point>}
39941             *         The currently selected points.
39942             *
39943             * @sample highcharts/plotoptions/series-allowpointselect-line/
39944             *         Get selected points
39945             */
39946            getSelectedPoints: function() {
39947                var points = [];
39948                each(this.series, function(serie) {
39949                    // series.data - for points outside of viewed range (#6445)
39950                    points = points.concat(grep(serie.data || [], function(point) {
39951                        return point.selected;
39952                    }));
39953                });
39954                return points;
39955            },
39956
39957            /**
39958             * Returns an array of all currently selected series in the chart. Series
39959             * can be selected either programmatically by the {@link
39960             * Highcharts.Series#select} function or by checking the checkbox next to
39961             * the legend item if {@link
39962             * https://api.highcharts.com/highcharts/plotOptions.series.showCheckbox|
39963             * series.showCheckBox} is true.
39964             * 
39965             * @return {Array.<Highcharts.Series>}
39966             *         The currently selected series.
39967             *
39968             * @sample highcharts/members/chart-getselectedseries/
39969             *         Get selected series
39970             */
39971            getSelectedSeries: function() {
39972                return grep(this.series, function(serie) {
39973                    return serie.selected;
39974                });
39975            },
39976
39977            /**
39978             * Set a new title or subtitle for the chart.
39979             *
39980             * @param  titleOptions {TitleOptions}
39981             *         New title options. The title text itself is set by the
39982             *         `titleOptions.text` property.
39983             * @param  subtitleOptions {SubtitleOptions}
39984             *         New subtitle options. The subtitle text itself is set by the
39985             *         `subtitleOptions.text` property.
39986             * @param  redraw {Boolean}
39987             *         Whether to redraw the chart or wait for a later call to 
39988             *         `chart.redraw()`.
39989             *
39990             * @sample highcharts/members/chart-settitle/ Set title text and styles
39991             *
39992             */
39993            setTitle: function(titleOptions, subtitleOptions, redraw) {
39994                var chart = this,
39995                    options = chart.options,
39996                    chartTitleOptions,
39997                    chartSubtitleOptions;
39998
39999                chartTitleOptions = options.title = merge(
40000
40001                    // Default styles
40002                    {
40003                        style: {
40004                            color: '#333333',
40005                            fontSize: options.isStock ? '16px' : '18px' // #2944
40006                        }
40007                    },
40008
40009                    options.title,
40010                    titleOptions
40011                );
40012                chartSubtitleOptions = options.subtitle = merge(
40013
40014                    // Default styles
40015                    {
40016                        style: {
40017                            color: '#666666'
40018                        }
40019                    },
40020
40021                    options.subtitle,
40022                    subtitleOptions
40023                );
40024
40025                // add title and subtitle
40026                each([
40027                    ['title', titleOptions, chartTitleOptions],
40028                    ['subtitle', subtitleOptions, chartSubtitleOptions]
40029                ], function(arr, i) {
40030                    var name = arr[0],
40031                        title = chart[name],
40032                        titleOptions = arr[1],
40033                        chartTitleOptions = arr[2];
40034
40035                    if (title && titleOptions) {
40036                        chart[name] = title = title.destroy(); // remove old
40037                    }
40038
40039                    if (chartTitleOptions && !title) {
40040                        chart[name] = chart.renderer.text(
40041                                chartTitleOptions.text,
40042                                0,
40043                                0,
40044                                chartTitleOptions.useHTML
40045                            )
40046                            .attr({
40047                                align: chartTitleOptions.align,
40048                                'class': 'highcharts-' + name,
40049                                zIndex: chartTitleOptions.zIndex || 4
40050                            })
40051                            .add();
40052
40053                        // Update methods, shortcut to Chart.setTitle
40054                        chart[name].update = function(o) {
40055                            chart.setTitle(!i && o, i && o);
40056                        };
40057
40058
40059                        // Presentational
40060                        chart[name].css(chartTitleOptions.style);
40061
40062
40063                    }
40064                });
40065                chart.layOutTitles(redraw);
40066            },
40067
40068            /**
40069             * Internal function to lay out the chart titles and cache the full offset
40070             * height for use in `getMargins`. The result is stored in 
40071             * `this.titleOffset`.
40072             *
40073             * @private
40074             */
40075            layOutTitles: function(redraw) {
40076                var titleOffset = 0,
40077                    requiresDirtyBox,
40078                    renderer = this.renderer,
40079                    spacingBox = this.spacingBox;
40080
40081                // Lay out the title and the subtitle respectively
40082                each(['title', 'subtitle'], function(key) {
40083                    var title = this[key],
40084                        titleOptions = this.options[key],
40085                        offset = key === 'title' ? -3 :
40086                        // Floating subtitle (#6574)
40087                        titleOptions.verticalAlign ? 0 : titleOffset + 2,
40088                        titleSize;
40089
40090                    if (title) {
40091
40092                        titleSize = titleOptions.style.fontSize;
40093
40094                        titleSize = renderer.fontMetrics(titleSize, title).b;
40095
40096                        title
40097                            .css({
40098                                width: (titleOptions.width ||
40099                                    spacingBox.width + titleOptions.widthAdjust) + 'px'
40100                            })
40101                            .align(extend({
40102                                y: offset + titleSize
40103                            }, titleOptions), false, 'spacingBox');
40104
40105                        if (!titleOptions.floating && !titleOptions.verticalAlign) {
40106                            titleOffset = Math.ceil(
40107                                titleOffset +
40108                                // Skip the cache for HTML (#3481)
40109                                title.getBBox(titleOptions.useHTML).height
40110                            );
40111                        }
40112                    }
40113                }, this);
40114
40115                requiresDirtyBox = this.titleOffset !== titleOffset;
40116                this.titleOffset = titleOffset; // used in getMargins
40117
40118                if (!this.isDirtyBox && requiresDirtyBox) {
40119                    this.isDirtyBox = requiresDirtyBox;
40120                    // Redraw if necessary (#2719, #2744)
40121                    if (this.hasRendered && pick(redraw, true) && this.isDirtyBox) {
40122                        this.redraw();
40123                    }
40124                }
40125            },
40126
40127            /**
40128             * Internal function to get the chart width and height according to options
40129             * and container size. Sets {@link Chart.chartWidth} and {@link
40130             * Chart.chartHeight}.
40131             */
40132            getChartSize: function() {
40133                var chart = this,
40134                    optionsChart = chart.options.chart,
40135                    widthOption = optionsChart.width,
40136                    heightOption = optionsChart.height,
40137                    renderTo = chart.renderTo;
40138
40139                // Get inner width and height
40140                if (!defined(widthOption)) {
40141                    chart.containerWidth = H.getStyle(renderTo, 'width');
40142                }
40143                if (!defined(heightOption)) {
40144                    chart.containerHeight = H.getStyle(renderTo, 'height');
40145                }
40146
40147                /**
40148                 * The current pixel width of the chart.
40149                 *
40150                 * @name chartWidth
40151                 * @memberOf Chart
40152                 * @type {Number}
40153                 */
40154                chart.chartWidth = Math.max( // #1393
40155                    0,
40156                    widthOption || chart.containerWidth || 600 // #1460
40157                );
40158                /**
40159                 * The current pixel height of the chart.
40160                 *
40161                 * @name chartHeight
40162                 * @memberOf Chart
40163                 * @type {Number}
40164                 */
40165                chart.chartHeight = Math.max(
40166                    0,
40167                    H.relativeLength(
40168                        heightOption,
40169                        chart.chartWidth
40170                    ) ||
40171                    (chart.containerHeight > 1 ? chart.containerHeight : 400)
40172                );
40173            },
40174
40175            /**
40176             * If the renderTo element has no offsetWidth, most likely one or more of
40177             * its parents are hidden. Loop up the DOM tree to temporarily display the
40178             * parents, then save the original display properties, and when the true
40179             * size is retrieved, reset them. Used on first render and on redraws.
40180             *
40181             * @private
40182             * 
40183             * @param  {Boolean} revert
40184             *         Revert to the saved original styles.
40185             */
40186            temporaryDisplay: function(revert) {
40187                var node = this.renderTo,
40188                    tempStyle;
40189                if (!revert) {
40190                    while (node && node.style) {
40191
40192                        // When rendering to a detached node, it needs to be temporarily
40193                        // attached in order to read styling and bounding boxes (#5783,
40194                        // #7024).
40195                        if (!doc.body.contains(node) && !node.parentNode) {
40196                            node.hcOrigDetached = true;
40197                            doc.body.appendChild(node);
40198                        }
40199                        if (
40200                            H.getStyle(node, 'display', false) === 'none' ||
40201                            node.hcOricDetached
40202                        ) {
40203                            node.hcOrigStyle = {
40204                                display: node.style.display,
40205                                height: node.style.height,
40206                                overflow: node.style.overflow
40207                            };
40208                            tempStyle = {
40209                                display: 'block',
40210                                overflow: 'hidden'
40211                            };
40212                            if (node !== this.renderTo) {
40213                                tempStyle.height = 0;
40214                            }
40215
40216                            H.css(node, tempStyle);
40217
40218                            // If it still doesn't have an offset width after setting
40219                            // display to block, it probably has an !important priority
40220                            // #2631, 6803
40221                            if (!node.offsetWidth) {
40222                                node.style.setProperty('display', 'block', 'important');
40223                            }
40224                        }
40225                        node = node.parentNode;
40226
40227                        if (node === doc.body) {
40228                            break;
40229                        }
40230                    }
40231                } else {
40232                    while (node && node.style) {
40233                        if (node.hcOrigStyle) {
40234                            H.css(node, node.hcOrigStyle);
40235                            delete node.hcOrigStyle;
40236                        }
40237                        if (node.hcOrigDetached) {
40238                            doc.body.removeChild(node);
40239                            node.hcOrigDetached = false;
40240                        }
40241                        node = node.parentNode;
40242                    }
40243                }
40244            },
40245
40246            /**
40247             * Set the {@link Chart.container|chart container's} class name, in
40248             * addition to `highcharts-container`. 
40249             */
40250            setClassName: function(className) {
40251                this.container.className = 'highcharts-container ' + (className || '');
40252            },
40253
40254            /**
40255             * Get the containing element, determine the size and create the inner
40256             * container div to hold the chart.
40257             *
40258             * @private
40259             */
40260            getContainer: function() {
40261                var chart = this,
40262                    container,
40263                    options = chart.options,
40264                    optionsChart = options.chart,
40265                    chartWidth,
40266                    chartHeight,
40267                    renderTo = chart.renderTo,
40268                    indexAttrName = 'data-highcharts-chart',
40269                    oldChartIndex,
40270                    Ren,
40271                    containerId = H.uniqueKey(),
40272                    containerStyle,
40273                    key;
40274
40275                if (!renderTo) {
40276                    chart.renderTo = renderTo = optionsChart.renderTo;
40277                }
40278
40279                if (isString(renderTo)) {
40280                    chart.renderTo = renderTo = doc.getElementById(renderTo);
40281                }
40282
40283                // Display an error if the renderTo is wrong
40284                if (!renderTo) {
40285                    H.error(13, true);
40286                }
40287
40288                // If the container already holds a chart, destroy it. The check for
40289                // hasRendered is there because web pages that are saved to disk from
40290                // the browser, will preserve the data-highcharts-chart attribute and
40291                // the SVG contents, but not an interactive chart. So in this case,
40292                // charts[oldChartIndex] will point to the wrong chart if any (#2609).
40293                oldChartIndex = pInt(attr(renderTo, indexAttrName));
40294                if (
40295                    isNumber(oldChartIndex) &&
40296                    charts[oldChartIndex] &&
40297                    charts[oldChartIndex].hasRendered
40298                ) {
40299                    charts[oldChartIndex].destroy();
40300                }
40301
40302                // Make a reference to the chart from the div
40303                attr(renderTo, indexAttrName, chart.index);
40304
40305                // remove previous chart
40306                renderTo.innerHTML = '';
40307
40308                // If the container doesn't have an offsetWidth, it has or is a child of
40309                // a node that has display:none. We need to temporarily move it out to a
40310                // visible state to determine the size, else the legend and tooltips
40311                // won't render properly. The skipClone option is used in sparklines as
40312                // a micro optimization, saving about 1-2 ms each chart.
40313                if (!optionsChart.skipClone && !renderTo.offsetWidth) {
40314                    chart.temporaryDisplay();
40315                }
40316
40317                // get the width and height
40318                chart.getChartSize();
40319                chartWidth = chart.chartWidth;
40320                chartHeight = chart.chartHeight;
40321
40322                // Create the inner container
40323
40324                containerStyle = extend({
40325                    position: 'relative',
40326                    overflow: 'hidden', // needed for context menu (avoid scrollbars)
40327                    // and content overflow in IE
40328                    width: chartWidth + 'px',
40329                    height: chartHeight + 'px',
40330                    textAlign: 'left',
40331                    lineHeight: 'normal', // #427
40332                    zIndex: 0, // #1072
40333                    '-webkit-tap-highlight-color': 'rgba(0,0,0,0)'
40334                }, optionsChart.style);
40335
40336
40337                /**
40338                 * The containing HTML element of the chart. The container is
40339                 * dynamically inserted into the element given as the `renderTo`
40340                 * parameterin the {@link Highcharts#chart} constructor.
40341                 *
40342                 * @memberOf Highcharts.Chart
40343                 * @type {HTMLDOMElement}
40344                 */
40345                container = createElement(
40346                    'div', {
40347                        id: containerId
40348                    },
40349                    containerStyle,
40350                    renderTo
40351                );
40352                chart.container = container;
40353
40354                // cache the cursor (#1650)
40355                chart._cursor = container.style.cursor;
40356
40357                // Initialize the renderer
40358                Ren = H[optionsChart.renderer] || H.Renderer;
40359
40360                /**
40361                 * The renderer instance of the chart. Each chart instance has only one
40362                 * associated renderer.
40363                 * @type {SVGRenderer}
40364                 * @name renderer
40365                 * @memberOf Chart
40366                 */
40367                chart.renderer = new Ren(
40368                    container,
40369                    chartWidth,
40370                    chartHeight,
40371                    null,
40372                    optionsChart.forExport,
40373                    options.exporting && options.exporting.allowHTML
40374                );
40375
40376
40377                chart.setClassName(optionsChart.className);
40378
40379                chart.renderer.setStyle(optionsChart.style);
40380
40381
40382                // Add a reference to the charts index
40383                chart.renderer.chartIndex = chart.index;
40384            },
40385
40386            /**
40387             * Calculate margins by rendering axis labels in a preliminary position.
40388             * Title, subtitle and legend have already been rendered at this stage, but
40389             * will be moved into their final positions.
40390             *
40391             * @private
40392             */
40393            getMargins: function(skipAxes) {
40394                var chart = this,
40395                    spacing = chart.spacing,
40396                    margin = chart.margin,
40397                    titleOffset = chart.titleOffset;
40398
40399                chart.resetMargins();
40400
40401                // Adjust for title and subtitle
40402                if (titleOffset && !defined(margin[0])) {
40403                    chart.plotTop = Math.max(
40404                        chart.plotTop,
40405                        titleOffset + chart.options.title.margin + spacing[0]
40406                    );
40407                }
40408
40409                // Adjust for legend
40410                if (chart.legend && chart.legend.display) {
40411                    chart.legend.adjustMargins(margin, spacing);
40412                }
40413
40414                // adjust for scroller
40415                if (chart.extraMargin) {
40416                    chart[chart.extraMargin.type] =
40417                        (chart[chart.extraMargin.type] || 0) + chart.extraMargin.value;
40418                }
40419
40420                // adjust for rangeSelector 
40421                if (chart.adjustPlotArea) {
40422                    chart.adjustPlotArea();
40423                }
40424
40425                if (!skipAxes) {
40426                    this.getAxisMargins();
40427                }
40428            },
40429
40430            getAxisMargins: function() {
40431
40432                var chart = this,
40433                    // [top, right, bottom, left]
40434                    axisOffset = chart.axisOffset = [0, 0, 0, 0],
40435                    margin = chart.margin;
40436
40437                // pre-render axes to get labels offset width
40438                if (chart.hasCartesianSeries) {
40439                    each(chart.axes, function(axis) {
40440                        if (axis.visible) {
40441                            axis.getOffset();
40442                        }
40443                    });
40444                }
40445
40446                // Add the axis offsets
40447                each(marginNames, function(m, side) {
40448                    if (!defined(margin[side])) {
40449                        chart[m] += axisOffset[side];
40450                    }
40451                });
40452
40453                chart.setChartSize();
40454
40455            },
40456
40457            /**
40458             * Reflows the chart to its container. By default, the chart reflows
40459             * automatically to its container following a `window.resize` event, as per
40460             * the {@link https://api.highcharts/highcharts/chart.reflow|chart.reflow}
40461             * option. However, there are no reliable events for div resize, so if the
40462             * container is resized without a window resize event, this must be called
40463             * explicitly.
40464             *
40465             * @param  {Object} e
40466             *         Event arguments. Used primarily when the function is called
40467             *         internally as a response to window resize.
40468             *
40469             * @sample highcharts/members/chart-reflow/
40470             *         Resize div and reflow
40471             * @sample highcharts/chart/events-container/
40472             *         Pop up and reflow
40473             */
40474            reflow: function(e) {
40475                var chart = this,
40476                    optionsChart = chart.options.chart,
40477                    renderTo = chart.renderTo,
40478                    hasUserSize = (
40479                        defined(optionsChart.width) &&
40480                        defined(optionsChart.height)
40481                    ),
40482                    width = optionsChart.width || H.getStyle(renderTo, 'width'),
40483                    height = optionsChart.height || H.getStyle(renderTo, 'height'),
40484                    target = e ? e.target : win;
40485
40486                // Width and height checks for display:none. Target is doc in IE8 and
40487                // Opera, win in Firefox, Chrome and IE9.
40488                if (!hasUserSize &&
40489                    !chart.isPrinting &&
40490                    width &&
40491                    height &&
40492                    (target === win || target === doc)
40493                ) {
40494                    if (
40495                        width !== chart.containerWidth ||
40496                        height !== chart.containerHeight
40497                    ) {
40498                        clearTimeout(chart.reflowTimeout);
40499                        // When called from window.resize, e is set, else it's called
40500                        // directly (#2224)
40501                        chart.reflowTimeout = syncTimeout(function() {
40502                            // Set size, it may have been destroyed in the meantime
40503                            // (#1257)
40504                            if (chart.container) {
40505                                chart.setSize(undefined, undefined, false);
40506                            }
40507                        }, e ? 100 : 0);
40508                    }
40509                    chart.containerWidth = width;
40510                    chart.containerHeight = height;
40511                }
40512            },
40513
40514            /**
40515             * Add the event handlers necessary for auto resizing, depending on the 
40516             * `chart.events.reflow` option.
40517             *
40518             * @private
40519             */
40520            initReflow: function() {
40521                var chart = this,
40522                    unbind;
40523
40524                unbind = addEvent(win, 'resize', function(e) {
40525                    chart.reflow(e);
40526                });
40527                addEvent(chart, 'destroy', unbind);
40528
40529                // The following will add listeners to re-fit the chart before and after
40530                // printing (#2284). However it only works in WebKit. Should have worked
40531                // in Firefox, but not supported in IE.
40532                /*
40533                if (win.matchMedia) {
40534                	win.matchMedia('print').addListener(function reflow() {
40535                		chart.reflow();
40536                	});
40537                }
40538                */
40539            },
40540
40541            /**
40542             * Resize the chart to a given width and height. In order to set the width
40543             * only, the height argument may be skipped. To set the height only, pass
40544             * `undefined for the width.
40545             * @param  {Number|undefined|null} [width]
40546             *         The new pixel width of the chart. Since v4.2.6, the argument can
40547             *         be `undefined` in order to preserve the current value (when
40548             *         setting height only), or `null` to adapt to the width of the
40549             *         containing element.
40550             * @param  {Number|undefined|null} [height]
40551             *         The new pixel height of the chart. Since v4.2.6, the argument can
40552             *         be `undefined` in order to preserve the current value, or `null`
40553             *         in order to adapt to the height of the containing element.
40554             * @param  {AnimationOptions} [animation=true]
40555             *         Whether and how to apply animation.
40556             *
40557             * @sample highcharts/members/chart-setsize-button/
40558             *         Test resizing from buttons
40559             * @sample highcharts/members/chart-setsize-jquery-resizable/
40560             *         Add a jQuery UI resizable
40561             * @sample stock/members/chart-setsize/
40562             *         Highstock with UI resizable
40563             */
40564            setSize: function(width, height, animation) {
40565                var chart = this,
40566                    renderer = chart.renderer,
40567                    globalAnimation;
40568
40569                // Handle the isResizing counter
40570                chart.isResizing += 1;
40571
40572                // set the animation for the current process
40573                H.setAnimation(animation, chart);
40574
40575                chart.oldChartHeight = chart.chartHeight;
40576                chart.oldChartWidth = chart.chartWidth;
40577                if (width !== undefined) {
40578                    chart.options.chart.width = width;
40579                }
40580                if (height !== undefined) {
40581                    chart.options.chart.height = height;
40582                }
40583                chart.getChartSize();
40584
40585                // Resize the container with the global animation applied if enabled
40586                // (#2503)
40587
40588                globalAnimation = renderer.globalAnimation;
40589                (globalAnimation ? animate : css)(chart.container, {
40590                    width: chart.chartWidth + 'px',
40591                    height: chart.chartHeight + 'px'
40592                }, globalAnimation);
40593
40594
40595                chart.setChartSize(true);
40596                renderer.setSize(chart.chartWidth, chart.chartHeight, animation);
40597
40598                // handle axes
40599                each(chart.axes, function(axis) {
40600                    axis.isDirty = true;
40601                    axis.setScale();
40602                });
40603
40604                chart.isDirtyLegend = true; // force legend redraw
40605                chart.isDirtyBox = true; // force redraw of plot and chart border
40606
40607                chart.layOutTitles(); // #2857
40608                chart.getMargins();
40609
40610                chart.redraw(animation);
40611
40612
40613                chart.oldChartHeight = null;
40614                fireEvent(chart, 'resize');
40615
40616                // Fire endResize and set isResizing back. If animation is disabled,
40617                // fire without delay
40618                syncTimeout(function() {
40619                    if (chart) {
40620                        fireEvent(chart, 'endResize', null, function() {
40621                            chart.isResizing -= 1;
40622                        });
40623                    }
40624                }, animObject(globalAnimation).duration);
40625            },
40626
40627            /**
40628             * Set the public chart properties. This is done before and after the
40629             * pre-render to determine margin sizes.
40630             *
40631             * @private
40632             */
40633            setChartSize: function(skipAxes) {
40634                var chart = this,
40635                    inverted = chart.inverted,
40636                    renderer = chart.renderer,
40637                    chartWidth = chart.chartWidth,
40638                    chartHeight = chart.chartHeight,
40639                    optionsChart = chart.options.chart,
40640                    spacing = chart.spacing,
40641                    clipOffset = chart.clipOffset,
40642                    clipX,
40643                    clipY,
40644                    plotLeft,
40645                    plotTop,
40646                    plotWidth,
40647                    plotHeight,
40648                    plotBorderWidth;
40649
40650                /**
40651                 * The current left position of the plot area in pixels.
40652                 *
40653                 * @name plotLeft
40654                 * @memberOf Chart
40655                 * @type {Number}
40656                 */
40657                chart.plotLeft = plotLeft = Math.round(chart.plotLeft);
40658
40659                /**
40660                 * The current top position of the plot area in pixels.
40661                 *
40662                 * @name plotTop
40663                 * @memberOf Chart
40664                 * @type {Number}
40665                 */
40666                chart.plotTop = plotTop = Math.round(chart.plotTop);
40667
40668                /**
40669                 * The current width of the plot area in pixels.
40670                 *
40671                 * @name plotWidth
40672                 * @memberOf Chart
40673                 * @type {Number}
40674                 */
40675                chart.plotWidth = plotWidth = Math.max(
40676                    0,
40677                    Math.round(chartWidth - plotLeft - chart.marginRight)
40678                );
40679
40680                /**
40681                 * The current height of the plot area in pixels.
40682                 *
40683                 * @name plotHeight
40684                 * @memberOf Chart
40685                 * @type {Number}
40686                 */
40687                chart.plotHeight = plotHeight = Math.max(
40688                    0,
40689                    Math.round(chartHeight - plotTop - chart.marginBottom)
40690                );
40691
40692                chart.plotSizeX = inverted ? plotHeight : plotWidth;
40693                chart.plotSizeY = inverted ? plotWidth : plotHeight;
40694
40695                chart.plotBorderWidth = optionsChart.plotBorderWidth || 0;
40696
40697                // Set boxes used for alignment
40698                chart.spacingBox = renderer.spacingBox = {
40699                    x: spacing[3],
40700                    y: spacing[0],
40701                    width: chartWidth - spacing[3] - spacing[1],
40702                    height: chartHeight - spacing[0] - spacing[2]
40703                };
40704                chart.plotBox = renderer.plotBox = {
40705                    x: plotLeft,
40706                    y: plotTop,
40707                    width: plotWidth,
40708                    height: plotHeight
40709                };
40710
40711                plotBorderWidth = 2 * Math.floor(chart.plotBorderWidth / 2);
40712                clipX = Math.ceil(Math.max(plotBorderWidth, clipOffset[3]) / 2);
40713                clipY = Math.ceil(Math.max(plotBorderWidth, clipOffset[0]) / 2);
40714                chart.clipBox = {
40715                    x: clipX,
40716                    y: clipY,
40717                    width: Math.floor(
40718                        chart.plotSizeX -
40719                        Math.max(plotBorderWidth, clipOffset[1]) / 2 -
40720                        clipX
40721                    ),
40722                    height: Math.max(
40723                        0,
40724                        Math.floor(
40725                            chart.plotSizeY -
40726                            Math.max(plotBorderWidth, clipOffset[2]) / 2 -
40727                            clipY
40728                        )
40729                    )
40730                };
40731
40732                if (!skipAxes) {
40733                    each(chart.axes, function(axis) {
40734                        axis.setAxisSize();
40735                        axis.setAxisTranslation();
40736                    });
40737                }
40738            },
40739
40740            /**
40741             * Initial margins before auto size margins are applied.
40742             *
40743             * @private
40744             */
40745            resetMargins: function() {
40746                var chart = this,
40747                    chartOptions = chart.options.chart;
40748
40749                // Create margin and spacing array
40750                each(['margin', 'spacing'], function splashArrays(target) {
40751                    var value = chartOptions[target],
40752                        values = isObject(value) ? value : [value, value, value, value];
40753
40754                    each(['Top', 'Right', 'Bottom', 'Left'], function(sideName, side) {
40755                        chart[target][side] = pick(
40756                            chartOptions[target + sideName],
40757                            values[side]
40758                        );
40759                    });
40760                });
40761
40762                // Set margin names like chart.plotTop, chart.plotLeft,
40763                // chart.marginRight, chart.marginBottom.
40764                each(marginNames, function(m, side) {
40765                    chart[m] = pick(chart.margin[side], chart.spacing[side]);
40766                });
40767                chart.axisOffset = [0, 0, 0, 0]; // top, right, bottom, left
40768                chart.clipOffset = [0, 0, 0, 0];
40769            },
40770
40771            /**
40772             * Internal function to draw or redraw the borders and backgrounds for chart
40773             * and plot area.
40774             *
40775             * @private
40776             */
40777            drawChartBox: function() {
40778                var chart = this,
40779                    optionsChart = chart.options.chart,
40780                    renderer = chart.renderer,
40781                    chartWidth = chart.chartWidth,
40782                    chartHeight = chart.chartHeight,
40783                    chartBackground = chart.chartBackground,
40784                    plotBackground = chart.plotBackground,
40785                    plotBorder = chart.plotBorder,
40786                    chartBorderWidth,
40787
40788                    plotBGImage = chart.plotBGImage,
40789                    chartBackgroundColor = optionsChart.backgroundColor,
40790                    plotBackgroundColor = optionsChart.plotBackgroundColor,
40791                    plotBackgroundImage = optionsChart.plotBackgroundImage,
40792
40793                    mgn,
40794                    bgAttr,
40795                    plotLeft = chart.plotLeft,
40796                    plotTop = chart.plotTop,
40797                    plotWidth = chart.plotWidth,
40798                    plotHeight = chart.plotHeight,
40799                    plotBox = chart.plotBox,
40800                    clipRect = chart.clipRect,
40801                    clipBox = chart.clipBox,
40802                    verb = 'animate';
40803
40804                // Chart area
40805                if (!chartBackground) {
40806                    chart.chartBackground = chartBackground = renderer.rect()
40807                        .addClass('highcharts-background')
40808                        .add();
40809                    verb = 'attr';
40810                }
40811
40812
40813                // Presentational
40814                chartBorderWidth = optionsChart.borderWidth || 0;
40815                mgn = chartBorderWidth + (optionsChart.shadow ? 8 : 0);
40816
40817                bgAttr = {
40818                    fill: chartBackgroundColor || 'none'
40819                };
40820
40821                if (chartBorderWidth || chartBackground['stroke-width']) { // #980
40822                    bgAttr.stroke = optionsChart.borderColor;
40823                    bgAttr['stroke-width'] = chartBorderWidth;
40824                }
40825                chartBackground
40826                    .attr(bgAttr)
40827                    .shadow(optionsChart.shadow);
40828
40829                chartBackground[verb]({
40830                    x: mgn / 2,
40831                    y: mgn / 2,
40832                    width: chartWidth - mgn - chartBorderWidth % 2,
40833                    height: chartHeight - mgn - chartBorderWidth % 2,
40834                    r: optionsChart.borderRadius
40835                });
40836
40837                // Plot background
40838                verb = 'animate';
40839                if (!plotBackground) {
40840                    verb = 'attr';
40841                    chart.plotBackground = plotBackground = renderer.rect()
40842                        .addClass('highcharts-plot-background')
40843                        .add();
40844                }
40845                plotBackground[verb](plotBox);
40846
40847
40848                // Presentational attributes for the background
40849                plotBackground
40850                    .attr({
40851                        fill: plotBackgroundColor || 'none'
40852                    })
40853                    .shadow(optionsChart.plotShadow);
40854
40855                // Create the background image
40856                if (plotBackgroundImage) {
40857                    if (!plotBGImage) {
40858                        chart.plotBGImage = renderer.image(
40859                            plotBackgroundImage,
40860                            plotLeft,
40861                            plotTop,
40862                            plotWidth,
40863                            plotHeight
40864                        ).add();
40865                    } else {
40866                        plotBGImage.animate(plotBox);
40867                    }
40868                }
40869
40870
40871                // Plot clip
40872                if (!clipRect) {
40873                    chart.clipRect = renderer.clipRect(clipBox);
40874                } else {
40875                    clipRect.animate({
40876                        width: clipBox.width,
40877                        height: clipBox.height
40878                    });
40879                }
40880
40881                // Plot area border
40882                verb = 'animate';
40883                if (!plotBorder) {
40884                    verb = 'attr';
40885                    chart.plotBorder = plotBorder = renderer.rect()
40886                        .addClass('highcharts-plot-border')
40887                        .attr({
40888                            zIndex: 1 // Above the grid
40889                        })
40890                        .add();
40891                }
40892
40893
40894                // Presentational
40895                plotBorder.attr({
40896                    stroke: optionsChart.plotBorderColor,
40897                    'stroke-width': optionsChart.plotBorderWidth || 0,
40898                    fill: 'none'
40899                });
40900
40901
40902                plotBorder[verb](plotBorder.crisp({
40903                    x: plotLeft,
40904                    y: plotTop,
40905                    width: plotWidth,
40906                    height: plotHeight
40907                }, -plotBorder.strokeWidth())); // #3282 plotBorder should be negative;
40908
40909                // reset
40910                chart.isDirtyBox = false;
40911            },
40912
40913            /**
40914             * Detect whether a certain chart property is needed based on inspecting its
40915             * options and series. This mainly applies to the chart.inverted property,
40916             * and in extensions to the chart.angular and chart.polar properties.
40917             *
40918             * @private
40919             */
40920            propFromSeries: function() {
40921                var chart = this,
40922                    optionsChart = chart.options.chart,
40923                    klass,
40924                    seriesOptions = chart.options.series,
40925                    i,
40926                    value;
40927
40928
40929                each(['inverted', 'angular', 'polar'], function(key) {
40930
40931                    // The default series type's class
40932                    klass = seriesTypes[optionsChart.type ||
40933                        optionsChart.defaultSeriesType];
40934
40935                    // Get the value from available chart-wide properties
40936                    value =
40937                        optionsChart[key] || // It is set in the options
40938                        (klass && klass.prototype[key]); // The default series class
40939                    // requires it
40940
40941                    // 4. Check if any the chart's series require it
40942                    i = seriesOptions && seriesOptions.length;
40943                    while (!value && i--) {
40944                        klass = seriesTypes[seriesOptions[i].type];
40945                        if (klass && klass.prototype[key]) {
40946                            value = true;
40947                        }
40948                    }
40949
40950                    // Set the chart property
40951                    chart[key] = value;
40952                });
40953
40954            },
40955
40956            /**
40957             * Internal function to link two or more series together, based on the 
40958             * `linkedTo` option. This is done from `Chart.render`, and after
40959             * `Chart.addSeries` and `Series.remove`.
40960             *
40961             * @private
40962             */
40963            linkSeries: function() {
40964                var chart = this,
40965                    chartSeries = chart.series;
40966
40967                // Reset links
40968                each(chartSeries, function(series) {
40969                    series.linkedSeries.length = 0;
40970                });
40971
40972                // Apply new links
40973                each(chartSeries, function(series) {
40974                    var linkedTo = series.options.linkedTo;
40975                    if (isString(linkedTo)) {
40976                        if (linkedTo === ':previous') {
40977                            linkedTo = chart.series[series.index - 1];
40978                        } else {
40979                            linkedTo = chart.get(linkedTo);
40980                        }
40981                        // #3341 avoid mutual linking
40982                        if (linkedTo && linkedTo.linkedParent !== series) {
40983                            linkedTo.linkedSeries.push(series);
40984                            series.linkedParent = linkedTo;
40985                            series.visible = pick(
40986                                series.options.visible,
40987                                linkedTo.options.visible,
40988                                series.visible
40989                            ); // #3879
40990                        }
40991                    }
40992                });
40993            },
40994
40995            /**
40996             * Render series for the chart.
40997             *
40998             * @private
40999             */
41000            renderSeries: function() {
41001                each(this.series, function(serie) {
41002                    serie.translate();
41003                    serie.render();
41004                });
41005            },
41006
41007            /**
41008             * Render labels for the chart.
41009             *
41010             * @private
41011             */
41012            renderLabels: function() {
41013                var chart = this,
41014                    labels = chart.options.labels;
41015                if (labels.items) {
41016                    each(labels.items, function(label) {
41017                        var style = extend(labels.style, label.style),
41018                            x = pInt(style.left) + chart.plotLeft,
41019                            y = pInt(style.top) + chart.plotTop + 12;
41020
41021                        // delete to prevent rewriting in IE
41022                        delete style.left;
41023                        delete style.top;
41024
41025                        chart.renderer.text(
41026                                label.html,
41027                                x,
41028                                y
41029                            )
41030                            .attr({
41031                                zIndex: 2
41032                            })
41033                            .css(style)
41034                            .add();
41035
41036                    });
41037                }
41038            },
41039
41040            /**
41041             * Render all graphics for the chart. Runs internally on initialization.
41042             *
41043             * @private
41044             */
41045            render: function() {
41046                var chart = this,
41047                    axes = chart.axes,
41048                    renderer = chart.renderer,
41049                    options = chart.options,
41050                    tempWidth,
41051                    tempHeight,
41052                    redoHorizontal,
41053                    redoVertical;
41054
41055                // Title
41056                chart.setTitle();
41057
41058
41059                // Legend
41060                chart.legend = new Legend(chart, options.legend);
41061
41062                // Get stacks
41063                if (chart.getStacks) {
41064                    chart.getStacks();
41065                }
41066
41067                // Get chart margins
41068                chart.getMargins(true);
41069                chart.setChartSize();
41070
41071                // Record preliminary dimensions for later comparison
41072                tempWidth = chart.plotWidth;
41073                // 21 is the most common correction for X axis labels
41074                // use Math.max to prevent negative plotHeight
41075                tempHeight = chart.plotHeight = Math.max(chart.plotHeight - 21, 0);
41076
41077                // Get margins by pre-rendering axes
41078                each(axes, function(axis) {
41079                    axis.setScale();
41080                });
41081                chart.getAxisMargins();
41082
41083                // If the plot area size has changed significantly, calculate tick positions again
41084                redoHorizontal = tempWidth / chart.plotWidth > 1.1;
41085                redoVertical = tempHeight / chart.plotHeight > 1.05; // Height is more sensitive
41086
41087                if (redoHorizontal || redoVertical) {
41088
41089                    each(axes, function(axis) {
41090                        if ((axis.horiz && redoHorizontal) || (!axis.horiz && redoVertical)) {
41091                            axis.setTickInterval(true); // update to reflect the new margins
41092                        }
41093                    });
41094                    chart.getMargins(); // second pass to check for new labels
41095                }
41096
41097                // Draw the borders and backgrounds
41098                chart.drawChartBox();
41099
41100
41101                // Axes
41102                if (chart.hasCartesianSeries) {
41103                    each(axes, function(axis) {
41104                        if (axis.visible) {
41105                            axis.render();
41106                        }
41107                    });
41108                }
41109
41110                // The series
41111                if (!chart.seriesGroup) {
41112                    chart.seriesGroup = renderer.g('series-group')
41113                        .attr({
41114                            zIndex: 3
41115                        })
41116                        .add();
41117                }
41118                chart.renderSeries();
41119
41120                // Labels
41121                chart.renderLabels();
41122
41123                // Credits
41124                chart.addCredits();
41125
41126                // Handle responsiveness
41127                if (chart.setResponsive) {
41128                    chart.setResponsive();
41129                }
41130
41131                // Set flag
41132                chart.hasRendered = true;
41133
41134            },
41135
41136            /**
41137             * Set a new credits label for the chart.
41138             *
41139             * @param  {CreditOptions} options
41140             *         A configuration object for the new credits.
41141             * @sample highcharts/credits/credits-update/ Add and update credits
41142             */
41143            addCredits: function(credits) {
41144                var chart = this;
41145
41146                credits = merge(true, this.options.credits, credits);
41147                if (credits.enabled && !this.credits) {
41148
41149                    /**
41150                     * The chart's credits label. The label has an `update` method that
41151                     * allows setting new options as per the {@link
41152                     * https://api.highcharts.com/highcharts/credits|
41153                     * credits options set}.
41154                     *
41155                     * @memberof Highcharts.Chart
41156                     * @name credits
41157                     * @type {Highcharts.SVGElement}
41158                     */
41159                    this.credits = this.renderer.text(
41160                            credits.text + (this.mapCredits || ''),
41161                            0,
41162                            0
41163                        )
41164                        .addClass('highcharts-credits')
41165                        .on('click', function() {
41166                            if (credits.href) {
41167                                win.location.href = credits.href;
41168                            }
41169                        })
41170                        .attr({
41171                            align: credits.position.align,
41172                            zIndex: 8
41173                        })
41174
41175                        .css(credits.style)
41176
41177                        .add()
41178                        .align(credits.position);
41179
41180                    // Dynamically update
41181                    this.credits.update = function(options) {
41182                        chart.credits = chart.credits.destroy();
41183                        chart.addCredits(options);
41184                    };
41185                }
41186            },
41187
41188            /**
41189             * Remove the chart and purge memory. This method is called internally
41190             * before adding a second chart into the same container, as well as on
41191             * window unload to prevent leaks.
41192             *
41193             * @sample highcharts/members/chart-destroy/
41194             *         Destroy the chart from a button
41195             * @sample stock/members/chart-destroy/
41196             *         Destroy with Highstock
41197             */
41198            destroy: function() {
41199                var chart = this,
41200                    axes = chart.axes,
41201                    series = chart.series,
41202                    container = chart.container,
41203                    i,
41204                    parentNode = container && container.parentNode;
41205
41206                // fire the chart.destoy event
41207                fireEvent(chart, 'destroy');
41208
41209                // Delete the chart from charts lookup array
41210                if (chart.renderer.forExport) {
41211                    H.erase(charts, chart); // #6569
41212                } else {
41213                    charts[chart.index] = undefined;
41214                }
41215                H.chartCount--;
41216                chart.renderTo.removeAttribute('data-highcharts-chart');
41217
41218                // remove events
41219                removeEvent(chart);
41220
41221                // ==== Destroy collections:
41222                // Destroy axes
41223                i = axes.length;
41224                while (i--) {
41225                    axes[i] = axes[i].destroy();
41226                }
41227
41228                // Destroy scroller & scroller series before destroying base series
41229                if (this.scroller && this.scroller.destroy) {
41230                    this.scroller.destroy();
41231                }
41232
41233                // Destroy each series
41234                i = series.length;
41235                while (i--) {
41236                    series[i] = series[i].destroy();
41237                }
41238
41239                // ==== Destroy chart properties:
41240                each([
41241                    'title', 'subtitle', 'chartBackground', 'plotBackground',
41242                    'plotBGImage', 'plotBorder', 'seriesGroup', 'clipRect', 'credits',
41243                    'pointer', 'rangeSelector', 'legend', 'resetZoomButton', 'tooltip',
41244                    'renderer'
41245                ], function(name) {
41246                    var prop = chart[name];
41247
41248                    if (prop && prop.destroy) {
41249                        chart[name] = prop.destroy();
41250                    }
41251                });
41252
41253                // remove container and all SVG
41254                if (container) { // can break in IE when destroyed before finished loading
41255                    container.innerHTML = '';
41256                    removeEvent(container);
41257                    if (parentNode) {
41258                        discardElement(container);
41259                    }
41260
41261                }
41262
41263                // clean it all up
41264                objectEach(chart, function(val, key) {
41265                    delete chart[key];
41266                });
41267
41268            },
41269
41270
41271            /**
41272             * VML namespaces can't be added until after complete. Listening
41273             * for Perini's doScroll hack is not enough.
41274             *
41275             * @private
41276             */
41277            isReadyToRender: function() {
41278                var chart = this;
41279
41280                // Note: win == win.top is required
41281                if ((!svg && (win == win.top && doc.readyState !== 'complete'))) { // eslint-disable-line eqeqeq
41282                    doc.attachEvent('onreadystatechange', function() {
41283                        doc.detachEvent('onreadystatechange', chart.firstRender);
41284                        if (doc.readyState === 'complete') {
41285                            chart.firstRender();
41286                        }
41287                    });
41288                    return false;
41289                }
41290                return true;
41291            },
41292
41293            /**
41294             * Prepare for first rendering after all data are loaded.
41295             *
41296             * @private
41297             */
41298            firstRender: function() {
41299                var chart = this,
41300                    options = chart.options;
41301
41302                // Check whether the chart is ready to render
41303                if (!chart.isReadyToRender()) {
41304                    return;
41305                }
41306
41307                // Create the container
41308                chart.getContainer();
41309
41310                // Run an early event after the container and renderer are established
41311                fireEvent(chart, 'init');
41312
41313
41314                chart.resetMargins();
41315                chart.setChartSize();
41316
41317                // Set the common chart properties (mainly invert) from the given series
41318                chart.propFromSeries();
41319
41320                // get axes
41321                chart.getAxes();
41322
41323                // Initialize the series
41324                each(options.series || [], function(serieOptions) {
41325                    chart.initSeries(serieOptions);
41326                });
41327
41328                chart.linkSeries();
41329
41330                // Run an event after axes and series are initialized, but before render. At this stage,
41331                // the series data is indexed and cached in the xData and yData arrays, so we can access
41332                // those before rendering. Used in Highstock.
41333                fireEvent(chart, 'beforeRender');
41334
41335                // depends on inverted and on margins being set
41336                if (Pointer) {
41337
41338                    /**
41339                     * The Pointer that keeps track of mouse and touch interaction.
41340                     *
41341                     * @memberof Chart
41342                     * @name pointer
41343                     * @type Pointer
41344                     */
41345                    chart.pointer = new Pointer(chart, options);
41346                }
41347
41348                chart.render();
41349
41350                // Fire the load event if there are no external images
41351                if (!chart.renderer.imgCount && chart.onload) {
41352                    chart.onload();
41353                }
41354
41355                // If the chart was rendered outside the top container, put it back in (#3679)
41356                chart.temporaryDisplay(true);
41357
41358            },
41359
41360            /** 
41361             * Internal function that runs on chart load, async if any images are loaded
41362             * in the chart. Runs the callbacks and triggers the `load` and `render`
41363             * events.
41364             *
41365             * @private
41366             */
41367            onload: function() {
41368
41369                // Run callbacks
41370                each([this.callback].concat(this.callbacks), function(fn) {
41371                    if (fn && this.index !== undefined) { // Chart destroyed in its own callback (#3600)
41372                        fn.apply(this, [this]);
41373                    }
41374                }, this);
41375
41376                fireEvent(this, 'load');
41377                fireEvent(this, 'render');
41378
41379
41380                // Set up auto resize, check for not destroyed (#6068)
41381                if (defined(this.index) && this.options.chart.reflow !== false) {
41382                    this.initReflow();
41383                }
41384
41385                // Don't run again
41386                this.onload = null;
41387            }
41388
41389        }); // end Chart
41390
41391    }
41391(Highcharts));
41392    (function(Highcharts) {
41393        /**
41394         * (c) 2010-2017 Torstein Honsi
41395         *
41396         * License: www.highcharts.com/license
41397         */
41398        var Point,
41399            H = Highcharts,
41400
41401            each = H.each,
41402            extend = H.extend,
41403            erase = H.erase,
41404            fireEvent = H.fireEvent,
41405            format = H.format,
41406            isArray = H.isArray,
41407            isNumber = H.isNumber,
41408            pick = H.pick,
41409            removeEvent = H.removeEvent;
41410
41411        /**
41412         * The Point object. The point objects are generated from the `series.data` 
41413         * configuration objects or raw numbers. They can be accessed from the
41414         * `Series.points` array. Other ways to instaniate points are through {@link
41415         * Highcharts.Series#addPoint} or {@link Highcharts.Series#setData}.
41416         *
41417         * @class
41418         */
41419
41420        Highcharts.Point = Point = function() {};
41421        Highcharts.Point.prototype = {
41422
41423            /**
41424             * Initialize the point. Called internally based on the `series.data`
41425             * option.
41426             * @param  {Series} series
41427             *         The series object containing this point.
41428             * @param  {Number|Array|Object} options
41429             *         The data in either number, array or object format.
41430             * @param  {Number} x Optionally, the X value of the point.
41431             * @return {Point} The Point instance.
41432             */
41433            init: function(series, options, x) {
41434
41435                var point = this,
41436                    colors,
41437                    colorCount = series.chart.options.chart.colorCount,
41438                    colorIndex;
41439
41440                /**
41441                 * The series object associated with the point.
41442                 *
41443                 * @name series
41444                 * @memberof Highcharts.Point
41445                 * @type Highcharts.Series
41446                 */
41447                point.series = series;
41448
41449
41450                /**
41451                 * The point's current color.
41452                 * @name color
41453                 * @memberof Highcharts.Point
41454                 * @type {Color}
41455                 */
41456                point.color = series.color; // #3445
41457
41458                point.applyOptions(options, x);
41459
41460                if (series.options.colorByPoint) {
41461
41462                    colors = series.options.colors || series.chart.options.colors;
41463                    point.color = point.color || colors[series.colorCounter];
41464                    colorCount = colors.length;
41465
41466                    colorIndex = series.colorCounter;
41467                    series.colorCounter++;
41468                    // loop back to zero
41469                    if (series.colorCounter === colorCount) {
41470                        series.colorCounter = 0;
41471                    }
41472                } else {
41473                    colorIndex = series.colorIndex;
41474                }
41475
41476                /**
41477                 * The point's current color index, used in styled mode instead of 
41478                 * `color`. The color index is inserted in class names used for styling.
41479                 * @name colorIndex
41480                 * @memberof Highcharts.Point
41481                 * @type {Number}
41482                 */
41483                point.colorIndex = pick(point.colorIndex, colorIndex);
41484
41485                series.chart.pointCount++;
41486                return point;
41487            },
41488            /**
41489             * Apply the options containing the x and y data and possible some extra
41490             * properties. Called on point init or from point.update.
41491             *
41492             * @private
41493             * @param {Object} options The point options as defined in series.data.
41494             * @param {Number} x Optionally, the X value.
41495             * @returns {Object} The Point instance.
41496             */
41497            applyOptions: function(options, x) {
41498                var point = this,
41499                    series = point.series,
41500                    pointValKey = series.options.pointValKey || series.pointValKey;
41501
41502                options = Point.prototype.optionsToObject.call(this, options);
41503
41504                // copy options directly to point
41505                extend(point, options);
41506                point.options = point.options ? extend(point.options, options) : options;
41507
41508                // Since options are copied into the Point instance, some accidental options must be shielded (#5681)
41509                if (options.group) {
41510                    delete point.group;
41511                }
41512
41513                // For higher dimension series types. For instance, for ranges, point.y is mapped to point.low.
41514                if (pointValKey) {
41515                    point.y = point[pointValKey];
41516                }
41517                point.isNull = pick(
41518                    point.isValid && !point.isValid(),
41519                    point.x === null || !isNumber(point.y, true)
41520                ); // #3571, check for NaN
41521
41522                // The point is initially selected by options (#5777)
41523                if (point.selected) {
41524                    point.state = 'select';
41525                }
41526
41527                // If no x is set by now, get auto incremented value. All points must have an
41528                // x value, however the y value can be null to create a gap in the series
41529                if ('name' in point && x === undefined && series.xAxis && series.xAxis.hasNames) {
41530                    point.x = series.xAxis.nameToX(point);
41531                }
41532                if (point.x === undefined && series) {
41533                    if (x === undefined) {
41534                        point.x = series.autoIncrement(point);
41535                    } else {
41536                        point.x = x;
41537                    }
41538                }
41539
41540                return point;
41541            },
41542
41543            /**
41544             * Transform number or array configs into objects. Used internally to unify
41545             * the different configuration formats for points. For example, a simple
41546             * number `10` in a line series will be transformed to `{ y: 10 }`, and an
41547             * array config like `[1, 10]` in a scatter series will be transformed to
41548             * `{ x: 1, y: 10 }`.
41549             *
41550             * @param  {Number|Array|Object} options
41551             *         The input options
41552             * @return {Object} Transformed options.
41553             */
41554            optionsToObject: function(options) {
41555                var ret = {},
41556                    series = this.series,
41557                    keys = series.options.keys,
41558                    pointArrayMap = keys || series.pointArrayMap || ['y'],
41559                    valueCount = pointArrayMap.length,
41560                    firstItemType,
41561                    i = 0,
41562                    j = 0;
41563
41564                if (isNumber(options) || options === null) {
41565                    ret[pointArrayMap[0]] = options;
41566
41567                } else if (isArray(options)) {
41568                    // with leading x value
41569                    if (!keys && options.length > valueCount) {
41570                        firstItemType = typeof options[0];
41571                        if (firstItemType === 'string') {
41572                            ret.name = options[0];
41573                        } else if (firstItemType === 'number') {
41574                            ret.x = options[0];
41575                        }
41576                        i++;
41577                    }
41578                    while (j < valueCount) {
41579                        if (!keys || options[i] !== undefined) { // Skip undefined positions for keys
41580                            ret[pointArrayMap[j]] = options[i];
41581                        }
41582                        i++;
41583                        j++;
41584                    }
41585                } else if (typeof options === 'object') {
41586                    ret = options;
41587
41588                    // This is the fastest way to detect if there are individual point dataLabels that need
41589                    // to be considered in drawDataLabels. These can only occur in object configs.
41590                    if (options.dataLabels) {
41591                        series._hasPointLabels = true;
41592                    }
41593
41594                    // Same approach as above for markers
41595                    if (options.marker) {
41596                        series._hasPointMarkers = true;
41597                    }
41598                }
41599                return ret;
41600            },
41601
41602            /**
41603             * Get the CSS class names for individual points. Used internally where the
41604             * returned value is set on every point.
41605             * 
41606             * @returns {String} The class names.
41607             */
41608            getClassName: function() {
41609                return 'highcharts-point' +
41610                    (this.selected ? ' highcharts-point-select' : '') +
41611                    (this.negative ? ' highcharts-negative' : '') +
41612                    (this.isNull ? ' highcharts-null-point' : '') +
41613                    (this.colorIndex !== undefined ? ' highcharts-color-' +
41614                        this.colorIndex : '') +
41615                    (this.options.className ? ' ' + this.options.className : '') +
41616                    (this.zone && this.zone.className ? ' ' +
41617                        this.zone.className.replace('highcharts-negative', '') : '');
41618            },
41619
41620            /**
41621             * In a series with `zones`, return the zone that the point belongs to.
41622             *
41623             * @return {Object}
41624             *         The zone item.
41625             */
41626            getZone: function() {
41627                var series = this.series,
41628                    zones = series.zones,
41629                    zoneAxis = series.zoneAxis || 'y',
41630                    i = 0,
41631                    zone;
41632
41633                zone = zones[i];
41634                while (this[zoneAxis] >= zone.value) {
41635                    zone = zones[++i];
41636                }
41637
41638                if (zone && zone.color && !this.options.color) {
41639                    this.color = zone.color;
41640                }
41641
41642                return zone;
41643            },
41644
41645            /**
41646             * Destroy a point to clear memory. Its reference still stays in
41647             * `series.data`.
41648             *
41649             * @private
41650             */
41651            destroy: function() {
41652                var point = this,
41653                    series = point.series,
41654                    chart = series.chart,
41655                    hoverPoints = chart.hoverPoints,
41656                    prop;
41657
41658                chart.pointCount--;
41659
41660                if (hoverPoints) {
41661                    point.setState();
41662                    erase(hoverPoints, point);
41663                    if (!hoverPoints.length) {
41664                        chart.hoverPoints = null;
41665                    }
41666
41667                }
41668                if (point === chart.hoverPoint) {
41669                    point.onMouseOut();
41670                }
41671
41672                // remove all events
41673                if (point.graphic || point.dataLabel) { // removeEvent and destroyElements are performance expensive
41674                    removeEvent(point);
41675                    point.destroyElements();
41676                }
41677
41678                if (point.legendItem) { // pies have legend items
41679                    chart.legend.destroyItem(point);
41680                }
41681
41682                for (prop in point) {
41683                    point[prop] = null;
41684                }
41685
41686
41687            },
41688
41689            /**
41690             * Destroy SVG elements associated with the point.
41691             *
41692             * @private
41693             */
41694            destroyElements: function() {
41695                var point = this,
41696                    props = ['graphic', 'dataLabel', 'dataLabelUpper', 'connector', 'shadowGroup'],
41697                    prop,
41698                    i = 6;
41699                while (i--) {
41700                    prop = props[i];
41701                    if (point[prop]) {
41702                        point[prop] = point[prop].destroy();
41703                    }
41704                }
41705            },
41706
41707            /**
41708             * Return the configuration hash needed for the data label and tooltip
41709             * formatters.
41710             *
41711             * @returns {Object}
41712             *          Abstract object used in formatters and formats.
41713             */
41714            getLabelConfig: function() {
41715                return {
41716                    x: this.category,
41717                    y: this.y,
41718                    color: this.color,
41719                    colorIndex: this.colorIndex,
41720                    key: this.name || this.category,
41721                    series: this.series,
41722                    point: this,
41723                    percentage: this.percentage,
41724                    total: this.total || this.stackTotal
41725                };
41726            },
41727
41728            /**
41729             * Extendable method for formatting each point's tooltip line.
41730             *
41731             * @param  {String} pointFormat
41732             *         The point format.
41733             * @return {String}
41734             *         A string to be concatenated in to the common tooltip text.
41735             */
41736            tooltipFormatter: function(pointFormat) {
41737
41738                // Insert options for valueDecimals, valuePrefix, and valueSuffix
41739                var series = this.series,
41740                    seriesTooltipOptions = series.tooltipOptions,
41741                    valueDecimals = pick(seriesTooltipOptions.valueDecimals, ''),
41742                    valuePrefix = seriesTooltipOptions.valuePrefix || '',
41743                    valueSuffix = seriesTooltipOptions.valueSuffix || '';
41744
41745                // Loop over the point array map and replace unformatted values with sprintf formatting markup
41746                each(series.pointArrayMap || ['y'], function(key) {
41747                    key = '{point.' + key; // without the closing bracket
41748                    if (valuePrefix || valueSuffix) {
41749                        pointFormat = pointFormat.replace(key + '}', valuePrefix + key + '}' + valueSuffix);
41750                    }
41751                    pointFormat = pointFormat.replace(key + '}', key + ':,.' + valueDecimals + 'f}');
41752                });
41753
41754                return format(pointFormat, {
41755                    point: this,
41756                    series: this.series
41757                });
41758            },
41759
41760            /**
41761             * Fire an event on the Point object.
41762             *
41763             * @private
41764             * @param {String} eventType
41765             * @param {Object} eventArgs Additional event arguments
41766             * @param {Function} defaultFunction Default event handler
41767             */
41768            firePointEvent: function(eventType, eventArgs, defaultFunction) {
41769                var point = this,
41770                    series = this.series,
41771                    seriesOptions = series.options;
41772
41773                // load event handlers on demand to save time on mouseover/out
41774                if (seriesOptions.point.events[eventType] || (point.options && point.options.events && point.options.events[eventType])) {
41775                    this.importEvents();
41776                }
41777
41778                // add default handler if in selection mode
41779                if (eventType === 'click' && seriesOptions.allowPointSelect) {
41780                    defaultFunction = function(event) {
41781                        // Control key is for Windows, meta (= Cmd key) for Mac, Shift for Opera
41782                        if (point.select) { // Could be destroyed by prior event handlers (#2911)
41783                            point.select(null, event.ctrlKey || event.metaKey || event.shiftKey);
41784                        }
41785                    };
41786                }
41787
41788                fireEvent(this, eventType, eventArgs, defaultFunction);
41789            },
41790
41791            /**
41792             * For certain series types, like pie charts, where individual points can
41793             * be shown or hidden. 
41794             *
41795             * @name visible
41796             * @memberOf Highcharts.Point
41797             * @type {Boolean}
41798             */
41799            visible: true
41800        };
41801
41802        /**
41803         * For categorized axes this property holds the category name for the 
41804         * point. For other axes it holds the X value.
41805         *
41806         * @name category
41807         * @memberOf Highcharts.Point
41808         * @type {String|Number}
41809         */
41810
41811        /**
41812         * The name of the point. The name can be given as the first position of the 
41813         * point configuration array, or as a `name` property in the configuration:
41814         *
41815         * @example
41816         * // Array config
41817         * data: [
41818         *     ['John', 1],
41819         *     ['Jane', 2]
41820         * ]
41821         *
41822         * // Object config
41823         * data: [{
41824         * 	   name: 'John',
41825         * 	   y: 1
41826         * }, {
41827         *     name: 'Jane',
41828         *     y: 2
41829         * }]
41830         *
41831         * @name name
41832         * @memberOf Highcharts.Point
41833         * @type {String}
41834         */
41835
41836
41837        /**
41838         * The percentage for points in a stacked series or pies.
41839         *
41840         * @name percentage
41841         * @memberOf Highcharts.Point
41842         * @type {Number}
41843         */
41844
41845        /**
41846         * The total of values in either a stack for stacked series, or a pie in a pie
41847         * series.
41848         *
41849         * @name total
41850         * @memberOf Highcharts.Point
41851         * @type {Number}
41852         */
41853
41854        /**
41855         * The x value of the point.
41856         *
41857         * @name x
41858         * @memberOf Highcharts.Point
41859         * @type {Number}
41860         */
41861
41862        /**
41863         * The y value of the point.
41864         *
41865         * @name y
41866         * @memberOf Highcharts.Point
41867         * @type {Number}
41868         */
41869
41870    }(Highcharts));
41871    (function(H) {
41872        /**
41873         * (c) 2010-2017 Torstein Honsi
41874         *
41875         * License: www.highcharts.com/license
41876         */
41877        var addEvent = H.addEvent,
41878            animObject = H.animObject,
41879            arrayMax = H.arrayMax,
41880            arrayMin = H.arrayMin,
41881            correctFloat = H.correctFloat,
41882            Date = H.Date,
41883            defaultOptions = H.defaultOptions,
41884            defaultPlotOptions = H.defaultPlotOptions,
41885            defined = H.defined,
41886            each = H.each,
41887            erase = H.erase,
41888            extend = H.extend,
41889            fireEvent = H.fireEvent,
41890            grep = H.grep,
41891            isArray = H.isArray,
41892            isNumber = H.isNumber,
41893            isString = H.isString,
41894            LegendSymbolMixin = H.LegendSymbolMixin, // @todo add as a requirement
41895            merge = H.merge,
41896            objectEach = H.objectEach,
41897            pick = H.pick,
41898            Point = H.Point, // @todo  add as a requirement
41899            removeEvent = H.removeEvent,
41900            splat = H.splat,
41901            SVGElement = H.SVGElement,
41902            syncTimeout = H.syncTimeout,
41903            win = H.win;
41904
41905        /**
41906         * This is the base series prototype that all other series types inherit from.
41907         * A new series is initialized either through the
41908         * {@link https://api.highcharts.com/highcharts/series|series} option structure,
41909         * or after the chart is initialized, through
41910         * {@link Highcharts.Chart#addSeries}.
41911         *
41912         * The object can be accessed in a number of ways. All series and point event
41913         * handlers give a reference to the `series` object. The chart object has a
41914         * {@link Highcharts.Chart.series|series} property that is a collection of all
41915         * the chart's series. The point objects and axis objects also have the same
41916         * reference.
41917         *
41918         * Another way to reference the series programmatically is by `id`. Add an id
41919         * in the series configuration options, and get the series object by {@link
41920         * Highcharts.Chart#get}.
41921         *
41922         * Configuration options for the series are given in three levels. Options for
41923         * all series in a chart are given in the
41924         * {@link https://api.highcharts.com/highcharts/plotOptions.series|
41925         * plotOptions.series} object. Then options for all series of a specific type
41926         * are given in the plotOptions of that type, for example `plotOptions.line`.
41927         * Next, options for one single series are given in the series array, or as
41928         * arguements to `chart.addSeries`.
41929         *
41930         * The data in the series is stored in various arrays.
41931         *
41932         * - First, `series.options.data` contains all the original config options for
41933         * each point whether added by options or methods like `series.addPoint`.
41934         * - Next, `series.data` contains those values converted to points, but in case
41935         * the series data length exceeds the `cropThreshold`, or if the data is
41936         * grouped, `series.data` doesn't contain all the points. It only contains the
41937         * points that have been created on demand.
41938         * - Then there's `series.points` that contains all currently visible point
41939         * objects. In case of cropping, the cropped-away points are not part of this
41940         * array. The `series.points` array starts at `series.cropStart` compared to
41941         * `series.data` and `series.options.data`. If however the series data is
41942         * grouped, these can't be correlated one to one.
41943         * - `series.xData` and `series.processedXData` contain clean x values,
41944         * equivalent to `series.data` and `series.points`.
41945         * - `series.yData` and `series.processedYData` contain clean y values,
41946         * equivalent to `series.data` and `series.points`.
41947         *
41948         * @class Highcharts.Series
41949         * @param  {Highcharts.Chart} chart
41950         *         The chart instance.
41951         * @param  {Options.plotOptions.series} options
41952         *         The series options.
41953         *
41954         */
41955
41956        /**
41957         * General options for all series types.
41958         * @optionparent plotOptions.series
41959         */
41960        H.Series = H.seriesType('line', null, { // base series options
41961
41962            /**
41963             * The SVG value used for the `stroke-linecap` and `stroke-linejoin`
41964             * of a line graph. Round means that lines are rounded in the ends and
41965             * bends.
41966             * 
41967             * @validvalue ["round", "butt", "square"]
41968             * @type {String}
41969             * @default round
41970             * @since 3.0.7
41971             * @apioption plotOptions.line.linecap
41972             */
41973
41974            /**
41975             * Pixel with of the graph line.
41976             * 
41977             * @type {Number}
41978             * @see In styled mode, the line stroke-width can be set with the
41979             * `.highcharts-graph` class name.
41980             * @sample {highcharts} highcharts/plotoptions/series-linewidth-general/
41981             *         On all series
41982             * @sample {highcharts} highcharts/plotoptions/series-linewidth-specific/
41983             *         On one single series
41984             * @default 2
41985             * @product highcharts highstock
41986             */
41987            lineWidth: 2,
41988
41989
41990            /**
41991             * For some series, there is a limit that shuts down initial animation
41992             * by default when the total number of points in the chart is too high.
41993             * For example, for a column chart and its derivatives, animation doesn't
41994             * run if there is more than 250 points totally. To disable this cap, set
41995             * `animationLimit` to `Infinity`.
41996             * 
41997             * @type {Number}
41998             * @apioption plotOptions.series.animationLimit
41999             */
42000
42001            /**
42002             * Allow this series' points to be selected by clicking on the graphic 
42003             * (columns, point markers, pie slices, map areas etc).
42004             *
42005             * @see [Chart#getSelectedPoints]
42006             *      (../class-reference/Highcharts.Chart#getSelectedPoints).
42007             * 
42008             * @type {Boolean}
42009             * @sample {highcharts} highcharts/plotoptions/series-allowpointselect-line/
42010             *         Line
42011             * @sample {highcharts}
42012             *         highcharts/plotoptions/series-allowpointselect-column/
42013             *         Column
42014             * @sample {highcharts} highcharts/plotoptions/series-allowpointselect-pie/
42015             *         Pie
42016             * @sample {highmaps} maps/plotoptions/series-allowpointselect/
42017             *         Map area
42018             * @sample {highmaps} maps/plotoptions/mapbubble-allowpointselect/
42019             *         Map bubble
42020             * @default false
42021             * @since 1.2.0
42022             */
42023            allowPointSelect: false,
42024
42025
42026
42027            /**
42028             * If true, a checkbox is displayed next to the legend item to allow
42029             * selecting the series. The state of the checkbox is determined by
42030             * the `selected` option.
42031             *
42032             * @productdesc {highmaps}
42033             * Note that if a `colorAxis` is defined, the color axis is represented in
42034             * the legend, not the series.
42035             * 
42036             * @type {Boolean}
42037             * @sample {highcharts} highcharts/plotoptions/series-showcheckbox-true/
42038             *         Show select box
42039             * @default false
42040             * @since 1.2.0
42041             */
42042            showCheckbox: false,
42043
42044
42045
42046            /**
42047             * Enable or disable the initial animation when a series is displayed.
42048             * The animation can also be set as a configuration object. Please
42049             * note that this option only applies to the initial animation of the
42050             * series itself. For other animations, see [chart.animation](#chart.
42051             * animation) and the animation parameter under the API methods. The
42052             * following properties are supported:
42053             * 
42054             * <dl>
42055             * 
42056             * <dt>duration</dt>
42057             * 
42058             * <dd>The duration of the animation in milliseconds.</dd>
42059             * 
42060             * <dt>
42060easing</dt>
42061             * 
42062             * <dd>A string reference to an easing function set on the `Math` object.
42063             * See the _Custom easing function_ demo below.</dd>
42064             * 
42065             * </dl>
42066             * 
42067             * Due to poor performance, animation is disabled in old IE browsers
42068             * for several chart types.
42069             * 
42070             * @type {Boolean}
42071             * @sample {highcharts} highcharts/plotoptions/series-animation-disabled/
42072             *         Animation disabled
42073             * @sample {highcharts} highcharts/plotoptions/series-animation-slower/
42074             *         Slower animation
42075             * @sample {highcharts} highcharts/plotoptions/series-animation-easing/
42076             *         Custom easing function
42077             * @sample {highstock} stock/plotoptions/animation-slower/
42078             *         Slower animation
42079             * @sample {highstock} stock/plotoptions/animation-easing/
42080             *         Custom easing function
42081             * @sample {highmaps} maps/plotoptions/series-animation-true/
42082             *         Animation enabled on map series
42083             * @sample {highmaps} maps/plotoptions/mapbubble-animation-false/
42084             *         Disabled on mapbubble series
42085             * @default {highcharts} true
42086             * @default {highstock} true
42087             * @default {highmaps} false
42088             */
42089            animation: {
42090                duration: 1000
42091            },
42092
42093            /**
42094             * A class name to apply to the series' graphical elements.
42095             * 
42096             * @type {String}
42097             * @since 5.0.0
42098             * @apioption plotOptions.series.className
42099             */
42100
42101            /**
42102             * The main color of the series. In line type series it applies to the
42103             * line and the point markers unless otherwise specified. In bar type
42104             * series it applies to the bars unless a color is specified per point.
42105             * The default value is pulled from the `options.colors` array.
42106             * 
42107             * In styled mode, the color can be defined by the
42108             * [colorIndex](#plotOptions.series.colorIndex) option. Also, the series
42109             * color can be set with the `.highcharts-series`, `.highcharts-color-{n}`,
42110             * `.highcharts-{type}-series` or `.highcharts-series-{n}` class, or
42111             * individual classes given by the `className` option.
42112             *
42113             * @productdesc {highmaps}
42114             * In maps, the series color is rarely used, as most choropleth maps use the
42115             * color to denote the value of each point. The series color can however be
42116             * used in a map with multiple series holding categorized data.
42117             * 
42118             * @type {Color}
42119             * @sample {highcharts} highcharts/plotoptions/series-color-general/
42120             *         General plot option
42121             * @sample {highcharts} highcharts/plotoptions/series-color-specific/
42122             *         One specific series
42123             * @sample {highcharts} highcharts/plotoptions/series-color-area/
42124             *         Area color
42125             * @sample {highmaps} maps/demo/category-map/
42126             *         Category map by multiple series
42127             * @apioption plotOptions.series.color
42128             */
42129
42130            /**
42131             * Styled mode only. A specific color index to use for the series, so its
42132             * graphic representations are given the class name `highcharts-color-
42133             * {n}`.
42134             * 
42135             * @type {Number}
42136             * @since 5.0.0
42137             * @apioption plotOptions.series.colorIndex
42138             */
42139
42140
42141            /**
42142             * Whether to connect a graph line across null points, or render a gap
42143             * between the two points on either side of the null.
42144             * 
42145             * @type {Boolean}
42146             * @sample {highcharts} highcharts/plotoptions/series-connectnulls-false/
42147             *         False by default
42148             * @sample {highcharts} highcharts/plotoptions/series-connectnulls-true/
42149             *         True
42150             * @product highcharts highstock
42151             * @apioption plotOptions.series.connectNulls
42152             */
42153
42154
42155            /**
42156             * You can set the cursor to "pointer" if you have click events attached
42157             * to the series, to signal to the user that the points and lines can
42158             * be clicked.
42159             * 
42160             * @validvalue [null, "default", "none", "help", "pointer", "crosshair"]
42161             * @type {String}
42162             * @see In styled mode, the series cursor can be set with the same classes
42163             * as listed under [series.color](#plotOptions.series.color).
42164             * @sample {highcharts} highcharts/plotoptions/series-cursor-line/
42165             *         On line graph
42166             * @sample {highcharts} highcharts/plotoptions/series-cursor-column/
42167             *         On columns
42168             * @sample {highcharts} highcharts/plotoptions/series-cursor-scatter/
42169             *         On scatter markers
42170             * @sample {highstock} stock/plotoptions/cursor/
42171             *         Pointer on a line graph
42172             * @sample {highmaps} maps/plotoptions/series-allowpointselect/
42173             *         Map area
42174             * @sample {highmaps} maps/plotoptions/mapbubble-allowpointselect/
42175             *         Map bubble
42176             * @apioption plotOptions.series.cursor
42177             */
42178
42179
42180            /**
42181             * A name for the dash style to use for the graph, or for some series types
42182             * the outline of each shape. The value for the `dashStyle` include:
42183             * 
42184             * *   Solid
42185             * *   ShortDash
42186             * *   ShortDot
42187             * *   ShortDashDot
42188             * *   ShortDashDotDot
42189             * *   Dot
42190             * *   Dash
42191             * *   LongDash
42192             * *   DashDot
42193             * *   LongDashDot
42194             * *   LongDashDotDot
42195             * 
42196             * @validvalue ["Solid", "ShortDash", "ShortDot", "ShortDashDot",
42197             *             "ShortDashDotDot", "Dot", "Dash" ,"LongDash", "DashDot",
42198             *             "LongDashDot", "LongDashDotDot"]
42199             * @type {String}
42200             * @see In styled mode, the [stroke dash-array](http://jsfiddle.net/gh/get/
42201             * library/pure/highcharts/highcharts/tree/master/samples/highcharts/css/
42202             * series-dashstyle/) can be set with the same classes as listed under
42203             * [series.color](#plotOptions.series.color).
42204             * 
42205             * @sample {highcharts} highcharts/plotoptions/series-dashstyle-all/
42206             *         Possible values demonstrated
42207             * @sample {highcharts} highcharts/plotoptions/series-dashstyle/
42208             *         Chart suitable for printing in black and white
42209             * @sample {highstock} highcharts/plotoptions/series-dashstyle-all/
42210             *         Possible values demonstrated
42211             * @sample {highmaps} highcharts/plotoptions/series-dashstyle-all/
42212             *         Possible values demonstrated
42213             * @sample {highmaps} maps/plotoptions/series-dashstyle/
42214             *         Dotted borders on a map
42215             * @default Solid
42216             * @since 2.1
42217             * @apioption plotOptions.series.dashStyle
42218             */
42219
42220            /**
42221             * Requires the Accessibility module.
42222             * 
42223             * A description of the series to add to the screen reader information
42224             * about the series.
42225             * 
42226             * @type {String}
42227             * @default undefined
42228             * @since 5.0.0
42229             * @apioption plotOptions.series.description
42230             */
42231
42232
42233
42234
42235
42236            /**
42237             * Enable or disable the mouse tracking for a specific series. This
42238             * includes point tooltips and click events on graphs and points. For
42239             * large datasets it improves performance.
42240             * 
42241             * @type {Boolean}
42242             * @sample {highcharts}
42243             *         highcharts/plotoptions/series-enablemousetracking-false/
42244             *         No mouse tracking
42245             * @sample {highmaps}
42246             *         maps/plotoptions/series-enablemousetracking-false/
42247             *         No mouse tracking
42248             * @default true
42249             * @apioption plotOptions.series.enableMouseTracking
42250             */
42251
42252            /**
42253             * By default, series are exposed to screen readers as regions. By enabling
42254             * this option, the series element itself will be exposed in the same
42255             * way as the data points. This is useful if the series is not used
42256             * as a grouping entity in the chart, but you still want to attach a
42257             * description to the series.
42258             * 
42259             * Requires the Accessibility module.
42260             * 
42261             * @type {Boolean}
42262             * @sample highcharts/accessibility/art-grants/
42263             *         Accessible data visualization
42264             * @default undefined
42265             * @since 5.0.12
42266             * @apioption plotOptions.series.exposeElementToA11y
42267             */
42268
42269            /**
42270             * Whether to use the Y extremes of the total chart width or only the
42271             * zoomed area when zooming in on parts of the X axis. By default, the
42272             * Y axis adjusts to the min and max of the visible data. Cartesian
42273             * series only.
42274             * 
42275             * @type {Boolean}
42276             * @default false
42277             * @since 4.1.6
42278             * @product highcharts highstock
42279             * @apioption plotOptions.series.getExtremesFromAll
42280             */
42281
42282            /**
42283             * An id for the series. This can be used after render time to get a
42284             * pointer to the series object through `chart.get()`.
42285             * 
42286             * @type {String}
42287             * @sample {highcharts} highcharts/plotoptions/series-id/ Get series by id
42288             * @since 1.2.0
42289             * @apioption series.id
42290             */
42291
42292            /**
42293             * The index of the series in the chart, affecting the internal index
42294             * in the `chart.series` array, the visible Z index as well as the order
42295             * in the legend.
42296             * 
42297             * @type {Number}
42298             * @default undefined
42299             * @since 2.3.0
42300             * @apioption series.index
42301             */
42302
42303            /**
42304             * An array specifying which option maps to which key in the data point
42305             * array. This makes it convenient to work with unstructured data arrays
42306             * from different sources.
42307             * 
42308             * @type {Array<String>}
42309             * @see [series.data](#series.line.data)
42310             * @sample {highcharts|highstock} highcharts/series/data-keys/
42311             *         An extended data array with keys
42312             * @since 4.1.6
42313             * @product highcharts highstock
42314             * @apioption plotOptions.series.keys
42315             */
42316
42317            /**
42318             * The sequential index of the series in the legend.
42319             * 
42320             * @sample {highcharts|highstock} highcharts/series/legendindex/
42321             *         Legend in opposite order
42322             * @type {Number}
42323             * @see [legend.reversed](#legend.reversed), [yAxis.reversedStacks](#yAxis.
42324             * reversedStacks)
42325             * @apioption series.legendIndex
42326             */
42327
42328            /**
42329             * The line cap used for line ends and line joins on the graph.
42330             * 
42331             * @validvalue ["round", "square"]
42332             * @type {String}
42333             * @default round
42334             * @product highcharts highstock
42335             * @apioption plotOptions.series.linecap
42336             */
42337
42338            /**
42339             * The [id](#series.id) of another series to link to. Additionally,
42340             * the value can be ":previous" to link to the previous series. When
42341             * two series are linked, only the first one appears in the legend.
42342             * Toggling the visibility of this also toggles the linked series.
42343             * 
42344             * @type {String}
42345             * @sample {highcharts} highcharts/demo/arearange-line/ Linked series
42346             * @sample {highstock} highcharts/demo/arearange-line/ Linked series
42347             * @since 3.0
42348             * @product highcharts highstock
42349             * @apioption plotOptions.series.linkedTo
42350             */
42351
42352            /**
42353             * The name of the series as shown in the legend, tooltip etc.
42354             * 
42355             * @type {String}
42356             * @sample {highcharts} highcharts/series/name/ Series name
42357             * @sample {highmaps} maps/demo/category-map/ Series name
42358             * @apioption series.name
42359             */
42360
42361            /**
42362             * The color for the parts of the graph or points that are below the
42363             * [threshold](#plotOptions.series.threshold).
42364             * 
42365             * @type {Color}
42366             * @see In styled mode, a negative color is applied by setting this
42367             * option to `true` combined with the `.highcharts-negative` class name.
42368             * 
42369             * @sample {highcharts} highcharts/plotoptions/series-negative-color/
42370             *         Spline, area and column
42371             * @sample {highcharts} highcharts/plotoptions/arearange-negativecolor/
42372             *         Arearange
42373             * @sample {highcharts} highcharts/css/series-negative-color/
42374             *         Styled mode
42375             * @sample {highstock} highcharts/plotoptions/series-negative-color/
42376             *         Spline, area and column
42377             * @sample {highstock} highcharts/plotoptions/arearange-negativecolor/
42378             *         Arearange
42379             * @sample {highmaps} highcharts/plotoptions/series-negative-color/
42380             *         Spline, area and column
42381             * @sample {highmaps} highcharts/plotoptions/arearange-negativecolor/
42382             *         Arearange
42383             * @default null
42384             * @since 3.0
42385             * @apioption plotOptions.series.negativeColor
42386             */
42387
42388            /**
42389             * Same as [accessibility.pointDescriptionFormatter](#accessibility.
42390             * pointDescriptionFormatter), but for an individual series. Overrides
42391             * the chart wide configuration.
42392             * 
42393             * @type {Function}
42394             * @since 5.0.12
42395             * @apioption plotOptions.series.pointDescriptionFormatter
42396             */
42397
42398            /**
42399             * If no x values are given for the points in a series, `pointInterval`
42400             * defines the interval of the x values. For example, if a series contains
42401             * one value every decade starting from year 0, set `pointInterval` to
42402             * `10`. In true `datetime` axes, the `pointInterval` is set in
42403             * milliseconds.
42404             * 
42405             * It can be also be combined with `pointIntervalUnit` to draw irregular
42406             * time intervals.
42407             * 
42408             * @type {Number}
42409             * @sample {highcharts} highcharts/plotoptions/series-pointstart-datetime/
42410             *         Datetime X axis
42411             * @sample {highstock} stock/plotoptions/pointinterval-pointstart/
42412             *         Using pointStart and pointInterval
42413             * @default 1
42414             * @product highcharts highstock
42415             * @apioption plotOptions.series.pointInterval
42416             */
42417
42418            /**
42419             * On datetime series, this allows for setting the
42420             * [pointInterval](#plotOptions.series.pointInterval) to irregular time 
42421             * units, `day`, `month` and `year`. A day is usually the same as 24 hours,
42422             * but `pointIntervalUnit` also takes the DST crossover into consideration
42423             * when dealing with local time. Combine this option with `pointInterval`
42424             * to draw weeks, quarters, 6 months, 10 years etc.
42425             * 
42426             * @validvalue [null, "day", "month", "year"]
42427             * @type {String}
42428             * @sample {highcharts} highcharts/plotoptions/series-pointintervalunit/
42429             *         One point a month
42430             * @sample {highstock} highcharts/plotoptions/series-pointintervalunit/
42431             *         One point a month
42432             * @since 4.1.0
42433             * @product highcharts highstock
42434             * @apioption plotOptions.series.pointIntervalUnit
42435             */
42436
42437            /**
42438             * Possible values: `null`, `"on"`, `"between"`.
42439             * 
42440             * In a column chart, when pointPlacement is `"on"`, the point will
42441             * not create any padding of the X axis. In a polar column chart this
42442             * means that the first column points directly north. If the pointPlacement
42443             * is `"between"`, the columns will be laid out between ticks. This
42444             * is useful for example for visualising an amount between two points
42445             * in time or in a certain sector of a polar chart.
42446             * 
42447             * Since Highcharts 3.0.2, the point placement can also be numeric,
42448             * where 0 is on the axis value, -0.5 is between this value and the
42449             * previous, and 0.5 is between this value and the next. Unlike the
42450             * textual options, numeric point placement options won't affect axis
42451             * padding.
42452             * 
42453             * Note that pointPlacement needs a [pointRange](#plotOptions.series.
42454             * pointRange) to work. For column series this is computed, but for
42455             * line-type series it needs to be set.
42456             * 
42457             * Defaults to `null` in cartesian charts, `"between"` in polar charts.
42458             * 
42459             * @validvalue [null, "on", "between"]
42460             * @type {String|Number}
42461             * @see [xAxis.tickmarkPlacement](#xAxis.tickmarkPlacement)
42462             * @sample {highcharts|highstock}
42463             *         highcharts/plotoptions/series-pointplacement-between/
42464             *         Between in a column chart
42465             * @sample {highcharts|highstock}
42466             *         highcharts/plotoptions/series-pointplacement-numeric/
42467             *         Numeric placement for custom layout
42468             * @default null
42469             * @since 2.3.0
42470             * @product highcharts highstock
42471             * @apioption plotOptions.series.pointPlacement
42472             */
42473
42474            /**
42475             * If no x values are given for the points in a series, pointStart defines
42476             * on what value to start. For example, if a series contains one yearly
42477             * value starting from 1945, set pointStart to 1945.
42478             * 
42479             * @type {Number}
42480             * @sample {highcharts} highcharts/plotoptions/series-pointstart-linear/
42481             *         Linear
42482             * @sample {highcharts} highcharts/plotoptions/series-pointstart-datetime/
42483             *         Datetime
42484             * @sample {highstock} stock/plotoptions/pointinterval-pointstart/
42485             *         Using pointStart and pointInterval
42486             * @default 0
42487             * @product highcharts highstock
42488             * @apioption plotOptions.series.pointStart
42489             */
42490
42491            /**
42492             * Whether to select the series initially. If `showCheckbox` is true,
42493             * the checkbox next to the series name in the legend will be checked for a
42494             * selected series.
42495             * 
42496             * @type {Boolean}
42497             * @sample {highcharts} highcharts/plotoptions/series-selected/
42498             *         One out of two series selected
42499             * @default false
42500             * @since 1.2.0
42501             * @apioption plotOptions.series.selected
42502             */
42503
42504            /**
42505             * Whether to apply a drop shadow to the graph line. Since 2.3 the shadow
42506             * can be an object configuration containing `color`, `offsetX`, `offsetY`,
42507             *  `opacity` and `width`.
42508             * 
42509             * @type {Boolean|Object}
42510             * @sample {highcharts} highcharts/plotoptions/series-shadow/ Shadow enabled
42511             * @default false
42512             * @apioption plotOptions.series.shadow
42513             */
42514
42515            /**
42516             * Whether to display this particular series or series type in the legend.
42517             * The default value is `true` for standalone series, `false` for linked
42518             * series.
42519             * 
42520             * @type {Boolean}
42521             * @sample {highcharts} highcharts/plotoptions/series-showinlegend/
42522             *         One series in the legend, one hidden
42523             * @default true
42524             * @apioption plotOptions.series.showInLegend
42525             */
42526
42527            /**
42528             * If set to `True`, the accessibility module will skip past the points
42529             * in this series for keyboard navigation.
42530             * 
42531             * @type {Boolean}
42532             * @since 5.0.12
42533             * @apioption plotOptions.series.skipKeyboardNavigation
42534             */
42535
42536            /**
42537             * This option allows grouping series in a stacked chart. The stack
42538             * option can be a string or a number or anything else, as long as the
42539             * grouped series' stack options match each other.
42540             * 
42541             * @type {String}
42542             * @sample {highcharts} highcharts/series/stack/ Stacked and grouped columns
42543             * @default null
42544             * @since 2.1
42545             * @product highcharts highstock
42546             * @apioption series.stack
42547             */
42548
42549            /**
42550             * Whether to stack the values of each series on top of each other.
42551             * Possible values are `null` to disable, `"normal"` to stack by value or
42552             * `"percent"`. When stacking is enabled, data must be sorted in ascending
42553             * X order. A special stacking option is with the streamgraph series type,
42554             * where the stacking option is set to `"stream"`.
42555             * 
42556             * @validvalue [null, "normal", "percent"]
42557             * @type {String}
42558             * @see [yAxis.reversedStacks](#yAxis.reversedStacks)
42559             * @sample {highcharts} highcharts/plotoptions/series-stacking-line/
42560             *         Line
42561             * @sample {highcharts} highcharts/plotoptions/series-stacking-column/
42562             *         Column
42563             * @sample {highcharts} highcharts/plotoptions/series-stacking-bar/
42564             *         Bar
42565             * @sample {highcharts} highcharts/plotoptions/series-stacking-area/
42566             *         Area
42567             * @sample {highcharts} highcharts/plotoptions/series-stacking-percent-line/
42568             *         Line
42569             * @sample {highcharts}
42570             *         highcharts/plotoptions/series-stacking-percent-column/
42571             *         Column
42572             * @sample {highcharts} highcharts/plotoptions/series-stacking-percent-bar/
42573             *         Bar
42574             * @sample {highcharts} highcharts/plotoptions/series-stacking-percent-area/
42575             *         Area
42576             * @sample {highstock} stock/plotoptions/stacking/
42577             *         Area
42578             * @default null
42579             * @product highcharts highstock
42580             * @apioption plotOptions.series.stacking
42581             */
42582
42583            /**
42584             * Whether to apply steps to the line. Possible values are `left`, `center`
42585             * and `right`.
42586             * 
42587             * @validvalue [null, "left", "center", "right"]
42588             * @type {String}
42589             * @sample {highcharts} highcharts/plotoptions/line-step/
42590             *         Different step line options
42591             * @sample {highcharts} highcharts/plotoptions/area-step/
42592             *         Stepped, stacked area
42593             * @sample {highstock} stock/plotoptions/line-step/
42594             *         Step line
42595             * @default {highcharts} null
42596             * @default {highstock} false
42597             * @since 1.2.5
42598             * @product highcharts highstock
42599             * @apioption plotOptions.series.step
42600             */
42601
42602            /**
42603             * The threshold, also called zero level or base level. For line type
42604             * series this is only used in conjunction with
42605             * [negativeColor](#plotOptions.series.negativeColor).
42606             * 
42607             * @type {Number}
42608             * @see [softThreshold](#plotOptions.series.softThreshold).
42609             * @default 0
42610             * @since 3.0
42611             * @product highcharts highstock
42612             * @apioption plotOptions.series.threshold
42613             */
42614
42615            /**
42616             * The type of series, for example `line` or `column`.
42617             * 
42618             * @validvalue [null, "line", "spline", "column", "area", "areaspline",
42619             *       "pie", "arearange", "areasplinerange", "boxplot", "bubble",
42620             *       "columnrange", "errorbar", "funnel", "gauge", "scatter",
42621             *       "waterfall"]
42622             * @type {String}
42623             * @sample {highcharts} highcharts/series/type/
42624             *         Line and column in the same chart
42625             * @sample {highmaps} maps/demo/mapline-mappoint/
42626             *         Multiple types in the same map
42627             * @apioption series.type
42628             */
42629
42630            /**
42631             * Set the initial visibility of the series.
42632             * 
42633             * @type {Boolean}
42634             * @sample {highcharts} highcharts/plotoptions/series-visible/
42635             *         Two series, one hidden and one visible
42636             * @sample {highstock} stock/plotoptions/series-visibility/
42637             *         Hidden series
42638             * @default true
42639             * @apioption plotOptions.series.visible
42640             */
42641
42642            /**
42643             * When using dual or multiple x axes, this number defines which xAxis
42644             * the particular series is connected to. It refers to either the [axis
42645             * id](#xAxis.id) or the index of the axis in the xAxis array, with
42646             * 0 being the first.
42647             * 
42648             * @type {Number|String}
42649             * @default 0
42650             * @product highcharts highstock
42651             * @apioption series.xAxis
42652             */
42653
42654            /**
42655             * When using dual or multiple y axes, this number defines which yAxis
42656             * the particular series is connected to. It refers to either the [axis
42657             * id](#yAxis.id) or the index of the axis in the yAxis array, with
42658             * 0 being the first.
42659             * 
42660             * @type {Number|String}
42661             * @sample {highcharts} highcharts/series/yaxis/
42662             *         Apply the column series to the secondary Y axis
42663             * @default 0
42664             * @product highcharts highstock
42665             * @apioption series.yAxis
42666             */
42667
42668            /**
42669             * Defines the Axis on which the zones are applied.
42670             * 
42671             * @type {String}
42672             * @see [zones](#plotOptions.series.zones)
42673             * @sample {highcharts} highcharts/series/color-zones-zoneaxis-x/
42674             *         Zones on the X-Axis
42675             * @sample {highstock} highcharts/series/color-zones-zoneaxis-x/
42676             *         Zones on the X-Axis
42677             * @default y
42678             * @since 4.1.0
42679             * @product highcharts highstock
42680             * @apioption plotOptions.series.zoneAxis
42681             */
42682
42683            /**
42684             * Define the visual z index of the series.
42685             * 
42686             * @type {Number}
42687             * @sample {highcharts} highcharts/plotoptions/series-zindex-default/
42688             *         With no z index, the series defined last are on top
42689             * @sample {highcharts} highcharts/plotoptions/series-zindex/
42690             *         With a z index, the series with the highest z index is on top
42691             * @sample {highstock} highcharts/plotoptions/series-zindex-default/
42692             *         With no z index, the series defined last are on top
42693             * @sample {highstock} highcharts/plotoptions/series-zindex/
42694             *         With a z index, the series with the highest z index is on top
42695             * @product highcharts highstock
42696             * @apioption series.zIndex
42697             */
42698
42699            /**
42700             * General event handlers for the series items. These event hooks can also
42701             * be attached to the series at run time using the `Highcharts.addEvent`
42702             * function.
42703             */
42704            events: {
42705
42706                /**
42707                 * Fires after the series has finished its initial animation, or in
42708                 * case animation is disabled, immediately as the series is displayed.
42709                 * 
42710                 * @type {Function}
42711                 * @context Series
42712                 * @sample {highcharts}
42713                 *         highcharts/plotoptions/series-events-afteranimate/
42714                 *         Show label after animate
42715                 * @sample {highstock}
42716                 *         highcharts/plotoptions/series-events-afteranimate/
42717                 *         Show label after animate
42718                 * @since 4.0
42719                 * @product highcharts highstock
42720                 * @apioption plotOptions.series.events.afterAnimate
42721                 */
42722
42723                /**
42724                 * Fires when the checkbox next to the series' name in the legend is
42725                 * clicked. One parameter, `event`, is passed to the function. The state
42726                 * of the checkbox is found by `event.checked`. The checked item is
42727                 * found by `event.item`. Return `false` to prevent the default action
42728                 * which is to toggle the select state of the series.
42729                 * 
42730                 * @type {Function}
42731                 * @context Series
42732                 * @sample {highcharts}
42733                 *         highcharts/plotoptions/series-events-checkboxclick/
42734                 *         Alert checkbox status
42735                 * @since 1.2.0
42736                 * @apioption plotOptions.series.events.checkboxClick
42737                 */
42738
42739                /**
42740                 * Fires when the series is clicked. One parameter, `event`, is passed
42741                 * to the function, containing common event information. Additionally,
42742                 * `event.point` holds a pointer to the nearest point on the graph.
42743                 * 
42744                 * @type {Function}
42745                 * @context Series
42746                 * @sample {highcharts} highcharts/plotoptions/series-events-click/
42747                 *         Alert click info
42748                 * @sample {highstock} stock/plotoptions/series-events-click/
42749                 *         Alert click info
42750                 * @sample {highmaps} maps/plotoptions/series-events-click/
42751                 *         Display click info in subtitle
42752                 * @apioption plotOptions.series.events.click
42753                 */
42754
42755                /**
42756                 * Fires when the series is hidden after chart generation time, either
42757                 * by clicking the legend item or by calling `.hide()`.
42758                 * 
42759                 * @type {Function}
42760                 * @context Series
42761                 * @sample {highcharts} highcharts/plotoptions/series-events-hide/
42762                 *         Alert when the series is hidden by clicking the legend item
42763                 * @since 1.2.0
42764                 * @apioption plotOptions.series.events.hide
42765                 */
42766
42767                /**
42768                 * Fires when the legend item belonging to the series is clicked. One
42769                 * parameter, `event`, is passed to the function. The default action
42770                 * is to toggle the visibility of the series. This can be prevented
42771                 * by returning `false` or calling `event.preventDefault()`.
42772                 * 
42773                 * @type {Function}
42774                 * @context Series
42775                 * @sample {highcharts}
42776                 *         highcharts/plotoptions/series-events-legenditemclick/
42777                 *         Confirm hiding and showing
42778                 * @apioption plotOptions.series.events.legendItemClick
42779                 */
42780
42781                /**
42782                 * Fires when the mouse leaves the graph. One parameter, `event`, is
42783                 * passed to the function, containing common event information. If the
42784                 * [stickyTracking](#plotOptions.series) option is true, `mouseOut`
42785                 * doesn't happen before the mouse enters another graph or leaves the
42786                 * plot area.
42787                 * 
42788                 * @type {Function}
42789                 * @context Series
42790                 * @sample {highcharts}
42791                 *         highcharts/plotoptions/series-events-mouseover-sticky/
42792                 *         With sticky tracking    by default
42793                 * @sample {highcharts}
42794                 *         highcharts/plotoptions/series-events-mouseover-no-sticky/
42795                 *         Without sticky tracking
42796                 * @apioption plotOptions.series.events.mouseOut
42797                 */
42798
42799                /**
42800                 * Fires when the mouse enters the graph. One parameter, `event`, is
42801                 * passed to the function, containing common event information.
42802                 * 
42803                 * @type {Function}
42804                 * @context Series
42805                 * @sample {highcharts}
42806                 *         highcharts/plotoptions/series-events-mouseover-sticky/
42807                 *         With sticky tracking by default
42808                 * @sample {highcharts}
42809                 *         highcharts/plotoptions/series-events-mouseover-no-sticky/
42810                 *         Without sticky tracking
42811                 * @apioption plotOptions.series.events.mouseOver
42812                 */
42813
42814                /**
42815                 * Fires when the series is shown after chart generation time, either
42816                 * by clicking the legend item or by calling `.show()`.
42817                 * 
42818                 * @type {Function}
42819                 * @context Series
42820                 * @sample {highcharts} highcharts/plotoptions/series-events-show/
42821                 *         Alert when the series is shown by clicking the legend item.
42822                 * @since 1.2.0
42823                 * @apioption plotOptions.series.events.show
42824                 */
42825
42826            },
42827
42828
42829
42830            /**
42831             * Options for the point markers of line-like series. Properties like
42832             * `fillColor`, `lineColor` and `lineWidth` define the visual appearance
42833             * of the markers. Other series types, like column series, don't have
42834             * markers, but have visual options on the series level instead.
42835             * 
42836             * In styled mode, the markers can be styled with the `.highcharts-point`,
42837             * `.highcharts-point-hover` and `.highcharts-point-select`
42838             * class names.
42839             * 
42840             * @product highcharts highstock
42841             */
42842            marker: {
42843
42844
42845
42846                /**
42847                 * The width of the point marker's outline.
42848                 * 
42849                 * @type {Number}
42850                 * @sample {highcharts} highcharts/plotoptions/series-marker-fillcolor/
42851                 *         2px blue marker
42852                 * @default 0
42853                 * @product highcharts highstock
42854                 */
42855                lineWidth: 0,
42856
42857
42858                /**
42859                 * The color of the point marker's outline. When `null`, the series'
42860                 * or point's color is used.
42861                 * 
42862                 * @type {Color}
42863                 * @sample {highcharts} highcharts/plotoptions/series-marker-fillcolor/
42864                 *         Inherit from series color (null)
42865                 * @product highcharts highstock
42866                 */
42867                lineColor: '#ffffff',
42868
42869                /**
42870                 * The fill color of the point marker. When `null`, the series' or
42871                 * point's color is used.
42872                 * 
42873                 * @type {Color}
42874                 * @sample {highcharts} highcharts/plotoptions/series-marker-fillcolor/
42875                 *         White fill
42876                 * @default null
42877                 * @product highcharts highstock
42878                 * @apioption plotOptions.series.marker.fillColor
42879                 */
42880
42881
42882
42883                /**
42884                 * Enable or disable the point marker. If `null`, the markers are hidden
42885                 * when the data is dense, and shown for more widespread data points.
42886                 * 
42887                 * @type {Boolean}
42888                 * @sample {highcharts} highcharts/plotoptions/series-marker-enabled/
42889                 *         Disabled markers
42890                 * @sample {highcharts}
42891                 *         highcharts/plotoptions/series-marker-enabled-false/
42892                 *         Disabled in normal state but enabled on hover
42893                 * @sample {highstock} stock/plotoptions/series-marker/
42894                 *         Enabled markers
42895                 * @default {highcharts} null
42896                 * @default {highstock} false
42897                 * @product highcharts highstock
42898                 * @apioption plotOptions.series.marker.enabled
42899                 */
42900
42901                /**
42902                 * Image markers only. Set the image width explicitly. When using this
42903                 * option, a `width` must also be set.
42904                 * 
42905                 * @type {Number}
42906                 * @sample {highcharts}
42907                 *         highcharts/plotoptions/series-marker-width-height/
42908                 *         Fixed width and height
42909                 * @sample {highstock}
42910                 *         highcharts/plotoptions/series-marker-width-height/
42911                 *         Fixed width and height
42912                 * @default null
42913                 * @since 4.0.4
42914                 * @product highcharts highstock
42915                 * @apioption plotOptions.series.marker.height
42916                 */
42917
42918                /**
42919                 * A predefined shape or symbol for the marker. When null, the symbol
42920                 * is pulled from options.symbols. Other possible values are "circle",
42921                 * "square", "diamond", "triangle" and "triangle-down".
42922                 * 
42923                 * Additionally, the URL to a graphic can be given on this form:
42924                 * "url(graphic.png)". Note that for the image to be applied to exported
42925                 * charts, its URL needs to be accessible by the export server.
42926                 * 
42927                 * Custom callbacks for symbol path generation can also be added to
42928                 * `Highcharts.SVGRenderer.prototype.symbols`. The callback is then
42929                 * used by its method name, as shown in the demo.
42930                 * 
42931                 * @validvalue [null, "circle", "square", "diamond", "triangle",
42932                 *         "triangle-down"]
42933                 * @type {String}
42934                 * @sample {highcharts} highcharts/plotoptions/series-marker-symbol/
42935                 *         Predefined, graphic and custom markers
42936                 * @sample {highstock} highcharts/plotoptions/series-marker-symbol/
42937                 *         Predefined, graphic and custom markers
42938                 * @default null
42939                 * @product highcharts highstock
42940                 * @apioption plotOptions.series.marker.symbol
42941                 */
42942
42943                /**
42944                 * The radius of the point marker.
42945                 * 
42946                 * @type {Number}
42947                 * @sample {highcharts} highcharts/plotoptions/series-marker-radius/
42948                 *         Bigger markers
42949                 * @default 4
42950                 * @product highcharts highstock
42951                 */
42952                radius: 4,
42953
42954                /**
42955                 * Image markers only. Set the image width explicitly. When using this
42956                 * option, a `height` must also be set.
42957                 * 
42958                 * @type {Number}
42959                 * @sample {highcharts}
42960                 *         highcharts/plotoptions/series-marker-width-height/
42961                 *         Fixed width and height
42962                 * @sample {highstock}
42963                 *         highcharts/plotoptions/series-marker-width-height/
42964                 *         Fixed width and height
42965                 * @default null
42966                 * @since 4.0.4
42967                 * @product highcharts highstock
42968                 * @apioption plotOptions.series.marker.width
42969                 */
42970
42971
42972                /**
42973                 * States for a single point marker.
42974                 * @product highcharts highstock
42975                 */
42976                states: {
42977                    /**
42978                     * The hover state for a single point marker.
42979                     * @product highcharts highstock
42980                     */
42981                    hover: {
42982
42983                        /**
42984                         * Animation when hovering over the marker.
42985                         * @type {Boolean|Object}
42986                         */
42987                        animation: {
42988                            duration: 50
42989                        },
42990
42991                        /**
42992                         * Enable or disable the point marker.
42993                         * 
42994                         * @type {Boolean}
42995                         * @sample {highcharts}
42996                         *         highcharts/plotoptions/series-marker-states-hover-enabled/
42997                         *         Disabled hover state
42998                         * @default true
42999                         * @product highcharts highstock
43000                         */
43001                        enabled: true,
43002
43003                        /**
43004                         * The fill color of the marker in hover state.
43005                         * 
43006                         * @type {Color}
43007                         * @default null
43008                         * @product highcharts highstock
43009                         * @apioption plotOptions.series.marker.states.hover.fillColor
43010                         */
43011
43012                        /**
43013                         * The color of the point marker's outline. When `null`, the
43014                         * series' or point's color is used.
43015                         * 
43016                         * @type {Color}
43017                         * @sample {highcharts}
43018                         *         highcharts/plotoptions/series-marker-states-hover-linecolor/
43019                         *         White fill color, black line color
43020                         * @default #ffffff
43021                         * @product highcharts highstock
43022                         * @apioption plotOptions.series.marker.states.hover.lineColor
43023                         */
43024
43025                        /**
43026                         * The width of the point marker's outline.
43027                         * 
43028                         * @type {Number}
43029                         * @sample {highcharts}
43030                         *         highcharts/plotoptions/series-marker-states-hover-linewidth/
43031                         *         3px line width
43032                         * @default 0
43033                         * @product highcharts highstock
43034                         * @apioption plotOptions.series.marker.states.hover.lineWidth
43035                         */
43036
43037                        /**
43038                         * The radius of the point marker. In hover state, it defaults to the
43039                         * normal state's radius + 2 as per the [radiusPlus](#plotOptions.series.
43040                         * marker.states.hover.radiusPlus) option.
43041                         * 
43042                         * @type {Number}
43043                         * @sample {highcharts} highcharts/plotoptions/series-marker-states-hover-radius/ 10px radius
43044                         * @product highcharts highstock
43045                         * @apioption plotOptions.series.marker.states.hover.radius
43046                         */
43047
43048                        /**
43049                         * The number of pixels to increase the radius of the hovered point.
43050                         * 
43051                         * @type {Number}
43052                         * @sample {highcharts} highcharts/plotoptions/series-states-hover-linewidthplus/ 5 pixels greater radius on hover
43053                         * @sample {highstock} highcharts/plotoptions/series-states-hover-linewidthplus/ 5 pixels greater radius on hover
43054                         * @default 2
43055                         * @since 4.0.3
43056                         * @product highcharts highstock
43057                         */
43058                        radiusPlus: 2,
43059
43060
43061
43062                        /**
43063                         * The additional line width for a hovered point.
43064                         * 
43065                         * @type {Number}
43066                         * @sample {highcharts} highcharts/plotoptions/series-states-hover-linewidthplus/ 2 pixels wider on hover
43067                         * @sample {highstock} highcharts/plotoptions/series-states-hover-linewidthplus/ 2 pixels wider on hover
43068                         * @default 1
43069                         * @since 4.0.3
43070                         * @product highcharts highstock
43071                         */
43072                        lineWidthPlus: 1
43073
43074                    },
43075
43076
43077
43078
43079                    /**
43080                     * The appearance of the point marker when selected. In order to
43081                     * allow a point to be selected, set the `series.allowPointSelect`
43082                     * option to true.
43083                     * 
43084                     * @product highcharts highstock
43085                     */
43086                    select: {
43087
43088                        /**
43089                         * Enable or disable visible feedback for selection.
43090                         * 
43091                         * @type {Boolean}
43092                         * @sample {highcharts} highcharts/plotoptions/series-marker-states-select-enabled/
43093                         *         Disabled select state
43094                         * @default true
43095                         * @product highcharts highstock
43096                         * @apioption plotOptions.series.marker.states.select.enabled
43097                         */
43098
43099                        /**
43100                         * The fill color of the point marker.
43101                         * 
43102                         * @type {Color}
43103                         * @sample {highcharts} highcharts/plotoptions/series-marker-states-select-fillcolor/
43104                         *         Solid red discs for selected points
43105                         * @default null
43106                         * @product highcharts highstock
43107                         */
43108                        fillColor: '#cccccc',
43109
43110
43111
43112                        /**
43113                         * The color of the point marker's outline. When `null`, the series'
43114                         * or point's color is used.
43115                         * 
43116                         * @type {Color}
43117                         * @sample {highcharts} highcharts/plotoptions/series-marker-states-select-linecolor/
43118                         *         Red line color for selected points
43119                         * @default #000000
43120                         * @product highcharts highstock
43121                         */
43122                        lineColor: '#000000',
43123
43124
43125
43126                        /**
43127                         * The width of the point marker's outline.
43128                         * 
43129                         * @type {Number}
43130                         * @sample {highcharts} highcharts/plotoptions/series-marker-states-select-linewidth/
43131                         *         3px line width for selected points
43132                         * @default 0
43133                         * @product highcharts highstock
43134                         */
43135                        lineWidth: 2
43136
43137                        /**
43138                         * The radius of the point marker. In hover state, it defaults to the
43139                         * normal state's radius + 2.
43140                         * 
43141                         * @type {Number}
43142                         * @sample {highcharts} highcharts/plotoptions/series-marker-states-select-radius/
43143                         *         10px radius for selected points
43144                         * @product highcharts highstock
43145                         * @apioption plotOptions.series.marker.states.select.radius
43146                         */
43147
43148                    }
43149
43150                }
43151            },
43152
43153
43154
43155            /**
43156             * Properties for each single point.
43157             */
43158            point: {
43159
43160
43161                /**
43162                 * Events for each single point.
43163                 */
43164                events: {
43165
43166                    /**
43167                     * Fires when a point is clicked. One parameter, `event`, is passed
43168                     * to the function, containing common event information.
43169                     * 
43170                     * If the `series.allowPointSelect` option is true, the default action
43171                     * for the point's click event is to toggle the point's select state.
43172                     *  Returning `false` cancels this action.
43173                     * 
43174                     * @type {Function}
43175                     * @context Point
43176                     * @sample {highcharts} highcharts/plotoptions/series-point-events-click/ Click marker to alert values
43177                     * @sample {highcharts} highcharts/plotoptions/series-point-events-click-column/ Click column
43178                     * @sample {highcharts} highcharts/plotoptions/series-point-events-click-url/ Go to URL
43179                     * @sample {highmaps} maps/plotoptions/series-point-events-click/ Click marker to display values
43180                     * @sample {highmaps} maps/plotoptions/series-point-events-click-url/ Go to URL
43181                     * @apioption plotOptions.series.point.events.click
43182                     */
43183
43184                    /**
43185                     * Fires when the mouse leaves the area close to the point. One parameter,
43186                     * `event`, is passed to the function, containing common event information.
43187                     * 
43188                     * @type {Function}
43189                     * @context Point
43190                     * @sample {highcharts} highcharts/plotoptions/series-point-events-mouseover/ Show values in the chart's corner on mouse over
43191                     * @apioption plotOptions.series.point.events.mouseOut
43192                     */
43193
43194                    /**
43195                     * Fires when the mouse enters the area close to the point. One parameter,
43196                     * `event`, is passed to the function, containing common event information.
43197                     * 
43198                     * @type {Function}
43199                     * @context Point
43200                     * @sample {highcharts} highcharts/plotoptions/series-point-events-mouseover/ Show values in the chart's corner on mouse over
43201                     * @apioption plotOptions.series.point.events.mouseOver
43202                     */
43203
43204                    /**
43205                     * Fires when the point is removed using the `.remove()` method. One
43206                     * parameter, `event`, is passed to the function. Returning `false`
43207                     * cancels the operation.
43208                     * 
43209                     * @type {Function}
43210                     * @context Point
43211                     * @sample {highcharts} highcharts/plotoptions/series-point-events-remove/ Remove point and confirm
43212                     * @since 1.2.0
43213                     * @apioption plotOptions.series.point.events.remove
43214                     */
43215
43216                    /**
43217                     * Fires when the point is selected either programmatically or following
43218                     * a click on the point. One parameter, `event`, is passed to the function.
43219                     *  Returning `false` cancels the operation.
43220                     * 
43221                     * @type {Function}
43222                     * @context Point
43223                     * @sample {highcharts} highcharts/plotoptions/series-point-events-select/ Report the last selected point
43224                     * @sample {highmaps} maps/plotoptions/series-allowpointselect/ Report select and unselect
43225                     * @since 1.2.0
43226                     * @apioption plotOptions.series.point.events.select
43227                     */
43228
43229                    /**
43230                     * Fires when the point is unselected either programmatically or following
43231                     * a click on the point. One parameter, `event`, is passed to the function.
43232                     *  Returning `false` cancels the operation.
43233                     * 
43234                     * @type {Function}
43235                     * @context Point
43236                     * @sample {highcharts} highcharts/plotoptions/series-point-events-unselect/ Report the last unselected point
43237                     * @sample {highmaps} maps/plotoptions/series-allowpointselect/ Report select and unselect
43238                     * @since 1.2.0
43239                     * @apioption plotOptions.series.point.events.unselect
43240                     */
43241
43242                    /**
43243                     * Fires when the point is updated programmatically through the `.update(
43243)`
43244                     * method. One parameter, `event`, is passed to the function. The new
43245                     * point options can be accessed through `event.options`. Returning
43246                     * `false` cancels the operation.
43247                     * 
43248                     * @type {Function}
43249                     * @context Point
43250                     * @sample {highcharts} highcharts/plotoptions/series-point-events-update/ Confirm point updating
43251                     * @since 1.2.0
43252                     * @apioption plotOptions.series.point.events.update
43253                     */
43254
43255                }
43256            },
43257
43258
43259
43260            /**
43261             * Options for the series data labels, appearing next to each data
43262             * point.
43263             * 
43264             * In styled mode, the data labels can be styled wtih the `.highcharts-data-label-box` and `.highcharts-data-label` class names ([see example](http://jsfiddle.
43265             * net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/css/series-
43266             * datalabels)).
43267             */
43268            dataLabels: {
43269
43270
43271                /**
43272                 * The alignment of the data label compared to the point. If `right`,
43273                 * the right side of the label should be touching the point. For
43274                 * points with an extent, like columns, the alignments also dictates
43275                 * how to align it inside the box, as given with the [inside](#plotOptions.
43276                 * column.dataLabels.inside) option. Can be one of "left", "center"
43277                 * or "right".
43278                 * 
43279                 * @validvalue ["left", "center", "right"]
43280                 * @type {String}
43281                 * @sample {highcharts} highcharts/plotoptions/series-datalabels-align-left/ Left aligned
43282                 * @default center
43283                 */
43284                align: 'center',
43285
43286
43287                /**
43288                 * Whether to allow data labels to overlap. To make the labels less
43289                 * sensitive for overlapping, the [dataLabels.padding](#plotOptions.
43290                 * series.dataLabels.padding) can be set to 0.
43291                 * 
43292                 * @type {Boolean}
43293                 * @sample {highcharts} highcharts/plotoptions/series-datalabels-allowoverlap-false/ Don't allow overlap
43294                 * @sample {highstock} highcharts/plotoptions/series-datalabels-allowoverlap-false/ Don't allow overlap
43295                 * @sample {highmaps} highcharts/plotoptions/series-datalabels-allowoverlap-false/ Don't allow overlap
43296                 * @default false
43297                 * @since 4.1.0
43298                 * @apioption plotOptions.series.dataLabels.allowOverlap
43299                 */
43300
43301
43302                /**
43303                 * The border radius in pixels for the data label.
43304                 * 
43305                 * @type {Number}
43306                 * @sample {highcharts} highcharts/plotoptions/series-datalabels-box/ Data labels box options
43307                 * @sample {highstock} highcharts/plotoptions/series-datalabels-box/ Data labels box options
43308                 * @sample {highmaps} maps/plotoptions/series-datalabels-box/ Data labels box options
43309                 * @default 0
43310                 * @since 2.2.1
43311                 * @apioption plotOptions.series.dataLabels.borderRadius
43312                 */
43313
43314
43315                /**
43316                 * The border width in pixels for the data label.
43317                 * 
43318                 * @type {Number}
43319                 * @sample {highcharts} highcharts/plotoptions/series-datalabels-box/ Data labels box options
43320                 * @sample {highstock} highcharts/plotoptions/series-datalabels-box/ Data labels box options
43321                 * @default 0
43322                 * @since 2.2.1
43323                 * @apioption plotOptions.series.dataLabels.borderWidth
43324                 */
43325
43326                /**
43327                 * A class name for the data label. Particularly in styled mode, this can
43328                 * be used to give each series' or point's data label unique styling.
43329                 * In addition to this option, a default color class name is added
43330                 * so that we can give the labels a [contrast text shadow](http://jsfiddle.
43331                 * net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/css/data-
43332                 * label-contrast/).
43333                 * 
43334                 * @type {String}
43335                 * @sample {highcharts} highcharts/css/series-datalabels/ Styling by CSS
43336                 * @sample {highstock} highcharts/css/series-datalabels/ Styling by CSS
43337                 * @sample {highmaps} highcharts/css/series-datalabels/ Styling by CSS
43338                 * @since 5.0.0
43339                 * @apioption plotOptions.series.dataLabels.className
43340                 */
43341
43342                /**
43343                 * The text color for the data labels. Defaults to `null`. For certain series
43344                 * types, like column or map, the data labels can be drawn inside the points.
43345                 * In this case the data label will be drawn with maximum contrast by default.
43346                 * Additionally, it will be given a `text-outline` style with the opposite
43347                 * color, to further increase the contrast. This can be overridden by setting
43348                 * the `text-outline` style to `none` in the `dataLabels.style` option.
43349                 * 
43350                 * @type {Color}
43351                 * @sample {highcharts} highcharts/plotoptions/series-datalabels-color/
43352                 *         Red data labels
43353                 * @sample {highmaps} maps/demo/color-axis/
43354                 *         White data labels
43355                 * @apioption plotOptions.series.dataLabels.color
43356                 */
43357
43358                /**
43359                 * Whether to hide data labels that are outside the plot area. By default,
43360                 * the data label is moved inside the plot area according to the [overflow](#plotOptions.
43361                 * series.dataLabels.overflow) option.
43362                 * 
43363                 * @type {Boolean}
43364                 * @default true
43365                 * @since 2.3.3
43366                 * @apioption plotOptions.series.dataLabels.crop
43367                 */
43368
43369                /**
43370                 * Whether to defer displaying the data labels until the initial series
43371                 * animation has finished.
43372                 * 
43373                 * @type {Boolean}
43374                 * @default true
43375                 * @since 4.0
43376                 * @product highcharts highstock
43377                 * @apioption plotOptions.series.dataLabels.defer
43378                 */
43379
43380                /**
43381                 * Enable or disable the data labels.
43382                 * 
43383                 * @type {Boolean}
43384                 * @sample {highcharts} highcharts/plotoptions/series-datalabels-enabled/ Data labels enabled
43385                 * @sample {highmaps} maps/demo/color-axis/ Data labels enabled
43386                 * @default false
43387                 * @apioption plotOptions.series.dataLabels.enabled
43388                 */
43389
43390                /**
43391                 * A [format string](http://www.highcharts.com/docs/chart-concepts/labels-
43392                 * and-string-formatting) for the data label. Available variables are
43393                 * the same as for `formatter`.
43394                 * 
43395                 * @type {String}
43396                 * @sample {highcharts} highcharts/plotoptions/series-datalabels-format/ Add a unit
43397                 * @sample {highstock} highcharts/plotoptions/series-datalabels-format/ Add a unit
43398                 * @sample {highmaps} maps/plotoptions/series-datalabels-format/ Formatted value in the data label
43399                 * @default {highcharts} {y}
43400                 * @default {highstock} {y}
43401                 * @default {highmaps} {point.value}
43402                 * @since 3.0
43403                 * @apioption plotOptions.series.dataLabels.format
43404                 */
43405
43406                /**
43407                 * Callback JavaScript function to format the data label. Note that
43408                 * if a `format` is defined, the format takes precedence and the formatter
43409                 * is ignored. Available data are:
43410                 * 
43411                 * <table>
43412                 * 
43413                 * <tbody>
43414                 * 
43415                 * <tr>
43416                 * 
43417                 * <td>`this.percentage`</td>
43418                 * 
43419                 * <td>Stacked series and pies only. The point's percentage of the
43420                 * total.</td>
43421                 * 
43422                 * </tr>
43423                 * 
43424                 * <tr>
43425                 * 
43426                 * <td>`this.point`</td>
43427                 * 
43428                 * <td>The point object. The point name, if defined, is available
43429                 * through `this.point.name`.</td>
43430                 * 
43431                 * </tr>
43432                 * 
43433                 * <tr>
43434                 * 
43435                 * <td>`this.series`:</td>
43436                 * 
43437                 * <td>The series object. The series name is available through `this.
43438                 * series.name`.</td>
43439                 * 
43440                 * </tr>
43441                 * 
43442                 * <tr>
43443                 * 
43444                 * <td>`this.total`</td>
43445                 * 
43446                 * <td>Stacked series only. The total value at this point's x value.
43447                 * </td>
43448                 * 
43449                 * </tr>
43450                 * 
43451                 * <tr>
43452                 * 
43453                 * <td>`this.x`:</td>
43454                 * 
43455                 * <td>The x value.</td>
43456                 * 
43457                 * </tr>
43458                 * 
43459                 * <tr>
43460                 * 
43461                 * <td>`this.y`:</td>
43462                 * 
43463                 * <td>The y value.</td>
43464                 * 
43465                 * </tr>
43466                 * 
43467                 * </tbody>
43468                 * 
43469                 * </table>
43470                 * 
43471                 * @type {Function}
43472                 * @sample {highmaps} maps/plotoptions/series-datalabels-format/ Formatted value
43473                 */
43474                formatter: function() {
43475                    return this.y === null ? '' : H.numberFormat(this.y, -1);
43476                },
43477
43478
43479
43480                /**
43481                 * Styles for the label. The default `color` setting is `"contrast"`,
43482                 * which is a pseudo color that Highcharts picks up and applies the
43483                 * maximum contrast to the underlying point item, for example the
43484                 * bar in a bar chart.
43485                 * 
43486                 * The `textOutline` is a pseudo property that
43487                 * applies an outline of the given width with the given color, which
43488                 * by default is the maximum contrast to the text. So a bright text
43489                 * color will result in a black text outline for maximum readability
43490                 * on a mixed background. In some cases, especially with grayscale
43491                 * text, the text outline doesn't work well, in which cases it can
43492                 * be disabled by setting it to `"none"`. When `useHTML` is true, the
43493                 * `textOutline` will not be picked up. In this, case, the same effect
43494                 * can be acheived through the `text-shadow` CSS property.
43495                 * 
43496                 * @type {CSSObject}
43497                 * @sample {highcharts} highcharts/plotoptions/series-datalabels-style/
43498                 *         Bold labels
43499                 * @sample {highmaps} maps/demo/color-axis/ Bold labels
43500                 * @default {"color": "contrast", "fontSize": "11px", "fontWeight": "bold", "textOutline": "1px contrast" }
43501                 * @since 4.1.0
43502                 */
43503                style: {
43504                    fontSize: '11px',
43505                    fontWeight: 'bold',
43506                    color: 'contrast',
43507                    textOutline: '1px contrast'
43508                },
43509
43510                /**
43511                 * The background color or gradient for the data label.
43512                 * 
43513                 * @type {Color}
43514                 * @sample {highcharts} highcharts/plotoptions/series-datalabels-box/ Data labels box options
43515                 * @sample {highmaps} maps/plotoptions/series-datalabels-box/ Data labels box options
43516                 * @since 2.2.1
43517                 * @apioption plotOptions.series.dataLabels.backgroundColor
43518                 */
43519
43520                /**
43521                 * The border color for the data label. Defaults to `undefined`.
43522                 * 
43523                 * @type {Color}
43524                 * @sample {highcharts} highcharts/plotoptions/series-datalabels-box/ Data labels box options
43525                 * @sample {highstock} highcharts/plotoptions/series-datalabels-box/ Data labels box options
43526                 * @default undefined
43527                 * @since 2.2.1
43528                 * @apioption plotOptions.series.dataLabels.borderColor
43529                 */
43530
43531                /**
43532                 * The shadow of the box. Works best with `borderWidth` or `backgroundColor`.
43533                 * Since 2.3 the shadow can be an object configuration containing `color`,
43534                 *  `offsetX`, `offsetY`, `opacity` and `width`.
43535                 * 
43536                 * @type {Boolean|Object}
43537                 * @sample {highcharts} highcharts/plotoptions/series-datalabels-box/ Data labels box options
43538                 * @sample {highstock} highcharts/plotoptions/series-datalabels-box/ Data labels box options
43539                 * @default false
43540                 * @since 2.2.1
43541                 * @apioption plotOptions.series.dataLabels.shadow
43542                 */
43543
43544
43545                /**
43546                 * For points with an extent, like columns or map areas, whether to align the data
43547                 * label inside the box or to the actual value point. Defaults to `false`
43548                 * in most cases, `true` in stacked columns.
43549                 * 
43550                 * @type {Boolean}
43551                 * @since 3.0
43552                 * @apioption plotOptions.series.dataLabels.inside
43553                 */
43554
43555                /**
43556                 * How to handle data labels that flow outside the plot area. The default
43557                 * is `justify`, which aligns them inside the plot area. For columns
43558                 * and bars, this means it will be moved inside the bar. To display
43559                 * data labels outside the plot area, set `crop` to `false` and `overflow`
43560                 * to `"none"`.
43561                 * 
43562                 * @validvalue ["justify", "none"]
43563                 * @type {String}
43564                 * @default justify
43565                 * @since 3.0.6
43566                 * @apioption plotOptions.series.dataLabels.overflow
43567                 */
43568
43569                /**
43570                 * Text rotation in degrees. Note that due to a more complex structure,
43571                 * backgrounds, borders and padding will be lost on a rotated data
43572                 * label.
43573                 * 
43574                 * @type {Number}
43575                 * @sample {highcharts} highcharts/plotoptions/series-datalabels-rotation/ Vertical labels
43576                 * @default 0
43577                 * @apioption plotOptions.series.dataLabels.rotation
43578                 */
43579
43580                /**
43581                 * Whether to [use HTML](http://www.highcharts.com/docs/chart-concepts/labels-
43582                 * and-string-formatting#html) to render the labels.
43583                 *
43584                 * @type {Boolean}
43585                 * @default false
43586                 * @apioption plotOptions.series.dataLabels.useHTML
43587                 */
43588
43589                /**
43590                 * The vertical alignment of a data label. Can be one of `top`, `middle`
43591                 * or `bottom`. The default value depends on the data, for instance
43592                 * in a column chart, the label is above positive values and below
43593                 * negative values.
43594                 * 
43595                 * @validvalue ["top", "middle", "bottom"]
43596                 * @type {String}
43597                 * @since 2.3.3
43598                 */
43599                verticalAlign: 'bottom', // above singular point
43600
43601
43602                /**
43603                 * The x position offset of the label relative to the point.
43604                 * 
43605                 * @type {Number}
43606                 * @sample {highcharts} highcharts/plotoptions/series-datalabels-rotation/ Vertical and positioned
43607                 * @default 0
43608                 */
43609                x: 0,
43610
43611
43612                /**
43613                 * The y position offset of the label relative to the point.
43614                 * 
43615                 * @type {Number}
43616                 * @sample {highcharts} highcharts/plotoptions/series-datalabels-rotation/ Vertical and positioned
43617                 * @default -6
43618                 */
43619                y: 0,
43620
43621
43622                /**
43623                 * When either the `borderWidth` or the `backgroundColor` is set,
43624                 * this is the padding within the box.
43625                 * 
43626                 * @type {Number}
43627                 * @sample {highcharts} highcharts/plotoptions/series-datalabels-box/ Data labels box options
43628                 * @sample {highstock} highcharts/plotoptions/series-datalabels-box/ Data labels box options
43629                 * @sample {highmaps} maps/plotoptions/series-datalabels-box/ Data labels box options
43630                 * @default {highcharts} 5
43631                 * @default {highstock} 5
43632                 * @default {highmaps} 0
43633                 * @since 2.2.1
43634                 */
43635                padding: 5
43636
43637                /**
43638                 * The name of a symbol to use for the border around the label. Symbols
43639                 * are predefined functions on the Renderer object.
43640                 * 
43641                 * @type {String}
43642                 * @sample {highcharts} highcharts/plotoptions/series-datalabels-shape/ A callout for annotations
43643                 * @sample {highstock} highcharts/plotoptions/series-datalabels-shape/ A callout for annotations
43644                 * @sample {highmaps} highcharts/plotoptions/series-datalabels-shape/ A callout for annotations (Highcharts demo)
43645                 * @default square
43646                 * @since 4.1.2
43647                 * @apioption plotOptions.series.dataLabels.shape
43648                 */
43649
43650                /**
43651                 * The Z index of the data labels. The default Z index puts it above
43652                 * the series. Use a Z index of 2 to display it behind the series.
43653                 * 
43654                 * @type {Number}
43655                 * @default 6
43656                 * @since 2.3.5
43657                 * @apioption plotOptions.series.dataLabels.zIndex
43658                 */
43659
43660                /**
43661                 * A declarative filter for which data labels to display. The
43662                 * declarative filter is designed for use when callback functions are
43663                 * not available, like when the chart options require a pure JSON
43664                 * structure or for use with graphical editors. For programmatic
43665                 * control, use the `formatter` instead, and return `false` to disable
43666                 * a single data label.
43667                 *
43668                 * @example
43669                 * filter: {
43670                 *     property: 'percentage',
43671                 *     operator: '>',
43672                 *     value: 4
43673                 * }
43674                 *
43675                 * @sample highcharts/demo/pie-monochrome
43676                 *         Data labels filtered by percentage
43677                 *
43678                 * @type {Object}
43679                 * @since 6.0.3
43680                 * @apioption plotOptions.series.dataLabels.filter
43681                 */
43682
43683                /**
43684                 * The point property to filter by. Point options are passed directly to
43685                 * properties, additionally there are `y` value, `percentage` and others
43686                 * listed under [Point](https://api.highcharts.com/class-reference/Highcharts.Point)
43687                 * members.
43688                 *
43689                 * @type {String}
43690                 * @apioption plotOptions.series.dataLabels.filter.property
43691                 */
43692
43693                /**
43694                 * The operator to compare by. Can be one of `>`, `<`, `>=`, `<=`, `==`,
43695                 * and `===`.
43696                 *
43697                 * @type {String}
43698                 * @validvalue [">", "<", ">=", "<=", "==", "===""]
43699                 * @apioption plotOptions.series.dataLabels.filter.operator
43700                 */
43701
43702                /**
43703                 * The value to compare against.
43704                 *
43705                 * @type {Mixed}
43706                 * @apioption plotOptions.series.dataLabels.filter.value
43707                 */
43708            },
43709            // draw points outside the plot area when the number of points is less than
43710            // this
43711
43712
43713
43714            /**
43715             * When the series contains less points than the crop threshold, all
43716             * points are drawn, even if the points fall outside the visible plot
43717             * area at the current zoom. The advantage of drawing all points (including
43718             * markers and columns), is that animation is performed on updates.
43719             * On the other hand, when the series contains more points than the
43720             * crop threshold, the series data is cropped to only contain points
43721             * that fall within the plot area. The advantage of cropping away invisible
43722             * points is to increase performance on large series.
43723             * 
43724             * @type {Number}
43725             * @default 300
43726             * @since 2.2
43727             * @product highcharts highstock
43728             */
43729            cropThreshold: 300,
43730
43731
43732
43733            /**
43734             * The width of each point on the x axis. For example in a column chart
43735             * with one value each day, the pointRange would be 1 day (= 24 * 3600
43736             * * 1000 milliseconds). This is normally computed automatically, but
43737             * this option can be used to override the automatic value.
43738             * 
43739             * @type {Number}
43740             * @default 0
43741             * @product highstock
43742             */
43743            pointRange: 0,
43744
43745            /**
43746             * When this is true, the series will not cause the Y axis to cross
43747             * the zero plane (or [threshold](#plotOptions.series.threshold) option)
43748             * unless the data actually crosses the plane.
43749             * 
43750             * For example, if `softThreshold` is `false`, a series of 0, 1, 2,
43751             * 3 will make the Y axis show negative values according to the `minPadding`
43752             * option. If `softThreshold` is `true`, the Y axis starts at 0.
43753             * 
43754             * @type {Boolean}
43755             * @default true
43756             * @since 4.1.9
43757             * @product highcharts highstock
43758             */
43759            softThreshold: true,
43760
43761
43762
43763            /**
43764             * A wrapper object for all the series options in specific states.
43765             * 
43766             * @type {plotOptions.series.states}
43767             */
43768            states: {
43769
43770
43771                /**
43772                 * Options for the hovered series. These settings override the normal
43773                 * state options when a series is moused over or touched.
43774                 *
43775                 */
43776                hover: {
43777
43778                    /**
43779                     * Enable separate styles for the hovered series to visualize that the
43780                     * user hovers either the series itself or the legend. .
43781                     * 
43782                     * @type {Boolean}
43783                     * @sample {highcharts} highcharts/plotoptions/series-states-hover-enabled/ Line
43784                     * @sample {highcharts} highcharts/plotoptions/series-states-hover-enabled-column/ Column
43785                     * @sample {highcharts} highcharts/plotoptions/series-states-hover-enabled-pie/ Pie
43786                     * @default true
43787                     * @since 1.2
43788                     * @apioption plotOptions.series.states.hover.enabled
43789                     */
43790
43791
43792                    /**
43793                     * Animation setting for hovering the graph in line-type series.
43794                     * 
43795                     * @type {Boolean|Object}
43796                     * @default { "duration": 50 }
43797                     * @since 5.0.8
43798                     * @product highcharts
43799                     */
43800                    animation: {
43801                        /**
43802                         * The duration of the hover animation in milliseconds. By
43803                         * default the hover state animates quickly in, and slowly back
43804                         * to normal.
43805                         */
43806                        duration: 50
43807                    },
43808
43809                    /**
43810                     * Pixel with of the graph line. By default this property is
43811                     * undefined, and the `lineWidthPlus` property dictates how much
43812                     * to increase the linewidth from normal state.
43813                     * 
43814                     * @type {Number}
43815                     * @sample {highcharts} highcharts/plotoptions/series-states-hover-linewidth/
43816                     *         5px line on hover
43817                     * @default undefined
43818                     * @product highcharts highstock
43819                     * @apioption plotOptions.series.states.hover.lineWidth
43820                     */
43821
43822
43823                    /**
43824                     * The additional line width for the graph of a hovered series.
43825                     * 
43826                     * @type {Number}
43827                     * @sample {highcharts} highcharts/plotoptions/series-states-hover-linewidthplus/
43828                     *         5 pixels wider
43829                     * @sample {highstock} highcharts/plotoptions/series-states-hover-linewidthplus/
43830                     *         5 pixels wider
43831                     * @default 1
43832                     * @since 4.0.3
43833                     * @product highcharts highstock
43834                     */
43835                    lineWidthPlus: 1,
43836
43837
43838
43839                    /**
43840                     * In Highcharts 1.0, the appearance of all markers belonging to
43841                     * the hovered series. For settings on the hover state of the individual
43842                     * point, see [marker.states.hover](#plotOptions.series.marker.states.
43843                     * hover).
43844                     * 
43845                     * @extends plotOptions.series.marker
43846                     * @deprecated
43847                     * @product highcharts highstock
43848                     */
43849                    marker: {
43850                        // lineWidth: base + 1,
43851                        // radius: base + 1
43852                    },
43853
43854
43855
43856                    /**
43857                     * Options for the halo appearing around the hovered point in line-
43858                     * type series as well as outside the hovered slice in pie charts.
43859                     * By default the halo is filled by the current point or series
43860                     * color with an opacity of 0.25\. The halo can be disabled by setting
43861                     * the `halo` option to `false`.
43862                     * 
43863                     * In styled mode, the halo is styled with the `.highcharts-halo` class, with colors inherited from `.highcharts-color-{n}`.
43864                     * 
43865                     * @type {Object}
43866                     * @sample {highcharts} highcharts/plotoptions/halo/ Halo options
43867                     * @sample {highstock} highcharts/plotoptions/halo/ Halo options
43868                     * @since 4.0
43869                     * @product highcharts highstock
43870                     */
43871                    halo: {
43872
43873                        /**
43874                         * A collection of SVG attributes to override the appearance of the
43875                         * halo, for example `fill`, `stroke` and `stroke-width`.
43876                         * 
43877                         * @type {Object}
43878                         * @since 4.0
43879                         * @product highcharts highstock
43880                         * @apioption plotOptions.series.states.hover.halo.attributes
43881                         */
43882
43883
43884                        /**
43885                         * The pixel size of the halo. For point markers this is the radius
43886                         * of the halo. For pie slices it is the width of the halo outside
43887                         * the slice. For bubbles it defaults to 5 and is the width of the
43888                         * halo outside the bubble.
43889                         * 
43890                         * @type {Number}
43891                         * @default 10
43892                         * @since 4.0
43893                         * @product highcharts highstock
43894                         */
43895                        size: 10,
43896
43897
43898
43899
43900                        /**
43901                         * Opacity for the halo unless a specific fill is overridden using
43902                         * the `attributes` setting. Note that Highcharts is only able to
43903                         * apply opacity to colors of hex or rgb(a) formats.
43904                         * 
43905                         * @type {Number}
43906                         * @default 0.25
43907                         * @since 4.0
43908                         * @product highcharts highstock
43909                         */
43910                        opacity: 0.25
43911
43912                    }
43913                },
43914
43915
43916                /**
43917                 * Specific options for point in selected states, after being selected
43918                 * by [allowPointSelect](#plotOptions.series.allowPointSelect) or
43919                 * programmatically.
43920                 * 
43921                 * @type {Object}
43922                 * @extends plotOptions.series.states.hover
43923                 * @excluding brightness
43924                 * @sample {highmaps} maps/plotoptions/series-allowpointselect/
43925                 *         Allow point select demo
43926                 * @product highmaps
43927                 */
43928                select: {
43929                    marker: {}
43930                }
43931            },
43932
43933
43934
43935            /**
43936             * Sticky tracking of mouse events. When true, the `mouseOut` event
43937             * on a series isn't triggered until the mouse moves over another series,
43938             * or out of the plot area. When false, the `mouseOut` event on a
43939             * series is triggered when the mouse leaves the area around the series'
43940             * graph or markers. This also implies the tooltip when not shared. When
43941             * `stickyTracking` is false and `tooltip.shared` is false, the tooltip will
43942             * be hidden when moving the mouse between series. Defaults to true for line
43943             * and area type series, but to false for columns, pies etc.
43944             * 
43945             * @type {Boolean}
43946             * @sample {highcharts} highcharts/plotoptions/series-stickytracking-true/
43947             *         True by default
43948             * @sample {highcharts} highcharts/plotoptions/series-stickytracking-false/
43949             *         False
43950             * @default {highcharts} true
43951             * @default {highstock} true
43952             * @default {highmaps} false
43953             * @since 2.0
43954             */
43955            stickyTracking: true,
43956
43957            /**
43958             * A configuration object for the tooltip rendering of each single series.
43959             * Properties are inherited from [tooltip](#tooltip), but only the
43960             * following properties can be defined on a series level.
43961             * 
43962             * @type {Object}
43963             * @extends tooltip
43964             * @excluding animation,backgroundColor,borderColor,borderRadius,borderWidth,crosshairs,enabled,formatter,positioner,shadow,shared,shape,snap,style,useHTML
43965             * @since 2.3
43966             * @apioption plotOptions.series.tooltip
43967             */
43968
43969            /**
43970             * When a series contains a data array that is longer than this, only
43971             * one dimensional arrays of numbers, or two dimensional arrays with
43972             * x and y values are allowed. Also, only the first point is tested,
43973             * and the rest are assumed to be the same format. This saves expensive
43974             * data checking and indexing in long series. Set it to `0` disable.
43975             * 
43976             * @type {Number}
43977             * @default 1000
43978             * @since 2.2
43979             * @product highcharts highstock
43980             */
43981            turboThreshold: 1000,
43982
43983            /**
43984             * An array defining zones within a series. Zones can be applied to
43985             * the X axis, Y axis or Z axis for bubbles, according to the `zoneAxis`
43986             * option.
43987             * 
43988             * In styled mode, the color zones are styled with the `.highcharts-
43989             * zone-{n}` class, or custom classed from the `className` option ([view
43990             * live demo](http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/css/color-
43991             * zones/)).
43992             * 
43993             * @type {Array}
43994             * @see [zoneAxis](#plotOptions.series.zoneAxis)
43995             * @sample {highcharts} highcharts/series/color-zones-simple/ Color zones
43996             * @sample {highstock} highcharts/series/color-zones-simple/ Color zones
43997             * @since 4.1.0
43998             * @product highcharts highstock
43999             * @apioption plotOptions.series.zones
44000             */
44001
44002            /**
44003             * Styled mode only. A custom class name for the zone.
44004             * 
44005             * @type {String}
44006             * @sample {highcharts} highcharts/css/color-zones/ Zones styled by class name
44007             * @sample {highstock} highcharts/css/color-zones/ Zones styled by class 
44007name
44008             * @sample {highmaps} highcharts/css/color-zones/ Zones styled by class name
44009             * @since 5.0.0
44010             * @apioption plotOptions.series.zones.className
44011             */
44012
44013            /**
44014             * Defines the color of the series.
44015             * 
44016             * @type {Color}
44017             * @see [series color](#plotOptions.series.color)
44018             * @since 4.1.0
44019             * @product highcharts highstock
44020             * @apioption plotOptions.series.zones.color
44021             */
44022
44023            /**
44024             * A name for the dash style to use for the graph.
44025             * 
44026             * @type {String}
44027             * @see [series.dashStyle](#plotOptions.series.dashStyle)
44028             * @sample {highcharts} highcharts/series/color-zones-dashstyle-dot/
44029             *         Dashed line indicates prognosis
44030             * @sample {highstock} highcharts/series/color-zones-dashstyle-dot/
44031             *         Dashed line indicates prognosis
44032             * @since 4.1.0
44033             * @product highcharts highstock
44034             * @apioption plotOptions.series.zones.dashStyle
44035             */
44036
44037            /**
44038             * Defines the fill color for the series (in area type series)
44039             * 
44040             * @type {Color}
44041             * @see [fillColor](#plotOptions.area.fillColor)
44042             * @since 4.1.0
44043             * @product highcharts highstock
44044             * @apioption plotOptions.series.zones.fillColor
44045             */
44046
44047            /**
44048             * The value up to where the zone extends, if undefined the zones stretches
44049             * to the last value in the series.
44050             * 
44051             * @type {Number}
44052             * @default undefined
44053             * @since 4.1.0
44054             * @product highcharts highstock
44055             * @apioption plotOptions.series.zones.value
44056             */
44057
44058
44059
44060            /**
44061             * Determines whether the series should look for the nearest point
44062             * in both dimensions or just the x-dimension when hovering the series.
44063             * Defaults to `'xy'` for scatter series and `'x'` for most other
44064             * series. If the data has duplicate x-values, it is recommended to
44065             * set this to `'xy'` to allow hovering over all points.
44066             * 
44067             * Applies only to series types using nearest neighbor search (not
44068             * direct hover) for tooltip.
44069             * 
44070             * @validvalue ['x', 'xy']
44071             * @type {String}
44072             * @sample {highcharts} highcharts/series/findnearestpointby/
44073             *         Different hover behaviors
44074             * @sample {highstock} highcharts/series/findnearestpointby/
44075             *         Different hover behaviors
44076             * @sample {highmaps} highcharts/series/findnearestpointby/
44077             *         Different hover behaviors
44078             * @since 5.0.10
44079             */
44080            findNearestPointBy: 'x'
44081
44082        }, /** @lends Highcharts.Series.prototype */ {
44083            isCartesian: true,
44084            pointClass: Point,
44085            sorted: true, // requires the data to be sorted
44086            requireSorting: true,
44087            directTouch: false,
44088            axisTypes: ['xAxis', 'yAxis'],
44089            colorCounter: 0,
44090            // each point's x and y values are stored in this.xData and this.yData
44091            parallelArrays: ['x', 'y'],
44092            coll: 'series',
44093            init: function(chart, options) {
44094                var series = this,
44095                    events,
44096                    chartSeries = chart.series,
44097                    lastSeries;
44098
44099                /**
44100                 * Read only. The chart that the series belongs to.
44101                 *
44102                 * @name chart
44103                 * @memberOf Series
44104                 * @type {Chart}
44105                 */
44106                series.chart = chart;
44107
44108                /**
44109                 * Read only. The series' type, like "line", "area", "column" etc. The
44110                 * type in the series options anc can be altered using {@link
44111                 * Series#update}.
44112                 *
44113                 * @name type
44114                 * @memberOf Series
44115                 * @type String
44116                 */
44117
44118                /**
44119                 * Read only. The series' current options. To update, use {@link
44120                 * Series#update}.
44121                 *
44122                 * @name options
44123                 * @memberOf Series
44124                 * @type SeriesOptions
44125                 */
44126                series.options = options = series.setOptions(options);
44127                series.linkedSeries = [];
44128
44129                // bind the axes
44130                series.bindAxes();
44131
44132                // set some variables
44133                extend(series, {
44134                    /**
44135                     * The series name as given in the options. Defaults to
44136                     * "Series {n}".
44137                     *
44138                     * @name name
44139                     * @memberOf Series
44140                     * @type {String}
44141                     */
44142                    name: options.name,
44143                    state: '',
44144                    /**
44145                     * Read only. The series' visibility state as set by {@link
44146                     * Series#show}, {@link Series#hide}, or in the initial
44147                     * configuration.
44148                     *
44149                     * @name visible
44150                     * @memberOf Series
44151                     * @type {Boolean}
44152                     */
44153                    visible: options.visible !== false, // true by default
44154                    /**
44155                     * Read only. The series' selected state as set by {@link
44156                     * Highcharts.Series#select}.
44157                     *
44158                     * @name selected
44159                     * @memberOf Series
44160                     * @type {Boolean}
44161                     */
44162                    selected: options.selected === true // false by default
44163                });
44164
44165                // register event listeners
44166                events = options.events;
44167
44168                objectEach(events, function(event, eventType) {
44169                    addEvent(series, eventType, event);
44170                });
44171                if (
44172                    (events && events.click) ||
44173                    (
44174                        options.point &&
44175                        options.point.events &&
44176                        options.point.events.click
44177                    ) ||
44178                    options.allowPointSelect
44179                ) {
44180                    chart.runTrackerClick = true;
44181                }
44182
44183                series.getColor();
44184                series.getSymbol();
44185
44186                // Set the data
44187                each(series.parallelArrays, function(key) {
44188                    series[key + 'Data'] = [];
44189                });
44190                series.setData(options.data, false);
44191
44192                // Mark cartesian
44193                if (series.isCartesian) {
44194                    chart.hasCartesianSeries = true;
44195                }
44196
44197                // Get the index and register the series in the chart. The index is one
44198                // more than the current latest series index (#5960).
44199                if (chartSeries.length) {
44200                    lastSeries = chartSeries[chartSeries.length - 1];
44201                }
44202                series._i = pick(lastSeries && lastSeries._i, -1) + 1;
44203
44204                // Insert the series and re-order all series above the insertion point.
44205                chart.orderSeries(this.insert(chartSeries));
44206            },
44207
44208            /**
44209             * Insert the series in a collection with other series, either the chart
44210             * series or yAxis series, in the correct order according to the index
44211             * option. Used internally when adding series.
44212             *
44213             * @private
44214             * @param   {Array.<Series>} collection
44215             *          A collection of series, like `chart.series` or `xAxis.series`.
44216             * @returns {Number} The index of the series in the collection.
44217             */
44218            insert: function(collection) {
44219                var indexOption = this.options.index,
44220                    i;
44221
44222                // Insert by index option
44223                if (isNumber(indexOption)) {
44224                    i = collection.length;
44225                    while (i--) {
44226                        // Loop down until the interted element has higher index
44227                        if (indexOption >=
44228                            pick(collection[i].options.index, collection[i]._i)) {
44229                            collection.splice(i + 1, 0, this);
44230                            break;
44231                        }
44232                    }
44233                    if (i === -1) {
44234                        collection.unshift(this);
44235                    }
44236                    i = i + 1;
44237
44238                    // Or just push it to the end
44239                } else {
44240                    collection.push(this);
44241                }
44242                return pick(i, collection.length - 1);
44243            },
44244
44245            /**
44246             * Set the xAxis and yAxis properties of cartesian series, and register the
44247             * series in the `axis.series` array.
44248             *
44249             * @private
44250             */
44251            bindAxes: function() {
44252                var series = this,
44253                    seriesOptions = series.options,
44254                    chart = series.chart,
44255                    axisOptions;
44256
44257                // repeat for xAxis and yAxis
44258                each(series.axisTypes || [], function(AXIS) {
44259
44260                    // loop through the chart's axis objects
44261                    each(chart[AXIS], function(axis) {
44262                        axisOptions = axis.options;
44263
44264                        // apply if the series xAxis or yAxis option mathches the number
44265                        // of the axis, or if undefined, use the first axis
44266                        if (
44267                            seriesOptions[AXIS] === axisOptions.index ||
44268                            (
44269                                seriesOptions[AXIS] !== undefined &&
44270                                seriesOptions[AXIS] === axisOptions.id
44271                            ) ||
44272                            (
44273                                seriesOptions[AXIS] === undefined &&
44274                                axisOptions.index === 0
44275                            )
44276                        ) {
44277
44278                            // register this series in the axis.series lookup
44279                            series.insert(axis.series);
44280
44281                            // set this series.xAxis or series.yAxis reference
44282                            /**
44283                             * Read only. The unique xAxis object associated with the
44284                             * series.
44285                             *
44286                             * @name xAxis
44287                             * @memberOf Series
44288                             * @type Axis
44289                             */
44290                            /**
44291                             * Read only. The unique yAxis object associated with the
44292                             * series.
44293                             *
44294                             * @name yAxis
44295                             * @memberOf Series
44296                             * @type Axis
44297                             */
44298                            series[AXIS] = axis;
44299
44300                            // mark dirty for redraw
44301                            axis.isDirty = true;
44302                        }
44303                    });
44304
44305                    // The series needs an X and an Y axis
44306                    if (!series[AXIS] && series.optionalAxis !== AXIS) {
44307                        H.error(18, true);
44308                    }
44309
44310                });
44311            },
44312
44313            /**
44314             * For simple series types like line and column, the data values are held in
44315             * arrays like xData and yData for quick lookup to find extremes and more.
44316             * For multidimensional series like bubble and map, this can be extended
44317             * with arrays like zData and valueData by adding to the
44318             * `series.parallelArrays` array.
44319             *
44320             * @private
44321             */
44322            updateParallelArrays: function(point, i) {
44323                var series = point.series,
44324                    args = arguments,
44325                    fn = isNumber(i) ?
44326                    // Insert the value in the given position
44327                    function(key) {
44328                        var val = key === 'y' && series.toYData ?
44329                            series.toYData(point) :
44330                            point[key];
44331                        series[key + 'Data'][i] = val;
44332                    } :
44333                    // Apply the method specified in i with the following arguments
44334                    // as arguments
44335                    function(key) {
44336                        Array.prototype[i].apply(
44337                            series[key + 'Data'],
44338                            Array.prototype.slice.call(args, 2)
44339                        );
44340                    };
44341
44342                each(series.parallelArrays, fn);
44343            },
44344
44345            /**
44346             * Return an auto incremented x value based on the pointStart and
44347             * pointInterval options. This is only used if an x value is not given for
44348             * the point that calls autoIncrement.
44349             *
44350             * @private
44351             */
44352            autoIncrement: function() {
44353
44354                var options = this.options,
44355                    xIncrement = this.xIncrement,
44356                    date,
44357                    pointInterval,
44358                    pointIntervalUnit = options.pointIntervalUnit;
44359
44360                xIncrement = pick(xIncrement, options.pointStart, 0);
44361
44362                this.pointInterval = pointInterval = pick(
44363                    this.pointInterval,
44364                    options.pointInterval,
44365                    1
44366                );
44367
44368                // Added code for pointInterval strings
44369                if (pointIntervalUnit) {
44370                    date = new Date(xIncrement);
44371
44372                    if (pointIntervalUnit === 'day') {
44373                        date = +date[Date.hcSetDate](
44374                            date[Date.hcGetDate]() + pointInterval
44375                        );
44376                    } else if (pointIntervalUnit === 'month') {
44377                        date = +date[Date.hcSetMonth](
44378                            date[Date.hcGetMonth]() + pointInterval
44379                        );
44380                    } else if (pointIntervalUnit === 'year') {
44381                        date = +date[Date.hcSetFullYear](
44382                            date[Date.hcGetFullYear]() + pointInterval
44383                        );
44384                    }
44385                    pointInterval = date - xIncrement;
44386
44387                }
44388
44389                this.xIncrement = xIncrement + pointInterval;
44390                return xIncrement;
44391            },
44392
44393            /**
44394             * Set the series options by merging from the options tree. Called
44395             * internally on initiating and updating series. This function will not
44396             * redraw the series. For API usage, use {@link Series#update}.
44397             * 
44398             * @param  {Options.plotOptions.series} itemOptions
44399             *         The series options.
44400             */
44401            setOptions: function(itemOptions) {
44402                var chart = this.chart,
44403                    chartOptions = chart.options,
44404                    plotOptions = chartOptions.plotOptions,
44405                    userOptions = chart.userOptions || {},
44406                    userPlotOptions = userOptions.plotOptions || {},
44407                    typeOptions = plotOptions[this.type],
44408                    options,
44409                    zones;
44410
44411                this.userOptions = itemOptions;
44412
44413                // General series options take precedence over type options because
44414                // otherwise, default type options like column.animation would be
44415                // overwritten by the general option. But issues have been raised here
44416                // (#3881), and the solution may be to distinguish between default
44417                // option and userOptions like in the tooltip below.
44418                options = merge(
44419                    typeOptions,
44420                    plotOptions.series,
44421                    itemOptions
44422                );
44423
44424                // The tooltip options are merged between global and series specific
44425                // options. Importance order asscendingly:
44426                // globals: (1)tooltip, (2)plotOptions.series, (3)plotOptions[this.type]
44427                // init userOptions with possible later updates: 4-6 like 1-3 and
44428                // (7)this series options
44429                this.tooltipOptions = merge(
44430                    defaultOptions.tooltip, // 1
44431                    defaultOptions.plotOptions.series &&
44432                    defaultOptions.plotOptions.series.tooltip, // 2
44433                    defaultOptions.plotOptions[this.type].tooltip, // 3
44434                    chartOptions.tooltip.userOptions, // 4
44435                    plotOptions.series && plotOptions.series.tooltip, // 5
44436                    plotOptions[this.type].tooltip, // 6
44437                    itemOptions.tooltip // 7
44438                );
44439
44440                // When shared tooltip, stickyTracking is true by default,
44441                // unless user says otherwise.
44442                this.stickyTracking = pick(
44443                    itemOptions.stickyTracking,
44444                    userPlotOptions[this.type] &&
44445                    userPlotOptions[this.type].stickyTracking,
44446                    userPlotOptions.series && userPlotOptions.series.stickyTracking,
44447                    (
44448                        this.tooltipOptions.shared && !this.noSharedTooltip ?
44449                        true :
44450                        options.stickyTracking
44451                    )
44452                );
44453
44454                // Delete marker object if not allowed (#1125)
44455                if (typeOptions.marker === null) {
44456                    delete options.marker;
44457                }
44458
44459                // Handle color zones
44460                this.zoneAxis = options.zoneAxis;
44461                zones = this.zones = (options.zones || []).slice();
44462                if (
44463                    (options.negativeColor || options.negativeFillColor) &&
44464                    !options.zones
44465                ) {
44466                    zones.push({
44467                        value: options[this.zoneAxis + 'Threshold'] ||
44468                            options.threshold ||
44469                            0,
44470                        className: 'highcharts-negative',
44471
44472                        color: options.negativeColor,
44473                        fillColor: options.negativeFillColor
44474
44475                    });
44476                }
44477                if (zones.length) { // Push one extra zone for the rest
44478                    if (defined(zones[zones.length - 1].value)) {
44479                        zones.push({
44480
44481                            color: this.color,
44482                            fillColor: this.fillColor
44483
44484                        });
44485                    }
44486                }
44487                return options;
44488            },
44489
44490            getCyclic: function(prop, value, defaults) {
44491                var i,
44492                    chart = this.chart,
44493                    userOptions = this.userOptions,
44494                    indexName = prop + 'Index',
44495                    counterName = prop + 'Counter',
44496                    len = defaults ? defaults.length : pick(
44497                        chart.options.chart[prop + 'Count'],
44498                        chart[prop + 'Count']
44499                    ),
44500                    setting;
44501
44502                if (!value) {
44503                    // Pick up either the colorIndex option, or the _colorIndex after
44504                    // Series.update()
44505                    setting = pick(
44506                        userOptions[indexName],
44507                        userOptions['_' + indexName]
44508                    );
44509                    if (defined(setting)) { // after Series.update()
44510                        i = setting;
44511                    } else {
44512                        // #6138
44513                        if (!chart.series.length) {
44514                            chart[counterName] = 0;
44515                        }
44516                        userOptions['_' + indexName] = i = chart[counterName] % len;
44517                        chart[counterName] += 1;
44518                    }
44519                    if (defaults) {
44520                        value = defaults[i];
44521                    }
44522                }
44523                // Set the colorIndex
44524                if (i !== undefined) {
44525                    this[indexName] = i;
44526                }
44527                this[prop] = value;
44528            },
44529
44530            /**
44531             * Get the series' color based on either the options or pulled from global
44532             * options.
44533             *
44534             * @return  {Color} The series color.
44535             */
44536
44537            getColor: function() {
44538                if (this.options.colorByPoint) {
44539                    // #4359, selected slice got series.color even when colorByPoint was
44540                    // set.
44541                    this.options.color = null;
44542                } else {
44543                    this.getCyclic(
44544                        'color',
44545                        this.options.color || defaultPlotOptions[this.type].color,
44546                        this.chart.options.colors
44547                    );
44548                }
44549            },
44550
44551            /**
44552             * Get the series' symbol based on either the options or pulled from global
44553             * options.
44554             */
44555            getSymbol: function() {
44556                var seriesMarkerOption = this.options.marker;
44557
44558                this.getCyclic(
44559                    'symbol',
44560                    seriesMarkerOption.symbol,
44561                    this.chart.options.symbols
44562                );
44563            },
44564
44565            drawLegendSymbol: LegendSymbolMixin.drawLineMarker,
44566
44567            /**
44568             * Apply a new set of data to the series and optionally redraw it. The new
44569             * data array is passed by reference (except in case of `updatePoints`), and
44570             * may later be mutated when updating the chart data.
44571             *
44572             * Note the difference in behaviour when setting the same amount of points,
44573             * or a different amount of points, as handled by the `updatePoints`
44574             * parameter.
44575             *
44576             * @param  {SeriesDataOptions} data
44577             *         Takes an array of data in the same format as de
44577scribed under
44578             *         `series.typedata` for the given series type.
44579             * @param  {Boolean} [redraw=true]
44580             *         Whether to redraw the chart after the series is altered. If doing
44581             *         more operations on the chart, it is a good idea to set redraw to
44582             *         false and call {@link Chart#redraw} after.
44583             * @param  {AnimationOptions} [animation]
44584             *         When the updated data is the same length as the existing data,
44585             *         points will be updated by default, and animation visualizes how
44586             *         the points are changed. Set false to disable animation, or a
44587             *         configuration object to set duration or easing.
44588             * @param  {Boolean} [updatePoints=true]
44589             *         When the updated data is the same length as the existing data,
44590             *         points will be updated instead of replaced. This allows updating
44591             *         with animation and performs better. In this case, the original
44592             *         array is not passed by reference. Set false to prevent.
44593             *
44594             * @sample highcharts/members/series-setdata/
44595             *         Set new data from a button
44596             * @sample highcharts/members/series-setdata-pie/
44597             *         Set data in a pie
44598             * @sample stock/members/series-setdata/
44599             *         Set new data in Highstock
44600             * @sample maps/members/series-setdata/
44601             *         Set new data in Highmaps
44602             */
44603            setData: function(data, redraw, animation, updatePoints) {
44604                var series = this,
44605                    oldData = series.points,
44606                    oldDataLength = (oldData && oldData.length) || 0,
44607                    dataLength,
44608                    options = series.options,
44609                    chart = series.chart,
44610                    firstPoint = null,
44611                    xAxis = series.xAxis,
44612                    i,
44613                    turboThreshold = options.turboThreshold,
44614                    pt,
44615                    xData = this.xData,
44616                    yData = this.yData,
44617                    pointArrayMap = series.pointArrayMap,
44618                    valueCount = pointArrayMap && pointArrayMap.length;
44619
44620                data = data || [];
44621                dataLength = data.length;
44622                redraw = pick(redraw, true);
44623
44624                // If the point count is the same as is was, just run Point.update which
44625                // is cheaper, allows animation, and keeps references to points.
44626                if (
44627                    updatePoints !== false &&
44628                    dataLength &&
44629                    oldDataLength === dataLength &&
44630                    !series.cropped &&
44631                    !series.hasGroupedData &&
44632                    series.visible
44633                ) {
44634                    each(data, function(point, i) {
44635                        // .update doesn't exist on a linked, hidden series (#3709)
44636                        if (oldData[i].update && point !== options.data[i]) {
44637                            oldData[i].update(point, false, null, false);
44638                        }
44639                    });
44640
44641                } else {
44642
44643                    // Reset properties
44644                    series.xIncrement = null;
44645
44646                    series.colorCounter = 0; // for series with colorByPoint (#1547)
44647
44648                    // Update parallel arrays
44649                    each(this.parallelArrays, function(key) {
44650                        series[key + 'Data'].length = 0;
44651                    });
44652
44653                    // In turbo mode, only one- or twodimensional arrays of numbers are
44654                    // allowed. The first value is tested, and we assume that all the
44655                    // rest are defined the same way. Although the 'for' loops are
44656                    // similar, they are repeated inside each if-else conditional for
44657                    // max performance.
44658                    if (turboThreshold && dataLength > turboThreshold) {
44659
44660                        // find the first non-null point
44661                        i = 0;
44662                        while (firstPoint === null && i < dataLength) {
44663                            firstPoint = data[i];
44664                            i++;
44665                        }
44666
44667
44668                        if (isNumber(firstPoint)) { // assume all points are numbers
44669                            for (i = 0; i < dataLength; i++) {
44670                                xData[i] = this.autoIncrement();
44671                                yData[i] = data[i];
44672                            }
44673
44674                            // Assume all points are arrays when first point is
44675                        } else if (isArray(firstPoint)) {
44676                            if (valueCount) { // [x, low, high] or [x, o, h, l, c]
44677                                for (i = 0; i < dataLength; i++) {
44678                                    pt = data[i];
44679                                    xData[i] = pt[0];
44680                                    yData[i] = pt.slice(1, valueCount + 1);
44681                                }
44682                            } else { // [x, y]
44683                                for (i = 0; i < dataLength; i++) {
44684                                    pt = data[i];
44685                                    xData[i] = pt[0];
44686                                    yData[i] = pt[1];
44687                                }
44688                            }
44689                        } else {
44690                            // Highcharts expects configs to be numbers or arrays in
44691                            // turbo mode
44692                            H.error(12);
44693                        }
44694                    } else {
44695                        for (i = 0; i < dataLength; i++) {
44696                            if (data[i] !== undefined) { // stray commas in oldIE
44697                                pt = {
44698                                    series: series
44699                                };
44700                                series.pointClass.prototype.applyOptions.apply(
44701                                    pt, [data[i]]
44702                                );
44703                                series.updateParallelArrays(pt, i);
44704                            }
44705                        }
44706                    }
44707
44708                    // Forgetting to cast strings to numbers is a common caveat when
44709                    // handling CSV or JSON
44710                    if (yData && isString(yData[0])) {
44711                        H.error(14, true);
44712                    }
44713
44714                    series.data = [];
44715                    series.options.data = series.userOptions.data = data;
44716
44717                    // destroy old points
44718                    i = oldDataLength;
44719                    while (i--) {
44720                        if (oldData[i] && oldData[i].destroy) {
44721                            oldData[i].destroy();
44722                        }
44723                    }
44724
44725                    // reset minRange (#878)
44726                    if (xAxis) {
44727                        xAxis.minRange = xAxis.userMinRange;
44728                    }
44729
44730                    // redraw
44731                    series.isDirty = chart.isDirtyBox = true;
44732                    series.isDirtyData = !!oldData;
44733                    animation = false;
44734                }
44735
44736                // Typically for pie series, points need to be processed and generated
44737                // prior to rendering the legend
44738                if (options.legendType === 'point') {
44739                    this.processData();
44740                    this.generatePoints();
44741                }
44742
44743                if (redraw) {
44744                    chart.redraw(animation);
44745                }
44746            },
44747
44748            /**
44749             * Internal function to process the data by cropping away unused data points
44750             * if the series is longer than the crop threshold. This saves computing
44751             * time for large series. In Highstock, this function is extended to
44752             * provide data grouping.
44753             *
44754             * @private
44755             * @param  {Boolean} force
44756             *         Force data grouping.
44757             */
44758            processData: function(force) {
44759                var series = this,
44760                    processedXData = series.xData, // copied during slice operation
44761                    processedYData = series.yData,
44762                    dataLength = processedXData.length,
44763                    croppedData,
44764                    cropStart = 0,
44765                    cropped,
44766                    distance,
44767                    closestPointRange,
44768                    xAxis = series.xAxis,
44769                    i, // loop variable
44770                    options = series.options,
44771                    cropThreshold = options.cropThreshold,
44772                    getExtremesFromAll =
44773                    series.getExtremesFromAll ||
44774                    options.getExtremesFromAll, // #4599
44775                    isCartesian = series.isCartesian,
44776                    xExtremes,
44777                    val2lin = xAxis && xAxis.val2lin,
44778                    isLog = xAxis && xAxis.isLog,
44779                    throwOnUnsorted = series.requireSorting,
44780                    min,
44781                    max;
44782
44783                // If the series data or axes haven't changed, don't go through this.
44784                // Return false to pass the message on to override methods like in data
44785                // grouping.
44786                if (
44787                    isCartesian &&
44788                    !series.isDirty &&
44789                    !xAxis.isDirty &&
44790                    !series.yAxis.isDirty &&
44791                    !force
44792                ) {
44793                    return false;
44794                }
44795
44796                if (xAxis) {
44797                    xExtremes = xAxis.getExtremes(); // corrected for log axis (#3053)
44798                    min = xExtremes.min;
44799                    max = xExtremes.max;
44800                }
44801
44802                // optionally filter out points outside the plot area
44803                if (
44804                    isCartesian &&
44805                    series.sorted &&
44806                    !getExtremesFromAll &&
44807                    (!cropThreshold || dataLength > cropThreshold || series.forceCrop)
44808                ) {
44809
44810                    // it's outside current extremes
44811                    if (
44812                        processedXData[dataLength - 1] < min ||
44813                        processedXData[0] > max
44814                    ) {
44815                        processedXData = [];
44816                        processedYData = [];
44817
44818                        // only crop if it's actually spilling out
44819                    } else if (
44820                        processedXData[0] < min ||
44821                        processedXData[dataLength - 1] > max
44822                    ) {
44823                        croppedData = this.cropData(
44824                            series.xData,
44825                            series.yData,
44826                            min,
44827                            max
44828                        );
44829                        processedXData = croppedData.xData;
44830                        processedYData = croppedData.yData;
44831                        cropStart = croppedData.start;
44832                        cropped = true;
44833                    }
44834                }
44835
44836
44837                // Find the closest distance between processed points
44838                i = processedXData.length || 1;
44839                while (--i) {
44840                    distance = isLog ?
44841                        val2lin(processedXData[i]) - val2lin(processedXData[i - 1]) :
44842                        processedXData[i] - processedXData[i - 1];
44843
44844                    if (
44845                        distance > 0 &&
44846                        (
44847                            closestPointRange === undefined ||
44848                            distance < closestPointRange
44849                        )
44850                    ) {
44851                        closestPointRange = distance;
44852
44853                        // Unsorted data is not supported by the line tooltip, as well as
44854                        // data grouping and navigation in Stock charts (#725) and width
44855                        // calculation of columns (#1900)
44856                    } else if (distance < 0 && throwOnUnsorted) {
44857                        H.error(15);
44858                        throwOnUnsorted = false; // Only once
44859                    }
44860                }
44861
44862                // Record the properties
44863                series.cropped = cropped; // undefined or true
44864                series.cropStart = cropStart;
44865                series.processedXData = processedXData;
44866                series.processedYData = processedYData;
44867
44868                series.closestPointRange = closestPointRange;
44869
44870            },
44871
44872            /**
44873             * Iterate over xData and crop values between min and max. Returns object
44874             * containing crop start/end cropped xData with corresponding part of yData,
44875             * dataMin and dataMax within the cropped range.
44876             *
44877             * @private
44878             */
44879            cropData: function(xData, yData, min, max) {
44880                var dataLength = xData.length,
44881                    cropStart = 0,
44882                    cropEnd = dataLength,
44883                    // line-type series need one point outside
44884                    cropShoulder = pick(this.cropShoulder, 1),
44885                    i,
44886                    j;
44887
44888                // iterate up to find slice start
44889                for (i = 0; i < dataLength; i++) {
44890                    if (xData[i] >= min) {
44891                        cropStart = Math.max(0, i - cropShoulder);
44892                        break;
44893                    }
44894                }
44895
44896                // proceed to find slice end
44897                for (j = i; j < dataLength; j++) {
44898                    if (xData[j] > max) {
44899                        cropEnd = j + cropShoulder;
44900                        break;
44901                    }
44902                }
44903
44904                return {
44905                    xData: xData.slice(cropStart, cropEnd),
44906                    yData: yData.slice(cropStart, cropEnd),
44907                    start: cropStart,
44908                    end: cropEnd
44909                };
44910            },
44911
44912
44913            /**
44914             * Generate the data point after the data has been processed by cropping
44915             * away unused points and optionally grouped in Highcharts Stock.
44916             *
44917             * @private
44918             */
44919            generatePoints: function() {
44920                var series = this,
44921                    options = series.options,
44922                    dataOptions = options.data,
44923                    data = series.data,
44924                    dataLength,
44925                    processedXData = series.processedXData,
44926                    processedYData = series.processedYData,
44927                    PointClass = series.pointClass,
44928                    processedDataLength = processedXData.length,
44929                    cropStart = series.cropStart || 0,
44930                    cursor,
44931                    hasGroupedData = series.hasGroupedData,
44932                    keys = options.keys,
44933                    point,
44934                    points = [],
44935                    i;
44936
44937                if (!data && !hasGroupedData) {
44938                    var arr = [];
44939                    arr.length = dataOptions.length;
44940                    data = series.data = arr;
44941                }
44942
44943                if (keys && hasGroupedData) {
44944                    // grouped data has already applied keys (#6590)
44945                    series.options.keys = false;
44946                }
44947
44948                for (i = 0; i < processedDataLength; i++) {
44949                    cursor = cropStart + i;
44950                    if (!hasGroupedData) {
44951                        point = data[cursor];
44952                        if (!point && dataOptions[cursor] !== undefined) { // #970
44953                            data[cursor] = point = (new PointClass()).init(
44954                                series,
44955                                dataOptions[cursor],
44956                                processedXData[i]
44957                            );
44958                        }
44959                    } else {
44960                        // splat the y data in case of ohlc data array
44961                        point = (new PointClass()).init(
44962                            series, [processedXData[i]].concat(splat(processedYData[i]))
44963                        );
44964
44965                        /**
44966                         * Highstock only. If a point object is created by data
44967                         * grouping, it doesn't reflect actual points in the raw data.
44968                         * In this case, the `dataGroup` property holds information
44969                         * that points back to the raw data.
44970                         *
44971                         * - `dataGroup.start` is the index of the first raw data point
44972                         * in the group.
44973                         * - `dataGroup.length` is the amount of points in the group.
44974                         *
44975                         * @name dataGroup
44976                         * @memberOf Point
44977                         * @type {Object}
44978                         *
44979                         */
44980                        point.dataGroup = series.groupMap[i];
44981                    }
44982                    if (point) { // #6279
44983                        point.index = cursor; // For faster access in Point.update
44984                        points[i] = point;
44985                    }
44986                }
44987
44988                // restore keys options (#6590)
44989                series.options.keys = keys;
44990
44991                // Hide cropped-away points - this only runs when the number of points
44992                // is above cropThreshold, or when swithching view from non-grouped
44993                // data to grouped data (#637)
44994                if (
44995                    data &&
44996                    (
44997                        processedDataLength !== (dataLength = data.length) ||
44998                        hasGroupedData
44999                    )
45000                ) {
45001                    for (i = 0; i < dataLength; i++) {
45002                        // when has grouped data, clear all points
45003                        if (i === cropStart && !hasGroupedData) {
45004                            i += processedDataLength;
45005                        }
45006                        if (data[i]) {
45007                            data[i].destroyElements();
45008                            data[i].plotX = undefined; // #1003
45009                        }
45010                    }
45011                }
45012
45013                /**
45014                 * Read only. An array containing those values converted to points, but
45015                 * in case the series data length exceeds the `cropThreshold`, or if the
45016                 * data is grouped, `series.data` doesn't contain all the points. It
45017                 * only contains the points that have been created on demand. To
45018                 * modify the data, use {@link Highcharts.Series#setData} or {@link
45019                 * Highcharts.Point#update}.
45020                 *
45021                 * @name data
45022                 * @memberOf Highcharts.Series
45023                 * @see  Series.points
45024                 * @type {Array.<Highcharts.Point>}
45025                 */
45026                series.data = data;
45027
45028                /**
45029                 * An array containing all currently visible point objects. In case of
45030                 * cropping, the cropped-away points are not part of this array. The
45031                 * `series.points` array starts at `series.cropStart` compared to
45032                 * `series.data` and `series.options.data`. If however the series data
45033                 * is grouped, these can't be correlated one to one. To
45034                 * modify the data, use {@link Highcharts.Series#setData} or {@link
45035                 * Highcharts.Point#update}.
45036                 * @name points
45037                 * @memberof Series
45038                 * @type {Array.<Point>}
45039                 */
45040                series.points = points;
45041            },
45042
45043            /**
45044             * Calculate Y extremes for the visible data. The result is set as 
45045             * `dataMin` and `dataMax` on the Series item.
45046             *
45047             * @param  {Array.<Number>} [yData]
45048             *         The data to inspect. Defaults to the current data within the
45049             *         visible range.
45050             * 
45051             */
45052            getExtremes: function(yData) {
45053                var xAxis = this.xAxis,
45054                    yAxis = this.yAxis,
45055                    xData = this.processedXData,
45056                    yDataLength,
45057                    activeYData = [],
45058                    activeCounter = 0,
45059                    // #2117, need to compensate for log X axis
45060                    xExtremes = xAxis.getExtremes(),
45061                    xMin = xExtremes.min,
45062                    xMax = xExtremes.max,
45063                    validValue,
45064                    withinRange,
45065                    x,
45066                    y,
45067                    i,
45068                    j;
45069
45070                yData = yData || this.stackedYData || this.processedYData || [];
45071                yDataLength = yData.length;
45072
45073                for (i = 0; i < yDataLength; i++) {
45074
45075                    x = xData[i];
45076                    y = yData[i];
45077
45078                    // For points within the visible range, including the first point
45079                    // outside the visible range (#7061), consider y extremes.
45080                    validValue =
45081                        (isNumber(y, true) || isArray(y)) &&
45082                        (!yAxis.positiveValuesOnly || (y.length || y > 0));
45083                    withinRange =
45084                        this.getExtremesFromAll ||
45085                        this.options.getExtremesFromAll ||
45086                        this.cropped ||
45087                        ((xData[i + 1] || x) >= xMin && (xData[i - 1] || x) <= xMax);
45088
45089                    if (validValue && withinRange) {
45090
45091                        j = y.length;
45092                        if (j) { // array, like ohlc or range data
45093                            while (j--) {
45094                                if (y[j] !== null) {
45095                                    activeYData[activeCounter++] = y[j];
45096                                }
45097                            }
45098                        } else {
45099                            activeYData[activeCounter++] = y;
45100                        }
45101                    }
45102                }
45103
45104                this.dataMin = arrayMin(activeYData);
45105                this.dataMax = arrayMax(activeYData);
45106            },
45107
45108            /**
45109             * Translate data points from raw data values to chart specific positioning
45110             * data needed later in the `drawPoints` and `drawGraph` functions. This
45111             * function can be overridden in plugins and custom series type
45112             * implementations.
45113             */
45114            translate: function() {
45115                if (!this.processedXData) { // hidden series
45116                    this.processData();
45117                }
45118                this.generatePoints();
45119                var series = this,
45120                    options = series.options,
45121                    stacking = options.stacking,
45122                    xAxis = series.xAxis,
45123                    categories = xAxis.categories,
45124                    yAxis = series.yAxis,
45125                    points = series.points,
45126                    dataLength = points.length,
45127                    hasModifyValue = !!series.modifyValue,
45128                    i,
45129                    pointPlacement = options.pointPlacement,
45130                    dynamicallyPlaced =
45131                    pointPlacement === 'between' ||
45132                    isNumber(pointPlacement),
45133                    threshold = options.threshold,
45134                    stackThreshold = options.startFromThreshold ? threshold : 0,
45135                    plotX,
45136                    plotY,
45137                    lastPlotX,
45138                    stackIndicator,
45139                    closestPointRangePx = Number.MAX_VALUE;
45140
45141                // Point placement is relative to each series pointRange (#5889)
45142                if (pointPlacement === 'between') {
45143                    pointPlacement = 0.5;
45144                }
45145                if (isNumber(pointPlacement)) {
45146                    pointPlacement *= pick(options.pointRange || xAxis.pointRange);
45147                }
45148
45149                // Translate each point
45150                for (i = 0; i < dataLength; i++) {
45151                    var point = points[i],
45152                        xValue = point.x,
45153                        yValue = point.y,
45154                        yBottom = point.low,
45155                        stack = stacking && yAxis.stacks[(
45156                            series.negStacks &&
45157                            yValue < (stackThreshold ? 0 : threshold) ? '-' : ''
45158                        ) + series.stackKey],
45159                        pointStack,
45160                        stackValues;
45161
45162                    // Discard disallowed y values for log axes (#3434)
45163                    if (yAxis.positiveValuesOnly && yValue !== null && yValue <= 0) {
45164                        point.isNull = true;
45165                    }
45166
45167                    // Get the plotX translation
45168                    point.plotX = plotX = correctFloat( // #5236
45169                        Math.min(Math.max(-1e5, xAxis.translate(
45170                            xValue,
45171                            0,
45172                            0,
45173                            0,
45174                            1,
45175                            pointPlacement,
45176                            this.type === 'flags'
45177                        )), 1e5) // #3923
45178                    );
45179
45180                    // Calculate the bottom y value for stacked series
45181                    if (
45182                        stacking &&
45183                        series.visible &&
45184                        !point.isNull &&
45185                        stack &&
45186                        stack[xValue]
45187                    ) {
45188                        stackIndicator = series.getStackIndicator(
45189                            stackIndicator,
45190                            xValue,
45191                            series.index
45192                        );
45193                        pointStack = stack[xValue];
45194                        stackValues = pointStack.points[stackIndicator.key];
45195                        yBottom = stackValues[0];
45196                        yValue = stackValues[1];
45197
45198                        if (
45199                            yBottom === stackThreshold &&
45200                            stackIndicator.key === stack[xValue].base
45201                        ) {
45202                            yBottom = pick(threshold, yAxis.min);
45203                        }
45204                        if (yAxis.positiveValuesOnly && yBottom <= 0) { // #1200, #1232
45205                            yBottom = null;
45206                        }
45207
45208                        point.total = point.stackTotal = pointStack.total;
45209                        point.percentage =
45210                            pointStack.total &&
45211                            (point.y / pointStack.total * 100);
45212                        point.stackY = yValue;
45213
45214                        // Place the stack label
45215                        pointStack.setOffset(
45216                            series.pointXOffset || 0,
45217                            series.barW || 0
45218                        );
45219
45220                    }
45221
45222                    // Set translated yBottom or remove it
45223                    point.yBottom = defined(yBottom) ?
45224                        yAxis.translate(yBottom, 0, 1, 0, 1) :
45225                        null;
45226
45227                    // general hook, used for Highstock compare mode
45228                    if (hasModifyValue) {
45229                        yValue = series.modifyValue(yValue, point);
45230                    }
45231
45232                    // Set the the plotY value, reset it for redraws
45233                    point.plotY = plotY =
45234                        (typeof yValue === 'number' && yValue !== Infinity) ?
45235                        Math.min(Math.max(-1e5,
45236                            yAxis.translate(yValue, 0, 1, 0, 1)), 1e5) : // #3201
45237                        undefined;
45238
45239                    point.isInside =
45240                        plotY !== undefined &&
45241                        plotY >= 0 &&
45242                        plotY <= yAxis.len && // #3519
45243                        plotX >= 0 &&
45244                        plotX <= xAxis.len;
45245
45246
45247                    // Set client related positions for mouse tracking
45248                    point.clientX = dynamicallyPlaced ?
45249                        correctFloat(
45250                            xAxis.translate(xValue, 0, 0, 0, 1, pointPlacement)
45251                        ) :
45252                        plotX; // #1514, #5383, #5518
45253
45254                    point.negative = point.y < (threshold || 0);
45255
45256                    // some API data
45257                    point.category = categories && categories[point.x] !== undefined ?
45258                        categories[point.x] : point.x;
45259
45260                    // Determine auto enabling of markers (#3635, #5099)
45261                    if (!point.isNull) {
45262                        if (lastPlotX !== undefined) {
45263                            closestPointRangePx = Math.min(
45264                                closestPointRangePx,
45265                                Math.abs(plotX - lastPlotX)
45266                            );
45267                        }
45268                        lastPlotX = plotX;
45269                    }
45270
45271                    // Find point zone
45272                    point.zone = this.zones.length && point.getZone();
45273                }
45274                series.closestPointRangePx = closestPointRangePx;
45275            },
45276
45277            /**
45278             * Return the series points with null points filtered out.
45279             *
45280             * @param  {Array.<Point>} [points]
45281             *         The points to inspect, defaults to {@link Series.points}.
45282             * @param  {Boolean} [insideOnly=false]
45283             *         Wh
45283ether to inspect only the points that are inside the visible
45284             *         view.
45285             *
45286             * @return {Array.<Point>}
45287             *         The valid points.
45288             */
45289            getValidPoints: function(points, insideOnly) {
45290                var chart = this.chart;
45291                // #3916, #5029, #5085
45292                return grep(points || this.points || [], function isValidPoint(point) {
45293                    if (insideOnly && !chart.isInsidePlot(
45294                            point.plotX,
45295                            point.plotY,
45296                            chart.inverted
45297                        )) {
45298                        return false;
45299                    }
45300                    return !point.isNull;
45301                });
45302            },
45303
45304            /**
45305             * Set the clipping for the series. For animated series it is called twice,
45306             * first to initiate animating the clip then the second time without the
45307             * animation to set the final clip.
45308             *
45309             * @private
45310             */
45311            setClip: function(animation) {
45312                var chart = this.chart,
45313                    options = this.options,
45314                    renderer = chart.renderer,
45315                    inverted = chart.inverted,
45316                    seriesClipBox = this.clipBox,
45317                    clipBox = seriesClipBox || chart.clipBox,
45318                    sharedClipKey =
45319                    this.sharedClipKey || [
45320                        '_sharedClip',
45321                        animation && animation.duration,
45322                        animation && animation.easing,
45323                        clipBox.height,
45324                        options.xAxis,
45325                        options.yAxis
45326                    ].join(','), // #4526
45327                    clipRect = chart[sharedClipKey],
45328                    markerClipRect = chart[sharedClipKey + 'm'];
45329
45330                // If a clipping rectangle with the same properties is currently present
45331                // in the chart, use that.
45332                if (!clipRect) {
45333
45334                    // When animation is set, prepare the initial positions
45335                    if (animation) {
45336                        clipBox.width = 0;
45337                        if (inverted) {
45338                            clipBox.x = chart.plotSizeX;
45339                        }
45340
45341                        chart[sharedClipKey + 'm'] = markerClipRect = renderer.clipRect(
45342                            inverted ? chart.plotSizeX + 99 : -99, // include the width of the first marker
45343                            inverted ? -chart.plotLeft : -chart.plotTop,
45344                            99,
45345                            inverted ? chart.chartWidth : chart.chartHeight
45346                        );
45347                    }
45348                    chart[sharedClipKey] = clipRect = renderer.clipRect(clipBox);
45349                    // Create hashmap for series indexes
45350                    clipRect.count = {
45351                        length: 0
45352                    };
45353
45354                }
45355                if (animation) {
45356                    if (!clipRect.count[this.index]) {
45357                        clipRect.count[this.index] = true;
45358                        clipRect.count.length += 1;
45359                    }
45360                }
45361
45362                if (options.clip !== false) {
45363                    this.group.clip(animation || seriesClipBox ? clipRect : chart.clipRect);
45364                    this.markerGroup.clip(markerClipRect);
45365                    this.sharedClipKey = sharedClipKey;
45366                }
45367
45368                // Remove the shared clipping rectangle when all series are shown
45369                if (!animation) {
45370                    if (clipRect.count[this.index]) {
45371                        delete clipRect.count[this.index];
45372                        clipRect.count.length -= 1;
45373                    }
45374
45375                    if (clipRect.count.length === 0 && sharedClipKey && chart[sharedClipKey]) {
45376                        if (!seriesClipBox) {
45377                            chart[sharedClipKey] = chart[sharedClipKey].destroy();
45378                        }
45379                        if (chart[sharedClipKey + 'm']) {
45380                            chart[sharedClipKey + 'm'] = chart[sharedClipKey + 'm'].destroy();
45381                        }
45382                    }
45383                }
45384            },
45385
45386            /**
45387             * Animate in the series. Called internally twice. First with the `init`
45388             * parameter set to true, which sets up the initial state of the animation.
45389             * Then when ready, it is called with the `init` parameter undefined, in 
45390             * order to perform the actual animation. After the second run, the function
45391             * is removed.
45392             *
45393             * @param  {Boolean} init
45394             *         Initialize the animation.
45395             */
45396            animate: function(init) {
45397                var series = this,
45398                    chart = series.chart,
45399                    clipRect,
45400                    animation = animObject(series.options.animation),
45401                    sharedClipKey;
45402
45403                // Initialize the animation. Set up the clipping rectangle.
45404                if (init) {
45405
45406                    series.setClip(animation);
45407
45408                    // Run the animation
45409                } else {
45410                    sharedClipKey = this.sharedClipKey;
45411                    clipRect = chart[sharedClipKey];
45412                    if (clipRect) {
45413                        clipRect.animate({
45414                            width: chart.plotSizeX,
45415                            x: 0
45416                        }, animation);
45417                    }
45418                    if (chart[sharedClipKey + 'm']) {
45419                        chart[sharedClipKey + 'm'].animate({
45420                            width: chart.plotSizeX + 99,
45421                            x: 0
45422                        }, animation);
45423                    }
45424
45425                    // Delete this function to allow it only once
45426                    series.animate = null;
45427
45428                }
45429            },
45430
45431            /**
45432             * This runs after animation to land on the final plot clipping.
45433             *
45434             * @private
45435             */
45436            afterAnimate: function() {
45437                this.setClip();
45438                fireEvent(this, 'afterAnimate');
45439                this.finishedAnimating = true;
45440            },
45441
45442            /**
45443             * Draw the markers for line-like series types, and columns or other
45444             * graphical representation for {@link Point} objects for other series
45445             * types. The resulting element is typically stored as {@link
45446             * Point.graphic}, and is created on the first call and updated and moved on
45447             * subsequent calls.
45448             */
45449            drawPoints: function() {
45450                var series = this,
45451                    points = series.points,
45452                    chart = series.chart,
45453                    i,
45454                    point,
45455                    symbol,
45456                    graphic,
45457                    options = series.options,
45458                    seriesMarkerOptions = options.marker,
45459                    pointMarkerOptions,
45460                    hasPointMarker,
45461                    enabled,
45462                    isInside,
45463                    markerGroup = series[series.specialGroup] || series.markerGroup,
45464                    xAxis = series.xAxis,
45465                    markerAttribs,
45466                    globallyEnabled = pick(
45467                        seriesMarkerOptions.enabled,
45468                        xAxis.isRadial ? true : null,
45469                        // Use larger or equal as radius is null in bubbles (#6321)
45470                        series.closestPointRangePx >= 2 * seriesMarkerOptions.radius
45471                    );
45472
45473                if (seriesMarkerOptions.enabled !== false || series._hasPointMarkers) {
45474
45475                    for (i = 0; i < points.length; i++) {
45476                        point = points[i];
45477                        graphic = point.graphic;
45478                        pointMarkerOptions = point.marker || {};
45479                        hasPointMarker = !!point.marker;
45480                        enabled = (globallyEnabled && pointMarkerOptions.enabled === undefined) || pointMarkerOptions.enabled;
45481                        isInside = point.isInside;
45482
45483                        // only draw the point if y is defined
45484                        if (enabled && !point.isNull) {
45485
45486                            // Shortcuts
45487                            symbol = pick(pointMarkerOptions.symbol, series.symbol);
45488                            point.hasImage = symbol.indexOf('url') === 0;
45489
45490                            markerAttribs = series.markerAttribs(
45491                                point,
45492                                point.selected && 'select'
45493                            );
45494
45495                            if (graphic) { // update
45496                                graphic[isInside ? 'show' : 'hide'](true) // Since the marker group isn't clipped, each individual marker must be toggled
45497                                    .animate(markerAttribs);
45498                            } else if (isInside && (markerAttribs.width > 0 || point.hasImage)) {
45499
45500                                /**
45501                                 * The graphic representation of the point. Typically
45502                                 * this is a simple shape, like a `rect` for column
45503                                 * charts or `path` for line markers, but for some 
45504                                 * complex series types like boxplot or 3D charts, the
45505                                 * graphic may be a `g` element containing other shapes.
45506                                 * The graphic is generated the first time {@link
45507                                 * Series#drawPoints} runs, and updated and moved on
45508                                 * subsequent runs.
45509                                 *
45510                                 * @memberof Point
45511                                 * @name graphic
45512                                 * @type {SVGElement}
45513                                 */
45514                                point.graphic = graphic = chart.renderer.symbol(
45515                                        symbol,
45516                                        markerAttribs.x,
45517                                        markerAttribs.y,
45518                                        markerAttribs.width,
45519                                        markerAttribs.height,
45520                                        hasPointMarker ? pointMarkerOptions : seriesMarkerOptions
45521                                    )
45522                                    .add(markerGroup);
45523                            }
45524
45525
45526                            // Presentational attributes
45527                            if (graphic) {
45528                                graphic.attr(series.pointAttribs(point, point.selected && 'select'));
45529                            }
45530
45531
45532                            if (graphic) {
45533                                graphic.addClass(point.getClassName(), true);
45534                            }
45535
45536                        } else if (graphic) {
45537                            point.graphic = graphic.destroy(); // #1269
45538                        }
45539                    }
45540                }
45541
45542            },
45543
45544            /**
45545             * Get non-presentational attributes for a point. Used internally for both
45546             * styled mode and classic. Can be overridden for different series types.
45547             *
45548             * @see    Series#pointAttribs
45549             *
45550             * @param  {Point} point
45551             *         The Point to inspect.
45552             * @param  {String} [state]
45553             *         The state, can be either `hover`, `select` or undefined.
45554             *
45555             * @return {SVGAttributes}
45556             *         A hash containing those attributes that are not settable from
45557             *         CSS.
45558             */
45559            markerAttribs: function(point, state) {
45560                var seriesMarkerOptions = this.options.marker,
45561                    seriesStateOptions,
45562                    pointMarkerOptions = point.marker || {},
45563                    pointStateOptions,
45564                    radius = pick(
45565                        pointMarkerOptions.radius,
45566                        seriesMarkerOptions.radius
45567                    ),
45568                    attribs;
45569
45570                // Handle hover and select states
45571                if (state) {
45572                    seriesStateOptions = seriesMarkerOptions.states[state];
45573                    pointStateOptions = pointMarkerOptions.states &&
45574                        pointMarkerOptions.states[state];
45575
45576                    radius = pick(
45577                        pointStateOptions && pointStateOptions.radius,
45578                        seriesStateOptions && seriesStateOptions.radius,
45579                        radius + (seriesStateOptions && seriesStateOptions.radiusPlus || 0)
45580                    );
45581                }
45582
45583                if (point.hasImage) {
45584                    radius = 0; // and subsequently width and height is not set
45585                }
45586
45587                attribs = {
45588                    x: Math.floor(point.plotX) - radius, // Math.floor for #1843
45589                    y: point.plotY - radius
45590                };
45591
45592                if (radius) {
45593                    attribs.width = attribs.height = 2 * radius;
45594                }
45595
45596                return attribs;
45597
45598            },
45599
45600
45601            /**
45602             * Internal function to get presentational attributes for each point. Unlike
45603             * {@link Series#markerAttribs}, this function should return those
45604             * attributes that can also be set in CSS. In styled mode, `pointAttribs`
45605             * won't be called.
45606             *
45607             * @param  {Point} point
45608             *         The point instance to inspect.
45609             * @param  {String} [state]
45610             *         The point state, can be either `hover`, `select` or undefined for
45611             *         normal state.
45612             *
45613             * @return {SVGAttributes}
45614             *         The presentational attributes to be set on the point.
45615             */
45616            pointAttribs: function(point, state) {
45617                var seriesMarkerOptions = this.options.marker,
45618                    seriesStateOptions,
45619                    pointOptions = point && point.options,
45620                    pointMarkerOptions = (pointOptions && pointOptions.marker) || {},
45621                    pointStateOptions,
45622                    color = this.color,
45623                    pointColorOption = pointOptions && pointOptions.color,
45624                    pointColor = point && point.color,
45625                    strokeWidth = pick(
45626                        pointMarkerOptions.lineWidth,
45627                        seriesMarkerOptions.lineWidth
45628                    ),
45629                    zoneColor = point && point.zone && point.zone.color,
45630                    fill,
45631                    stroke;
45632
45633                color = pointColorOption || zoneColor || pointColor || color;
45634                fill = pointMarkerOptions.fillColor || seriesMarkerOptions.fillColor || color;
45635                stroke = pointMarkerOptions.lineColor || seriesMarkerOptions.lineColor || color;
45636
45637                // Handle hover and select states
45638                if (state) {
45639                    seriesStateOptions = seriesMarkerOptions.states[state];
45640                    pointStateOptions = (pointMarkerOptions.states && pointMarkerOptions.states[state]) || {};
45641                    strokeWidth = pick(
45642                        pointStateOptions.lineWidth,
45643                        seriesStateOptions.lineWidth,
45644                        strokeWidth + pick(
45645                            pointStateOptions.lineWidthPlus,
45646                            seriesStateOptions.lineWidthPlus,
45647                            0
45648                        )
45649                    );
45650                    fill = pointStateOptions.fillColor || seriesStateOptions.fillColor || fill;
45651                    stroke = pointStateOptions.lineColor || seriesStateOptions.lineColor || stroke;
45652                }
45653
45654                return {
45655                    'stroke': stroke,
45656                    'stroke-width': strokeWidth,
45657                    'fill': fill
45658                };
45659            },
45660
45661            /**
45662             * Clear DOM objects and free up memory.
45663             *
45664             * @private
45665             */
45666            destroy: function() {
45667                var series = this,
45668                    chart = series.chart,
45669                    issue134 = /AppleWebKit\/533/.test(win.navigator.userAgent),
45670                    destroy,
45671                    i,
45672                    data = series.data || [],
45673                    point,
45674                    axis;
45675
45676                // add event hook
45677                fireEvent(series, 'destroy');
45678
45679                // remove all events
45680                removeEvent(series);
45681
45682                // erase from axes
45683                each(series.axisTypes || [], function(AXIS) {
45684                    axis = series[AXIS];
45685                    if (axis && axis.series) {
45686                        erase(axis.series, series);
45687                        axis.isDirty = axis.forceRedraw = true;
45688                    }
45689                });
45690
45691                // remove legend items
45692                if (series.legendItem) {
45693                    series.chart.legend.destroyItem(series);
45694                }
45695
45696                // destroy all points with their elements
45697                i = data.length;
45698                while (i--) {
45699                    point = data[i];
45700                    if (point && point.destroy) {
45701                        point.destroy();
45702                    }
45703                }
45704                series.points = null;
45705
45706                // Clear the animation timeout if we are destroying the series during initial animation
45707                clearTimeout(series.animationTimeout);
45708
45709                // Destroy all SVGElements associated to the series
45710                objectEach(series, function(val, prop) {
45711                    if (val instanceof SVGElement && !val.survive) { // Survive provides a hook for not destroying
45712
45713                        // issue 134 workaround
45714                        destroy = issue134 && prop === 'group' ?
45715                            'hide' :
45716                            'destroy';
45717
45718                        val[destroy]();
45719                    }
45720                });
45721
45722                // remove from hoverSeries
45723                if (chart.hoverSeries === series) {
45724                    chart.hoverSeries = null;
45725                }
45726                erase(chart.series, series);
45727                chart.orderSeries();
45728
45729                // clear all members
45730                objectEach(series, function(val, prop) {
45731                    delete series[prop];
45732                });
45733            },
45734
45735            /**
45736             * Get the graph path.
45737             *
45738             * @private
45739             */
45740            getGraphPath: function(points, nullsAsZeroes, connectCliffs) {
45741                var series = this,
45742                    options = series.options,
45743                    step = options.step,
45744                    reversed,
45745                    graphPath = [],
45746                    xMap = [],
45747                    gap;
45748
45749                points = points || series.points;
45750
45751                // Bottom of a stack is reversed
45752                reversed = points.reversed;
45753                if (reversed) {
45754                    points.reverse();
45755                }
45756                // Reverse the steps (#5004)
45757                step = {
45758                    right: 1,
45759                    center: 2
45760                }[step] || (step && 3);
45761                if (step && reversed) {
45762                    step = 4 - step;
45763                }
45764
45765                // Remove invalid points, especially in spline (#5015)
45766                if (options.connectNulls && !nullsAsZeroes && !connectCliffs) {
45767                    points = this.getValidPoints(points);
45768                }
45769
45770                // Build the line
45771                each(points, function(point, i) {
45772
45773                    var plotX = point.plotX,
45774                        plotY = point.plotY,
45775                        lastPoint = points[i - 1],
45776                        pathToPoint; // the path to this point from the previous
45777
45778                    if ((point.leftCliff || (lastPoint && lastPoint.rightCliff)) && !connectCliffs) {
45779                        gap = true; // ... and continue
45780                    }
45781
45782                    // Line series, nullsAsZeroes is not handled
45783                    if (point.isNull && !defined(nullsAsZeroes) && i > 0) {
45784                        gap = !options.connectNulls;
45785
45786                        // Area series, nullsAsZeroes is set
45787                    } else if (point.isNull && !nullsAsZeroes) {
45788                        gap = true;
45789
45790                    } else {
45791
45792                        if (i === 0 || gap) {
45793                            pathToPoint = ['M', point.plotX, point.plotY];
45794
45795                        } else if (series.getPointSpline) { // generate the spline as defined in the SplineSeries object
45796
45797                            pathToPoint = series.getPointSpline(points, point, i);
45798
45799                        } else if (step) {
45800
45801                            if (step === 1) { // right
45802                                pathToPoint = [
45803                                    'L',
45804                                    lastPoint.plotX,
45805                                    plotY
45806                                ];
45807
45808                            } else if (step === 2) { // center
45809                                pathToPoint = [
45810                                    'L',
45811                                    (lastPoint.plotX + plotX) / 2,
45812                                    lastPoint.plotY,
45813                                    'L',
45814                                    (lastPoint.plotX + plotX) / 2,
45815                                    plotY
45816                                ];
45817
45818                            } else {
45819                                pathToPoint = [
45820                                    'L',
45821                                    plotX,
45822                                    lastPoint.plotY
45823                                ];
45824                            }
45825                            pathToPoint.push('L', plotX, plotY);
45826
45827                        } else {
45828                            // normal line to next point
45829                            pathToPoint = [
45830                                'L',
45831                                plotX,
45832                                plotY
45833                            ];
45834                        }
45835
45836                        // Prepare for animation. When step is enabled, there are two path nodes for each x value.
45837                        xMap.push(point.x);
45838                        if (step) {
45839                            xMap.push(point.x);
45840                        }
45841
45842                        graphPath.push.apply(graphPath, pathToPoint);
45843                        gap = false;
45844                    }
45845                });
45846
45847                graphPath.xMap = xMap;
45848                series.graphPath = graphPath;
45849
45850                return graphPath;
45851
45852            },
45853
45854            /**
45855             * Draw the graph. Called internally when rendering line-like series types.
45856             * The first time it generates the `series.graph` item and optionally other
45857             * series-wide items like `series.area` for area charts. On subsequent calls
45858             * these items are updated with new positions and attributes.
45859             */
45860            drawGraph: function() {
45861                var series = this,
45862                    options = this.options,
45863                    graphPath = (this.gappedPath || this.getGraphPath).call(this),
45864                    props = [
45865                        [
45866                            'graph',
45867                            'highcharts-graph',
45868
45869                            options.lineColor || this.color,
45870                            options.dashStyle
45871
45872                        ]
45873                    ];
45874
45875                // Add the zone properties if any
45876                each(this.zones, function(zone, i) {
45877                    props.push([
45878                        'zone-graph-' + i,
45879                        'highcharts-graph highcharts-zone-graph-' + i + ' ' + (zone.className || ''),
45880
45881                        zone.color || series.color,
45882                        zone.dashStyle || options.dashStyle
45883
45884                    ]);
45885                });
45886
45887                // Draw the graph
45888                each(props, function(prop, i) {
45889                    var graphKey = prop[0],
45890                        graph = series[graphKey],
45891                        attribs;
45892
45893                    if (graph) {
45894                        graph.endX = series.preventGraphAnimation ?
45895                            null :
45896                            graphPath.xMap;
45897                        graph.animate({
45898                            d: graphPath
45899                        });
45900
45901                    } else if (graphPath.length) { // #1487
45902
45903                        series[graphKey] = series.chart.renderer.path(graphPath)
45904                            .addClass(prop[1])
45905                            .attr({
45906                                zIndex: 1
45907                            }) // #1069
45908                            .add(series.group);
45909
45910
45911                        attribs = {
45912                            'stroke': prop[2],
45913                            'stroke-width': options.lineWidth,
45914                            'fill': (series.fillGraph && series.color) || 'none' // Polygon series use filled graph
45915                        };
45916
45917                        if (prop[3]) {
45918                            attribs.dashstyle = prop[3];
45919                        } else if (options.linecap !== 'square') {
45920                            attribs['stroke-linecap'] = attribs['stroke-linejoin'] = 'round';
45921                        }
45922
45923                        graph = series[graphKey]
45924                            .attr(attribs)
45925                            .shadow((i < 2) && options.shadow); // add shadow to normal series (0) or to first zone (1) #3932
45926
45927                    }
45928
45929                    // Helpers for animation
45930                    if (graph) {
45931                        graph.startX = graphPath.xMap;
45932                        graph.isArea = graphPath.isArea; // For arearange animation
45933                    }
45934                });
45935            },
45936
45937            /**
45938             * Clip the graphs into zones for colors and styling.
45939             *
45940             * @private
45941             */
45942            applyZones: function() {
45943                var series = this,
45944                    chart = this.chart,
45945                    renderer = chart.renderer,
45946                    zones = this.zones,
45947                    translatedFrom,
45948                    translatedTo,
45949                    clips = this.clips || [],
45950                    clipAttr,
45951                    graph = this.graph,
45952                    area = this.area,
45953                    chartSizeMax = Math.max(chart.chartWidth, chart.chartHeight),
45954                    axis = this[(this.zoneAxis || 'y') + 'Axis'],
45955                    extremes,
45956                    reversed,
45957                    inverted = chart.inverted,
45958                    horiz,
45959                    pxRange,
45960                    pxPosMin,
45961                    pxPosMax,
45962                    ignoreZones = false;
45963
45964                if (zones.length && (graph || area) && axis && axis.min !== undefined) {
45965                    reversed = axis.reversed;
45966                    horiz = axis.horiz;
45967                    // The use of the Color Threshold assumes there are no gaps
45968                    // so it is safe to hide the original graph and area
45969                    if (graph) {
45970                        graph.hide();
45971                    }
45972                    if (area) {
45973                        area.hide();
45974                    }
45975
45976                    // Create the clips
45977                    extremes = axis.getExtremes();
45978                    each(zones, function(threshold, i) {
45979
45980                        translatedFrom = reversed ?
45981                            (horiz ? chart.plotWidth : 0) :
45982                            (horiz ? 0 : axis.toPixels(extremes.min));
45983                        translatedFrom = Math.min(Math.max(pick(translatedTo, translatedFrom), 0), chartSizeMax);
45984                        translatedTo = Math.min(Math.max(Math.round(axis.toPixels(pick(threshold.value, extremes.max), true)), 0), chartSizeMax);
45985
45986                        if (ignoreZones) {
45987                            translatedFrom = translatedTo = axis.toPixels(extremes.max);
45988                        }
45989
45990                        pxRange = Math.abs(translatedFrom - translatedTo);
45991                        pxPosMin = Math.min(translatedFrom, translatedTo);
45992                        pxPosMax = Math.max(translatedFrom, translatedTo);
45993                        if (axis.isXAxis) {
45994                            clipAttr = {
45995                                x: inverted ? pxPosMax : pxPosMin,
45996                                y: 0,
45997                                width: pxRange,
45998                                height: chartSizeMax
45999                            };
46000                            if (!horiz) {
46001                                clipAttr.x = chart.plotHeight - clipAttr.x;
46002                            }
46003                        } else {
46004                            clipAttr = {
46005                                x: 0,
46006                                y: inverted ? pxPosMax : pxPosMin,
46007                                width: chartSizeMax,
46008                                height: pxRange
46009                            };
46010                            if (horiz) {
46011                                clipAttr.y = chart.plotWidth - clipAttr.y;
46012                            }
46013                        }
46014
46015
46016                        // VML SUPPPORT
46017                        if (inverted && renderer.isVML) {
46018                            if (axis.isXAxis) {
46019                                clipAttr = {
46020                                    x: 0,
46021                                    y: reversed ? pxPosMin : pxPosMax,
46022                                    height: clipAttr.width,
46023                                    width: chart.chartWidth
46024                                };
46025                            } else {
46026                                clipAttr = {
46027                                    x: clipAttr.y - chart.plotLeft - chart.spacingBox.x,
46028                                    y: 0,
46029                                    width: clipAttr.height,
46030                                    height: chart.chartHeight
46031                                };
46032                            }
46033                        }
46034                        // END OF VML SUPPORT
46035
46036
46037                        if (clips[i]) {
46038                            clips[i].animate(clipAttr);
46039                        } else {
46040                            clips[i] = renderer.clipRect(clipAttr);
46041
46042                            if (graph) {
46043                                series['zone-graph-' + i].clip(clips[i]);
46044                            }
46045
46046                            if (area) {
46047                                series['zone-area-' + i].clip(clips[i]);
46048                            }
46049                        }
46050                        // if this zone extends out of the axis, ignore the others
46051                        ignoreZones = threshold.value > extremes.max;
46052                    });
46053                    this.clips = clips;
46054                }
46055            },
46056
46057            /**
46058             * Initialize and perform group inversion on series.group and
46059             * series.markerGroup.
46060             *
46061             * @private
46062             */
46063            invertGroups: function(inverted) {
46064                var series = this,
46065                    chart = series.chart,
46066                    remover;
46067
46068                function setInvert() {
46069                    each(['group', 'markerGroup'], function(groupName) {
46070                        if (series[groupName]) {
46071
46072                            // VML/HTML needs explicit attributes for flipping
46073                            if (chart.renderer.isVML) {
46074                                series[groupName].attr({
46075                                    width: series.yAxis.len,
46076                                    height: series.xAxis.len
46077                                });
46078                            }
46079
46080                            series[groupName].width = series.yAxis.len;
46081                            series[groupName].height = series.xAxis.len;
46082                            series[groupName].invert(inverted);
46083                        }
46084                    });
46085                }
46086
46087                // Pie, go away (#1736)
46088                if (!series.xAxis) {
46089                    return;
46090                }
46091
46092                // A fixed size is needed for inversion to work
46093                remover = addEvent(chart, 'resize', setInvert);
46094                addEvent(series, 'destroy', remover);
46095
46096                // Do it now
46097                setInvert(inverted); // do it now
46098
46099                // On subsequent render and redraw, just do setInvert without setting up events again
46100                series.invertGroups = setInvert;
46101            },
46102
46103            /**
46104             * General abstraction for creating plot groups like series.group,
46105             * series.dataLabelsGroup and series.markerGroup. On subsequent calls, the
46106             * group will only be adjusted to the updated plot size.
46107             *
46108             * @private
46109             */
46110            plotGroup: function(prop, name, visibility, zIndex, parent) {
46111                var group = this[prop],
46112                    isNew = !group;
46113
46114                // Generate it on first call
46115                if (isNew) {
46116                    this[prop] = group = this.chart.renderer.g()
46117                        .attr({
46118                            zIndex: zIndex || 0.1 // IE8 and pointer logic use this
46119                        })
46120                        .add(parent);
46121
46122                }
46123
46124                // Add the class names, and replace existing ones as response to
46125                // Series.update (#6660)
46126                group.addClass(
46127                    (
46128                        'highcharts-' + name +
46129                        ' highcharts-series-' + this.index +
46130                        ' highcharts-' + this.type + '-series ' +
46131                        (
46132                            defined(this.colorIndex) ?
46133                            'highcharts-color-' + this.colorIndex + ' ' :
46134                            ''
46135                        ) +
46136                        (this.options.className || '') +
46137                        (group.hasClass('highcharts-tracker') ? ' highcharts-tracker' : '')
46138                    ),
46139                    true
46140                );
46141
46142                // Place it on first and subsequent (redraw) calls
46143                group.attr({
46144                    visibility: visibility
46145                })[isNew ? 'attr' : 'animate'](
46146                    this.getPlotBox()
46147                );
46148                return group;
46149            },
46150
46151            /**
46152             * Get the translation and scale for the plot area of this series.
46153             */
46154            getPlotBox: function() {
46155                var chart = this.chart,
46156                    xAxis = this.xAxis,
46157                    yAxis = this.yAxis;
46158
46159                // Swap axes for inverted (#2339)
46160                if (chart.inverted) {
46161                    xAxis = yAxis;
46162                    yAxis = this.xAxis;
46163                }
46164                return {
46165                    translateX: xAxis ? xAxis.left : chart.plotLeft,
46166                    translateY: yAxis ? yAxis.top : chart.plotTop,
46167                    scaleX: 1, // #1623
46168                    scaleY: 1
46169                };
46170            },
46171
46172            /**
46173             * Render the graph and markers. Called internally when first rendering and
46174             * later when redrawing the chart. This function can be extended in plugins,
46175             * but normally shouldn't be called directly.
46176             */
46177            render: function() {
46178                var series = this,
46179                    chart = series.chart,
46180                    group,
46181                    options = series.options,
46182                    // Animation doesn't work in IE8 quirks when the group div is
46183                    // hidden, and looks bad in other oldIE
46184                    animDuration = (!!series.animate &&
46185                        chart.renderer.isSVG &&
46186                        animObject(options.animation).duration
46187                    ),
46188                    visibility = series.visible ? 'inherit' : 'hidden', // #2597
46189                    zIndex = options.zIndex,
46190                    hasRendered = series.hasRendered,
46191                    chartSeriesGroup = chart.seriesGroup,
46192                    inverted = chart.inverted;
46193
46194                // the group
46195                group = series.plotGroup(
46196                    'group',
46197                    'series',
46198                    visibility,
46199                    zIndex,
46200                    chartSeriesGroup
46201                );
46202
46203                series.markerGroup = series.plotGroup(
46204                    'markerGroup',
46205                    'markers',
46206                    visibility,
46207                    zIndex,
46208                    chartSeriesGroup
46209                );
46210
46211                // initiate the animation
46212                if (animDuration) {
46213                    series.animate(true);
46214                }
46215
46216                // SVGRenderer needs to know this before drawing elements (#1089, #1795)
46217                group.inverted = series.isCartesian ? inverted : false;
46218
46219                // draw the graph if any
46220                if (series.drawGraph) {
46221                    series.drawGraph();
46222                    series.applyZones();
46223                }
46224
46225                /*		each(series.points, function (point) {
46226                			if (point.redraw) {
46227                				point.redraw();
46228                			}
46229                		});*/
46230
46231                // draw the data labels (inn pies they go before the points)
46232                if (series.drawDataLabels) {
46233                    series.drawDataLabels();
46234                }
46235
46236                // draw the points
46237                if (series.visible) {
46238                    series.drawPoints();
46239                }
46240
46241
46242                // draw the mouse tracking area
46243                if (
46244                    series.drawTracker &&
46245                    series.options.enableMouseTracking !== false
46246                ) {
46247                    series.drawTracker();
46248                }
46249
46250                // Handle inverted series and tracker groups
46251                series.invertGroups(inverted);
46252
46253                // Initial clipping, must be defined after inverting groups for VML.
46254                // Applies to columns etc. (#3839).
46255                if (options.clip !== false && !series.sharedClipKey && !hasRendered) {
46256                    group.clip(chart.clipRect);
46257                }
46258
46259                // Run the animation
46260                if (animDuration) {
46261                    series.animate();
46262                }
46263
46264                // Call the afterAnimate function on animation complete (but don't
46265                // overwrite the animation.complete option which should be available to
46266                // the user).
46267                if (!hasRendered) {
46268                    series.animationTimeout = syncTimeout(function() {
46269                        series.afterAnimate();
46270                    }, animDuration);
46271                }
46272
46273                series.isDirty = false; // means data is in accordance with what you see
46274                // (See #322) series.isDirty = series.isDirtyData = false; // means
46275                // data is in accordance with what you see
46276                series.hasRendered = true;
46277            },
46278
46279            /**
46280             * Redraw the series. This function is called internally from `chart.redraw`
46281             * and normally shouldn't be called directly.
46282             *
46283             * @private
46284             */
46285            redraw: function() {
46286                var series = this,
46287                    chart = series.chart,
46288                    // cache it here as it is set to false in render, but used after
46289                    wasDirty = series.isDirty || series.isDirtyData,
46290                    group = series.group,
46291                    xAxis = series.xAxis,
46292                    yAxis = series.yAxis;
46293
46294                // reposition on resize
46295                if (group) {
46296                    if (chart.inverted) {
46297                        group.attr({
46298                            width: chart.plotWidth,
46299                            height: chart.plotHeight
46300                        });
46301                    }
46302
46303                    group.animate({
46304                        translateX: pick(xAxis && xAxis.left, chart.plotLeft),
46305                        translateY: pick(yAxis && yAxis.top, chart.plotTop)
46306                    });
46307                }
46308
46309                series.translate();
46310                series.render();
46311                if (wasDirty) { // #3868, #3945
46312                    delete this.kdTree;
46313                }
46314            },
46315
46316            kdAxisArray: ['clientX', 'plotY'],
46317
46318            searchPoint: function(e, compareX) {
46319                var series = this,
46320                    xAxis = series.xAxis,
46321                    yAxis = series.yAxis,
46322                    inverted = series.chart.inverted;
46323
46324                return this.searchKDTree({
46325                    clientX: inverted ?
46326                        xAxis.len - e.chartY + xAxis.pos : e.chartX - xAxis.pos,
46327                    plotY: inverted ?
46328                        yAxis.len - e.chartX + yAxis.pos : e.chartY - yAxis.pos
46329                }, compareX);
46330            },
46331
46332            /**
46333             * Build the k-d-tree that is used by mouse and touch interaction to get the
46334             * closest point. Line-like series typically have a one-dimensional tree
46335             * where points are searched along the X axis, while scatter-like series
46336             * typically search in two dimensions, X and Y.
46337             *
46338             * @private
46339             */
46340            buildKDTree: function() {
46341
46342                // Prevent multiple k-d-trees from being built simultaneously (#6235)
46343                this.buildingKdTree = true;
46344
46345                var series = this,
46346                    dimensions = series.options.findNearestPointBy.indexOf('y') > -1 ?
46347                    2 : 1;
46348
46349                // Internal function
46350                function _kdtree(points, depth, dimensions) {
46351                    var axis,
46352                        median,
46353                        length = points && points.length;
46354
46355                    if (length) {
46356
46357                        // alternate between the axis
46358                        axis = series.kdAxisArray[depth % dimensions];
46359
46360                        // sort point array
46361                        points.sort(function(a, b) {
46362                            return a[axis] - b[axis];
46363                        });
46364
46365                        median = Math.floor(length / 2);
46366
46367                        // build and return nod
46368                        return {
46369                            point: points[median],
46370                            left: _kdtree(
46371                                points.slice(0, median), depth + 1, dimensions
46372                            ),
46373                            right: _kdtree(
46374                                points.slice(median + 1), depth + 1, dimensions
46375                            )
46376                        };
46377
46378                    }
46379                }
46380
46381                // Start the recursive build process with a clone of the points array
46382                // and null points filtered out (#3873)
46383                function startRecursive() {
46384                    series.kdTree = _kdtree(
46385                        series.getValidPoints(
46386                            null,
46387                            // For line-type series restrict to plot area, but
46388                            // column-type series not (#3916, #4511)
46389                            !series.directTouch
46390                        ),
46391                        dimensions,
46392                        dimensions
46393                    );
46394                    series.buildingKdTree = false;
46395                }
46396                delete series.kdTree;
46397
46398                // For testing tooltips, don't build async
46399                syncTimeout(startRecursive, series.options.kdNow ? 0 : 1);
46400            },
46401
46402            searchKDTree: function(point, compareX) {
46403                var series = this,
46404                    kdX = this.kdAxisArray[0],
46405                    kdY = this.kdAxisArray[1],
46406                    kdComparer = compareX ? 'distX' : 'dist',
46407                    kdDimensions = series.options.findNearestPointBy.indexOf('y') > -1 ?
46408                    2 : 1;
46409
46410                // Set the one and two dimensional distance on the point object
46411                function setDistance(p1, p2) {
46412                    var x = (defined(p1[kdX]) && defined(p2[kdX])) ?
46413                        Math.pow(p1[kdX] - p2[kdX], 2) :
46414                        null,
46415                        y = (defined(p1[kdY]) && defined(p2[kdY])) ?
46416                        Math.pow(p1[kdY] - p2[kdY], 2) :
46417                        null,
46418                        r = (x || 0) + (y || 0);
46419
46420                    p2.dist = defined(r) ? Math.sqrt(r) : Number.MAX_VALUE;
46421                    p2.distX = defined(x) ? Math.sqrt(x) : Number.MAX_VALUE;
46422                }
46423
46424                function _search(search, tree, depth, dimensions) {
46425                    var point = tree.point,
46426                        axis = series.kdAxisArray[depth % dimensions],
46427                        tdist,
46428                        sideA,
46429                        sideB,
46430                        ret = point,
46431                        nPoint1,
46432                        nPoint2;
46433
46434                    setDistance(search, point);
46435
46436                    // Pick side based on distance to splitting point
46437                    tdist = search[axis] - point[axis];
46438                    sideA = tdist < 0 ? 'left' : 'right';
46439                    sideB = tdist < 0 ? 'right' : 'left';
46440
46441                    // End of tree
46442                    if (tree[sideA]) {
46443                        nPoint1 = _search(search, tree[sideA], depth + 1, dimensions);
46444
46445                        ret = (nPoint1[kdComparer] < ret[kdComparer] ? nPoint1 : point);
46446                    }
46447                    if (tree[sideB]) {
46448                        // compare distance to current best to splitting point to decide
46449                        // wether to check side B or not
46450                        if (Math.sqrt(tdist * tdist) < ret[kdComparer]) {
46451                            nPoint2 = _search(
46452                                search,
46453                                tree[sideB],
46454                                depth + 1,
46455                                dimensions
46456                            );
46457                            ret = nPoint2[kdComparer] < ret[kdComparer] ?
46458                                nPoint2 :
46459                                ret;
46460                        }
46461                    }
46462
46463                    return ret;
46464                }
46465
46466                if (!this.kdTree && !this.buildingKdTree) {
46467                    this.buildKDTree();
46468                }
46469
46470                if (this.kdTree) {
46471                    return _search(point, this.kdTree, kdDimensions, kdDimensions);
46472                }
46473            }
46474
46475        }); // end Series prototype
46476
46477        /**
46478         * A line series displays information as a series of data points connected by
46479         * straight line segments.
46480         *
46481         * @sample {highcharts} highcharts/demo/line-basic/ Line chart
46482         * @sample {highstock} stock/demo/basic-line/ Line chart
46483         * 
46484         * @extends plotOptions.series
46485         * @product highcharts highstock
46486         * @apioption plotOptions.line
46487         */
46488
46489        /**
46490         * A `line` series. If the [type](#series.line.type) option is not
46491         * specified, it is inherited from [chart.type](#chart.type).
46492         * 
46493         * For options that apply to multiple series, it is recommended to add
46494         * them to the [plotOptions.series](#plotOptions.series) options structure.
46495         * To apply to all series of this specific type, apply it to [plotOptions.
46496         * line](#plotOptions.line).
46497         * 
46498         * @type {Object}
46499         * @extends series,plotOptions.line
46500         * @excluding dataParser,dataURL
46501         * @product highcharts highstock
46502         * @apioption series.line
46503         */
46504
46505        /**
46506         * An array of data points for the series. For the `line` series type,
46507         * points can be given in the following ways:
46508         * 
46509         * 1.  An array of numerical values. In this case, the numerical values
46510         * will be interpreted as `y` options. The `x` values will be automatically
46511         * calculated, either starting at 0 and incremented by 1, or from `pointStart`
46512         * and `pointInterval` given in the series options. If the axis has
46513         * categories, these will be used. Example:
46514         * 
46515         *  ```js
46516         *  data: [0, 5, 3, 5]
46517         *  ```
46518         * 
46519         * 2.  An array of arrays with 2 values. In this case, the values correspond
46520         * to `x,y`. If the first value is a string, it is applied as the name
46521         * of the point, and the `x` value is inferred.
46522         * 
46523         *  ```js
46524         *     data: [
46525         *         [0, 1],
46526         *         [1, 2],
46527         *         [2, 8]
46528         *     ]
46529         *  ```
46530         * 
46531         * 3.  An array of objects with named values. The objects are point
46532         * configuration objects as seen below. If the total number of data
46533         * points exceeds the series' [turboThreshold](#series.line.turboThreshold),
46534         * this option is not available.
46535         * 
46536         *  ```js
46537         *     data: [{
46538         *         x: 1,
46539         *         y: 9,
46540         *         name: "Point2",
46541         *         color: "#00FF00"
46542         *     }, {
46543         *         x: 1,
46544         *         y: 6,
46545         *         name: "Point1",
46546         *         color: "#FF00FF"
46547         *     }]
46548         *  ```
46549         * 
46550         * @type {Array<Object|Array|Number>}
46551         * @sample {highcharts} highcharts/chart/reflow-true/ Numerical values
46552         * @sample {highcharts} highcharts/series/data-array-of-arrays/ Arrays of numeric x and y
46553         * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/ Arrays of datetime x and y
46554         * @sample {highcharts} highcharts/series/data-array-of-name-value/ Arrays of point.name and 
46554y
46555         * @sample {highcharts} highcharts/series/data-array-of-objects/ Config objects
46556         * @apioption series.line.data
46557         */
46558
46559        /**
46560         * An additional, individual class name for the data point's graphic
46561         * representation.
46562         * 
46563         * @type {String}
46564         * @since 5.0.0
46565         * @product highcharts
46566         * @apioption series.line.data.className
46567         */
46568
46569        /**
46570         * Individual color for the point. By default the color is pulled from
46571         * the global `colors` array.
46572         *
46573         * In styled mode, the `color` option doesn't take effect. Instead, use 
46574         * `colorIndex`.
46575         * 
46576         * @type {Color}
46577         * @sample {highcharts} highcharts/point/color/ Mark the highest point
46578         * @default undefined
46579         * @product highcharts highstock
46580         * @apioption series.line.data.color
46581         */
46582
46583        /**
46584         * Styled mode only. A specific color index to use for the point, so its
46585         * graphic representations are given the class name
46586         * `highcharts-color-{n}`.
46587         * 
46588         * @type {Number}
46589         * @since 5.0.0
46590         * @product highcharts
46591         * @apioption series.line.data.colorIndex
46592         */
46593
46594        /**
46595         * Individual data label for each point. The options are the same as
46596         * the ones for [plotOptions.series.dataLabels](#plotOptions.series.
46597         * dataLabels)
46598         * 
46599         * @type {Object}
46600         * @sample {highcharts} highcharts/point/datalabels/ Show a label for the last value
46601         * @sample {highstock} highcharts/point/datalabels/ Show a label for the last value
46602         * @product highcharts highstock
46603         * @apioption series.line.data.dataLabels
46604         */
46605
46606        /**
46607         * A description of the point to add to the screen reader information
46608         * about the point. Requires the Accessibility module.
46609         * 
46610         * @type {String}
46611         * @default undefined
46612         * @since 5.0.0
46613         * @apioption series.line.data.description
46614         */
46615
46616        /**
46617         * An id for the point. This can be used after render time to get a
46618         * pointer to the point object through `chart.get()`.
46619         * 
46620         * @type {String}
46621         * @sample {highcharts} highcharts/point/id/ Remove an id'd point
46622         * @default null
46623         * @since 1.2.0
46624         * @product highcharts highstock
46625         * @apioption series.line.data.id
46626         */
46627
46628        /**
46629         * The rank for this point's data label in case of collision. If two
46630         * data labels are about to overlap, only the one with the highest `labelrank`
46631         * will be drawn.
46632         * 
46633         * @type {Number}
46634         * @apioption series.line.data.labelrank
46635         */
46636
46637        /**
46638         * The name of the point as shown in the legend, tooltip, dataLabel
46639         * etc.
46640         * 
46641         * @type {String}
46642         * @sample {highcharts} highcharts/series/data-array-of-objects/ Point names
46643         * @see [xAxis.uniqueNames](#xAxis.uniqueNames)
46644         * @apioption series.line.data.name
46645         */
46646
46647        /**
46648         * Whether the data point is selected initially.
46649         * 
46650         * @type {Boolean}
46651         * @default false
46652         * @product highcharts highstock
46653         * @apioption series.line.data.selected
46654         */
46655
46656        /**
46657         * The x value of the point. For datetime axes, the X value is the timestamp
46658         * in milliseconds since 1970.
46659         * 
46660         * @type {Number}
46661         * @product highcharts highstock
46662         * @apioption series.line.data.x
46663         */
46664
46665        /**
46666         * The y value of the point.
46667         * 
46668         * @type {Number}
46669         * @default null
46670         * @product highcharts highstock
46671         * @apioption series.line.data.y
46672         */
46673
46674        /**
46675         * Individual point events
46676         * 
46677         * @extends plotOptions.series.point.events
46678         * @product highcharts highstock
46679         * @apioption series.line.data.events
46680         */
46681
46682        /**
46683         * @extends plotOptions.series.marker
46684         * @product highcharts highstock
46685         * @apioption series.line.data.marker
46686         */
46687
46688    }
46688(Highcharts));
46689    (function(H) {
46690        /**
46691         * (c) 2010-2017 Torstein Honsi
46692         *
46693         * License: www.highcharts.com/license
46694         */
46695        var Axis = H.Axis,
46696            Chart = H.Chart,
46697            correctFloat = H.correctFloat,
46698            defined = H.defined,
46699            destroyObjectProperties = H.destroyObjectProperties,
46700            each = H.each,
46701            format = H.format,
46702            objectEach = H.objectEach,
46703            pick = H.pick,
46704            Series = H.Series;
46705
46706        /**
46707         * The class for stacks. Each stack, on a specific X value and either negative
46708         * or positive, has its own stack item.
46709         *
46710         * @class
46711         */
46712        H.StackItem = function(axis, options, isNegative, x, stackOption) {
46713
46714            var inverted = axis.chart.inverted;
46715
46716            this.axis = axis;
46717
46718            // Tells if the stack is negative
46719            this.isNegative = isNegative;
46720
46721            // Save the options to be able to style the label
46722            this.options = options;
46723
46724            // Save the x value to be able to position the label later
46725            this.x = x;
46726
46727            // Initialize total value
46728            this.total = null;
46729
46730            // This will keep each points' extremes stored by series.index and point 
46731            // index
46732            this.points = {};
46733
46734            // Save the stack option on the series configuration object, and whether to 
46735            // treat it as percent
46736            this.stack = stackOption;
46737            this.leftCliff = 0;
46738            this.rightCliff = 0;
46739
46740            // The align options and text align varies on whether the stack is negative 
46741            // and if the chart is inverted or not.
46742            // First test the user supplied value, then use the dynamic.
46743            this.alignOptions = {
46744                align: options.align ||
46745                    (inverted ? (isNegative ? 'left' : 'right') : 'center'),
46746                verticalAlign: options.verticalAlign ||
46747                    (inverted ? 'middle' : (isNegative ? 'bottom' : 'top')),
46748                y: pick(options.y, inverted ? 4 : (isNegative ? 14 : -6)),
46749                x: pick(options.x, inverted ? (isNegative ? -6 : 6) : 0)
46750            };
46751
46752            this.textAlign = options.textAlign ||
46753                (inverted ? (isNegative ? 'right' : 'left') : 'center');
46754        };
46755
46756        H.StackItem.prototype = {
46757            destroy: function() {
46758                destroyObjectProperties(this, this.axis);
46759            },
46760
46761            /**
46762             * Renders the stack total label and adds it to the stack label group.
46763             */
46764            render: function(group) {
46765                var options = this.options,
46766                    formatOption = options.format,
46767                    str = formatOption ?
46768                    format(formatOption, this) :
46769                    options.formatter.call(this); // format the text in the label
46770
46771                // Change the text to reflect the new total and set visibility to hidden
46772                // in case the serie is hidden
46773                if (this.label) {
46774                    this.label.attr({
46775                        text: str,
46776                        visibility: 'hidden'
46777                    });
46778                    // Create new label
46779                } else {
46780                    this.label =
46781                        this.axis.chart.renderer.text(str, null, null, options.useHTML)
46782                        .css(options.style)
46783                        .attr({
46784                            align: this.textAlign,
46785                            rotation: options.rotation,
46786                            visibility: 'hidden' // hidden until setOffset is called
46787                        })
46788                        .add(group); // add to the labels-group
46789                }
46790            },
46791
46792            /**
46793             * Sets the offset that the stack has from the x value and repositions the
46794             * label.
46795             */
46796            setOffset: function(xOffset, xWidth) {
46797                var stackItem = this,
46798                    axis = stackItem.axis,
46799                    chart = axis.chart,
46800                    // stack value translated mapped to chart coordinates
46801                    y = axis.translate(
46802                        axis.usePercentage ? 100 : stackItem.total,
46803                        0,
46804                        0,
46805                        0,
46806                        1
46807                    ),
46808                    yZero = axis.translate(0), // stack origin
46809                    h = Math.abs(y - yZero), // stack height
46810                    x = chart.xAxis[0].translate(stackItem.x) + xOffset, // x position
46811                    stackBox = stackItem.getStackBox(chart, stackItem, x, y, xWidth, h),
46812                    label = stackItem.label,
46813                    alignAttr;
46814
46815                if (label) {
46816                    // Align the label to the box
46817                    label.align(stackItem.alignOptions, null, stackBox);
46818
46819                    // Set visibility (#678)
46820                    alignAttr = label.alignAttr;
46821                    label[
46822                        stackItem.options.crop === false || chart.isInsidePlot(
46823                            alignAttr.x,
46824                            alignAttr.y
46825                        ) ? 'show' : 'hide'](true);
46826                }
46827            },
46828            getStackBox: function(chart, stackItem, x, y, xWidth, h) {
46829                var reversed = stackItem.axis.reversed,
46830                    inverted = chart.inverted,
46831                    plotHeight = chart.plotHeight,
46832                    neg = (stackItem.isNegative && !reversed) ||
46833                    (!stackItem.isNegative && reversed); // #4056
46834
46835                return { // this is the box for the complete stack
46836                    x: inverted ? (neg ? y : y - h) : x,
46837                    y: inverted ?
46838                        plotHeight - x - xWidth :
46839                        (neg ?
46840                            (plotHeight - y - h) :
46841                            plotHeight - y
46842                        ),
46843                    width: inverted ? h : xWidth,
46844                    height: inverted ? xWidth : h
46845                };
46846            }
46847        };
46848
46849        /**
46850         * Generate stacks for each series and calculate stacks total values
46851         */
46852        Chart.prototype.getStacks = function() {
46853            var chart = this;
46854
46855            // reset stacks for each yAxis
46856            each(chart.yAxis, function(axis) {
46857                if (axis.stacks && axis.hasVisibleSeries) {
46858                    axis.oldStacks = axis.stacks;
46859                }
46860            });
46861
46862            each(chart.series, function(series) {
46863                if (series.options.stacking && (series.visible === true ||
46864                        chart.options.chart.ignoreHiddenSeries === false)) {
46865                    series.stackKey = series.type + pick(series.options.stack, '');
46866                }
46867            });
46868        };
46869
46870
46871        // Stacking methods defined on the Axis prototype
46872
46873        /**
46874         * Build the stacks from top down
46875         */
46876        Axis.prototype.buildStacks = function() {
46877            var axisSeries = this.series,
46878                reversedStacks = pick(this.options.reversedStacks, true),
46879                len = axisSeries.length,
46880                i;
46881            if (!this.isXAxis) {
46882                this.usePercentage = false;
46883                i = len;
46884                while (i--) {
46885                    axisSeries[reversedStacks ? i : len - i - 1].setStackedPoints();
46886                }
46887
46888                // Loop up again to compute percent and stream stack
46889                for (i = 0; i < len; i++) {
46890                    axisSeries[i].modifyStacks();
46891                }
46892            }
46893        };
46894
46895        Axis.prototype.renderStackTotals = function() {
46896            var axis = this,
46897                chart = axis.chart,
46898                renderer = chart.renderer,
46899                stacks = axis.stacks,
46900                stackTotalGroup = axis.stackTotalGroup;
46901
46902            // Create a separate group for the stack total labels
46903            if (!stackTotalGroup) {
46904                axis.stackTotalGroup = stackTotalGroup =
46905                    renderer.g('stack-labels')
46906                    .attr({
46907                        visibility: 'visible',
46908                        zIndex: 6
46909                    })
46910                    .add();
46911            }
46912
46913            // plotLeft/Top will change when y axis gets wider so we need to translate
46914            // the stackTotalGroup at every render call. See bug #506 and #516
46915            stackTotalGroup.translate(chart.plotLeft, chart.plotTop);
46916
46917            // Render each stack total
46918            objectEach(stacks, function(type) {
46919                objectEach(type, function(stack) {
46920                    stack.render(stackTotalGroup);
46921                });
46922            });
46923        };
46924
46925        /**
46926         * Set all the stacks to initial states and destroy unused ones.
46927         */
46928        Axis.prototype.resetStacks = function() {
46929            var axis = this,
46930                stacks = axis.stacks;
46931            if (!axis.isXAxis) {
46932                objectEach(stacks, function(type) {
46933                    objectEach(type, function(stack, key) {
46934                        // Clean up memory after point deletion (#1044, #4320)
46935                        if (stack.touched < axis.stacksTouched) {
46936                            stack.destroy();
46937                            delete type[key];
46938
46939                            // Reset stacks
46940                        } else {
46941                            stack.total = null;
46942                            stack.cum = null;
46943                        }
46944                    });
46945                });
46946            }
46947        };
46948
46949        Axis.prototype.cleanStacks = function() {
46950            var stacks;
46951
46952            if (!this.isXAxis) {
46953                if (this.oldStacks) {
46954                    stacks = this.stacks = this.oldStacks;
46955                }
46956
46957                // reset stacks
46958                objectEach(stacks, function(type) {
46959                    objectEach(type, function(stack) {
46960                        stack.cum = stack.total;
46961                    });
46962                });
46963            }
46964        };
46965
46966
46967        // Stacking methods defnied for Series prototype
46968
46969        /**
46970         * Adds series' points value to corresponding stack
46971         */
46972        Series.prototype.setStackedPoints = function() {
46973            if (!this.options.stacking || (this.visible !== true &&
46974                    this.chart.options.chart.ignoreHiddenSeries !== false)) {
46975                return;
46976            }
46977
46978            var series = this,
46979                xData = series.processedXData,
46980                yData = series.processedYData,
46981                stackedYData = [],
46982                yDataLength = yData.length,
46983                seriesOptions = series.options,
46984                threshold = seriesOptions.threshold,
46985                stackThreshold = seriesOptions.startFromThreshold ? threshold : 0,
46986                stackOption = seriesOptions.stack,
46987                stacking = seriesOptions.stacking,
46988                stackKey = series.stackKey,
46989                negKey = '-' + stackKey,
46990                negStacks = series.negStacks,
46991                yAxis = series.yAxis,
46992                stacks = yAxis.stacks,
46993                oldStacks = yAxis.oldStacks,
46994                stackIndicator,
46995                isNegative,
46996                stack,
46997                other,
46998                key,
46999                pointKey,
47000                i,
47001                x,
47002                y;
47003
47004
47005            yAxis.stacksTouched += 1;
47006
47007            // loop over the non-null y values and read them into a local array
47008            for (i = 0; i < yDataLength; i++) {
47009                x = xData[i];
47010                y = yData[i];
47011                stackIndicator = series.getStackIndicator(
47012                    stackIndicator,
47013                    x,
47014                    series.index
47015                );
47016                pointKey = stackIndicator.key;
47017                // Read stacked values into a stack based on the x value,
47018                // the sign of y and the stack key. Stacking is also handled for null
47019                // values (#739)
47020                isNegative = negStacks && y < (stackThreshold ? 0 : threshold);
47021                key = isNegative ? negKey : stackKey;
47022
47023                // Create empty object for this stack if it doesn't exist yet
47024                if (!stacks[key]) {
47025                    stacks[key] = {};
47026                }
47027
47028                // Initialize StackItem for this x
47029                if (!stacks[key][x]) {
47030                    if (oldStacks[key] && oldStacks[key][x]) {
47031                        stacks[key][x] = oldStacks[key][x];
47032                        stacks[key][x].total = null;
47033                    } else {
47034                        stacks[key][x] = new H.StackItem(
47035                            yAxis,
47036                            yAxis.options.stackLabels,
47037                            isNegative,
47038                            x,
47039                            stackOption
47040                        );
47041                    }
47042                }
47043
47044                // If the StackItem doesn't exist, create it first
47045                stack = stacks[key][x];
47046                if (y !== null) {
47047                    stack.points[pointKey] = stack.points[series.index] = [pick(stack.cum, stackThreshold)];
47048
47049                    // Record the base of the stack
47050                    if (!defined(stack.cum)) {
47051                        stack.base = pointKey;
47052                    }
47053                    stack.touched = yAxis.stacksTouched;
47054
47055
47056                    // In area charts, if there are multiple points on the same X value,
47057                    // let the area fill the full span of those points
47058                    if (stackIndicator.index > 0 && series.singleStacks === false) {
47059                        stack.points[pointKey][0] =
47060                            stack.points[series.index + ',' + x + ',0'][0];
47061                    }
47062                }
47063
47064                // Add value to the stack total
47065                if (stacking === 'percent') {
47066
47067                    // Percent stacked column, totals are the same for the positive and
47068                    // negative stacks
47069                    other = isNegative ? stackKey : negKey;
47070                    if (negStacks && stacks[other] && stacks[other][x]) {
47071                        other = stacks[other][x];
47072                        stack.total = other.total =
47073                            Math.max(other.total, stack.total) + Math.abs(y) || 0;
47074
47075                        // Percent stacked areas
47076                    } else {
47077                        stack.total = correctFloat(stack.total + (Math.abs(y) || 0));
47078                    }
47079                } else {
47080                    stack.total = correctFloat(stack.total + (y || 0));
47081                }
47082
47083                stack.cum = pick(stack.cum, stackThreshold) + (y || 0);
47084
47085                if (y !== null) {
47086                    stack.points[pointKey].push(stack.cum);
47087                    stackedYData[i] = stack.cum;
47088                }
47089
47090            }
47091
47092            if (stacking === 'percent') {
47093                yAxis.usePercentage = true;
47094            }
47095
47096            this.stackedYData = stackedYData; // To be used in getExtremes
47097
47098            // Reset old stacks
47099            yAxis.oldStacks = {};
47100        };
47101
47102        /**
47103         * Iterate over all stacks and compute the absolute values to percent
47104         */
47105        Series.prototype.modifyStacks = function() {
47106            var series = this,
47107                stackKey = series.stackKey,
47108                stacks = series.yAxis.stacks,
47109                processedXData = series.processedXData,
47110                stackIndicator,
47111                stacking = series.options.stacking;
47112
47113            if (series[stacking + 'Stacker']) { // Modifier function exists
47114                each([stackKey, '-' + stackKey], function(key) {
47115                    var i = processedXData.length,
47116                        x,
47117                        stack,
47118                        pointExtremes;
47119
47120                    while (i--) {
47121                        x = processedXData[i];
47122                        stackIndicator = series.getStackIndicator(
47123                            stackIndicator,
47124                            x,
47125                            series.index,
47126                            key
47127                        );
47128                        stack = stacks[key] && stacks[key][x];
47129                        pointExtremes = stack && stack.points[stackIndicator.key];
47130                        if (pointExtremes) {
47131                            series[stacking + 'Stacker'](pointExtremes, stack, i);
47132                        }
47133                    }
47134                });
47135            }
47136        };
47137
47138        /**
47139         * Modifier function for percent stacks. Blows up the stack to 100%.
47140         */
47141        Series.prototype.percentStacker = function(pointExtremes, stack, i) {
47142            var totalFactor = stack.total ? 100 / stack.total : 0;
47143            // Y bottom value
47144            pointExtremes[0] = correctFloat(pointExtremes[0] * totalFactor);
47145            // Y value
47146            pointExtremes[1] = correctFloat(pointExtremes[1] * totalFactor);
47147            this.stackedYData[i] = pointExtremes[1];
47148        };
47149
47150        /**
47151         * Get stack indicator, according to it's x-value, to determine points with the
47152         * same x-value
47153         */
47154        Series.prototype.getStackIndicator = function(stackIndicator, x, index, key) {
47155            // Update stack indicator, when:
47156            // first point in a stack || x changed || stack type (negative vs positive)
47157            // changed:
47158            if (!defined(stackIndicator) || stackIndicator.x !== x ||
47159                (key && stackIndicator.key !== key)) {
47160                stackIndicator = {
47161                    x: x,
47162                    index: 0,
47163                    key: key
47164                };
47165            } else {
47166                stackIndicator.index++;
47167            }
47168
47169            stackIndicator.key = [index, x, stackIndicator.index].join(',');
47170
47171            return stackIndicator;
47172        };
47173
47174    }(Highcharts));
47175    (function(H) {
47176        /**
47177         * (c) 2010-2017 Torstein Honsi
47178         *
47179         * License: www.highcharts.com/license
47180         */
47181        var addEvent = H.addEvent,
47182            animate = H.animate,
47183            Axis = H.Axis,
47184            Chart = H.Chart,
47185            createElement = H.createElement,
47186            css = H.css,
47187            defined = H.defined,
47188            each = H.each,
47189            erase = H.erase,
47190            extend = H.extend,
47191            fireEvent = H.fireEvent,
47192            inArray = H.inArray,
47193            isNumber = H.isNumber,
47194            isObject = H.isObject,
47195            isArray = H.isArray,
47196            merge = H.merge,
47197            objectEach = H.objectEach,
47198            pick = H.pick,
47199            Point = H.Point,
47200            Series = H.Series,
47201            seriesTypes = H.seriesTypes,
47202            setAnimation = H.setAnimation,
47203            splat = H.splat;
47204
47205        // Extend the Chart prototype for dynamic methods
47206        extend(Chart.prototype, /** @lends Highcharts.Chart.prototype */ {
47207
47208            /**
47209             * Add a series to the chart after render time. Note that this method should
47210             * never be used when adding data synchronously at chart render time, as it
47211             * adds expense to the calculations and rendering. When adding data at the
47212             * same time as the chart is initialized, add the series as a configuration
47213             * option instead. With multiple axes, the `offset` is dynamically adjusted.
47214             *
47215             * @param  {SeriesOptions} options
47216             *         The config options for the series.
47217             * @param  {Boolean} [redraw=true]
47218             *         Whether to redraw the chart after adding.
47219             * @param  {AnimationOptions} animation
47220             *         Whether to apply animation, and optionally animation
47221             *         configuration.
47222             *
47223             * @return {Highcharts.Series}
47224             *         The newly created series object.
47225             *
47226             * @sample highcharts/members/chart-addseries/
47227             *         Add a series from a button
47228             * @sample stock/members/chart-addseries/
47229             *         Add a series in Highstock
47230             */
47231            addSeries: function(options, redraw, animation) {
47232                var series,
47233                    chart = this;
47234
47235                if (options) {
47236                    redraw = pick(redraw, true); // defaults to true
47237
47238                    fireEvent(chart, 'addSeries', {
47239                        options: options
47240                    }, function() {
47241                        series = chart.initSeries(options);
47242
47243                        chart.isDirtyLegend = true; // the series array is out of sync with the display
47244                        chart.linkSeries();
47245                        if (redraw) {
47246                            chart.redraw(animation);
47247                        }
47248                    });
47249                }
47250
47251                return series;
47252            },
47253
47254            /**
47255             * Add an axis to the chart after render time. Note that this method should
47256             * never be used when adding data synchronously at chart render time, as it
47257             * adds expense to the calculations and rendering. When adding data at the
47258             * same time as the chart is initialized, add the axis as a configuration
47259             * option instead.
47260             * @param  {AxisOptions} options
47261             *         The axis options.
47262             * @param  {Boolean} [isX=false]
47263             *         Whether it is an X axis or a value axis.
47264             * @param  {Boolean} [redraw=true]
47265             *         Whether to redraw the chart after adding.
47266             * @param  {AnimationOptions} [animation=true]
47267             *         Whether and how to apply animation in the redraw.
47268             *
47269             * @sample highcharts/members/chart-addaxis/ Add and remove axes
47270             *
47271             * @return {Axis}
47272             *         The newly generated Axis object.
47273             */
47274            addAxis: function(options, isX, redraw, animation) {
47275                var key = isX ? 'xAxis' : 'yAxis',
47276                    chartOptions = this.options,
47277                    userOptions = merge(options, {
47278                        index: this[key].length,
47279                        isX: isX
47280                    }),
47281                    axis;
47282
47283                axis = new Axis(this, userOptions);
47284
47285                // Push the new axis options to the chart options
47286                chartOptions[key] = splat(chartOptions[key] || {});
47287                chartOptions[key].push(userOptions);
47288
47289                if (pick(redraw, true)) {
47290                    this.redraw(animation);
47291                }
47292
47293                return axis;
47294            },
47295
47296            /**
47297             * Dim the chart and show a loading text or symbol. Options for the loading
47298             * screen are defined in {@link
47299             * https://api.highcharts.com/highcharts/loading|the loading options}.
47300             * 
47301             * @param  {String} str
47302             *         An optional text to show in the loading label instead of the
47303             *         default one. The default text is set in {@link
47304             *         http://api.highcharts.com/highcharts/lang.loading|lang.loading}.
47305             *
47306             * @sample highcharts/members/chart-hideloading/
47307             *         Show and hide loading from a button
47308             * @sample highcharts/members/chart-showloading/
47309             *         Apply different text labels
47310             * @sample stock/members/chart-show-hide-loading/
47311             *         Toggle loading in Highstock
47312             */
47313            showLoading: function(str) {
47314                var chart = this,
47315                    options = chart.options,
47316                    loadingDiv = chart.loadingDiv,
47317                    loadingOptions = options.loading,
47318                    setLoadingSize = function() {
47319                        if (loadingDiv) {
47320                            css(loadingDiv, {
47321                                left: chart.plotLeft + 'px',
47322                                top: chart.plotTop + 'px',
47323                                width: chart.plotWidth + 'px',
47324                                height: chart.plotHeight + 'px'
47325                            });
47326                        }
47327                    };
47328
47329                // create the layer at the first call
47330                if (!loadingDiv) {
47331                    chart.loadingDiv = loadingDiv = createElement('div', {
47332                        className: 'highcharts-loading highcharts-loading-hidden'
47333                    }, null, chart.container);
47334
47335                    chart.loadingSpan = createElement(
47336                        'span', {
47337                            className: 'highcharts-loading-inner'
47338                        },
47339                        null,
47340                        loadingDiv
47341                    );
47342                    addEvent(chart, 'redraw', setLoadingSize); // #1080
47343                }
47344
47345                loadingDiv.className = 'highcharts-loading';
47346
47347                // Update text
47348                chart.loadingSpan.innerHTML = str || options.lang.loading;
47349
47350
47351                // Update visuals
47352                css(loadingDiv, extend(loadingOptions.style, {
47353                    zIndex: 10
47354                }));
47355                css(chart.loadingSpan, loadingOptions.labelStyle);
47356
47357                // Show it
47358                if (!chart.loadingShown) {
47359                    css(loadingDiv, {
47360                        opacity: 0,
47361                        display: ''
47362                    });
47363                    animate(loadingDiv, {
47364                        opacity: loadingOptions.style.opacity || 0.5
47365                    }, {
47366                        duration: loadingOptions.showDuration || 0
47367                    });
47368                }
47369
47370
47371                chart.loadingShown = true;
47372                setLoadingSize();
47373            },
47374
47375            /**
47376             * Hide the loading layer.
47377             *
47378             * @see    Highcharts.Chart#showLoading
47379             * @sample highcharts/members/chart-hideloading/
47380             *         Show and hide loading from a button
47381             * @sample stock/members/chart-show-hide-loading/
47382             *         Toggle loading in Highstock
47383             */
47384            hideLoading: function() {
47385                var options = this.options,
47386                    loadingDiv = this.loadingDiv;
47387
47388                if (loadingDiv) {
47389                    loadingDiv.className = 'highcharts-loading highcharts-loading-hidden';
47390
47391                    animate(loadingDiv, {
47392                        opacity: 0
47393                    }, {
47394                        duration: options.loading.hideDuration || 100,
47395                        complete: function() {
47396                            css(loadingDiv, {
47397                                display: 'none'
47398                            });
47399                        }
47400                    });
47401
47402                }
47403                this.loadingShown = false;
47404            },
47405
47406            /** 
47407             * These properties cause isDirtyBox to be set to true when updating. Can be extended from plugins.
47408             */
47409            propsRequireDirtyBox: ['backgroundColor', 'borderColor', 'borderWidth', 'margin', 'marginTop', 'marginRight',
47410                'marginBottom', 'marginLeft', 'spacing', 'spacingTop', 'spacingRight', 'spacingBottom', 'spacingLeft',
47411                'borderRadius', 'plotBackgroundColor', 'plotBackgroundImage', 'plotBorderColor', 'plotBorderWidth',
47412                'plotShadow', 'shadow'
47413            ],
47414
47415            /** 
47416             * These properties cause all series to be updated when updating. Can be
47417             * extended from plugins.
47418             */
47419            propsRequireUpdateSeries: ['chart.inverted', 'chart.polar',
47420                'chart.ignoreHiddenSeries', 'chart.type', 'colors', 'plotOptions',
47421                'tooltip'
47422            ],
47423
47424            /**
47425             * A generic function to update any element of the chart. Elements can be
47426             * enabled and disabled, moved, re-styled, re-formatted etc.
47427             *
47428             * A special case is configuration objects that take arrays, for example
47429             * {@link https://api.highcharts.com/highcharts/xAxis|xAxis}, 
47430             * {@link https://api.highcharts.com/highcharts/yAxis|yAxis} or 
47431             * {@link https://api.highcharts.com/highcharts/series|series}. For these
47432             * collections, an `id` option is used to map the new option set to an
47433             * existing object. If an existing object of the same id is not found, the
47434             * corresponding item is updated. So for example, running `chart.update`
47435             * with a series item without an id, will cause the existing chart's series
47436             * with the same index in the series array to be updated. When the
47437             * `oneToOne` parameter is true, `chart.update` will also take care of
47438             * adding and removing items from the collection. Read more under the
47439             * parameter description below.
47440             *
47441             * See also the {@link https://api.highcharts.com/highcharts/responsive|
47442             * responsive option set}. Switching between `responsive.rules` basically
47443             * runs `chart.update` under the hood.
47444             *
47445             * @param  {Options} options
47446             *         A configuration object for the new chart options.
47447             * @param  {Boolean} [redraw=true]
47448             *         Whether to redraw the chart.
47449             * @param  {Boolean} [oneToOne=false]
47450             *         When `true`, the `series`, `xAxis` and `yAxis` collections will
47451             *         be updated one to one, and items will be either added or removed
47452             *         to match the new updated options. For example, if the chart has
47453             *         two series and we call `chart.update` with a configuration 
47454             *         containing three series, one will be added. If we call
47455             *         `chart.update` with one series, one will be removed. Setting an
47456             *         empty `series` array will remove all series, but leaving out the
47457             *         `series` property will leave all series untouched. If the series
47458             *         have id's, the new series options will be matched by id, and the
47459             *         remaining ones removed.
47460             *
47461             * @sample highcharts/members/chart-update/
47462             *         Update chart geometry 
47463             */
47464            update: function(options, redraw, oneToOne) {
47465                var chart = this,
47466                    adders = {
47467                        credits: 'addCredits',
47468                        title: 'setTitle',
47469                        subtitle: 'setSubtitle'
47470                    },
47471                    optionsChart = options.chart,
47472                    updateAllAxes,
47473                    updateAllSeries,
47474                    newWidth,
47475                    newHeight,
47476                    itemsForRemoval = [];
47477
47478                // If the top-level chart option is present, some special updates are required		
47479                if (optionsChart) {
47480                    merge(true, chart.options.chart, optionsChart);
47481
47482                    // Setter function
47483                    if ('className' in optionsChart) {
47484                        chart.setClassName(optionsChart.className);
47485                    }
47486
47487                    if ('inverted' in optionsChart || 'polar' in optionsChart) {
47488                        // Parse options.chart.inverted and options.chart.polar together
47489                        // with the available series.
47490                        chart.propFromSeries();
47491                        updateAllAxes = true;
47492                    }
47493
47494                    if ('alignTicks' in optionsChart) { // #6452
47495                        updateAllAxes = true;
47496                    }
47497
47498                    objectEach(optionsChart, function(val, key) {
47499                        if (inArray('chart.' + key, chart.propsRequireUpdateSeries) !== -1) {
47500                            updateAllSeries = true;
47501                        }
47502                        // Only dirty box
47503                        if (inArray(key, chart.propsRequireDirtyBox) !== -1) {
47504                            chart.isDirtyBox = true;
47505                        }
47506                    });
47507
47508
47509                    if ('style' in optionsChart) {
47510                        chart.renderer.setStyle(optionsChart.style);
47511                    }
47512
47513                }
47514
47515                // Moved up, because tooltip needs updated plotOptions (#6218)
47516
47517                if (options.colors) {
47518                    this.options.colors = options.colors;
47519                }
47520
47521
47522                if (options.plotOptions) {
47523                    merge(true, this.options.plotOptions, options.plotOptions);
47524                }
47525
47526                // Some option stuctures correspond one-to-one to chart objects that
47527                // have update methods, for example
47528                // options.credits => chart.credits
47529                // options.legend => chart.legend
47530                // options.title => chart.title
47531                // options.tooltip => chart.tooltip
47532                // options.subtitle => chart.subtitle
47533                // options.mapNavigation => chart.mapNavigation
47534                // options.navigator => chart.navigator
47535                // options.scrollbar => chart.scrollbar
47536                objectEach(options, function(val, key) {
47537                    if (chart[key] && typeof chart[key].update === 'function') {
47538                        chart[key].update(val, false);
47539
47540                        // If a one-to-one object does not exist, look for an adder function
47541                    } else if (typeof chart[adders[key]] === 'function') {
47542                        chart[adders[key]](val);
47543                    }
47544
47545                    if (
47546                        key !== 'chart' &&
47547                        inArray(key, chart.propsRequireUpdateSeries) !== -1
47548                    ) {
47549                        updateAllSeries = true;
47550                    }
47551                });
47552
47553                // Setters for collections. For axes and series, each item is referred
47554                // by an id. If the id is not found, it defaults to the corresponding
47555                // item in the collection, so setting one series without an id, will
47556                // update the first series in the chart. Setting two series without
47557                // an id will update the first and the second respectively (#6019)
47558                // chart.update and responsive.
47559                each([
47560                    'xAxis',
47561                    'yAxis',
47562                    'zAxis',
47563                    'series',
47564                    'colorAxis',
47565                    'pane'
47566                ], function(coll) {
47567                    if (options[coll]) {
47568                        each(splat(options[coll]), function(newOptions, i) {
47569                            var item = (
47570                                defined(newOptions.id) &&
47571                                chart.get(newOptions.id)
47572                            ) || chart[coll][i];
47573                            if (item && item.coll === coll) {
47574                                item.update(newOptions, false);
47575
47576                                if (oneToOne) {
47577                                    item.touched = true;
47578                                }
47579                            }
47580
47581                            // If oneToOne and no matching item is found, add one
47582                            if (!item && oneToOne) {
47583                                if (coll === 'series') {
47584                                    chart.addSeries(newOptions, false)
47585                                        .touched = true;
47586                                } else if (coll === 'xAxis' || coll === 'yAxis') {
47587                                    chart.addAxis(newOptions, coll === 'xAxis', false)
47588                                        .touched = true;
47589                                }
47590                            }
47591
47592                        });
47593
47594                        // Add items for removal
47595                        if (oneToOne) {
47596                            each(chart[coll], function(item) {
47597                                if (!item.touched) {
47598                                    itemsForRemoval.push(item);
47599                                } else {
47600                                    delete item.touched;
47601                                }
47602                            });
47603                        }
47604
47605
47606                    }
47607                });
47608
47609                each(itemsForRemoval, function(item) {
47610                    item.remove(false);
47611                });
47612
47613                if (updateAllAxes) {
47614                    each(chart.axes, function(axis) {
47615                        axis.update({}, false);
47616                    });
47617                }
47618
47619                // Certain options require the whole series structure to be thrown away
47620                // and rebuilt
47621                if (updateAllSeries) {
47622                    each(chart.series, function(series) {
47623                        series.update({}, false);
47624                    });
47625                }
47626
47627                // For loading, just update the options, do not redraw
47628                if (options.loading) {
47629                    merge(true, chart.options.loading, options.loading);
47630                }
47631
47632                // Update size. Redraw is forced.
47633                newWidth = optionsChart && optionsChart.width;
47634                newHeight = optionsChart && optionsChart.height;
47635                if ((isNumber(newWidth) && newWidth !== chart.chartWidth) ||
47636                    (isNumber(newHeight) && newHeight !== chart.chartHeight)) {
47637                    chart.setSize(newWidth, newHeight);
47638                } else if (pick(redraw, true)) {
47639                    chart.redraw();
47640                }
47641            },
47642
47643            /**
47644             * Shortcut to set the subtitle options. This can also be done from {@link
47645             * Chart#update} or {@link Chart#setTitle}.
47646             *
47647             * @param  {SubtitleOptions} options
47648             *         New subtitle options. The subtitle text itself is set by the
47649             *         `options.text` property.
47650             */
47651            setSubtitle: function(options) {
47652                this.setTitle(undefined, options);
47653            }
47654
47655
47656        });
47657
47658        // extend the Point prototype for dynamic methods
47659        extend(Point.prototype, /** @lends Highcharts.Point.prototype */ {
47660            /**
47661             * Update point with new options (typically x/y data) and optionally redraw
47662             * the series.
47663             *
47664             * @param  {Object} options
47665             *         The point options. Point options are handled as described under
47666             *         the `series.type.data` item for each series type. For example
47667             *         for a line series, if options is a single number, the point will
47668             *         be given that number as the main y value. If it is an array, it
47669             *         will be interpreted as x and y values respectively. If it is an
47670             *         object, advanced options are applied. 
47671             * @param  {Boolean} [redraw=true]
47672             *          Whether to redraw the chart after the point is updated. If doing
47673             *          more operations on the chart, it is best practice to set
47674             *          `redraw` to false and call `chart.redraw()` after.
47675             * @param  {AnimationOptions} [animation=true]
47676             *         Whether to apply animation, and optionally animation
47677             *         configuration.
47678             *
47679             * @sample highcharts/members/point-update-column/
47680             *         Update column value
47681             * @sample highcharts/members/point-update-pie/
47682             *         Update pie slice
47683             * @sample maps/members/point-update/
47684             *         Update map area value in Highmaps
47685             */
47686            update: function(options, redraw, animation, runEvent) {
47687                var point = this,
47688                    series = point.series,
47689                    graphic = point.graphic,
47690                    i,
47691                    chart = series.chart,
47692                    seriesOptions = series.options;
47693
47694                redraw = pick(redraw, true);
47695
47696                function update() {
47697
47698                    point.applyOptions(options);
47699
47700                    // Update visuals
47701                    if (point.y === null && graphic) { // #4146
47702                        point.graphic = graphic.destroy();
47703                    }
47704                    if (isObject(options, true)) {
47705                        // Destroy so we can get new elements
47706                        if (graphic && graphic.element) {
47707                            // "null" is also a valid symbol
47708                            if (options && options.marker && options.marker.symbol !== undefined) {
47709                                point.graphic = graphic.destroy();
47710                            }
47711                        }
47712                        if (options && options.dataLabels && point.dataLabel) { // #2468
47713                            point.dataLabel = point.dataLabel.destroy();
47714                        }
47715                        if (point.connector) {
47716                            point.connector = point.connector.destroy(); // #7243
47717                        }
47718                    }
47719
47720                    // record changes in the parallel arrays
47721                    i = point.index;
47722                    series.updateParallelArrays(point, i);
47723
47724                    // Record the options to options.data. If the old or the new config
47725                    // is an object, use point options, otherwise use raw options
47726                    // (#4701, #4916).
47727                    seriesOptions.data[i] = (
47728                            isObject(seriesOptions.data[i], true) ||
47729                            isObject(options, true)
47730                        ) ?
47731                        point.options :
47732                        options;
47733
47734                    // redraw
47735                    series.isDirty = series.isDirtyData = true;
47736                    if (!series.fixedBox && series.hasCartesianSeries) { // #1906, #2320
47737                        chart.isDirtyBox = true;
47738                    }
47739
47740                    if (seriesOptions.legendType === 'point') { // #1831, #1885
47741                        chart.isDirtyLegend = true;
47742                    }
47743                    if (redraw) {
47744                        chart.redraw(animation);
47745                    }
47746                }
47747
47748                // Fire the event with a default handler of doing the update
47749                if (runEvent === false) { // When called from setData
47750                    update();
47751                } else {
47752                    point.firePointEvent('update', {
47753                        options: options
47754                    }, update);
47755                }
47756            },
47757
47758            /**
47759             * Remove a point and optionally redraw the series and if necessary the axes
47760             * @param  {Boolean} redraw
47761             *         Whether to redraw the chart or wait for an explicit call. When
47762             *         doing more operations on the chart, for example running
47763             *         `point.remove()` in a loop, it is best practice to set `redraw`
47764             *         to false and call `chart.redraw()` after.         
47765             * @param  {AnimationOptions} [animation=false]
47766             *         Whether to apply animation, and optionally animation
47767             *         configuration.
47768             *
47769             * @sample highcharts/plotoptions/series-point-events-remove/
47770             *         Remove point and confirm
47771             * @sample highcharts/members/point-remove/
47772             *         Remove pie slice
47773             * @sample maps/members/point-remove/
47774             *         Remove selected points in Highmaps
47775             */
47776            remove: function(redraw, animation) {
47777                this.series.removePoint(inArray(this, this.series.data), redraw, animation);
47778            }
47779        });
47780
47781        // Extend the series prototype for dynamic methods
47782        extend(Series.prototype, /** @lends Series.prototype */ {
47783            /**
47784             * Add a point to the series after render time. The point can be added at
47785             * the end, or by giving it an X value, to the start or in the middle of the
47786             * series.
47787             * 
47788             * @param  {Number|Array|Object} options
47789             *         The point options. If options is a single number, a point with
47790             *         that y value is appended to the series.If it is an array, it will
47791             *         be interpreted as x and y values respectively. If it is an
47792             *         object, advanced options as outlined under `series.data` are
47793             *         applied.
47794             * @param  {Boolean} [redraw=true]
47795             *         Whether to redraw the chart after the point is added. When adding
47796             *         more than one point, it is highly recommended that the redraw
47797             *         option be set to false, and instead {@link Chart#redraw}
47798             *         is explicitly called after the adding of points is finished.
47799             *         Otherwise, the chart will redraw after adding each point.
47800             * @param  {Boolean} [shift=false]
47801             *         If true, a point is shifted off the start of the series as one is
47802             *         appended to the end.
47803             * @param  {AnimationOptions} [animation]
47804             *         Whether to apply animation, and optionally animation
47805             *         configuration.
47806             *
47807             * @sample highcharts/members/series-addpoint-append/
47808             *         Append point
47809             * @sample highcharts/members/series-addpoint-append-and-shift/
47810             *         Append and shift
47811             * @sample highcharts/members/series-addpoint-x-and-y/
47812             *         Both X and Y values given
47813             * @sample highcharts/members/series-addpoint-pie/
47814             *         Append pie slice
47815             * @sample stock/members/series-addpoint/
47816             *         Append 100 points in Highstock
47817             * @sample stock/members/series-addpoint-shift/
47818             *         Append and shift in Highstock
47819             * @sample maps/members/series-addpoint/
47820             *         Add a point in Highmaps
47821             */
47822            addPoint: function(options, redraw, shift, animation) {
47823                var series = this,
47824                    seriesOptions = series.options,
47825                    data = series.data,
47826                    chart = series.chart,
47827                    xAxis = series.xAxis,
47828                    names = xAxis && xAxis.hasNames && xAxis.names,
47829                    dataOptions = seriesOptions.data,
47830                    point,
47831                    isInTheMiddle,
47832                    xData = series.xData,
47833                    i,
47834                    x;
47835
47836                // Optional redraw, defaults to true
47837                redraw = pick(redraw, true);
47838
47839                // Get options and push the point to xData, yData and series.options. In series.generatePoints
47840                // the Point instance will be created on demand and pushed to the series.data array.
47841                point = {
47842                    series: series
47843                };
47844                series.pointClass.prototype.applyOptions.apply(point, [options]);
47845                x = point.x;
47846
47847                // Get the insertion point
47848                i = xData.length;
47849                if (series.requireSorting && x < xData[i - 1]) {
47850                    isInTheMiddle = true;
47851                    while (i && xData[i - 1] > x) {
47852                        i--;
47853                    }
47854                }
47855
47856                series.updateParallelArrays(point, 'splice', i, 0, 0); // insert undefined item
47857                series.updateParallelArrays(point, i); // update it
47858
47859                if (names && point.name) {
47860                    names[x] = point.name;
47861                }
47862                dataOptions.splice(i, 0, options);
47863
47864                if (isInTheMiddle) {
47865                    series.data.splice(i, 0, null);
47866                    series.processData();
47867                }
47868
47869                // Generate points to be added to the legend (#1329)
47870                if (seriesOptions.legendType === 'point') {
47871                    series.generatePoints();
47872                }
47873
47874                // Shift the first point off the parallel arrays
47875                if (shift) {
47876                    if (data[0] && data[0].remove) {
47877                        data[0].remove(false);
47878                    } else {
47879                        data.shift();
47880                        series.updateParallelArrays(point, 'shift');
47881
47882                        dataOptions.shift();
47883                    }
47884                }
47885
47886                // redraw
47887                series.isDirty = true;
47888                series.isDirtyData = true;
47889
47890                if (redraw) {
47891                    chart.redraw(animation); // Animation is set anyway on redraw, #5665
47892                }
47893            },
47894
47895            /**
47896             * Remove a point from the series. Unlike the {@link Highcharts.Point#remove}
47897             * method, this can also be done on a point that is not instanciated because
47898             * it is outside the view or subject to Highstock data grouping.
47899             *
47900             * @param  {Number} i
47901             *         The index of the point in the {@link Highcharts.Series.data|data}
47902             *         array.
47903             * @param  {Boolean} [redraw=true]
47904             *         Whether to redraw the chart after the point is added. When 
47905             *         removing more than one point, it is highly recommended that the
47906             *         `redraw` option be set to `false`, and instead {@link
47907             *         Highcharts.Chart#redraw} is explicitly called after the adding of
47908             *         points is finished.
47909             * @param  {AnimationOptions} [animation]
47910             *         Whether and optionally how the series should be animated.
47911             *
47912             * @sample highcharts/members/series-removepoint/
47913             *         Remove cropped point
47914             */
47915            removePoint: function(i, redraw, animation) {
47916
47917                var series = this,
47918                    data = series.data,
47919                    point = data[i],
47920                    points = series.points,
47921                    chart = series.chart,
47922                    remove = function() {
47923
47924                        if (points && points.length === data.length) { // #4935
47925                            points.splice(i, 1);
47926                        }
47927                        data.splice(i, 1);
47928                        series.options.data.splice(i, 1);
47929                        series.updateParallelArrays(point || {
47930                            series: series
47931                        }, 'splice', i, 1);
47932
47933                        if (point) {
47934                            point.destroy();
47935                        }
47936
47937                        // redraw
47938                        series.isDirty = true;
47939                        series.isDirtyData = true;
47940                        if (redraw) {
47941                            chart.redraw();
47942                        }
47943                    };
47944
47945                setAnimation(animation, chart);
47946                redraw = pick(redraw, true);
47947
47948                // Fire the event with a default handler of removing the point
47949                if (point) {
47950                    point.firePointEvent('remove', null, remove);
47951                } else {
47952                    remove();
47953                }
47954            },
47955
47956            /**
47957             * Remove a series and optionally redraw the chart.
47958             *
47959             * @param  {Boolean} [redraw=true]
47960             *         Whether to redraw the chart or wait for an explicit call to
47961             *         {@link Highcharts.Chart#redraw}.
47962             * @param  {AnimationOptions} [animation]
47963             *         Whether to apply animation, and optionally animation
47964             *         configuration
47965             * @param  {Boolean} [withEvent=true]
47966             *         Used internally, whether to fire the series `remove` event.
47967             *
47968             * @sample highcharts/members/series-remove/
47969             *         Remove first series from a button
47970             */
47971            remove: function(redraw, animation, withEvent) {
47972                var series = this,
47973                    chart = series.chart;
47974
47975                function remove() {
47976
47977                    // Destroy elements
47978                    series.destroy();
47979
47980                    // Redraw
47981                    chart.isDirtyLegend = chart.isDirtyBox = true;
47982                    chart.linkSeries();
47983
47984                    if (pick(redraw, true)) {
47985                        chart.redraw(animation);
47986                    }
47987                }
47988
47989                // Fire the event with a default handler of removing the point
47990                if (withEvent !== false) {
47991                    fireEvent(series, 'remove', null, remove);
47992                } else {
47993                    remove();
47994                }
47995            },
47996
47997            /**
47998             * Update the series with a new set of options. For a clean and precise
47999             * handling of new options, all methods and elements from the series are
48000             * removed, and it is initiated from scratch. Therefore, this method is more
48001             * performance expensive than some other utility methods like {@link
48002             * Series#setData} or {@link Series#setVisible}.
48003             *
48004             * @param  {SeriesOptions} options
48005             *         New options that will be merged with the series' existing
48006             *         options.
48007             * @param  {Boolean} [redraw=true]
48008             *         Whether to redraw the chart after the series is altered. If doing
48009             *         more operations on the chart, it is a good idea to set redraw to
48010             *         false and call {@link Chart#redraw} after.
48011             *
48012             * @sample highcharts/members/series-update/
48013             *         Updating series options
48014             * @sample maps/members/series-update/
48015             *         Update series options in Highmaps
48016             */
48017            update: function(newOptions, redraw) {
48018                var series = this,
48019                    chart = series.chart,
48020                    // must use user options when changing type because series.options
48021                    // is merged in with type specific plotOptions
48022                    oldOptions = series.userOptions,
48023                    oldType = series.oldType || series.type,
48024                    newType = newOptions.type || oldOptions.type || chart.options.chart.type,
48025                    proto = seriesTypes[oldType].prototype,
48026                    n,
48027                    preserveGroups = [
48028                        'group',
48029                        'markerGroup',
48030                        'dataLabelsGroup'
48031                    ],
48032                    preserve = [
48033                        'navigatorSeries',
48034                        'baseSeries'
48035                    ],
48036
48037                    // Animation must be enabled when calling update before the initial
48038                    // animation has first run. This happens when calling update
48039                    // directly after chart initialization, or when applying responsive
48040                    // rules (#6912).
48041                    animation = series.finishedAnimating && {
48042                        animation: false
48043                    };
48044
48045                // Running Series.update to update the data only is an intuitive usage,
48046                // so we want to make sure that when used like this, we run the
48047                // cheaper setData function and allow animation instead of completely
48048                // recreating the series instance.
48049                if (Object.keys && Object.keys(newOptions).toString() === 'data') {
48050                    return this.setData(newOptions.data, redraw);
48051                }
48052
48053                // If we're changing type or zIndex, create new groups (#3380, #3404)
48054                // Also create new groups for navigator series.
48055                if (
48056                    (newType && newType !== oldType) ||
48057                    newOptions.zIndex !== undefined
48058                ) {
48059                    preserveGroups.length = 0;
48060                }
48061
48062                // Make sure preserved properties are not destroyed (#3094)
48063                preserve = preserveGroups.concat(preserve);
48064                each(preserve, function(prop) {
48065                    preserve[prop] = series[prop];
48066                    delete series[prop];
48067                });
48068
48069                // Do the merge, with some forced options
48070                newOptions = merge(oldOptions, animation, {
48071                    index: series.index,
48072                    pointStart: series.xData[0] // when updating after addPoint
48073                }, {
48074                    data: series.options.data
48075                }, newOptions);
48076
48077                // Destroy the series and delete all properties. Re
48077insert all methods
48078                // and properties from the new type prototype (#2270, #3719)
48079                series.remove(false, null, false);
48080                for (n in proto) {
48081                    series[n] = undefined;
48082                }
48083                extend(series, seriesTypes[newType || oldType].prototype);
48084
48085                // Re-register groups (#3094) and other preserved properties
48086                each(preserve, function(prop) {
48087                    series[prop] = preserve[prop];
48088                });
48089
48090                series.init(chart, newOptions);
48091                series.oldType = oldType;
48092                chart.linkSeries(); // Links are lost in series.remove (#3028)
48093                if (pick(redraw, true)) {
48094                    chart.redraw(false);
48095                }
48096            }
48097        });
48098
48099        // Extend the Axis.prototype for dynamic methods
48100        extend(Axis.prototype, /** @lends Highcharts.Axis.prototype */ {
48101
48102            /**
48103             * Update an axis object with a new set of options. The options are merged
48104             * with the existing options, so only new or altered options need to be
48105             * specified.
48106             *
48107             * @param  {Object} options
48108             *         The new options that will be merged in with existing options on
48109             *         the axis.
48110             * @sample highcharts/members/axis-update/ Axis update demo
48111             */
48112            update: function(options, redraw) {
48113                var chart = this.chart;
48114
48115                options = chart.options[this.coll][this.options.index] =
48116                    merge(this.userOptions, options);
48117
48118                this.destroy(true);
48119
48120                this.init(chart, extend(options, {
48121                    events: undefined
48122                }));
48123
48124                chart.isDirtyBox = true;
48125                if (pick(redraw, true)) {
48126                    chart.redraw();
48127                }
48128            },
48129
48130            /**
48131             * Remove the axis from the chart.
48132             *
48133             * @param {Boolean} [redraw=true] Whether to redraw the chart following the
48134             * remove.
48135             *
48136             * @sample highcharts/members/chart-addaxis/ Add and remove axes
48137             */
48138            remove: function(redraw) {
48139                var chart = this.chart,
48140                    key = this.coll, // xAxis or yAxis
48141                    axisSeries = this.series,
48142                    i = axisSeries.length;
48143
48144                // Remove associated series (#2687)
48145                while (i--) {
48146                    if (axisSeries[i]) {
48147                        axisSeries[i].remove(false);
48148                    }
48149                }
48150
48151                // Remove the axis
48152                erase(chart.axes, this);
48153                erase(chart[key], this);
48154
48155                if (isArray(chart.options[key])) {
48156                    chart.options[key].splice(this.options.index, 1);
48157                } else { // color axis, #6488
48158                    delete chart.options[key];
48159                }
48160
48161                each(chart[key], function(axis, i) { // Re-index, #1706
48162                    axis.options.index = i;
48163                });
48164                this.destroy();
48165                chart.isDirtyBox = true;
48166
48167                if (pick(redraw, true)) {
48168                    chart.redraw();
48169                }
48170            },
48171
48172            /**
48173             * Update the axis title by options after render time.
48174             *
48175             * @param  {TitleOptions} titleOptions
48176             *         The additional title options.
48177             * @param  {Boolean} [redraw=true]
48178             *         Whether to redraw the chart after setting the title.
48179             * @sample highcharts/members/axis-settitle/ Set a new Y axis title
48180             */
48181            setTitle: function(titleOptions, redraw) {
48182                this.update({
48183                    title: titleOptions
48184                }, redraw);
48185            },
48186
48187            /**
48188             * Set new axis categories and optionally redraw.
48189             * @param {Array.<String>} categories - The new categories.
48190             * @param {Boolean} [redraw=true] - Whether to redraw the chart.
48191             * @sample highcharts/members/axis-setcategories/ Set categories by click on
48192             * a button
48193             */
48194            setCategories: function(categories, redraw) {
48195                this.update({
48196                    categories: categories
48197                }, redraw);
48198            }
48199
48200        });
48201
48202    }
48202(Highcharts));
48203    (function(H) {
48204        /**
48205         * (c) 2010-2017 Torstein Honsi
48206         *
48207         * License: www.highcharts.com/license
48208         */
48209        var color = H.color,
48210            each = H.each,
48211            LegendSymbolMixin = H.LegendSymbolMixin,
48212            map = H.map,
48213            pick = H.pick,
48214            Series = H.Series,
48215            seriesType = H.seriesType;
48216
48217        /**
48218         * Area series type.
48219         * @constructor seriesTypes.area
48220         * @extends {Series}
48221         */
48222        /**
48223         * The area series type.
48224         * @extends {plotOptions.line}
48225         * @product highcharts highstock
48226         * @sample {highcharts} highcharts/demo/area-basic/
48227         *         Area chart
48228         * @sample {highstock} stock/demo/area/
48229         *         Area chart
48230         * @optionparent plotOptions.area
48231         */
48232        seriesType('area', 'line', {
48233
48234            /**
48235             * Fill color or gradient for the area. When `null`, the series' `color`
48236             * is used with the series' `fillOpacity`.
48237             * 
48238             * @type {Color}
48239             * @see In styled mode, the fill color can be set with the `.highcharts-area` class name.
48240             * @sample {highcharts} highcharts/plotoptions/area-fillcolor-default/ Null by default
48241             * @sample {highcharts} highcharts/plotoptions/area-fillcolor-gradient/ Gradient
48242             * @default null
48243             * @product highcharts highstock
48244             * @apioption plotOptions.area.fillColor
48245             */
48246
48247            /**
48248             * Fill opacity for the area. When you set an explicit `fillColor`,
48249             * the `fillOpacity` is not applied. Instead, you should define the
48250             * opacity in the `fillColor` with an rgba color definition. The `fillOpacity`
48251             * setting, also the default setting, overrides the alpha component
48252             * of the `color` setting.
48253             * 
48254             * @type {Number}
48255             * @see In styled mode, the fill opacity can be set with the `.highcharts-area` class name.
48256             * @sample {highcharts} highcharts/plotoptions/area-fillopacity/ Automatic fill color and fill opacity of 0.1
48257             * @default {highcharts} 0.75
48258             * @default {highstock} .75
48259             * @product highcharts highstock
48260             * @apioption plotOptions.area.fillOpacity
48261             */
48262
48263            /**
48264             * A separate color for the graph line. By default the line takes the
48265             * `color` of the series, but the lineColor setting allows setting a
48266             * separate color for the line without altering the `fillColor`.
48267             * 
48268             * @type {Color}
48269             * @see In styled mode, the line stroke can be set with the `.highcharts-graph` class name.
48270             * @sample {highcharts} highcharts/plotoptions/area-linecolor/ Dark gray line
48271             * @default null
48272             * @product highcharts highstock
48273             * @apioption plotOptions.area.lineColor
48274             */
48275
48276            /**
48277             * A separate color for the negative part of the area.
48278             * 
48279             * @type {Color}
48280             * @see [negativeColor](#plotOptions.area.negativeColor). In styled mode, a negative
48281             * color is set with the `.highcharts-negative` class name ([view live
48282             * demo](http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/css/series-
48283             * negative-color/)).
48284             * @since 3.0
48285             * @product highcharts
48286             * @apioption plotOptions.area.negativeFillColor
48287             */
48288
48289            /**
48290             * When this is true, the series will not cause the Y axis to cross
48291             * the zero plane (or [threshold](#plotOptions.series.threshold) option)
48292             * unless the data actually crosses the plane.
48293             * 
48294             * For example, if `softThreshold` is `false`, a series of 0, 1, 2,
48295             * 3 will make the Y axis show negative values according to the `minPadding`
48296             * option. If `softThreshold` is `true`, the Y axis starts at 0.
48297             * 
48298             * @type {Boolean}
48299             * @default false
48300             * @since 4.1.9
48301             * @product highcharts highstock
48302             */
48303            softThreshold: false,
48304
48305            /**
48306             * The Y axis value to serve as the base for the area, for distinguishing
48307             * between values above and below a threshold. If `null`, the area
48308             * behaves like a line series with fill between the graph and the Y
48309             * axis minimum.
48310             * 
48311             * @type {Number}
48312             * @sample {highcharts} highcharts/plotoptions/area-threshold/ A threshold of 100
48313             * @default 0
48314             * @since 2.0
48315             * @product highcharts highstock
48316             */
48317            threshold: 0
48318
48319            /**
48320             * Whether the whole area or just the line should respond to mouseover
48321             * tooltips and other mouse or touch events.
48322             * 
48323             * @type {Boolean}
48324             * @sample {highcharts} highcharts/plotoptions/area-trackbyarea/ Display the tooltip when the     area is hovered
48325             * @sample {highstock} highcharts/plotoptions/area-trackbyarea/ Display the tooltip when the     area is hovered
48326             * @default false
48327             * @since 1.1.6
48328             * @product highcharts highstock
48329             * @apioption plotOptions.area.trackByArea
48330             */
48331
48332
48333        }, /** @lends seriesTypes.area.prototype */ {
48334            singleStacks: false,
48335            /** 
48336             * Return an array of stacked points, where null and missing points are replaced by 
48337             * dummy points in order for gaps to be drawn correctly in stacks.
48338             */
48339            getStackPoints: function(points) {
48340                var series = this,
48341                    segment = [],
48342                    keys = [],
48343                    xAxis = this.xAxis,
48344                    yAxis = this.yAxis,
48345                    stack = yAxis.stacks[this.stackKey],
48346                    pointMap = {},
48347                    seriesIndex = series.index,
48348                    yAxisSeries = yAxis.series,
48349                    seriesLength = yAxisSeries.length,
48350                    visibleSeries,
48351                    upOrDown = pick(yAxis.options.reversedStacks, true) ? 1 : -1,
48352                    i;
48353
48354
48355                points = points || this.points;
48356
48357                if (this.options.stacking) {
48358
48359                    for (i = 0; i < points.length; i++) {
48360                        // Reset after point update (#7326)
48361                        points[i].leftNull = points[i].rightNull = null;
48362
48363                        // Create a map where we can quickly look up the points by their
48364                        // X values.
48365                        pointMap[points[i].x] = points[i];
48366                    }
48367
48368                    // Sort the keys (#1651)
48369                    H.objectEach(stack, function(stackX, x) {
48370                        if (stackX.total !== null) { // nulled after switching between grouping and not (#1651, #2336)
48371                            keys.push(x);
48372                        }
48373                    });
48374                    keys.sort(function(a, b) {
48375                        return a - b;
48376                    });
48377
48378                    visibleSeries = map(yAxisSeries, function() {
48379                        return this.visible;
48380                    });
48381
48382                    each(keys, function(x, idx) {
48383                        var y = 0,
48384                            stackPoint,
48385                            stackedValues;
48386
48387                        if (pointMap[x] && !pointMap[x].isNull) {
48388                            segment.push(pointMap[x]);
48389
48390                            // Find left and right cliff. -1 goes left, 1 goes right.
48391                            each([-1, 1], function(direction) {
48392                                var nullName = direction === 1 ? 'rightNull' : 'leftNull',
48393                                    cliffName = direction === 1 ? 'rightCliff' : 'leftCliff',
48394                                    cliff = 0,
48395                                    otherStack = stack[keys[idx + direction]];
48396
48397                                // If there is a stack next to this one, to the left or to the right...
48398                                if (otherStack) {
48399                                    i = seriesIndex;
48400                                    while (i >= 0 && i < seriesLength) { // Can go either up or down, depending on reversedStacks
48401                                        stackPoint = otherStack.points[i];
48402                                        if (!stackPoint) {
48403                                            // If the next point in this series is missing, mark the point
48404                                            // with point.leftNull or point.rightNull = true.
48405                                            if (i === seriesIndex) {
48406                                                pointMap[x][nullName] = true;
48407
48408                                                // If there are missing points in the next stack 
48408in any of the 
48409                                                // series below this one, we need to substract the missing values
48410                                                // and add a hiatus to the left or right.
48411                                            } else if (visibleSeries[i]) {
48412                                                stackedValues = stack[x].points[i];
48413                                                if (stackedValues) {
48414                                                    cliff -= stackedValues[1] - stackedValues[0];
48415                                                }
48416                                            }
48417                                        }
48418                                        // When reversedStacks is true, loop up, else loop down
48419                                        i += upOrDown;
48420                                    }
48421                                }
48422                                pointMap[x][cliffName] = cliff;
48423                            });
48424
48425
48426                            // There is no point for this X value in this series, so we 
48427                            // insert a dummy point in order for the areas to be drawn
48428                            // correctly.
48429                        } else {
48430
48431                            // Loop down the stack to find the series below this one that has
48432                            // a value (#1991)
48433                            i = seriesIndex;
48434                            while (i >= 0 && i < seriesLength) {
48435                                stackPoint = stack[x].points[i];
48436                                if (stackPoint) {
48437                                    y = stackPoint[1];
48438                                    break;
48439                                }
48440                                // When reversedStacks is true, loop up, else loop down
48441                                i += upOrDown;
48442                            }
48443                            y = yAxis.translate(y, 0, 1, 0, 1); // #6272
48444                            segment.push({
48445                                isNull: true,
48446                                plotX: xAxis.translate(x, 0, 0, 0, 1), // #6272
48447                                x: x,
48448                                plotY: y,
48449                                yBottom: y
48450                            });
48451                        }
48452                    });
48453
48454                }
48455
48456                return segment;
48457            },
48458
48459            getGraphPath: function(points) {
48460                var getGraphPath = Series.prototype.getGraphPath,
48461                    graphPath,
48462                    options = this.options,
48463                    stacking = options.stacking,
48464                    yAxis = this.yAxis,
48465                    topPath,
48466                    bottomPath,
48467                    bottomPoints = [],
48468                    graphPoints = [],
48469                    seriesIndex = this.index,
48470                    i,
48471                    areaPath,
48472                    plotX,
48473                    stacks = yAxis.stacks[this.stackKey],
48474                    threshold = options.threshold,
48475                    translatedThreshold = yAxis.getThreshold(options.threshold),
48476                    isNull,
48477                    yBottom,
48478                    connectNulls = options.connectNulls || stacking === 'percent',
48479                    /**
48480                     * To display null points in underlying stacked series, this series graph must be 
48481                     * broken, and the area also fall down to fill the gap left by the null point. #2069
48482                     */
48483                    addDummyPoints = function(i, otherI, side) {
48484                        var point = points[i],
48485                            stackedValues = stacking && stacks[point.x].points[seriesIndex],
48486                            nullVal = point[side + 'Null'] || 0,
48487                            cliffVal = point[side + 'Cliff'] || 0,
48488                            top,
48489                            bottom,
48490                            isNull = true;
48491
48492                        if (cliffVal || nullVal) {
48493
48494                            top = (nullVal ? stackedValues[0] : stackedValues[1]) + cliffVal;
48495                            bottom = stackedValues[0] + cliffVal;
48496                            isNull = !!nullVal;
48497
48498                        } else if (!stacking && points[otherI] && points[otherI].isNull) {
48499                            top = bottom = threshold;
48500                        }
48501
48502                        // Add to the top and bottom line of the area
48503                        if (top !== undefined) {
48504                            graphPoints.push({
48505                                plotX: plotX,
48506                                plotY: top === null ? translatedThreshold : yAxis.getThreshold(top),
48507                                isNull: isNull,
48508                                isCliff: true
48509                            });
48510                            bottomPoints.push({
48511                                plotX: plotX,
48512                                plotY: bottom === null ? translatedThreshold : yAxis.getThreshold(bottom),
48513                                doCurve: false // #1041, gaps in areaspline areas
48514                            });
48515                        }
48516                    };
48517
48518                // Find what points to use
48519                points = points || this.points;
48520
48521                // Fill in missing points
48522                if (stacking) {
48523                    points = this.getStackPoints(points);
48524                }
48525
48526                for (i = 0; i < points.length; i++) {
48527                    isNull = points[i].isNull;
48528                    plotX = pick(points[i].rectPlotX, points[i].plotX);
48529                    yBottom = pick(points[i].yBottom, translatedThreshold);
48530
48531                    if (!isNull || connectNulls) {
48532
48533                        if (!connectNulls) {
48534                            addDummyPoints(i, i - 1, 'left');
48535                        }
48536
48537                        if (!(isNull && !stacking && connectNulls)) { // Skip null point when stacking is false and connectNulls true
48538                            graphPoints.push(points[i]);
48539                            bottomPoints.push({
48540                                x: i,
48541                                plotX: plotX,
48542                                plotY: yBottom
48543                            });
48544                        }
48545
48546                        if (!connectNulls) {
48547                            addDummyPoints(i, i + 1, 'right');
48548                        }
48549                    }
48550                }
48551
48552                topPath = getGraphPath.call(this, graphPoints, true, true);
48553
48554                bottomPoints.reversed = true;
48555                bottomPath = getGraphPath.call(this, bottomPoints, true, true);
48556                if (bottomPath.length) {
48557                    bottomPath[0] = 'L';
48558                }
48559
48560                areaPath = topPath.concat(bottomPath);
48561                graphPath = getGraphPath.call(this, graphPoints, false, connectNulls); // TODO: don't set leftCliff and rightCliff when connectNulls?
48562
48563                areaPath.xMap = topPath.xMap;
48564                this.areaPath = areaPath;
48565
48566                return graphPath;
48567            },
48568
48569            /**
48570             * Draw the graph and the underlying area. This method calls the Series base
48571             * function and adds the area. The areaPath is calculated in the getSegmentPath
48572             * method called from Series.prototype.drawGraph.
48573             */
48574            drawGraph: function() {
48575
48576                // Define or reset areaPath
48577                this.areaPath = [];
48578
48579                // Call the base method
48580                Series.prototype.drawGraph.apply(this);
48581
48582                // Define local variables
48583                var series = this,
48584                    areaPath = this.areaPath,
48585                    options = this.options,
48586                    zones = this.zones,
48587                    props = [
48588                        [
48589                            'area',
48590                            'highcharts-area',
48591
48592                            this.color,
48593                            options.fillColor
48594
48595                        ]
48596                    ]; // area name, main color, fill color
48597
48598                each(zones, function(zone, i) {
48599                    props.push([
48600                        'zone-area-' + i,
48601                        'highcharts-area highcharts-zone-area-' + i + ' ' + zone.className,
48602
48603                        zone.color || series.color,
48604                        zone.fillColor || options.fillColor
48605
48606                    ]);
48607                });
48608
48609                each(props, function(prop) {
48610                    var areaKey = prop[0],
48611                        area = series[areaKey];
48612
48613                    // Create or update the area
48614                    if (area) { // update
48615                        area.endX = series.preventGraphAnimation ? null : areaPath.xMap;
48616                        area.animate({
48617                            d: areaPath
48618                        });
48619
48620                    } else { // create
48621                        area = series[areaKey] = series.chart.renderer.path(areaPath)
48622                            .addClass(prop[1])
48623                            .attr({
48624
48625                                fill: pick(
48626                                    prop[3],
48627                                    color(prop[2]).setOpacity(pick(options.fillOpacity, 0.75)).get()
48628                                ),
48629
48630                                zIndex: 0 // #1069
48631                            }).add(series.group);
48632                        area.isArea = true;
48633                    }
48634                    area.startX = areaPath.xMap;
48635                    area.shiftUnit = options.step ? 2 : 1;
48636                });
48637            },
48638
48639            drawLegendSymbol: LegendSymbolMixin.drawRectangle
48640        });
48641
48642        /**
48643         * A `area` series. If the [type](#series.area.type) option is not
48644         * specified, it is inherited from [chart.type](#chart.type).
48645         * 
48646         * For options that apply to multiple series, it is recommended to add
48647         * them to the [plotOptions.series](#plotOptions.series) options structure.
48648         * To apply to all series of this specific type, apply it to [plotOptions.
48649         * area](#plotOptions.area).
48650         * 
48651         * @type {Object}
48652         * @extends series,plotOptions.area
48653         * @excluding dataParser,dataURL
48654         * @product highcharts highstock
48655         * @apioption series.area
48656         */
48657
48658        /**
48659         * An array of data points for the series. For the `area` series type,
48660         * points can be given in the following ways:
48661         * 
48662         * 1.  An array of numerical values. In this case, the numerical values
48663         * will be interpreted as `y` options. The `x` values will be automatically
48664         * calculated, either starting at 0 and incremented by 1, or from `pointStart`
48665         * and `pointInterval` given in the series options. If the axis has
48666         * categories, these will be used. Example:
48667         * 
48668         *  ```js
48669         *  data: [0, 5, 3, 5]
48670         *  ```
48671         * 
48672         * 2.  An array of arrays with 2 values. In this case, the values correspond
48673         * to `x,y`. If the first value is a string, it is applied as the name
48674         * of the point, and the `x` value is inferred.
48675         * 
48676         *  ```js
48677         *     data: [
48678         *         [0, 9],
48679         *         [1, 7],
48680         *         [2, 6]
48681         *     ]
48682         *  ```
48683         * 
48684         * 3.  An array of objects with named values. The objects are point
48685         * configuration objects as seen below. If the total number of data
48686         * points exceeds the series' [turboThreshold](#series.area.turboThreshold),
48687         * this option is not available.
48688         * 
48689         *  ```js
48690         *     data: [{
48691         *         x: 1,
48692         *         y: 9,
48693         *         name: "Point2",
48694         *         color: "#00FF00"
48695         *     }, {
48696         *         x: 1,
48697         *         y: 6,
48698         *         name: "Point1",
48699         *         color: "#FF00FF"
48700         *     }]
48701         *  ```
48702         * 
48703         * @type {Array<Object|Array|Number>}
48704         * @extends series.line.data
48705         * @sample {highcharts} highcharts/chart/reflow-true/ Numerical values
48706         * @sample {highcharts} highcharts/series/data-array-of-arrays/ Arrays of numeric x and y
48707         * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/ Arrays of datetime x and y
48708         * @sample {highcharts} highcharts/series/data-array-of-name-value/ Arrays of point.name and 
48708y
48709         * @sample {highcharts} highcharts/series/data-array-of-objects/ Config objects
48710         * @product highcharts highstock
48711         * @apioption series.area.data
48712         */
48713
48714    }(Highcharts));
48715    (function(H) {
48716        /**
48717         * (c) 2010-2017 Torstein Honsi
48718         *
48719         * License: www.highcharts.com/license
48720         */
48721        var pick = H.pick,
48722            seriesType = H.seriesType;
48723
48724        /**
48725         * A spline series is a special type of line series, where the segments between
48726         * the data points are smoothed.
48727         *
48728         * @sample {highcharts} highcharts/demo/spline-irregular-time/ Spline chart
48729         * @sample {highstock} stock/demo/spline/ Spline chart
48730         * 
48731         * @extends plotOptions.series
48732         * @excluding step
48733         * @product highcharts highstock
48734         * @apioption plotOptions.spline
48735         */
48736
48737        /**
48738         * Spline series type.
48739         * @constructor seriesTypes.spline
48740         * @extends {Series}
48741         */
48742        seriesType('spline', 'line', {}, /** @lends seriesTypes.spline.prototype */ {
48743            /**
48744             * Get the spline segment from a given point's previous neighbour to the
48745             * given point
48746             */
48747            getPointSpline: function(points, point, i) {
48748                var
48749                    // 1 means control points midway between points, 2 means 1/3 from
48750                    // the point, 3 is 1/4 etc
48751                    smoothing = 1.5,
48752                    denom = smoothing + 1,
48753                    plotX = point.plotX,
48754                    plotY = point.plotY,
48755                    lastPoint = points[i - 1],
48756                    nextPoint = points[i + 1],
48757                    leftContX,
48758                    leftContY,
48759                    rightContX,
48760                    rightContY,
48761                    ret;
48762
48763                function doCurve(otherPoint) {
48764                    return otherPoint &&
48765                        !otherPoint.isNull &&
48766                        otherPoint.doCurve !== false &&
48767                        !point.isCliff; // #6387, area splines next to null
48768                }
48769
48770                // Find control points
48771                if (doCurve(lastPoint) && doCurve(nextPoint)) {
48772                    var lastX = lastPoint.plotX,
48773                        lastY = lastPoint.plotY,
48774                        nextX = nextPoint.plotX,
48775                        nextY = nextPoint.plotY,
48776                        correction = 0;
48777
48778                    leftContX = (smoothing * plotX + lastX) / denom;
48779                    leftContY = (smoothing * plotY + lastY) / denom;
48780                    rightContX = (smoothing * plotX + nextX) / denom;
48781                    rightContY = (smoothing * plotY + nextY) / denom;
48782
48783                    // Have the two control points make a straight line through main
48784                    // point
48785                    if (rightContX !== leftContX) { // #5016, division by zero
48786                        correction = ((rightContY - leftContY) * (rightContX - plotX)) /
48787                            (rightContX - leftContX) + plotY - rightContY;
48788                    }
48789
48790                    leftContY += correction;
48791                    rightContY += correction;
48792
48793                    // to prevent false extremes, check that control points are between
48794                    // neighbouring points' y values
48795                    if (leftContY > lastY && leftContY > plotY) {
48796                        leftContY = Math.max(lastY, plotY);
48797                        // mirror of left control point
48798                        rightContY = 2 * plotY - leftContY;
48799                    } else if (leftContY < lastY && leftContY < plotY) {
48800                        leftContY = Math.min(lastY, plotY);
48801                        rightContY = 2 * plotY - leftContY;
48802                    }
48803                    if (rightContY > nextY && rightContY > plotY) {
48804                        rightContY = Math.max(nextY, plotY);
48805                        leftContY = 2 * plotY - rightContY;
48806                    } else if (rightContY < nextY && rightContY < plotY) {
48807                        rightContY = Math.min(nextY, plotY);
48808                        leftContY = 2 * plotY - rightContY;
48809                    }
48810
48811                    // record for drawing in next point
48812                    point.rightContX = rightContX;
48813                    point.rightContY = rightContY;
48814
48815
48816                }
48817
48818                // Visualize control points for debugging
48819                /*
48820                if (leftContX) {
48821                	this.chart.renderer.circle(
48822                			leftContX + this.chart.plotLeft,
48823                			leftContY + this.chart.plotTop,
48824                			2
48825                		)
48826                		.attr({
48827                			stroke: 'red',
48828                			'stroke-width': 2,
48829                			fill: 'none',
48830                			zIndex: 9
48831                		})
48832                		.add();
48833                	this.chart.renderer.path(['M', leftContX + this.chart.plotLeft,
48834                		leftContY + this.chart.plotTop,
48835                		'L', plotX + this.chart.plotLeft, plotY + this.chart.plotTop])
48836                		.attr({
48837                			stroke: 'red',
48838                			'stroke-width': 2,
48839                			zIndex: 9
48840                		})
48841                		.add();
48842                }
48843                if (rightContX) {
48844                	this.chart.renderer.circle(
48845                			rightContX + this.chart.plotLeft,
48846                			rightContY + this.chart.plotTop,
48847                			2
48848                		)
48849                		.attr({
48850                			stroke: 'green',
48851                			'stroke-width': 2,
48852                			fill: 'none',
48853                			zIndex: 9
48854                		})
48855                		.add();
48856                	this.chart.renderer.path(['M', rightContX + this.chart.plotLeft,
48857                		rightContY + this.chart.plotTop,
48858                		'L', plotX + this.chart.plotLeft, plotY + this.chart.plotTop])
48859                		.attr({
48860                			stroke: 'green',
48861                			'stroke-width': 2,
48862                			zIndex: 9
48863                		})
48864                		.add();
48865                }
48866                // */
48867                ret = [
48868                    'C',
48869                    pick(lastPoint.rightContX, lastPoint.plotX),
48870                    pick(lastPoint.rightContY, lastPoint.plotY),
48871                    pick(leftContX, plotX),
48872                    pick(leftContY, plotY),
48873                    plotX,
48874                    plotY
48875                ];
48876                // reset for updating series later
48877                lastPoint.rightContX = lastPoint.rightContY = null;
48878                return ret;
48879            }
48880        });
48881
48882        /**
48883         * A `spline` series. If the [type](#series.spline.type) option is
48884         * not specified, it is inherited from [chart.type](#chart.type).
48885         * 
48886         * For options that apply to multiple series, it is recommended to add
48887         * them to the [plotOptions.series](#plotOptions.series) options structure.
48888         * To apply to all series of this specific type, apply it to [plotOptions.
48889         * spline](#plotOptions.spline).
48890         * 
48891         * @type {Object}
48892         * @extends series,plotOptions.spline
48893         * @excluding dataParser,dataURL
48894         * @product highcharts highstock
48895         * @apioption series.spline
48896         */
48897
48898        /**
48899         * An array of data points for the series. For the `spline` series type,
48900         * points can be given in the following ways:
48901         * 
48902         * 1.  An array of numerical values. In this case, the numerical values
48903         * will be interpreted as `y` options. The `x` values will be automatically
48904         * calculated, either starting at 0 and incremented by 1, or from `pointStart`
48905         * and `pointInterval` given in the series options. If the axis has
48906         * categories, these will be used. Example:
48907         * 
48908         *  ```js
48909         *  data: [0, 5, 3, 5]
48910         *  ```
48911         * 
48912         * 2.  An array of arrays with 2 values. In this case, the values correspond
48913         * to `x,y`. If the first value is a string, it is applied as the name
48914         * of the point, and the `x` value is inferred.
48915         * 
48916         *  ```js
48917         *     data: [
48918         *         [0, 9],
48919         *         [1, 2],
48920         *         [2, 8]
48921         *     ]
48922         *  ```
48923         * 
48924         * 3.  An array of objects with named values. The objects are point
48925         * configuration objects as seen below. If the total number of data
48926         * points exceeds the series' [turboThreshold](#series.spline.turboThreshold),
48927         * this option is not available.
48928         * 
48929         *  ```js
48930         *     data: [{
48931         *         x: 1,
48932         *         y: 9,
48933         *         name: "Point2",
48934         *         color: "#00FF00"
48935         *     }, {
48936         *         x: 1,
48937         *         y: 0,
48938         *         name: "Point1",
48939         *         color: "#FF00FF"
48940         *     }]
48941         *  ```
48942         * 
48943         * @type {Array<Object|Array|Number>}
48944         * @extends series.line.data
48945         * @sample {highcharts} highcharts/chart/reflow-true/
48946         *         Numerical values
48947         * @sample {highcharts} highcharts/series/data-array-of-arrays/
48948         *         Arrays of numeric x and y
48949         * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
48950         *         Arrays of datetime x and y
48951         * @sample {highcharts} highcharts/series/data-array-of-name-value/
48952         *         Arrays of point.name and y
48953         * @sample {highcharts} highcharts/series/data-array-of-objects/
48954         *         Config objects
48955         * @product highcharts highstock
48956         * @apioption series.spline.data
48957         */
48958
48959    }(Highcharts));
48960    (function(H) {
48961        /**
48962         * (c) 2010-2017 Torstein Honsi
48963         *
48964         * License: www.highcharts.com/license
48965         */
48966        var areaProto = H.seriesTypes.area.prototype,
48967            defaultPlotOptions = H.defaultPlotOptions,
48968            LegendSymbolMixin = H.LegendSymbolMixin,
48969            seriesType = H.seriesType;
48970        /**
48971         * AreaSplineSeries object
48972         */
48973        /**
48974         * The area spline series is an area series where the graph between the points
48975         * is smoothed into a spline.
48976         * 
48977         * @extends plotOptions.area
48978         * @excluding step
48979         * @sample {highcharts} highcharts/demo/areaspline/ Area spline chart
48980         * @sample {highstock} stock/demo/areaspline/ Area spline chart
48981         * @product highcharts highstock
48982         * @apioption plotOptions.areaspline
48983         */
48984        seriesType('areaspline', 'spline', defaultPlotOptions.area, {
48985            getStackPoints: areaProto.getStackPoints,
48986            getGraphPath: areaProto.getGraphPath,
48987            drawGraph: areaProto.drawGraph,
48988            drawLegendSymbol: LegendSymbolMixin.drawRectangle
48989        });
48990        /**
48991         * A `areaspline` series. If the [type](#series.areaspline.type) option
48992         * is not specified, it is inherited from [chart.type](#chart.type).
48993         * 
48994         * 
48995         * For options that apply to multiple series, it is recommended to add
48996         * them to the [plotOptions.series](#plotOptions.series) options structure.
48997         * To apply to all series of this specific type, apply it to [plotOptions.
48998         * areaspline](#plotOptions.areaspline).
48999         * 
49000         * @type {Object}
49001         * @extends series,plotOptions.areaspline
49002         * @excluding dataParser,dataURL
49003         * @product highcharts highstock
49004         * @apioption series.areaspline
49005         */
49006
49007
49008        /**
49009         * An array of data points for the series. For the `areaspline` series
49010         * type, points can be given in the following ways:
49011         * 
49012         * 1.  An array of numerical values. In this case, the numerical values
49013         * will be interpreted as `y` options. The `x` values will be automatically
49014         * calculated, either starting at 0 and incremented by 1, or from `pointStart`
49015         * and `pointInterval` given in the series options. If the axis has
49016         * categories, these will be used. Example:
49017         * 
49018         *  ```js
49019         *  data: [0, 5, 3, 5]
49020         *  ```
49021         * 
49022         * 2.  An array of arrays with 2 values. In this case, the values correspond
49023         * to `x,y`. If the first value is a string, it is applied as the name
49024         * of the point, and the `x` value is inferred.
49025         * 
49026         *  ```js
49027         *     data: [
49028         *         [0, 10],
49029         *         [1, 9],
49030         *         [2, 3]
49031         *     ]
49032         *  ```
49033         * 
49034         * 3.  An array of objects with named values. The objects are point
49035         * configuration objects as seen below. If the total number of data
49036         * points exceeds the series' [turboThreshold](#series.areaspline.turboThreshold),
49037         * this option is not available.
49038         * 
49039         *  ```js
49040         *     data: [{
49041         *         x: 1,
49042         *         y: 4,
49043         *         name: "Point2",
49044         *         color: "#00FF00"
49045         *     }, {
49046         *         x: 1,
49047         *         y: 4,
49048         *         name: "Point1",
49049         *         color: "#FF00FF"
49050         *     }]
49051         *  ```
49052         * 
49053         * @type {Array<Object|Array|Number>}
49054         * @extends series.line.data
49055         * @sample {highcharts} highcharts/chart/reflow-true/ Numerical values
49056         * @sample {highcharts} highcharts/series/data-array-of-arrays/ Arrays of numeric x and y
49057         * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/ Arrays of datetime x and y
49058         * @sample {highcharts} highcharts/series/data-array-of-name-value/ Arrays of point.name and 
49058y
49059         * @sample {highcharts} highcharts/series/data-array-of-objects/ Config objects
49060         * @product highcharts highstock
49061         * @apioption series.areaspline.data
49062         */
49063
49064
49065
49066    }(Highcharts));
49067    (function(H) {
49068        /**
49069         * (c) 2010-2017 Torstein Honsi
49070         *
49071         * License: www.highcharts.com/license
49072         */
49073        var animObject = H.animObject,
49074            color = H.color,
49075            each = H.each,
49076            extend = H.extend,
49077            isNumber = H.isNumber,
49078            LegendSymbolMixin = H.LegendSymbolMixin,
49079            merge = H.merge,
49080            noop = H.noop,
49081            pick = H.pick,
49082            Series = H.Series,
49083            seriesType = H.seriesType,
49084            svg = H.svg;
49085        /**
49086         * The column series type.
49087         *
49088         * @constructor seriesTypes.column
49089         * @augments Series
49090         */
49091
49092        /**
49093         * Column series display one column per value along an X axis.
49094         *
49095         * @sample {highcharts} highcharts/demo/column-basic/ Column chart
49096         * @sample {highstock} stock/demo/column/ Column chart
49097         *
49098         * @extends {plotOptions.line}
49099         * @product highcharts highstock
49100         * @excluding connectNulls,dashStyle,gapSize,gapUnit,linecap,lineWidth,marker,
49101         *          connectEnds,step
49102         * @optionparent plotOptions.column
49103         */
49104        seriesType('column', 'line', {
49105
49106            /**
49107             * The corner radius of the border surrounding each column or bar.
49108             *
49109             * @type {Number}
49110             * @sample {highcharts} highcharts/plotoptions/column-borderradius/
49111             *         Rounded columns
49112             * @default 0
49113             * @product highcharts highstock
49114             */
49115            borderRadius: 0,
49116
49117            /**
49118             * The width of the border surrounding each column or bar.
49119             *
49120             * In styled mode, the stroke width can be set with the `.highcharts-point`
49121             * rule.
49122             *
49123             * @type {Number}
49124             * @sample {highcharts} highcharts/plotoptions/column-borderwidth/
49125             *         2px black border
49126             * @default 1
49127             * @product highcharts highstock
49128             * @apioption plotOptions.column.borderWidth
49129             */
49130
49131            /**
49132             * When using automatic point colors pulled from the `options.colors`
49133             * collection, this option determines whether the chart should receive
49134             * one color per series or one color per point.
49135             *
49136             * @type {Boolean}
49137             * @see [series colors](#plotOptions.column.colors)
49138             * @sample {highcharts} highcharts/plotoptions/column-colorbypoint-false/
49139             *         False by default
49140             * @sample {highcharts} highcharts/plotoptions/column-colorbypoint-true/
49141             *         True
49142             * @default false
49143             * @since 2.0
49144             * @product highcharts highstock
49145             * @apioption plotOptions.column.colorByPoint
49146             */
49147
49148            /**
49149             * A series specific or series type specific color set to apply instead
49150             * of the global [colors](#colors) when [colorByPoint](#plotOptions.
49151             * column.colorByPoint) is true.
49152             *
49153             * @type {Array<Color>}
49154             * @since 3.0
49155             * @product highcharts highstock
49156             * @apioption plotOptions.column.colors
49157             */
49158
49159            /**
49160             * When true, each column edge is rounded to its nearest pixel in order
49161             * to render sharp on screen. In some cases, when there are a lot of
49162             * densely packed columns, this leads to visible difference in column
49163             * widths or distance between columns. In these cases, setting `crisp`
49164             * to `false` may look better, even though each column is rendered
49165             * blurry.
49166             *
49167             * @type {Boolean}
49168             * @sample {highcharts} highcharts/plotoptions/column-crisp-false/
49169             *         Crisp is false
49170             * @default true
49171             * @since 5.0.10
49172             * @product highcharts highstock
49173             */
49174            crisp: true,
49175
49176            /**
49177             * Padding between each value groups, in x axis units.
49178             *
49179             * @type {Number}
49180             * @sample {highcharts} highcharts/plotoptions/column-grouppadding-default/
49181             *         0.2 by default
49182             * @sample {highcharts} highcharts/plotoptions/column-grouppadding-none/
49183             *         No group padding - all columns are evenly spaced
49184             * @default 0.2
49185             * @product highcharts highstock
49186             */
49187            groupPadding: 0.2,
49188
49189            /**
49190             * Whether to group non-stacked columns or to let them render independent
49191             * of each other. Non-grouped columns will be laid out individually
49192             * and overlap each other.
49193             *
49194             * @type {Boolean}
49195             * @sample {highcharts} highcharts/plotoptions/column-grouping-false/
49196             *         Grouping disabled
49197             * @sample {highstock} highcharts/plotoptions/column-grouping-false/
49198             *         Grouping disabled
49199             * @default true
49200             * @since 2.3.0
49201             * @product highcharts highstock
49202             * @apioption plotOptions.column.grouping
49203             */
49204
49205            marker: null, // point options are specified in the base options
49206
49207            /**
49208             * The maximum allowed pixel width for a column, translated to the height
49209             * of a bar in a bar chart. This prevents the columns from becoming
49210             * too wide when there is a small number of points in the chart.
49211             *
49212             * @type {Number}
49213             * @see [pointWidth](#plotOptions.column.pointWidth)
49214             * @sample {highcharts} highcharts/plotoptions/column-maxpointwidth-20/
49215             *         Limited to 50
49216             * @sample {highstock} highcharts/plotoptions/column-maxpointwidth-20/
49217             *         Limited to 50
49218             * @default null
49219             * @since 4.1.8
49220             * @product highcharts highstock
49221             * @apioption plotOptions.column.maxPointWidth
49222             */
49223
49224            /**
49225             * Padding between each column or bar, in x axis units.
49226             *
49227             * @type {Number}
49228             * @sample {highcharts} highcharts/plotoptions/column-pointpadding-default/
49229             *         0.1 by default
49230             * @sample {highcharts} highcharts/plotoptions/column-pointpadding-025/
49231             *         0.25
49232             * @sample {highcharts} highcharts/plotoptions/column-pointpadding-none/
49233             *         0 for tightly packed columns
49234             * @default 0.1
49235             * @product highcharts highstock
49236             */
49237            pointPadding: 0.1,
49238
49239            /**
49240             * A pixel value specifying a fixed width for each column or bar. When
49241             * `null`, the width is calculated from the `pointPadding` and
49242             * `groupPadding`.
49243             *
49244             * @type {Number}
49245             * @see [maxPointWidth](#plotOptions.column.maxPointWidth)
49246             * @sample {highcharts} highcharts/plotoptions/column-pointwidth-20/
49247             *         20px wide columns regardless of chart width or the amount of data
49248             *         points
49249             * @default null
49250             * @since 1.2.5
49251             * @product highcharts highstock
49252             * @apioption plotOptions.column.pointWidth
49253             */
49254
49255            /**
49256             * The minimal height for a column or width for a bar. By default,
49257             * 0 values are not shown. To visualize a 0 (or close to zero) point,
49258             * set the minimal point length to a pixel value like 3\. In stacked
49259             * column charts, minPointLength might not be respected for tightly
49260             * packed values.
49261             *
49262             * @type {Number}
49263             * @sample {highcharts} highcharts/plotoptions/column-minpointlength/
49264             *         Zero base value
49265             * @sample {highcharts} highcharts/plotoptions/column-minpointlength-pos-and-neg/
49266             *         Positive and negative close to zero values
49267             * @default 0
49268             * @product highcharts highstock
49269             */
49270            minPointLength: 0,
49271
49272            /**
49273             * When the series contains less points than the crop threshold, all
49274             * points are drawn, event if the points fall outside the visible plot
49275             * area at the current zoom. The advantage of drawing all points (including
49276             * markers and columns), is that animation is performed on updates.
49277             * On the other hand, when the series contains more points than the
49278             * crop threshold, the series data is cropped to only contain points
49279             * that fall within the plot area. The advantage of cropping away invisible
49280             * points is to increase performance on large series. .
49281             *
49282             * @type {Number}
49283             * @default 50
49284             * @product highcharts highstock
49285             */
49286            cropThreshold: 50,
49287
49288            /**
49289             * The X axis range that each point is valid for. This determines the
49290             * width of the column. On a categorized axis, the range will be 1
49291             * by default (one category unit). On linear and datetime axes, the
49292             * range will be computed as the distance between the two closest data
49293             * points.
49294             *
49295             * The default `null` means it is computed automatically, but this option
49296             * can be used to override the automatic value.
49297             *
49298             * @type {Number}
49299             * @sample {highcharts} highcharts/plotoptions/column-pointrange/
49300             *         Set the point range to one day on a data set with one week
49301             *         between the points
49302             * @default null
49303             * @since 2.3
49304             * @product highcharts highstock
49305             */
49306            pointRange: null,
49307
49308            states: {
49309
49310                /**
49311                 * @extends plotOptions.series.states.hover
49312                 * @excluding halo,lineWidth,lineWidthPlus,marker
49313                 * @product highcharts highstock
49314                 */
49315                hover: {
49316
49317                    /**
49318                     * @ignore-option
49319                     */
49320                    halo: false,
49321                    /**
49322                     * A specific border color for the hovered point. Defaults to
49323                     * inherit the normal state border color.
49324                     *
49325                     * @type {Color}
49326                     * @product highcharts
49327                     * @apioption plotOptions.column.states.hover.borderColor
49328                     */
49329
49330                    /**
49331                     * A specific color for the hovered point.
49332                     *
49333                     * @type {Color}
49334                     * @default undefined
49335                     * @product highcharts
49336                     * @apioption plotOptions.column.states.hover.color
49337                     */
49338
49339
49340
49341                    /**
49342                     * How much to brighten the point on interaction. Requires the main
49343                     * color to be defined in hex or rgb(a) format.
49344                     *
49345                     * In styled mode, the hover brightening is by default replaced
49346                     * with a fill-opacity set in the `.highcharts-point:hover` rule.
49347                     *
49348                     * @type {Number}
49349                     * @sample {highcharts} highcharts/plotoptions/column-states-hover-brightness/
49350                     *         Brighten by 0.5
49351                     * @default 0.1
49352                     * @product highcharts highstock
49353                     */
49354                    brightness: 0.1
49355
49356
49357                },
49358
49359
49360                select: {
49361                    color: '#cccccc',
49362                    borderColor: '#000000'
49363                }
49364
49365            },
49366
49367            dataLabels: {
49368                align: null, // auto
49369                verticalAlign: null, // auto
49370                y: null
49371            },
49372
49373            /**
49374             * When this is true, the series will not cause the Y axis to cross
49375             * the zero plane (or [threshold](#plotOptions.series.threshold) option)
49376             * unless the data actually crosses the plane.
49377             *
49378             * For example, if `softThreshold` is `false`, a series of 0, 1, 2,
49379             * 3 will make the Y axis show negative values according to the `minPadding`
49380             * option. If `softThreshold` is `true`, the Y axis starts at 0.
49381             *
49382             * @type {Boolean}
49383             * @default {highcharts} true
49384             * @default {highstock} false
49385             * @since 4.1.9
49386             * @product highcharts highstock
49387             */
49388            softThreshold: false,
49389
49390            // false doesn't work well: http://jsfiddle.net/highcharts/hz8fopan/14/
49391            /**	@ignore */
49392            startFromThreshold: true,
49393
49394            stickyTracking: false,
49395
49396            tooltip: {
49397                distance: 6
49398            },
49399
49400            /**
49401             * The Y axis value to serve as the base for the columns, for distinguishing
49402             * between values above and below a threshold. If `null`, the columns
49403             * extend from the padding Y axis minimum.
49404             *
49405             * @type {Number}
49406             * @default 0
49407             * @since 2.0
49408             * @product highcharts
49409             */
49410            threshold: 0,
49411
49412
49413            /**
49414             * The color of the border surrounding each column or bar.
49415             *
49416             * In styled mode, the border stroke can be set with the `.highcharts-point`
49417             * rule.
49418             *
49419             * @type {Color}
49420             * @sample {highcharts} highcharts/plotoptions/column-bordercolor/
49421             *         Dark gray border
49422             * @default #ffffff
49423             * @product highcharts highstock
49424             */
49425            borderColor: '#ffffff'
49426            // borderWidth: 1
49427
49428
49429        }, /** @lends seriesTypes.column.prototype */ {
49430            cropShoulder: 0,
49431            // When tooltip is not shared, this series (and derivatives) requires direct
49432            // touch/hover. KD-tree does not apply.
49433            directTouch: true,
49434            trackerGroups: ['group', 'dataLabelsGroup'],
49435            // use separate negative stacks, unlike area stacks where a negative point
49436            // is substracted from previous (#1910)
49437            negStacks: true,
49438
49439            /**
49440             * Initialize the series. Extends the basic Series.init method by
49441             * marking other series of the same type as dirty.
49442             *
49443             * @function #init
49444             * @memberOf seriesTypes.column
49445             *
49446             */
49447            init: function() {
49448                Series.prototype.init.apply(this, arguments);
49449
49450                var series = this,
49451                    chart = series.chart;
49452
49453                // if the series is added dynamically, force redraw of other
49454                // series affected by a new column
49455                if (chart.hasRendered) {
49456                    each(chart.series, function(otherSeries) {
49457                        if (otherSeries.type === series.type) {
49458                            otherSeries.isDirty = true;
49459                        }
49460                    });
49461                }
49462            },
49463
49464            /**
49465             * Return the width and x offset of the columns adjusted for grouping,
49466             * groupPadding, pointPadding, pointWidth etc.
49467             */
49468            getColumnMetrics: function() {
49469
49470                var series = this,
49471                    options = series.options,
49472                    xAxis = series.xAxis,
49473                    yAxis = series.yAxis,
49474                    reversedXAxis = xAxis.reversed,
49475                    stackKey,
49476                    stackGroups = {},
49477                    columnCount = 0;
49478
49479                // Get the total number of column type series. This is called on every
49480                // series. Consider moving this logic to a chart.orderStacks() function
49481                // and call it on init, addSeries and removeSeries
49482                if (options.grouping === false) {
49483                    columnCount = 1;
49484                } else {
49485                    each(series.chart.series, function(otherSeries) {
49486                        var otherOptions = otherSeries.options,
49487                            otherYAxis = otherSeries.yAxis,
49488                            columnIndex;
49489                        if (
49490                            otherSeries.type === series.type &&
49491                            (
49492                                otherSeries.visible ||
49493                                !series.chart.options.chart.ignoreHiddenSeries
49494                            ) &&
49495                            yAxis.len === otherYAxis.len &&
49496                            yAxis.pos === otherYAxis.pos
49497                        ) { // #642, #2086
49498                            if (otherOptions.stacking) {
49499                                stackKey = otherSeries.stackKey;
49500                                if (stackGroups[stackKey] === undefined) {
49501                                    stackGroups[stackKey] = columnCount++;
49502                                }
49503                                columnIndex = stackGroups[stackKey];
49504                            } else if (otherOptions.grouping !== false) { // #1162
49505                                columnIndex = columnCount++;
49506                            }
49507                            otherSeries.columnIndex = columnIndex;
49508                        }
49509                    });
49510                }
49511
49512                var categoryWidth = Math.min(
49513                        Math.abs(xAxis.transA) * (
49514                            xAxis.ordinalSlope ||
49515                            options.pointRange ||
49516                            xAxis.closestPointRange ||
49517                            xAxis.tickInterval ||
49518                            1
49519                        ), // #2610
49520                        xAxis.len // #1535
49521                    ),
49522                    groupPadding = categoryWidth * options.groupPadding,
49523                    groupWidth = categoryWidth - 2 * groupPadding,
49524                    pointOffsetWidth = groupWidth / (columnCount || 1),
49525                    pointWidth = Math.min(
49526                        options.maxPointWidth || xAxis.len,
49527                        pick(
49528                            options.pointWidth,
49529                            pointOffsetWidth * (1 - 2 * options.pointPadding)
49530                        )
49531                    ),
49532                    pointPadding = (pointOffsetWidth - pointWidth) / 2,
49533                    // #1251, #3737
49534                    colIndex = (series.columnIndex || 0) + (reversedXAxis ? 1 : 0),
49535                    pointXOffset =
49536                    pointPadding +
49537                    (
49538                        groupPadding +
49539                        colIndex * pointOffsetWidth -
49540                        (categoryWidth / 2)
49541                    ) * (reversedXAxis ? -1 : 1);
49542
49543                // Save it for reading in linked series (Error bars particularly)
49544                series.columnMetrics = {
49545                    width: pointWidth,
49546                    offset: pointXOffset
49547                };
49548                return series.columnMetrics;
49549
49550            },
49551
49552            /**
49553             * Make the columns crisp. The edges are rounded to the nearest full pixel.
49554             */
49555            crispCol: function(x, y, w, h) {
49556                var chart = this.chart,
49557                    borderWidth = this.borderWidth,
49558                    xCrisp = -(borderWidth % 2 ? 0.5 : 0),
49559                    yCrisp = borderWidth % 2 ? 0.5 : 1,
49560                    right,
49561                    bottom,
49562                    fromTop;
49563
49564                if (chart.inverted && chart.renderer.isVML) {
49565                    yCrisp += 1;
49566                }
49567
49568                // Horizontal. We need to first compute the exact right edge, then round
49569                // it and compute the width from there.
49570                if (this.options.crisp) {
49571                    right = Math.round(x + w) + xCrisp;
49572                    x = Math.round(x) + xCrisp;
49573                    w = right - x;
49574                }
49575
49576                // Vertical
49577                bottom = Math.round(y + h) + yCrisp;
49578                fromTop = Math.abs(y) <= 0.5 && bottom > 0.5; // #4504, #4656
49579                y = Math.round(y) + yCrisp;
49580                h = bottom - y;
49581
49582                // Top edges are exceptions
49583                if (fromTop && h) { // #5146
49584                    y -= 1;
49585                    h += 1;
49586                }
49587
49588                return {
49589                    x: x,
49590                    y: y,
49591                    width: w,
49592                    height: h
49593                };
49594            },
49595
49596            /**
49597             * Translate each point to the plot area coordinate system and find shape
49598             * positions
49599             */
49600            translate: function() {
49601                var series = this,
49602                    chart = series.chart,
49603                    options = series.options,
49604                    dense = series.dense =
49605                    series.closestPointRange * series.xAxis.transA < 2,
49606                    borderWidth = series.borderWidth = pick(
49607                        options.borderWidth,
49608                        dense ? 0 : 1 // #3635
49609                    ),
49610                    yAxis = series.yAxis,
49611                    threshold = options.threshold,
49612                    translatedThreshold = series.translatedThreshold =
49613                    yAxis.getThreshold(threshold),
49614                    minPointLength = pick(options.minPointLength, 5),
49615                    metrics = series.getColumnMetrics(),
49616                    pointWidth = metrics.width,
49617                    // postprocessed for border width
49618                    seriesBarW = series.barW =
49619                    Math.max(pointWidth, 1 + 2 * borderWidth),
49620                    pointXOffset = series.pointXOffset = metrics.offset;
49621
49622                if (chart.inverted) {
49623                    translatedThreshold -= 0.5; // #3355
49624                }
49625
49626                // When the pointPadding is 0, we want the columns to be packed tightly,
49627                // so we allow individual columns to have individual sizes. When
49628                // pointPadding is greater, we strive for equal-width columns (#2694).
49629                if (options.pointPadding) {
49630                    seriesBarW = Math.ceil(seriesBarW);
49631                }
49632
49633                Series.prototype.translate.apply(series);
49634
49635                // Record the new values
49636                each(series.points, function(point) {
49637                    var yBottom = pick(point.yBottom, translatedThreshold),
49638                        safeDistance = 999 + Math.abs(yBottom),
49639                        plotY = Math.min(
49640                            Math.max(-safeDistance, point.plotY),
49641                            yAxis.len + safeDistance
49642                        ), // Don't draw too far outside plot area (#1303, #2241, #4264)
49643                        barX = point.plotX + pointXOffset,
49644                        barW = seriesBarW,
49645                        barY = Math.min(plotY, yBottom),
49646                        up,
49647                        barH = Math.max(plotY, yBottom) - barY;
49648
49649                    // Handle options.minPointLength
49650                    if (minPointLength && Math.abs(barH) < minPointLength) {
49651                        barH = minPointLength;
49652                        up = (!yAxis.reversed && !point.negative) ||
49653                            (yAxis.reversed && point.negative);
49654
49655                        // Reverse zeros if there's no positive value in the series
49656                        // in visible range (#7046)
49657                        if (
49658                            point.y === threshold &&
49659                            series.dataMax <= threshold &&
49660                            yAxis.min < threshold // and if there's room for it (#7311)
49661                        ) {
49662                            up = !up;
49663                        }
49664
49665                        // If stacked...
49666                        barY = Math.abs(barY - translatedThreshold) > minPointLength ?
49667                            // ...keep position
49668                            yBottom - minPointLength :
49669                            // #1485, #4051
49670                            translatedThreshold - (up ? minPointLength : 0);
49671                    }
49672
49673                    // Cache for access in polar
49674                    point.barX = barX;
49675                    point.pointWidth = pointWidth;
49676
49677                    // Fix the tooltip on center of grouped columns (#1216, #424, #3648)
49678                    point.tooltipPos = chart.inverted ? [
49679                        yAxis.len + yAxis.pos - chart.plotLeft - plotY,
49680                        series.xAxis.len - barX - barW / 2, barH
49681                    ] : [barX + barW / 2, plotY + yAxis.pos - chart.plotTop, barH];
49682
49683                    // Register shape type and arguments to be used in drawPoints
49684                    point.shapeType = 'rect';
49685                    point.shapeArgs = series.crispCol.apply(
49686                        series,
49687                        point.isNull ?
49688                        // #3169, drilldown from null must have a position to work
49689                        // from #6585, dataLabel should be placed on xAxis, not
49690                        // floating in the middle of the chart
49691                        [barX, translatedThreshold, barW, 0] : [barX, barY, barW, barH]
49692                    );
49693                });
49694
49695            },
49696
49697            getSymbol: noop,
49698
49699            /**
49700             * Use a solid rectangle like the area series types
49701             */
49702            drawLegendSymbol: LegendSymbolMixin.drawRectangle,
49703
49704
49705            /**
49706             * Columns have no graph
49707             */
49708            drawGraph: function() {
49709                this.group[
49710                    this.dense ? 'addClass' : 'removeClass'
49711                ]('highcharts-dense-data');
49712            },
49713
49714
49715            /**
49716             * Get presentational attributes
49717             */
49718            pointAttribs: function(point, state) {
49719                var options = this.options,
49720                    stateOptions,
49721                    ret,
49722                    p2o = this.pointAttrToOptions || {},
49723                    strokeOption = p2o.stroke || 'borderColor',
49724                    strokeWidthOption = p2o['stroke-width'] || 'borderWidth',
49725                    fill = (point && point.color) || this.color,
49726                    stroke = (point && point[strokeOption]) || options[strokeOption] ||
49727                    this.color || fill, // set to fill when borderColor null
49728                    strokeWidth = (point && point[strokeWidthOption]) ||
49729                    options[strokeWidthOption] || this[strokeWidthOption] || 0,
49730                    dashstyle = options.dashStyle,
49731                    zone,
49732                    brightness;
49733
49734                // Handle zone colors
49735                if (point && this.zones.length) {
49736                    zone = point.getZone();
49737                    // When zones are present, don't use point.color (#4267). Changed
49738                    // order (#6527)
49739                    fill = point.options.color || (zone && zone.color) || this.color;
49740                }
49741
49742                // Select or hover states
49743                if (state) {
49744                    stateOptions = merge(
49745                        options.states[state],
49746                        // #6401
49747                        point.options.states && point.options.states[state] || {}
49748                    );
49749                    brightness = stateOptions.brightness;
49750                    fill = stateOptions.color ||
49751                        (
49752                            brightness !== undefined &&
49753                            color(fill).brighten(stateOptions.brightness).get()
49754                        ) ||
49755                        fill;
49756                    stroke = stateOptions[strokeOption] || stroke;
49757                    strokeWidth = stateOptions[strokeWidthOption] || strokeWidth;
49758                    dashstyle = stateOptions.dashStyle || dashstyle;
49759                }
49760
49761                ret = {
49762                    'fill': fill,
49763                    'stroke': stroke,
49764                    'stroke-width': strokeWidth
49765                };
49766
49767                if (dashstyle) {
49768                    ret.dashstyle = dashstyle;
49769                }
49770
49771                return ret;
49772            },
49773
49774
49775            /**
49776             * Draw the columns. For bars, the series.group is rotated, so the same
49777             * coordinates apply for columns and bars. This method is inherited by
49778             * scatter series.
49779             */
49780            drawPoints: function() {
49781                var series = this,
49782                    chart = this.chart,
49783                    options = series.options,
49784                    renderer = chart.renderer,
49785                    animationLimit = options.animationLimit || 250,
49786                    shapeArgs;
49787
49788                // draw the columns
49789                each(series.points, function(point) {
49790                    var plotY = point.plotY,
49791                        graphic = point.graphic;
49792
49793                    if (isNumber(plotY) && point.y !== null) {
49794                        shapeArgs = point.shapeArgs;
49795
49796                        if (graphic) { // update
49797                            graphic[
49798                                chart.pointCount < animationLimit ? 'animate' : 'attr'
49799                            ](
49800                                merge(shapeArgs)
49801                            );
49802
49803                        } else {
49804                            point.graphic = graphic =
49805                                renderer[point.shapeType](shapeArgs)
49806                                .add(point.group || series.group);
49807                        }
49808
49809                        // Border radius is not stylable (#6900)
49810                        if (options.borderRadius) {
49811                            graphic.attr({
49812                                r: options.borderRadius
49813                            });
49814                        }
49815
49816
49817                        // Presentational
49818                        graphic
49819                            .attr(series.pointAttribs(
49820                                point,
49821                                point.selected && 'select'
49822                            ))
49823                            .shadow(
49824                                options.shadow,
49825                                null,
49826                                options.stacking && !options.borderRadius
49827                            );
49828
49829
49830                        graphic.addClass(point.getClassName(), true);
49831
49832
49833                    } else if (graphic) {
49834                        point.graphic = graphic.destroy(); // #1269
49835                    }
49836                });
49837            },
49838
49839            /**
49840             * Animate the column heights one by one from zero
49841             * @param {Boolean} init Whether to initialize the animation or run it
49842             */
49843            animate: function(init) {
49844                var series = this,
49845                    yAxis = this.yAxis,
49846                    options = series.options,
49847                    inverted = this.chart.inverted,
49848                    attr = {},
49849                    translateProp = inverted ? 'translateX' : 'translateY',
49850                    translateStart,
49851                    translatedThreshold;
49852
49853                if (svg) { // VML is too slow anyway
49854                    if (init) {
49855                        attr.scaleY = 0.001;
49856                        translatedThreshold = Math.min(
49857                            yAxis.pos + yAxis.len,
49858                            Math.max(yAxis.pos, yAxis.toPixels(options.threshold))
49859                        );
49860                        if (inverted) {
49861                            attr.translateX = translatedThreshold - yAxis.len;
49862                        } else {
49863                            attr.translateY = translatedThreshold;
49864                        }
49865                        series.group.attr(attr);
49866
49867                    } else { // run the animation
49868                        translateStart = series.group.attr(translateProp);
49869                        series.group.animate({
49870                                scaleY: 1
49871                            },
49872                            extend(animObject(series.options.animation), {
49873                                // Do the scale synchronously to ensure smooth updating
49874                                // (#5030, #7228)
49875                                step: function(val, fx) {
49876
49877                                    attr[translateProp] =
49878                                        translateStart +
49879                                        fx.pos * (yAxis.pos - translateStart);
49880                                    series.group.attr(attr);
49881                                }
49882                            }));
49883
49884                        // delete this function to allow it only once
49885                        series.animate = null;
49886                    }
49887                }
49888            },
49889
49890            /**
49891             * Remove this series from the chart
49892             */
49893            remove: function() {
49894                var series = this,
49895                    chart = series.chart;
49896
49897                // column and bar series affects other series of the same type
49898                // as they are either stacked or grouped
49899                if (chart.hasRendered) {
49900                    each(chart.series, function(otherSeries) {
49901                        if (otherSeries.type === series.type) {
49902                            otherSeries.isDirty = true;
49903                        }
49904                    });
49905                }
49906
49907                Series.prototype.remove.apply(series, arguments);
49908            }
49909        });
49910
49911
49912        /**
49913         * A `column` series. If the [type](#series.column.type) option is
49914         * not specified, it is inherited from [chart.type](#chart.type).
49915         *
49916         * For options that apply to multiple series, it is recommended to add
49917         * them to the [plotOptions.series](#plotOptions.series) options structure.
49918         * To apply to all series of this specific type, apply it to [plotOptions.
49919         * column](#plotOptions.column).
49920         *
49921         * @type {Object}
49922         * @extends series,plotOptions.column
49923         * @excluding dataParser,dataURL,marker
49924         * @product highcharts highstock
49925         * @apioption series.column
49926         */
49927
49928        /**
49929         * An array of data points for the series. For the `column` series type,
49930         * points can be given in the following ways:
49931         *
49932         * 1.  An array of numerical values. In this case, the numerical values
49933         * will be interpreted as `y` options. The `x` values will be automatically
49934         * calculated, either starting at 0 and incremented by 1, or from `pointStart`
49935         * and `pointInterval` given in the series options. If the axis has
49936         * categories, these will be used. Example:
49937         *
49938         *  ```js
49939         *  data: [0, 5, 3, 5]
49940         *  ```
49941         *
49942         * 2.  An array of arrays with 2 values. In this case, the values correspond
49943         * to `x,y`. If the first value is a string, it is applied as the name
49944         * of the point, and the `x` value is inferred.
49945         *
49946         *  ```js
49947         *     data: [
49948         *         [0, 6],
49949         *         [1, 2],
49950         *         [2, 6]
49951         *     ]
49952         *  ```
49953         *
49954         * 3.  An array of objects with named values. The objects are point
49955         * configuration objects as seen below. If the total number of data
49956         * points exceeds the series' [turboThreshold](#series.column.turboThreshold),
49957         * this option is not available.
49958         *
49959         *  ```js
49960         *     data: [{
49961         *         x: 1,
49962         *         y: 9,
49963         *         name: "Point2",
49964         *         color: "#00FF00"
49965         *     }, {
49966         *         x: 1,
49967         *         y: 6,
49968         *         name: "Point1",
49969         *         color: "#FF00FF"
49970         *     }]
49971         *  ```
49972         *
49973         * @type {Array<Object|Array|Number>}
49974         * @extends series.line.data
49975         * @excluding marker
49976         * @sample {highcharts} highcharts/chart/reflow-true/ Numerical values
49977         * @sample {highcharts} highcharts/series/data-array-of-arrays/
49978         *         Arrays of numeric x and y
49979         * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
49980         *         Arrays of datetime x and y
49981         * @sample {highcharts} highcharts/series/data-array-of-name-value/
49982         *         Arrays of point.name and y
49983         * @sample {highcharts} highcharts/series/data-array-of-objects/
49984         *         Config objects
49985         * @product highcharts highstock
49986         * @apioption series.column.data
49987         */
49988
49989
49990    }(Highcharts));
49991    (function(H) {
49992        /**
49993         * (c) 2010-2017 Torstein Honsi
49994         *
49995         * License: www.highcharts.com/license
49996         */
49997
49998        var seriesType = H.seriesType;
49999
50000        /**
50001         * The Bar series class
50002         */
50003        seriesType('bar', 'column', null, {
50004            inverted: true
50005        });
50006        /**
50007         * A bar series is a special type of column series where the columns are
50008         * horizontal.
50009         *
50010         * @sample highcharts/demo/bar-basic/ Bar chart
50011         * @extends {plotOptions.column}
50012         * @product highcharts
50013         * @optionparent plotOptions.bar
50014         */
50015
50016
50017        /**
50018         * A `bar` series. If the [type](#series.bar.type) option is not specified,
50019         * it is inherited from [chart.type](#chart.type).
50020         * 
50021         * For options that apply to multiple series, it is recommended to add
50022         * them to the [plotOptions.series](#plotOptions.series) options structure.
50023         * To apply to all series of this specific type, apply it to [plotOptions.
50024         * bar](#plotOptions.bar).
50025         * 
50026         * @type {Object}
50027         * @extends series,plotOptions.bar
50028         * @excluding dataParser,dataURL
50029         * @product highcharts
50030         * @apioption series.bar
50031         */
50032
50033        /**
50034         * An array of data points for the series. For the `bar` series type,
50035         * points can be given in the following ways:
50036         * 
50037         * 1.  An array of numerical values. In this case, the numerical values
50038         * will be interpreted as `y` options. The `x` values will be automatically
50039         * calculated, either starting at 0 and incremented by 1, or from `pointStart`
50040         * and `pointInterval` given in the series options. If the axis has
50041         * categories, these will be used. Example:
50042         * 
50043         *  ```js
50044         *  data: [0, 5, 3, 5]
50045         *  ```
50046         * 
50047         * 2.  An array of arrays with 2 values. In this case, the values correspond
50048         * to `x,y`. If the first value is a string, it is applied as the name
50049         * of the point, and the `x` value is inferred.
50050         * 
50051         *  ```js
50052         *     data: [
50053         *         [0, 5],
50054         *         [1, 10],
50055         *         [2, 3]
50056         *     ]
50057         *  ```
50058         * 
50059         * 3.  An array of objects with named values. The objects are point
50060         * configuration objects as seen below. If the total number of data
50061         * points exceeds the series' [turboThreshold](#series.bar.turboThreshold),
50062         * this option is not available.
50063         * 
50064         *  ```js
50065         *     data: [{
50066         *         x: 1,
50067         *         y: 1,
50068         *         name: "Point2",
50069         *         color: "#00FF00"
50070         *     }, {
50071         *         x: 1,
50072         *         y: 10,
50073         *         name: "Point1",
50074         *         color: "#FF00FF"
50075         *     }]
50076         *  ```
50077         * 
50078         * @type {Array<Object|Array|Number>}
50079         * @extends series.column.data
50080         * @sample {highcharts} highcharts/chart/reflow-true/ Numerical values
50081         * @sample {highcharts} highcharts/series/data-array-of-arrays/ Arrays of numeric x and y
50082         * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/ Arrays of datetime x and y
50083         * @sample {highcharts} highcharts/series/data-array-of-name-value/ Arrays of point.name and y
50084         * @sample {highcharts} highcharts/series/data-array-of-objects/ Config objects
50085         * @product highcharts
50086         * @apioption series.bar.data
50087         */
50088
50089        /**
50090         * Alignment of the data label relative to the data point.
50091         * 
50092         * @type {String}
50093         * @sample {highcharts} highcharts/plotoptions/bar-datalabels-align-inside-bar/
50094         *         Data labels inside the bar
50095         * @default left
50096         * @product highcharts
50097         * @apioption plotOptions.bar.dataLabels.align
50098         */
50099
50100        /**
50101         * The x position of the data label relative to the data point.
50102         * 
50103         * @type {Number}
50104         * @sample {highcharts} highcharts/plotoptions/bar-datalabels-align-inside-bar/
50105         *         Data labels inside the bar
50106         * @default 5
50107         * @product highcharts
50108         * @apioption plotOptions.bar.dataLabels.x
50109         */
50110
50111    }
50111(Highcharts));
50112    (function(H) {
50113        /**
50114         * (c) 2010-2017 Torstein Honsi
50115         *
50116         * License: www.highcharts.com/license
50117         */
50118        var Series = H.Series,
50119            seriesType = H.seriesType;
50120
50121        /**
50122         * A scatter plot uses cartesian coordinates to display values for two variables
50123         * for a set of data.
50124         *
50125         * @sample {highcharts} highcharts/demo/scatter/ Scatter plot
50126         * 
50127         * @extends {plotOptions.line}
50128         * @product highcharts highstock
50129         * @optionparent plotOptions.scatter
50130         */
50131        seriesType('scatter', 'line', {
50132
50133            /**
50134             * The width of the line connecting the data points.
50135             * 
50136             * @type {Number}
50137             * @sample {highcharts} highcharts/plotoptions/scatter-linewidth-none/
50138             *         0 by default
50139             * @sample {highcharts} highcharts/plotoptions/scatter-linewidth-1/
50140             *         1px
50141             * @default 0
50142             * @product highcharts highstock
50143             */
50144            lineWidth: 0,
50145
50146            findNearestPointBy: 'xy',
50147            marker: {
50148                enabled: true // Overrides auto-enabling in line series (#3647)
50149            },
50150
50151            /**
50152             * Sticky tracking of mouse events. When true, the `mouseOut` event
50153             * on a series isn't triggered until the mouse moves over another series,
50154             * or out of the plot area. When false, the `mouseOut` event on a series
50155             * is triggered when the mouse leaves the area around the series' graph
50156             * or markers. This also implies the tooltip. When `stickyTracking`
50157             * is false and `tooltip.shared` is false, the tooltip will be hidden
50158             * when moving the mouse between series.
50159             * 
50160             * @type {Boolean}
50161             * @default false
50162             * @product highcharts highstock
50163             * @apioption plotOptions.scatter.stickyTracking
50164             */
50165
50166            /**
50167             * A configuration object for the tooltip rendering of each single
50168             * series. Properties are inherited from <a class="internal">#tooltip</a>.
50169             * Overridable properties are `headerFormat`, `pointFormat`, `yDecimals`,
50170             * `xDateFormat`, `yPrefix` and `ySuffix`. Unlike other series, in
50171             * a scatter plot the series.name by default shows in the headerFormat
50172             * and point.x and point.y in the pointFormat.
50173             * 
50174             * @product highcharts highstock
50175             */
50176            tooltip: {
50177
50178                headerFormat: '<span style="color:{point.color}">\u25CF</span> ' +
50179                    '<span style="font-size: 0.85em"> {series.name}</span><br/>',
50180
50181
50182                pointFormat: 'x: <b>{point.x}</b><br/>y: <b>{point.y}</b><br/>'
50183            }
50184
50185            // Prototype members
50186        }, {
50187            sorted: false,
50188            requireSorting: false,
50189            noSharedTooltip: true,
50190            trackerGroups: ['group', 'markerGroup', 'dataLabelsGroup'],
50191            takeOrdinalPosition: false, // #2342
50192            drawGraph: function() {
50193                if (this.options.lineWidth) {
50194                    Series.prototype.drawGraph.call(this);
50195                }
50196            }
50197        });
50198
50199        /**
50200         * A `scatter` series. If the [type](#series.scatter.type) option is
50201         * not specified, it is inherited from [chart.type](#chart.type).
50202         * 
50203         * For options that apply to multiple series, it is recommended to add
50204         * them to the [plotOptions.series](#plotOptions.series) options structure.
50205         * To apply to all series of this specific type, apply it to [plotOptions.
50206         * scatter](#plotOptions.scatter).
50207         * 
50208         * @type {Object}
50209         * @extends series,plotOptions.scatter
50210         * @excluding dataParser,dataURL,stack
50211         * @product highcharts highstock
50212         * @apioption series.scatter
50213         */
50214
50215        /**
50216         * An array of data points for the series. For the `scatter` series
50217         * type, points can be given in the following ways:
50218         * 
50219         * 1.  An array of numerical values. In this case, the numerical values
50220         * will be interpreted as `y` options. The `x` values will be automatically
50221         * calculated, either starting at 0 and incremented by 1, or from `pointStart`
50222         * and `pointInterval` given in the series options. If the axis has
50223         * categories, these will be used. Example:
50224         * 
50225         *  ```js
50226         *  data: [0, 5, 3, 5]
50227         *  ```
50228         * 
50229         * 2.  An array of arrays with 2 values. In this case, the values correspond
50230         * to `x,y`. If the first value is a string, it is applied as the name
50231         * of the point, and the `x` value is inferred.
50232         * 
50233         *  ```js
50234         *     data: [
50235         *         [0, 0],
50236         *         [1, 8],
50237         *         [2, 9]
50238         *     ]
50239         *  ```
50240         * 
50241         * 3.  An array of objects with named values. The objects are point
50242         * configuration objects as seen below. If the total number of data
50243         * points exceeds the series' [turboThreshold](#series.scatter.turboThreshold),
50244         * this option is not available.
50245         * 
50246         *  ```js
50247         *     data: [{
50248         *         x: 1,
50249         *         y: 2,
50250         *         name: "Point2",
50251         *         color: "#00FF00"
50252         *     }, {
50253         *         x: 1,
50254         *         y: 4,
50255         *         name: "Point1",
50256         *         color: "#FF00FF"
50257         *     }]
50258         *  ```
50259         * 
50260         * @type {Array<Object|Array|Number>}
50261         * @extends series.line.data
50262         * @sample {highcharts} highcharts/chart/reflow-true/
50263         *         Numerical values
50264         * @sample {highcharts} highcharts/series/data-array-of-arrays/
50265         *         Arrays of numeric x and y
50266         * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
50267         *         Arrays of datetime x and y
50268         * @sample {highcharts} highcharts/series/data-array-of-name-value/
50269         *         Arrays of point.name and y
50270         * @sample {highcharts} highcharts/series/data-array-of-objects/
50271         *         Config objects
50272         * @product highcharts highstock
50273         * @apioption series.scatter.data
50274         */
50275
50276
50277    }(Highcharts));
50278    (function(H) {
50279        /**
50280         * (c) 2010-2017 Torstein Honsi
50281         *
50282         * License: www.highcharts.com/license
50283         */
50284        var deg2rad = H.deg2rad,
50285            isNumber = H.isNumber,
50286            pick = H.pick,
50287            relativeLength = H.relativeLength;
50288        H.CenteredSeriesMixin = {
50289            /**
50290             * Get the center of the pie based on the size and center options relative to the
50291             * plot area. Borrowed by the polar and gauge series types.
50292             */
50293            getCenter: function() {
50294
50295                var options = this.options,
50296                    chart = this.chart,
50297                    slicingRoom = 2 * (options.slicedOffset || 0),
50298                    handleSlicingRoom,
50299                    plotWidth = chart.plotWidth - 2 * slicingRoom,
50300                    plotHeight = chart.plotHeight - 2 * slicingRoom,
50301                    centerOption = options.center,
50302                    positions = [pick(centerOption[0], '50%'), pick(centerOption[1], '50%'), options.size || '100%', options.innerSize || 0],
50303                    smallestSize = Math.min(plotWidth, plotHeight),
50304                    i,
50305                    value;
50306
50307                for (i = 0; i < 4; ++i) {
50308                    value = positions[i];
50309                    handleSlicingRoom = i < 2 || (i === 2 && /%$/.test(value));
50310
50311                    // i == 0: centerX, relative to width
50312                    // i == 1: centerY, relative to height
50313                    // i == 2: size, relative to smallestSize
50314                    // i == 3: innerSize, relative to size
50315                    positions[i] = relativeLength(value, [plotWidth, plotHeight, smallestSize, positions[2]][i]) +
50316                        (handleSlicingRoom ? slicingRoom : 0);
50317
50318                }
50319                // innerSize cannot be larger than size (#3632)
50320                if (positions[3] > positions[2]) {
50321                    positions[3] = positions[2];
50322                }
50323                return positions;
50324            },
50325            /**
50326             * getStartAndEndRadians - Calculates start and end angles in radians.
50327             * Used in series types such as pie and sunburst.
50328             *
50329             * @param  {Number} start Start angle in degrees.
50330             * @param  {Number} end Start angle in degrees.
50331             * @return {object}
50331 Returns an object containing start and end angles as
50332             * radians.
50333             */
50334            getStartAndEndRadians: function getStartAndEndRadians(start, end) {
50335                var startAngle = isNumber(start) ? start : 0, // must be a number
50336                    endAngle = (
50337                        (
50338                            isNumber(end) && // must be a number
50339                            end > startAngle && // must be larger than the start angle
50340                            // difference must be less than 360 degrees
50341                            (end - startAngle) < 360
50342                        ) ?
50343                        end :
50344                        startAngle + 360
50345                    ),
50346                    correction = -90;
50347                return {
50348                    start: deg2rad * (startAngle + correction),
50349                    end: deg2rad * (endAngle + correction)
50350                };
50351            }
50352        };
50353
50354    }(Highcharts));
50355    (function(H) {
50356        /**
50357         * (c) 2010-2017 Torstein Honsi
50358         *
50359         * License: www.highcharts.com/license
50360         */
50361        var addEvent = H.addEvent,
50362            CenteredSeriesMixin = H.CenteredSeriesMixin,
50363            defined = H.defined,
50364            each = H.each,
50365            extend = H.extend,
50366            getStartAndEndRadians = CenteredSeriesMixin.getStartAndEndRadians,
50367            inArray = H.inArray,
50368            LegendSymbolMixin = H.LegendSymbolMixin,
50369            noop = H.noop,
50370            pick = H.pick,
50371            Point = H.Point,
50372            Series = H.Series,
50373            seriesType = H.seriesType,
50374            seriesTypes = H.seriesTypes,
50375            setAnimation = H.setAnimation;
50376
50377        /**
50378         * The pie series type.
50379         *
50380         * @constructor seriesTypes.pie
50381         * @augments Series
50382         */
50383
50384        /**
50385         * A pie chart is a circular graphic which is divided into slices to illustrate
50386         * numerical proportion.
50387         *
50388         * @sample highcharts/demo/pie-basic/ Pie chart
50389         * 
50390         * @extends {plotOptions.line}
50391         * @excluding animationLimit,boostThreshold,connectEnds,connectNulls,
50392         *          cropThreshold,dashStyle,findNearestPointBy,getExtremesFromAll,
50393         *          lineWidth,marker,negativeColor,pointInterval,pointIntervalUnit,
50394         *          pointPlacement,pointStart,softThreshold,stacking,step,threshold,
50395         *          turboThreshold,zoneAxis,zones
50396         * @product highcharts
50397         * @optionparent plotOptions.pie
50398         */
50399        seriesType('pie', 'line', {
50400
50401            /**
50402             * The center of the pie chart relative to the plot area. Can be percentages
50403             * or pixel values. The default behaviour (as of 3.0) is to center
50404             * the pie so that all slices and data labels are within the plot area.
50405             * As a consequence, the pie may actually jump around in a chart with
50406             * dynamic values, as the data labels move. In that case, the center
50407             * should be explicitly set, for example to `["50%", "50%"]`.
50408             * 
50409             * @type {Array<String|Number>}
50410             * @sample {highcharts} highcharts/plotoptions/pie-center/ Centered at 100, 100
50411             * @default [null, null]
50412             * @product highcharts
50413             */
50414            center: [null, null],
50415
50416            clip: false,
50417
50418            /** @ignore */
50419            colorByPoint: true, // always true for pies
50420
50421            /**
50422             * A series specific or series type specific color set to use instead
50423             * of the global [colors](#colors).
50424             * 
50425             * @type {Array<Color>}
50426             * @sample {highcharts} highcharts/demo/pie-monochrome/ Set default colors for all pies
50427             * @since 3.0
50428             * @product highcharts
50429             * @apioption plotOptions.pie.colors
50430             */
50431
50432            /**
50433             * @extends plotOptions.series.dataLabels
50434             * @excluding align,allowOverlap,staggerLines,step
50435             * @product highcharts
50436             */
50437            dataLabels: {
50438                /**
50439                 * The color of the line connecting the data label to the pie slice.
50440                 * The default color is the same as the point's color.
50441                 * 
50442                 * In styled mode, the connector stroke is given in the
50443                 * `.highcharts-data-label-connector` class.
50444                 * 
50445                 * @type {String}
50446                 * @sample {highcharts} highcharts/plotoptions/pie-datalabels-connectorcolor/ Blue connectors
50447                 * @sample {highcharts} highcharts/css/pie-point/ Styled connectors
50448                 * @default {point.color}
50449                 * @since 2.1
50450                 * @product highcharts
50451                 * @apioption plotOptions.pie.dataLabels.connectorColor
50452                 */
50453
50454                /**
50455                 * The distance from the data label to the connector.
50456                 * 
50457                 * @type {Number}
50458                 * @sample {highcharts} highcharts/plotoptions/pie-datalabels-connectorpadding/ No padding
50459                 * @default 5
50460                 * @since 2.1
50461                 * @product highcharts
50462                 * @apioption plotOptions.pie.dataLabels.connectorPadding
50463                 */
50464
50465                /**
50466                 * The width of the line connecting the data label to the pie slice.
50467                 * 
50468                 * 
50469                 * In styled mode, the connector stroke width is given in the
50470                 * `.highcharts-data-label-connector` class.
50471                 * 
50472                 * @type {Number}
50473                 * @sample {highcharts} highcharts/plotoptions/pie-datalabels-connectorwidth-disabled/ Disable the connector
50474                 * @sample {highcharts} highcharts/css/pie-point/ Styled connectors
50475                 * @default 1
50476                 * @since 2.1
50477                 * @product highcharts
50478                 * @apioption plotOptions.pie.dataLabels.connectorWidth
50479                 */
50480
50481                /**
50482                 * The distance of the data label from the pie's edge. Negative numbers
50483                 * put the data label on top of the pie slices. Connectors are only
50484                 * shown for data labels outside the pie.
50485                 * 
50486                 * @type {Number}
50487                 * @sample {highcharts} highcharts/plotoptions/pie-datalabels-distance/ Data labels on top of the pie
50488                 * @default 30
50489                 * @since 2.1
50490                 * @product highcharts
50491                 */
50492                distance: 30,
50493
50494                /**
50495                 * Enable or disable the data labels.
50496                 * 
50497                 * @type {Boolean}
50498                 * @since 2.1
50499                 * @product highcharts
50500                 */
50501                enabled: true,
50502
50503                formatter: function() { // #2945
50504                    return this.point.isNull ? undefined : this.point.name;
50505                },
50506
50507                /**
50508                 * Whether to render the connector as a soft arc or a line with sharp
50509                 * break.
50510                 * 
50511                 * @type {Number}
50512                 * @sample {highcharts} highcharts/plotoptions/pie-datalabels-softconnector-true/ Soft
50513                 * @sample {highcharts} highcharts/plotoptions/pie-datalabels-softconnector-false/ Non soft
50514                 * @since 2.1.7
50515                 * @product highcharts
50516                 * @apioption plotOptions.pie.dataLabels.softConnector
50517                 */
50518
50519                x: 0
50520                // y: 0
50521            },
50522
50523            /**
50524             * The end angle of the pie in degrees where 0 is top and 90 is right.
50525             * Defaults to `startAngle` plus 360.
50526             * 
50527             * @type {Number}
50528             * @sample {highcharts} highcharts/demo/pie-semi-circle/ Semi-circle donut
50529             * @default null
50530             * @since 1.3.6
50531             * @product highcharts
50532             * @apioption plotOptions.pie.endAngle
50533             */
50534
50535            /**
50536             * Equivalent to [chart.ignoreHiddenSeries](#chart.ignoreHiddenSeries),
50537             * this option tells whether the series shall be redrawn as if the
50538             * hidden point were `null`.
50539             * 
50540             * The default value changed from `false` to `true` with Highcharts
50541             * 3.0.
50542             * 
50543             * @type {Boolean}
50544             * @sample {highcharts} highcharts/plotoptions/pie-ignorehiddenpoint/ True, the hiddden point is ignored
50545             * @default true
50546             * @since 2.3.0
50547             * @product highcharts
50548             */
50549            ignoreHiddenPoint: true,
50550
50551            /**
50552             * The size of the inner diameter for the pie. A size greater than 0
50553             * renders a donut chart. Can be a percentage or pixel value. Percentages
50554             * are relative to the pie size. Pixel values are given as integers.
50555             * 
50556             * 
50557             * Note: in Highcharts < 4.1.2, the percentage was relative to the plot
50558             * area, not the pie size.
50559             * 
50560             * @type {String|Number}
50561             * @sample {highcharts} highcharts/plotoptions/pie-innersize-80px/ 80px inner size
50562             * @sample {highcharts} highcharts/plotoptions/pie-innersize-50percent/ 50% of the plot area
50563             * @sample {highcharts} highcharts/demo/3d-pie-donut/ 3D donut
50564             * @default 0
50565             * @since 2.0
50566             * @product highcharts
50567             * @apioption plotOptions.pie.innerSize
50568             */
50569
50570            /** @ignore */
50571            legendType: 'point',
50572
50573            /**	 @ignore */
50574            marker: null, // point options are specified in the base options
50575
50576            /**
50577             * The minimum size for a pie in response to auto margins. The pie will
50578             * try to shrink to make room for data labels in side the plot area,
50579             *  but only to this size.
50580             * 
50581             * @type {Number}
50582             * @default 80
50583             * @since 3.0
50584             * @product highcharts
50585             * @apioption plotOptions.pie.minSize
50586             */
50587
50588            /**
50589             * The diameter of the pie relative to the plot area. Can be a percentage
50590             * or pixel value. Pixel values are given as integers. The default
50591             * behaviour (as of 3.0) is to scale to the plot area and give room
50592             * for data labels within the plot area. As a consequence, the size
50593             * of the pie may vary when points are updated and data labels more
50594             * around. In that case it is best to set a fixed value, for example
50595             * `"75%"`.
50596             * 
50597             * @type {String|Number}
50598             * @sample {highcharts} highcharts/plotoptions/pie-size/ Smaller pie
50599             * @default  
50600             * @product highcharts
50601             */
50602            size: null,
50603
50604            /**
50605             * Whether to display this particular series or series type in the
50606             * legend. Since 2.1, pies are not shown in the legend by default.
50607             * 
50608             * @type {Boolean}
50609             * @sample {highcharts} highcharts/plotoptions/series-showinlegend/ One series in the legend, one hidden
50610             * @product highcharts
50611             */
50612            showInLegend: false,
50613
50614            /**
50615             * If a point is sliced, moved out from the center, how many pixels
50616             * should it be moved?.
50617             * 
50618             * @type {Number}
50619             * @sample {highcharts} highcharts/plotoptions/pie-slicedoffset-20/ 20px offset
50620             * @default 10
50621             * @product highcharts
50622             */
50623            slicedOffset: 10,
50624
50625            /**
50626             * The start angle of the pie slices in degrees where 0 is top and 90
50627             * right.
50628             * 
50629             * @type {Number}
50630             * @sample {highcharts} highcharts/plotoptions/pie-startangle-90/ Start from right
50631             * @default 0
50632             * @since 2.3.4
50633             * @product highcharts
50634             * @apioption plotOptions.pie.startAngle
50635             */
50636
50637            /**
50638             * Sticky tracking of mouse events. When true, the `mouseOut` event
50639             * on a series isn't triggered until the mouse moves over another series,
50640             * or out of the plot area. When false, the `mouseOut` event on a
50641             * series is triggered when the mouse leaves the area around the series'
50642             * graph or markers. This also implies the tooltip. When `stickyTracking`
50643             * is false and `tooltip.shared` is false, the tooltip will be hidden
50644             * when moving the mouse between series.
50645             * 
50646             * @product highcharts
50647             */
50648            stickyTracking: false,
50649
50650            tooltip: {
50651                followPointer: true
50652            },
50653
50654
50655            /**
50656             * The color of the border surrounding each slice. When `null`, the
50657             * border takes the same color as the slice fill. This can be used
50658             * together with a `borderWidth` to fill drawing gaps created by antialiazing
50659             * artefacts in borderless pies.
50660             * 
50661             * In styled mode, the border stroke is given in the `.highcharts-point` class.
50662             * 
50663             * @type {Color}
50664             * @sample {highcharts} highcharts/plotoptions/pie-bordercolor-black/ Black border
50665             * @default #ffffff
50666             * @product highcharts
50667             */
50668            borderColor: '#ffffff',
50669
50670            /**
50671             * The width of the border surrounding each slice.
50672             * 
50673             * When setting the border width to 0, there may be small gaps between
50674             * the slices due to SVG antialiasing artefacts. To work around this,
50675             * keep the border width at 0.5 or 1, but set the `borderColor` to
50676             * `null` instead.
50677             * 
50678             * In styled mode, the border stroke width is given in the `.highcharts-point` class.
50679             * 
50680             * @type {Number}
50681             * @sample {highcharts} highcharts/plotoptions/pie-borderwidth/ 3px border
50682             * @default 1
50683             * @product highcharts
50684             */
50685            borderWidth: 1,
50686
50687            states: {
50688
50689                /**
50690                 * @extends plotOptions.series.states.hover
50691                 * @product highcharts
50692                 */
50693                hover: {
50694
50695                    /**
50696                     * How much to brighten the point on interaction. Requires the main
50697                     * color to be defined in hex or rgb(a) format.
50698                     * 
50699                     * In styled mode, the hover brightness is by default replaced
50700                     * by a fill-opacity given in the `.highcharts-point-hover` class.
50701                     * 
50702                     * @type {Number}
50703                     * @sample {highcharts} highcharts/plotoptions/pie-states-hover-brightness/ Brightened by 0.5
50704                     * @default 0.1
50705                     * @product highcharts
50706                     */
50707                    brightness: 0.1,
50708
50709                    shadow: false
50710                }
50711            }
50712
50713
50714        }, /** @lends seriesTypes.pie.prototype */ {
50715            isCartesian: false,
50716            requireSorting: false,
50717            directTouch: true,
50718            noSharedTooltip: true,
50719            trackerGroups: ['group', 'dataLabelsGroup'],
50720            axisTypes: [],
50721            pointAttribs: seriesTypes.column.prototype.pointAttribs,
50722            /**
50723             * Animate the pies in
50724             */
50725            animate: function(init) {
50726                var series = this,
50727                    points = series.points,
50728                    startAngleRad = series.startAngleRad;
50729
50730                if (!init) {
50731                    each(points, function(point) {
50732                        var graphic = point.graphic,
50733                            args = point.shapeArgs;
50734
50735                        if (graphic) {
50736                            // start values
50737                            graphic.attr({
50738                                r: point.startR || (series.center[3] / 2), // animate from inner radius (#779)
50739                                start: startAngleRad,
50740                                end: startAngleRad
50741                            });
50742
50743                            // animate
50744                            graphic.animate({
50745                                r: args.r,
50746                                start: args.start,
50747                                end: args.end
50748                            }, series.options.animation);
50749                        }
50750                    });
50751
50752                    // delete this function to allow it only once
50753                    series.animate = null;
50754                }
50755            },
50756
50757            /**
50758             * Recompute total chart sum and update percentages of points.
50759             */
50760            updateTotals: function() {
50761                var i,
50762                    total = 0,
50763                    points = this.points,
50764                    len = points.length,
50765                    point,
50766                    ignoreHiddenPoint = this.options.ignoreHiddenPoint;
50767
50768                // Get the total sum
50769                for (i = 0; i < len; i++) {
50770                    point = points[i];
50771                    total += (ignoreHiddenPoint && !point.visible) ?
50772                        0 :
50773                        point.isNull ? 0 : point.y;
50774                }
50775                this.total = total;
50776
50777                // Set each point's properties
50778                for (i = 0; i < len; i++) {
50779                    point = points[i];
50780                    point.percentage = (total > 0 && (point.visible || !ignoreHiddenPoint)) ? point.y / total * 100 : 0;
50781                    point.total = total;
50782                }
50783            },
50784
50785            /**
50786             * Extend the generatePoints method by adding total and percentage properties to each point
50787             */
50788            generatePoints: function() {
50789                Series.prototype.generatePoints.call(this);
50790                this.updateTotals();
50791            },
50792
50793            /**
50794             * Do translation for pie slices
50795             */
50796            translate: function(positions) {
50797                this.generatePoints();
50798
50799                var series = this,
50800                    cumulative = 0,
50801                    precision = 1000, // issue #172
50802                    options = series.options,
50803                    slicedOffset = options.slicedOffset,
50804                    connectorOffset = slicedOffset + (options.borderWidth || 0),
50805                    finalConnectorOffset,
50806                    start,
50807                    end,
50808                    angle,
50809                    radians = getStartAndEndRadians(options.startAngle, options.endAngle),
50810                    startAngleRad = series.startAngleRad = radians.start,
50811                    endAngleRad = series.endAngleRad = radians.end,
50812                    circ = endAngleRad - startAngleRad, // 2 * Math.PI,
50813                    points = series.points,
50814                    radiusX, // the x component of the radius vector for a given point
50815                    radiusY,
50816                    labelDistance = options.dataLabels.distance,
50817                    ignoreHiddenPoint = options.ignoreHiddenPoint,
50818                    i,
50819                    len = points.length,
50820                    point;
50821
50822                // Get positions - either an integer or a percentage string must be given.
50823                // If positions are passed as a parameter, we're in a recursive loop for adju
50823sting
50824                // space for data labels.
50825                if (!positions) {
50826                    series.center = positions = series.getCenter();
50827                }
50828
50829                // Utility for getting the x value from a given y, used for anticollision
50830                // logic in data labels.
50831                // Added point for using specific points' label distance.
50832                series.getX = function(y, left, point) {
50833                    angle = Math.asin(Math.min((y - positions[1]) / (positions[2] / 2 + point.labelDistance), 1));
50834                    return positions[0] +
50835                        (left ? -1 : 1) *
50836                        (Math.cos(angle) * (positions[2] / 2 + point.labelDistance));
50837                };
50838
50839                // Calculate the geometry for each point
50840                for (i = 0; i < len; i++) {
50841
50842                    point = points[i];
50843
50844                    // Used for distance calculation for specific point.
50845                    point.labelDistance = pick(
50846                        point.options.dataLabels && point.options.dataLabels.distance,
50847                        labelDistance
50848                    );
50849
50850                    // Saved for later dataLabels distance calculation.
50851                    series.maxLabelDistance = Math.max(series.maxLabelDistance || 0, point.labelDistance);
50852
50853                    // set start and end angle
50854                    start = startAngleRad + (cumulative * circ);
50855                    if (!ignoreHiddenPoint || point.visible) {
50856                        cumulative += point.percentage / 100;
50857                    }
50858                    end = startAngleRad + (cumulative * circ);
50859
50860                    // set the shape
50861                    point.shapeType = 'arc';
50862                    point.shapeArgs = {
50863                        x: positions[0],
50864                        y: positions[1],
50865                        r: positions[2] / 2,
50866                        innerR: positions[3] / 2,
50867                        start: Math.round(start * precision) / precision,
50868                        end: Math.round(end * precision) / precision
50869                    };
50870
50871                    // The angle must stay within -90 and 270 (#2645)
50872                    angle = (end + start) / 2;
50873                    if (angle > 1.5 * Math.PI) {
50874                        angle -= 2 * Math.PI;
50875                    } else if (angle < -Math.PI / 2) {
50876                        angle += 2 * Math.PI;
50877                    }
50878
50879                    // Center for the sliced out slice
50880                    point.slicedTranslation = {
50881                        translateX: Math.round(Math.cos(angle) * slicedOffset),
50882                        translateY: Math.round(Math.sin(angle) * slicedOffset)
50883                    };
50884
50885                    // set the anchor point for tooltips
50886                    radiusX = Math.cos(angle) * positions[2] / 2;
50887                    radiusY = Math.sin(angle) * positions[2] / 2;
50888                    point.tooltipPos = [
50889                        positions[0] + radiusX * 0.7,
50890                        positions[1] + radiusY * 0.7
50891                    ];
50892
50893                    point.half = angle < -Math.PI / 2 || angle > Math.PI / 2 ? 1 : 0;
50894                    point.angle = angle;
50895
50896                    // Set the anchor point for data labels. Use point.labelDistance 
50897                    // instead of labelDistance // #1174
50898                    // finalConnectorOffset - not override connectorOffset value.
50899                    finalConnectorOffset = Math.min(connectorOffset, point.labelDistance / 5); // #1678
50900                    point.labelPos = [
50901                        positions[0] + radiusX + Math.cos(angle) * point.labelDistance, // first break of connector
50902                        positions[1] + radiusY + Math.sin(angle) * point.labelDistance, // a/a
50903                        positions[0] + radiusX + Math.cos(angle) * finalConnectorOffset, // second break, right outside pie
50904                        positions[1] + radiusY + Math.sin(angle) * finalConnectorOffset, // a/a
50905                        positions[0] + radiusX, // landing point for connector
50906                        positions[1] + radiusY, // a/a
50907                        point.labelDistance < 0 ? // alignment
50908                        'center' :
50909                        point.half ? 'right' : 'left', // alignment
50910                        angle // center angle
50911                    ];
50912
50913                }
50914            },
50915
50916            drawGraph: null,
50917
50918            /**
50919             * Draw the data points
50920             */
50921            drawPoints: function() {
50922                var series = this,
50923                    chart = series.chart,
50924                    renderer = chart.renderer,
50925                    groupTranslation,
50926                    graphic,
50927                    pointAttr,
50928                    shapeArgs;
50929
50930
50931                var shadow = series.options.shadow;
50932                if (shadow && !series.shadowGroup) {
50933                    series.shadowGroup = renderer.g('shadow')
50934                        .add(series.group);
50935                }
50936
50937
50938                // draw the slices
50939                each(series.points, function(point) {
50940                    graphic = point.graphic;
50941                    if (!point.isNull) {
50942                        shapeArgs = point.shapeArgs;
50943
50944
50945                        // If the point is sliced, use special translation, else use
50946                        // plot area traslation
50947                        groupTranslation = point.getTranslate();
50948
50949
50950                        // Put the shadow behind all points
50951                        var shadowGroup = point.shadowGroup;
50952                        if (shadow && !shadowGroup) {
50953                            shadowGroup = point.shadowGroup = renderer.g('shadow')
50954                                .add(series.shadowGroup);
50955                        }
50956
50957                        if (shadowGroup) {
50958                            shadowGroup.attr(groupTranslation);
50959                        }
50960                        pointAttr = series.pointAttribs(point, point.selected && 'select');
50961
50962
50963                        // Draw the slice
50964                        if (graphic) {
50965                            graphic
50966                                .setRadialReference(series.center)
50967
50968                                .attr(pointAttr)
50969
50970                                .animate(extend(shapeArgs, groupTranslation));
50971                        } else {
50972
50973                            point.graphic = graphic = renderer[point.shapeType](shapeArgs)
50974                                .setRadialReference(series.center)
50975                                .attr(groupTranslation)
50976                                .add(series.group);
50977
50978                            if (!point.visible) {
50979                                graphic.attr({
50980                                    visibility: 'hidden'
50981                                });
50982                            }
50983
50984
50985                            graphic
50986                                .attr(pointAttr)
50987                                .attr({
50988                                    'stroke-linejoin': 'round'
50989                                })
50990                                .shadow(shadow, shadowGroup);
50991
50992                        }
50993
50994                        graphic.addClass(point.getClassName());
50995
50996                    } else if (graphic) {
50997                        point.graphic = graphic.destroy();
50998                    }
50999                });
51000
51001            },
51002
51003
51004            searchPoint: noop,
51005
51006            /**
51007             * Utility for sorting data labels
51008             */
51009            sortByAngle: function(points, sign) {
51010                points.sort(function(a, b) {
51011                    return a.angle !== undefined && (b.angle - a.angle) * sign;
51012                });
51013            },
51014
51015            /**
51016             * Use a simple symbol from LegendSymbolMixin
51017             */
51018            drawLegendSymbol: LegendSymbolMixin.drawRectangle,
51019
51020            /**
51021             * Use the getCenter method from drawLegendSymbol
51022             */
51023            getCenter: CenteredSeriesMixin.getCenter,
51024
51025            /**
51026             * Pies don't have point marker symbols
51027             */
51028            getSymbol: noop
51029
51030
51031            /**
51032             * @constructor seriesTypes.pie.prototype.pointClass
51033             * @extends {Point}
51034             */
51035        }, /** @lends seriesTypes.pie.prototype.pointClass.prototype */ {
51036            /**
51037             * Initiate the pie slice
51038             */
51039            init: function() {
51040
51041                Point.prototype.init.apply(this, arguments);
51042
51043                var point = this,
51044                    toggleSlice;
51045
51046                point.name = pick(point.name, 'Slice');
51047
51048                // add event listener for select
51049                toggleSlice = function(e) {
51050                    point.slice(e.type === 'select');
51051                };
51052                addEvent(point, 'select', toggleSlice);
51053                addEvent(point, 'unselect', toggleSlice);
51054
51055                return point;
51056            },
51057
51058            /**
51059             * Negative points are not valid (#1530, #3623, #5322)
51060             */
51061            isValid: function() {
51062                return H.isNumber(this.y, true) && this.y >= 0;
51063            },
51064
51065            /**
51066             * Toggle the visibility of the pie slice
51067             * @param {Boolean} vis Whether to show the slice or not. If undefined, the
51068             *    visibility is toggled
51069             */
51070            setVisible: function(vis, redraw) {
51071                var point = this,
51072                    series = point.series,
51073                    chart = series.chart,
51074                    ignoreHiddenPoint = series.options.ignoreHiddenPoint;
51075
51076                redraw = pick(redraw, ignoreHiddenPoint);
51077
51078                if (vis !== point.visible) {
51079
51080                    // If called without an argument, toggle visibility
51081                    point.visible = point.options.visible = vis = vis === undefined ? !point.visible : vis;
51082                    series.options.data[inArray(point, series.data)] = point.options; // update userOptions.data
51083
51084                    // Show and hide associated elements. This is performed regardless of redraw or not,
51085                    // because chart.redraw only handles full series.
51086                    each(['graphic', 'dataLabel', 'connector', 'shadowGroup'], function(key) {
51087                        if (point[key]) {
51088                            point[key][vis ? 'show' : 'hide'](true);
51089                        }
51090                    });
51091
51092                    if (point.legendItem) {
51093                        chart.legend.colorizeItem(point, vis);
51094                    }
51095
51096                    // #4170, hide halo after hiding point
51097                    if (!vis && point.state === 'hover') {
51098                        point.setState('');
51099                    }
51100
51101                    // Handle ignore hidden slices
51102                    if (ignoreHiddenPoint) {
51103                        series.isDirty = true;
51104                    }
51105
51106                    if (redraw) {
51107                        chart.redraw();
51108                    }
51109                }
51110            },
51111
51112            /**
51113             * Set or toggle whether the slice is cut out from the pie
51114             * @param {Boolean} sliced When undefined, the slice state is toggled
51115             * @param {Boolean} redraw Whether to redraw the chart. True by default.
51116             */
51117            slice: function(sliced, redraw, animation) {
51118                var point = this,
51119                    series = point.series,
51120                    chart = series.chart;
51121
51122                setAnimation(animation, chart);
51123
51124                // redraw is true by default
51125                redraw = pick(redraw, true);
51126
51127                // if called without an argument, toggle
51128                point.sliced = point.options.sliced = sliced = defined(sliced) ? sliced : !point.sliced;
51129                series.options.data[inArray(point, series.data)] = point.options; // update userOptions.data
51130
51131                point.graphic.animate(this.getTranslate());
51132
51133
51134                if (point.shadowGroup) {
51135                    point.shadowGroup.animate(this.getTranslate());
51136                }
51137
51138            },
51139
51140            getTranslate: function() {
51141                return this.sliced ? this.slicedTranslation : {
51142                    translateX: 0,
51143                    translateY: 0
51144                };
51145            },
51146
51147            haloPath: function(size) {
51148                var shapeArgs = this.shapeArgs;
51149
51150                return this.sliced || !this.visible ? [] :
51151                    this.series.chart.renderer.symbols.arc(
51152                        shapeArgs.x,
51153                        shapeArgs.y,
51154                        shapeArgs.r + size,
51155                        shapeArgs.r + size, {
51156                            innerR: this.shapeArgs.r,
51157                            start: shapeArgs.start,
51158                            end: shapeArgs.end
51159                        }
51160                    );
51161            }
51162        });
51163
51164        /**
51165         * A `pie` series. If the [type](#series.pie.type) option is not specified,
51166         * it is inherited from [chart.type](#chart.type).
51167         * 
51168         * For options that apply to multiple series, it is recommended to add
51169         * them to the [plotOptions.series](#plotOptions.series) options structure.
51170         * To apply to all series of this specific type, apply it to [plotOptions.
51171         * pie](#plotOptions.pie).
51172         * 
51173         * @type {Object}
51174         * @extends series,plotOptions.pie
51175         * @excluding dataParser,dataURL,stack,xAxis,yAxis
51176         * @product highcharts
51177         * @apioption series.pie
51178         */
51179
51180        /**
51181         * An array of data points for the series. For the `pie` series type,
51182         * points can be given in the following ways:
51183         * 
51184         * 1.  An array of numerical values. In this case, the numerical values
51185         * will be interpreted as `y` options. Example:
51186         * 
51187         *  ```js
51188         *  data: [0, 5, 3, 5]
51189         *  ```
51190         * 
51191         * 2.  An array of objects with named values. The objects are point
51192         * configuration objects as seen below. If the total number of data
51193         * points exceeds the series' [turboThreshold](#series.pie.turboThreshold),
51194         * this option is not available.
51195         * 
51196         *  ```js
51197         *     data: [{
51198         *     y: 1,
51199         *     name: "Point2",
51200         *     color: "#00FF00"
51201         * }, {
51202         *     y: 7,
51203         *     name: "Point1",
51204         *     color: "#FF00FF"
51205         * }]</pre>
51206         * 
51207         * @type {Array<Object|Number>}
51208         * @extends series.line.data
51209         * @excluding marker,x
51210         * @sample {highcharts} highcharts/chart/reflow-true/ Numerical values
51211         * @sample {highcharts} highcharts/series/data-array-of-arrays/ Arrays of numeric x and y
51212         * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/ Arrays of datetime x and y
51213         * @sample {highcharts} highcharts/series/data-array-of-name-value/ Arrays of point.name and 
51213y
51214         * @sample {highcharts} highcharts/series/data-array-of-objects/ Config objects
51215         * @product highcharts
51216         * @apioption series.pie.data
51217         */
51218
51219        /**
51220         * The sequential index of the data point in the legend.
51221         * 
51222         * @type {Number}
51223         * @product highcharts
51224         * @apioption series.pie.data.legendIndex
51225         */
51226
51227        /**
51228         * Whether to display a slice offset from the center.
51229         * 
51230         * @type {Boolean}
51231         * @sample {highcharts} highcharts/point/sliced/ One sliced point
51232         * @product highcharts
51233         * @apioption series.pie.data.sliced
51234         */
51235
51236        /**
51237         * Fires when the checkbox next to the point name in the legend is clicked.
51238         * One parameter, event, is passed to the function. The state of the
51239         * checkbox is found by event.checked. The checked item is found by
51240         * event.item. Return false to prevent the default action which is to
51241         * toggle the select state of the series.
51242         * 
51243         * @type {Function}
51244         * @context Point
51245         * @sample {highcharts} highcharts/plotoptions/series-events-checkboxclick/
51246         *         Alert checkbox status
51247         * @since 1.2.0
51248         * @product highcharts
51249         * @apioption plotOptions.pie.events.checkboxClick
51250         */
51251
51252        /**
51253         * Not applicable to pies, as the legend item is per point. See point.
51254         * events.
51255         * 
51256         * @type {Function}
51257         * @since 1.2.0
51258         * @product highcharts
51259         * @apioption plotOptions.pie.events.legendItemClick
51260         */
51261
51262        /**
51263         * Fires when the legend item belonging to the pie point (slice) is
51264         * clicked. The `this` keyword refers to the point itself. One parameter,
51265         * `event`, is passed to the function, containing common event information. The
51266         * default action is to toggle the visibility of the point. This can be
51267         * prevented by calling `event.preventDefault()`.
51268         * 
51269         * @type {Function}
51270         * @sample {highcharts} highcharts/plotoptions/pie-point-events-legenditemclick/
51271         *         Confirm toggle visibility
51272         * @since 1.2.0
51273         * @product highcharts
51274         * @apioption plotOptions.pie.point.events.legendItemClick
51275         */
51276
51277    }(Highcharts));
51278    (function(H) {
51279        /**
51280         * (c) 2010-2017 Torstein Honsi
51281         *
51282         * License: www.highcharts.com/license
51283         */
51284        var addEvent = H.addEvent,
51285            arrayMax = H.arrayMax,
51286            defined = H.defined,
51287            each = H.each,
51288            extend = H.extend,
51289            format = H.format,
51290            map = H.map,
51291            merge = H.merge,
51292            noop = H.noop,
51293            pick = H.pick,
51294            relativeLength = H.relativeLength,
51295            Series = H.Series,
51296            seriesTypes = H.seriesTypes,
51297            stableSort = H.stableSort;
51298
51299        /* eslint max-len: ["warn", 80, 4] */
51300        /**
51301         * General distribution algorithm for distributing labels of differing size
51302         * along a confined length in two dimensions. The algorithm takes an array of
51303         * objects containing a size, a target and a rank. It will place the labels as
51304         * close as possible to their targets, skipping the lowest ranked labels if
51305         * necessary.
51306         */
51307        H.distribute = function(boxes, len) {
51308
51309            var i,
51310                overlapping = true,
51311                origBoxes = boxes, // Original array will be altered with added .pos
51312                restBoxes = [], // The outranked overshoot
51313                box,
51314                target,
51315                total = 0;
51316
51317            function sortByTarget(a, b) {
51318                return a.target - b.target;
51319            }
51320
51321            // If the total size exceeds the len, remove those boxes with the lowest
51322            // rank
51323            i = boxes.length;
51324            while (i--) {
51325                total += boxes[i].size;
51326            }
51327
51328            // Sort by rank, then slice away overshoot
51329            if (total > len) {
51330                stableSort(boxes, function(a, b) {
51331                    return (b.rank || 0) - (a.rank || 0);
51332                });
51333                i = 0;
51334                total = 0;
51335                while (total <= len) {
51336                    total += boxes[i].size;
51337                    i++;
51338                }
51339                restBoxes = boxes.splice(i - 1, boxes.length);
51340            }
51341
51342            // Order by target
51343            stableSort(boxes, sortByTarget);
51344
51345
51346            // So far we have been mutating the original array. Now
51347            // create a copy with target arrays
51348            boxes = map(boxes, function(box) {
51349                return {
51350                    size: box.size,
51351                    targets: [box.target],
51352                    align: pick(box.align, 0.5)
51353                };
51354            });
51355
51356            while (overlapping) {
51357                // Initial positions: target centered in box
51358                i = boxes.length;
51359                while (i--) {
51360                    box = boxes[i];
51361                    // Composite box, average of targets
51362                    target = (
51363                        Math.min.apply(0, box.targets) +
51364                        Math.max.apply(0, box.targets)
51365                    ) / 2;
51366                    box.pos = Math.min(
51367                        Math.max(0, target - box.size * box.align),
51368                        len - box.size
51369                    );
51370                }
51371
51372                // Detect overlap and join boxes
51373                i = boxes.length;
51374                overlapping = false;
51375                while (i--) {
51376                    // Overlap
51377                    if (i > 0 && boxes[i - 1].pos + boxes[i - 1].size > boxes[i].pos) {
51378                        // Add this size to the previous box
51379                        boxes[i - 1].size += boxes[i].size;
51380                        boxes[i - 1].targets = boxes[i - 1]
51381                            .targets
51382                            .concat(boxes[i].targets);
51383                        boxes[i - 1].align = 0.5;
51384
51385                        // Overlapping right, push left
51386                        if (boxes[i - 1].pos + boxes[i - 1].size > len) {
51387                            boxes[i - 1].pos = len - boxes[i - 1].size;
51388                        }
51389                        boxes.splice(i, 1); // Remove this item
51390                        overlapping = true;
51391                    }
51392                }
51393            }
51394
51395            // Now the composite boxes are placed, we need to put the original boxes
51396            // within them
51397            i = 0;
51398            each(boxes, function(box) {
51399                var posInCompositeBox = 0;
51400                each(box.targets, function() {
51401                    origBoxes[i].pos = box.pos + posInCompositeBox;
51402                    posInCompositeBox += origBoxes[i].size;
51403                    i++;
51404                });
51405            });
51406
51407            // Add the rest (hidden) boxes and sort by target
51408            origBoxes.push.apply(origBoxes, restBoxes);
51409            stableSort(origBoxes, sortByTarget);
51410        };
51411
51412
51413        /**
51414         * Draw the data labels
51415         */
51416        Series.prototype.drawDataLabels = function() {
51417            var series = this,
51418                seriesOptions = series.options,
51419                options = seriesOptions.dataLabels,
51420                points = series.points,
51421                pointOptions,
51422                generalOptions,
51423                hasRendered = series.hasRendered || 0,
51424                str,
51425                dataLabelsGroup,
51426                defer = pick(options.defer, !!seriesOptions.animation),
51427                renderer = series.chart.renderer;
51428
51429            /*
51430             * Handle the dataLabels.filter option.
51431             */
51432            function applyFilter(point, options) {
51433                var filter = options.filter,
51434                    op,
51435                    prop,
51436                    val;
51437                if (filter) {
51438                    op = filter.operator;
51439                    prop = point[filter.property];
51440                    val = filter.value;
51441                    if (
51442                        (op === '>' && prop > val) ||
51443                        (op === '<' && prop < val) ||
51444                        (op === '>=' && prop >= val) ||
51445                        (op === '<=' && prop <= val) ||
51446                        (op === '==' && prop == val) || // eslint-disable-line eqeqeq
51447                        (op === '===' && prop === val)
51448                    ) {
51449                        return true;
51450                    }
51451                    return false;
51452                }
51453                return true;
51454            }
51455
51456            if (options.enabled || series._hasPointLabels) {
51457
51458                // Process default alignment of data labels for columns
51459                if (series.dlProcessOptions) {
51460                    series.dlProcessOptions(options);
51461                }
51462
51463                // Create a separate group for the data labels to avoid rotation
51464                dataLabelsGroup = series.plotGroup(
51465                    'dataLabelsGroup',
51466                    'data-labels',
51467                    defer && !hasRendered ? 'hidden' : 'visible', // #5133
51468                    options.zIndex || 6
51469                );
51470
51471                if (defer) {
51472                    dataLabelsGroup.attr({
51473                        opacity: +hasRendered
51474                    }); // #3300
51475                    if (!hasRendered) {
51476                        addEvent(series, 'afterAnimate', function() {
51477                            if (series.visible) { // #2597, #3023, #3024
51478                                dataLabelsGroup.show(true);
51479                            }
51480                            dataLabelsGroup[
51481                                seriesOptions.animation ? 'animate' : 'attr'
51482                            ]({
51483                                opacity: 1
51484                            }, {
51485                                duration: 200
51486                            });
51487                        });
51488                    }
51489                }
51490
51491                // Make the labels for each point
51492                generalOptions = options;
51493                each(points, function(point) {
51494                    var enabled,
51495                        dataLabel = point.dataLabel,
51496                        labelConfig,
51497                        attr,
51498                        rotation,
51499                        connector = point.connector,
51500                        isNew = !dataLabel,
51501                        style,
51502                        formatString;
51503
51504                    // Determine if each data label is enabled
51505                    // @note dataLabelAttribs (like pointAttribs) would eradicate
51506                    // the need for dlOptions, and simplify the section below.
51507                    pointOptions = point.dlOptions || // dlOptions is used in treemaps
51508                        (point.options && point.options.dataLabels);
51509                    enabled = pick(
51510                        pointOptions && pointOptions.enabled,
51511                        generalOptions.enabled
51512                    ) && !point.isNull; // #2282, #4641, #7112
51513
51514                    if (enabled) {
51515                        enabled = applyFilter(point, pointOptions || options) === true;
51516                    }
51517
51518                    if (enabled) {
51519                        // Create individual options structure that can be extended
51520                        // without affecting others
51521                        options = merge(generalOptions, pointOptions);
51522                        labelConfig = point.getLabelConfig();
51523                        formatString = (
51524                            options[point.formatPrefix + 'Format'] ||
51525                            options.format
51526                        );
51527
51528                        str = defined(formatString) ?
51529                            format(formatString, labelConfig) :
51530                            (
51531                                options[point.formatPrefix + 'Formatter'] ||
51532                                options.formatter
51533                            ).call(labelConfig, options);
51534
51535                        style = options.style;
51536                        rotation = options.rotation;
51537
51538                        // Determine the color
51539                        style.color = pick(
51540                            options.color,
51541                            style.color,
51542                            series.color,
51543                            '#000000'
51544                        );
51545                        // Get automated contrast color
51546                        if (style.color === 'contrast') {
51547                            point.contrastColor =
51548                                renderer.getContrast(point.color || series.color);
51549                            style.color = options.inside ||
51550                                pick(point.labelDistance, options.distance) < 0 ||
51551                                !!seriesOptions.stacking ?
51552                                point.contrastColor :
51553                                '#000000';
51554                        }
51555                        if (seriesOptions.cursor) {
51556                            style.cursor = seriesOptions.cursor;
51557                        }
51558
51559
51560                        attr = {
51561
51562                            fill: options.backgroundColor,
51563                            stroke: options.borderColor,
51564                            'stroke-width': options.borderWidth,
51565
51566                            r: options.borderRadius || 0,
51567                            rotation: rotation,
51568                            padding: options.padding,
51569                            zIndex: 1
51570                        };
51571
51572                        // Remove unused attributes (#947)
51573                        H.objectEach(attr, function(val, name) {
51574                            if (val === undefined) {
51575                                delete attr[name];
51576                            }
51577                        });
51578                    }
51579                    // If the point is outside the plot area, destroy it. #678, #820
51580                    if (dataLabel && (!enabled || !defined(str))) {
51581                        point.dataLabel = dataLabel = dataLabel.destroy();
51582                        if (connector) {
51583                            point.connector = connector.destroy();
51584                        }
51585                        // Individual labels are disabled if the are explicitly disabled
51586                        // in the point options, or if they fall outside the plot area.
51587                    } else if (enabled && defined(str)) {
51588                        // create new label
51589                        if (!dataLabel) {
51590                            dataLabel = point.dataLabel = renderer[
51591                                rotation ? 'text' : 'label' // labels don't rotate
51592                            ](
51593                                str,
51594                                0, -9999,
51595                                options.shape,
51596                                null,
51597                                null,
51598                                options.useHTML,
51599                                null,
51600                                'data-label'
51601                            );
51602                            dataLabel.addClass(
51603                                'highcharts-data-label-color-' + point.colorIndex +
51604                                ' ' + (options.className || '') +
51605                                (options.useHTML ? 'highcharts-tracker' : '') // #3398
51606                            );
51607                        } else {
51608                            attr.text = str;
51609                        }
51610                        dataLabel.attr(attr);
51611
51612                        // Styles must be applied before add in order to read text
51613                        // bounding box
51614                        dataLabel.css(style).shadow(options.shadow);
51615
51616
51617                        if (!dataLabel.added) {
51618                            dataLabel.add(dataLabelsGroup);
51619                        }
51620                        // Now the data label is created and placed at 0,0, so we need
51621                        // to align it
51622                        series.alignDataLabel(point, dataLabel, options, null, isNew);
51623                    }
51624                });
51625            }
51626        };
51627
51628        /**
51629         * Align each individual data label
51630         */
51631        Series.prototype.alignDataLabel = function(
51632            point,
51633            dataLabel,
51634            options,
51635            alignTo,
51636            isNew
51637        ) {
51638            var chart = this.chart,
51639                inverted = chart.inverted,
51640                plotX = pick(point.dlBox && point.dlBox.centerX, point.plotX, -9999),
51641                plotY = pick(point.plotY, -9999),
51642                bBox = dataLabel.getBBox(),
51643                fontSize,
51644                baseline,
51645                rotation = options.rotation,
51646                normRotation,
51647                negRotation,
51648                align = options.align,
51649                rotCorr, // rotation correction
51650                // Math.round for rounding errors (#2683), alignTo to allow column
51651                // labels (#2700)
51652                visible =
51653                this.visible &&
51654                (
51655                    point.series.forceDL ||
51656                    chart.isInsidePlot(plotX, Math.round(plotY), inverted) ||
51657                    (
51658                        alignTo && chart.isInsidePlot(
51659                            plotX,
51660                            inverted ?
51661                            alignTo.x + 1 :
51662                            alignTo.y + alignTo.height - 1,
51663                            inverted
51664                        )
51665                    )
51666                ),
51667                alignAttr, // the final position;
51668                justify = pick(options.overflow, 'justify') === 'justify';
51669
51670            if (visible) {
51671
51672
51673                fontSize = options.style.fontSize;
51674
51675
51676                baseline = chart.renderer.fontMetrics(fontSize, dataLabel).b;
51677
51678                // The alignment box is a singular point
51679                alignTo = extend({
51680                    x: inverted ? this.yAxis.len - plotY : plotX,
51681                    y: Math.round(inverted ? this.xAxis.len - plotX : plotY),
51682                    width: 0,
51683                    height: 0
51684                }, alignTo);
51685
51686                // Add the text size for alignment calculation
51687                extend(options, {
51688                    width: bBox.width,
51689                    height: bBox.height
51690                });
51691
51692                // Allow a hook for changing alignment in the last moment, then do the
51693                // alignment
51694                if (rotation) {
51695                    justify = false; // Not supported for rotated text
51696                    rotCorr = chart.renderer.rotCorr(baseline, rotation); // #3723
51697                    alignAttr = {
51698                        x: alignTo.x + options.x + alignTo.width / 2 + rotCorr.x,
51699                        y: (
51700                            alignTo.y +
51701                            options.y + {
51702                                top: 0,
51703                                middle: 0.5,
51704                                bottom: 1
51705                            }[options.verticalAlign] *
51706                            alignTo.height
51707                        )
51708                    };
51709                    dataLabel[isNew ? 'attr' : 'animate'](alignAttr)
51710                        .attr({ // #3003
51711                            align: align
51712                        });
51713
51714                    // Compensate for the rotated label sticking out on the sides
51715                    normRotation = (rotation + 720) % 360;
51716                    negRotation = normRotation > 180 && normRotation < 360;
51717
51718                    if (align === 'left') {
51719                        alignAttr.y -= negRotation ? bBox.height : 0;
51720                    } else if (align === 'center') {
51721                        alignAttr.x -= bBox.width / 2;
51722                        alignAttr.y -= bBox.height / 2;
51723                    } else if (align === 'right') {
51724                        alignAttr.x -= bBox.width;
51725                        alignAttr.y -= negRotation ? 0 : bBox.height;
51726                    }
51727
51728
51729                } else {
51730                    dataLabel.align(options, null, alignTo);
51731                    alignAttr = dataLabel.alignAttr;
51732                }
51733
51734                // Handle justify or crop
51735                if (justify) {
51736                    point.isLabelJustified = this.justifyDataLabel(
51737                        dataLabel,
51738                        options,
51739                        alignAttr,
51740                        bBox,
51741                        alignTo,
51742                        isNew
51743                    );
51744
51745                    // Now check that the data label is within the plot area
51746                } else if (pick(options.crop, true)) {
51747                    visible =
51748                        chart.isInsidePlot(
51749                            alignAttr.x,
51750                            alignAttr.y
51751                        ) &&
51752                        chart.isInsidePlot(
51753                            alignAttr.x + bBox.width,
51754                            alignAttr.y + bBox.height
51755                        );
51756                }
51757
51758                // When we're using a shape, make it possible with a connector or an
51759                // arrow pointing to thie point
51760                if (options.shape && !rotation) {
51761                    dataLabel[isNew ? 'attr' : 'animate']({
51762                        anchorX: inverted ? chart.plotWidth - point.plotY : point.plotX,
51763                        anchorY: inverted ? chart.plotHeight - point.plotX : point.plotY
51764                    });
51765                }
51766            }
51767
51768            // Show or hide based on the final aligned position
51769            if (!visible) {
51770                dataLabel.attr({
51771                    y: -9999
51772                });
51773                dataLabel.placed = false; // don't animate back in
51774            }
51775
51776        };
51777
51778        /**
51779         * If data labels fall partly outside the plot area, align them back in, in a
51780         * way that doesn't hide the point.
51781         */
51782        Series.prototype.justifyDataLabel = function(
51783            dataLabel,
51784            options,
51785            alignAttr,
51786            bBox,
51787            alignTo,
51788            isNew
51789        ) {
51790            var chart = this.chart,
51791                align = options.align,
51792                verticalAlign = options.verticalAlign,
51793                off,
51794                justified,
51795                padding = dataLabel.box ? 0 : (dataLabel.padding || 0);
51796
51797            // Off left
51798            off = alignAttr.x + padding;
51799            if (off < 0) {
51800                if (align === 'right') {
51801                    options.align = 'left';
51802                } else {
51803                    options.x = -off;
51804                }
51805                justified = true;
51806            }
51807
51808            // Off right
51809            off = alignAttr.x + bBox.width - padding;
51810            if (off > chart.plotWidth) {
51811                if (align === 'left') {
51812                    options.align = 'right';
51813                } else {
51814                    options.x = chart.plotWidth - off;
51815                }
51816                justified = true;
51817            }
51818
51819            // Off top
51820            off = alignAttr.y + padding;
51821            if (off < 0) {
51822                if (verticalAlign === 'bottom') {
51823                    options.verticalAlign = 'top';
51824                } else {
51825                    options.y = -off;
51826                }
51827                justified = true;
51828            }
51829
51830            // Off bottom
51831            off = alignAttr.y + bBox.height - padding;
51832            if (off > chart.plotHeight) {
51833                if (verticalAlign === 'top') {
51834                    options.verticalAlign = 'bottom';
51835                } else {
51836                    options.y = chart.plotHeight - off;
51837                }
51838                justified = true;
51839            }
51840
51841            if (justified) {
51842                dataLabel.placed = !isNew;
51843                dataLabel.align(options, null, alignTo);
51844            }
51845
51846            return justified;
51847        };
51848
51849        /**
51850         * Override the base drawDataLabels method by pie specific functionality
51851         */
51852        if (seriesTypes.pie) {
51853            seriesTypes.pie.prototype.drawDataLabels = function() {
51854                var series = this,
51855                    data = series.data,
51856                    point,
51857                    chart = series.chart,
51858                    options = series.options.dataLabels,
51859                    connectorPadding = pick(options.connectorPadding, 10),
51860                    connectorWidth = pick(options.connectorWidth, 1),
51861                    plotWidth = chart.plotWidth,
51862                    plotHeight = chart.plotHeight,
51863                    connector,
51864                    seriesCenter = series.center,
51865                    radius = seriesCenter[2] / 2,
51866                    centerY = seriesCenter[1],
51867                    dataLabel,
51868                    dataLabelWidth,
51869                    labelPos,
51870                    labelHeight,
51871                    // divide the points into right and left halves for anti collision
51872                    halves = [
51873                        [], // right
51874                        [] // left
51875                    ],
51876                    x,
51877                    y,
51878                    visibility,
51879                    j,
51880                    overflow = [0, 0, 0, 0]; // top, right, bottom, left
51881
51882                // get out if not enabled
51883                if (!series.visible || (!options.enabled && !series._hasPointLabels)) {
51884                    return;
51885                }
51886
51887                // Reset all labels that have been shortened
51888                each(data, function(point) {
51889                    if (point.dataLabel && point.visible && point.dataLabel.shortened) {
51890                        point.dataLabel
51891                            .attr({
51892                                width: 'auto'
51893                            }).css({
51894                                width: 'auto',
51895                                textOverflow: 'clip'
51896                            });
51897                        point.dataLabel.shortened = false;
51898                    }
51899                });
51900
51901
51902                // run parent method
51903                Series.prototype.drawDataLabels.apply(series);
51904
51905                each(data, function(point) {
51906                    if (point.dataLabel && point.visible) { // #407, #2510
51907
51908                        // Arrange points for detection collision
51909                        halves[point.half].push(point);
51910
51911                        // Reset positions (#4905)
51912                        point.dataLabel._pos = null;
51913                    }
51914                });
51915
51916                /* Loop over the points in each half, starting from the top and bottom
51917                 * of the pie to detect overlapping labels.
51918                 */
51919                each(halves, function(points, i) {
51920
51921                    var top,
51922                        bottom,
51923                        length = points.length,
51924                        positions = [],
51925                        naturalY,
51926                        sideOverflow,
51927                        positionsIndex, // Point index in positions array.
51928                        size;
51929
51930                    if (!length) {
51931                        return;
51932                    }
51933
51934                    // Sort by angle
51935                    series.sortByAngle(points, i - 0.5);
51936                    // Only do anti-collision when we have dataLabels outside the pie 
51937                    // and have connectors. (#856)
51938                    if (series.maxLabelDistance > 0) {
51939                        top = Math.max(
51940                            0,
51941                            centerY - radius - series.maxLabelDistance
51942                        );
51943                        bottom = Math.min(
51944                            centerY + radius + series.maxLabelDistance,
51945                            chart.plotHeight
51946                        );
51947                        each(points, function(point) {
51948                            // check if specific points' label is outside the pie
51949                            if (point.labelDistance > 0 && point.dataLabel) {
51950                                // point.top depends on point.labelDistance value
51951                                // Used for calculation of y value in getX method 
51952                                point.top = Math.max(
51953                                    0,
51954                                    centerY - radius - point.labelDistance
51955                                );
51956                                point.bottom = Math.min(
51957                                    centerY + radius + point.labelDistance,
51958                                    chart.plotHeight
51959                                );
51960                                size = point.dataLabel.getBBox().height || 21;
51961
51962                                // point.positionsIndex is needed for getting index of 
51963                                // parameter related to specific point inside positions 
51964                                // array - not every point is in positions array.
51965                                point.positionsIndex = positions.push({
51966                                    target: point.labelPos[1] - point.top + size / 2,
51967                                    size: size,
51968                                    rank: point.y
51969                                }) - 1;
51970                            }
51971                        });
51972                        H.distribute(positions, bottom + size - top);
51973                    }
51974
51975                    // Now the used slots are sorted, fill them up sequentially
51976                    for (j = 0; j < length; j++) {
51977
51978                        point = points[j];
51979                        positionsIndex = point.positionsIndex;
51980                        labelPos = point.labelPos;
51981                        dataLabel = point.dataLabel;
51982                        visibility = point.visible === false ? 'hidden' : 'inherit';
51983                        naturalY = labelPos[1];
51984                        y = naturalY;
51985
51986                        if (positions && defined(positions[positionsIndex])) {
51987                            if (positions[positionsIndex].pos === undefined) {
51988                                visibility = 'hidden';
51989                            } else {
51990                                labelHeight = positions[positionsIndex].size;
51991                                y = point.top + positions[positionsIndex].pos;
51992                            }
51993                        }
51994
51995                        // It is needed to delete point.positionIndex for 
51996                        // dynamically added points etc.
51997
51998                        delete point.positionIndex;
51999
52000                        // get the x - use the natural x position for labels near the 
52001                        // top and bottom, to prevent the top and botton slice
52002                        // connectors from touching each other on either side
52003                        if (options.justify) {
52004                            x = seriesCenter[0] +
52005                                (i ? -1 : 1) * (radius + point.labelDistance);
52006                        } else {
52007                            x = series.getX(
52008                                y < point.top + 2 || y > point.bottom - 2 ?
52009                                naturalY :
52010                                y,
52011                                i,
52012                                point
52013                            );
52014                        }
52015
52016
52017                        // Record the placement and visibility
52018                        dataLabel._attr = {
52019                            visibility: visibility,
52020                            align: labelPos[6]
52021                        };
52022                        dataLabel._pos = {
52023                            x: (
52024                                x +
52025                                options.x +
52026                                ({
52027                                    left: connectorPadding,
52028                                    right: -connectorPadding
52029                                }[labelPos[6]] || 0)
52030                            ),
52031
52032                            // 10 is for the baseline (label vs text)
52033                            y: y + options.y - 10
52034                        };
52035                        labelPos.x = x;
52036                        labelPos.y = y;
52037
52038
52039                        // Detect overflowing data labels
52040                        if (pick(options.crop, true)) {
52041                            dataLabelWidth = dataLabel.getBBox().width;
52042
52043                            sideOverflow = null;
52044                            // Overflow left
52045                            if (x - dataLabelWidth < connectorPadding) {
52046                                sideOverflow = Math.round(
52047                                    dataLabelWidth - x + connectorPadding
52048                                );
52049                                overflow[3] = Math.max(sideOverflow, overflow[3]);
52050
52051                                // Overflow right
52052                            } else if (
52053                                x + dataLabelWidth >
52054                                plotWidth - connectorPadding
52055                            ) {
52056                                sideOverflow = Math.round(
52057                                    x + dataLabelWidth - plotWidth + connectorPadding
52058                                );
52059                                overflow[1] = Math.max(sideOverflow, overflow[1]);
52060                            }
52061
52062                            // Overflow top
52063                            if (y - labelHeight / 2 < 0) {
52064                                overflow[0] = Math.max(
52065                                    Math.round(-y + labelHeight / 2),
52066                                    overflow[0]
52067                                );
52068
52069                                // Overflow left
52070                            } else if (y + labelHeight / 2 > plotHeight) {
52071                                overflow[2] = Math.max(
52072                                    Math.round(y + labelHeight / 2 - plotHeight),
52073                                    overflow[2]
52074                                );
52075                            }
52076                            dataLabel.sideOverflow = sideOverflow;
52077                        }
52078                    } // for each point
52079                }); // for each half
52080
52081                // Do not apply the final placement and draw the connectors until we
52082                // have verified that labels are not spilling over.
52083                if (
52084                    arrayMax(overflow) === 0 ||
52085                    this.verifyDataLabelOverflow(overflow)
52086                ) {
52087
52088                    // Place the labels in the final position
52089                    this.placeDataLabels();
52090
52091                    // Draw the connectors
52092                    if (connectorWidth) {
52093                        each(this.points, function(point) {
52094                            var isNew;
52095
52096                            connector = point.connector;
52097                            dataLabel = point.dataLabel;
52098
52099                            if (
52100                                dataLabel &&
52101                                dataLabel._pos &&
52102                                point.visible &&
52103                                point.labelDistance > 0
52104                            ) {
52105                                visibility = dataLabel._attr.visibility;
52106
52107                                isNew = !connector;
52108
52109                                if (isNew) {
52110                                    point.connector = connector = chart.renderer.path()
52111                                        .addClass('highcharts-data-label-connector ' +
52112                                            ' highcharts-color-' + point.colorIndex)
52113                                        .add(series.dataLabelsGroup);
52114
52115
52116                                    connector.attr({
52117                                        'stroke-width': connectorWidth,
52118                                        'stroke': (
52119                                            options.connectorColor ||
52120                                            point.color ||
52121                                            '#666666'
52122                                        )
52123                                    });
52124
52125                                }
52126                                connector[isNew ? 'attr' : 'animate']({
52127                                    d: series.connectorPath(point.labelPos)
52128                                });
52129                                connector.attr('visibility', visibility);
52130
52131                            } else if (connector) {
52132                                point.connector = connector.destroy();
52133                            }
52134                        });
52135                    }
52136                }
52137            };
52138
52139            /**
52140             * Extendable method for getting the path of the connector between the data
52141             * label and the pie slice.
52142             */
52143            seriesTypes.pie.prototype.connectorPath = function(labelPos) {
52144                var x = labelPos.x,
52145                    y = labelPos.y;
52146                return pick(this.options.dataLabels.softConnector, true) ? [
52147                    'M',
52148                    // end of the string at the label
52149                    x + (labelPos[6] === 'left' ? 5 : -5), y,
52150                    'C',
52151                    x, y, // first break, next to the label
52152                    2 * labelPos[2] - labelPos[4], 2 * labelPos[3] - labelPos[5],
52153                    labelPos[2], labelPos[3], // second break
52154                    'L',
52155                    labelPos[4], labelPos[5] // base
52156                ] : [
52157                    'M',
52158                    // end of the string at the label
52159                    x + (labelPos[6] === 'left' ? 5 : -5), y,
52160                    'L',
52161                    labelPos[2], labelPos[3], // second break
52162                    'L',
52163                    labelPos[4], labelPos[5] // base
52164                ];
52165            };
52166
52167            /**
52168             * Perform the final placement of the data labels after we have verified
52169             * that they fall within the plot area.
52170             */
52171            seriesTypes.pie.prototype.placeDataLabels = function() {
52172                each(this.points, function(point) {
52173                    var dataLabel = point.dataLabel,
52174                        _pos;
52175                    if (dataLabel && point.visible) {
52176                        _pos = dataLabel._pos;
52177                        if (_pos) {
52178
52179                            // Shorten data labels with ellipsis if they still overflow
52180                            // after the pie has reached minSize (#223).
52181                            if (dataLabel.sideOverflow) {
52182                                dataLabel._attr.width =
52183                                    dataLabel.getBBox().width - dataLabel.sideOverflow;
52184                                dataLabel.css({
52185                                    width: dataLabel._attr.width + 'px',
52186                                    textOverflow: 'ellipsis'
52187                                });
52188                                dataLabel.shortened = true;
52189                            }
52190
52191                            dataLabel.attr(dataLabel._attr);
52192                            dataLabel[dataLabel.moved ? 'animate' : 'attr'](_pos);
52193                            dataLabel.moved = true;
52194                        } else if (dataLabel) {
52195                            dataLabel.attr({
52196                                y: -9999
52197                            });
52198                        }
52199                    }
52200                }, this);
52201            };
52202
52203            seriesTypes.pie.prototype.alignDataLabel = noop;
52204
52205            /**
52206             * Verify whether the data labels are allowed to draw, or we should run more
52207             * translation and data label positioning to keep them inside the plot area.
52208             * Returns true when data labels are ready to draw.
52209             */
52210            seriesTypes.pie.prototype.verifyDataLabelOverflow = function(overflow) {
52211
52212                var center = this.center,
52213                    options = this.options,
52214                    centerOption = options.center,
52215                    minSize = options.minSize || 80,
52216                    newSize = minSize,
52217                    // If a size is set, return true and don't try to shrink the pie
52218                    // to fit the labels.
52219                    ret = options.size !== null;
52220
52221                if (!ret) {
52222                    // Handle horizontal size and center
52223                    if (centerOption[0] !== null) { // Fixed center
52224                        newSize = Math.max(center[2] -
52225                            Math.max(overflow[1], overflow[3]), minSize);
52226
52227                    } else { // Auto center
52228                        newSize = Math.max(
52229                            // horizontal overflow
52230                            center[2] - overflow[1] - overflow[3],
52231                            minSize
52232                        );
52233                        // horizontal center
52234                        center[0] += (overflow[3] - overflow[1]) / 2;
52235                    }
52236
52237                    // Handle vertical size and center
52238                    if (centerOption[1] !== null) { // Fixed center
52239                        newSize = Math.max(Math.min(newSize, center[2] -
52240                            Math.max(overflow[0], overflow[2])), minSize);
52241
52242                    } else { // Auto center
52243                        newSize = Math.max(
52244                            Math.min(
52245                                newSize,
52246                                // vertical overflow
52247                                center[2] - overflow[0] - overflow[2]
52248                            ),
52249                            minSize
52250                        );
52251                        // vertical center
52252                        center[1] += (overflow[0] - overflow[2]) / 2;
52253                    }
52254
52255                    // If the size must be decreased, we need to run translate and
52256                    // drawDataLabels again
52257                    if (newSize < center[2]) {
52258                        center[2] = newSize;
52259                        center[3] = Math.min( // #3632
52260                            relativeLength(options.innerSize || 0, newSize),
52261                            newSize
52262                        );
52263                        this.translate(center);
52264
52265                        if (this.drawDataLabels) {
52266                            this.drawDataLabels();
52267                        }
52268                        // Else, return true to indicate that the pie and its labels is
52269                        // within the plot area
52270                    } else {
52271                        ret = true;
52272                    }
52273                }
52274                return ret;
52275            };
52276        }
52277
52278        if (seriesTypes.column) {
52279
52280            /**
52281             * Override the basic data label alignment by adjusting for the position of
52282             * the column
52283             */
52284            seriesTypes.column.prototype.alignDataLabel = function(
52285                point,
52286                dataLabel,
52287                options,
52288                alignTo,
52289                isNew
52290            ) {
52291                var inverted = this.chart.inverted,
52292                    series = point.series,
52293                    // data label box for alignment
52294                    dlBox = point.dlBox || point.shapeArgs,
52295                    below = pick(
52296                        point.below, // range series
52297                        point.plotY > pick(this.translatedThreshold, series.yAxis.len)
52298                    ),
52299                    // draw it inside the box?
52300                    inside = pick(options.inside, !!this.options.stacking),
52301                    overshoot;
52302
52303                // Align to the column itself, or the top of it
52304                if (dlBox) { // Area range uses this method but not alignTo
52305                    alignTo = merge(dlBox);
52306
52307                    if (alignTo.y < 0) {
52308                        alignTo.height += alignTo.y;
52309                        alignTo.y = 0;
52310                    }
52311                    overshoot = alignTo.y + alignTo.height - series.yAxis.len;
52312                    if (overshoot > 0) {
52313                        alignTo.height -= overshoot;
52314                    }
52315
52316                    if (inverted) {
52317                        alignTo = {
52318                            x: series.yAxis.len - alignTo.y - alignTo.height,
52319                            y: series.xAxis.len - alignTo.x - alignTo.width,
52320                            width: alignTo.height,
52321                            height: alignTo.width
52322                        };
52323                    }
52324
52325                    // Compute the alignment box
52326                    if (!inside) {
52327                        if (inverted) {
52328                            alignTo.x += below ? 0 : alignTo.width;
52329                            alignTo.width = 0;
52330                        } else {
52331                            alignTo.y += below ? alignTo.height : 0;
52332                            alignTo.height = 0;
52333                        }
52334                    }
52335                }
52336
52337
52338                // When alignment is undefined (typically columns and bars), display the
52339                // individual point below or above the point depending on the threshold
52340                options.align = pick(
52341                    options.align, !inverted || inside ? 'center' : below ? 'right' : 'left'
52342                );
52343                options.verticalAlign = pick(
52344                    options.verticalAlign,
52345                    inverted || inside ? 'middle' : below ? 'top' : 'bottom'
52346                );
52347
52348                // Call the parent method
52349                Series.prototype.alignDataLabel.call(
52350                    this,
52351                    point,
52352                    dataLabel,
52353                    options,
52354                    alignTo,
52355                    isNew
52356                );
52357
52358                // If label was justified and we have contrast, set it:
52359                if (point.isLabelJustified && point.contrastColor) {
52360                    point.dataLabel.css({
52361                        color: point.contrastColor
52362                    });
52363                }
52364            };
52365        }
52366
52367    }
52367(Highcharts));
52368    (function(H) {
52369        /**
52370         * (c) 2009-2017 Torstein Honsi
52371         *
52372         * License: www.highcharts.com/license
52373         */
52374        /**
52375         * Highcharts module to hide overlapping data labels. This module is included in
52376         * Highcharts.
52377         */
52378        var Chart = H.Chart,
52379            each = H.each,
52380            objectEach = H.objectEach,
52381            pick = H.pick,
52382            addEvent = H.addEvent;
52383
52384        // Collect potensial overlapping data labels. Stack labels probably don't need
52385        // to be considered because they are usually accompanied by data labels that lie
52386        // inside the columns.
52387        addEvent(Chart.prototype, 'render', function collectAndHide() {
52388            var labels = [];
52389
52390            // Consider external label collectors
52391            each(this.labelCollectors || [], function(collector) {
52392                labels = labels.concat(collector());
52393            });
52394
52395            each(this.yAxis || [], function(yAxis) {
52396                if (
52397                    yAxis.options.stackLabels &&
52398                    !yAxis.options.stackLabels.allowOverlap
52399                ) {
52400                    objectEach(yAxis.stacks, function(stack) {
52401                        objectEach(stack, function(stackItem) {
52402                            labels.push(stackItem.label);
52403                        });
52404                    });
52405                }
52406            });
52407
52408            each(this.series || [], function(series) {
52409                var dlOptions = series.options.dataLabels,
52410                    // Range series have two collections
52411                    collections = series.dataLabelCollections || ['dataLabel'];
52412
52413                if (
52414                    (dlOptions.enabled || series._hasPointLabels) &&
52415                    !dlOptions.allowOverlap &&
52416                    series.visible
52417                ) { // #3866
52418                    each(collections, function(coll) {
52419                        each(series.points, function(point) {
52420                            if (point[coll]) {
52421                                point[coll].labelrank = pick(
52422                                    point.labelrank,
52423                                    point.shapeArgs && point.shapeArgs.height
52424                                ); // #4118
52425                                labels.push(point[coll]);
52426                            }
52427                        });
52428                    });
52429                }
52430            });
52431            this.hideOverlappingLabels(labels);
52432        });
52433
52434        /**
52435         * Hide overlapping labels. Labels are moved and faded in and out on zoom to
52436         * provide a smooth visual imression.
52437         */
52438        Chart.prototype.hideOverlappingLabels = function(labels) {
52439
52440            var len = labels.length,
52441                label,
52442                i,
52443                j,
52444                label1,
52445                label2,
52446                isIntersecting,
52447                pos1,
52448                pos2,
52449                parent1,
52450                parent2,
52451                padding,
52452                bBox,
52453                intersectRect = function(x1, y1, w1, h1, x2, y2, w2, h2) {
52454                    return !(
52455                        x2 > x1 + w1 ||
52456                        x2 + w2 < x1 ||
52457                        y2 > y1 + h1 ||
52458                        y2 + h2 < y1
52459                    );
52460                };
52461
52462            for (i = 0; i < len; i++) {
52463                label = labels[i];
52464                if (label) {
52465
52466                    // Mark with initial opacity
52467                    label.oldOpacity = label.opacity;
52468                    label.newOpacity = 1;
52469
52470                    // Get width and height if pure text nodes (stack labels)
52471                    if (!label.width) {
52472                        bBox = label.getBBox();
52473                        label.width = bBox.width;
52474                        label.height = bBox.height;
52475                    }
52476                }
52477            }
52478
52479            // Prevent a situation in a gradually rising slope, that each label will
52480            // hide the previous one because the previous one always has lower rank.
52481            labels.sort(function(a, b) {
52482                return (b.labelrank || 0) - (a.labelrank || 0);
52483            });
52484
52485            // Detect overlapping labels
52486            for (i = 0; i < len; i++) {
52487                label1 = labels[i];
52488
52489                for (j = i + 1; j < len; ++j) {
52490                    label2 = labels[j];
52491                    if (
52492                        label1 && label2 &&
52493                        label1 !== label2 && // #6465, polar chart with connectEnds
52494                        label1.placed && label2.placed &&
52495                        label1.newOpacity !== 0 && label2.newOpacity !== 0
52496                    ) {
52497                        pos1 = label1.alignAttr;
52498                        pos2 = label2.alignAttr;
52499                        // Different panes have different positions
52500                        parent1 = label1.parentGroup;
52501                        parent2 = label2.parentGroup;
52502                        // Substract the padding if no background or border (#4333)
52503                        padding = 2 * (label1.box ? 0 : (label1.padding || 0));
52504                        isIntersecting = intersectRect(
52505                            pos1.x + parent1.translateX,
52506                            pos1.y + parent1.translateY,
52507                            label1.width - padding,
52508                            label1.height - padding,
52509                            pos2.x + parent2.translateX,
52510                            pos2.y + parent2.translateY,
52511                            label2.width - padding,
52512                            label2.height - padding
52513                        );
52514
52515                        if (isIntersecting) {
52516                            (label1.labelrank < label2.labelrank ? label1 : label2)
52517                            .newOpacity = 0;
52518                        }
52519                    }
52520                }
52521            }
52522
52523            // Hide or show
52524            each(labels, function(label) {
52525                var complete,
52526                    newOpacity;
52527
52528                if (label) {
52529                    newOpacity = label.newOpacity;
52530
52531                    if (label.oldOpacity !== newOpacity && label.placed) {
52532
52533                        // Make sure the label is completely hidden to avoid catching
52534                        // clicks (#4362)
52535                        if (newOpacity) {
52536                            label.show(true);
52537                        } else {
52538                            complete = function() {
52539                                label.hide();
52540                            };
52541                        }
52542
52543                        // Animate or set the opacity					
52544                        label.alignAttr.opacity = newOpacity;
52545                        label[label.isOld ? 'animate' : 'attr'](
52546                            label.alignAttr,
52547                            null,
52548                            complete
52549                        );
52550
52551                    }
52552                    label.isOld = true;
52553                }
52554            });
52555        };
52556
52557    }(Highcharts));
52558    (function(H) {
52559        /**
52560         * (c) 2010-2017 Torstein Honsi
52561         *
52562         * License: www.highcharts.com/license
52563         */
52564        var addEvent = H.addEvent,
52565            Chart = H.Chart,
52566            createElement = H.createElement,
52567            css = H.css,
52568            defaultOptions = H.defaultOptions,
52569            defaultPlotOptions = H.defaultPlotOptions,
52570            each = H.each,
52571            extend = H.extend,
52572            fireEvent = H.fireEvent,
52573            hasTouch = H.hasTouch,
52574            inArray = H.inArray,
52575            isObject = H.isObject,
52576            Legend = H.Legend,
52577            merge = H.merge,
52578            pick = H.pick,
52579            Point = H.Point,
52580            Series = H.Series,
52581            seriesTypes = H.seriesTypes,
52582            svg = H.svg,
52583            TrackerMixin;
52584
52585        /**
52586         * TrackerMixin for points and graphs.
52587         */
52588        TrackerMixin = H.TrackerMixin = {
52589
52590            /**
52591             * Draw the tracker for a point.
52592             */
52593            drawTrackerPoint: function() {
52594                var series = this,
52595                    chart = series.chart,
52596                    pointer = chart.pointer,
52597                    onMouseOver = function(e) {
52598                        var point = pointer.getPointFromEvent(e);
52599                        // undefined on graph in scatterchart
52600                        if (point !== undefined) {
52601                            pointer.isDirectTouch = true;
52602                            point.onMouseOver(e);
52603                        }
52604                    };
52605
52606                // Add reference to the point
52607                each(series.points, function(point) {
52608                    if (point.graphic) {
52609                        point.graphic.element.point = point;
52610                    }
52611                    if (point.dataLabel) {
52612                        if (point.dataLabel.div) {
52613                            point.dataLabel.div.point = point;
52614                        } else {
52615                            point.dataLabel.element.point = point;
52616                        }
52617                    }
52618                });
52619
52620                // Add the event listeners, we need to do this only once
52621                if (!series._hasTracking) {
52622                    each(series.trackerGroups, function(key) {
52623                        if (series[key]) { // we don't always have dataLabelsGroup
52624                            series[key]
52625                                .addClass('highcharts-tracker')
52626                                .on('mouseover', onMouseOver)
52627                                .on('mouseout', function(e) {
52628                                    pointer.onTrackerMouseOut(e);
52629                                });
52630                            if (hasTouch) {
52631                                series[key].on('touchstart', onMouseOver);
52632                            }
52633
52634
52635                            if (series.options.cursor) {
52636                                series[key]
52637                                    .css(css)
52638                                    .css({
52639                                        cursor: series.options.cursor
52640                                    });
52641                            }
52642
52643                        }
52644                    });
52645                    series._hasTracking = true;
52646                }
52647            },
52648
52649            /**
52650             * Draw the tracker object that sits above all data labels and markers to
52651             * track mouse events on the graph or points. For the line type charts
52652             * the tracker uses the same graphPath, but with a greater stroke width
52653             * for better control.
52654             */
52655            drawTrackerGraph: function() {
52656                var series = this,
52657                    options = series.options,
52658                    trackByArea = options.trackByArea,
52659                    trackerPath = [].concat(trackByArea ? series.areaPath : series.graphPath),
52660                    trackerPathLength = trackerPath.length,
52661                    chart = series.chart,
52662                    pointer = chart.pointer,
52663                    renderer = chart.renderer,
52664                    snap = chart.options.tooltip.snap,
52665                    tracker = series.tracker,
52666                    i,
52667                    onMouseOver = function() {
52668                        if (chart.hoverSeries !== series) {
52669                            series.onMouseOver();
52670                        }
52671                    },
52672                    /*
52673                     * Empirical lowest possible opacities for TRACKER_FILL for an element to stay invisible but clickable
52674                     * IE6: 0.002
52675                     * IE7: 0.002
52676                     * IE8: 0.002
52677                     * IE9: 0.00000000001 (unlimited)
52678                     * IE10: 0.0001 (exporting only)
52679                     * FF: 0.00000000001 (unlimited)
52680                     * Chrome: 0.000001
52681                     * Safari: 0.000001
52682                     * Opera: 0.00000000001 (unlimited)
52683                     */
52684                    TRACKER_FILL = 'rgba(192,192,192,' + (svg ? 0.0001 : 0.002) + ')';
52685
52686                // Extend end points. A better way would be to use round linecaps,
52687                // but those are not clickable in VML.
52688                if (trackerPathLength && !trackByArea) {
52689                    i = trackerPathLength + 1;
52690                    while (i--) {
52691                        if (trackerPath[i] === 'M') { // extend left side
52692                            trackerPath.splice(i + 1, 0, trackerPath[i + 1] - snap, trackerPath[i + 2], 'L');
52693                        }
52694                        if ((i && trackerPath[i] === 'M') || i === trackerPathLength) { // extend right side
52695                            trackerPath.splice(i, 0, 'L', trackerPath[i - 2] + snap, trackerPath[i - 1]);
52696                        }
52697                    }
52698                }
52699
52700                // draw the tracker
52701                if (tracker) {
52702                    tracker.attr({
52703                        d: trackerPath
52704                    });
52705                } else if (series.graph) { // create
52706
52707                    series.tracker = renderer.path(trackerPath)
52708                        .attr({
52709                            'stroke-linejoin': 'round', // #1225
52710                            visibility: series.visible ? 'visible' : 'hidden',
52711                            stroke: TRACKER_FILL,
52712                            fill: trackByArea ? TRACKER_FILL : 'none',
52713                            'stroke-width': series.graph.strokeWidth() + (trackByArea ? 0 : 2 * snap),
52714                            zIndex: 2
52715                        })
52716                        .add(series.group);
52717
52718                    // The tracker is added to the series group, which is clipped, but is covered
52719                    // by the marker group. So the marker group also needs to capture events.
52720                    each([series.tracker, series.markerGroup], function(tracker) {
52721                        tracker.addClass('highcharts-tracker')
52722                            .on('mouseover', onMouseOver)
52723                            .on('mouseout', function(e) {
52724                                pointer.onTrackerMouseOut(e);
52725                            });
52726
52727
52728                        if (options.cursor) {
52729                            tracker.css({
52730                                cursor: options.cursor
52731                            });
52732                        }
52733
52734
52735                        if (hasTouch) {
52736                            tracker.on('touchstart', onMouseOver);
52737                        }
52738                    });
52739                }
52740            }
52741        };
52742        /* End TrackerMixin */
52743
52744
52745        /**
52746         * Add tracking event listener to the series group, so the point graphics
52747         * themselves act as trackers
52748         */
52749
52750        if (seriesTypes.column) {
52751            seriesTypes.column.prototype.drawTracker = TrackerMixin.drawTrackerPoint;
52752        }
52753
52754        if (seriesTypes.pie) {
52755            seriesTypes.pie.prototype.drawTracker = TrackerMixin.drawTrackerPoint;
52756        }
52757
52758        if (seriesTypes.scatter) {
52759            seriesTypes.scatter.prototype.drawTracker = TrackerMixin.drawTrackerPoint;
52760        }
52761
52762        /*
52763         * Extend Legend for item events
52764         */
52765        extend(Legend.prototype, {
52766
52767            setItemEvents: function(item, legendItem, useHTML) {
52768                var legend = this,
52769                    boxWrapper = legend.chart.renderer.boxWrapper,
52770                    activeClass = 'highcharts-legend-' + (item.series ? 'point' : 'series') + '-active';
52771
52772                // Set the events on the item group, or in case of useHTML, the item itself (#1249)
52773                (useHTML ? legendItem : item.legendGroup).on('mouseover', function() {
52774                        item.setState('hover');
52775
52776                        // A CSS class to dim or hide other than the hovered series
52777                        boxWrapper.addClass(activeClass);
52778
52779
52780                        legendItem.css(legend.options.itemHoverStyle);
52781
52782                    })
52783                    .on('mouseout', function() {
52784
52785                        legendItem.css(merge(item.visible ? legend.itemStyle : legend.itemHiddenStyle));
52786
52787
52788                        // A CSS class to dim or hide other than the hovered series
52789                        boxWrapper.removeClass(activeClass);
52790
52791                        item.setState();
52792                    })
52793                    .on('click', function(event) {
52794                        var strLegendItemClick = 'legendItemClick',
52795                            fnLegendItemClick = function() {
52796                                if (item.setVisible) {
52797                                    item.setVisible();
52798                                }
52799                            };
52800
52801                        // Pass over the click/touch event. #4.
52802                        event = {
52803                            browserEvent: event
52804                        };
52805
52806                        // click the name or symbol
52807                        if (item.firePointEvent) { // point
52808                            item.firePointEvent(strLegendItemClick, event, fnLegendItemClick);
52809                        } else {
52810                            fireEvent(item, strLegendItemClick, event, fnLegendItemClick);
52811                        }
52812                    });
52813            },
52814
52815            createCheckboxForItem: function(item) {
52816                var legend = this;
52817
52818                item.checkbox = createElement('input', {
52819                    type: 'checkbox',
52820                    checked: item.selected,
52821                    defaultChecked: item.selected // required by IE7
52822                }, legend.options.itemCheckboxStyle, legend.chart.container);
52823
52824                addEvent(item.checkbox, 'click', function(event) {
52825                    var target = event.target;
52826                    fireEvent(
52827                        item.series || item,
52828                        'checkboxClick', { // #3712
52829                            checked: target.checked,
52830                            item: item
52831                        },
52832                        function() {
52833                            item.select();
52834                        }
52835                    );
52836                });
52837            }
52838        });
52839
52840
52841
52842        // Add pointer cursor to legend itemstyle in defaultOptions
52843        defaultOptions.legend.itemStyle.cursor = 'pointer';
52844
52845
52846
52847        /*
52848         * Extend the Chart object with interaction
52849         */
52850
52851        extend(Chart.prototype, /** @lends Chart.prototype */ {
52852            /**
52853             * Display the zoom button.
52854             *
52855             * @private
52856             */
52857            showResetZoom: function() {
52858                var chart = this,
52859                    lang = defaultOptions.lang,
52860                    btnOptions = chart.options.chart.resetZoomButton,
52861                    theme = btnOptions.theme,
52862                    states = theme.states,
52863                    alignTo = btnOptions.relativeTo === 'chart' ? null : 'plotBox';
52864
52865                function zoomOut() {
52866                    chart.zoomOut();
52867                }
52868
52869                this.resetZoomButton = chart.renderer.button(lang.resetZoom, null, null, zoomOut, theme, states && states.hover)
52870                    .attr({
52871                        align: btnOptions.position.align,
52872                        title: lang.resetZoomTitle
52873                    })
52874                    .addClass('highcharts-reset-zoom')
52875                    .add()
52876                    .align(btnOptions.position, false, alignTo);
52877
52878            },
52879
52880            /**
52881             * Zoom out to 1:1.
52882             *
52883             * @private
52884             */
52885            zoomOut: function() {
52886                var chart = this;
52887                fireEvent(chart, 'selection', {
52888                    resetSelection: true
52889                }, function() {
52890                    chart.zoom();
52891                });
52892            },
52893
52894            /**
52895             * Zoom into a given portion of the chart given by axis coordinates.
52896             * @param {Object} event
52897             *
52898             * @private
52899             */
52900            zoom: function(event) {
52901                var chart = this,
52902                    hasZoomed,
52903                    pointer = chart.pointer,
52904                    displayButton = false,
52905                    resetZoomButton;
52906
52907                // If zoom is called with no arguments, reset the axes
52908                if (!event || event.resetSelection) {
52909                    each(chart.axes, function(axis) {
52910                        hasZoomed = axis.zoom();
52911                    });
52912                    pointer.initiated = false; // #6804
52913
52914                } else { // else, zoom in on all axes
52915                    each(event.xAxis.concat(event.yAxis), function(axisData) {
52916                        var axis = axisData.axis,
52917                            isXAxis = axis.isXAxis;
52918
52919                        // don't zoom more than minRange
52920                        if (pointer[isXAxis ? 'zoomX' : 'zoomY']) {
52921                            hasZoomed = axis.zoom(axisData.min, axisData.max);
52922                            if (axis.displayBtn) {
52923                                displayButton = true;
52924                            }
52925                        }
52926                    });
52927                }
52928
52929                // Show or hide the Reset zoom button
52930                resetZoomButton = chart.resetZoomButton;
52931                if (displayButton && !resetZoomButton) {
52932                    chart.showResetZoom();
52933                } else if (!displayButton && isObject(resetZoomButton)) {
52934                    chart.resetZoomButton = resetZoomButton.destroy();
52935                }
52936
52937
52938                // Redraw
52939                if (hasZoomed) {
52940                    chart.redraw(
52941                        pick(chart.options.chart.animation, event && event.animation, chart.pointCount < 100) // animation
52942                    );
52943                }
52944            },
52945
52946            /**
52947             * Pan the chart by dragging the mouse across the pane. This function is
52948             * called on mouse move, and the distance to pan is computed from chartX
52949             * compared to the first chartX position in the dragging operation.
52950             *
52951             * @private
52952             */
52953            pan: function(e, panning) {
52954
52955                var chart = this,
52956                    hoverPoints = chart.hoverPoints,
52957                    doRedraw;
52958
52959                // remove active points for shared tooltip
52960                if (hoverPoints) {
52961                    each(hoverPoints, function(point) {
52962                        point.setState();
52963                    });
52964                }
52965
52966                each(panning === 'xy' ? [1, 0] : [1], function(isX) { // xy is used in maps
52967                    var axis = chart[isX ? 'xAxis' : 'yAxis'][0],
52968                        horiz = axis.horiz,
52969                        mousePos = e[horiz ? 'chartX' : 'chartY'],
52970                        mouseDown = horiz ? 'mouseDownX' : 'mouseDownY',
52971                        startPos = chart[mouseDown],
52972                        halfPointRange = (axis.pointRange || 0) / 2,
52973                        extremes = axis.getExtremes(),
52974                        panMin = axis.toValue(startPos - mousePos, true) +
52975                        halfPointRange,
52976                        panMax = axis.toValue(startPos + axis.len - mousePos, true) -
52977                        halfPointRange,
52978                        flipped = panMax < panMin,
52979                        newMin = flipped ? panMax : panMin,
52980                        newMax = flipped ? panMin : panMax,
52981                        paddedMin = Math.min(
52982                            extremes.dataMin,
52983                            axis.toValue(
52984                                axis.toPixels(extremes.min) - axis.minPixelPadding
52985                            )
52986                        ),
52987                        paddedMax = Math.max(
52988                            extremes.dataMax,
52989                            axis.toValue(
52990                                axis.toPixels(extremes.max) + axis.minPixelPadding
52991                            )
52992                        ),
52993                        spill;
52994
52995                    // If the new range spills over, either to the min or max, adjust
52996                    // the new range.
52997                    spill = paddedMin - newMin;
52998                    if (spill > 0) {
52999                        newMax += spill;
53000                        newMin = paddedMin;
53001                    }
53002                    spill = newMax - paddedMax;
53003                    if (spill > 0) {
53004                        newMax = paddedMax;
53005                        newMin -= spill;
53006                    }
53007
53008                    // Set new extremes if they are actually new
53009                    if (axis.series.length && newMin !== extremes.min && newMax !== extremes.max) {
53010                        axis.setExtremes(
53011                            newMin,
53012                            newMax,
53013                            false,
53014                            false, {
53015                                trigger: 'pan'
53016                            }
53017                        );
53018                        doRedraw = true;
53019                    }
53020
53021                    chart[mouseDown] = mousePos; // set new reference for next run
53022                });
53023
53024                if (doRedraw) {
53025                    chart.redraw(false);
53026                }
53027                css(chart.container, {
53028                    cursor: 'move'
53029                });
53030            }
53031        });
53032
53033        /*
53034         * Extend the Point object with interaction
53035         */
53036        extend(Point.prototype, /** @lends Highcharts.Point.prototype */ {
53037            /**
53038             * Toggle the selection status of a point.
53039             * @param  {Boolean} [selected]
53040             *         When `true`, the point is selected. When `false`, the point is
53041             *         unselected. When `null` or `undefined`, the selection state is
53042             *         toggled.
53043             * @param  {Boolean} [accumulate=false]
53044             *         When `true`, the selection is added to other selected points.
53045             *         When `false`, other selected points are deselected. Internally in
53046             *         Highcharts, when {@link http://api.highcharts.com/highcharts/plotOptions.series.allowPointSelect|allowPointSelect}
53047             *         is `true`, selected points are accumulated on Control, Shift or
53048             *         Cmd clicking the point.
53049             *
53050             * @see    Highcharts.Chart#getSelectedPoints
53051             *
53052             * @sample highcharts/members/point-select/
53053             *         Select a point from a button
53054             * @sample highcharts/chart/events-selection-points/
53055             *         Select a range of points through a drag selection
53056             * @sample maps/series/data-id/
53057             *         Select a point in Highmaps
53058             */
53059            select: function(selected, accumulate) {
53060                var point = this,
53061                    series = point.series,
53062                    chart = series.chart;
53063
53064                selected = pick(selected, !point.selected);
53065
53066                // fire the event with the default handler
53067                point.firePointEvent(selected ? 'select' : 'unselect', {
53068                    accumulate: accumulate
53069                }, function() {
53070
53071                    /**
53072                     * Whether the point is selected or not. 
53073                     * @see Point#select
53074                     * @see Chart#getSelectedPoints
53075                     * @memberof Point
53076                     * @name selected
53077                     * @type {Boolean}
53078                     */
53079                    point.selected = point.options.selected = selected;
53080                    series.options.data[inArray(point, series.data)] = point.options;
53081
53082                    point.setState(selected && 'select');
53083
53084                    // unselect all other points unless Ctrl or Cmd + click
53085                    if (!accumulate) {
53086                        each(chart.getSelectedPoints(), function(loopPoint) {
53087                            if (loopPoint.selected && loopPoint !== point) {
53088                                loopPoint.selected = loopPoint.options.selected = false;
53089                                series.options.data[inArray(loopPoint, series.data)] = loopPoint.options;
53090                                loopPoint.setState('');
53091                                loopPoint.firePointEvent('unselect');
53092                            }
53093                        });
53094                    }
53095                });
53096            },
53097
53098            /**
53099             * Runs on mouse over the point. Called internally from mouse and touch
53100             * events.
53101             * 
53102             * @param {Object} e The event arguments
53103             */
53104            onMouseOver: function(e) {
53105                var point = this,
53106                    series = point.series,
53107                    chart = series.chart,
53108                    pointer = chart.pointer;
53109                e = e ?
53110                    pointer.normalize(e) :
53111                    // In cases where onMouseOver is called directly without an event
53112                    pointer.getChartCoordinatesFromPoint(point, chart.inverted);
53113                pointer.runPointActions(e, point);
53114            },
53115
53116            /**
53117             * Runs on mouse out from the point. Called internally from mouse and touch
53118             * events.
53119             */
53120            onMouseOut: function() {
53121                var point = this,
53122                    chart = point.series.chart;
53123                point.firePointEvent('mouseOut');
53124                each(chart.hoverPoints || [], function(p) {
53125                    p.setState();
53126                });
53127                chart.hoverPoints = chart.hoverPoint = null;
53128            },
53129
53130            /**
53131             * Import events from the series' and point's options. Only do it on
53132             * demand, to save processing time on hovering.
53133             *
53134             * @private
53135             */
53136            importEvents: function() {
53137                if (!this.hasImportedEvents) {
53138                    var point = this,
53139                        options = merge(point.series.options.point, point.options),
53140                        events = options.events;
53141
53142                    point.events = events;
53143
53144                    H.objectEach(events, function(event, eventType) {
53145                        addEvent(point, eventType, event);
53146                    });
53147                    this.hasImportedEvents = true;
53148
53149                }
53150            },
53151
53152            /**
53153             * Set the point's state.
53154             * @param  {String} [state]
53155             *         The new state, can be one of `''` (an empty string), `hover` or
53156             *         `select`.
53157             */
53158            setState: function(state, move) {
53159                var point = this,
53160                    plotX = Math.floor(point.plotX), // #4586
53161                    plotY = point.plotY,
53162                    series = point.series,
53163                    stateOptions = series.options.states[state] || {},
53164                    markerOptions = defaultPlotOptions[series.type].marker &&
53165                    series.options.marker,
53166                    normalDisabled = markerOptions && markerOptions.enabled === false,
53167                    markerStateOptions = (markerOptions && markerOptions.states &&
53168                        markerOptions.states[state]) || {},
53169                    stateDisabled = markerStateOptions.enabled === false,
53170                    stateMarkerGraphic = series.stateMarkerGraphic,
53171                    pointMarker = point.marker || {},
53172                    chart = series.chart,
53173                    halo = series.halo,
53174                    haloOptions,
53175                    markerAttribs,
53176                    hasMarkers = markerOptions && series.markerAttribs,
53177                    newSymbol;
53178
53179                state = state || ''; // empty string
53180
53181                if (
53182                    // already has this state
53183                    (state === point.state && !move) ||
53184
53185                    // selected points don't respond to hover
53186                    (point.selected && state !== 'select') ||
53187
53188                    // series' state options is disabled
53189                    (stateOptions.enabled === false) ||
53190
53191                    // general point marker's state options is disabled
53192                    (state && (
53193                        stateDisabled ||
53194                        (normalDisabled && markerStateOptions.enabled === false)
53195                    )) ||
53196
53197                    // individual point marker's state options is disabled
53198                    (
53199                        state &&
53200                        pointMarker.states &&
53201                        pointMarker.states[state] &&
53202                        pointMarker.states[state].enabled === false
53203                    ) // #1610
53204
53205                ) {
53206                    return;
53207                }
53208
53209                if (hasMarkers) {
53210                    markerAttribs = series.markerAttribs(point, state);
53211                }
53212
53213                // Apply hover styles to the existing point
53214                if (point.graphic) {
53215
53216                    if (point.state) {
53217                        point.graphic.removeClass('highcharts-point-' + point.state);
53218                    }
53219                    if (state) {
53220                        point.graphic.addClass('highcharts-point-' + state);
53221                    }
53222
53223
53224                    point.graphic.animate(
53225                        series.pointAttribs(point, state),
53226                        pick(
53227                            chart.options.chart.animation,
53228                            stateOptions.animation
53229                        )
53230                    );
53231
53232
53233                    if (markerAttribs) {
53234                        point.graphic.animate(
53235                            markerAttribs,
53236                            pick(
53237                                chart.options.chart.animation, // Turn off globally
53238                                markerStateOptions.animation,
53239                                markerOptions.animation
53240                            )
53241                        );
53242                    }
53243
53244                    // Zooming in from a range with no markers to a range with markers
53245                    if (stateMarkerGraphic) {
53246                        stateMarkerGraphic.hide();
53247                    }
53248                } else {
53249                    // if a graphic is not applied to each point in the normal state, create a shared
53250                    // graphic for the hover state
53251                    if (state && markerStateOptions) {
53252                        newSymbol = pointMarker.symbol || series.symbol;
53253
53254                        // If the point has another symbol than the previous one, throw away the
53255                        // state marker graphic and force a new one (#1459)
53256                        if (stateMarkerGraphic && stateMarkerGraphic.currentSymbol !== newSymbol) {
53257                            stateMarkerGraphic = stateMarkerGraphic.destroy();
53258                        }
53259
53260                        // Add a new state marker graphic
53261                        if (!stateMarkerGraphic) {
53262                            if (newSymbol) {
53263                                series.stateMarkerGraphic = stateMarkerGraphic = chart.renderer.symbol(
53264                                        newSymbol,
53265                                        markerAttribs.x,
53266                                        markerAttribs.y,
53267                                        markerAttribs.width,
53268                                        markerAttribs.height
53269                                    )
53270                                    .add(series.markerGroup);
53271                                stateMarkerGraphic.currentSymbol = newSymbol;
53272                            }
53273
53274                            // Move the existing graphic
53275                        } else {
53276                            stateMarkerGraphic[move ? 'animate' : 'attr']({ // #1054
53277                                x: markerAttribs.x,
53278                                y: markerAttribs.y
53279                            });
53280                        }
53281
53282                        if (stateMarkerGraphic) {
53283                            stateMarkerGraphic.attr(series.pointAttribs(point, state));
53284                        }
53285
53286                    }
53287
53288                    if (stateMarkerGraphic) {
53289                        stateMarkerGraphic[state && chart.isInsidePlot(plotX, plotY, chart.inverted) ? 'show' : 'hide'](); // #2450
53290                        stateMarkerGraphic.element.point = point;
53290 // #4310
53291                    }
53292                }
53293
53294                // Show me your halo
53295                haloOptions = stateOptions.halo;
53296                if (haloOptions && haloOptions.size) {
53297                    if (!halo) {
53298                        series.halo = halo = chart.renderer.path()
53299                            // #5818, #5903, #6705
53300                            .add((point.graphic || stateMarkerGraphic).parentGroup);
53301                    }
53302                    halo[move ? 'animate' : 'attr']({
53303                        d: point.haloPath(haloOptions.size)
53304                    });
53305                    halo.attr({
53306                        'class': 'highcharts-halo highcharts-color-' +
53307                            pick(point.colorIndex, series.colorIndex)
53308                    });
53309                    halo.point = point; // #6055
53310
53311
53312                    halo.attr(extend({
53313                        'fill': point.color || series.color,
53314                        'fill-opacity': haloOptions.opacity,
53315                        'zIndex': -1 // #4929, IE8 added halo above everything
53316                    }, haloOptions.attributes));
53317
53318
53319                } else if (halo && halo.point && halo.point.haloPath) {
53320                    // Animate back to 0 on the current halo point (#6055)
53321                    halo.animate({
53322                        d: halo.point.haloPath(0)
53323                    });
53324                }
53325
53326                point.state = state;
53327            },
53328
53329            /**
53330             * Get the path definition for the halo, which is usually a shadow-like
53331             * circle around the currently hovered point.
53332             * @param  {Number} size
53333             *         The radius of the circular halo.
53334             * @return {Array} The path definition
53335             */
53336            haloPath: function(size) {
53337                var series = this.series,
53338                    chart = series.chart;
53339
53340                return chart.renderer.symbols.circle(
53341                    Math.floor(this.plotX) - size,
53342                    this.plotY - size,
53343                    size * 2,
53344                    size * 2
53345                );
53346            }
53347        });
53348
53349        /*
53350         * Extend the Series object with interaction
53351         */
53352
53353        extend(Series.prototype, /** @lends Highcharts.Series.prototype */ {
53354            /**
53355             * Runs on mouse over the series graphical items.
53356             */
53357            onMouseOver: function() {
53358                var series = this,
53359                    chart = series.chart,
53360                    hoverSeries = chart.hoverSeries;
53361
53362                // set normal state to previous series
53363                if (hoverSeries && hoverSeries !== series) {
53364                    hoverSeries.onMouseOut();
53365                }
53366
53367                // trigger the event, but to save processing time,
53368                // only if defined
53369                if (series.options.events.mouseOver) {
53370                    fireEvent(series, 'mouseOver');
53371                }
53372
53373                // hover this
53374                series.setState('hover');
53375                chart.hoverSeries = series;
53376            },
53377
53378            /**
53379             * Runs on mouse out of the series graphical items.
53380             */
53381            onMouseOut: function() {
53382                // trigger the event only if listeners exist
53383                var series = this,
53384                    options = series.options,
53385                    chart = series.chart,
53386                    tooltip = chart.tooltip,
53387                    hoverPoint = chart.hoverPoint;
53388
53389                chart.hoverSeries = null; // #182, set to null before the mouseOut event fires
53390
53391                // trigger mouse out on the point, which must be in this series
53392                if (hoverPoint) {
53393                    hoverPoint.onMouseOut();
53394                }
53395
53396                // fire the mouse out event
53397                if (series && options.events.mouseOut) {
53398                    fireEvent(series, 'mouseOut');
53399                }
53400
53401
53402                // hide the tooltip
53403                if (tooltip && !series.stickyTracking && (!tooltip.shared || series.noSharedTooltip)) {
53404                    tooltip.hide();
53405                }
53406
53407                // set normal state
53408                series.setState();
53409            },
53410
53411            /**
53412             * Set the state of the series. Called internally on mouse interaction and
53413             * select operations, but it can also be called directly to visually
53414             * highlight a series.
53415             *
53416             * @param  {String} [state]
53417             *         Can be either `hover`, `select` or undefined to set to normal
53418             *         state.
53419             */
53420            setState: function(state) {
53421                var series = this,
53422                    options = series.options,
53423                    graph = series.graph,
53424                    stateOptions = options.states,
53425                    lineWidth = options.lineWidth,
53426                    attribs,
53427                    i = 0;
53428
53429                state = state || '';
53430
53431                if (series.state !== state) {
53432
53433                    // Toggle class names
53434                    each([
53435                        series.group,
53436                        series.markerGroup,
53437                        series.dataLabelsGroup
53438                    ], function(group) {
53439                        if (group) {
53440                            // Old state
53441                            if (series.state) {
53442                                group.removeClass('highcharts-series-' + series.state);
53443                            }
53444                            // New state
53445                            if (state) {
53446                                group.addClass('highcharts-series-' + state);
53447                            }
53448                        }
53449                    });
53450
53451                    series.state = state;
53452
53453
53454
53455                    if (stateOptions[state] && stateOptions[state].enabled === false) {
53456                        return;
53457                    }
53458
53459                    if (state) {
53460                        lineWidth = stateOptions[state].lineWidth || lineWidth + (stateOptions[state].lineWidthPlus || 0); // #4035
53461                    }
53462
53463                    if (graph && !graph.dashstyle) { // hover is turned off for dashed lines in VML
53464                        attribs = {
53465                            'stroke-width': lineWidth
53466                        };
53467
53468                        // Animate the graph stroke-width. By default a quick animation
53469                        // to hover, slower to un-hover.
53470                        graph.animate(
53471                            attribs,
53472                            pick(
53473                                series.chart.options.chart.animation,
53474                                stateOptions[state] && stateOptions[state].animation
53475                            )
53476                        );
53477                        while (series['zone-graph-' + i]) {
53478                            series['zone-graph-' + i].attr(attribs);
53479                            i = i + 1;
53480                        }
53481                    }
53482
53483                }
53484            },
53485
53486            /**
53487             * Show or hide the series.
53488             *
53489             * @param  {Boolean} [visible]
53490             *         True to show the series, false to hide. If undefined, the
53491             *         visibility is toggled.
53492             * @param  {Boolean} [redraw=true]
53493             *         Whether to redraw the chart after the series is altered. If doing
53494             *         more operations on the chart, it is a good idea to set redraw to
53495             *         false and call {@link Chart#redraw|chart.redraw()} after.
53496             */
53497            setVisible: function(vis, redraw) {
53498                var series = this,
53499                    chart = series.chart,
53500                    legendItem = series.legendItem,
53501                    showOrHide,
53502                    ignoreHiddenSeries = chart.options.chart.ignoreHiddenSeries,
53503                    oldVisibility = series.visible;
53504
53505                // if called without an argument, toggle visibility
53506                series.visible = vis = series.options.visible = series.userOptions.visible = vis === undefined ? !oldVisibility : vis; // #5618
53507                showOrHide = vis ? 'show' : 'hide';
53508
53509                // show or hide elements
53510                each(['group', 'dataLabelsGroup', 'markerGroup', 'tracker', 'tt'], function(key) {
53511                    if (series[key]) {
53512                        series[key][showOrHide]();
53513                    }
53514                });
53515
53516
53517                // hide tooltip (#1361)
53518                if (chart.hoverSeries === series || (chart.hoverPoint && chart.hoverPoint.series) === series) {
53519                    series.onMouseOut();
53520                }
53521
53522
53523                if (legendItem) {
53524                    chart.legend.colorizeItem(series, vis);
53525                }
53526
53527
53528                // rescale or adapt to resized chart
53529                series.isDirty = true;
53530                // in a stack, all other series are affected
53531                if (series.options.stacking) {
53532                    each(chart.series, function(otherSeries) {
53533                        if (otherSeries.options.stacking && otherSeries.visible) {
53534                            otherSeries.isDirty = true;
53535                        }
53536                    });
53537                }
53538
53539                // show or hide linked series
53540                each(series.linkedSeries, function(otherSeries) {
53541                    otherSeries.setVisible(vis, false);
53542                });
53543
53544                if (ignoreHiddenSeries) {
53545                    chart.isDirtyBox = true;
53546                }
53547                if (redraw !== false) {
53548                    chart.redraw();
53549                }
53550
53551                fireEvent(series, showOrHide);
53552            },
53553
53554            /**
53555             * Show the series if hidden.
53556             *
53557             * @sample highcharts/members/series-hide/
53558             *         Toggle visibility from a button
53559             */
53560            show: function() {
53561                this.setVisible(true);
53562            },
53563
53564            /**
53565             * Hide the series if visible. If the {@link
53566             * https://api.highcharts.com/highcharts/chart.ignoreHiddenSeries|
53567             * chart.ignoreHiddenSeries} option is true, the chart is redrawn without
53568             * this series.
53569             *
53570             * @sample highcharts/members/series-hide/
53571             *         Toggle visibility from a button
53572             */
53573            hide: function() {
53574                this.setVisible(false);
53575            },
53576
53577
53578            /**
53579             * Select or unselect the series. This means its {@link
53580             * Highcharts.Series.selected|selected} property is set, the checkbox in the
53581             * legend is toggled and when selected, the series is returned by the
53582             * {@link Highcharts.Chart#getSelectedSeries} function.
53583             *
53584             * @param  {Boolean} [selected]
53585             *         True to select the series, false to unselect. If	undefined, the
53586             *         selection state is toggled.
53587             *
53588             * @sample highcharts/members/series-select/
53589             *         Select a series from a button
53590             */
53591            select: function(selected) {
53592                var series = this;
53593
53594                series.selected = selected = (selected === undefined) ?
53595                    !series.selected :
53596                    selected;
53597
53598                if (series.checkbox) {
53599                    series.checkbox.checked = selected;
53600                }
53601
53602                fireEvent(series, selected ? 'select' : 'unselect');
53603            },
53604
53605            drawTracker: TrackerMixin.drawTrackerGraph
53606        });
53607
53608    }
53608(Highcharts));
53609    (function(H) {
53610        /**
53611         * (c) 2010-2017 Torstein Honsi
53612         *
53613         * License: www.highcharts.com/license
53614         */
53615        var Chart = H.Chart,
53616            each = H.each,
53617            inArray = H.inArray,
53618            isArray = H.isArray,
53619            isObject = H.isObject,
53620            pick = H.pick,
53621            splat = H.splat;
53622
53623
53624        /**
53625         * Allows setting a set of rules to apply for different screen or chart
53626         * sizes. Each rule specifies additional chart options.
53627         * 
53628         * @sample {highstock} stock/demo/responsive/ Stock chart
53629         * @sample highcharts/responsive/axis/ Axis
53630         * @sample highcharts/responsive/legend/ Legend
53631         * @sample highcharts/responsive/classname/ Class name
53632         * @since 5.0.0
53633         * @apioption responsive
53634         */
53635
53636        /**
53637         * A set of rules for responsive settings. The rules are executed from
53638         * the top down.
53639         * 
53640         * @type {Array<Object>}
53641         * @sample {highcharts} highcharts/responsive/axis/ Axis changes
53642         * @sample {highstock} highcharts/responsive/axis/ Axis changes
53643         * @sample {highmaps} highcharts/responsive/axis/ Axis changes
53644         * @since 5.0.0
53645         * @apioption responsive.rules
53646         */
53647
53648        /**
53649         * A full set of chart options to apply as overrides to the general
53650         * chart options. The chart options are applied when the given rule
53651         * is active.
53652         * 
53653         * A special case is configuration objects that take arrays, for example
53654         * [xAxis](#xAxis), [yAxis](#yAxis) or [series](#series). For these
53655         * collections, an `id` option is used to map the new option set to
53656         * an existing object. If an existing object of the same id is not found,
53657         * the item of the same indexupdated. So for example, setting `chartOptions`
53658         * with two series items without an `id`, will cause the existing chart's
53659         * two series to be updated with respective options.
53660         * 
53661         * @type {Object}
53662         * @sample {highstock} stock/demo/responsive/ Stock chart
53663         * @sample highcharts/responsive/axis/ Axis
53664         * @sample highcharts/responsive/legend/ Legend
53665         * @sample highcharts/responsive/classname/ Class name
53666         * @since 5.0.0
53667         * @apioption responsive.rules.chartOptions
53668         */
53669
53670        /**
53671         * Under which conditions the rule applies.
53672         * 
53673         * @type {Object}
53674         * @since 5.0.0
53675         * @apioption responsive.rules.condition
53676         */
53677
53678        /**
53679         * A callback function to gain complete control on when the responsive
53680         * rule applies. Return `true` if it applies. This opens for checking
53681         * against other metrics than the chart size, or example the document
53682         * size or other elements.
53683         * 
53684         * @type {Function}
53685         * @context Chart
53686         * @since 5.0.0
53687         * @apioption responsive.rules.condition.callback
53688         */
53689
53690        /**
53691         * The responsive rule applies if the chart height is less than this.
53692         * 
53693         * @type {Number}
53694         * @since 5.0.0
53695         * @apioption responsive.rules.condition.maxHeight
53696         */
53697
53698        /**
53699         * The responsive rule applies if the chart width is less than this.
53700         * 
53701         * @type {Number}
53702         * @sample highcharts/responsive/axis/ Max width is 500
53703         * @since 5.0.0
53704         * @apioption responsive.rules.condition.maxWidth
53705         */
53706
53707        /**
53708         * The responsive rule applies if the chart height is greater than this.
53709         * 
53710         * @type {Number}
53711         * @default 0
53712         * @since 5.0.0
53713         * @apioption responsive.rules.condition.minHeight
53714         */
53715
53716        /**
53717         * The responsive rule applies if the chart width is greater than this.
53718         * 
53719         * @type {Number}
53720         * @default 0
53721         * @since 5.0.0
53722         * @apioption responsive.rules.condition.minWidth
53723         */
53724
53725        /**
53726         * Update the chart based on the current chart/document size and options for
53727         * responsiveness.
53728         */
53729        Chart.prototype.setResponsive = function(redraw) {
53730            var options = this.options.responsive,
53731                ruleIds = [],
53732                currentResponsive = this.currentResponsive,
53733                currentRuleIds;
53734
53735            if (options && options.rules) {
53736                each(options.rules, function(rule) {
53737                    if (rule._id === undefined) {
53738                        rule._id = H.uniqueKey();
53739                    }
53740
53741                    this.matchResponsiveRule(rule, ruleIds, redraw);
53742                }, this);
53743            }
53744
53745            // Merge matching rules
53746            var mergedOptions = H.merge.apply(0, H.map(ruleIds, function(ruleId) {
53747                return H.find(options.rules, function(rule) {
53748                    return rule._id === ruleId;
53749                }).chartOptions;
53750            }));
53751
53752            // Stringified key for the rules that currently apply.
53753            ruleIds = ruleIds.toString() || undefined;
53754            currentRuleIds = currentResponsive && currentResponsive.ruleIds;
53755
53756
53757            // Changes in what rules apply
53758            if (ruleIds !== currentRuleIds) {
53759
53760                // Undo previous rules. Before we apply a new set of rules, we need to
53761                // roll back completely to base options (#6291).
53762                if (currentResponsive) {
53763                    this.update(currentResponsive.undoOptions, redraw);
53764                }
53765
53766                if (ruleIds) {
53767                    // Get undo-options for matching rules
53768                    this.currentResponsive = {
53769                        ruleIds: ruleIds,
53770                        mergedOptions: mergedOptions,
53771                        undoOptions: this.currentOptions(mergedOptions)
53772                    };
53773
53774                    this.update(mergedOptions, redraw);
53775
53776                } else {
53777                    this.currentResponsive = undefined;
53778                }
53779            }
53780        };
53781
53782        /**
53783         * Handle a single responsiveness rule
53784         */
53785        Chart.prototype.matchResponsiveRule = function(rule, matches) {
53786            var condition = rule.condition,
53787                fn = condition.callback || function() {
53788                    return this.chartWidth <= pick(condition.maxWidth, Number.MAX_VALUE) &&
53789                        this.chartHeight <= pick(condition.maxHeight, Number.MAX_VALUE) &&
53790                        this.chartWidth >= pick(condition.minWidth, 0) &&
53791                        this.chartHeight >= pick(condition.minHeight, 0);
53792                };
53793
53794            if (fn.call(this)) {
53795                matches.push(rule._id);
53796            }
53797
53798        };
53799
53800        /**
53801         * Get the current values for a given set of options. Used before we update
53802         * the chart with a new responsiveness rule.
53803         * TODO: Restore axis options (by id?)
53804         */
53805        Chart.prototype.currentOptions = function(options) {
53806
53807            var ret = {};
53808
53809            /**
53810             * Recurse over a set of options and its current values,
53811             * and store the current values in the ret object.
53812             */
53813            function getCurrent(options, curr, ret, depth) {
53814                var i;
53815                H.objectEach(options, function(val, key) {
53816                    if (!depth && inArray(key, ['series', 'xAxis', 'yAxis']) > -1) {
53817                        val = splat(val);
53818
53819                        ret[key] = [];
53820
53821                        // Iterate over collections like series, xAxis or yAxis and map
53822                        // the items by index.
53823                        for (i = 0; i < val.length; i++) {
53824                            if (curr[key][i]) { // Item exists in current data (#6347)
53825                                ret[key][i] = {};
53826                                getCurrent(
53827                                    val[i],
53828                                    curr[key][i],
53829                                    ret[key][i],
53830                                    depth + 1
53831                                );
53832                            }
53833                        }
53834                    } else if (isObject(val)) {
53835                        ret[key] = isArray(val) ? [] : {};
53836                        getCurrent(val, curr[key] || {}, ret[key], depth + 1);
53837                    } else {
53838                        ret[key] = curr[key] || null;
53839                    }
53840                });
53841            }
53842
53843            getCurrent(options, this.options, ret, 0);
53844            return ret;
53845        };
53846
53847    }(Highcharts));
53848    return Highcharts
53849}));
53850//! moment.js
53851//! version : 2.29.4
53852//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
53853//! license : MIT
53854//! momentjs.com
53855
53856;(function (global, factory) {
53857    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
53858    typeof define === 'function' && define.amd ? define(factory) :
53859    global.moment = factory()
53860}(this, (function () { 'use strict';
53861
53862    var hookCallback;
53863
53864    function hooks() {
53865        return hookCallback.apply(null, arguments);
53866    }
53867
53868    // This is done to register the method called with moment()
53869    // without creating circular dependencies.
53870    function setHookCallback(callback) {
53871        hookCallback = callback;
53872    }
53873
53874    function isArray(input) {
53875        return (
53876            input instanceof Array ||
53877            Object.prototype.toString.call(input) === '[object Array]'
53878        );
53879    }
53880
53881    function isObject(input) {
53882        // IE8 will treat undefined and null as object if it wasn't for
53883        // input != null
53884        return (
53885            input != null &&
53886            Object.prototype.toString.call(input) === '[object Object]'
53887        );
53888    }
53889
53890    function hasOwnProp(a, b) {
53891        return Object.prototype.hasOwnProperty.call(a, b);
53892    }
53893
53894    function isObjectEmpty(obj) {
53895        if (Object.getOwnPropertyNames) {
53896            return Object.getOwnPropertyNames(obj).length === 0;
53897        } else {
53898            var k;
53899            for (k in obj) {
53900                if (hasOwnProp(obj, k)) {
53901                    return false;
53902                }
53903            }
53904            return true;
53905        }
53906    }
53907
53908    function isUndefined(input) {
53909        return input === void 0;
53910    }
53911
53912    function isNumber(input) {
53913        return (
53914            typeof input === 'number' ||
53915            Object.prototype.toString.call(input) === '[object Number]'
53916        );
53917    }
53918
53919    function isDate(input) {
53920        return (
53921            input instanceof Date ||
53922            Object.prototype.toString.call(input) === '[object Date]'
53923        );
53924    }
53925
53926    function map(arr, fn) {
53927        var res = [],
53928            i,
53929            arrLen = arr.length;
53930        for (i = 0; i < arrLen; ++i) {
53931            res.push(fn(arr[i], i));
53932        }
53933        return res;
53934    }
53935
53936    function extend(a, b) {
53937        for (var i in b) {
53938            if (hasOwnProp(b, i)) {
53939                a[i] = b[i];
53940            }
53941        }
53942
53943        if (hasOwnProp(b, 'toString')) {
53944            a.toString = b.toString;
53945        }
53946
53947        if (hasOwnProp(b, 'valueOf')) {
53948            a.valueOf = b.valueOf;
53949        }
53950
53951        return a;
53952    }
53953
53954    function createUTC(input, format, locale, strict) {
vendor: 67,673 bytes, lines 53955-56139
53955        return createLocalOrUTC(input, format, locale, strict, true).utc();
53956    }
53957
53958    function defaultParsingFlags() {
53959        // We need to deep clone this object.
53960        return {
53961            empty: false,
53962            unusedTokens: [],
53963            unusedInput: [],
53964            overflow: -2,
53965            charsLeftOver: 0,
53966            nullInput: false,
53967            invalidEra: null,
53968            invalidMonth: null,
53969            invalidFormat: false,
53970            userInvalidated: false,
53971            iso: false,
53972            parsedDateParts: [],
53973            era: null,
53974            meridiem: null,
53975            rfc2822: false,
53976            weekdayMismatch: false,
53977        };
53978    }
53979
53980    function getParsingFlags(m) {
53981        if (m._pf == null) {
53982            m._pf = defaultParsingFlags();
53983        }
53984        return m._pf;
53985    }
53986
53987    var some;
53988    if (Array.prototype.some) {
53989        some = Array.prototype.some;
53990    } else {
53991        some = function (fun) {
53992            var t = Object(this),
53993                len = t.length >>> 0,
53994                i;
53995
53996            for (i = 0; i < len; i++) {
53997                if (i in t && fun.call(this, t[i], i, t)) {
53998                    return true;
53999                }
54000            }
54001
54002            return false;
54003        };
54004    }
54005
54006    function isValid(m) {
54007        if (m._isValid == null) {
54008            var flags = getParsingFlags(m),
54009                parsedParts = some.call(flags.parsedDateParts, function (i) {
54010                    return i != null;
54011                }),
54012                isNowValid =
54013                    !isNaN(m._d.getTime()) &&
54014                    flags.overflow < 0 &&
54015                    !flags.empty &&
54016                    !flags.invalidEra &&
54017                    !flags.invalidMonth &&
54018                    !flags.invalidWeekday &&
54019                    !flags.weekdayMismatch &&
54020                    !flags.nullInput &&
54021                    !flags.invalidFormat &&
54022                    !flags.userInvalidated &&
54023                    (!flags.meridiem || (flags.meridiem && parsedParts));
54024
54025            if (m._strict) {
54026                isNowValid =
54027                    isNowValid &&
54028                    flags.charsLeftOver === 0 &&
54029                    flags.unusedTokens.length === 0 &&
54030                    flags.bigHour === undefined;
54031            }
54032
54033            if (Object.isFrozen == null || !Object.isFrozen(m)) {
54034                m._isValid = isNowValid;
54035            } else {
54036                return isNowValid;
54037            }
54038        }
54039        return m._isValid;
54040    }
54041
54042    function createInvalid(flags) {
54043        var m = createUTC(NaN);
54044        if (flags != null) {
54045            extend(getParsingFlags(m), flags);
54046        } else {
54047            getParsingFlags(m).userInvalidated = true;
54048        }
54049
54050        return m;
54051    }
54052
54053    // Plugins that add properties should also add the key here (null value),
54054    // so we can properly clone ourselves.
54055    var momentProperties = (hooks.momentProperties = []),
54056        updateInProgress = false;
54057
54058    function copyConfig(to, from) {
54059        var i,
54060            prop,
54061            val,
54062            momentPropertiesLen = momentProperties.length;
54063
54064        if (!isUndefined(from._isAMomentObject)) {
54065            to._isAMomentObject = from._isAMomentObject;
54066        }
54067        if (!isUndefined(from._i)) {
54068            to._i = from._i;
54069        }
54070        if (!isUndefined(from._f)) {
54071            to._f = from._f;
54072        }
54073        if (!isUndefined(from._l)) {
54074            to._l = from._l;
54075        }
54076        if (!isUndefined(from._strict)) {
54077            to._strict = from._strict;
54078        }
54079        if (!isUndefined(from._tzm)) {
54080            to._tzm = from._tzm;
54081        }
54082        if (!isUndefined(from._isUTC)) {
54083            to._isUTC = from._isUTC;
54084        }
54085        if (!isUndefined(from._offset)) {
54086            to._offset = from._offset;
54087        }
54088        if (!isUndefined(from._pf)) {
54089            to._pf = getParsingFlags(from);
54090        }
54091        if (!isUndefined(from._locale)) {
54092            to._locale = from._locale;
54093        }
54094
54095        if (momentPropertiesLen > 0) {
54096            for (i = 0; i < momentPropertiesLen; i++) {
54097                prop = momentProperties[i];
54098                val = from[prop];
54099                if (!isUndefined(val)) {
54100                    to[prop] = val;
54101                }
54102            }
54103        }
54104
54105        return to;
54106    }
54107
54108    // Moment prototype object
54109    function Moment(config) {
54110        copyConfig(this, config);
54111        this._d = new Date(config._d != null ? config._d.getTime() : NaN);
54112        if (!this.isValid()) {
54113            this._d = new Date(NaN);
54114        }
54115        // Prevent infinite loop in case updateOffset creates new moment
54116        // objects.
54117        if (updateInProgress === false) {
54118            updateInProgress = true;
54119            hooks.updateOffset(this);
54120            updateInProgress = false;
54121        }
54122    }
54123
54124    function isMoment(obj) {
54125        return (
54126            obj instanceof Moment || (obj != null && obj._isAMomentObject != null)
54127        );
54128    }
54129
54130    function warn(msg) {
54131        if (
54132            hooks.suppressDeprecationWarnings === false &&
54133            typeof console !== 'undefined' &&
54134            console.warn
54135        ) {
54136            console.warn('Deprecation warning: ' + msg);
54137        }
54138    }
54139
54140    function deprecate(msg, fn) {
54141        var firstTime = true;
54142
54143        return extend(function () {
54144            if (hooks.deprecationHandler != null) {
54145                hooks.deprecationHandler(null, msg);
54146            }
54147            if (firstTime) {
54148                var args = [],
54149                    arg,
54150                    i,
54151                    key,
54152                    argLen = arguments.length;
54153                for (i = 0; i < argLen; i++) {
54154                    arg = '';
54155                    if (typeof arguments[i] === 'object') {
54156                        arg += '\n[' + i + '] ';
54157                        for (key in arguments[0]) {
54158                            if (hasOwnProp(arguments[0], key)) {
54159                                arg += key + ': ' + arguments[0][key] + ', ';
54160                            }
54161                        }
54162                        arg = arg.slice(0, -2); // Remove trailing comma and space
54163                    } else {
54164                        arg = arguments[i];
54165                    }
54166                    args.push(arg);
54167                }
54168                warn(
54169                    msg +
54170                        '\nArguments: ' +
54171                        Array.prototype.slice.call(args).join('') +
54172                        '\n' +
54173                        new Error().stack
54174                );
54175                firstTime = false;
54176            }
54177            return fn.apply(this, arguments);
54178        }, fn);
54179    }
54180
54181    var deprecations = {};
54182
54183    function deprecateSimple(name, msg) {
54184        if (hooks.deprecationHandler != null) {
54185            hooks.deprecationHandler(name, msg);
54186        }
54187        if (!deprecations[name]) {
54188            warn(msg);
54189            deprecations[name] = true;
54190        }
54191    }
54192
54193    hooks.suppressDeprecationWarnings = false;
54194    hooks.deprecationHandler = null;
54195
54196    function isFunction(input) {
54197        return (
54198            (typeof Function !== 'undefined' && input instanceof Function) ||
54199            Object.prototype.toString.call(input) === '[object Function]'
54200        );
54201    }
54202
54203    function set(config) {
54204        var prop, i;
54205        for (i in config) {
54206            if (hasOwnProp(config, i)) {
54207                prop = config[i];
54208                if (isFunction(prop)) {
54209                    this[i] = prop;
54210                } else {
54211                    this['_' + i] = prop;
54212                }
54213            }
54214        }
54215        this._config = config;
54216        // Lenient ordinal parsing accepts just a number in addition to
54217        // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
54218        // TODO: Remove "ordinalParse" fallback in next major release.
54219        this._dayOfMonthOrdinalParseLenient = new RegExp(
54220            (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +
54221                '|' +
54222                /\d{1,2}/.source
54223        );
54224    }
54225
54226    function mergeConfigs(parentConfig, childConfig) {
54227        var res = extend({}, parentConfig),
54228            prop;
54229        for (prop in childConfig) {
54230            if (hasOwnProp(childConfig, prop)) {
54231                if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
54232                    res[prop] = {};
54233                    extend(res[prop], parentConfig[prop]);
54234                    extend(res[prop], childConfig[prop]);
54235                } else if (childConfig[prop] != null) {
54236                    res[prop] = childConfig[prop];
54237                } else {
54238                    delete res[prop];
54239                }
54240            }
54241        }
54242        for (prop in parentConfig) {
54243            if (
54244                hasOwnProp(parentConfig, prop) &&
54245                !hasOwnProp(childConfig, prop) &&
54246                isObject(parentConfig[prop])
54247            ) {
54248                // make sure changes to properties don't modify parent config
54249                res[prop] = extend({}, res[prop]);
54250            }
54251        }
54252        return res;
54253    }
54254
54255    function Locale(config) {
54256        if (config != null) {
54257            this.set(config);
54258        }
54259    }
54260
54261    var keys;
54262
54263    if (Object.keys) {
54264        keys = Object.keys;
54265    } else {
54266        keys = function (obj) {
54267            var i,
54268                res = [];
54269            for (i in obj) {
54270                if (hasOwnProp(obj, i)) {
54271                    res.push(i);
54272                }
54273            }
54274            return res;
54275        };
54276    }
54277
54278    var defaultCalendar = {
54279        sameDay: '[Today at] LT',
54280        nextDay: '[Tomorrow at] LT',
54281        nextWeek: 'dddd [at] LT',
54282        lastDay: '[Yesterday at] LT',
54283        lastWeek: '[Last] dddd [at] LT',
54284        sameElse: 'L',
54285    };
54286
54287    function calendar(key, mom, now) {
54288        var output = this._calendar[key] || this._calendar['sameElse'];
54289        return isFunction(output) ? output.call(mom, now) : output;
54290    }
54291
54292    function zeroFill(number, targetLength, forceSign) {
54293        var absNumber = '' + Math.abs(number),
54294            zerosToFill = targetLength - absNumber.length,
54295            sign = number >= 0;
54296        return (
54297            (sign ? (forceSign ? '+' : '') : '-') +
54298            Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) +
54299            absNumber
54300        );
54301    }
54302
54303    var formattingTokens =
54304            /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|N{1,5}|YYYYYY|YYYYY|YYYY|YY|y{2,4}|yo?|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,
54305        localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,
54306        formatFunctions = {},
54307        formatTokenFunctions = {};
54308
54309    // token:    'M'
54310    // padded:   ['MM', 2]
54311    // ordinal:  'Mo'
54312    // callback: function () { this.month() + 1 }
54313    function addFormatToken(token, padded, ordinal, callback) {
54314        var func = callback;
54315        if (typeof callback === 'string') {
54316            func = function () {
54317                return this[callback]();
54318            };
54319        }
54320        if (token) {
54321            formatTokenFunctions[token] = func;
54322        }
54323        if (padded) {
54324            formatTokenFunctions[padded[0]] = function () {
54325                return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
54326            };
54327        }
54328        if (ordinal) {
54329            formatTokenFunctions[ordinal] = function () {
54330                return this.localeData().ordinal(
54331                    func.apply(this, arguments),
54332                    token
54333                );
54334            };
54335        }
54336    }
54337
54338    function removeFormattingTokens(input) {
54339        if (input.match(/\[[\s\S]/)) {
54340            return input.replace(/^\[|\]$/g, '');
54341        }
54342        return input.replace(/\\/g, '');
54343    }
54344
54345    function makeFormatFunction(format) {
54346        var array = format.match(formattingTokens),
54347            i,
54348            length;
54349
54350        for (i = 0, length = array.length; i < length; i++) {
54351            if (formatTokenFunctions[array[i]]) {
54352                array[i] = formatTokenFunctions[array[i]];
54353            } else {
54354                array[i] = removeFormattingTokens(array[i]);
54355            }
54356        }
54357
54358        return function (mom) {
54359            var output = '',
54360                i;
54361            for (i = 0; i < length; i++) {
54362                output += isFunction(array[i])
54363                    ? array[i].call(mom, format)
54364                    : array[i];
54365            }
54366            return output;
54367        };
54368    }
54369
54370    // format date using native date object
54371    function formatMoment(m, format) {
54372        if (!m.isValid()) {
54373            return m.localeData().invalidDate();
54374        }
54375
54376        format = expandFormat(format, m.localeData());
54377        formatFunctions[format] =
54378            formatFunctions[format] || makeFormatFunction(format);
54379
54380        return formatFunctions[format](m);
54381    }
54382
54383    function expandFormat(format, locale) {
54384        var i = 5;
54385
54386        function replaceLongDateFormatTokens(input) {
54387            return locale.longDateFormat(input) || input;
54388        }
54389
54390        localFormattingTokens.lastIndex = 0;
54391        while (i >= 0 && localFormattingTokens.test(format)) {
54392            format = format.replace(
54393                localFormattingTokens,
54394                replaceLongDateFormatTokens
54395            );
54396            localFormattingTokens.lastIndex = 0;
54397            i -= 1;
54398        }
54399
54400        return format;
54401    }
54402
54403    var defaultLongDateFormat = {
54404        LTS: 'h:mm:ss A',
54405        LT: 'h:mm A',
54406        L: 'MM/DD/YYYY',
54407        LL: 'MMMM D, YYYY',
54408        LLL: 'MMMM D, YYYY h:mm A',
54409        LLLL: 'dddd, MMMM D, YYYY h:mm A',
54410    };
54411
54412    function longDateFormat(key) {
54413        var format = this._longDateFormat[key],
54414            formatUpper = this._longDateFormat[key.toUpperCase()];
54415
54416        if (format || !formatUpper) {
54417            return format;
54418        }
54419
54420        this._longDateFormat[key] = formatUpper
54421            .match(formattingTokens)
54422            .map(function (tok) {
54423                if (
54424                    tok === 'MMMM' ||
54425                    tok === 'MM' ||
54426                    tok === 'DD' ||
54427                    tok === 'dddd'
54428                ) {
54429                    return tok.slice(1);
54430                }
54431                return tok;
54432            })
54433            .join('');
54434
54435        return this._longDateFormat[key];
54436    }
54437
54438    var defaultInvalidDate = 'Invalid date';
54439
54440    function invalidDate() {
54441        return this._invalidDate;
54442    }
54443
54444    var defaultOrdinal = '%d',
54445        defaultDayOfMonthOrdinalParse = /\d{1,2}/;
54446
54447    function ordinal(number) {
54448        return this._ordinal.replace('%d', number);
54449    }
54450
54451    var defaultRelativeTime = {
54452        future: 'in %s',
54453        past: '%s ago',
54454        s: 'a few seconds',
54455        ss: '%d seconds',
54456        m: 'a minute',
54457        mm: '%d minutes',
54458        h: 'an hour',
54459        hh: '%d hours',
54460        d: 'a day',
54461        dd: '%d days',
54462        w: 'a week',
54463        ww: '%d weeks',
54464        M: 'a month',
54465        MM: '%d months',
54466        y: 'a year',
54467        yy: '%d years',
54468    };
54469
54470    function relativeTime(number, withoutSuffix, string, isFuture) {
54471        var output = this._relativeTime[string];
54472        return isFunction(output)
54473            ? output(number, withoutSuffix, string, isFuture)
54474            : output.replace(/%d/i, number);
54475    }
54476
54477    function pastFuture(diff, output) {
54478        var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
54479        return isFunction(format) ? format(output) : format.replace(/%s/i, output);
54480    }
54481
54482    var aliases = {};
54483
54484    function addUnitAlias(unit, shorthand) {
54485        var lowerCase = unit.toLowerCase();
54486        aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
54487    }
54488
54489    function normalizeUnits(units) {
54490        return typeof units === 'string'
54491            ? aliases[units] || aliases[units.toLowerCase()]
54492            : undefined;
54493    }
54494
54495    function normalizeObjectUnits(inputObject) {
54496        var normalizedInput = {},
54497            normalizedProp,
54498            prop;
54499
54500        for (prop in inputObject) {
54501            if (hasOwnProp(inputObject, prop)) {
54502                normalizedProp = normalizeUnits(prop);
54503                if (normalizedProp) {
54504                    normalizedInput[normalizedProp] = inputObject[prop];
54505                }
54506            }
54507        }
54508
54509        return normalizedInput;
54510    }
54511
54512    var priorities = {};
54513
54514    function addUnitPriority(unit, priority) {
54515        priorities[unit] = priority;
54516    }
54517
54518    function getPrioritizedUnits(unitsObj) {
54519        var units = [],
54520            u;
54521        for (u in unitsObj) {
54522            if (hasOwnProp(unitsObj, u)) {
54523                units.push({ unit: u, priority: priorities[u] });
54524            }
54525        }
54526        units.sort(function (a, b) {
54527            return a.priority - b.priority;
54528        });
54529        return units;
54530    }
54531
54532    function isLeapYear(year) {
54533        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
54534    }
54535
54536    function absFloor(number) {
54537        if (number < 0) {
54538            // -0 -> 0
54539            return Math.ceil(number) || 0;
54540        } else {
54541            return Math.floor(number);
54542        }
54543    }
54544
54545    function toInt(argumentForCoercion) {
54546        var coercedNumber = +argumentForCoercion,
54547            value = 0;
54548
54549        if (coercedNumber !== 0 && isFinite(coercedNumber)) {
54550            value = absFloor(coercedNumber);
54551        }
54552
54553        return value;
54554    }
54555
54556    function makeGetSet(unit, keepTime) {
54557        return function (value) {
54558            if (value != null) {
54559                set$1(this, unit, value);
54560                hooks.updateOffset(this, keepTime);
54561                return this;
54562            } else {
54563                return get(this, unit);
54564            }
54565        };
54566    }
54567
54568    function get(mom, unit) {
54569        return mom.isValid()
54570            ? mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]()
54571            : NaN;
54572    }
54573
54574    function set$1(mom, unit, value) {
54575        if (mom.isValid() && !isNaN(value)) {
54576            if (
54577                unit === 'FullYear' &&
54578                isLeapYear(mom.year()) &&
54579                mom.month() === 1 &&
54580                mom.date() === 29
54581            ) {
54582                value = toInt(value);
54583                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](
54584                    value,
54585                    mom.month(),
54586                    daysInMonth(value, mom.month())
54587                );
54588            } else {
54589                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
54590            }
54591        }
54592    }
54593
54594    // MOMENTS
54595
54596    function stringGet(units) {
54597        units = normalizeUnits(units);
54598        if (isFunction(this[units])) {
54599            return this[units]();
54600        }
54601        return this;
54602    }
54603
54604    function stringSet(units, value) {
54605        if (typeof units === 'object') {
54606            units = normalizeObjectUnits(units);
54607            var prioritized = getPrioritizedUnits(units),
54608                i,
54609                prioritizedLen = prioritized.length;
54610            for (i = 0; i < prioritizedLen; i++) {
54611                this[prioritized[i].unit](units[prioritized[i].unit]);
54612            }
54613        } else {
54614            units = normalizeUnits(units);
54615            if (isFunction(this[units])) {
54616                return this[units](value);
54617            }
54618        }
54619        return this;
54620    }
54621
54622    var match1 = /\d/, //       0 - 9
54623        match2 = /\d\d/, //      00 - 99
54624        match3 = /\d{3}/, //     000 - 999
54625        match4 = /\d{4}/, //    0000 - 9999
54626        match6 = /[+-]?\d{6}/, // -999999 - 999999
54627        match1to2 = /\d\d?/, //       0 - 99
54628        match3to4 = /\d\d\d\d?/, //     999 - 9999
54629        match5to6 = /\d\d\d\d\d\d?/, //   99999 - 999999
54630        match1to3 = /\d{1,3}/, //       0 - 999
54631        match1to4 = /\d{1,4}/, //       0 - 9999
54632        match1to6 = /[+-]?\d{1,6}/, // -999999 - 999999
54633        matchUnsigned = /\d+/, //       0 - inf
54634        matchSigned = /[+-]?\d+/, //    -inf - inf
54635        matchOffset = /Z|[+-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z
54636        matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi, // +00 -00 +00:00 -00:00 +0000 -0000 or Z
54637        matchTimestamp = /[+-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123
54638        // any word (or two) characters or numbers including two/three word month in arabic.
54639        // includes scottish gaelic two word and hyphenated months
54640        matchWord =
54641            /[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,
54642        regexes;
54643
54644    regexes = {};
54645
54646    function addRegexToken(token, regex, strictRegex) {
54647        regexes[token] = isFunction(regex)
54648            ? regex
54649            : function (isStrict, localeData) {
54650                  return isStrict && strictRegex ? strictRegex : regex;
54651              };
54652    }
54653
54654    function getParseRegexForToken(token, config) {
54655        if (!hasOwnProp(regexes, token)) {
54656            return new RegExp(unescapeFormat(token));
54657        }
54658
54659        return regexes[token](config._strict, config._locale);
54660    }
54661
54662    // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
54663    function unescapeFormat(s) {
54664        return regexEscape(
54665            s
54666                .replace('\\', '')
54667                .replace(
54668                    /\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,
54669                    function (matched, p1, p2, p3, p4) {
54670                        return p1 || p2 || p3 || p4;
54671                    }
54672                )
54673        );
54674    }
54675
54676    function regexEscape(s) {
54677        return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
54678    }
54679
54680    var tokens = {};
54681
54682    function addParseToken(token, callback) {
54683        var i,
54684            func = callback,
54685            tokenLen;
54686        if (typeof token === 'string') {
54687            token = [token];
54688        }
54689        if (isNumber(callback)) {
54690            func = function (input, array) {
54691                array[callback] = toInt(input);
54692            };
54693        }
54694        tokenLen = token.length;
54695        for (i = 0; i < tokenLen; i++) {
54696            tokens[token[i]] = func;
54697        }
54698    }
54699
54700    function addWeekParseToken(token, callback) {
54701        addParseToken(token, function (input, array, config, token) {
54702            config._w = config._w || {};
54703            callback(input, config._w, config, token);
54704        });
54705    }
54706
54707    function addTimeToArrayFromToken(token, input, config) {
54708        if (input != null && hasOwnProp(tokens, token)) {
54709            tokens[token](input, config._a, config, token);
54710        }
54711    }
54712
54713    var YEAR = 0,
54714        MONTH = 1,
54715        DATE = 2,
54716        HOUR = 3,
54717        MINUTE = 4,
54718        SECOND = 5,
54719        MILLISECOND = 6,
54720        WEEK = 7,
54721        WEEKDAY = 8;
54722
54723    function mod(n, x) {
54724        return ((n % x) + x) % x;
54725    }
54726
54727    var indexOf;
54728
54729    if (Array.prototype.indexOf) {
54730        indexOf = Array.prototype.indexOf;
54731    } else {
54732        indexOf = function (o) {
54733            // I know
54734            var i;
54735            for (i = 0; i < this.length; ++i) {
54736                if (this[i] === o) {
54737                    return i;
54738                }
54739            }
54740            return -1;
54741        };
54742    }
54743
54744    function daysInMonth(year, month) {
54745        if (isNaN(year) || isNaN(month)) {
54746            return NaN;
54747        }
54748        var modMonth = mod(month, 12);
54749        year += (month - modMonth) / 12;
54750        return modMonth === 1
54751            ? isLeapYear(year)
54752                ? 29
54753                : 28
54754            : 31 - ((modMonth % 7) % 2);
54755    }
54756
54757    // FORMATTING
54758
54759    addFormatToken('M', ['MM', 2], 'Mo', function () {
54760        return this.month() + 1;
54761    });
54762
54763    addFormatToken('MMM', 0, 0, function (format) {
54764        return this.localeData().monthsShort(this, format);
54765    });
54766
54767    addFormatToken('MMMM', 0, 0, function (format) {
54768        return this.localeData().months(this, format);
54769    });
54770
54771    // ALIASES
54772
54773    addUnitAlias('month', 'M');
54774
54775    // PRIORITY
54776
54777    addUnitPriority('month', 8);
54778
54779    // PARSING
54780
54781    addRegexToken('M', match1to2);
54782    addRegexToken('MM', match1to2, match2);
54783    addRegexToken('MMM', function (isStrict, locale) {
54784        return locale.monthsShortRegex(isStrict);
54785    });
54786    addRegexToken('MMMM', function (isStrict, locale) {
54787        return locale.monthsRegex(isStrict);
54788    });
54789
54790    addParseToken(['M', 'MM'], function (input, array) {
54791        array[MONTH] = toInt(input) - 1;
54792    });
54793
54794    addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
54795        var month = config._locale.monthsParse(input, token, config._strict);
54796        // if we didn't find a month name, mark the date as invalid.
54797        if (month != null) {
54798            array[MONTH] = month;
54799        } else {
54800            getParsingFlags(config).invalidMonth = input;
54801        }
54802    });
54803
54804    // LOCALES
54805
54806    var defaultLocaleMonths =
54807            'January_February_March_April_May_June_July_August_September_October_November_December'.split(
54808                '_'
54809            ),
54810        defaultLocaleMonthsShort =
54811            'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
54812        MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,
54813        defaultMonthsShortRegex = matchWord,
54814        defaultMonthsRegex = matchWord;
54815
54816    function localeMonths(m, format) {
54817        if (!m) {
54818            return isArray(this._months)
54819                ? this._months
54820                : this._months['standalone'];
54821        }
54822        return isArray(this._months)
54823            ? this._months[m.month()]
54824            : this._months[
54825                  (this._months.isFormat || MONTHS_IN_FORMAT).test(format)
54826                      ? 'format'
54827                      : 'standalone'
54828              ][m.month()];
54829    }
54830
54831    function localeMonthsShort(m, format) {
54832        if (!m) {
54833            return isArray(this._monthsShort)
54834                ? this._monthsShort
54835                : this._monthsShort['standalone'];
54836        }
54837        return isArray(this._monthsShort)
54838            ? this._monthsShort[m.month()]
54839            : this._monthsShort[
54840                  MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'
54841              ][m.month()];
54842    }
54843
54844    function handleStrictParse(monthName, format, strict) {
54845        var i,
54846            ii,
54847            mom,
54848            llc = monthName.toLocaleLowerCase();
54849        if (!this._monthsParse) {
54850            // this is not used
54851            this._monthsParse = [];
54852            this._longMonthsParse = [];
54853            this._shortMonthsParse = [];
54854            for (i = 0; i < 12; ++i) {
54855                mom = createUTC([2000, i]);
54856                this._shortMonthsParse[i] = this.monthsShort(
54857                    mom,
54858                    ''
54859                ).toLocaleLowerCase();
54860                this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
54861            }
54862        }
54863
54864        if (strict) {
54865            if (format === 'MMM') {
54866                ii = indexOf.call(this._shortMonthsParse, llc);
54867                return ii !== -1 ? ii : null;
54868            } else {
54869                ii = indexOf.call(this._longMonthsParse, llc);
54870                return ii !== -1 ? ii : null;
54871            }
54872        } else {
54873            if (format === 'MMM') {
54874                ii = indexOf.call(this._shortMonthsParse, llc);
54875                if (ii !== -1) {
54876                    return ii;
54877                }
54878                ii = indexOf.call(this._longMonthsParse, llc);
54879                return ii !== -1 ? ii : null;
54880            } else {
54881                ii = indexOf.call(this._longMonthsParse, llc);
54882                if (ii !== -1) {
54883                    return ii;
54884                }
54885                ii = indexOf.call(this._shortMonthsParse, llc);
54886                return ii !== -1 ? ii : null;
54887            }
54888        }
54889    }
54890
54891    function localeMonthsParse(monthName, format, strict) {
54892        var i, mom, regex;
54893
54894        if (this._monthsParseExact) {
54895            return handleStrictParse.call(this, monthName, format, strict);
54896        }
54897
54898        if (!this._monthsParse) {
54899            this._monthsParse = [];
54900            this._longMonthsParse = [];
54901            this._shortMonthsParse = [];
54902        }
54903
54904        // TODO: add sorting
54905        // Sorting makes sure if one month (or abbr) is a prefix of another
54906        // see sorting in computeMonthsParse
54907        for (i = 0; i < 12; i++) {
54908            // make the regex if we don't have it already
54909            mom = createUTC([2000, i]);
54910            if (strict && !this._longMonthsParse[i]) {
54911                this._longMonthsParse[i] = new RegExp(
54912                    '^' + this.months(mom, '').replace('.', '') + '$',
54913                    'i'
54914                );
54915                this._shortMonthsParse[i] = new RegExp(
54916                    '^' + this.monthsShort(mom, '').replace('.', '') + '$',
54917                    'i'
54918                );
54919            }
54920            if (!strict && !this._monthsParse[i]) {
54921                regex =
54922                    '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
54923                this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
54924            }
54925            // test the regex
54926            if (
54927                strict &&
54928                format === 'MMMM' &&
54929                this._longMonthsParse[i].test(monthName)
54930            ) {
54931                return i;
54932            } else if (
54933                strict &&
54934                format === 'MMM' &&
54935                this._shortMonthsParse[i].test(monthName)
54936            ) {
54937                return i;
54938            } else if (!strict && this._monthsParse[i].test(monthName)) {
54939                return i;
54940            }
54941        }
54942    }
54943
54944    // MOMENTS
54945
54946    function setMonth(mom, value) {
54947        var dayOfMonth;
54948
54949        if (!mom.isValid()) {
54950            // No op
54951            return mom;
54952        }
54953
54954        if (typeof value === 'string') {
54955            if (/^\d+$/.test(value)) {
54956                value = toInt(value);
54957            } else {
54958                value = mom.localeData().monthsParse(value);
54959                // TODO: Another silent failure?
54960                if (!isNumber(value)) {
54961                    return mom;
54962                }
54963            }
54964        }
54965
54966        dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
54967        mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
54968        return mom;
54969    }
54970
54971    function getSetMonth(value) {
54972        if (value != null) {
54973            setMonth(this, value);
54974            hooks.updateOffset(this, true);
54975            return this;
54976        } else {
54977            return get(this, 'Month');
54978        }
54979    }
54980
54981    function getDaysInMonth() {
54982        return daysInMonth(this.year(), this.month());
54983    }
54984
54985    function monthsShortRegex(isStrict) {
54986        if (this._monthsParseExact) {
54987            if (!hasOwnProp(this, '_monthsRegex')) {
54988                computeMonthsParse.call(this);
54989            }
54990            if (isStrict) {
54991                return this._monthsShortStrictRegex;
54992            } else {
54993                return this._monthsShortRegex;
54994            }
54995        } else {
54996            if (!hasOwnProp(this, '_monthsShortRegex')) {
54997                this._monthsShortRegex = defaultMonthsShortRegex;
54998            }
54999            return this._monthsShortStrictRegex && isStrict
55000                ? this._monthsShortStrictRegex
55001                : this._monthsShortRegex;
55002        }
55003    }
55004
55005    function monthsRegex(isStrict) {
55006        if (this._monthsParseExact) {
55007            if (!hasOwnProp(this, '_monthsRegex')) {
55008                computeMonthsParse.call(this);
55009            }
55010            if (isStrict) {
55011                return this._monthsStrictRegex;
55012            } else {
55013                return this._monthsRegex;
55014            }
55015        } else {
55016            if (!hasOwnProp(this, '_monthsRegex')) {
55017                this._monthsRegex = defaultMonthsRegex;
55018            }
55019            return this._monthsStrictRegex && isStrict
55020                ? this._monthsStrictRegex
55021                : this._monthsRegex;
55022        }
55023    }
55024
55025    function computeMonthsParse() {
55026        function cmpLenRev(a, b) {
55027            return b.length - a.length;
55028        }
55029
55030        var shortPieces = [],
55031            longPieces = [],
55032            mixedPieces = [],
55033            i,
55034            mom;
55035        for (i = 0; i < 12; i++) {
55036            // make the regex if we don't have it already
55037            mom = createUTC([2000, i]);
55038            shortPieces.push(this.monthsShort(mom, ''));
55039            longPieces.push(this.months(mom, ''));
55040            mixedPieces.push(this.months(mom, ''));
55041            mixedPieces.push(this.monthsShort(mom, ''));
55042        }
55043        // Sorting makes sure if one month (or abbr) is a prefix of another it
55044        // will match the longer piece.
55045        shortPieces.sort(cmpLenRev);
55046        longPieces.sort(cmpLenRev);
55047        mixedPieces.sort(cmpLenRev);
55048        for (i = 0; i < 12; i++) {
55049            shortPieces[i] = regexEscape(shortPieces[i]);
55050            longPieces[i] = regexEscape(longPieces[i]);
55051        }
55052        for (i = 0; i < 24; i++) {
55053            mixedPieces[i] = regexEscape(mixedPieces[i]);
55054        }
55055
55056        this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
55057        this._monthsShortRegex = this._monthsRegex;
55058        this._monthsStrictRegex = new RegExp(
55059            '^(' + longPieces.join('|') + ')',
55060            'i'
55061        );
55062        this._monthsShortStrictRegex = new RegExp(
55063            '^(' + shortPieces.join('|') + ')',
55064            'i'
55065        );
55066    }
55067
55068    // FORMATTING
55069
55070    addFormatToken('Y', 0, 0, function () {
55071        var y = this.year();
55072        return y <= 9999 ? zeroFill(y, 4) : '+' + y;
55073    });
55074
55075    addFormatToken(0, ['YY', 2], 0, function () {
55076        return this.year() % 100;
55077    });
55078
55079    addFormatToken(0, ['YYYY', 4], 0, 'year');
55080    addFormatToken(0, ['YYYYY', 5], 0, 'year');
55081    addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');
55082
55083    // ALIASES
55084
55085    addUnitAlias('year', 'y');
55086
55087    // PRIORITIES
55088
55089    addUnitPriority('year', 1);
55090
55091    // PARSING
55092
55093    addRegexToken('Y', matchSigned);
55094    addRegexToken('YY', match1to2, match2);
55095    addRegexToken('YYYY', match1to4, match4);
55096    addRegexToken('YYYYY', match1to6, match6);
55097    addRegexToken('YYYYYY', match1to6, match6);
55098
55099    addParseToken(['YYYYY', 'YYYYYY'], YEAR);
55100    addParseToken('YYYY', function (input, array) {
55101        array[YEAR] =
55102            input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
55103    });
55104    addParseToken('YY', function (input, array) {
55105        array[YEAR] = hooks.parseTwoDigitYear(input);
55106    });
55107    addParseToken('Y', function (input, array) {
55108        array[YEAR] = parseInt(input, 10);
55109    });
55110
55111    // HELPERS
55112
55113    function daysInYear(year) {
55114        return isLeapYear(year) ? 366 : 365;
55115    }
55116
55117    // HOOKS
55118
55119    hooks.parseTwoDigitYear = function (input) {
55120        return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
55121    };
55122
55123    // MOMENTS
55124
55125    var getSetYear = makeGetSet('FullYear', true);
55126
55127    function getIsLeapYear() {
55128        return isLeapYear(this.year());
55129    }
55130
55131    function createDate(y, m, d, h, M, s, ms) {
55132        // can't just apply() to create a date:
55133        // https://stackoverflow.com/q/181348
55134        var date;
55135        // the date constructor remaps years 0-99 to 1900-1999
55136        if (y < 100 && y >= 0) {
55137            // preserve leap years using a full 400 year cycle, then reset
55138            date = new Date(y + 400, m, d, h, M, s, ms);
55139            if (isFinite(date.getFullYear())) {
55140                date.setFullYear(y);
55141            }
55142        } else {
55143            date = new Date(y, m, d, h, M, s, ms);
55144        }
55145
55146        return date;
55147    }
55148
55149    function createUTCDate(y) {
55150        var date, args;
55151        // the Date.UTC function remaps years 0-99 to 1900-1999
55152        if (y < 100 && y >= 0) {
55153            args = Array.prototype.slice.call(arguments);
55154            // preserve leap years using a full 400 year cycle, then reset
55155            args[0] = y + 400;
55156            date = new Date(Date.UTC.apply(null, args));
55157            if (isFinite(date.getUTCFullYear())) {
55158                date.setUTCFullYear(y);
55159            }
55160        } else {
55161            date = new Date(Date.UTC.apply(null, arguments));
55162        }
55163
55164        return date;
55165    }
55166
55167    // start-of-first-week - start-of-year
55168    function firstWeekOffset(year, dow, doy) {
55169        var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
55170            fwd = 7 + dow - doy,
55171            // first-week day local weekday -- which local weekday is fwd
55172            fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
55173
55174        return -fwdlw + fwd - 1;
55175    }
55176
55177    // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
55178    function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
55179        var localWeekday = (7 + weekday - dow) % 7,
55180            weekOffset = firstWeekOffset(year, dow, doy),
55181            dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
55182            resYear,
55183            resDayOfYear;
55184
55185        if (dayOfYear <= 0) {
55186            resYear = year - 1;
55187            resDayOfYear = daysInYear(resYear) + dayOfYear;
55188        } else if (dayOfYear > daysInYear(year)) {
55189            resYear = year + 1;
55190            resDayOfYear = dayOfYear - daysInYear(year);
55191        } else {
55192            resYear = year;
55193            resDayOfYear = dayOfYear;
55194        }
55195
55196        return {
55197            year: resYear,
55198            dayOfYear: resDayOfYear,
55199        };
55200    }
55201
55202    function weekOfYear(mom, dow, doy) {
55203        var weekOffset = firstWeekOffset(mom.year(), dow, doy),
55204            week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
55205            resWeek,
55206            resYear;
55207
55208        if (week < 1) {
55209            resYear = mom.year() - 1;
55210            resWeek = week + weeksInYear(resYear, dow, doy);
55211        } else if (week > weeksInYear(mom.year(), dow, doy)) {
55212            resWeek = week - weeksInYear(mom.year(), dow, doy);
55213            resYear = mom.year() + 1;
55214        } else {
55215            resYear = mom.year();
55216            resWeek = week;
55217        }
55218
55219        return {
55220            week: resWeek,
55221            year: resYear,
55222        };
55223    }
55224
55225    function weeksInYear(year, dow, doy) {
55226        var weekOffset = firstWeekOffset(year, dow, doy),
55227            weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
55228        return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
55229    }
55230
55231    // FORMATTING
55232
55233    addFormatToken('w', ['ww', 2], 'wo', 'week');
55234    addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');
55235
55236    // ALIASES
55237
55238    addUnitAlias('week', 'w');
55239    addUnitAlias('isoWeek', 'W');
55240
55241    // PRIORITIES
55242
55243    addUnitPriority('week', 5);
55244    addUnitPriority('isoWeek', 5);
55245
55246    // PARSING
55247
55248    addRegexToken('w', match1to2);
55249    addRegexToken('ww', match1to2, match2);
55250    addRegexToken('W', match1to2);
55251    addRegexToken('WW', match1to2, match2);
55252
55253    addWeekParseToken(
55254        ['w', 'ww', 'W', 'WW'],
55255        function (input, week, config, token) {
55256            week[token.substr(0, 1)] = toInt(input);
55257        }
55258    );
55259
55260    // HELPERS
55261
55262    // LOCALES
55263
55264    function localeWeek(mom) {
55265        return weekOfYear(mom, this._week.dow, this._week.doy).week;
55266    }
55267
55268    var defaultLocaleWeek = {
55269        dow: 0, // Sunday is the first day of the week.
55270        doy: 6, // The week that contains Jan 6th is the first week of the year.
55271    };
55272
55273    function localeFirstDayOfWeek() {
55274        return this._week.dow;
55275    }
55276
55277    function localeFirstDayOfYear() {
55278        return this._week.doy;
55279    }
55280
55281    // MOMENTS
55282
55283    function getSetWeek(input) {
55284        var week = this.localeData().week(this);
55285        return input == null ? week : this.add((input - week) * 7, 'd');
55286    }
55287
55288    function getSetISOWeek(input) {
55289        var week = weekOfYear(this, 1, 4).week;
55290        return input == null ? week : this.add((input - week) * 7, 'd');
55291    }
55292
55293    // FORMATTING
55294
55295    addFormatToken('d', 0, 'do', 'day');
55296
55297    addFormatToken('dd', 0, 0, function (format) {
55298        return this.localeData().weekdaysMin(this, format);
55299    });
55300
55301    addFormatToken('ddd', 0, 0, function (format) {
55302        return this.localeData().weekdaysShort(this, format);
55303    });
55304
55305    addFormatToken('dddd', 0, 0, function (format) {
55306        return this.localeData().weekdays(this, format);
55307    });
55308
55309    addFormatToken('e', 0, 0, 'weekday');
55310    addFormatToken('E', 0, 0, 'isoWeekday');
55311
55312    // ALIASES
55313
55314    addUnitAlias('day', 'd');
55315    addUnitAlias('weekday', 'e');
55316    addUnitAlias('isoWeekday', 'E');
55317
55318    // PRIORITY
55319    addUnitPriority('day', 11);
55320    addUnitPriority('weekday', 11);
55321    addUnitPriority('isoWeekday', 11);
55322
55323    // PARSING
55324
55325    addRegexToken('d', match1to2);
55326    addRegexToken('e', match1to2);
55327    addRegexToken('E', match1to2);
55328    addRegexToken('dd', function (isStrict, locale) {
55329        return locale.weekdaysMinRegex(isStrict);
55330    });
55331    addRegexToken('ddd', function (isStrict, locale) {
55332        return locale.weekdaysShortRegex(isStrict);
55333    });
55334    addRegexToken('dddd', function (isStrict, locale) {
55335        return locale.weekdaysRegex(isStrict);
55336    });
55337
55338    addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
55339        var weekday = config._locale.weekdaysParse(input, token, config._strict);
55340        // if we didn't get a weekday name, mark the date as invalid
55341        if (weekday != null) {
55342            week.d = weekday;
55343        } else {
55344            getParsingFlags(config).invalidWeekday = input;
55345        }
55346    });
55347
55348    addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
55349        week[token] = toInt(input);
55350    });
55351
55352    // HELPERS
55353
55354    function parseWeekday(input, locale) {
55355        if (typeof input !== 'string') {
55356            return input;
55357        }
55358
55359        if (!isNaN(input)) {
55360            return parseInt(input, 10);
55361        }
55362
55363        input = locale.weekdaysParse(input);
55364        if (typeof input === 'number') {
55365            return input;
55366        }
55367
55368        return null;
55369    }
55370
55371    function parseIsoWeekday(input, locale) {
55372        if (typeof input === 'string') {
55373            return locale.weekdaysParse(input) % 7 || 7;
55374        }
55375        return isNaN(input) ? null : input;
55376    }
55377
55378    // LOCALES
55379    function shiftWeekdays(ws, n) {
55380        return ws.slice(n, 7).concat(ws.slice(0, n));
55381    }
55382
55383    var defaultLocaleWeekdays =
55384            'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
55385        defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
55386        defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
55387        defaultWeekdaysRegex = matchWord,
55388        defaultWeekdaysShortRegex = matchWord,
55389        defaultWeekdaysMinRegex = matchWord;
55390
55391    function localeWeekdays(m, format) {
55392        var weekdays = isArray(this._weekdays)
55393            ? this._weekdays
55394            : this._weekdays[
55395                  m && m !== true && this._weekdays.isFormat.test(format)
55396                      ? 'format'
55397                      : 'standalone'
55398              ];
55399        return m === true
55400            ? shiftWeekdays(weekdays, this._week.dow)
55401            : m
55402            ? weekdays[m.day()]
55403            : weekdays;
55404    }
55405
55406    function localeWeekdaysShort(m) {
55407        return m === true
55408            ? shiftWeekdays(this._weekdaysShort, this._week.dow)
55409            : m
55410            ? this._weekdaysShort[m.day()]
55411            : this._weekdaysShort;
55412    }
55413
55414    function localeWeekdaysMin(m) {
55415        return m === true
55416            ? shiftWeekdays(this._weekdaysMin, this._week.dow)
55417            : m
55418            ? this._weekdaysMin[m.day()]
55419            : this._weekdaysMin;
55420    }
55421
55422    function handleStrictParse$1(weekdayName, format, strict) {
55423        var i,
55424            ii,
55425            mom,
55426            llc = weekdayName.toLocaleLowerCase();
55427        if (!this._weekdaysParse) {
55428            this._weekdaysParse = [];
55429            this._shortWeekdaysParse = [];
55430            this._minWeekdaysParse = [];
55431
55432            for (i = 0; i < 7; ++i) {
55433                mom = createUTC([2000, 1]).day(i);
55434                this._minWeekdaysParse[i] = this.weekdaysMin(
55435                    mom,
55436                    ''
55437                ).toLocaleLowerCase();
55438                this._shortWeekdaysParse[i] = this.weekdaysShort(
55439                    mom,
55440                    ''
55441                ).toLocaleLowerCase();
55442                this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
55443            }
55444        }
55445
55446        if (strict) {
55447            if (format === 'dddd') {
55448                ii = indexOf.call(this._weekdaysParse, llc);
55449                return ii !== -1 ? ii : null;
55450            } else if (format === 'ddd') {
55451                ii = indexOf.call(this._shortWeekdaysParse, llc);
55452                return ii !== -1 ? ii : null;
55453            } else {
55454                ii = indexOf.call(this._minWeekdaysParse, llc);
55455                return ii !== -1 ? ii : null;
55456            }
55457        } else {
55458            if (format === 'dddd') {
55459                ii = indexOf.call(this._weekdaysParse, llc);
55460                if (ii !== -1) {
55461                    return ii;
55462                }
55463                ii = indexOf.call(this._shortWeekdaysParse, llc);
55464                if (ii !== -1) {
55465                    return ii;
55466                }
55467                ii = indexOf.call(this._minWeekdaysParse, llc);
55468                return ii !== -1 ? ii : null;
55469            } else if (format === 'ddd') {
55470                ii = indexOf.call(this._shortWeekdaysParse, llc);
55471                if (ii !== -1) {
55472                    return ii;
55473                }
55474                ii = indexOf.call(this._weekdaysParse, llc);
55475                if (ii !== -1) {
55476                    return ii;
55477                }
55478                ii = indexOf.call(this._minWeekdaysParse, llc);
55479                return ii !== -1 ? ii : null;
55480            } else {
55481                ii = indexOf.call(this._minWeekdaysParse, llc);
55482                if (ii !== -1) {
55483                    return ii;
55484                }
55485                ii = indexOf.call(this._weekdaysParse, llc);
55486                if (ii !== -1) {
55487                    return ii;
55488                }
55489                ii = indexOf.call(this._shortWeekdaysParse, llc);
55490                return ii !== -1 ? ii : null;
55491            }
55492        }
55493    }
55494
55495    function localeWeekdaysParse(weekdayName, format, strict) {
55496        var i, mom, regex;
55497
55498        if (this._weekdaysParseExact) {
55499            return handleStrictParse$1.call(this, weekdayName, format, strict);
55500        }
55501
55502        if (!this._weekdaysParse) {
55503            this._weekdaysParse = [];
55504            this._minWeekdaysParse = [];
55505            this._shortWeekdaysParse = [];
55506            this._fullWeekdaysParse = [];
55507        }
55508
55509        for (i = 0; i < 7; i++) {
55510            // make the regex if we don't have it already
55511
55512            mom = createUTC([2000, 1]).day(i);
55513            if (strict && !this._fullWeekdaysParse[i]) {
55514                this._fullWeekdaysParse[i] = new RegExp(
55515                    '^' + this.weekdays(mom, '').replace('.', '\\.?') + '$',
55516                    'i'
55517                );
55518                this._shortWeekdaysParse[i] = new RegExp(
55519                    '^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$',
55520                    'i'
55521                );
55522                this._minWeekdaysParse[i] = new RegExp(
55523                    '^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$',
55524                    'i'
55525                );
55526            }
55527            if (!this._weekdaysParse[i]) {
55528                regex =
55529                    '^' +
55530                    this.weekdays(mom, '') +
55531                    '|^' +
55532                    this.weekdaysShort(mom, '') +
55533                    '|^' +
55534                    this.weekdaysMin(mom, '');
55535                this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
55536            }
55537            // test the regex
55538            if (
55539                strict &&
55540                format === 'dddd' &&
55541                this._fullWeekdaysParse[i].test(weekdayName)
55542            ) {
55543                return i;
55544            } else if (
55545                strict &&
55546                format === 'ddd' &&
55547                this._shortWeekdaysParse[i].test(weekdayName)
55548            ) {
55549                return i;
55550            } else if (
55551                strict &&
55552                format === 'dd' &&
55553                this._minWeekdaysParse[i].test(weekdayName)
55554            ) {
55555                return i;
55556            } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
55557                return i;
55558            }
55559        }
55560    }
55561
55562    // MOMENTS
55563
55564    function getSetDayOfWeek(input) {
55565        if (!this.isValid()) {
55566            return input != null ? this : NaN;
55567        }
55568        var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
55569        if (input != null) {
55570            input = parseWeekday(input, this.localeData());
55571            return this.add(input - day, 'd');
55572        } else {
55573            return day;
55574        }
55575    }
55576
55577    function getSetLocaleDayOfWeek(input) {
55578        if (!this.isValid()) {
55579            return input != null ? this : NaN;
55580        }
55581        var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
55582        return input == null ? weekday : this.add(input - weekday, 'd');
55583    }
55584
55585    function getSetISODayOfWeek(input) {
55586        if (!this.isValid()) {
55587            return input != null ? this : NaN;
55588        }
55589
55590        // behaves the same as moment#day except
55591        // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
55592        // as a setter, sunday should belong to the previous week.
55593
55594        if (input != null) {
55595            var weekday = parseIsoWeekday(input, this.localeData());
55596            return this.day(this.day() % 7 ? weekday : weekday - 7);
55597        } else {
55598            return this.day() || 7;
55599        }
55600    }
55601
55602    function weekdaysRegex(isStrict) {
55603        if (this._weekdaysParseExact) {
55604            if (!hasOwnProp(this, '_weekdaysRegex')) {
55605                computeWeekdaysParse.call(this);
55606            }
55607            if (isStrict) {
55608                return this._weekdaysStrictRegex;
55609            } else {
55610                return this._weekdaysRegex;
55611            }
55612        } else {
55613            if (!hasOwnProp(this, '_weekdaysRegex')) {
55614                this._weekdaysRegex = defaultWeekdaysRegex;
55615            }
55616            return this._weekdaysStrictRegex && isStrict
55617                ? this._weekdaysStrictRegex
55618                : this._weekdaysRegex;
55619        }
55620    }
55621
55622    function weekdaysShortRegex(isStrict) {
55623        if (this._weekdaysParseExact) {
55624            if (!hasOwnProp(this, '_weekdaysRegex')) {
55625                computeWeekdaysParse.call(this);
55626            }
55627            if (isStrict) {
55628                return this._weekdaysShortStrictRegex;
55629            } else {
55630                return this._weekdaysShortRegex;
55631            }
55632        } else {
55633            if (!hasOwnProp(this, '_weekdaysShortRegex')) {
55634                this._weekdaysShortRegex = defaultWeekdaysShortRegex;
55635            }
55636            return this._weekdaysShortStrictRegex && isStrict
55637                ? this._weekdaysShortStrictRegex
55638                : this._weekdaysShortRegex;
55639        }
55640    }
55641
55642    function weekdaysMinRegex(isStrict) {
55643        if (this._weekdaysParseExact) {
55644            if (!hasOwnProp(this, '_weekdaysRegex')) {
55645                computeWeekdaysParse.call(this);
55646            }
55647            if (isStrict) {
55648                return this._weekdaysMinStrictRegex;
55649            } else {
55650                return this._weekdaysMinRegex;
55651            }
55652        } else {
55653            if (!hasOwnProp(this, '_weekdaysMinRegex')) {
55654                this._weekdaysMinRegex = defaultWeekdaysMinRegex;
55655            }
55656            return this._weekdaysMinStrictRegex && isStrict
55657                ? this._weekdaysMinStrictRegex
55658                : this._weekdaysMinRegex;
55659        }
55660    }
55661
55662    function computeWeekdaysParse() {
55663        function cmpLenRev(a, b) {
55664            return b.length - a.length;
55665        }
55666
55667        var minPieces = [],
55668            shortPieces = [],
55669            longPieces = [],
55670            mixedPieces = [],
55671            i,
55672            mom,
55673            minp,
55674            shortp,
55675            longp;
55676        for (i = 0; i < 7; i++) {
55677            // make the regex if we don't have it already
55678            mom = createUTC([2000, 1]).day(i);
55679            minp = regexEscape(this.weekdaysMin(mom, ''));
55680            shortp = regexEscape(this.weekdaysShort(mom, ''));
55681            longp = regexEscape(this.weekdays(mom, ''));
55682            minPieces.push(minp);
55683            shortPieces.push(shortp);
55684            longPieces.push(longp);
55685            mixedPieces.push(minp);
55686            mixedPieces.push(shortp);
55687            mixedPieces.push(longp);
55688        }
55689        // Sorting makes sure if one weekday (or abbr) is a prefix of another it
55690        // will match the longer piece.
55691        minPieces.sort(cmpLenRev);
55692        shortPieces.sort(cmpLenRev);
55693        longPieces.sort(cmpLenRev);
55694        mixedPieces.sort(cmpLenRev);
55695
55696        this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
55697        this._weekdaysShortRegex = this._weekdaysRegex;
55698        this._weekdaysMinRegex = this._weekdaysRegex;
55699
55700        this._weekdaysStrictRegex = new RegExp(
55701            '^(' + longPieces.join('|') + ')',
55702            'i'
55703        );
55704        this._weekdaysShortStrictRegex = new RegExp(
55705            '^(' + shortPieces.join('|') + ')',
55706            'i'
55707        );
55708        this._weekdaysMinStrictRegex = new RegExp(
55709            '^(' + minPieces.join('|') + ')',
55710            'i'
55711        );
55712    }
55713
55714    // FORMATTING
55715
55716    function hFormat() {
55717        return this.hours() % 12 || 12;
55718    }
55719
55720    function kFormat() {
55721        return this.hours() || 24;
55722    }
55723
55724    addFormatToken('H', ['HH', 2], 0, 'hour');
55725    addFormatToken('h', ['hh', 2], 0, hFormat);
55726    addFormatToken('k', ['kk', 2], 0, kFormat);
55727
55728    addFormatToken('hmm', 0, 0, function () {
55729        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
55730    });
55731
55732    addFormatToken('hmmss', 0, 0, function () {
55733        return (
55734            '' +
55735            hFormat.apply(this) +
55736            zeroFill(this.minutes(), 2) +
55737            zeroFill(this.seconds(), 2)
55738        );
55739    });
55740
55741    addFormatToken('Hmm', 0, 0, function () {
55742        return '' + this.hours() + zeroFill(this.minutes(), 2);
55743    });
55744
55745    addFormatToken('Hmmss', 0, 0, function () {
55746        return (
55747            '' +
55748            this.hours() +
55749            zeroFill(this.minutes(), 2) +
55750            zeroFill(this.seconds(), 2)
55751        );
55752    });
55753
55754    function meridiem(token, lowercase) {
55755        addFormatToken(token, 0, 0, function () {
55756            return this.localeData().meridiem(
55757                this.hours(),
55758                this.minutes(),
55759                lowercase
55760            );
55761        });
55762    }
55763
55764    meridiem('a', true);
55765    meridiem('A', false);
55766
55767    // ALIASES
55768
55769    addUnitAlias('hour', 'h');
55770
55771    // PRIORITY
55772    addUnitPriority('hour', 13);
55773
55774    // PARSING
55775
55776    function matchMeridiem(isStrict, locale) {
55777        return locale._meridiemParse;
55778    }
55779
55780    addRegexToken('a', matchMeridiem);
55781    addRegexToken('A', matchMeridiem);
55782    addRegexToken('H', match1to2);
55783    addRegexToken('h', match1to2);
55784    addRegexToken('k', match1to2);
55785    addRegexToken('HH', match1to2, match2);
55786    addRegexToken('hh', match1to2, match2);
55787    addRegexToken('kk', match1to2, match2);
55788
55789    addRegexToken('hmm', match3to4);
55790    addRegexToken('hmmss', match5to6);
55791    addRegexToken('Hmm', match3to4);
55792    addRegexToken('Hmmss', match5to6);
55793
55794    addParseToken(['H', 'HH'], HOUR);
55795    addParseToken(['k', 'kk'], function (input, array, config) {
55796        var kInput = toInt(input);
55797        array[HOUR] = kInput === 24 ? 0 : kInput;
55798    });
55799    addParseToken(['a', 'A'], function (input, array, config) {
55800        config._isPm = config._locale.isPM(input);
55801        config._meridiem = input;
55802    });
55803    addParseToken(['h', 'hh'], function (input, array, config) {
55804        array[HOUR] = toInt(input);
55805        getParsingFlags(config).bigHour = true;
55806    });
55807    addParseToken('hmm', function (input, array, config) {
55808        var pos = input.length - 2;
55809        array[HOUR] = toInt(input.substr(0, pos));
55810        array[MINUTE] = toInt(input.substr(pos));
55811        getParsingFlags(config).bigHour = true;
55812    });
55813    addParseToken('hmmss', function (input, array, config) {
55814        var pos1 = input.length - 4,
55815            pos2 = input.length - 2;
55816        array[HOUR] = toInt(input.substr(0, pos1));
55817        array[MINUTE] = toInt(input.substr(pos1, 2));
55818        array[SECOND] = toInt(input.substr(pos2));
55819        getParsingFlags(config).bigHour = true;
55820    });
55821    addParseToken('Hmm', function (input, array, config) {
55822        var pos = input.length - 2;
55823        array[HOUR] = toInt(input.substr(0, pos));
55824        array[MINUTE] = toInt(input.substr(pos));
55825    });
55826    addParseToken('Hmmss', function (input, array, config) {
55827        var pos1 = input.length - 4,
55828            pos2 = input.length - 2;
55829        array[HOUR] = toInt(input.substr(0, pos1));
55830        array[MINUTE] = toInt(input.substr(pos1, 2));
55831        array[SECOND] = toInt(input.substr(pos2));
55832    });
55833
55834    // LOCALES
55835
55836    function localeIsPM(input) {
55837        // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
55838        // Using charAt should be more compatible.
55839        return (input + '').toLowerCase().charAt(0) === 'p';
55840    }
55841
55842    var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i,
55843        // Setting the hour should keep the time, because the user explicitly
55844        // specified which hour they want. So trying to maintain the same hour (in
55845        // a new timezone) makes sense. Adding/subtracting hours does not follow
55846        // this rule.
55847        getSetHour = makeGetSet('Hours', true);
55848
55849    function localeMeridiem(hours, minutes, isLower) {
55850        if (hours > 11) {
55851            return isLower ? 'pm' : 'PM';
55852        } else {
55853            return isLower ? 'am' : 'AM';
55854        }
55855    }
55856
55857    var baseConfig = {
55858        calendar: defaultCalendar,
55859        longDateFormat: defaultLongDateFormat,
55860        invalidDate: defaultInvalidDate,
55861        ordinal: defaultOrdinal,
55862        dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
55863        relativeTime: defaultRelativeTime,
55864
55865        months: defaultLocaleMonths,
55866        monthsShort: defaultLocaleMonthsShort,
55867
55868        week: defaultLocaleWeek,
55869
55870        weekdays: defaultLocaleWeekdays,
55871        weekdaysMin: defaultLocaleWeekdaysMin,
55872        weekdaysShort: defaultLocaleWeekdaysShort,
55873
55874        meridiemParse: defaultLocaleMeridiemParse,
55875    };
55876
55877    // internal storage for locale config files
55878    var locales = {},
55879        localeFamilies = {},
55880        globalLocale;
55881
55882    function commonPrefix(arr1, arr2) {
55883        var i,
55884            minl = Math.min(arr1.length, arr2.length);
55885        for (i = 0; i < minl; i += 1) {
55886            if (arr1[i] !== arr2[i]) {
55887                return i;
55888            }
55889        }
55890        return minl;
55891    }
55892
55893    function normalizeLocale(key) {
55894        return key ? key.toLowerCase().replace('_', '-') : key;
55895    }
55896
55897    // pick the locale from the array
55898    // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
55899    // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
55900    function chooseLocale(names) {
55901        var i = 0,
55902            j,
55903            next,
55904            locale,
55905            split;
55906
55907        while (i < names.length) {
55908            split = normalizeLocale(names[i]).split('-');
55909            j = split.length;
55910            next = normalizeLocale(names[i + 1]);
55911            next = next ? next.split('-') : null;
55912            while (j > 0) {
55913                locale = loadLocale(split.slice(0, j).join('-'));
55914                if (locale) {
55915                    return locale;
55916                }
55917                if (
55918                    next &&
55919                    next.length >= j &&
55920                    commonPrefix(split, next) >= j - 1
55921                ) {
55922                    //the next array item is better than a shallower substring of this one
55923                    break;
55924                }
55925                j--;
55926            }
55927            i++;
55928        }
55929        return globalLocale;
55930    }
55931
55932    function isLocaleNameSane(name) {
55933        // Prevent names that look like filesystem paths, i.e contain '/' or '\'
55934        return name.match('^[^/\\\\]*$') != null;
55935    }
55936
55937    function loadLocale(name) {
55938        var oldLocale = null,
55939            aliasedRequire;
55940        // TODO: Find a better way to register and load all the locales in Node
55941        if (
55942            locales[name] === undefined &&
55943            typeof module !== 'undefined' &&
55944            module &&
55945            module.exports &&
55946            isLocaleNameSane(name)
55947        ) {
55948            try {
55949                oldLocale = globalLocale._abbr;
55950                aliasedRequire = require;
55951                aliasedRequire('./locale/' + name);
55952                getSetGlobalLocale(oldLocale);
55953            } catch (e) {
55954                // mark as not found to avoid repeating expensive file require call causing high CPU
55955                // when trying to find en-US, en_US, en-us for every format call
55956                locales[name] = null; // null means not found
55957            }
55958        }
55959        return locales[name];
55960    }
55961
55962    // This function will load locale and then set the global locale.  If
55963    // no arguments are passed in, it will simply return the current global
55964    // locale key.
55965    function getSetGlobalLocale(key, values) {
55966        var data;
55967        if (key) {
55968            if (isUndefined(values)) {
55969                data = getLocale(key);
55970            } else {
55971                data = defineLocale(key, values);
55972            }
55973
55974            if (data) {
55975                // moment.duration._locale = moment._locale = data;
55976                globalLocale = data;
55977            } else {
55978                if (typeof console !== 'undefined' && console.warn) {
55979                    //warn user if arguments are passed but the locale could not be set
55980                    console.warn(
55981                        'Locale ' + key + ' not found. Did you forget to load it?'
55982                    );
55983                }
55984            }
55985        }
55986
55987        return globalLocale._abbr;
55988    }
55989
55990    function defineLocale(name, config) {
55991        if (config !== null) {
55992            var locale,
55993                parentConfig = baseConfig;
55994            config.abbr = name;
55995            if (locales[name] != null) {
55996                deprecateSimple(
55997                    'defineLocaleOverride',
55998                    'use moment.updateLocale(localeName, config) to change ' +
55999                        'an existing locale. moment.defineLocale(localeName, ' +
56000                        'config) should only be used for creating a new locale ' +
56001                        'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.'
56002                );
56003                parentConfig = locales[name]._config;
56004            } else if (config.parentLocale != null) {
56005                if (locales[config.parentLocale] != null) {
56006                    parentConfig = locales[config.parentLocale]._config;
56007                } else {
56008                    locale = loadLocale(config.parentLocale);
56009                    if (locale != null) {
56010                        parentConfig = locale._config;
56011                    } else {
56012                        if (!localeFamilies[config.parentLocale]) {
56013                            localeFamilies[config.parentLocale] = [];
56014                        }
56015                        localeFamilies[config.parentLocale].push({
56016                            name: name,
56017                            config: config,
56018                        });
56019                        return null;
56020                    }
56021                }
56022            }
56023            locales[name] = new Locale(mergeConfigs(parentConfig, config));
56024
56025            if (localeFamilies[name]) {
56026                localeFamilies[name].forEach(function (x) {
56027                    defineLocale(x.name, x.config);
56028                });
56029            }
56030
56031            // backwards compat for now: also set the locale
56032            // make sure we set the locale AFTER all child locales have been
56033            // created, so we won't end up with the child locale set.
56034            getSetGlobalLocale(name);
56035
56036            return locales[name];
56037        } else {
56038            // useful for testing
56039            delete locales[name];
56040            return null;
56041        }
56042    }
56043
56044    function updateLocale(name, config) {
56045        if (config != null) {
56046            var locale,
56047                tmpLocale,
56048                parentConfig = baseConfig;
56049
56050            if (locales[name] != null && locales[name].parentLocale != null) {
56051                // Update existing child locale in-place to avoid memory-leaks
56052                locales[name].set(mergeConfigs(locales[name]._config, config));
56053            } else {
56054                // MERGE
56055                tmpLocale = loadLocale(name);
56056                if (tmpLocale != null) {
56057                    parentConfig = tmpLocale._config;
56058                }
56059                config = mergeConfigs(parentConfig, config);
56060                if (tmpLocale == null) {
56061                    // updateLocale is called for creating a new locale
56062                    // Set abbr so it will have a name (getters return
56063                    // undefined otherwise).
56064                    config.abbr = name;
56065                }
56066                locale = new Locale(config);
56067                locale.parentLocale = locales[name];
56068                locales[name] = locale;
56069            }
56070
56071            // backwards compat for now: also set the locale
56072            getSetGlobalLocale(name);
56073        } else {
56074            // pass null for config to unupdate, useful for tests
56075            if (locales[name] != null) {
56076                if (locales[name].parentLocale != null) {
56077                    locales[name] = locales[name].parentLocale;
56078                    if (name === getSetGlobalLocale()) {
56079                        getSetGlobalLocale(name);
56080                    }
56081                } else if (locales[name] != null) {
56082                    delete locales[name];
56083                }
56084            }
56085        }
56086        return locales[name];
56087    }
56088
56089    // returns locale data
56090    function getLocale(key) {
56091        var locale;
56092
56093        if (key && key._locale && key._locale._abbr) {
56094            key = key._locale._abbr;
56095        }
56096
56097        if (!key) {
56098            return globalLocale;
56099        }
56100
56101        if (!isArray(key)) {
56102            //short-circuit everything else
56103            locale = loadLocale(key);
56104            if (locale) {
56105                return locale;
56106            }
56107            key = [key];
56108        }
56109
56110        return chooseLocale(key);
56111    }
56112
56113    function listLocales() {
56114        return keys(locales);
56115    }
56116
56117    function checkOverflow(m) {
56118        var overflow,
56119            a = m._a;
56120
56121        if (a && getParsingFlags(m).overflow === -2) {
56122            overflow =
56123                a[MONTH] < 0 || a[MONTH] > 11
56124                    ? MONTH
56125                    : a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH])
56126                    ? DATE
56127                    : a[HOUR] < 0 ||
56128                      a[HOUR] > 24 ||
56129                      (a[HOUR] === 24 &&
56130                          (a[MINUTE] !== 0 ||
56131                              a[SECOND] !== 0 ||
56132                              a[MILLISECOND] !== 0))
56133                    ? HOUR
56134                    : a[MINUTE] < 0 || a[MINUTE] > 59
56135                    ? MINUTE
56136                    : a[SECOND] < 0 || a[SECOND] > 59
56137                    ? SECOND
56138                    : a[MILLISECOND] < 0 || a[MILLISECOND] > 999
56139                    ? MILLISECOND
vendor: 9,346 bytes, lines 56140-56423
56140                    : -1;
56141
56142            if (
56143                getParsingFlags(m)._overflowDayOfYear &&
56144                (overflow < YEAR || overflow > DATE)
56145            ) {
56146                overflow = DATE;
56147            }
56148            if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
56149                overflow = WEEK;
56150            }
56151            if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
56152                overflow = WEEKDAY;
56153            }
56154
56155            getParsingFlags(m).overflow = overflow;
56156        }
56157
56158        return m;
56159    }
56160
56161    // iso 8601 regex
56162    // 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)
56163    var extendedIsoRegex =
56164            /^\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)?)?$/,
56165        basicIsoRegex =
56166            /^\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)?)?$/,
56167        tzRegex = /Z|[+-]\d\d(?::?\d\d)?/,
56168        isoDates = [
56169            ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/],
56170            ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/],
56171            ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/],
56172            ['GGGG-[W]WW', /\d{4}-W\d\d/, false],
56173            ['YYYY-DDD', /\d{4}-\d{3}/],
56174            ['YYYY-MM', /\d{4}-\d\d/, false],
56175            ['YYYYYYMMDD', /[+-]\d{10}/],
56176            ['YYYYMMDD', /\d{8}/],
56177            ['GGGG[W]WWE', /\d{4}W\d{3}/],
56178            ['GGGG[W]WW', /\d{4}W\d{2}/, false],
56179            ['YYYYDDD', /\d{7}/],
56180            ['YYYYMM', /\d{6}/, false],
56181            ['YYYY', /\d{4}/, false],
56182        ],
56183        // iso time formats and regexes
56184        isoTimes = [
56185            ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
56186            ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
56187            ['HH:mm:ss', /\d\d:\d\d:\d\d/],
56188            ['HH:mm', /\d\d:\d\d/],
56189            ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/],
56190            ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/],
56191            ['HHmmss', /\d\d\d\d\d\d/],
56192            ['HHmm', /\d\d\d\d/],
56193            ['HH', /\d\d/],
56194        ],
56195        aspNetJsonRegex = /^\/?Date\((-?\d+)/i,
56196        // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
56197        rfc2822 =
56198            /^(?:(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}))$/,
56199        obsOffsets = {
56200            UT: 0,
56201            GMT: 0,
56202            EDT: -4 * 60,
56203            EST: -5 * 60,
56204            CDT: -5 * 60,
56205            CST: -6 * 60,
56206            MDT: -6 * 60,
56207            MST: -7 * 60,
56208            PDT: -7 * 60,
56209            PST: -8 * 60,
56210        };
56211
56212    // date from iso format
56213    function configFromISO(config) {
56214        var i,
56215            l,
56216            string = config._i,
56217            match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
56218            allowTime,
56219            dateFormat,
56220            timeFormat,
56221            tzFormat,
56222            isoDatesLen = isoDates.length,
56223            isoTimesLen = isoTimes.length;
56224
56225        if (match) {
56226            getParsingFlags(config).iso = true;
56227            for (i = 0, l = isoDatesLen; i < l; i++) {
56228                if (isoDates[i][1].exec(match[1])) {
56229                    dateFormat = isoDates[i][0];
56230                    allowTime = isoDates[i][2] !== false;
56231                    break;
56232                }
56233            }
56234            if (dateFormat == null) {
56235                config._isValid = false;
56236                return;
56237            }
56238            if (match[3]) {
56239                for (i = 0, l = isoTimesLen; i < l; i++) {
56240                    if (isoTimes[i][1].exec(match[3])) {
56241                        // match[2] should be 'T' or space
56242                        timeFormat = (match[2] || ' ') + isoTimes[i][0];
56243                        break;
56244                    }
56245                }
56246                if (timeFormat == null) {
56247                    config._isValid = false;
56248                    return;
56249                }
56250            }
56251            if (!allowTime && timeFormat != null) {
56252                config._isValid = false;
56253                return;
56254            }
56255            if (match[4]) {
56256                if (tzRegex.exec(match[4])) {
56257                    tzFormat = 'Z';
56258                } else {
56259                    config._isValid = false;
56260                    return;
56261                }
56262            }
56263            config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
56264            configFromStringAndFormat(config);
56265        } else {
56266            config._isValid = false;
56267        }
56268    }
56269
56270    function extractFromRFC2822Strings(
56271        yearStr,
56272        monthStr,
56273        dayStr,
56274        hourStr,
56275        minuteStr,
56276        secondStr
56277    ) {
56278        var result = [
56279            untruncateYear(yearStr),
56280            defaultLocaleMonthsShort.indexOf(monthStr),
56281            parseInt(dayStr, 10),
56282            parseInt(hourStr, 10),
56283            parseInt(minuteStr, 10),
56284        ];
56285
56286        if (secondStr) {
56287            result.push(parseInt(secondStr, 10));
56288        }
56289
56290        return result;
56291    }
56292
56293    function untruncateYear(yearStr) {
56294        var year = parseInt(yearStr, 10);
56295        if (year <= 49) {
56296            return 2000 + year;
56297        } else if (year <= 999) {
56298            return 1900 + year;
56299        }
56300        return year;
56301    }
56302
56303    function preprocessRFC2822(s) {
56304        // Remove comments and folding whitespace and replace multiple-spaces with a single space
56305        return s
56306            .replace(/\([^()]*\)|[\n\t]/g, ' ')
56307            .replace(/(\s\s+)/g, ' ')
56308            .replace(/^\s\s*/, '')
56309            .replace(/\s\s*$/, '');
56310    }
56311
56312    function checkWeekday(weekdayStr, parsedInput, config) {
56313        if (weekdayStr) {
56314            // TODO: Replace the vanilla JS Date object with an independent day-of-week check.
56315            var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),
56316                weekdayActual = new Date(
56317                    parsedInput[0],
56318                    parsedInput[1],
56319                    parsedInput[2]
56320                ).getDay();
56321            if (weekdayProvided !== weekdayActual) {
56322                getParsingFlags(config).weekdayMismatch = true;
56323                config._isValid = false;
56324                return false;
56325            }
56326        }
56327        return true;
56328    }
56329
56330    function calculateOffset(obsOffset, militaryOffset, numOffset) {
56331        if (obsOffset) {
56332            return obsOffsets[obsOffset];
56333        } else if (militaryOffset) {
56334            // the only allowed military tz is Z
56335            return 0;
56336        } else {
56337            var hm = parseInt(numOffset, 10),
56338                m = hm % 100,
56339                h = (hm - m) / 100;
56340            return h * 60 + m;
56341        }
56342    }
56343
56344    // date and time from ref 2822 format
56345    function configFromRFC2822(config) {
56346        var match = rfc2822.exec(preprocessRFC2822(config._i)),
56347            parsedArray;
56348        if (match) {
56349            parsedArray = extractFromRFC2822Strings(
56350                match[4],
56351                match[3],
56352                match[2],
56353                match[5],
56354                match[6],
56355                match[7]
56356            );
56357            if (!checkWeekday(match[1], parsedArray, config)) {
56358                return;
56359            }
56360
56361            config._a = parsedArray;
56362            config._tzm = calculateOffset(match[8], match[9], match[10]);
56363
56364            config._d = createUTCDate.apply(null, config._a);
56365            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
56366
56367            getParsingFlags(config).rfc2822 = true;
56368        } else {
56369            config._isValid = false;
56370        }
56371    }
56372
56373    // date from 1) ASP.NET, 2) ISO, 3) RFC 2822 formats, or 4) optional fallback if parsing isn't strict
56374    function configFromString(config) {
56375        var matched = aspNetJsonRegex.exec(config._i);
56376        if (matched !== null) {
56377            config._d = new Date(+matched[1]);
56378            return;
56379        }
56380
56381        configFromISO(config);
56382        if (config._isValid === false) {
56383            delete config._isValid;
56384        } else {
56385            return;
56386        }
56387
56388        configFromRFC2822(config);
56389        if (config._isValid === false) {
56390            delete config._isValid;
56391        } else {
56392            return;
56393        }
56394
56395        if (config._strict) {
56396            config._isValid = false;
56397        } else {
56398            // Final attempt, use Input Fallback
56399            hooks.createFromInputFallback(config);
56400        }
56401    }
56402
56403    hooks.createFromInputFallback = deprecate(
56404        'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +
56405            'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +
56406            'discouraged. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.',
56407        function (config) {
56408            config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
56409        }
56410    );
56411
56412    // Pick the first defined of two or three arguments.
56413    function defaults(a, b, c) {
56414        if (a != null) {
56415            return a;
56416        }
56417        if (b != null) {
56418            return b;
56419        }
56420        return c;
56421    }
56422
56423    function currentDateArray(config
vendor: 94,968 bytes, lines 56423-59535
56423) {
56424        // hooks is actually the exported moment object
56425        var nowValue = new Date(hooks.now());
56426        if (config._useUTC) {
56427            return [
56428                nowValue.getUTCFullYear(),
56429                nowValue.getUTCMonth(),
56430                nowValue.getUTCDate(),
56431            ];
56432        }
56433        return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
56434    }
56435
56436    // convert an array to a date.
56437    // the array should mirror the parameters below
56438    // note: all values past the year are optional and will default to the lowest possible value.
56439    // [year, month, day , hour, minute, second, millisecond]
56440    function configFromArray(config) {
56441        var i,
56442            date,
56443            input = [],
56444            currentDate,
56445            expectedWeekday,
56446            yearToUse;
56447
56448        if (config._d) {
56449            return;
56450        }
56451
56452        currentDate = currentDateArray(config);
56453
56454        //compute day of the year from weeks and weekdays
56455        if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
56456            dayOfYearFromWeekInfo(config);
56457        }
56458
56459        //if the day of the year is set, figure out what it is
56460        if (config._dayOfYear != null) {
56461            yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
56462
56463            if (
56464                config._dayOfYear > daysInYear(yearToUse) ||
56465                config._dayOfYear === 0
56466            ) {
56467                getParsingFlags(config)._overflowDayOfYear = true;
56468            }
56469
56470            date = createUTCDate(yearToUse, 0, config._dayOfYear);
56471            config._a[MONTH] = date.getUTCMonth();
56472            config._a[DATE] = date.getUTCDate();
56473        }
56474
56475        // Default to current date.
56476        // * if no year, month, day of month are given, default to today
56477        // * if day of month is given, default month and year
56478        // * if month is given, default only year
56479        // * if year is given, don't default anything
56480        for (i = 0; i < 3 && config._a[i] == null; ++i) {
56481            config._a[i] = input[i] = currentDate[i];
56482        }
56483
56484        // Zero out whatever was not defaulted, including time
56485        for (; i < 7; i++) {
56486            config._a[i] = input[i] =
56487                config._a[i] == null ? (i === 2 ? 1 : 0) : config._a[i];
56488        }
56489
56490        // Check for 24:00:00.000
56491        if (
56492            config._a[HOUR] === 24 &&
56493            config._a[MINUTE] === 0 &&
56494            config._a[SECOND] === 0 &&
56495            config._a[MILLISECOND] === 0
56496        ) {
56497            config._nextDay = true;
56498            config._a[HOUR] = 0;
56499        }
56500
56501        config._d = (config._useUTC ? createUTCDate : createDate).apply(
56502            null,
56503            input
56504        );
56505        expectedWeekday = config._useUTC
56506            ? config._d.getUTCDay()
56507            : config._d.getDay();
56508
56509        // Apply timezone offset from input. The actual utcOffset can be changed
56510        // with parseZone.
56511        if (config._tzm != null) {
56512            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
56513        }
56514
56515        if (config._nextDay) {
56516            config._a[HOUR] = 24;
56517        }
56518
56519        // check for mismatching day of week
56520        if (
56521            config._w &&
56522            typeof config._w.d !== 'undefined' &&
56523            config._w.d !== expectedWeekday
56524        ) {
56525            getParsingFlags(config).weekdayMismatch = true;
56526        }
56527    }
56528
56529    function dayOfYearFromWeekInfo(config) {
56530        var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow, curWeek;
56531
56532        w = config._w;
56533        if (w.GG != null || w.W != null || w.E != null) {
56534            dow = 1;
56535            doy = 4;
56536
56537            // TODO: We need to take the current isoWeekYear, but that depends on
56538            // how we interpret now (local, utc, fixed offset). So create
56539            // a now version of current config (take local/utc/offset flags, and
56540            // create now).
56541            weekYear = defaults(
56542                w.GG,
56543                config._a[YEAR],
56544                weekOfYear(createLocal(), 1, 4).year
56545            );
56546            week = defaults(w.W, 1);
56547            weekday = defaults(w.E, 1);
56548            if (weekday < 1 || weekday > 7) {
56549                weekdayOverflow = true;
56550            }
56551        } else {
56552            dow = config._locale._week.dow;
56553            doy = config._locale._week.doy;
56554
56555            curWeek = weekOfYear(createLocal(), dow, doy);
56556
56557            weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);
56558
56559            // Default to current week.
56560            week = defaults(w.w, curWeek.week);
56561
56562            if (w.d != null) {
56563                // weekday -- low day numbers are considered next week
56564                weekday = w.d;
56565                if (weekday < 0 || weekday > 6) {
56566                    weekdayOverflow = true;
56567                }
56568            } else if (w.e != null) {
56569                // local weekday -- counting starts from beginning of week
56570                weekday = w.e + dow;
56571                if (w.e < 0 || w.e > 6) {
56572                    weekdayOverflow = true;
56573                }
56574            } else {
56575                // default to beginning of week
56576                weekday = dow;
56577            }
56578        }
56579        if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
56580            getParsingFlags(config)._overflowWeeks = true;
56581        } else if (weekdayOverflow != null) {
56582            getParsingFlags(config)._overflowWeekday = true;
56583        } else {
56584            temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
56585            config._a[YEAR] = temp.year;
56586            config._dayOfYear = temp.dayOfYear;
56587        }
56588    }
56589
56590    // constant that refers to the ISO standard
56591    hooks.ISO_8601 = function () {};
56592
56593    // constant that refers to the RFC 2822 form
56594    hooks.RFC_2822 = function () {};
56595
56596    // date from string and format string
56597    function configFromStringAndFormat(config) {
56598        // TODO: Move this to another part of the creation flow to prevent circular deps
56599        if (config._f === hooks.ISO_8601) {
56600            configFromISO(config);
56601            return;
56602        }
56603        if (config._f === hooks.RFC_2822) {
56604            configFromRFC2822(config);
56605            return;
56606        }
56607        config._a = [];
56608        getParsingFlags(config).empty = true;
56609
56610        // This array is used to make a Date, either with `new Date` or `Date.UTC`
56611        var string = '' + config._i,
56612            i,
56613            parsedInput,
56614            tokens,
56615            token,
56616            skipped,
56617            stringLength = string.length,
56618            totalParsedInputLength = 0,
56619            era,
56620            tokenLen;
56621
56622        tokens =
56623            expandFormat(config._f, config._locale).match(formattingTokens) || [];
56624        tokenLen = tokens.length;
56625        for (i = 0; i < tokenLen; i++) {
56626            token = tokens[i];
56627            parsedInput = (string.match(getParseRegexForToken(token, config)) ||
56628                [])[0];
56629            if (parsedInput) {
56630                skipped = string.substr(0, string.indexOf(parsedInput));
56631                if (skipped.length > 0) {
56632                    getParsingFlags(config).unusedInput.push(skipped);
56633                }
56634                string = string.slice(
56635                    string.indexOf(parsedInput) + parsedInput.length
56636                );
56637                totalParsedInputLength += parsedInput.length;
56638            }
56639            // don't parse if it's not a known token
56640            if (formatTokenFunctions[token]) {
56641                if (parsedInput) {
56642                    getParsingFlags(config).empty = false;
56643                } else {
56644                    getParsingFlags(config).unusedTokens.push(token);
56645                }
56646                addTimeToArrayFromToken(token, parsedInput, config);
56647            } else if (config._strict && !parsedInput) {
56648                getParsingFlags(config).unusedTokens.push(token);
56649            }
56650        }
56651
56652        // add remaining unparsed input length to the string
56653        getParsingFlags(config).charsLeftOver =
56654            stringLength - totalParsedInputLength;
56655        if (string.length > 0) {
56656            getParsingFlags(config).unusedInput.push(string);
56657        }
56658
56659        // clear _12h flag if hour is <= 12
56660        if (
56661            config._a[HOUR] <= 12 &&
56662            getParsingFlags(config).bigHour === true &&
56663            config._a[HOUR] > 0
56664        ) {
56665            getParsingFlags(config).bigHour = undefined;
56666        }
56667
56668        getParsingFlags(config).parsedDateParts = config._a.slice(0);
56669        getParsingFlags(config).meridiem = config._meridiem;
56670        // handle meridiem
56671        config._a[HOUR] = meridiemFixWrap(
56672            config._locale,
56673            config._a[HOUR],
56674            config._meridiem
56675        );
56676
56677        // handle era
56678        era = getParsingFlags(config).era;
56679        if (era !== null) {
56680            config._a[YEAR] = config._locale.erasConvertYear(era, config._a[YEAR]);
56681        }
56682
56683        configFromArray(config);
56684        checkOverflow(config);
56685    }
56686
56687    function meridiemFixWrap(locale, hour, meridiem) {
56688        var isPm;
56689
56690        if (meridiem == null) {
56691            // nothing to do
56692            return hour;
56693        }
56694        if (locale.meridiemHour != null) {
56695            return locale.meridiemHour(hour, meridiem);
56696        } else if (locale.isPM != null) {
56697            // Fallback
56698            isPm = locale.isPM(meridiem);
56699            if (isPm && hour < 12) {
56700                hour += 12;
56701            }
56702            if (!isPm && hour === 12) {
56703                hour = 0;
56704            }
56705            return hour;
56706        } else {
56707            // this is not supposed to happen
56708            return hour;
56709        }
56710    }
56711
56712    // date from string and array of format strings
56713    function configFromStringAndArray(config) {
56714        var tempConfig,
56715            bestMoment,
56716            scoreToBeat,
56717            i,
56718            currentScore,
56719            validFormatFound,
56720            bestFormatIsValid = false,
56721            configfLen = config._f.length;
56722
56723        if (configfLen === 0) {
56724            getParsingFlags(config).invalidFormat = true;
56725            config._d = new Date(NaN);
56726            return;
56727        }
56728
56729        for (i = 0; i < configfLen; i++) {
56730            currentScore = 0;
56731            validFormatFound = false;
56732            tempConfig = copyConfig({}, config);
56733            if (config._useUTC != null) {
56734                tempConfig._useUTC = config._useUTC;
56735            }
56736            tempConfig._f = config._f[i];
56737            configFromStringAndFormat(tempConfig);
56738
56739            if (isValid(tempConfig)) {
56740                validFormatFound = true;
56741            }
56742
56743            // if there is any input that was not parsed add a penalty for that format
56744            currentScore += getParsingFlags(tempConfig).charsLeftOver;
56745
56746            //or tokens
56747            currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
56748
56749            getParsingFlags(tempConfig).score = currentScore;
56750
56751            if (!bestFormatIsValid) {
56752                if (
56753                    scoreToBeat == null ||
56754                    currentScore < scoreToBeat ||
56755                    validFormatFound
56756                ) {
56757                    scoreToBeat = currentScore;
56758                    bestMoment = tempConfig;
56759                    if (validFormatFound) {
56760                        bestFormatIsValid = true;
56761                    }
56762                }
56763            } else {
56764                if (currentScore < scoreToBeat) {
56765                    scoreToBeat = currentScore;
56766                    bestMoment = tempConfig;
56767                }
56768            }
56769        }
56770
56771        extend(config, bestMoment || tempConfig);
56772    }
56773
56774    function configFromObject(config) {
56775        if (config._d) {
56776            return;
56777        }
56778
56779        var i = normalizeObjectUnits(config._i),
56780            dayOrDate = i.day === undefined ? i.date : i.day;
56781        config._a = map(
56782            [i.year, i.month, dayOrDate, i.hour, i.minute, i.second, i.millisecond],
56783            function (obj) {
56784                return obj && parseInt(obj, 10);
56785            }
56786        );
56787
56788        configFromArray(config);
56789    }
56790
56791    function createFromConfig(config) {
56792        var res = new Moment(checkOverflow(prepareConfig(config)));
56793        if (res._nextDay) {
56794            // Adding is smart enough around DST
56795            res.add(1, 'd');
56796            res._nextDay = undefined;
56797        }
56798
56799        return res;
56800    }
56801
56802    function prepareConfig(config) {
56803        var input = config._i,
56804            format = config._f;
56805
56806        config._locale = config._locale || getLocale(config._l);
56807
56808        if (input === null || (format === undefined && input === '')) {
56809            return createInvalid({ nullInput: true });
56810        }
56811
56812        if (typeof input === 'string') {
56813            config._i = input = config._locale.preparse(input);
56814        }
56815
56816        if (isMoment(input)) {
56817            return new Moment(checkOverflow(input));
56818        } else if (isDate(input)) {
56819            config._d = input;
56820        } else if (isArray(format)) {
56821            configFromStringAndArray(config);
56822        } else if (format) {
56823            configFromStringAndFormat(config);
56824        } else {
56825            configFromInput(config);
56826        }
56827
56828        if (!isValid(config)) {
56829            config._d = null;
56830        }
56831
56832        return config;
56833    }
56834
56835    function configFromInput(config) {
56836        var input = config._i;
56837        if (isUndefined(input)) {
56838            config._d = new Date(hooks.now());
56839        } else if (isDate(input)) {
56840            config._d = new Date(input.valueOf());
56841        } else if (typeof input === 'string') {
56842            configFromString(config);
56843        } else if (isArray(input)) {
56844            config._a = map(input.slice(0), function (obj) {
56845                return parseInt(obj, 10);
56846            });
56847            configFromArray(config);
56848        } else if (isObject(input)) {
56849            configFromObject(config);
56850        } else if (isNumber(input)) {
56851            // from milliseconds
56852            config._d = new Date(input);
56853        } else {
56854            hooks.createFromInputFallback(config);
56855        }
56856    }
56857
56858    function createLocalOrUTC(input, format, locale, strict, isUTC) {
56859        var c = {};
56860
56861        if (format === true || format === false) {
56862            strict = format;
56863            format = undefined;
56864        }
56865
56866        if (locale === true || locale === false) {
56867            strict = locale;
56868            locale = undefined;
56869        }
56870
56871        if (
56872            (isObject(input) && isObjectEmpty(input)) ||
56873            (isArray(input) && input.length === 0)
56874        ) {
56875            input = undefined;
56876        }
56877        // object construction must be done this way.
56878        // https://github.com/moment/moment/issues/1423
56879        c._isAMomentObject = true;
56880        c._useUTC = c._isUTC = isUTC;
56881        c._l = locale;
56882        c._i = input;
56883        c._f = format;
56884        c._strict = strict;
56885
56886        return createFromConfig(c);
56887    }
56888
56889    function createLocal(input, format, locale, strict) {
56890        return createLocalOrUTC(input, format, locale, strict, false);
56891    }
56892
56893    var prototypeMin = deprecate(
56894            'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',
56895            function () {
56896                var other = createLocal.apply(null, arguments);
56897                if (this.isValid() && other.isValid()) {
56898                    return other < this ? this : other;
56899                } else {
56900                    return createInvalid();
56901                }
56902            }
56903        ),
56904        prototypeMax = deprecate(
56905            'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',
56906            function () {
56907                var other = createLocal.apply(null, arguments);
56908                if (this.isValid() && other.isValid()) {
56909                    return other > this ? this : other;
56910                } else {
56911                    return createInvalid();
56912                }
56913            }
56914        );
56915
56916    // Pick a moment m from moments so that m[fn](other) is true for all
56917    // other. This relies on the function fn to be transitive.
56918    //
56919    // moments should either be an array of moment objects or an array, whose
56920    // first element is an array of moment objects.
56921    function pickBy(fn, moments) {
56922        var res, i;
56923        if (moments.length === 1 && isArray(moments[0])) {
56924            moments = moments[0];
56925        }
56926        if (!moments.length) {
56927            return createLocal();
56928        }
56929        res = moments[0];
56930        for (i = 1; i < moments.length; ++i) {
56931            if (!moments[i].isValid() || moments[i][fn](res)) {
56932                res = moments[i];
56933            }
56934        }
56935        return res;
56936    }
56937
56938    // TODO: Use [].sort instead?
56939    function min() {
56940        var args = [].slice.call(arguments, 0);
56941
56942        return pickBy('isBefore', args);
56943    }
56944
56945    function max() {
56946        var args = [].slice.call(arguments, 0);
56947
56948        return pickBy('isAfter', args);
56949    }
56950
56951    var now = function () {
56952        return Date.now ? Date.now() : +new Date();
56953    };
56954
56955    var ordering = [
56956        'year',
56957        'quarter',
56958        'month',
56959        'week',
56960        'day',
56961        'hour',
56962        'minute',
56963        'second',
56964        'millisecond',
56965    ];
56966
56967    function isDurationValid(m) {
56968        var key,
56969            unitHasDecimal = false,
56970            i,
56971            orderLen = ordering.length;
56972        for (key in m) {
56973            if (
56974                hasOwnProp(m, key) &&
56975                !(
56976                    indexOf.call(ordering, key) !== -1 &&
56977                    (m[key] == null || !isNaN(m[key]))
56978                )
56979            ) {
56980                return false;
56981            }
56982        }
56983
56984        for (i = 0; i < orderLen; ++i) {
56985            if (m[ordering[i]]) {
56986                if (unitHasDecimal) {
56987                    return false; // only allow non-integers for smallest unit
56988                }
56989                if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
56990                    unitHasDecimal = true;
56991                }
56992            }
56993        }
56994
56995        return true;
56996    }
56997
56998    function isValid$1() {
56999        return this._isValid;
57000    }
57001
57002    function createInvalid$1() {
57003        return createDuration(NaN);
57004    }
57005
57006    function Duration(duration) {
57007        var normalizedInput = normalizeObjectUnits(duration),
57008            years = normalizedInput.year || 0,
57009            quarters = normalizedInput.quarter || 0,
57010            months = normalizedInput.month || 0,
57011            weeks = normalizedInput.week || normalizedInput.isoWeek || 0,
57012            days = normalizedInput.day || 0,
57013            hours = normalizedInput.hour || 0,
57014            minutes = normalizedInput.minute || 0,
57015            seconds = normalizedInput.second || 0,
57016            milliseconds = normalizedInput.millisecond || 0;
57017
57018        this._isValid = isDurationValid(normalizedInput);
57019
57020        // representation for dateAddRemove
57021        this._milliseconds =
57022            +milliseconds +
57023            seconds * 1e3 + // 1000
57024            minutes * 6e4 + // 1000 * 60
57025            hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
57026        // Because of dateAddRemove treats 24 hours as different from a
57027        // day when working around DST, we need to store them separately
57028        this._days = +days + weeks * 7;
57029        // It is impossible to translate months into days without knowing
57030        // which months you are are talking about, so we have to store
57031        // it separately.
57032        this._months = +months + quarters * 3 + years * 12;
57033
57034        this._data = {};
57035
57036        this._locale = getLocale();
57037
57038        this._bubble();
57039    }
57040
57041    function isDuration(obj) {
57042        return obj instanceof Duration;
57043    }
57044
57045    function absRound(number) {
57046        if (number < 0) {
57047            return Math.round(-1 * number) * -1;
57048        } else {
57049            return Math.round(number);
57050        }
57051    }
57052
57053    // compare two arrays, return the number of differences
57054    function compareArrays(array1, array2, dontConvert) {
57055        var len = Math.min(array1.length, array2.length),
57056            lengthDiff = Math.abs(array1.length - array2.length),
57057            diffs = 0,
57058            i;
57059        for (i = 0; i < len; i++) {
57060            if (
57061                (dontConvert && array1[i] !== array2[i]) ||
57062                (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))
57063            ) {
57064                diffs++;
57065            }
57066        }
57067        return diffs + lengthDiff;
57068    }
57069
57070    // FORMATTING
57071
57072    function offset(token, separator) {
57073        addFormatToken(token, 0, 0, function () {
57074            var offset = this.utcOffset(),
57075                sign = '+';
57076            if (offset < 0) {
57077                offset = -offset;
57078                sign = '-';
57079            }
57080            return (
57081                sign +
57082                zeroFill(~~(offset / 60), 2) +
57083                separator +
57084                zeroFill(~~offset % 60, 2)
57085            );
57086        });
57087    }
57088
57089    offset('Z', ':');
57090    offset('ZZ', '');
57091
57092    // PARSING
57093
57094    addRegexToken('Z', matchShortOffset);
57095    addRegexToken('ZZ', matchShortOffset);
57096    addParseToken(['Z', 'ZZ'], function (input, array, config) {
57097        config._useUTC = true;
57098        config._tzm = offsetFromString(matchShortOffset, input);
57099    });
57100
57101    // HELPERS
57102
57103    // timezone chunker
57104    // '+10:00' > ['10',  '00']
57105    // '-1530'  > ['-15', '30']
57106    var chunkOffset = /([\+\-]|\d\d)/gi;
57107
57108    function offsetFromString(matcher, string) {
57109        var matches = (string || '').match(matcher),
57110            chunk,
57111            parts,
57112            minutes;
57113
57114        if (matches === null) {
57115            return null;
57116        }
57117
57118        chunk = matches[matches.length - 1] || [];
57119        parts = (chunk + '').match(chunkOffset) || ['-', 0, 0];
57120        minutes = +(parts[1] * 60) + toInt(parts[2]);
57121
57122        return minutes === 0 ? 0 : parts[0] === '+' ? minutes : -minutes;
57123    }
57124
57125    // Return a moment from input, that is local/utc/zone equivalent to model.
57126    function cloneWithOffset(input, model) {
57127        var res, diff;
57128        if (model._isUTC) {
57129            res = model.clone();
57130            diff =
57131                (isMoment(input) || isDate(input)
57132                    ? input.valueOf()
57133                    : createLocal(input).valueOf()) - res.valueOf();
57134            // Use low-level api, because this fn is low-level api.
57135            res._d.setTime(res._d.valueOf() + diff);
57136            hooks.updateOffset(res, false);
57137            return res;
57138        } else {
57139            return createLocal(input).local();
57140        }
57141    }
57142
57143    function getDateOffset(m) {
57144        // On Firefox.24 Date#getTimezoneOffset returns a floating point.
57145        // https://github.com/moment/moment/pull/1871
57146        return -Math.round(m._d.getTimezoneOffset());
57147    }
57148
57149    // HOOKS
57150
57151    // This function will be called whenever a moment is mutated.
57152    // It is intended to keep the offset in sync with the timezone.
57153    hooks.updateOffset = function () {};
57154
57155    // MOMENTS
57156
57157    // keepLocalTime = true means only change the timezone, without
57158    // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
57159    // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
57160    // +0200, so we adjust the time as needed, to be valid.
57161    //
57162    // Keeping the time actually adds/subtracts (one hour)
57163    // from the actual represented time. That is why we call updateOffset
57164    // a second time. In case it wants us to change the offset again
57165    // _changeInProgress == true case, then we have to adjust, because
57166    // there is no such time in the given timezone.
57167    function getSetOffset(input, keepLocalTime, keepMinutes) {
57168        var offset = this._offset || 0,
57169            localAdjust;
57170        if (!this.isValid()) {
57171            return input != null ? this : NaN;
57172        }
57173        if (input != null) {
57174            if (typeof input === 'string') {
57175                input = offsetFromString(matchShortOffset, input);
57176                if (input === null) {
57177                    return this;
57178                }
57179            } else if (Math.abs(input) < 16 && !keepMinutes) {
57180                input = input * 60;
57181            }
57182            if (!this._isUTC && keepLocalTime) {
57183                localAdjust = getDateOffset(this);
57184            }
57185            this._offset = input;
57186            this._isUTC = true;
57187            if (localAdjust != null) {
57188                this.add(localAdjust, 'm');
57189            }
57190            if (offset !== input) {
57191                if (!keepLocalTime || this._changeInProgress) {
57192                    addSubtract(
57193                        this,
57194                        createDuration(input - offset, 'm'),
57195                        1,
57196                        false
57197                    );
57198                } else if (!this._changeInProgress) {
57199                    this._changeInProgress = true;
57200                    hooks.updateOffset(this, true);
57201                    this._changeInProgress = null;
57202                }
57203            }
57204            return this;
57205        } else {
57206            return this._isUTC ? offset : getDateOffset(this);
57207        }
57208    }
57209
57210    function getSetZone(input, keepLocalTime) {
57211        if (input != null) {
57212            if (typeof input !== 'string') {
57213                input = -input;
57214            }
57215
57216            this.utcOffset(input, keepLocalTime);
57217
57218            return this;
57219        } else {
57220            return -this.utcOffset();
57221        }
57222    }
57223
57224    function setOffsetToUTC(keepLocalTime) {
57225        return this.utcOffset(0, keepLocalTime);
57226    }
57227
57228    function setOffsetToLocal(keepLocalTime) {
57229        if (this._isUTC) {
57230            this.utcOffset(0, keepLocalTime);
57231            this._isUTC = false;
57232
57233            if (keepLocalTime) {
57234                this.subtract(getDateOffset(this), 'm');
57235            }
57236        }
57237        return this;
57238    }
57239
57240    function setOffsetToParsedOffset() {
57241        if (this._tzm != null) {
57242            this.utcOffset(this._tzm, false, true);
57243        } else if (typeof this._i === 'string') {
57244            var tZone = offsetFromString(matchOffset, this._i);
57245            if (tZone != null) {
57246                this.utcOffset(tZone);
57247            } else {
57248                this.utcOffset(0, true);
57249            }
57250        }
57251        return this;
57252    }
57253
57254    function hasAlignedHourOffset(input) {
57255        if (!this.isValid()) {
57256            return false;
57257        }
57258        input = input ? createLocal(input).utcOffset() : 0;
57259
57260        return (this.utcOffset() - input) % 60 === 0;
57261    }
57262
57263    function isDaylightSavingTime() {
57264        return (
57265            this.utcOffset() > this.clone().month(0).utcOffset() ||
57266            this.utcOffset() > this.clone().month(5).utcOffset()
57267        );
57268    }
57269
57270    function isDaylightSavingTimeShifted() {
57271        if (!isUndefined(this._isDSTShifted)) {
57272            return this._isDSTShifted;
57273        }
57274
57275        var c = {},
57276            other;
57277
57278        copyConfig(c, this);
57279        c = prepareConfig(c);
57280
57281        if (c._a) {
57282            other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
57283            this._isDSTShifted =
57284                this.isValid() && compareArrays(c._a, other.toArray()) > 0;
57285        } else {
57286            this._isDSTShifted = false;
57287        }
57288
57289        return this._isDSTShifted;
57290    }
57291
57292    function isLocal() {
57293        return this.isValid() ? !this._isUTC : false;
57294    }
57295
57296    function isUtcOffset() {
57297        return this.isValid() ? this._isUTC : false;
57298    }
57299
57300    function isUtc() {
57301        return this.isValid() ? this._isUTC && this._offset === 0 : false;
57302    }
57303
57304    // ASP.NET json date format regex
57305    var aspNetRegex = /^(-|\+)?(?:(\d*)[. ])?(\d+):(\d+)(?::(\d+)(\.\d*)?)?$/,
57306        // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
57307        // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
57308        // and further modified to allow for strings containing both week and day
57309        isoRegex =
57310            /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;
57311
57312    function createDuration(input, key) {
57313        var duration = input,
57314            // matching against regexp is expensive, do it on demand
57315            match = null,
57316            sign,
57317            ret,
57318            diffRes;
57319
57320        if (isDuration(input)) {
57321            duration = {
57322                ms: input._milliseconds,
57323                d: input._days,
57324                M: input._months,
57325            };
57326        } else if (isNumber(input) || !isNaN(+input)) {
57327            duration = {};
57328            if (key) {
57329                duration[key] = +input;
57330            } else {
57331                duration.milliseconds = +input;
57332            }
57333        } else if ((match = aspNetRegex.exec(input))) {
57334            sign = match[1] === '-' ? -1 : 1;
57335            duration = {
57336                y: 0,
57337                d: toInt(match[DATE]) * sign,
57338                h: toInt(match[HOUR]) * sign,
57339                m: toInt(match[MINUTE]) * sign,
57340                s: toInt(match[SECOND]) * sign,
57341                ms: toInt(absRound(match[MILLISECOND] * 1000)) * sign, // the millisecond decimal point is included in the match
57342            };
57343        } else if ((match = isoRegex.exec(input))) {
57344            sign = match[1] === '-' ? -1 : 1;
57345            duration = {
57346                y: parseIso(match[2], sign),
57347                M: parseIso(match[3], sign),
57348                w: parseIso(match[4], sign),
57349                d: parseIso(match[5], sign),
57350                h: parseIso(match[6], sign),
57351                m: parseIso(match[7], sign),
57352                s: parseIso(match[8], sign),
57353            };
57354        } else if (duration == null) {
57355            // checks for null or undefined
57356            duration = {};
57357        } else if (
57358            typeof duration === 'object' &&
57359            ('from' in duration || 'to' in duration)
57360        ) {
57361            diffRes = momentsDifference(
57362                createLocal(duration.from),
57363                createLocal(duration.to)
57364            );
57365
57366            duration = {};
57367            duration.ms = diffRes.milliseconds;
57368            duration.M = diffRes.months;
57369        }
57370
57371        ret = new Duration(duration);
57372
57373        if (isDuration(input) && hasOwnProp(input, '_locale')) {
57374            ret._locale = input._locale;
57375        }
57376
57377        if (isDuration(input) && hasOwnProp(input, '_isValid')) {
57378            ret._isValid = input._isValid;
57379        }
57380
57381        return ret;
57382    }
57383
57384    createDuration.fn = Duration.prototype;
57385    createDuration.invalid = createInvalid$1;
57386
57387    function parseIso(inp, sign) {
57388        // We'd normally use ~~inp for this, but unfortunately it also
57389        // converts floats to ints.
57390        // inp may be undefined, so careful calling replace on it.
57391        var res = inp && parseFloat(inp.replace(',', '.'));
57392        // apply sign while we're at it
57393        return (isNaN(res) ? 0 : res) * sign;
57394    }
57395
57396    function positiveMomentsDifference(base, other) {
57397        var res = {};
57398
57399        res.months =
57400            other.month() - base.month() + (other.year() - base.year()) * 12;
57401        if (base.clone().add(res.months, 'M').isAfter(other)) {
57402            --res.months;
57403        }
57404
57405        res.milliseconds = +other - +base.clone().add(res.months, 'M');
57406
57407        return res;
57408    }
57409
57410    function momentsDifference(base, other) {
57411        var res;
57412        if (!(base.isValid() && other.isValid())) {
57413            return { milliseconds: 0, months: 0 };
57414        }
57415
57416        other = cloneWithOffset(other, base);
57417        if (base.isBefore(other)) {
57418            res = positiveMomentsDifference(base, other);
57419        } else {
57420            res = positiveMomentsDifference(other, base);
57421            res.milliseconds = -res.milliseconds;
57422            res.months = -res.months;
57423        }
57424
57425        return res;
57426    }
57427
57428    // TODO: remove 'name' arg after deprecation is removed
57429    function createAdder(direction, name) {
57430        return function (val, period) {
57431            var dur, tmp;
57432            //invert the arguments, but complain about it
57433            if (period !== null && !isNaN(+period)) {
57434                deprecateSimple(
57435                    name,
57436                    'moment().' +
57437                        name +
57438                        '(period, number) is deprecated. Please use moment().' +
57439                        name +
57440                        '(number, period). ' +
57441                        'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.'
57442                );
57443                tmp = val;
57444                val = period;
57445                period = tmp;
57446            }
57447
57448            dur = createDuration(val, period);
57449            addSubtract(this, dur, direction);
57450            return this;
57451        };
57452    }
57453
57454    function addSubtract(mom, duration, isAdding, updateOffset) {
57455        var milliseconds = duration._milliseconds,
57456            days = absRound(duration._days),
57457            months = absRound(duration._months);
57458
57459        if (!mom.isValid()) {
57460            // No op
57461            return;
57462        }
57463
57464        updateOffset = updateOffset == null ? true : updateOffset;
57465
57466        if (months) {
57467            setMonth(mom, get(mom, 'Month') + months * isAdding);
57468        }
57469        if (days) {
57470            set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
57471        }
57472        if (milliseconds) {
57473            mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
57474        }
57475        if (updateOffset) {
57476            hooks.updateOffset(mom, days || months);
57477        }
57478    }
57479
57480    var add = createAdder(1, 'add'),
57481        subtract = createAdder(-1, 'subtract');
57482
57483    function isString(input) {
57484        return typeof input === 'string' || input instanceof String;
57485    }
57486
57487    // type MomentInput = Moment | Date | string | number | (number | string)[] | MomentInputObject | void; // null | undefined
57488    function isMomentInput(input) {
57489        return (
57490            isMoment(input) ||
57491            isDate(input) ||
57492            isString(input) ||
57493            isNumber(input) ||
57494            isNumberOrStringArray(input) ||
57495            isMomentInputObject(input) ||
57496            input === null ||
57497            input === undefined
57498        );
57499    }
57500
57501    function isMomentInputObject(input) {
57502        var objectTest = isObject(input) && !isObjectEmpty(input),
57503            propertyTest = false,
57504            properties = [
57505                'years',
57506                'year',
57507                'y',
57508                'months',
57509                'month',
57510                'M',
57511                'days',
57512                'day',
57513                'd',
57514                'dates',
57515                'date',
57516                'D',
57517                'hours',
57518                'hour',
57519                'h',
57520                'minutes',
57521                'minute',
57522                'm',
57523                'seconds',
57524                'second',
57525                's',
57526                'milliseconds',
57527                'millisecond',
57528                'ms',
57529            ],
57530            i,
57531            property,
57532            propertyLen = properties.length;
57533
57534        for (i = 0; i < propertyLen; i += 1) {
57535            property = properties[i];
57536            propertyTest = propertyTest || hasOwnProp(input, property);
57537        }
57538
57539        return objectTest && propertyTest;
57540    }
57541
57542    function isNumberOrStringArray(input) {
57543        var arrayTest = isArray(input),
57544            dataTypeTest = false;
57545        if (arrayTest) {
57546            dataTypeTest =
57547                input.filter(function (item) {
57548                    return !isNumber(item) && isString(input);
57549                }).length === 0;
57550        }
57551        return arrayTest && dataTypeTest;
57552    }
57553
57554    function isCalendarSpec(input) {
57555        var objectTest = isObject(input) && !isObjectEmpty(input),
57556            propertyTest = false,
57557            properties = [
57558                'sameDay',
57559                'nextDay',
57560                'lastDay',
57561                'nextWeek',
57562                'lastWeek',
57563                'sameElse',
57564            ],
57565            i,
57566            property;
57567
57568        for (i = 0; i < properties.length; i += 1) {
57569            property = properties[i];
57570            propertyTest = propertyTest || hasOwnProp(input, property);
57571        }
57572
57573        return objectTest && propertyTest;
57574    }
57575
57576    function getCalendarFormat(myMoment, now) {
57577        var diff = myMoment.diff(now, 'days', true);
57578        return diff < -6
57579            ? 'sameElse'
57580            : diff < -1
57581            ? 'lastWeek'
57582            : diff < 0
57583            ? 'lastDay'
57584            : diff < 1
57585            ? 'sameDay'
57586            : diff < 2
57587            ? 'nextDay'
57588            : diff < 7
57589            ? 'nextWeek'
57590            : 'sameElse';
57591    }
57592
57593    function calendar$1(time, formats) {
57594        // Support for single parameter, formats only overload to the calendar function
57595        if (arguments.length === 1) {
57596            if (!arguments[0]) {
57597                time = undefined;
57598                formats = undefined;
57599            } else if (isMomentInput(arguments[0])) {
57600                time = arguments[0];
57601                formats = undefined;
57602            } else if (isCalendarSpec(arguments[0])) {
57603                formats = arguments[0];
57604                time = undefined;
57605            }
57606        }
57607        // We want to compare the start of today, vs this.
57608        // Getting start-of-today depends on whether we're local/utc/offset or not.
57609        var now = time || createLocal(),
57610            sod = cloneWithOffset(now, this).startOf('day'),
57611            format = hooks.calendarFormat(this, sod) || 'sameElse',
57612            output =
57613                formats &&
57614                (isFunction(formats[format])
57615                    ? formats[format].call(this, now)
57616                    : formats[format]);
57617
57618        return this.format(
57619            output || this.localeData().calendar(format, this, createLocal(now))
57620        );
57621    }
57622
57623    function clone() {
57624        return new Moment(this);
57625    }
57626
57627    function isAfter(input, units) {
57628        var localInput = isMoment(input) ? input : createLocal(input);
57629        if (!(this.isValid() && localInput.isValid())) {
57630            return false;
57631        }
57632        units = normalizeUnits(units) || 'millisecond';
57633        if (units === 'millisecond') {
57634            return this.valueOf() > localInput.valueOf();
57635        } else {
57636            return localInput.valueOf() < this.clone().startOf(units).valueOf();
57637        }
57638    }
57639
57640    function isBefore(input, units) {
57641        var localInput = isMoment(input) ? input : createLocal(input);
57642        if (!(this.isValid() && localInput.isValid())) {
57643            return false;
57644        }
57645        units = normalizeUnits(units) || 'millisecond';
57646        if (units === 'millisecond') {
57647            return this.valueOf() < localInput.valueOf();
57648        } else {
57649            return this.clone().endOf(units).valueOf() < localInput.valueOf();
57650        }
57651    }
57652
57653    function isBetween(from, to, units, inclusivity) {
57654        var localFrom = isMoment(from) ? from : createLocal(from),
57655            localTo = isMoment(to) ? to : createLocal(to);
57656        if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {
57657            return false;
57658        }
57659        inclusivity = inclusivity || '()';
57660        return (
57661            (inclusivity[0] === '('
57662                ? this.isAfter(localFrom, units)
57663                : !this.isBefore(localFrom, units)) &&
57664            (inclusivity[1] === ')'
57665                ? this.isBefore(localTo, units)
57666                : !this.isAfter(localTo, units))
57667        );
57668    }
57669
57670    function isSame(input, units) {
57671        var localInput = isMoment(input) ? input : createLocal(input),
57672            inputMs;
57673        if (!(this.isValid() && localInput.isValid())) {
57674            return false;
57675        }
57676        units = normalizeUnits(units) || 'millisecond';
57677        if (units === 'millisecond') {
57678            return this.valueOf() === localInput.valueOf();
57679        } else {
57680            inputMs = localInput.valueOf();
57681            return (
57682                this.clone().startOf(units).valueOf() <= inputMs &&
57683                inputMs <= this.clone().endOf(units).valueOf()
57684            );
57685        }
57686    }
57687
57688    function isSameOrAfter(input, units) {
57689        return this.isSame(input, units) || this.isAfter(input, units);
57690    }
57691
57692    function isSameOrBefore(input, units) {
57693        return this.isSame(input, units) || this.isBefore(input, units);
57694    }
57695
57696    function diff(input, units, asFloat) {
57697        var that, zoneDelta, output;
57698
57699        if (!this.isValid()) {
57700            return NaN;
57701        }
57702
57703        that = cloneWithOffset(input, this);
57704
57705        if (!that.isValid()) {
57706            return NaN;
57707        }
57708
57709        zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
57710
57711        units = normalizeUnits(units);
57712
57713        switch (units) {
57714            case 'year':
57715                output = monthDiff(this, that) / 12;
57716                break;
57717            case 'month':
57718                output = monthDiff(this, that);
57719                break;
57720            case 'quarter':
57721                output = monthDiff(this, that) / 3;
57722                break;
57723            case 'second':
57724                output = (this - that) / 1e3;
57725                break; // 1000
57726            case 'minute':
57727                output = (this - that) / 6e4;
57728                break; // 1000 * 60
57729            case 'hour':
57730                output = (this - that) / 36e5;
57731                break; // 1000 * 60 * 60
57732            case 'day':
57733                output = (this - that - zoneDelta) / 864e5;
57734                break; // 1000 * 60 * 60 * 24, negate dst
57735            case 'week':
57736                output = (this - that - zoneDelta) / 6048e5;
57737                break; // 1000 * 60 * 60 * 24 * 7, negate dst
57738            default:
57739                output = this - that;
57740        }
57741
57742        return asFloat ? output : absFloor(output);
57743    }
57744
57745    function monthDiff(a, b) {
57746        if (a.date() < b.date()) {
57747            // end-of-month calculations work correct when the start month has more
57748            // days than the end month.
57749            return -monthDiff(b, a);
57750        }
57751        // difference in months
57752        var wholeMonthDiff = (b.year() - a.year()) * 12 + (b.month() - a.month()),
57753            // b is in (anchor - 1 month, anchor + 1 month)
57754            anchor = a.clone().add(wholeMonthDiff, 'months'),
57755            anchor2,
57756            adjust;
57757
57758        if (b - anchor < 0) {
57759            anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
57760            // linear across the month
57761            adjust = (b - anchor) / (anchor - anchor2);
57762        } else {
57763            anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
57764            // linear across the month
57765            adjust = (b - anchor) / (anchor2 - anchor);
57766        }
57767
57768        //check for negative zero, return zero if negative zero
57769        return -(wholeMonthDiff + adjust) || 0;
57770    }
57771
57772    hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
57773    hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';
57774
57775    function toString() {
57776        return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
57777    }
57778
57779    function toISOString(keepOffset) {
57780        if (!this.isValid()) {
57781            return null;
57782        }
57783        var utc = keepOffset !== true,
57784            m = utc ? this.clone().utc() : this;
57785        if (m.year() < 0 || m.year() > 9999) {
57786            return formatMoment(
57787                m,
57788                utc
57789                    ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]'
57790                    : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ'
57791            );
57792        }
57793        if (isFunction(Date.prototype.toISOString)) {
57794            // native implementation is ~50x faster, use it when we can
57795            if (utc) {
57796                return this.toDate().toISOString();
57797            } else {
57798                return new Date(this.valueOf() + this.utcOffset() * 60 * 1000)
57799                    .toISOString()
57800                    .replace('Z', formatMoment(m, 'Z'));
57801            }
57802        }
57803        return formatMoment(
57804            m,
57805            utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ'
57806        );
57807    }
57808
57809    /**
57810     * Return a human readable representation of a moment that can
57811     * also be evaluated to get a new moment which is the same
57812     *
57813     * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
57814     */
57815    function inspect() {
57816        if (!this.isValid()) {
57817            return 'moment.invalid(/* ' + this._i + ' */)';
57818        }
57819        var func = 'moment',
57820            zone = '',
57821            prefix,
57822            year,
57823            datetime,
57824            suffix;
57825        if (!this.isLocal()) {
57826            func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
57827            zone = 'Z';
57828        }
57829        prefix = '[' + func + '("]';
57830        year = 0 <= this.year() && this.year() <= 9999 ? 'YYYY' : 'YYYYYY';
57831        datetime = '-MM-DD[T]HH:mm:ss.SSS';
57832        suffix = zone + '[")]';
57833
57834        return this.format(prefix + year + datetime + suffix);
57835    }
57836
57837    function format(inputString) {
57838        if (!inputString) {
57839            inputString = this.isUtc()
57840                ? hooks.defaultFormatUtc
57841                : hooks.defaultFormat;
57842        }
57843        var output = formatMoment(this, inputString);
57844        return this.localeData().postformat(output);
57845    }
57846
57847    function from(time, withoutSuffix) {
57848        if (
57849            this.isValid() &&
57850            ((isMoment(time) && time.isValid()) || createLocal(time).isValid())
57851        ) {
57852            return createDuration({ to: this, from: time })
57853                .locale(this.locale())
57854                .humanize(!withoutSuffix);
57855        } else {
57856            return this.localeData().invalidDate();
57857        }
57858    }
57859
57860    function fromNow(withoutSuffix) {
57861        return this.from(createLocal(), withoutSuffix);
57862    }
57863
57864    function to(time, withoutSuffix) {
57865        if (
57866            this.isValid() &&
57867            ((isMoment(time) && time.isValid()) || createLocal(time).isValid())
57868        ) {
57869            return createDuration({ from: this, to: time })
57870                .locale(this.locale())
57871                .humanize(!withoutSuffix);
57872        } else {
57873            return this.localeData().invalidDate();
57874        }
57875    }
57876
57877    function toNow(withoutSuffix) {
57878        return this.to(createLocal(), withoutSuffix);
57879    }
57880
57881    // If passed a locale key, it will set the locale for this
57882    // instance.  Otherwise, it will return the locale configuration
57883    // variables for this instance.
57884    function locale(key) {
57885        var newLocaleData;
57886
57887        if (key === undefined) {
57888            return this._locale._abbr;
57889        } else {
57890            newLocaleData = getLocale(key);
57891            if (newLocaleData != null) {
57892                this._locale = newLocaleData;
57893            }
57894            return this;
57895        }
57896    }
57897
57898    var lang = deprecate(
57899        'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
57900        function (key) {
57901            if (key === undefined) {
57902                return this.localeData();
57903            } else {
57904                return this.locale(key);
57905            }
57906        }
57907    );
57908
57909    function localeData() {
57910        return this._locale;
57911    }
57912
57913    var MS_PER_SECOND = 1000,
57914        MS_PER_MINUTE = 60 * MS_PER_SECOND,
57915        MS_PER_HOUR = 60 * MS_PER_MINUTE,
57916        MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR;
57917
57918    // actual modulo - handles negative numbers (for dates before 1970):
57919    function mod$1(dividend, divisor) {
57920        return ((dividend % divisor) + divisor) % divisor;
57921    }
57922
57923    function localStartOfDate(y, m, d) {
57924        // the date constructor remaps years 0-99 to 1900-1999
57925        if (y < 100 && y >= 0) {
57926            // preserve leap years using a full 400 year cycle, then reset
57927            return new Date(y + 400, m, d) - MS_PER_400_YEARS;
57928        } else {
57929            return new Date(y, m, d).valueOf();
57930        }
57931    }
57932
57933    function utcStartOfDate(y, m, d) {
57934        // Date.UTC remaps years 0-99 to 1900-1999
57935        if (y < 100 && y >= 0) {
57936            // preserve leap years using a full 400 year cycle, then reset
57937            return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS;
57938        } else {
57939            return Date.UTC(y, m, d);
57940        }
57941    }
57942
57943    function startOf(units) {
57944        var time, startOfDate;
57945        units = normalizeUnits(units);
57946        if (units === undefined || units === 'millisecond' || !this.isValid()) {
57947            return this;
57948        }
57949
57950        startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
57951
57952        switch (units) {
57953            case 'year':
57954                time = startOfDate(this.year(), 0, 1);
57955                break;
57956            case 'quarter':
57957                time = startOfDate(
57958                    this.year(),
57959                    this.month() - (this.month() % 3),
57960                    1
57961                );
57962                break;
57963            case 'month':
57964                time = startOfDate(this.year(), this.month(), 1);
57965                break;
57966            case 'week':
57967                time = startOfDate(
57968                    this.year(),
57969                    this.month(),
57970                    this.date() - this.weekday()
57971                );
57972                break;
57973            case 'isoWeek':
57974                time = startOfDate(
57975                    this.year(),
57976                    this.month(),
57977                    this.date() - (this.isoWeekday() - 1)
57978                );
57979                break;
57980            case 'day':
57981            case 'date':
57982                time = startOfDate(this.year(), this.month(), this.date());
57983                break;
57984            case 'hour':
57985                time = this._d.valueOf();
57986                time -= mod$1(
57987                    time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE),
57988                    MS_PER_HOUR
57989                );
57990                break;
57991            case 'minute':
57992                time = this._d.valueOf();
57993                time -= mod$1(time, MS_PER_MINUTE);
57994                break;
57995            case 'second':
57996                time = this._d.valueOf();
57997                time -= mod$1(time, MS_PER_SECOND);
57998                break;
57999        }
58000
58001        this._d.setTime(time);
58002        hooks.updateOffset(this, true);
58003        return this;
58004    }
58005
58006    function endOf(units) {
58007        var time, startOfDate;
58008        units = normalizeUnits(units);
58009        if (units === undefined || units === 'millisecond' || !this.isValid()) {
58010            return this;
58011        }
58012
58013        startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
58014
58015        switch (units) {
58016            case 'year':
58017                time = startOfDate(this.year() + 1, 0, 1) - 1;
58018                break;
58019            case 'quarter':
58020                time =
58021                    startOfDate(
58022                        this.year(),
58023                        this.month() - (this.month() % 3) + 3,
58024                        1
58025                    ) - 1;
58026                break;
58027            case 'month':
58028                time = startOfDate(this.year(), this.month() + 1, 1) - 1;
58029                break;
58030            case 'week':
58031                time =
58032                    startOfDate(
58033                        this.year(),
58034                        this.month(),
58035                        this.date() - this.weekday() + 7
58036                    ) - 1;
58037                break;
58038            case 'isoWeek':
58039                time =
58040                    startOfDate(
58041                        this.year(),
58042                        this.month(),
58043                        this.date() - (this.isoWeekday() - 1) + 7
58044                    ) - 1;
58045                break;
58046            case 'day':
58047            case 'date':
58048                time = startOfDate(this.year(), this.month(), this.date() + 1) - 1;
58049                break;
58050            case 'hour':
58051                time = this._d.valueOf();
58052                time +=
58053                    MS_PER_HOUR -
58054                    mod$1(
58055                        time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE),
58056                        MS_PER_HOUR
58057                    ) -
58058                    1;
58059                break;
58060            case 'minute':
58061                time = this._d.valueOf();
58062                time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1;
58063                break;
58064            case 'second':
58065                time = this._d.valueOf();
58066                time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1;
58067                break;
58068        }
58069
58070        this._d.setTime(time);
58071        hooks.updateOffset(this, true);
58072        return this;
58073    }
58074
58075    function valueOf() {
58076        return this._d.valueOf() - (this._offset || 0) * 60000;
58077    }
58078
58079    function unix() {
58080        return Math.floor(this.valueOf() / 1000);
58081    }
58082
58083    function toDate() {
58084        return new Date(this.valueOf());
58085    }
58086
58087    function toArray() {
58088        var m = this;
58089        return [
58090            m.year(),
58091            m.month(),
58092            m.date(),
58093            m.hour(),
58094            m.minute(),
58095            m.second(),
58096            m.millisecond(),
58097        ];
58098    }
58099
58100    function toObject() {
58101        var m = this;
58102        return {
58103            years: m.year(),
58104            months: m.month(),
58105            date: m.date(),
58106            hours: m.hours(),
58107            minutes: m.minutes(),
58108            seconds: m.seconds(),
58109            milliseconds: m.milliseconds(),
58110        };
58111    }
58112
58113    function toJSON() {
58114        // new Date(NaN).toJSON() === null
58115        return this.isValid() ? this.toISOString() : null;
58116    }
58117
58118    function isValid$2() {
58119        return isValid(this);
58120    }
58121
58122    function parsingFlags() {
58123        return extend({}, getParsingFlags(this));
58124    }
58125
58126    function invalidAt() {
58127        return getParsingFlags(this).overflow;
58128    }
58129
58130    function creationData() {
58131        return {
58132            input: this._i,
58133            format: this._f,
58134            locale: this._locale,
58135            isUTC: this._isUTC,
58136            strict: this._strict,
58137        };
58138    }
58139
58140    addFormatToken('N', 0, 0, 'eraAbbr');
58141    addFormatToken('NN', 0, 0, 'eraAbbr');
58142    addFormatToken('NNN', 0, 0, 'eraAbbr');
58143    addFormatToken('NNNN', 0, 0, 'eraName');
58144    addFormatToken('NNNNN', 0, 0, 'eraNarrow');
58145
58146    addFormatToken('y', ['y', 1], 'yo', 'eraYear');
58147    addFormatToken('y', ['yy', 2], 0, 'eraYear');
58148    addFormatToken('y', ['yyy', 3], 0, 'eraYear');
58149    addFormatToken('y', ['yyyy', 4], 0, 'eraYear');
58150
58151    addRegexToken('N', matchEraAbbr);
58152    addRegexToken('NN', matchEraAbbr);
58153    addRegexToken('NNN', matchEraAbbr);
58154    addRegexToken('NNNN', matchEraName);
58155    addRegexToken('NNNNN', matchEraNarrow);
58156
58157    addParseToken(
58158        ['N', 'NN', 'NNN', 'NNNN', 'NNNNN'],
58159        function (input, array, config, token) {
58160            var era = config._locale.erasParse(input, token, config._strict);
58161            if (era) {
58162                getParsingFlags(config).era = era;
58163            } else {
58164                getParsingFlags(config).invalidEra = input;
58165            }
58166        }
58167    );
58168
58169    addRegexToken('y', matchUnsigned);
58170    addRegexToken('yy', matchUnsigned);
58171    addRegexToken('yyy', matchUnsigned);
58172    addRegexToken('yyyy', matchUnsigned);
58173    addRegexToken('yo', matchEraYearOrdinal);
58174
58175    addParseToken(['y', 'yy', 'yyy', 'yyyy'], YEAR);
58176    addParseToken(['yo'], function (input, array, config, token) {
58177        var match;
58178        if (config._locale._eraYearOrdinalRegex) {
58179            match = input.match(config._locale._eraYearOrdinalRegex);
58180        }
58181
58182        if (config._locale.eraYearOrdinalParse) {
58183            array[YEAR] = config._locale.eraYearOrdinalParse(input, match);
58184        } else {
58185            array[YEAR] = parseInt(input, 10);
58186        }
58187    });
58188
58189    function localeEras(m, format) {
58190        var i,
58191            l,
58192            date,
58193            eras = this._eras || getLocale('en')._eras;
58194        for (i = 0, l = eras.length; i < l; ++i) {
58195            switch (typeof eras[i].since) {
58196                case 'string':
58197                    // truncate time
58198                    date = hooks(eras[i].since).startOf('day');
58199                    eras[i].since = date.valueOf();
58200                    break;
58201            }
58202
58203            switch (typeof eras[i].until) {
58204                case 'undefined':
58205                    eras[i].until = +Infinity;
58206                    break;
58207                case 'string':
58208                    // truncate time
58209                    date = hooks(eras[i].until).startOf('day').valueOf();
58210                    eras[i].until = date.valueOf();
58211                    break;
58212            }
58213        }
58214        return eras;
58215    }
58216
58217    function localeErasParse(eraName, format, strict) {
58218        var i,
58219            l,
58220            eras = this.eras(),
58221            name,
58222            abbr,
58223            narrow;
58224        eraName = eraName.toUpperCase();
58225
58226        for (i = 0, l = eras.length; i < l; ++i) {
58227            name = eras[i].name.toUpperCase();
58228            abbr = eras[i].abbr.toUpperCase();
58229            narrow = eras[i].narrow.toUpperCase();
58230
58231            if (strict) {
58232                switch (format) {
58233                    case 'N':
58234                    case 'NN':
58235                    case 'NNN':
58236                        if (abbr === eraName) {
58237                            return eras[i];
58238                        }
58239                        break;
58240
58241                    case 'NNNN':
58242                        if (name === eraName) {
58243                            return eras[i];
58244                        }
58245                        break;
58246
58247                    case 'NNNNN':
58248                        if (narrow === eraName) {
58249                            return eras[i];
58250                        }
58251                        break;
58252                }
58253            } else if ([name, abbr, narrow].indexOf(eraName) >= 0) {
58254                return eras[i];
58255            }
58256        }
58257    }
58258
58259    function localeErasConvertYear(era, year) {
58260        var dir = era.since <= era.until ? +1 : -1;
58261        if (year === undefined) {
58262            return hooks(era.since).year();
58263        } else {
58264            return hooks(era.since).year() + (year - era.offset) * dir;
58265        }
58266    }
58267
58268    function getEraName() {
58269        var i,
58270            l,
58271            val,
58272            eras = this.localeData().eras();
58273        for (i = 0, l = eras.length; i < l; ++i) {
58274            // truncate time
58275            val = this.clone().startOf('day').valueOf();
58276
58277            if (eras[i].since <= val && val <= eras[i].until) {
58278                return eras[i].name;
58279            }
58280            if (eras[i].until <= val && val <= eras[i].since) {
58281                return eras[i].name;
58282            }
58283        }
58284
58285        return '';
58286    }
58287
58288    function getEraNarrow() {
58289        var i,
58290            l,
58291            val,
58292            eras = this.localeData().eras();
58293        for (i = 0, l = eras.length; i < l; ++i) {
58294            // truncate time
58295            val = this.clone().startOf('day').valueOf();
58296
58297            if (eras[i].since <= val && val <= eras[i].until) {
58298                return eras[i].narrow;
58299            }
58300            if (eras[i].until <= val && val <= eras[i].since) {
58301                return eras[i].narrow;
58302            }
58303        }
58304
58305        return '';
58306    }
58307
58308    function getEraAbbr() {
58309        var i,
58310            l,
58311            val,
58312            eras = this.localeData().eras();
58313        for (i = 0, l = eras.length; i < l; ++i) {
58314            // truncate time
58315            val = this.clone().startOf('day').valueOf();
58316
58317            if (eras[i].since <= val && val <= eras[i].until) {
58318                return eras[i].abbr;
58319            }
58320            if (eras[i].until <= val && val <= eras[i].since) {
58321                return eras[i].abbr;
58322            }
58323        }
58324
58325        return '';
58326    }
58327
58328    function getEraYear() {
58329        var i,
58330            l,
58331            dir,
58332            val,
58333            eras = this.localeData().eras();
58334        for (i = 0, l = eras.length; i < l; ++i) {
58335            dir = eras[i].since <= eras[i].until ? +1 : -1;
58336
58337            // truncate time
58338            val = this.clone().startOf('day').valueOf();
58339
58340            if (
58341                (eras[i].since <= val && val <= eras[i].until) ||
58342                (eras[i].until <= val && val <= eras[i].since)
58343            ) {
58344                return (
58345                    (this.year() - hooks(eras[i].since).year()) * dir +
58346                    eras[i].offset
58347                );
58348            }
58349        }
58350
58351        return this.year();
58352    }
58353
58354    function erasNameRegex(isStrict) {
58355        if (!hasOwnProp(this, '_erasNameRegex')) {
58356            computeErasParse.call(this);
58357        }
58358        return isStrict ? this._erasNameRegex : this._erasRegex;
58359    }
58360
58361    function erasAbbrRegex(isStrict) {
58362        if (!hasOwnProp(this, '_erasAbbrRegex')) {
58363            computeErasParse.call(this);
58364        }
58365        return isStrict ? this._erasAbbrRegex : this._erasRegex;
58366    }
58367
58368    function erasNarrowRegex(isStrict) {
58369        if (!hasOwnProp(this, '_erasNarrowRegex')) {
58370            computeErasParse.call(this);
58371        }
58372        return isStrict ? this._erasNarrowRegex : this._erasRegex;
58373    }
58374
58375    function matchEraAbbr(isStrict, locale) {
58376        return locale.erasAbbrRegex(isStrict);
58377    }
58378
58379    function matchEraName(isStrict, locale) {
58380        return locale.erasNameRegex(isStrict);
58381    }
58382
58383    function matchEraNarrow(isStrict, locale) {
58384        return locale.erasNarrowRegex(isStrict);
58385    }
58386
58387    function matchEraYearOrdinal(isStrict, locale) {
58388        return locale._eraYearOrdinalRegex || matchUnsigned;
58389    }
58390
58391    function computeErasParse() {
58392        var abbrPieces = [],
58393            namePieces = [],
58394            narrowPieces = [],
58395            mixedPieces = [],
58396            i,
58397            l,
58398            eras = this.eras();
58399
58400        for (i = 0, l = eras.length; i < l; ++i) {
58401            namePieces.push(regexEscape(eras[i].name));
58402            abbrPieces.push(regexEscape(eras[i].abbr));
58403            narrowPieces.push(regexEscape(eras[i].narrow));
58404
58405            mixedPieces.push(regexEscape(eras[i].name));
58406            mixedPieces.push(regexEscape(eras[i].abbr));
58407            mixedPieces.push(regexEscape(eras[i].narrow));
58408        }
58409
58410        this._erasRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
58411        this._erasNameRegex = new RegExp('^(' + namePieces.join('|') + ')', 'i');
58412        this._erasAbbrRegex = new RegExp('^(' + abbrPieces.join('|') + ')', 'i');
58413        this._erasNarrowRegex = new RegExp(
58414            '^(' + narrowPieces.join('|') + ')',
58415            'i'
58416        );
58417    }
58418
58419    // FORMATTING
58420
58421    addFormatToken(0, ['gg', 2], 0, function () {
58422        return this.weekYear() % 100;
58423    });
58424
58425    addFormatToken(0, ['GG', 2], 0, function () {
58426        return this.isoWeekYear() % 100;
58427    });
58428
58429    function addWeekYearFormatToken(token, getter) {
58430        addFormatToken(0, [token, token.length], 0, getter);
58431    }
58432
58433    addWeekYearFormatToken('gggg', 'weekYear');
58434    addWeekYearFormatToken('ggggg', 'weekYear');
58435    addWeekYearFormatToken('GGGG', 'isoWeekYear');
58436    addWeekYearFormatToken('GGGGG', 'isoWeekYear');
58437
58438    // ALIASES
58439
58440    addUnitAlias('weekYear', 'gg');
58441    addUnitAlias('isoWeekYear', 'GG');
58442
58443    // PRIORITY
58444
58445    addUnitPriority('weekYear', 1);
58446    addUnitPriority('isoWeekYear', 1);
58447
58448    // PARSING
58449
58450    addRegexToken('G', matchSigned);
58451    addRegexToken('g', matchSigned);
58452    addRegexToken('GG', match1to2, match2);
58453    addRegexToken('gg', match1to2, match2);
58454    addRegexToken('GGGG', match1to4, match4);
58455    addRegexToken('gggg', match1to4, match4);
58456    addRegexToken('GGGGG', match1to6, match6);
58457    addRegexToken('ggggg', match1to6, match6);
58458
58459    addWeekParseToken(
58460        ['gggg', 'ggggg', 'GGGG', 'GGGGG'],
58461        function (input, week, config, token) {
58462            week[token.substr(0, 2)] = toInt(input);
58463        }
58464    );
58465
58466    addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
58467        week[token] = hooks.parseTwoDigitYear(input);
58468    });
58469
58470    // MOMENTS
58471
58472    function getSetWeekYear(input) {
58473        return getSetWeekYearHelper.call(
58474            this,
58475            input,
58476            this.week(),
58477            this.weekday(),
58478            this.localeData()._week.dow,
58479            this.localeData()._week.doy
58480        );
58481    }
58482
58483    function getSetISOWeekYear(input) {
58484        return getSetWeekYearHelper.call(
58485            this,
58486            input,
58487            this.isoWeek(),
58488            this.isoWeekday(),
58489            1,
58490            4
58491        );
58492    }
58493
58494    function getISOWeeksInYear() {
58495        return weeksInYear(this.year(), 1, 4);
58496    }
58497
58498    function getISOWeeksInISOWeekYear() {
58499        return weeksInYear(this.isoWeekYear(), 1, 4);
58500    }
58501
58502    function getWeeksInYear() {
58503        var weekInfo = this.localeData()._week;
58504        return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
58505    }
58506
58507    function getWeeksInWeekYear() {
58508        var weekInfo = this.localeData()._week;
58509        return weeksInYear(this.weekYear(), weekInfo.dow, weekInfo.doy);
58510    }
58511
58512    function getSetWeekYearHelper(input, week, weekday, dow, doy) {
58513        var weeksTarget;
58514        if (input == null) {
58515            return weekOfYear(this, dow, doy).year;
58516        } else {
58517            weeksTarget = weeksInYear(input, dow, doy);
58518            if (week > weeksTarget) {
58519                week = weeksTarget;
58520            }
58521            return setWeekAll.call(this, input, week, weekday, dow, doy);
58522        }
58523    }
58524
58525    function setWeekAll(weekYear, week, weekday, dow, doy) {
58526        var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
58527            date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
58528
58529        this.year(date.getUTCFullYear());
58530        this.month(date.getUTCMonth());
58531        this.date(date.getUTCDate());
58532        return this;
58533    }
58534
58535    // FORMATTING
58536
58537    addFormatToken('Q', 0, 'Qo', 'quarter');
58538
58539    // ALIASES
58540
58541    addUnitAlias('quarter', 'Q');
58542
58543    // PRIORITY
58544
58545    addUnitPriority('quarter', 7);
58546
58547    // PARSING
58548
58549    addRegexToken('Q', match1);
58550    addParseToken('Q', function (input, array) {
58551        array[MONTH] = (toInt(input) - 1) * 3;
58552    });
58553
58554    // MOMENTS
58555
58556    function getSetQuarter(input) {
58557        return input == null
58558            ? Math.ceil((this.month() + 1) / 3)
58559            : this.month((input - 1) * 3 + (this.month() % 3));
58560    }
58561
58562    // FORMATTING
58563
58564    addFormatToken('D', ['DD', 2], 'Do', 'date');
58565
58566    // ALIASES
58567
58568    addUnitAlias('date', 'D');
58569
58570    // PRIORITY
58571    addUnitPriority('date', 9);
58572
58573    // PARSING
58574
58575    addRegexToken('D', match1to2);
58576    addRegexToken('DD', match1to2, match2);
58577    addRegexToken('Do', function (isStrict, locale) {
58578        // TODO: Remove "ordinalParse" fallback in next major release.
58579        return isStrict
58580            ? locale._dayOfMonthOrdinalParse || locale._ordinalParse
58581            : locale._dayOfMonthOrdinalParseLenient;
58582    });
58583
58584    addParseToken(['D', 'DD'], DATE);
58585    addParseToken('Do', function (input, array) {
58586        array[DATE] = toInt(input.match(match1to2)[0]);
58587    });
58588
58589    // MOMENTS
58590
58591    var getSetDayOfMonth = makeGetSet('Date', true);
58592
58593    // FORMATTING
58594
58595    addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
58596
58597    // ALIASES
58598
58599    addUnitAlias('dayOfYear', 'DDD');
58600
58601    // PRIORITY
58602    addUnitPriority('dayOfYear', 4);
58603
58604    // PARSING
58605
58606    addRegexToken('DDD', match1to3);
58607    addRegexToken('DDDD', match3);
58608    addParseToken(['DDD', 'DDDD'], function (input, array, config) {
58609        config._dayOfYear = toInt(input);
58610    });
58611
58612    // HELPERS
58613
58614    // MOMENTS
58615
58616    function getSetDayOfYear(input) {
58617        var dayOfYear =
58618            Math.round(
58619                (this.clone().startOf('day') - this.clone().startOf('year')) / 864e5
58620            ) + 1;
58621        return input == null ? dayOfYear : this.add(input - dayOfYear, 'd');
58622    }
58623
58624    // FORMATTING
58625
58626    addFormatToken('m', ['mm', 2], 0, 'minute');
58627
58628    // ALIASES
58629
58630    addUnitAlias('minute', 'm');
58631
58632    // PRIORITY
58633
58634    addUnitPriority('minute', 14);
58635
58636    // PARSING
58637
58638    addRegexToken('m', match1to2);
58639    addRegexToken('mm', match1to2, match2);
58640    addParseToken(['m', 'mm'], MINUTE);
58641
58642    // MOMENTS
58643
58644    var getSetMinute = makeGetSet('Minutes', false);
58645
58646    // FORMATTING
58647
58648    addFormatToken('s', ['ss', 2], 0, 'second');
58649
58650    // ALIASES
58651
58652    addUnitAlias('second', 's');
58653
58654    // PRIORITY
58655
58656    addUnitPriority('second', 15);
58657
58658    // PARSING
58659
58660    addRegexToken('s', match1to2);
58661    addRegexToken('ss', match1to2, match2);
58662    addParseToken(['s', 'ss'], SECOND);
58663
58664    // MOMENTS
58665
58666    var getSetSecond = makeGetSet('Seconds', false);
58667
58668    // FORMATTING
58669
58670    addFormatToken('S', 0, 0, function () {
58671        return ~~(this.millisecond() / 100);
58672    });
58673
58674    addFormatToken(0, ['SS', 2], 0, function () {
58675        return ~~(this.millisecond() / 10);
58676    });
58677
58678    addFormatToken(0, ['SSS', 3], 0, 'millisecond');
58679    addFormatToken(0, ['SSSS', 4], 0, function () {
58680        return this.millisecond() * 10;
58681    });
58682    addFormatToken(0, ['SSSSS', 5], 0, function () {
58683        return this.millisecond() * 100;
58684    });
58685    addFormatToken(0, ['SSSSSS', 6], 0, function () {
58686        return this.millisecond() * 1000;
58687    });
58688    addFormatToken(0, ['SSSSSSS', 7], 0, function () {
58689        return this.millisecond() * 10000;
58690    });
58691    addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
58692        return this.millisecond() * 100000;
58693    });
58694    addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
58695        return this.millisecond() * 1000000;
58696    });
58697
58698    // ALIASES
58699
58700    addUnitAlias('millisecond', 'ms');
58701
58702    // PRIORITY
58703
58704    addUnitPriority('millisecond', 16);
58705
58706    // PARSING
58707
58708    addRegexToken('S', match1to3, match1);
58709    addRegexToken('SS', match1to3, match2);
58710    addRegexToken('SSS', match1to3, match3);
58711
58712    var token, getSetMillisecond;
58713    for (token = 'SSSS'; token.length <= 9; token += 'S') {
58714        addRegexToken(token, matchUnsigned);
58715    }
58716
58717    function parseMs(input, array) {
58718        array[MILLISECOND] = toInt(('0.' + input) * 1000);
58719    }
58720
58721    for (token = 'S'; token.length <= 9; token += 'S') {
58722        addParseToken(token, parseMs);
58723    }
58724
58725    getSetMillisecond = makeGetSet('Milliseconds', false);
58726
58727    // FORMATTING
58728
58729    addFormatToken('z', 0, 0, 'zoneAbbr');
58730    addFormatToken('zz', 0, 0, 'zoneName');
58731
58732    // MOMENTS
58733
58734    function getZoneAbbr() {
58735        return this._isUTC ? 'UTC' : '';
58736    }
58737
58738    function getZoneName() {
58739        return this._isUTC ? 'Coordinated Universal Time' : '';
58740    }
58741
58742    var proto = Moment.prototype;
58743
58744    proto.add = add;
58745    proto.calendar = calendar$1;
58746    proto.clone = clone;
58747    proto.diff = diff;
58748    proto.endOf = endOf;
58749    proto.format = format;
58750    proto.from = from;
58751    proto.fromNow = fromNow;
58752    proto.to = to;
58753    proto.toNow = toNow;
58754    proto.get = stringGet;
58755    proto.invalidAt = invalidAt;
58756    proto.isAfter = isAfter;
58757    proto.isBefore = isBefore;
58758    proto.isBetween = isBetween;
58759    proto.isSame = isSame;
58760    proto.isSameOrAfter = isSameOrAfter;
58761    proto.isSameOrBefore = isSameOrBefore;
58762    proto.isValid = isValid$2;
58763    proto.lang = lang;
58764    proto.locale = locale;
58765    proto.localeData = localeData;
58766    proto.max = prototypeMax;
58767    proto.min = prototypeMin;
58768    proto.parsingFlags = parsingFlags;
58769    proto.set = stringSet;
58770    proto.startOf = startOf;
58771    proto.subtract = subtract;
58772    proto.toArray = toArray;
58773    proto.toObject = toObject;
58774    proto.toDate = toDate;
58775    proto.toISOString = toISOString;
58776    proto.inspect = inspect;
58777    if (typeof Symbol !== 'undefined' && Symbol.for != null) {
58778        proto[Symbol.for('nodejs.util.inspect.custom')] = function () {
58779            return 'Moment<' + this.format() + '>';
58780        };
58781    }
58782    proto.toJSON = toJSON;
58783    proto.toString = toString;
58784    proto.unix = unix;
58785    proto.valueOf = valueOf;
58786    proto.creationData = creationData;
58787    proto.eraName = getEraName;
58788    proto.eraNarrow = getEraNarrow;
58789    proto.eraAbbr = getEraAbbr;
58790    proto.eraYear = getEraYear;
58791    proto.year = getSetYear;
58792    proto.isLeapYear = getIsLeapYear;
58793    proto.weekYear = getSetWeekYear;
58794    proto.isoWeekYear = getSetISOWeekYear;
58795    proto.quarter = proto.quarters = getSetQuarter;
58796    proto.month = getSetMonth;
58797    proto.daysInMonth = getDaysInMonth;
58798    proto.week = proto.weeks = getSetWeek;
58799    proto.isoWeek = proto.isoWeeks = getSetISOWeek;
58800    proto.weeksInYear = getWeeksInYear;
58801    proto.weeksInWeekYear = getWeeksInWeekYear;
58802    proto.isoWeeksInYear = getISOWeeksInYear;
58803    proto.isoWeeksInISOWeekYear = getISOWeeksInISOWeekYear;
58804    proto.date = getSetDayOfMonth;
58805    proto.day = proto.days = getSetDayOfWeek;
58806    proto.weekday = getSetLocaleDayOfWeek;
58807    proto.isoWeekday = getSetISODayOfWeek;
58808    proto.dayOfYear = getSetDayOfYear;
58809    proto.hour = proto.hours = getSetHour;
58810    proto.minute = proto.minutes = getSetMinute;
58811    proto.second = proto.seconds = getSetSecond;
58812    proto.millisecond = proto.milliseconds = getSetMillisecond;
58813    proto.utcOffset = getSetOffset;
58814    proto.utc = setOffsetToUTC;
58815    proto.local = setOffsetToLocal;
58816    proto.parseZone = setOffsetToParsedOffset;
58817    proto.hasAlignedHourOffset = hasAlignedHourOffset;
58818    proto.isDST = isDaylightSavingTime;
58819    proto.isLocal = isLocal;
58820    proto.isUtcOffset = isUtcOffset;
58821    proto.isUtc = isUtc;
58822    proto.isUTC = isUtc;
58823    proto.zoneAbbr = getZoneAbbr;
58824    proto.zoneName = getZoneName;
58825    proto.dates = deprecate(
58826        'dates accessor is deprecated. Use date instead.',
58827        getSetDayOfMonth
58828    );
58829    proto.months = deprecate(
58830        'months accessor is deprecated. Use month instead',
58831        getSetMonth
58832    );
58833    proto.years = deprecate(
58834        'years accessor is deprecated. Use year instead',
58835        getSetYear
58836    );
58837    proto.zone = deprecate(
58838        'moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/',
58839        getSetZone
58840    );
58841    proto.isDSTShifted = deprecate(
58842        'isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information',
58843        isDaylightSavingTimeShifted
58844    );
58845
58846    function createUnix(input) {
58847        return createLocal(input * 1000);
58848    }
58849
58850    function createInZone() {
58851        return createLocal.apply(null, arguments).parseZone();
58852    }
58853
58854    function preParsePostFormat(string) {
58855        return string;
58856    }
58857
58858    var proto$1 = Locale.prototype;
58859
58860    proto$1.calendar = calendar;
58861    proto$1.longDateFormat = longDateFormat;
58862    proto$1.invalidDate = invalidDate;
58863    proto$1.ordinal = ordinal;
58864    proto$1.preparse = preParsePostFormat;
58865    proto$1.postformat = preParsePostFormat;
58866    proto$1.relativeTime = relativeTime;
58867    proto$1.pastFuture = pastFuture;
58868    proto$1.set = set;
58869    proto$1.eras = localeEras;
58870    proto$1.erasParse = localeErasParse;
58871    proto$1.erasConvertYear = localeErasConvertYear;
58872    proto$1.erasAbbrRegex = erasAbbrRegex;
58873    proto$1.erasNameRegex = erasNameRegex;
58874    proto$1.erasNarrowRegex = erasNarrowRegex;
58875
58876    proto$1.months = localeMonths;
58877    proto$1.monthsShort = localeMonthsShort;
58878    proto$1.monthsParse = localeMonthsParse;
58879    proto$1.monthsRegex = monthsRegex;
58880    proto$1.monthsShortRegex = monthsShortRegex;
58881    proto$1.week = localeWeek;
58882    proto$1.firstDayOfYear = localeFirstDayOfYear;
58883    proto$1.firstDayOfWeek = localeFirstDayOfWeek;
58884
58885    proto$1.weekdays = localeWeekdays;
58886    proto$1.weekdaysMin = localeWeekdaysMin;
58887    proto$1.weekdaysShort = localeWeekdaysShort;
58888    proto$1.weekdaysParse = localeWeekdaysParse;
58889
58890    proto$1.weekdaysRegex = weekdaysRegex;
58891    proto$1.weekdaysShortRegex = weekdaysShortRegex;
58892    proto$1.weekdaysMinRegex = weekdaysMinRegex;
58893
58894    proto$1.isPM = localeIsPM;
58895    proto$1.meridiem = localeMeridiem;
58896
58897    function get$1(format, index, field, setter) {
58898        var locale = getLocale(),
58899            utc = createUTC().set(setter, index);
58900        return locale[field](utc, format);
58901    }
58902
58903    function listMonthsImpl(format, index, field) {
58904        if (isNumber(format)) {
58905            index = format;
58906            format = undefined;
58907        }
58908
58909        format = format || '';
58910
58911        if (index != null) {
58912            return get$1(format, index, field, 'month');
58913        }
58914
58915        var i,
58916            out = [];
58917        for (i = 0; i < 12; i++) {
58918            out[i] = get$1(format, i, field, 'month');
58919        }
58920        return out;
58921    }
58922
58923    // ()
58924    // (5)
58925    // (fmt, 5)
58926    // (fmt)
58927    // (true)
58928    // (true, 5)
58929    // (true, fmt, 5)
58930    // (true, fmt)
58931    function listWeekdaysImpl(localeSorted, format, index, field) {
58932        if (typeof localeSorted === 'boolean') {
58933            if (isNumber(format)) {
58934                index = format;
58935                format = undefined;
58936            }
58937
58938            format = format || '';
58939        } else {
58940            format = localeSorted;
58941            index = format;
58942            localeSorted = false;
58943
58944            if (isNumber(format)) {
58945                index = format;
58946                format = undefined;
58947            }
58948
58949            format = format || '';
58950        }
58951
58952        var locale = getLocale(),
58953            shift = localeSorted ? locale._week.dow : 0,
58954            i,
58955            out = [];
58956
58957        if (index != null) {
58958            return get$1(format, (index + shift) % 7, field, 'day');
58959        }
58960
58961        for (i = 0; i < 7; i++) {
58962            out[i] = get$1(format, (i + shift) % 7, field, 'day');
58963        }
58964        return out;
58965    }
58966
58967    function listMonths(format, index) {
58968        return listMonthsImpl(format, index, 'months');
58969    }
58970
58971    function listMonthsShort(format, index) {
58972        return listMonthsImpl(format, index, 'monthsShort');
58973    }
58974
58975    function listWeekdays(localeSorted, format, index) {
58976        return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
58977    }
58978
58979    function listWeekdaysShort(localeSorted, format, index) {
58980        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
58981    }
58982
58983    function listWeekdaysMin(localeSorted, format, index) {
58984        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
58985    }
58986
58987    getSetGlobalLocale('en', {
58988        eras: [
58989            {
58990                since: '0001-01-01',
58991                until: +Infinity,
58992                offset: 1,
58993                name: 'Anno Domini',
58994                narrow: 'AD',
58995                abbr: 'AD',
58996            },
58997            {
58998                since: '0000-12-31',
58999                until: -Infinity,
59000                offset: 1,
59001                name: 'Before Christ',
59002                narrow: 'BC',
59003                abbr: 'BC',
59004            },
59005        ],
59006        dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
59007        ordinal: function (number) {
59008            var b = number % 10,
59009                output =
59010                    toInt((number % 100) / 10) === 1
59011                        ? 'th'
59012                        : b === 1
59013                        ? 'st'
59014                        : b === 2
59015                        ? 'nd'
59016                        : b === 3
59017                        ? 'rd'
59018                        : 'th';
59019            return number + output;
59020        },
59021    });
59022
59023    // Side effect imports
59024
59025    hooks.lang = deprecate(
59026        'moment.lang is deprecated. Use moment.locale instead.',
59027        getSetGlobalLocale
59028    );
59029    hooks.langData = deprecate(
59030        'moment.langData is deprecated. Use moment.localeData instead.',
59031        getLocale
59032    );
59033
59034    var mathAbs = Math.abs;
59035
59036    function abs() {
59037        var data = this._data;
59038
59039        this._milliseconds = mathAbs(this._milliseconds);
59040        this._days = mathAbs(this._days);
59041        this._months = mathAbs(this._months);
59042
59043        data.milliseconds = mathAbs(data.milliseconds);
59044        data.seconds = mathAbs(data.seconds);
59045        data.minutes = mathAbs(data.minutes);
59046        data.hours = mathAbs(data.hours);
59047        data.months = mathAbs(data.months);
59048        data.years = mathAbs(data.years);
59049
59050        return this;
59051    }
59052
59053    function addSubtract$1(duration, input, value, direction) {
59054        var other = createDuration(input, value);
59055
59056        duration._milliseconds += direction * other._milliseconds;
59057        duration._days += direction * other._days;
59058        duration._months += direction * other._months;
59059
59060        return duration._bubble();
59061    }
59062
59063    // supports only 2.0-style add(1, 's') or add(duration)
59064    function add$1(input, value) {
59065        return addSubtract$1(this, input, value, 1);
59066    }
59067
59068    // supports only 2.0-style subtract(1, 's') or subtract(duration)
59069    function subtract$1(input, value) {
59070        return addSubtract$1(this, input, value, -1);
59071    }
59072
59073    function absCeil(number) {
59074        if (number < 0) {
59075            return Math.floor(number);
59076        } else {
59077            return Math.ceil(number);
59078        }
59079    }
59080
59081    function bubble() {
59082        var milliseconds = this._milliseconds,
59083            days = this._days,
59084            months = this._months,
59085            data = this._data,
59086            seconds,
59087            minutes,
59088            hours,
59089            years,
59090            monthsFromDays;
59091
59092        // if we have a mix of positive and negative values, bubble down first
59093        // check: https://github.com/moment/moment/issues/2166
59094        if (
59095            !(
59096                (milliseconds >= 0 && days >= 0 && months >= 0) ||
59097                (milliseconds <= 0 && days <= 0 && months <= 0)
59098            )
59099        ) {
59100            milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
59101            days = 0;
59102            months = 0;
59103        }
59104
59105        // The following code bubbles up values, see the tests for
59106        // examples of what that means.
59107        data.milliseconds = milliseconds % 1000;
59108
59109        seconds = absFloor(milliseconds / 1000);
59110        data.seconds = seconds % 60;
59111
59112        minutes = absFloor(seconds / 60);
59113        data.minutes = minutes % 60;
59114
59115        hours = absFloor(minutes / 60);
59116        data.hours = hours % 24;
59117
59118        days += absFloor(hours / 24);
59119
59120        // convert days to months
59121        monthsFromDays = absFloor(daysToMonths(days));
59122        months += monthsFromDays;
59123        days -= absCeil(monthsToDays(monthsFromDays));
59124
59125        // 12 months -> 1 year
59126        years = absFloor(months / 12);
59127        months %= 12;
59128
59129        data.days = days;
59130        data.months = months;
59131        data.years = years;
59132
59133        return this;
59134    }
59135
59136    function daysToMonths(days) {
59137        // 400 years have 146097 days (taking into account leap year rules)
59138        // 400 years have 12 months === 4800
59139        return (days * 4800) / 146097;
59140    }
59141
59142    function monthsToDays(months) {
59143        // the reverse of daysToMonths
59144        return (months * 146097) / 4800;
59145    }
59146
59147    function as(units) {
59148        if (!this.isValid()) {
59149            return NaN;
59150        }
59151        var days,
59152            months,
59153            milliseconds = this._milliseconds;
59154
59155        units = normalizeUnits(units);
59156
59157        if (units === 'month' || units === 'quarter' || units === 'year') {
59158            days = this._days + milliseconds / 864e5;
59159            months = this._months + daysToMonths(days);
59160            switch (units) {
59161                case 'month':
59162                    return months;
59163                case 'quarter':
59164                    return months / 3;
59165                case 'year':
59166                    return months / 12;
59167            }
59168        } else {
59169            // handle milliseconds separately because of floating point math errors (issue #1867)
59170            days = this._days + Math.round(monthsToDays(this._months));
59171            switch (units) {
59172                case 'week':
59173                    return days / 7 + milliseconds / 6048e5;
59174                case 'day':
59175                    return days + milliseconds / 864e5;
59176                case 'hour':
59177                    return days * 24 + milliseconds / 36e5;
59178                case 'minute':
59179                    return days * 1440 + milliseconds / 6e4;
59180                case 'second':
59181                    return days * 86400 + milliseconds / 1000;
59182                // Math.floor prevents floating point math errors here
59183                case 'millisecond':
59184                    return Math.floor(days * 864e5) + milliseconds;
59185                default:
59186                    throw new Error('Unknown unit ' + units);
59187            }
59188        }
59189    }
59190
59191    // TODO: Use this.as('ms')?
59192    function valueOf$1() {
59193        if (!this.isValid()) {
59194            return NaN;
59195        }
59196        return (
59197            this._milliseconds +
59198            this._days * 864e5 +
59199            (this._months % 12) * 2592e6 +
59200            toInt(this._months / 12) * 31536e6
59201        );
59202    }
59203
59204    function makeAs(alias) {
59205        return function () {
59206            return this.as(alias);
59207        };
59208    }
59209
59210    var asMilliseconds = makeAs('ms'),
59211        asSeconds = makeAs('s'),
59212        asMinutes = makeAs('m'),
59213        asHours = makeAs('h'),
59214        asDays = makeAs('d'),
59215        asWeeks = makeAs('w'),
59216        asMonths = makeAs('M'),
59217        asQuarters = makeAs('Q'),
59218        asYears = makeAs('y');
59219
59220    function clone$1() {
59221        return createDuration(this);
59222    }
59223
59224    function get$2(units) {
59225        units = normalizeUnits(units);
59226        return this.isValid() ? this[units + 's']() : NaN;
59227    }
59228
59229    function makeGetter(name) {
59230        return function () {
59231            return this.isValid() ? this._data[name] : NaN;
59232        };
59233    }
59234
59235    var milliseconds = makeGetter('milliseconds'),
59236        seconds = makeGetter('seconds'),
59237        minutes = makeGetter('minutes'),
59238        hours = makeGetter('hours'),
59239        days = makeGetter('days'),
59240        months = makeGetter('months'),
59241        years = makeGetter('years');
59242
59243    function weeks() {
59244        return absFloor(this.days() / 7);
59245    }
59246
59247    var round = Math.round,
59248        thresholds = {
59249            ss: 44, // a few seconds to seconds
59250            s: 45, // seconds to minute
59251            m: 45, // minutes to hour
59252            h: 22, // hours to day
59253            d: 26, // days to month/week
59254            w: null, // weeks to month
59255            M: 11, // months to year
59256        };
59257
59258    // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
59259    function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
59260        return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
59261    }
59262
59263    function relativeTime$1(posNegDuration, withoutSuffix, thresholds, locale) {
59264        var duration = createDuration(posNegDuration).abs(),
59265            seconds = round(duration.as('s')),
59266            minutes = round(duration.as('m')),
59267            hours = round(duration.as('h')),
59268            days = round(duration.as('d')),
59269            months = round(duration.as('M')),
59270            weeks = round(duration.as('w')),
59271            years = round(duration.as('y')),
59272            a =
59273                (seconds <= thresholds.ss && ['s', seconds]) ||
59274                (seconds < thresholds.s && ['ss', seconds]) ||
59275                (minutes <= 1 && ['m']) ||
59276                (minutes < thresholds.m && ['mm', minutes]) ||
59277                (hours <= 1 && ['h']) ||
59278                (hours < thresholds.h && ['hh', hours]) ||
59279                (days <= 1 && ['d']) ||
59280                (days < thresholds.d && ['dd', days]);
59281
59282        if (thresholds.w != null) {
59283            a =
59284                a ||
59285                (weeks <= 1 && ['w']) ||
59286                (weeks < thresholds.w && ['ww', weeks]);
59287        }
59288        a = a ||
59289            (months <= 1 && ['M']) ||
59290            (months < thresholds.M && ['MM', months]) ||
59291            (years <= 1 && ['y']) || ['yy', years];
59292
59293        a[2] = withoutSuffix;
59294        a[3] = +posNegDuration > 0;
59295        a[4] = locale;
59296        return substituteTimeAgo.apply(null, a);
59297    }
59298
59299    // This function allows you to set the rounding function for relative time strings
59300    function getSetRelativeTimeRounding(roundingFunction) {
59301        if (roundingFunction === undefined) {
59302            return round;
59303        }
59304        if (typeof roundingFunction === 'function') {
59305            round = roundingFunction;
59306            return true;
59307        }
59308        return false;
59309    }
59310
59311    // This function allows you to set a threshold for relative time strings
59312    function getSetRelativeTimeThreshold(threshold, limit) {
59313        if (thresholds[threshold] === undefined) {
59314            return false;
59315        }
59316        if (limit === undefined) {
59317            return thresholds[threshold];
59318        }
59319        thresholds[threshold] = limit;
59320        if (threshold === 's') {
59321            thresholds.ss = limit - 1;
59322        }
59323        return true;
59324    }
59325
59326    function humanize(argWithSuffix, argThresholds) {
59327        if (!this.isValid()) {
59328            return this.localeData().invalidDate();
59329        }
59330
59331        var withSuffix = false,
59332            th = thresholds,
59333            locale,
59334            output;
59335
59336        if (typeof argWithSuffix === 'object') {
59337            argThresholds = argWithSuffix;
59338            argWithSuffix = false;
59339        }
59340        if (typeof argWithSuffix === 'boolean') {
59341            withSuffix = argWithSuffix;
59342        }
59343        if (typeof argThresholds === 'object') {
59344            th = Object.assign({}, thresholds, argThresholds);
59345            if (argThresholds.s != null && argThresholds.ss == null) {
59346                th.ss = argThresholds.s - 1;
59347            }
59348        }
59349
59350        locale = this.localeData();
59351        output = relativeTime$1(this, !withSuffix, th, locale);
59352
59353        if (withSuffix) {
59354            output = locale.pastFuture(+this, output);
59355        }
59356
59357        return locale.postformat(output);
59358    }
59359
59360    var abs$1 = Math.abs;
59361
59362    function sign(x) {
59363        return (x > 0) - (x < 0) || +x;
59364    }
59365
59366    function toISOString$1() {
59367        // for ISO strings we do not use the normal bubbling rules:
59368        //  * milliseconds bubble up until they become hours
59369        //  * days do not bubble at all
59370        //  * months bubble up until they become years
59371        // This is because there is no context-free conversion between hours and days
59372        // (think of clock changes)
59373        // and also not between days and months (28-31 days per month)
59374        if (!this.isValid()) {
59375            return this.localeData().invalidDate();
59376        }
59377
59378        var seconds = abs$1(this._milliseconds) / 1000,
59379            days = abs$1(this._days),
59380            months = abs$1(this._months),
59381            minutes,
59382            hours,
59383            years,
59384            s,
59385            total = this.asSeconds(),
59386            totalSign,
59387            ymSign,
59388            daysSign,
59389            hmsSign;
59390
59391        if (!total) {
59392            // this is the same as C#'s (Noda) and python (isodate)...
59393            // but not other JS (goog.date)
59394            return 'P0D';
59395        }
59396
59397        // 3600 seconds -> 60 minutes -> 1 hour
59398        minutes = absFloor(seconds / 60);
59399        hours = absFloor(minutes / 60);
59400        seconds %= 60;
59401        minutes %= 60;
59402
59403        // 12 months -> 1 year
59404        years = absFloor(months / 12);
59405        months %= 12;
59406
59407        // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
59408        s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : '';
59409
59410        totalSign = total < 0 ? '-' : '';
59411        ymSign = sign(this._months) !== sign(total) ? '-' : '';
59412        daysSign = sign(this._days) !== sign(total) ? '-' : '';
59413        hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';
59414
59415        return (
59416            totalSign +
59417            'P' +
59418            (years ? ymSign + years + 'Y' : '') +
59419            (months ? ymSign + months + 'M' : '') +
59420            (days ? daysSign + days + 'D' : '') +
59421            (hours || minutes || seconds ? 'T' : '') +
59422            (hours ? hmsSign + hours + 'H' : '') +
59423            (minutes ? hmsSign + minutes + 'M' : '') +
59424            (seconds ? hmsSign + s + 'S' : '')
59425        );
59426    }
59427
59428    var proto$2 = Duration.prototype;
59429
59430    proto$2.isValid = isValid$1;
59431    proto$2.abs = abs;
59432    proto$2.add = add$1;
59433    proto$2.subtract = subtract$1;
59434    proto$2.as = as;
59435    proto$2.asMilliseconds = asMilliseconds;
59436    proto$2.asSeconds = asSeconds;
59437    proto$2.asMinutes = asMinutes;
59438    proto$2.asHours = asHours;
59439    proto$2.asDays = asDays;
59440    proto$2.asWeeks = asWeeks;
59441    proto$2.asMonths = asMonths;
59442    proto$2.asQuarters = asQuarters;
59443    proto$2.asYears = asYears;
59444    proto$2.valueOf = valueOf$1;
59445    proto$2._bubble = bubble;
59446    proto$2.clone = clone$1;
59447    proto$2.get = get$2;
59448    proto$2.milliseconds = milliseconds;
59449    proto$2.seconds = seconds;
59450    proto$2.minutes = minutes;
59451    proto$2.hours = hours;
59452    proto$2.days = days;
59453    proto$2.weeks = weeks;
59454    proto$2.months = months;
59455    proto$2.years = years;
59456    proto$2.humanize = humanize;
59457    proto$2.toISOString = toISOString$1;
59458    proto$2.toString = toISOString$1;
59459    proto$2.toJSON = toISOString$1;
59460    proto$2.locale = locale;
59461    proto$2.localeData = localeData;
59462
59463    proto$2.toIsoString = deprecate(
59464        'toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)',
59465        toISOString$1
59466    );
59467    proto$2.lang = lang;
59468
59469    // FORMATTING
59470
59471    addFormatToken('X', 0, 0, 'unix');
59472    addFormatToken('x', 0, 0, 'valueOf');
59473
59474    // PARSING
59475
59476    addRegexToken('x', matchSigned);
59477    addRegexToken('X', matchTimestamp);
59478    addParseToken('X', function (input, array, config) {
59479        config._d = new Date(parseFloat(input) * 1000);
59480    });
59481    addParseToken('x', function (input, array, config) {
59482        config._d = new Date(toInt(input));
59483    });
59484
59485    //! moment.js
59486
59487    hooks.version = '2.29.4';
59488
59489    setHookCallback(createLocal);
59490
59491    hooks.fn = proto;
59492    hooks.min = min;
59493    hooks.max = max;
59494    hooks.now = now;
59495    hooks.utc = createUTC;
59496    hooks.unix = createUnix;
59497    hooks.months = listMonths;
59498    hooks.isDate = isDate;
59499    hooks.locale = getSetGlobalLocale;
59500    hooks.invalid = createInvalid;
59501    hooks.duration = createDuration;
59502    hooks.isMoment = isMoment;
59503    hooks.weekdays = listWeekdays;
59504    hooks.parseZone = createInZone;
59505    hooks.localeData = getLocale;
59506    hooks.isDuration = isDuration;
59507    hooks.monthsShort = listMonthsShort;
59508    hooks.weekdaysMin = listWeekdaysMin;
59509    hooks.defineLocale = defineLocale;
59510    hooks.updateLocale = updateLocale;
59511    hooks.locales = listLocales;
59512    hooks.weekdaysShort = listWeekdaysShort;
59513    hooks.normalizeUnits = normalizeUnits;
59514    hooks.relativeTimeRounding = getSetRelativeTimeRounding;
59515    hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
59516    hooks.calendarFormat = getCalendarFormat;
59517    hooks.prototype = proto;
59518
59519    // currently HTML5 input type only supports 24-hour formats
59520    hooks.HTML5_FMT = {
59521        DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm', // <input type="datetime-local" />
59522        DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', // <input type="datetime-local" step="1" />
59523        DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', // <input type="datetime-local" step="0.001" />
59524        DATE: 'YYYY-MM-DD', // <input type="date" />
59525        TIME: 'HH:mm', // <input type="time" />
59526        TIME_SECONDS: 'HH:mm:ss', // <input type="time" step="1" />
59527        TIME_MS: 'HH:mm:ss.SSS', // <input type="time" step="0.001" />
59528        WEEK: 'GGGG-[W]WW', // <input type="week" />
59529        MONTH: 'YYYY-MM', // <input type="month" />
59530    };
59531
59532    return hooks;
59533
59534})));
59535/**
59536* @version: 3.0.3
59537* @author: Dan Grossman http://www.dangrossman.info/
59538* @copyright: Copyright (c) 2012-2018 Dan Grossman. All rights reserved.
59539* @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php
59540* @website: http://www.daterangepicker.com/
59541*/
59542// Following the UMD template https://github.com/umdjs/umd/blob/master/templates/returnExportsGlobal.js
59543(function (root, factory) {
59544    if (typeof define === 'function' && define.amd) {
59545        // AMD. Make globaly available as well
59546        define(['moment', 'jquery'], function (moment, jquery) {
59547            if (!jquery.fn) jquery.fn = {}; // webpack server rendering
59548            return factory(moment, jquery);
59549        });
59550    } else if (typeof module === 'object' && module.exports) {
59551        // Node / Browserify
59552        //isomorphic issue
59553        var jQuery = (typeof window != 'undefined') ? window.jQuery : undefined;
59554        if (!jQuery) {
59555            jQuery = require('jquery');
59556            if (!jQuery.fn) jQuery.fn = {};
59557        }
59558        var moment = (typeof window != 'undefined' && typeof window.moment != 'undefined') ? window.moment : require('moment');
59559        module.exports = factory(moment, jQuery);
59560    } else {
59561        // Browser globals
59562        root.daterangepicker = factory(root.moment, root.jQuery);
59563    }
59564}(this, function(moment, $) {
59565    var DateRangePicker = function(element, options, cb) {
59566
59567        //default settings for options
59568        this.parentEl = 'body';
59569        this.element = $(element);
59570        this.startDate = moment().startOf('day');
59571        this.endDate = moment().endOf('day');
59572        this.minDate = false;
59573        this.maxDate = false;
59574        this.maxSpan = false;
59575        this.autoApply = false;
59576        this.singleDatePicker = false;
59577        this.showDropdowns = false;
59578        this.minYear = moment().subtract(100, 'year').format('YYYY');
59579        this.maxYear = moment().add(100, 'year').format('YYYY');
59580        this.showWeekNumbers = false;
59581        this.showISOWeekNumbers = false;
59582        this.showCustomRangeLabel = true;
59583        this.timePicker = false;
59584        this.timePicker24Hour = false;
vendor: 37,450 bytes, lines 59585-60466
59585        this.timePickerIncrement = 1;
59586        this.timePickerSeconds = false;
59587        this.linkedCalendars = true;
59588        this.autoUpdateInput = true;
59589        this.alwaysShowCalendars = false;
59590        this.ranges = {};
59591
59592        this.opens = 'right';
59593        if (this.element.hasClass('pull-right'))
59594            this.opens = 'left';
59595
59596        this.drops = 'down';
59597        if (this.element.hasClass('dropup'))
59598            this.drops = 'up';
59599
59600        this.buttonClasses = 'btn btn-sm';
59601        this.applyButtonClasses = 'btn-primary';
59602        this.cancelButtonClasses = 'btn-default';
59603
59604        this.locale = {
59605            direction: 'ltr',
59606            format: moment.localeData().longDateFormat('L'),
59607            separator: ' - ',
59608            applyLabel: 'Apply',
59609            cancelLabel: 'Cancel',
59610            weekLabel: 'W',
59611            customRangeLabel: 'Custom Range',
59612            daysOfWeek: moment.weekdaysMin(),
59613            monthNames: moment.monthsShort(),
59614            firstDay: moment.localeData().firstDayOfWeek()
59615        };
59616
59617        this.callback = function() { };
59618
59619        //some state information
59620        this.isShowing = false;
59621        this.leftCalendar = {};
59622        this.rightCalendar = {};
59623
59624        //custom options from user
59625        if (typeof options !== 'object' || options === null)
59626            options = {};
59627
59628        //allow setting options with data attributes
59629        //data-api options will be overwritten with custom javascript options
59630        options = $.extend(this.element.data(), options);
59631
59632        //html template for the picker UI
59633        if (typeof options.template !== 'string' && !(options.template instanceof $))
59634            options.template =
59635            '<div class="daterangepicker">' +
59636                '<div class="ranges"></div>' +
59637                '<div class="drp-calendar left">' +
59638                    '<div class="calendar-table"></div>' +
59639                    '<div class="calendar-time"></div>' +
59640                '</div>' +
59641                '<div class="drp-calendar right">' +
59642                    '<div class="calendar-table"></div>' +
59643                    '<div class="calendar-time"></div>' +
59644                '</div>' +
59645                '<div class="drp-buttons">' +
59646                    '<span class="drp-selected"></span>' +
59647                    '<button class="cancelBtn" type="button"></button>' +
59648                    '<button class="applyBtn" disabled="disabled" type="button"></button> ' +
59649                '</div>' +
59650            '</div>';
59651
59652        this.parentEl = (options.parentEl && $(options.parentEl).length) ? $(options.parentEl) : $(this.parentEl);
59653        this.container = $(options.template).appendTo(this.parentEl);
59654
59655        //
59656        // handle all the possible options overriding defaults
59657        //
59658
59659        if (typeof options.locale === 'object') {
59660
59661            if (typeof options.locale.direction === 'string')
59662                this.locale.direction = options.locale.direction;
59663
59664            if (typeof options.locale.format === 'string')
59665                this.locale.format = options.locale.format;
59666
59667            if (typeof options.locale.separator === 'string')
59668                this.locale.separator = options.locale.separator;
59669
59670            if (typeof options.locale.daysOfWeek === 'object')
59671                this.locale.daysOfWeek = options.locale.daysOfWeek.slice();
59672
59673            if (typeof options.locale.monthNames === 'object')
59674              this.locale.monthNames = options.locale.monthNames.slice();
59675
59676            if (typeof options.locale.firstDay === 'number')
59677              this.locale.firstDay = options.locale.firstDay;
59678
59679            if (typeof options.locale.applyLabel === 'string')
59680              this.locale.applyLabel = options.locale.applyLabel;
59681
59682            if (typeof options.locale.cancelLabel === 'string')
59683              this.locale.cancelLabel = options.locale.cancelLabel;
59684
59685            if (typeof options.locale.weekLabel === 'string')
59686              this.locale.weekLabel = options.locale.weekLabel;
59687
59688            if (typeof options.locale.customRangeLabel === 'string'){
59689                //Support unicode chars in the custom range name.
59690                var elem = document.createElement('textarea');
59691                elem.innerHTML = options.locale.customRangeLabel;
59692                var rangeHtml = elem.value;
59693                this.locale.customRangeLabel = rangeHtml;
59694            }
59695        }
59696        this.container.addClass(this.locale.direction);
59697
59698        if (typeof options.startDate === 'string')
59699            this.startDate = moment(options.startDate, this.locale.format);
59700
59701        if (typeof options.endDate === 'string')
59702            this.endDate = moment(options.endDate, this.locale.format);
59703
59704        if (typeof options.minDate === 'string')
59705            this.minDate = moment(options.minDate, this.locale.format);
59706
59707        if (typeof options.maxDate === 'string')
59708            this.maxDate = moment(options.maxDate, this.locale.format);
59709
59710        if (typeof options.startDate === 'object')
59711            this.startDate = moment(options.startDate);
59712
59713        if (typeof options.endDate === 'object')
59714            this.endDate = moment(options.endDate);
59715
59716        if (typeof options.minDate === 'object')
59717            this.minDate = moment(options.minDate);
59718
59719        if (typeof options.maxDate === 'object')
59720            this.maxDate = moment(options.maxDate);
59721
59722        // sanity check for bad options
59723        if (this.minDate && this.startDate.isBefore(this.minDate))
59724            this.startDate = this.minDate.clone();
59725
59726        // sanity check for bad options
59727        if (this.maxDate && this.endDate.isAfter(this.maxDate))
59728            this.endDate = this.maxDate.clone();
59729
59730        if (typeof options.applyButtonClasses === 'string')
59731            this.applyButtonClasses = options.applyButtonClasses;
59732
59733        if (typeof options.applyClass === 'string') //backwards compat
59734            this.applyButtonClasses = options.applyClass;
59735
59736        if (typeof options.cancelButtonClasses === 'string')
59737            this.cancelButtonClasses = options.cancelButtonClasses;
59738
59739        if (typeof options.cancelClass === 'string') //backwards compat
59740            this.cancelButtonClasses = options.cancelClass;
59741
59742        if (typeof options.maxSpan === 'object')
59743            this.maxSpan = options.maxSpan;
59744
59745        if (typeof options.dateLimit === 'object') //backwards compat
59746            this.maxSpan = options.dateLimit;
59747
59748        if (typeof options.opens === 'string')
59749            this.opens = options.opens;
59750
59751        if (typeof options.drops === 'string')
59752            this.drops = options.drops;
59753
59754        if (typeof options.showWeekNumbers === 'boolean')
59755            this.showWeekNumbers = options.showWeekNumbers;
59756
59757        if (typeof options.showISOWeekNumbers === 'boolean')
59758            this.showISOWeekNumbers = options.showISOWeekNumbers;
59759
59760        if (typeof options.buttonClasses === 'string')
59761            this.buttonClasses = options.buttonClasses;
59762
59763        if (typeof options.buttonClasses === 'object')
59764            this.buttonClasses = options.buttonClasses.join(' ');
59765
59766        if (typeof options.showDropdowns === 'boolean')
59767            this.showDropdowns = options.showDropdowns;
59768
59769        if (typeof options.minYear === 'number')
59770            this.minYear = options.minYear;
59771
59772        if (typeof options.maxYear === 'number')
59773            this.maxYear = options.maxYear;
59774
59775        if (typeof options.showCustomRangeLabel === 'boolean')
59776            this.showCustomRangeLabel = options.showCustomRangeLabel;
59777
59778        if (typeof options.singleDatePicker === 'boolean') {
59779            this.singleDatePicker = options.singleDatePicker;
59780            if (this.singleDatePicker)
59781                this.endDate = this.startDate.clone();
59782        }
59783
59784        if (typeof options.timePicker === 'boolean')
59785            this.timePicker = options.timePicker;
59786
59787        if (typeof options.timePickerSeconds === 'boolean')
59788            this.timePickerSeconds = options.timePickerSeconds;
59789
59790        if (typeof options.timePickerIncrement === 'number')
59791            this.timePickerIncrement = options.timePickerIncrement;
59792
59793        if (typeof options.timePicker24Hour === 'boolean')
59794            this.timePicker24Hour = options.timePicker24Hour;
59795
59796        if (typeof options.autoApply === 'boolean')
59797            this.autoApply = options.autoApply;
59798
59799        if (typeof options.autoUpdateInput === 'boolean')
59800            this.autoUpdateInput = options.autoUpdateInput;
59801
59802        if (typeof options.linkedCalendars === 'boolean')
59803            this.linkedCalendars = options.linkedCalendars;
59804
59805        if (typeof options.isInvalidDate === 'function')
59806            this.isInvalidDate = options.isInvalidDate;
59807
59808        if (typeof options.isCustomDate === 'function')
59809            this.isCustomDate = options.isCustomDate;
59810
59811        if (typeof options.alwaysShowCalendars === 'boolean')
59812            this.alwaysShowCalendars = options.alwaysShowCalendars;
59813
59814        // update day names order to firstDay
59815        if (this.locale.firstDay != 0) {
59816            var iterator = this.locale.firstDay;
59817            while (iterator > 0) {
59818                this.locale.daysOfWeek.push(this.locale.daysOfWeek.shift());
59819                iterator--;
59820            }
59821        }
59822
59823        var start, end, range;
59824
59825        //if no start/end dates set, check if an input element contains initial values
59826        if (typeof options.startDate === 'undefined' && typeof options.endDate === 'undefined') {
59827            if ($(this.element).is(':text')) {
59828                var val = $(this.element).val(),
59829                    split = val.split(this.locale.separator);
59830
59831                start = end = null;
59832
59833                if (split.length == 2) {
59834                    start = moment(split[0], this.locale.format);
59835                    end = moment(split[1], this.locale.format);
59836                } else if (this.singleDatePicker && val !== "") {
59837                    start = moment(val, this.locale.format);
59838                    end = moment(val, this.locale.format);
59839                }
59840                if (start !== null && end !== null) {
59841                    this.setStartDate(start);
59842                    this.setEndDate(end);
59843                }
59844            }
59845        }
59846
59847        if (typeof options.ranges === 'object') {
59848            for (range in options.ranges) {
59849
59850                if (typeof options.ranges[range][0] === 'string')
59851                    start = moment(options.ranges[range][0], this.locale.format);
59852                else
59853                    start = moment(options.ranges[range][0]);
59854
59855                if (typeof options.ranges[range][1] === 'string')
59856                    end = moment(options.ranges[range][1], this.locale.format);
59857                else
59858                    end = moment(options.ranges[range][1]);
59859
59860                // If the start or end date exceed those allowed by the minDate or maxSpan
59861                // options, shorten the range to the allowable period.
59862                if (this.minDate && start.isBefore(this.minDate))
59863                    start = this.minDate.clone();
59864
59865                var maxDate = this.maxDate;
59866                if (this.maxSpan && maxDate && start.clone().add(this.maxSpan).isAfter(maxDate))
59867                    maxDate = start.clone().add(this.maxSpan);
59868                if (maxDate && end.isAfter(maxDate))
59869                    end = maxDate.clone();
59870
59871                // If the end of the range is before the minimum or the start of the range is
59872                // after the maximum, don't display this range option at all.
59873                if ((this.minDate && end.isBefore(this.minDate, this.timepicker ? 'minute' : 'day'))
59874                  || (maxDate && start.isAfter(maxDate, this.timepicker ? 'minute' : 'day')))
59875                    continue;
59876
59877                //Support unicode chars in the range names.
59878                var elem = document.createElement('textarea');
59879                elem.innerHTML = range;
59880                var rangeHtml = elem.value;
59881
59882                this.ranges[rangeHtml] = [start, end];
59883            }
59884
59885            var list = '<ul>';
59886            for (range in this.ranges) {
59887                list += '<li data-range-key="' + range + '">' + range + '</li>';
59888            }
59889            if (this.showCustomRangeLabel) {
59890                list += '<li data-range-key="' + this.locale.customRangeLabel + '">' + this.locale.customRangeLabel + '</li>';
59891            }
59892            list += '</ul>';
59893            this.container.find('.ranges').prepend(list);
59894        }
59895
59896        if (typeof cb === 'function') {
59897            this.callback = cb;
59898        }
59899
59900        if (!this.timePicker) {
59901            this.startDate = this.startDate.startOf('day');
59902            this.endDate = this.endDate.endOf('day');
59903            this.container.find('.calendar-time').hide();
59904        }
59905
59906        //can't be used together for now
59907        if (this.timePicker && this.autoApply)
59908            this.autoApply = false;
59909
59910        if (this.autoApply) {
59911            this.container.addClass('auto-apply');
59912        }
59913
59914        if (typeof options.ranges === 'object')
59915            this.container.addClass('show-ranges');
59916
59917        if (this.singleDatePicker) {
59918            this.container.addClass('single');
59919            this.container.find('.drp-calendar.left').addClass('single');
59920            this.container.find('.drp-calendar.left').show();
59921            this.container.find('.drp-calendar.right').hide();
59922            if (!this.timePicker) {
59923                this.container.addClass('auto-apply');
59924            }
59925        }
59926
59927        if ((typeof options.ranges === 'undefined' && !this.singleDatePicker) || this.alwaysShowCalendars) {
59928            this.container.addClass('show-calendar');
59929        }
59930
59931        this.container.addClass('opens' + this.opens);
59932
59933        //apply CSS classes and labels to buttons
59934        this.container.find('.applyBtn, .cancelBtn').addClass(this.buttonClasses);
59935        if (this.applyButtonClasses.length)
59936            this.container.find('.applyBtn').addClass(this.applyButtonClasses);
59937        if (this.cancelButtonClasses.length)
59938            this.container.find('.cancelBtn').addClass(this.cancelButtonClasses);
59939        this.container.find('.applyBtn').html(this.locale.applyLabel);
59940        this.container.find('.cancelBtn').html(this.locale.cancelLabel);
59941
59942        //
59943        // event listeners
59944        //
59945
59946        this.container.find('.drp-calendar')
59947            .on('click.daterangepicker', '.prev', $.proxy(this.clickPrev, this))
59948            .on('click.daterangepicker', '.next', $.proxy(this.clickNext, this))
59949            .on('mousedown.daterangepicker', 'td.available', $.proxy(this.clickDate, this))
59950            .on('mouseenter.daterangepicker', 'td.available', $.proxy(this.hoverDate, this))
59951            .on('change.daterangepicker', 'select.yearselect', $.proxy(this.monthOrYearChanged, this))
59952            .on('change.daterangepicker', 'select.monthselect', $.proxy(this.monthOrYearChanged, this))
59953            .on('change.daterangepicker', 'select.hourselect,select.minuteselect,select.secondselect,select.ampmselect', $.proxy(this.timeChanged, this))
59954
59955        this.container.find('.ranges')
59956            .on('click.daterangepicker', 'li', $.proxy(this.clickRange, this))
59957
59958        this.container.find('.drp-buttons')
59959            .on('click.daterangepicker', 'button.applyBtn', $.proxy(this.clickApply, this))
59960            .on('click.daterangepicker', 'button.cancelBtn', $.proxy(this.clickCancel, this))
59961
59962        if (this.element.is('input') || this.element.is('button')) {
59963            this.element.on({
59964                'click.daterangepicker': $.proxy(this.show, this),
59965                'focus.daterangepicker': $.proxy(this.show, this),
59966                'keyup.daterangepicker': $.proxy(this.elementChanged, this),
59967                'keydown.daterangepicker': $.proxy(this.keydown, this) //IE 11 compatibility
59968            });
59969        } else {
59970            this.element.on('click.daterangepicker', $.proxy(this.toggle, this));
59971            this.element.on('keydown.daterangepicker', $.proxy(this.toggle, this));
59972        }
59973
59974        //
59975        // if attached to a text input, set the initial value
59976        //
59977
59978        this.updateElement();
59979
59980    };
59981
59982    DateRangePicker.prototype = {
59983
59984        constructor: DateRangePicker,
59985
59986        setStartDate: function(startDate) {
59987            if (typeof startDate === 'string')
59988                this.startDate = moment(startDate, this.locale.format);
59989
59990            if (typeof startDate === 'object')
59991                this.startDate = moment(startDate);
59992
59993            if (!this.timePicker)
59994                this.startDate = this.startDate.startOf('day');
59995
59996            if (this.timePicker && this.timePickerIncrement)
59997                this.startDate.minute(Math.round(this.startDate.minute() / this.timePickerIncrement) * this.timePickerIncrement);
59998
59999            if (this.minDate && this.startDate.isBefore(this.minDate)) {
60000                this.startDate = this.minDate.clone();
60001                if (this.timePicker && this.timePickerIncrement)
60002                    this.startDate.minute(Math.round(this.startDate.minute() / this.timePickerIncrement) * this.timePickerIncrement);
60003            }
60004
60005            if (this.maxDate && this.startDate.isAfter(this.maxDate)) {
60006                this.startDate = this.maxDate.clone();
60007                if (this.timePicker && this.timePickerIncrement)
60008                    this.startDate.minute(Math.floor(this.startDate.minute() / this.timePickerIncrement) * this.timePickerIncrement);
60009            }
60010
60011            if (!this.isShowing)
60012                this.updateElement();
60013
60014            this.updateMonthsInView();
60015        },
60016
60017        setEndDate: function(endDate) {
60018            if (typeof endDate === 'string')
60019                this.endDate = moment(endDate, this.locale.format);
60020
60021            if (typeof endDate === 'object')
60022                this.endDate = moment(endDate);
60023
60024            if (!this.timePicker)
60025                this.endDate = this.endDate.add(1,'d').startOf('day').subtract(1,'second');
60026
60027            if (this.timePicker && this.timePickerIncrement)
60028                this.endDate.minute(Math.round(this.endDate.minute() / this.timePickerIncrement) * this.timePickerIncrement);
60029
60030            if (this.endDate.isBefore(this.startDate))
60031                this.endDate = this.startDate.clone();
60032
60033            if (this.maxDate && this.endDate.isAfter(this.maxDate))
60034                this.endDate = this.maxDate.clone();
60035
60036            if (this.maxSpan && this.startDate.clone().add(this.maxSpan).isBefore(this.endDate))
60037                this.endDate = this.startDate.clone().add(this.maxSpan);
60038
60039            this.previousRightTime = this.endDate.clone();
60040
60041            this.container.find('.drp-selected').html(this.startDate.format(this.locale.format) + this.locale.separator + this.endDate.format(this.locale.format));
60042
60043            if (!this.isShowing)
60044                this.updateElement();
60045
60046            this.updateMonthsInView();
60047        },
60048
60049        isInvalidDate: function() {
60050            return false;
60051        },
60052
60053        isCustomDate: function() {
60054            return false;
60055        },
60056
60057        updateView: function() {
60058            if (this.timePicker) {
60059                this.renderTimePicker('left');
60060                this.renderTimePicker('right');
60061                if (!this.endDate) {
60062                    this.container.find('.right .calendar-time select').attr('disabled', 'disabled').addClass('disabled');
60063                } else {
60064                    this.container.find('.right .calendar-time select').removeAttr('disabled').removeClass('disabled');
60065                }
60066            }
60067            if (this.endDate)
60068                this.container.find('.drp-selected').html(this.startDate.format(this.locale.format) + this.locale.separator + this.endDate.format(this.locale.format));
60069            this.updateMonthsInView();
60070            this.updateCalendars();
60071            this.updateFormInputs();
60072        },
60073
60074        updateMonthsInView: function() {
60075            if (this.endDate) {
60076
60077                //if both dates are visible already, do nothing
60078                if (!this.singleDatePicker && this.leftCalendar.month && this.rightCalendar.month &&
60079                    (this.startDate.format('YYYY-MM') == this.leftCalendar.month.format('YYYY-MM') || this.startDate.format('YYYY-MM') == this.rightCalendar.month.format('YYYY-MM'))
60080                    &&
60081                    (this.endDate.format('YYYY-MM') == this.leftCalendar.month.format('YYYY-MM') || this.endDate.format('YYYY-MM') == this.rightCalendar.month.format('YYYY-MM'))
60082                    ) {
60083                    return;
60084                }
60085
60086                this.leftCalendar.month = this.startDate.clone().date(2);
60087                if (!this.linkedCalendars && (this.endDate.month() != this.startDate.month() || this.endDate.year() != this.startDate.year())) {
60088                    this.rightCalendar.month = this.endDate.clone().date(2);
60089                } else {
60090                    this.rightCalendar.month = this.startDate.clone().date(2).add(1, 'month');
60091                }
60092
60093            } else {
60094                if (this.leftCalendar.month.format('YYYY-MM') != this.startDate.format('YYYY-MM') && this.rightCalendar.month.format('YYYY-MM') != this.startDate.format('YYYY-MM')) {
60095                    this.leftCalendar.month = this.startDate.clone().date(2);
60096                    this.rightCalendar.month = this.startDate.clone().date(2).add(1, 'month');
60097                }
60098            }
60099            if (this.maxDate && this.linkedCalendars && !this.singleDatePicker && this.rightCalendar.month > this.maxDate) {
60100              this.rightCalendar.month = this.maxDate.clone().date(2);
60101              this.leftCalendar.month = this.maxDate.clone().date(2).subtract(1, 'month');
60102            }
60103        },
60104
60105        updateCalendars: function() {
60106
60107            if (this.timePicker) {
60108                var hour, minute, second;
60109                if (this.endDate) {
60110                    hour = parseInt(this.container.find('.left .hourselect').val(), 10);
60111                    minute = parseInt(this.container.find('.left .minuteselect').val(), 10);
60112                    second = this.timePickerSeconds ? parseInt(this.container.find('.left .secondselect').val(), 10) : 0;
60113                    if (!this.timePicker24Hour) {
60114                        var ampm = this.container.find('.left .ampmselect').val();
60115                        if (ampm === 'PM' && hour < 12)
60116                            hour += 12;
60117                        if (ampm === 'AM' && hour === 12)
60118                            hour = 0;
60119                    }
60120                } else {
60121                    hour = parseInt(this.container.find('.right .hourselect').val(), 10);
60122                    minute = parseInt(this.container.find('.right .minuteselect').val(), 10);
60123                    second = this.timePickerSeconds ? parseInt(this.container.find('.right .secondselect').val(), 10) : 0;
60124                    if (!this.timePicker24Hour) {
60125                        var ampm = this.container.find('.right .ampmselect').val();
60126                        if (ampm === 'PM' && hour < 12)
60127                            hour += 12;
60128                        if (ampm === 'AM' && hour === 12)
60129                            hour = 0;
60130                    }
60131                }
60132                this.leftCalendar.month.hour(hour).minute(minute).second(second);
60133                this.rightCalendar.month.hour(hour).minute(minute).second(second);
60134            }
60135
60136            this.renderCalendar('left');
60137            this.renderCalendar('right');
60138
60139            //highlight any predefined range matching the current start and end dates
60140            this.container.find('.ranges li').removeClass('active');
60141            if (this.endDate == null) return;
60142
60143            this.calculateChosenLabel();
60144        },
60145
60146        renderCalendar: function(side) {
60147
60148            //
60149            // Build the matrix of dates that will populate the calendar
60150            //
60151
60152            var calendar = side == 'left' ? this.leftCalendar : this.rightCalendar;
60153            var month = calendar.month.month();
60154            var year = calendar.month.year();
60155            var hour = calendar.month.hour();
60156            var minute = calendar.month.minute();
60157            var second = calendar.month.second();
60158            var daysInMonth = moment([year, month]).daysInMonth();
60159            var firstDay = moment([year, month, 1]);
60160            var lastDay = moment([year, month, daysInMonth]);
60161            var lastMonth = moment(firstDay).subtract(1, 'month').month();
60162            var lastYear = moment(firstDay).subtract(1, 'month').year();
60163            var daysInLastMonth = moment([lastYear, lastMonth]).daysInMonth();
60164            var dayOfWeek = firstDay.day();
60165
60166            //initialize a 6 rows x 7 columns array for the calendar
60167            var calendar = [];
60168            calendar.firstDay = firstDay;
60169            calendar.lastDay = lastDay;
60170
60171            for (var i = 0; i < 6; i++) {
60172                calendar[i] = [];
60173            }
60174
60175            //populate the calendar with date objects
60176            var startDay = daysInLastMonth - dayOfWeek + this.locale.firstDay + 1;
60177            if (startDay > daysInLastMonth)
60178                startDay -= 7;
60179
60180            if (dayOfWeek == this.locale.firstDay)
60181                startDay = daysInLastMonth - 6;
60182
60183            var curDate = moment([lastYear, lastMonth, startDay, 12, minute, second]);
60184
60185            var col, row;
60186            for (var i = 0, col = 0, row = 0; i < 42; i++, col++, curDate = moment(curDate).add(24, 'hour')) {
60187                if (i > 0 && col % 7 === 0) {
60188                    col = 0;
60189                    row++;
60190                }
60191                calendar[row][col] = curDate.clone().hour(hour).minute(minute).second(second);
60192                curDate.hour(12);
60193
60194                if (this.minDate && calendar[row][col].format('YYYY-MM-DD') == this.minDate.format('YYYY-MM-DD') && calendar[row][col].isBefore(this.minDate) && side == 'left') {
60195                    calendar[row][col] = this.minDate.clone();
60196                }
60197
60198                if (this.maxDate && calendar[row][col].format('YYYY-MM-DD') == this.maxDate.format('YYYY-MM-DD') && calendar[row][col].isAfter(this.maxDate) && side == 'right') {
60199                    calendar[row][col] = this.maxDate.clone();
60200                }
60201
60202            }
60203
60204            //make the calendar object available to hoverDate/clickDate
60205            if (side == 'left') {
60206                this.leftCalendar.calendar = calendar;
60207            } else {
60208                this.rightCalendar.calendar = calendar;
60209            }
60210
60211            //
60212            // Display the calendar
60213            //
60214
60215            var minDate = side == 'left' ? this.minDate : this.startDate;
60216            var maxDate = this.maxDate;
60217            var selected = side == 'left' ? this.startDate : this.endDate;
60218            var arrow = this.locale.direction == 'ltr' ? {left: 'chevron-left', right: 'chevron-right'} : {left: 'chevron-right', right: 'chevron-left'};
60219
60220            var html = '<table class="table-condensed">';
60221            html += '<thead>';
60222            html += '<tr>';
60223
60224            // add empty cell for week number
60225            if (this.showWeekNumbers || this.showISOWeekNumbers)
60226                html += '<th></th>';
60227
60228            if ((!minDate || minDate.isBefore(calendar.firstDay)) && (!this.linkedCalendars || side == 'left')) {
60229                html += '<th class="prev available"><span></span></th>';
60230            } else {
60231                html += '<th></th>';
60232            }
60233
60234            var dateHtml = this.locale.monthNames[calendar[1][1].month()] + calendar[1][1].format(" YYYY");
60235
60236            if (this.showDropdowns) {
60237                var currentMonth = calendar[1][1].month();
60238                var currentYear = calendar[1][1].year();
60239                var maxYear = (maxDate && maxDate.year()) || (this.maxYear);
60240                var minYear = (minDate && minDate.year()) || (this.minYear);
60241                var inMinYear = currentYear == minYear;
60242                var inMaxYear = currentYear == maxYear;
60243
60244                var monthHtml = '<select class="monthselect">';
60245                for (var m = 0; m < 12; m++) {
60246                    if ((!inMinYear || m >= minDate.month()) && (!inMaxYear || m <= maxDate.month())) {
60247                        monthHtml += "<option value='" + m + "'" +
60248                            (m === currentMonth ? " selected='selected'" : "") +
60249                            ">" + this.locale.monthNames[m] + "</option>";
60250                    } else {
60251                        monthHtml += "<option value='" + m + "'" +
60252                            (m === currentMonth ? " selected='selected'" : "") +
60253                            " disabled='disabled'>" + this.locale.monthNames[m] + "</option>";
60254                    }
60255                }
60256                monthHtml += "</select>";
60257
60258                var yearHtml = '<select class="yearselect">';
60259                for (var y = minYear; y <= maxYear; y++) {
60260                    yearHtml += '<option value="' + y + '"' +
60261                        (y === currentYear ? ' selected="selected"' : '') +
60262                        '>' + y + '</option>';
60263                }
60264                yearHtml += '</select>';
60265
60266                dateHtml = monthHtml + yearHtml;
60267            }
60268
60269            html += '<th colspan="5" class="month">' + dateHtml + '</th>';
60270            if ((!maxDate || maxDate.isAfter(calendar.lastDay)) && (!this.linkedCalendars || side == 'right' || this.singleDatePicker)) {
60271                html += '<th class="next available"><span></span></th>';
60272            } else {
60273                html += '<th></th>';
60274            }
60275
60276            html += '</tr>';
60277            html += '<tr>';
60278
60279            // add week number label
60280            if (this.showWeekNumbers || this.showISOWeekNumbers)
60281                html += '<th class="week">' + this.locale.weekLabel + '</th>';
60282
60283            $.each(this.locale.daysOfWeek, function(index, dayOfWeek) {
60284                html += '<th>' + dayOfWeek + '</th>';
60285            });
60286
60287            html += '</tr>';
60288            html += '</thead>';
60289            html += '<tbody>';
60290
60291            //adjust maxDate to reflect the maxSpan setting in order to
60292            //grey out end dates beyond the maxSpan
60293            if (this.endDate == null && this.maxSpan) {
60294                var maxLimit = this.startDate.clone().add(this.maxSpan).endOf('day');
60295                if (!maxDate || maxLimit.isBefore(maxDate)) {
60296                    maxDate = maxLimit;
60297                }
60298            }
60299
60300            for (var row = 0; row < 6; row++) {
60301                html += '<tr>';
60302
60303                // add week number
60304                if (this.showWeekNumbers)
60305                    html += '<td class="week">' + calendar[row][0].week() + '</td>';
60306                else if (this.showISOWeekNumbers)
60307                    html += '<td class="week">' + calendar[row][0].isoWeek() + '</td>';
60308
60309                for (var col = 0; col < 7; col++) {
60310
60311                    var classes = [];
60312
60313                    //highlight today's date
60314                    if (calendar[row][col].isSame(new Date(), "day"))
60315                        classes.push('today');
60316
60317                    //highlight weekends
60318                    if (calendar[row][col].isoWeekday() > 5)
60319                        classes.push('weekend');
60320
60321                    //grey out the dates in other months displayed at beginning and end of this calendar
60322                    if (calendar[row][col].month() != calendar[1][1].month())
60323                        classes.push('off');
60324
60325                    //don't allow selection of dates before the minimum date
60326                    if (this.minDate && calendar[row][col].isBefore(this.minDate, 'day'))
60327                        classes.push('off', 'disabled');
60328
60329                    //don't allow selection of dates after the maximum date
60330                    if (maxDate && calendar[row][col].isAfter(maxDate, 'day'))
60331                        classes.push('off', 'disabled');
60332
60333                    //don't allow selection of date if a custom function decides it's invalid
60334                    if (this.isInvalidDate(calendar[row][col]))
60335                        classes.push('off', 'disabled');
60336
60337                    //highlight the currently selected start date
60338                    if (calendar[row][col].format('YYYY-MM-DD') == this.startDate.format('YYYY-MM-DD'))
60339                        classes.push('active', 'start-date');
60340
60341                    //highlight the currently selected end date
60342                    if (this.endDate != null && calendar[row][col].format('YYYY-MM-DD') == this.endDate.format('YYYY-MM-DD'))
60343                        classes.push('active', 'end-date');
60344
60345                    //highlight dates in-between the selected dates
60346                    if (this.endDate != null && calendar[row][col] > this.startDate && calendar[row][col] < this.endDate)
60347                        classes.push('in-range');
60348
60349                    //apply custom classes for this date
60350                    var isCustom = this.isCustomDate(calendar[row][col]);
60351                    if (isCustom !== false) {
60352                        if (typeof isCustom === 'string')
60353                            classes.push(isCustom);
60354                        else
60355                            Array.prototype.push.apply(classes, isCustom);
60356                    }
60357
60358                    var cname = '', disabled = false;
60359                    for (var i = 0; i < classes.length; i++) {
60360                        cname += classes[i] + ' ';
60361                        if (classes[i] == 'disabled')
60362                            disabled = true;
60363                    }
60364                    if (!disabled)
60365                        cname += 'available';
60366
60367                    html += '<td class="' + cname.replace(/^\s+|\s+$/g, '') + '" data-title="' + 'r' + row + 'c' + col + '">' + calendar[row][col].date() + '</td>';
60368
60369                }
60370                html += '</tr>';
60371            }
60372
60373            html += '</tbody>';
60374            html += '</table>';
60375
60376            this.container.find('.drp-calendar.' + side + ' .calendar-table').html(html);
60377
60378        },
60379
60380        renderTimePicker: function(side) {
60381
60382            // Don't bother updating the time picker if it's currently disabled
60383            // because an end date hasn't been clicked yet
60384            if (side == 'right' && !this.endDate) return;
60385
60386            var html, selected, minDate, maxDate = this.maxDate;
60387
60388            if (this.maxSpan && (!this.maxDate || this.startDate.clone().add(this.maxSpan).isAfter(this.maxDate)))
60389                maxDate = this.startDate.clone().add(this.maxSpan);
60390
60391            if (side == 'left') {
60392                selected = this.startDate.clone();
60393                minDate = this.minDate;
60394            } else if (side == 'right') {
60395                selected = this.endDate.clone();
60396                minDate = this.startDate;
60397
60398                //Preserve the time already selected
60399                var timeSelector = this.container.find('.drp-calendar.right .calendar-time');
60400                if (timeSelector.html() != '') {
60401
60402                    selected.hour(selected.hour() || timeSelector.find('.hourselect option:selected').val());
60403                    selected.minute(selected.minute() || timeSelector.find('.minuteselect option:selected').val());
60404                    selected.second(selected.second() || timeSelector.find('.secondselect option:selected').val());
60405
60406                    if (!this.timePicker24Hour) {
60407                        var ampm = timeSelector.find('.ampmselect option:selected').val();
60408                        if (ampm === 'PM' && selected.hour() < 12)
60409                            selected.hour(selected.hour() + 12);
60410                        if (ampm === 'AM' && selected.hour() === 12)
60411                            selected.hour(0);
60412                    }
60413
60414                }
60415
60416                if (selected.isBefore(this.startDate))
60417                    selected = this.startDate.clone();
60418
60419                if (maxDate && selected.isAfter(maxDate))
60420                    selected = maxDate.clone();
60421
60422            }
60423
60424            //
60425            // hours
60426            //
60427
60428            html = '<select class="hourselect">';
60429
60430            var start = this.timePicker24Hour ? 0 : 1;
60431            var end = this.timePicker24Hour ? 23 : 12;
60432
60433            for (var i = start; i <= end; i++) {
60434                var i_in_24 = i;
60435                if (!this.timePicker24Hour)
60436                    i_in_24 = selected.hour() >= 12 ? (i == 12 ? 12 : i + 12) : (i == 12 ? 0 : i);
60437
60438                var time = selected.clone().hour(i_in_24);
60439                var disabled = false;
60440                if (minDate && time.minute(59).isBefore(minDate))
60441                    disabled = true;
60442                if (maxDate && time.minute(0).isAfter(maxDate))
60443                    disabled = true;
60444
60445                if (i_in_24 == selected.hour() && !disabled) {
60446                    html += '<option value="' + i + '" selected="selected">' + i + '</option>';
60447                } else if (disabled) {
60448                    html += '<option value="' + i + '" disabled="disabled" class="disabled">' + i + '</option>';
60449                } else {
60450                    html += '<option value="' + i + '">' + i + '</option>';
60451                }
60452            }
60453
60454            html += '</select> ';
60455
60456            //
60457            // minutes
60458            //
60459
60460            html += ': <select class="minuteselect">';
60461
60462            for (var i = 0; i < 60; i += this.timePickerIncrement) {
60463                var padded = i < 10 ? '0' + i : i;
60464                var time = selected.clone().minute(i);
60465
60466                var disabled = false;
60467                if (minDate && time.second(59).isBefore(minDate))
60468                    disabled = true;
60469                if (maxDate && time.second(0).isAfter(maxDate))
60470                    disabled = true;
60471
60472                if (selected.minute() == i && !disabled) {
60473                    html += '<option value="' + i + '" selected="selected">' + padded + '</option>';
60474                } else if (disabled) {
60475                    html += '<option value="' + i + '" disabled="disabled" class="disabled">' + padded + '</option>';
60476                } else {
60477                    html += '<option value="' + i + '">' + padded + '</option>';
60478                }
60479            }
60480
60481            html += '</select> ';
60482
60483            //
60484            // seconds
60485            //
60486
60487            if (this.timePickerSeconds) {
60488                html += ': <select class="secondselect">';
60489
60490                for (var i = 0; i < 60; i++) {
60491                    var padded = i < 10 ? '0' + i : i;
60492                    var time = selected.clone().second(i);
60493
60494                    var disabled = false;
60495                    if (minDate && time.isBefore(minDate))
60496                        disabled = true;
60497                    if (maxDate && time.isAfter(maxDate))
60498                        disabled = true;
60499
60500                    if (selected.second() == i && !disabled) {
60501                        html += '<option value="' + i + '" selected="selected">' + padded + '</option>';
60502                    } else if (disabled) {
60503                        html += '<option value="' + i + '" disabled="disabled" class="disabled">' + padded + '</option>';
60504                    } else {
60505                        html += '<option value="' + i + '">' + padded + '</option>';
60506                    }
60507                }
60508
60509                html += '</select> ';
60510            }
60511
60512            //
60513            // AM/PM
60514            //
60515
60516            if (!this.timePicker24Hour) {
60517                html += '<select class="ampmselect">';
60518
60519                var am_html = '';
60520                var pm_html = '';
60521
60522                if (minDate && selected.clone().hour(12).minute(0).second(0).isBefore(minDate))
60523                    am_html = ' disabled="disabled" class="disabled"';
60524
60525                if (maxDate && selected.clone().hour(0).minute(0).second(0).isAfter(maxDate))
60526                    pm_html = ' disabled="disabled" class="disabled"';
60527
60528                if (selected.hour() >= 12) {
60529                    html += '<option value="AM"' + am_html + '>AM</option><option value="PM" selected="selected"' + pm_html + '>PM</option>';
60530                } else {
60531                    html += '<option value="AM" selected="selected"' + am_html + '>AM</option><option value="PM"' + pm_html + '>PM</option>';
60532                }
60533
60534                html += '</select>';
60535            }
60536
60537            this.container.find('.drp-calendar.' + side + ' .calendar-time').html(html);
60538
60539        },
60540
60541        updateFormInputs: function() {
60542
60543            if (this.singleDatePicker || (this.endDate && (this.startDate.isBefore(this.endDate) || this.startDate.isSame(this.endDate)))) {
60544                this.container.find('button.applyBtn').removeAttr('disabled');
60545            } else {
60546                this.container.find('button.applyBtn').attr('disabled', 'disabled');
60547            }
60548
60549        },
60550
60551        move: function() {
60552            var parentOffset = { top: 0, left: 0 },
60553                containerTop;
60554            var parentRightEdge = $(window).width();
60555            if (!this.parentEl.is('body')) {
60556                parentOffset = {
60557                    top: this.parentEl.offset().top - this.parentEl.scrollTop(),
60558                    left: this.parentEl.offset().left - this.parentEl.scrollLeft()
60559                };
60560                parentRightEdge = this.parentEl[0].clientWidth + this.parentEl.offset().left;
60561            }
60562
60563            if (this.drops == 'up')
60564                containerTop = this.element.offset().top - this.container.outerHeight() - parentOffset.top;
60565            else
60566                containerTop = this.element.offset().top + this.element.outerHeight() - parentOffset.top;
60567            this.container[this.drops == 'up' ? 'addClass' : 'removeClass']('drop-up');
60568
60569            if (this.opens == 'left') {
60570                this.container.css({
60571                    top: containerTop,
60572                    right: parentRightEdge - this.element.offset().left - this.element.outerWidth(),
60573                    left: 'auto'
60574                });
60575                if (this.container.offset().left < 0) {
60576                    this.container.css({
60577                        right: 'auto',
60578                        left: 9
60579                    });
60580                }
60581            } else if (this.opens == 'center') {
60582                this.container.css({
60583                    top: containerTop,
60584                    left: this.element.offset().left - parentOffset.left + this.element.outerWidth() / 2
60585                            - this.container.outerWidth() / 2,
60586                    right: 'auto'
60587                });
60588                if (this.container.offset().left < 0) {
60589                    this.container.css({
60590                        right: 'auto',
60591                        left: 9
60592                    });
60593                }
60594            } else {
60595                this.container.css({
60596                    top: containerTop,
60597                    left: this.element.offset().left - parentOffset.left,
60598                    right: 'auto'
60599                });
60600                if (this.container.offset().left + this.container.outerWidth() > $(window).width()) {
60601                    this.container.css({
60602                        left: 'auto',
60603                        right: 0
60604                    });
60605                }
60606            }
60607        },
60608
60609        show: function(e) {
60610            if (this.isShowing) return;
60611
60612            // Create a click proxy that is private to this instance of datepicker, for unbinding
60613            this._outsideClickProxy = $.proxy(function(e) { this.outsideClick(e); }, this);
60614
60615            // Bind global datepicker mousedown for hiding and
60616            $(document)
60617              .on('mousedown.daterangepicker', this._outsideClickProxy)
60618              // also support mobile devices
60619              .on('touchend.daterangepicker', this._outsideClickProxy)
60620              // also explicitly play nice with Bootstrap dropdowns, which stopPropagation when clicking them
60621              .on('click.daterangepicker', '[data-toggle=dropdown]', this._outsideClickProxy)
vendor: 18,175 bytes, lines 60622-61067
60622              // and also close when focus changes to outside the picker (eg. tabbing between controls)
60623              .on('focusin.daterangepicker', this._outsideClickProxy);
60624
60625            // Reposition the picker if the window is resized while it's open
60626            $(window).on('resize.daterangepicker', $.proxy(function(e) { this.move(e); }, this));
60627
60628            this.oldStartDate = this.startDate.clone();
60629            this.oldEndDate = this.endDate.clone();
60630            this.previousRightTime = this.endDate.clone();
60631
60632            this.updateView();
60633            this.container.show();
60634            this.move();
60635            this.element.trigger('show.daterangepicker', this);
60636            this.isShowing = true;
60637        },
60638
60639        hide: function(e) {
60640            if (!this.isShowing) return;
60641
60642            //incomplete date selection, revert to last values
60643            if (!this.endDate) {
60644                this.startDate = this.oldStartDate.clone();
60645                this.endDate = this.oldEndDate.clone();
60646            }
60647
60648            //if a new date range was selected, invoke the user callback function
60649            if (!this.startDate.isSame(this.oldStartDate) || !this.endDate.isSame(this.oldEndDate))
60650                this.callback(this.startDate.clone(), this.endDate.clone(), this.chosenLabel);
60651
60652            //if picker is attached to a text input, update it
60653            this.updateElement();
60654
60655            $(document).off('.daterangepicker');
60656            $(window).off('.daterangepicker');
60657            this.container.hide();
60658            this.element.trigger('hide.daterangepicker', this);
60659            this.isShowing = false;
60660        },
60661
60662        toggle: function(e) {
60663            if (this.isShowing) {
60664                this.hide();
60665            } else {
60666                this.show();
60667            }
60668        },
60669
60670        outsideClick: function(e) {
60671            var target = $(e.target);
60672            // if the page is clicked anywhere except within the daterangerpicker/button
60673            // itself then call this.hide()
60674            if (
60675                // ie modal dialog fix
60676                e.type == "focusin" ||
60677                target.closest(this.element).length ||
60678                target.closest(this.container).length ||
60679                target.closest('.calendar-table').length
60680                ) return;
60681            this.hide();
60682            this.element.trigger('outsideClick.daterangepicker', this);
60683        },
60684
60685        showCalendars: function() {
60686            this.container.addClass('show-calendar');
60687            this.move();
60688            this.element.trigger('showCalendar.daterangepicker', this);
60689        },
60690
60691        hideCalendars: function() {
60692            this.container.removeClass('show-calendar');
60693            this.element.trigger('hideCalendar.daterangepicker', this);
60694        },
60695
60696        clickRange: function(e) {
60697            var label = e.target.getAttribute('data-range-key');
60698            this.chosenLabel = label;
60699            if (label == this.locale.customRangeLabel) {
60700                this.showCalendars();
60701            } else {
60702                var dates = this.ranges[label];
60703                this.startDate = dates[0];
60704                this.endDate = dates[1];
60705
60706                if (!this.timePicker) {
60707                    this.startDate.startOf('day');
60708                    this.endDate.endOf('day');
60709                }
60710
60711                if (!this.alwaysShowCalendars)
60712                    this.hideCalendars();
60713                this.clickApply();
60714            }
60715        },
60716
60717        clickPrev: function(e) {
60718            var cal = $(e.target).parents('.drp-calendar');
60719            if (cal.hasClass('left')) {
60720                this.leftCalendar.month.subtract(1, 'month');
60721                if (this.linkedCalendars)
60722                    this.rightCalendar.month.subtract(1, 'month');
60723            } else {
60724                this.rightCalendar.month.subtract(1, 'month');
60725            }
60726            this.updateCalendars();
60727        },
60728
60729        clickNext: function(e) {
60730            var cal = $(e.target).parents('.drp-calendar');
60731            if (cal.hasClass('left')) {
60732                this.leftCalendar.month.add(1, 'month');
60733            } else {
60734                this.rightCalendar.month.add(1, 'month');
60735                if (this.linkedCalendars)
60736                    this.leftCalendar.month.add(1, 'month');
60737            }
60738            this.updateCalendars();
60739        },
60740
60741        hoverDate: function(e) {
60742
60743            //ignore dates that can't be selected
60744            if (!$(e.target).hasClass('available')) return;
60745
60746            var title = $(e.target).attr('data-title');
60747            var row = title.substr(1, 1);
60748            var col = title.substr(3, 1);
60749            var cal = $(e.target).parents('.drp-calendar');
60750            var date = cal.hasClass('left') ? this.leftCalendar.calendar[row][col] : this.rightCalendar.calendar[row][col];
60751
60752            //highlight the dates between the start date and the date being hovered as a potential end date
60753            var leftCalendar = this.leftCalendar;
60754            var rightCalendar = this.rightCalendar;
60755            var startDate = this.startDate;
60756            if (!this.endDate) {
60757                this.container.find('.drp-calendar tbody td').each(function(index, el) {
60758
60759                    //skip week numbers, only look at dates
60760                    if ($(el).hasClass('week')) return;
60761
60762                    var title = $(el).attr('data-title');
60763                    var row = title.substr(1, 1);
60764                    var col = title.substr(3, 1);
60765                    var cal = $(el).parents('.drp-calendar');
60766                    var dt = cal.hasClass('left') ? leftCalendar.calendar[row][col] : rightCalendar.calendar[row][col];
60767
60768                    if ((dt.isAfter(startDate) && dt.isBefore(date)) || dt.isSame(date, 'day')) {
60769                        $(el).addClass('in-range');
60770                    } else {
60771                        $(el).removeClass('in-range');
60772                    }
60773
60774                });
60775            }
60776
60777        },
60778
60779        clickDate: function(e) {
60780
60781            if (!$(e.target).hasClass('available')) return;
60782
60783            var title = $(e.target).attr('data-title');
60784            var row = title.substr(1, 1);
60785            var col = title.substr(3, 1);
60786            var cal = $(e.target).parents('.drp-calendar');
60787            var date = cal.hasClass('left') ? this.leftCalendar.calendar[row][col] : this.rightCalendar.calendar[row][col];
60788
60789            //
60790            // this function needs to do a few things:
60791            // * alternate between selecting a start and end date for the range,
60792            // * if the time picker is enabled, apply the hour/minute/second from the select boxes to the clicked date
60793            // * if autoapply is enabled, and an end date was chosen, apply the selection
60794            // * if single date picker mode, and time picker isn't enabled, apply the selection immediately
60795            // * if one of the inputs above the calendars was focused, cancel that manual input
60796            //
60797
60798            if (this.endDate || date.isBefore(this.startDate, 'day')) { //picking start
60799                if (this.timePicker) {
60800                    var hour = parseInt(this.container.find('.left .hourselect').val(), 10);
60801                    if (!this.timePicker24Hour) {
60802                        var ampm = this.container.find('.left .ampmselect').val();
60803                        if (ampm === 'PM' && hour < 12)
60804                            hour += 12;
60805                        if (ampm === 'AM' && hour === 12)
60806                            hour = 0;
60807                    }
60808                    var minute = parseInt(this.container.find('.left .minuteselect').val(), 10);
60809                    var second = this.timePickerSeconds ? parseInt(this.container.find('.left .secondselect').val(), 10) : 0;
60810                    date = date.clone().hour(hour).minute(minute).second(second);
60811                }
60812                this.endDate = null;
60813                this.setStartDate(date.clone());
60814            } else if (!this.endDate && date.isBefore(this.startDate)) {
60815                //special case: clicking the same date for start/end,
60816                //but the time of the end date is before the start date
60817                this.setEndDate(this.startDate.clone());
60818            } else { // picking end
60819                if (this.timePicker) {
60820                    var hour = parseInt(this.container.find('.right .hourselect').val(), 10);
60821                    if (!this.timePicker24Hour) {
60822                        var ampm = this.container.find('.right .ampmselect').val();
60823                        if (ampm === 'PM' && hour < 12)
60824                            hour += 12;
60825                        if (ampm === 'AM' && hour === 12)
60826                            hour = 0;
60827                    }
60828                    var minute = parseInt(this.container.find('.right .minuteselect').val(), 10);
60829                    var second = this.timePickerSeconds ? parseInt(this.container.find('.right .secondselect').val(), 10) : 0;
60830                    date = date.clone().hour(hour).minute(minute).second(second);
60831                }
60832                this.setEndDate(date.clone());
60833                if (this.autoApply) {
60834                  this.calculateChosenLabel();
60835                  this.clickApply();
60836                }
60837            }
60838
60839            if (this.singleDatePicker) {
60840                this.setEndDate(this.startDate);
60841                if (!this.timePicker)
60842                    this.clickApply();
60843            }
60844
60845            this.updateView();
60846
60847            //This is to cancel the blur event handler if the mouse was in one of the inputs
60848            e.stopPropagation();
60849
60850        },
60851
60852        calculateChosenLabel: function () {
60853            var customRange = true;
60854            var i = 0;
60855            for (var range in this.ranges) {
60856              if (this.timePicker) {
60857                    var format = this.timePickerSeconds ? "YYYY-MM-DD hh:mm:ss" : "YYYY-MM-DD hh:mm";
60858                    //ignore times when comparing dates if time picker seconds is not enabled
60859                    if (this.startDate.format(format) == this.ranges[range][0].format(format) && this.endDate.format(format) == this.ranges[range][1].format(format)) {
60860                        customRange = false;
60861                        this.chosenLabel = this.container.find('.ranges li:eq(' + i + ')').addClass('active').attr('data-range-key');
60862                        break;
60863                    }
60864                } else {
60865                    //ignore times when comparing dates if time picker is not enabled
60866                    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')) {
60867                        customRange = false;
60868                        this.chosenLabel = this.container.find('.ranges li:eq(' + i + ')').addClass('active').attr('data-range-key');
60869                        break;
60870                    }
60871                }
60872                i++;
60873            }
60874            if (customRange) {
60875                if (this.showCustomRangeLabel) {
60876                    this.chosenLabel = this.container.find('.ranges li:last').addClass('active').attr('data-range-key');
60877                } else {
60878                    this.chosenLabel = null;
60879                }
60880                this.showCalendars();
60881            }
60882        },
60883
60884        clickApply: function(e) {
60885            this.hide();
60886            this.element.trigger('apply.daterangepicker', this);
60887        },
60888
60889        clickCancel: function(e) {
60890            this.startDate = this.oldStartDate;
60891            this.endDate = this.oldEndDate;
60892            this.hide();
60893            this.element.trigger('cancel.daterangepicker', this);
60894        },
60895
60896        monthOrYearChanged: function(e) {
60897            var isLeft = $(e.target).closest('.drp-calendar').hasClass('left'),
60898                leftOrRight = isLeft ? 'left' : 'right',
60899                cal = this.container.find('.drp-calendar.'+leftOrRight);
60900
60901            // Month must be Number for new moment versions
60902            var month = parseInt(cal.find('.monthselect').val(), 10);
60903            var year = cal.find('.yearselect').val();
60904
60905            if (!isLeft) {
60906                if (year < this.startDate.year() || (year == this.startDate.year() && month < this.startDate.month())) {
60907                    month = this.startDate.month();
60908                    year = this.startDate.year();
60909                }
60910            }
60911
60912            if (this.minDate) {
60913                if (year < this.minDate.year() || (year == this.minDate.year() && month < this.minDate.month())) {
60914                    month = this.minDate.month();
60915                    year = this.minDate.year();
60916                }
60917            }
60918
60919            if (this.maxDate) {
60920                if (year > this.maxDate.year() || (year == this.maxDate.year() && month > this.maxDate.month())) {
60921                    month = this.maxDate.month();
60922                    year = this.maxDate.year();
60923                }
60924            }
60925
60926            if (isLeft) {
60927                this.leftCalendar.month.month(month).year(year);
60928                if (this.linkedCalendars)
60929                    this.rightCalendar.month = this.leftCalendar.month.clone().add(1, 'month');
60930            } else {
60931                this.rightCalendar.month.month(month).year(year);
60932                if (this.linkedCalendars)
60933                    this.leftCalendar.month = this.rightCalendar.month.clone().subtract(1, 'month');
60934            }
60935            this.updateCalendars();
60936        },
60937
60938        timeChanged: function(e) {
60939
60940            var cal = $(e.target).closest('.drp-calendar'),
60941                isLeft = cal.hasClass('left');
60942
60943            var hour = parseInt(cal.find('.hourselect').val(), 10);
60944            var minute = parseInt(cal.find('.minuteselect').val(), 10);
60945            var second = this.timePickerSeconds ? parseInt(cal.find('.secondselect').val(), 10) : 0;
60946
60947            if (!this.timePicker24Hour) {
60948                var ampm = cal.find('.ampmselect').val();
60949                if (ampm === 'PM' && hour < 12)
60950                    hour += 12;
60951                if (ampm === 'AM' && hour === 12)
60952                    hour = 0;
60953            }
60954
60955            if (isLeft) {
60956                var start = this.startDate.clone();
60957                start.hour(hour);
60958                start.minute(minute);
60959                start.second(second);
60960                this.setStartDate(start);
60961                if (this.singleDatePicker) {
60962                    this.endDate = this.startDate.clone();
60963                } else if (this.endDate && this.endDate.format('YYYY-MM-DD') == start.format('YYYY-MM-DD') && this.endDate.isBefore(start)) {
60964                    this.setEndDate(start.clone());
60965                }
60966            } else if (this.endDate) {
60967                var end = this.endDate.clone();
60968                end.hour(hour);
60969                end.minute(minute);
60970                end.second(second);
60971                this.setEndDate(end);
60972            }
60973
60974            //update the calendars so all clickable dates reflect the new time component
60975            this.updateCalendars();
60976
60977            //update the form inputs above the calendars with the new time
60978            this.updateFormInputs();
60979
60980            //re-render the time pickers because changing one selection can affect what's enabled in another
60981            this.renderTimePicker('left');
60982            this.renderTimePicker('right');
60983
60984        },
60985
60986        elementChanged: function() {
60987            if (!this.element.is('input')) return;
60988            if (!this.element.val().length) return;
60989
60990            var dateString = this.element.val().split(this.locale.separator),
60991                start = null,
60992                end = null;
60993
60994            if (dateString.length === 2) {
60995                start = moment(dateString[0], this.locale.format);
60996                end = moment(dateString[1], this.locale.format);
60997            }
60998
60999            if (this.singleDatePicker || start === null || end === null) {
61000                start = moment(this.element.val(), this.locale.format);
61001                end = start;
61002            }
61003
61004            if (!start.isValid() || !end.isValid()) return;
61005
61006            this.setStartDate(start);
61007            this.setEndDate(end);
61008            this.updateView();
61009        },
61010
61011        keydown: function(e) {
61012            //hide on tab or enter
61013            if ((e.keyCode === 9) || (e.keyCode === 13)) {
61014                this.hide();
61015            }
61016
61017            //hide on esc and prevent propagation
61018            if (e.keyCode === 27) {
61019                e.preventDefault();
61020                e.stopPropagation();
61021
61022                this.hide();
61023            }
61024        },
61025
61026        updateElement: function() {
61027            if (this.element.is('input') && this.autoUpdateInput) {
61028                var newValue = this.startDate.format(this.locale.format);
61029                if (!this.singleDatePicker) {
61030                    newValue += this.locale.separator + this.endDate.format(this.locale.format);
61031                }
61032                if (newValue !== this.element.val()) {
61033                    this.element.val(newValue).trigger('change');
61034                }
61035            }
61036        },
61037
61038        remove: function() {
61039            this.container.remove();
61040            this.element.off('.daterangepicker');
61041            this.element.removeData();
61042        }
61043
61044    };
61045
61046    $.fn.daterangepicker = function(options, callback) {
61047        var implementOptions = $.extend(true, {}, $.fn.daterangepicker.defaultOptions, options);
61048        this.each(function() {
61049            var el = $(this);
61050            if (el.data('daterangepicker'))
61051                el.data('daterangepicker').remove();
61052            el.data('daterangepicker', new DateRangePicker(el, implementOptions, callback));
61053        });
61054        return this;
61055    };
61056
61057    return DateRangePicker;
61058
61059}));
61060(function(global, factory) {
61061  typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define([ "exports" ], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, 
61062  factory(global.ActiveStorage = {}));
61063})(this, (function(exports) {
61064  "use strict";
61065  var sparkMd5 = {
61066    exports: {}
61067  };
61068  (function(module, exports) {
61069    (function(factory) {
61070      {
61071        module.exports = factory();
61072      }
61073    })((function(undefined$1) {
61074      var hex_chr = [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" ];
61075      function md5cycle(x, k) {
61076        var a = x[0], b = x[1], c = x[2], d = x[3];
61077        a += (b & c | ~b & d) + k[0] - 680876936 | 0;
61078        a = (a << 7 | a >>> 25) + b | 0;
61079        d += (a & b | ~a & c) + k[1] - 389564586 | 0;
61080        d = (d << 12 | d >>> 20) + a | 0;
61081        c += (d & a | ~d & b) + k[2] + 606105819 | 0;
61082        c = (c << 17 | c >>> 15) + d | 0;
61083        b += (c & d | ~c & a) + k[3] - 1044525330 | 0;
61084        b = (b << 22 | b >>> 10) + c | 0;
61085        a += (b & c | ~b & d) + k[4] - 176418897 | 0;
61086        a = (a << 7 | a >>> 25) + b | 0;
61087        d += (a & b | ~a & c) + k[5] + 1200080426 | 0;
61088        d = (d << 12 | d >>> 20) + a | 0;
61089        c += (d & a | ~d & b) + k[6] - 1473231341 | 0;
61090        c = (c << 17 | c >>> 15) + d | 0;
61091        b += (c & d | ~c & a) + k[7] - 45705983 | 0;
61092        b = (b << 22 | b >>> 10) + c | 0;
61093        a += (b & c | ~b & d) + k[8] + 1770035416 | 0;
61094        a = (a << 7 | a >>> 25) + b | 0;
61095        d += (a & b | ~a & c) + k[9] - 1958414417 | 0;
61096        d = (d << 12 | d >>> 20) + a | 0;
61097        c += (d & a | ~d & b) + k[10] - 42063 | 0;
61098        c = (c << 17 | c >>> 15) + d | 0;
61099        b += (c & d | ~c & a) + k[11] - 1990404162 | 0;
61100        b = (b << 22 | b >>> 10) + c | 0;
61101        a += (b & c | ~b & d) + k[12] + 1804603682 | 0;
61102        a = (a << 7 | a >>> 25) + b | 0;
61103        d += (a & b | ~a & c) + k[13] - 40341101 | 0;
61104        d = (d << 12 | d >>> 20) + a | 0;
61105        c += (d & a | ~d & b) + k[14] - 1502002290 | 0;
61106        c = (c << 17 | c >>> 15) + d | 0;
61107        b += (c & d | ~c & a) + k[15] + 1236535329 | 0;
61108        b = (b << 22 | b >>> 10) + c | 0;
61109        a += (b & d | c & ~d) + k[1] - 165796510 | 0;
61110        a = (a << 5 | a >>> 27) + b | 0;
61111        d += (a & c | b & ~c) + k[6] - 1069501632 | 0;
61112        d = (d << 9 | d >>> 23) + a | 0;
61113        c += (d & b | a & ~b) + k[11] + 643717713 | 0;
61114        c = (c << 14 | c >>> 18) + d | 0;
61115        b += (c & a | d & ~a) + k[0] - 373897302 | 0;
61116        b = (b << 20 | b >>> 12) + c | 0;
61117        a += (b & d | c & ~d) + k[5] - 701558691 | 0;
61118        a = (a << 5 | a >>> 27) + b | 0;
61119        d += (a & c | b & ~c) + k[10] + 38016083 | 0;
61120        d = (d << 9 | d >>> 23) + a | 0;
61121        c += (d & b | a & ~b) + k[15] - 660478335 | 0;
61122        c = (c << 14 | c >>> 18) + d | 0;
61123        b += (c & a | d & ~a) + k[4] - 405537848 | 0;
61124        b = (b << 20 | b >>> 12) + c | 0;
61125        a += (b & d | c & ~d) + k[9] + 568446438 | 0;
61126        a = (a << 5 | a >>> 27) + b | 0;
61127        d += (a & c | b & ~c) + k[14] - 1019803690 | 0;
61128        d = (d << 9 | d >>> 23) + a | 0;
61129        c += (d & b | a & ~b) + k[3] - 187363961 | 0;
61130        c = (c << 14 | c >>> 18) + d | 0;
61131        b += (c & a | d & ~a) + k[8] + 1163531501 | 0;
61132        b = (b << 20 | b >>> 12) + c | 0;
61133        a += (b & d | c & ~d) + k[13] - 1444681467 | 0;
61134        a = (a << 5 | a >>> 27) + b | 0;
61135        d += (a & c | b & ~c) + k[2] - 51403784 | 0;
61136        d = (d << 9 | d >>> 23) + a | 0;
61137        c += (d & b | a & ~b) + k[7] + 1735328473 | 0;
61138        c = (c << 14 | c >>> 18) + d | 0;
61139        b += (c & a | d & ~a) + k[12] - 1926607734 | 0;
61140        b = (b << 20 | b >>> 12) + c | 0;
61141        a += (b ^ c ^ d) + k[5] - 378558 | 0;
61142        a = (a << 4 | a >>> 28) + b | 0;
61143        d += (a ^ b ^ c) + k[8] - 2022574463 | 0;
61144        d = (d << 11 | d >>> 21) + a | 0;
61145        c += (d ^ a ^ b) + k[11] + 1839030562 | 0;
61146        c = (c << 16 | c >>> 16) + d | 0;
61147        b += (c ^ d ^ a) + k[14] - 35309556 | 0;
61148        b = (b << 23 | b >>> 9) + c | 0;
61149        a += (b ^ c ^ d) + k[1] - 1530992060 | 0;
61150        a = (a << 4 | a >>> 28) + b | 0;
61151        d += (a ^ b ^ c) + k[4] + 1272893353 | 0;
61152        d = (d << 11 | d >>> 21) + a | 0;
61153        c += (d ^ a ^ b) + k[7] - 155497632 | 0;
61154        c = (c << 16 | c >>> 16) + d | 0;
61155        b += (c ^ d ^ a) + k[10] - 1094730640 | 0;
61156        b = (b << 23 | b >>> 9) + c | 0;
61157        a += (b ^ c ^ d) + k[13] + 681279174 | 0;
61158        a = (a << 4 | a >>> 28) + b | 0;
61159        d += (a ^ b ^ c) + k[0] - 358537222 | 0;
61160        d = (d << 11 | d >>> 21) + a | 0;
61161        c += (d ^ a ^ b) + k[3] - 722521979 | 0;
61162        c = (c << 16 | c >>> 16) + d | 0;
61163        b += (c ^ d ^ a) + k[6] + 76029189 | 0;
61164        b = (b << 23 | b >>> 9) + c | 0;
61165        a += (b ^ c ^ d) + k[9] - 640364487 | 0;
61166        a = (a << 4 | a >>> 28) + b | 0;
61167        d += (a ^ b ^ c) + k[12] - 421815835 | 0;
61168        d = (d << 11 | d >>> 21) + a | 0;
61169        c += (d ^ a ^ b) + k[15] + 530742520 | 0;
61170        c = (c << 16 | c >>> 16) + d | 0;
61171        b += (c ^ d ^ a) + k[2] - 995338651 | 0;
61172        b = (b << 23 | b >>> 9) + c | 0;
61173        a += (c ^ (b | ~d)) + k[0] - 198630844 | 0;
61174        a = (a << 6 | a >>> 26) + b | 0;
61175        d += (b ^ (a | ~c)) + k[7] + 1126891415 | 0;
61176        d = (d << 10 | d >>> 22) + a | 0;
61177        c += (a ^ (d | ~b)) + k[14] - 1416354905 | 0;
61178        c = (c << 15 | c >>> 17) + d | 0;
61179        b += (d ^ (c | ~a)) + k[5] - 57434055 | 0;
61180        b = (b << 21 | b >>> 11) + c | 0;
61181        a += (c ^ (b | ~d)) + k[12] + 1700485571 | 0;
61182        a = (a << 6 | a >>> 26) + b | 0;
61183        d += (b ^ (a | ~c)) + k[3] - 1894986606 | 0;
61184        d = (d << 10 | d >>> 22) + a | 0;
61185        c += (a ^ (d | ~b)) + k[10] - 1051523 | 0;
61186        c = (c << 15 | c >>> 17) + d | 0;
61187        b += (d ^ (c | ~a)) + k[1] - 2054922799 | 0;
61188        b = (b << 21 | b >>> 11) + c | 0;
61189        a += (c ^ (b | ~d)) + k[8] + 1873313359 | 0;
61190        a = (a << 6 | a >>> 26) + b | 0;
61191        d += (b ^ (a | ~c)) + k[15] - 30611744 | 0;
61192        d = (d << 10 | d >>> 22) + a | 0;
61193        c += (a ^ (d | ~b)) + k[6] - 1560198380 | 0;
61194        c = (c << 15 | c >>> 17) + d | 0;
61195        b += (d ^ (c | ~a)) + k[13] + 1309151649 | 0;
61196        b = (b << 21 | b >>> 11) + c | 0;
61197        a += (c ^ (b | ~d)) + k[4] - 145523070 | 0;
61198        a = (a << 6 | a >>> 26) + b | 0;
vendor: 10,289 bytes, lines 61199-61484
61199        d += (b ^ (a | ~c)) + k[11] - 1120210379 | 0;
61200        d = (d << 10 | d >>> 22) + a | 0;
61201        c += (a ^ (d | ~b)) + k[2] + 718787259 | 0;
61202        c = (c << 15 | c >>> 17) + d | 0;
61203        b += (d ^ (c | ~a)) + k[9] - 343485551 | 0;
61204        b = (b << 21 | b >>> 11) + c | 0;
61205        x[0] = a + x[0] | 0;
61206        x[1] = b + x[1] | 0;
61207        x[2] = c + x[2] | 0;
61208        x[3] = d + x[3] | 0;
61209      }
61210      function md5blk(s) {
61211        var md5blks = [], i;
61212        for (i = 0; i < 64; i += 4) {
61213          md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24);
61214        }
61215        return md5blks;
61216      }
61217      function md5blk_array(a) {
61218        var md5blks = [], i;
61219        for (i = 0; i < 64; i += 4) {
61220          md5blks[i >> 2] = a[i] + (a[i + 1] << 8) + (a[i + 2] << 16) + (a[i + 3] << 24);
61221        }
61222        return md5blks;
61223      }
61224      function md51(s) {
61225        var n = s.length, state = [ 1732584193, -271733879, -1732584194, 271733878 ], i, length, tail, tmp, lo, hi;
61226        for (i = 64; i <= n; i += 64) {
61227          md5cycle(state, md5blk(s.substring(i - 64, i)));
61228        }
61229        s = s.substring(i - 64);
61230        length = s.length;
61231        tail = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
61232        for (i = 0; i < length; i += 1) {
61233          tail[i >> 2] |= s.charCodeAt(i) << (i % 4 << 3);
61234        }
61235        tail[i >> 2] |= 128 << (i % 4 << 3);
61236        if (i > 55) {
61237          md5cycle(state, tail);
61238          for (i = 0; i < 16; i += 1) {
61239            tail[i] = 0;
61240          }
61241        }
61242        tmp = n * 8;
61243        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
61244        lo = parseInt(tmp[2], 16);
61245        hi = parseInt(tmp[1], 16) || 0;
61246        tail[14] = lo;
61247        tail[15] = hi;
61248        md5cycle(state, tail);
61249        return state;
61250      }
61251      function md51_array(a) {
61252        var n = a.length, state = [ 1732584193, -271733879, -1732584194, 271733878 ], i, length, tail, tmp, lo, hi;
61253        for (i = 64; i <= n; i += 64) {
61254          md5cycle(state, md5blk_array(a.subarray(i - 64, i)));
61255        }
61256        a = i - 64 < n ? a.subarray(i - 64) : new Uint8Array(0);
61257        length = a.length;
61258        tail = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
61259        for (i = 0; i < length; i += 1) {
61260          tail[i >> 2] |= a[i] << (i % 4 << 3);
61261        }
61262        tail[i >> 2] |= 128 << (i % 4 << 3);
61263        if (i > 55) {
61264          md5cycle(state, tail);
61265          for (i = 0; i < 16; i += 1) {
61266            tail[i] = 0;
61267          }
61268        }
61269        tmp = n * 8;
61270        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
61271        lo = parseInt(tmp[2], 16);
61272        hi = parseInt(tmp[1], 16) || 0;
61273        tail[14] = lo;
61274        tail[15] = hi;
61275        md5cycle(state, tail);
61276        return state;
61277      }
61278      function rhex(n) {
61279        var s = "", j;
61280        for (j = 0; j < 4; j += 1) {
61281          s += hex_chr[n >> j * 8 + 4 & 15] + hex_chr[n >> j * 8 & 15];
61282        }
61283        return s;
61284      }
61285      function hex(x) {
61286        var i;
61287        for (i = 0; i < x.length; i += 1) {
61288          x[i] = rhex(x[i]);
61289        }
61290        return x.join("");
61291      }
61292      if (hex(md51("hello")) !== "5d41402abc4b2a76b9719d911017c592") ;
61293      if (typeof ArrayBuffer !== "undefined" && !ArrayBuffer.prototype.slice) {
61294        (function() {
61295          function clamp(val, length) {
61296            val = val | 0 || 0;
61297            if (val < 0) {
61298              return Math.max(val + length, 0);
61299            }
61300            return Math.min(val, length);
61301          }
61302          ArrayBuffer.prototype.slice = function(from, to) {
61303            var length = this.byteLength, begin = clamp(from, length), end = length, num, target, targetArray, sourceArray;
61304            if (to !== undefined$1) {
61305              end = clamp(to, length);
61306            }
61307            if (begin > end) {
61308              return new ArrayBuffer(0);
61309            }
61310            num = end - begin;
61311            target = new ArrayBuffer(num);
61312            targetArray = new Uint8Array(target);
61313            sourceArray = new Uint8Array(this, begin, num);
61314            targetArray.set(sourceArray);
61315            return target;
61316          };
61317        })();
61318      }
61319      function toUtf8(str) {
61320        if (/[\u0080-\uFFFF]/.test(str)) {
61321          str = unescape(encodeURIComponent(str));
61322        }
61323        return str;
61324      }
61325      function utf8Str2ArrayBuffer(str, returnUInt8Array) {
61326        var length = str.length, buff = new ArrayBuffer(length), arr = new Uint8Array(buff), i;
61327        for (i = 0; i < length; i += 1) {
61328          arr[i] = str.charCodeAt(i);
61329        }
61330        return returnUInt8Array ? arr : buff;
61331      }
61332      function arrayBuffer2Utf8Str(buff) {
61333        return String.fromCharCode.apply(null, new Uint8Array(buff));
61334      }
61335      function concatenateArrayBuffers(first, second, returnUInt8Array) {
61336        var result = new Uint8Array(first.byteLength + second.byteLength);
61337        result.set(new Uint8Array(first));
61338        result.set(new Uint8Array(second), first.byteLength);
61339        return returnUInt8Array ? result : result.buffer;
61340      }
61341      function hexToBinaryString(hex) {
61342        var bytes = [], length = hex.length, x;
61343        for (x = 0; x < length - 1; x += 2) {
61344          bytes.push(parseInt(hex.substr(x, 2), 16));
61345        }
61346        return String.fromCharCode.apply(String, bytes);
61347      }
61348      function SparkMD5() {
61349        this.reset();
61350      }
61351      SparkMD5.prototype.append = function(str) {
61352        this.appendBinary(toUtf8(str));
61353        return this;
61354      };
61355      SparkMD5.prototype.appendBinary = function(contents) {
61356        this._buff += contents;
61357        this._length += contents.length;
61358        var length = this._buff.length, i;
61359        for (i = 64; i <= length; i += 64) {
61360          md5cycle(this._hash, md5blk(this._buff.substring(i - 64, i)));
61361        }
61362        this._buff = this._buff.substring(i - 64);
61363        return this;
61364      };
61365      SparkMD5.prototype.end = function(raw) {
61366        var buff = this._buff, length = buff.length, i, tail = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], ret;
61367        for (i = 0; i < length; i += 1) {
61368          tail[i >> 2] |= buff.charCodeAt(i) << (i % 4 << 3);
61369        }
61370        this._finish(tail, length);
61371        ret = hex(this._hash);
61372        if (raw) {
61373          ret = hexToBinaryString(ret);
61374        }
61375        this.reset();
61376        return ret;
61377      };
61378      SparkMD5.prototype.reset = function() {
61379        this._buff = "";
61380        this._length = 0;
61381        this._hash = [ 1732584193, -271733879, -1732584194, 271733878 ];
61382        return this;
61383      };
61384      SparkMD5.prototype.getState = function() {
61385        return {
61386          buff: this._buff,
61387          length: this._length,
61388          hash: this._hash.slice()
61389        };
61390      };
61391      SparkMD5.prototype.setState = function(state) {
61392        this._buff = state.buff;
61393        this._length = state.length;
61394        this._hash = state.hash;
61395        return this;
61396      };
61397      SparkMD5.prototype.destroy = function() {
61398        delete this._hash;
61399        delete this._buff;
61400        delete this._length;
61401      };
61402      SparkMD5.prototype._finish = function(tail, length) {
61403        var i = length, tmp, lo, hi;
61404        tail[i >> 2] |= 128 << (i % 4 << 3);
61405        if (i > 55) {
61406          md5cycle(this._hash, tail);
61407          for (i = 0; i < 16; i += 1) {
61408            tail[i] = 0;
61409          }
61410        }
61411        tmp = this._length * 8;
61412        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
61413        lo = parseInt(tmp[2], 16);
61414        hi = parseInt(tmp[1], 16) || 0;
61415        tail[14] = lo;
61416        tail[15] = hi;
61417        md5cycle(this._hash, tail);
61418      };
61419      SparkMD5.hash = function(str, raw) {
61420        return SparkMD5.hashBinary(toUtf8(str), raw);
61421      };
61422      SparkMD5.hashBinary = function(content, raw) {
61423        var hash = md51(content), ret = hex(hash);
61424        return raw ? hexToBinaryString(ret) : ret;
61425      };
61426      SparkMD5.ArrayBuffer = function() {
61427        this.reset();
61428      };
61429      SparkMD5.ArrayBuffer.prototype.append = function(arr) {
61430        var buff = concatenateArrayBuffers(this._buff.buffer, arr, true), length = buff.length, i;
61431        this._length += arr.byteLength;
61432        for (i = 64; i <= length; i += 64) {
61433          md5cycle(this._hash, md5blk_array(buff.subarray(i - 64, i)));
61434        }
61435        this._buff = i - 64 < length ? new Uint8Array(buff.buffer.slice(i - 64)) : new Uint8Array(0);
61436        return this;
61437      };
61438      SparkMD5.ArrayBuffer.prototype.end = function(raw) {
61439        var buff = this._buff, length = buff.length, tail = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], i, ret;
61440        for (i = 0; i < length; i += 1) {
61441          tail[i >> 2] |= buff[i] << (i % 4 << 3);
61442        }
61443        this._finish(tail, length);
61444        ret = hex(this._hash);
61445        if (raw) {
61446          ret = hexToBinaryString(ret);
61447        }
61448        this.reset();
61449        return ret;
61450      };
61451      SparkMD5.ArrayBuffer.prototype.reset = function() {
61452        this._buff = new Uint8Array(0);
61453        this._length = 0;
61454        this._hash = [ 1732584193, -271733879, -1732584194, 271733878 ];
61455        return this;
61456      };
61457      SparkMD5.ArrayBuffer.prototype.getState = function() {
61458        var state = SparkMD5.prototype.getState.call(this);
61459        state.buff = arrayBuffer2Utf8Str(state.buff);
61460        return state;
61461      };
61462      SparkMD5.ArrayBuffer.prototype.setState = function(state) {
61463        state.buff = utf8Str2ArrayBuffer(state.buff, true);
61464        return SparkMD5.prototype.setState.call(this, state);
61465      };
61466      SparkMD5.ArrayBuffer.prototype.destroy = SparkMD5.prototype.destroy;
61467      SparkMD5.ArrayBuffer.prototype._finish = SparkMD5.prototype._finish;
61468      SparkMD5.ArrayBuffer.hash = function(arr, raw) {
61469        var hash = md51_array(new Uint8Array(arr)), ret = hex(hash);
61470        return raw ? hexToBinaryString(ret) : ret;
61471      };
61472      return SparkMD5;
61473    }));
61474  })(sparkMd5);
61475  var SparkMD5 = sparkMd5.exports;
61476  const fileSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
61477  class FileChecksum {
61478    static create(file, callback) {
61479      const instance = new FileChecksum(file);
61480      instance.create(callback);
61481    }
61482    constructor(file) {
61483      this.file = file;
61484      this.chunkSize = 2097152;
61485      this.chunkCount = Math.ceil(this.file.size / this.chunkSize);
61486      this.chunkIndex = 0;
61487    }
61488    create(callback) {
61489      this.callback = callback;
61490      this.md5Buffer = new SparkMD5.ArrayBuffer;
61491      this.fileReader = new FileReader;
61492      this.fileReader.addEventListener("load", (event => this.fileReaderDidLoad(event)));
61493      this.fileReader.addEventListener("error", (event => this.fileReaderDidError(event)));
61494      this.readNextChunk();
61495    }
61496    fileReaderDidLoad(event) {
61497      this.md5Buffer.append(event.target.result);
61498      if (!this.readNextChunk()) {
61499        const binaryDigest = this.md5Buffer.end(true);
61500        const base64digest = btoa(binaryDigest);
61501        this.callback(null, base64digest);
61502      }
61503    }
61504    fileReaderDidError(event) {
61505      this.callback(`Error reading ${this.file.name}`);
61506    }
61507    readNextChunk() {
61508      if (this.chunkIndex < this.chunkCount || this.chunkIndex == 0 && this.chunkCount == 0) {
61509        const start = this.chunkIndex * this.chunkSize;
61510        const end = Math.min(start + this.chunkSize, this.file.size);
61511        const bytes = fileSlice.call(this.file, start, end);
61512        this.fileReader.readAsArrayBuffer(bytes);
61513        this.chunkIndex++;
61514        return true;
61515      } else {
61516        return false;
61517      }
61518    }
61519  }
61520  function getMetaValue(name) {
61521    const element = findElement(document.head, `meta[name="${name}"]`);
61522    if (element) {
61523      return element.getAttribute("content");
61524    }
61525  }
61526  function findElements(root, selector) {
61527    if (typeof root == "string") {
61528      selector = root;
61529      root = document;
61530    }
61531    const elements = root.querySelectorAll(selector);
61532    return toArray(elements);
61533  }
61534  function findElement(root, selector) {
61535    if (typeof root == "string") {
61536      selector = root;
61537      root = document;
61538    }
61539    return root.querySelector(selector);
61540  }
61541  function dispatchEvent(element, type, eventInit = {}) {
61542    const {disabled: disabled} = element;
61543    const {bubbles: bubbles, cancelable: cancelable, detail: detail} = eventInit;
61544    const event = document.createEvent("Event");
61545    event.initEvent(type, bubbles || true, cancelable || true);
61546    event.detail = detail || {};
61547    try {
61548      element.disabled = false;
61549      element.dispatchEvent(event);
61550    } finally {
61551      element.disabled = disabled;
61552    }
61553    return event;
61554  }
61555  function toArray(value) {
61556    if (Array.isArray(value)) {
61557      return value;
61558    } else if (Array.from) {
61559      return Array.from(value);
61560    } else {
61561      return [].slice.call(value);
61562    }
61563  }
61564  class BlobRecord {
61565    constructor(file, checksum, url) {
61566      this.file = file;
61567      this.attributes = {
61568        filename: file.name,
61569        content_type: file.type || "application/octet-stream",
61570        byte_size: file.size,
61571        checksum: checksum
61572      };
61573      this.xhr = new XMLHttpRequest;
61574      this.xhr.open("POST", url, true);
61575      this.xhr.responseType = "json";
61576      this.xhr.setRequestHeader("Content-Type", "application/json");
61577      this.xhr.setRequestHeader("Accept", "application/json");
61578      this.xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
61579      const csrfToken = getMetaValue("csrf-token");
61580      if (csrfToken != undefined) {
61581        this.xhr.setRequestHeader("X-CSRF-Token", csrfToken);
61582      }
61583      this.xhr.addEventListener("load", (event => this.requestDidLoad(event)));
61584      this.xhr.addEventListener("error", (event => this.requestDidError(event)));
61585    }
61586    get status() {
61587      return this.xhr.status;
61588    }
61589    get response() {
61590      const {responseType: responseType, response: response} = this.xhr;
61591      if (responseType == "json") {
61592        return response;
61593      } else {
61594        return JSON.parse(response);
61595      }
61596    }
61597    create(callback) {
61598      this.callback = callback;
61599      this.xhr.send(JSON.stringify({
61600        blob: this.attributes
61601      }));
61602    }
61603    requestDidLoad(event) {
61604      if (this.status >= 200 && this.status < 300) {
61605        const {response: response} = this;
61606        const {direct_upload: direct_upload} = response;
61607        delete response.direct_upload;
61608        this.attributes = response;
61609        this.directUploadData = direct_upload;
61610        this.callback(null, this.toJSON());
61611      } else {
61612        this.requestDidError(event);
61613      }
61614    }
61615    requestDidError(event) {
61616      this.callback(`Error creating Blob for "${this.file.name}". Status: ${this.status}`);
61617    }
61618    toJSON() {
61619      const result = {};
61620      for (const key in this.attributes) {
61621        result[key] = this.attributes[key];
61622      }
61623      return result;
61624    }
61625  }
61626  class BlobUpload {
61627    constructor(blob) {
61628      this.blob = blob;
61629      this.file = blob.file;
61630      const {url: url, headers: headers} = blob.directUploadData;
61631      this.xhr = new XMLHttpRequest;
61632      this.xhr.open("PUT", url, true);
61633      this.xhr.responseType = "text";
61634      for (const key in headers) {
61635        this.xhr.setRequestHeader(key, headers[key]);
61636      }
61637      this.xhr.addEventListener("load", (event => this.requestDidLoad(event)));
61638      this.xhr.addEventListener("error", (event => this.requestDidError(event)));
61639    }
61640    create(callback) {
61641      this.callback = callback;
61642      this.xhr.send(this.file.slice());
61643    }
61644    requestDidLoad(event) {
61645      const {status: status, response: response} = this.xhr;
61646      if (status >= 200 && status < 300) {
61647        this.callback(null, response);
61648      } else {
61649        this.requestDidError(event);
61650      }
61651    }
61652    requestDidError(event) {
61653      this.callback(`Error storing "${this.file.name}". Status: ${this.xhr.status}`);
61654    }
61655  }
61656  let id = 0;
61657  class DirectUpload {
61658    constructor(file, url, delegate) {
61659      this.id = ++id;
61660      this.file = file;
61661      this.url = url;
61662      this.delegate = delegate;
61663    }
61664    create(callback) {
61665      FileChecksum.create(this.file, ((error, checksum) => {
61666        if (error) {
61667          callback(error);
61668          return;
61669        }
61670        const blob = new BlobRecord(this.file, checksum, this.url);
61671        notify(this.delegate, "directUploadWillCreateBlobWithXHR", blob.xhr);
61672        blob.create((error => {
61673          if (error) {
61674            callback(error);
61675          } else {
61676            const upload = new BlobUpload(blob);
61677            notify(this.delegate, "directUploadWillStoreFileWithXHR", upload.xhr);
61678            upload.create((error => {
61679              if (error) {
61680                callback(error);
61681              } else {
61682                callback(null, blob.toJSON());
61683              }
61684            }));
61685          }
61686        }));
61687      }));
61688    }
61689  }
61690  function notify(object, methodName, ...messages) {
61691    if (object && typeof object[methodName] == "function") {
61692      return object[methodName](...messages);
61693    }
61694  }
61695  class DirectUploadController {
61696    constructor(input, file) {
61697      this.input = input;
61698      this.file = file;
61699      this.directUpload = new DirectUpload(this.file, this.url, this);
61700      this.dispatch("initialize");
61701    }
61702    start(callback) {
61703      const hiddenInput = document.createElement("input");
61704      hiddenInput.type = "hidden";
61705      hiddenInput.name = this.input.name;
61706      this.input.insertAdjacentElement("beforebegin", hiddenInput);
61707      this.dispatch("start");
61708      this.directUpload.create(((error, attributes) => {
61709        if (error) {
61710          hiddenInput.parentNode.removeChild(hiddenInput);
61711          this.dispatchError(error);
61712        } else {
61713          hiddenInput.value = attributes.signed_id;
61714        }
61715        this.dispatch("end");
61716        callback(error);
61717      }));
61718    }
61719    uploadRequestDidProgress(event) {
61720      const progress = event.loaded / event.total * 100;
61721      if (progress) {
61722        this.dispatch("progress", {
61723          progress: progress
61724        });
61725      }
61726    }
61727    get url() {
61728      return this.input.getAttribute("data-direct-upload-url");
61729    }
61730    dispatch(name, detail = {}) {
61731      detail.file = this.file;
61732      detail.id = this.directUpload.id;
61733      return dispatchEvent(this.input, `direct-upload:${name}`, {
61734        detail: detail
61735      });
61736    }
61737    dispatchError(error) {
61738      const event = this.dispatch("error", {
61739        error: error
61740      });
61741      if (!event.defaultPrevented) {
61742        alert(error);
61743      }
61744    }
61745    directUploadWillCreateBlobWithXHR(xhr) {
61746      this.dispatch("before-blob-request", {
61747        xhr: xhr
61748      });
61749    }
61750    directUploadWillStoreFileWithXHR(xhr) {
61751      this.dispatch("before-storage-request", {
61752        xhr: xhr
61753      });
61754      xhr.upload.addEventListener("progress", (event => this.uploadRequestDidProgress(event)));
61755    }
61756  }
61757  const inputSelector = "input[type=file][data-direct-upload-url]:not([disabled])";
61758  class DirectUploadsController {
61759    constructor(form) {
61760      this.form = form;
61761      this.inputs = findElements(form, inputSelector).filter((input => input.files.length));
61762    }
61763    start(callback) {
61764      const controllers = this.createDirectUploadControllers();
61765      const startNextController = () => {
61766        const controller = controllers.shift();
61767        if (controller) {
61768          controller.start((error => {
61769            if (error) {
61770              callback(error);
61771              this.dispatch("end");
61772            } else {
61773              startNextController();
61774            }
61775          }));
61776        } else {
61777          callback();
61778          this.dispatch("end");
61779        }
61780      };
61781      this.dispatch("start");
61782      startNextController();
61783    }
61784    createDirectUploadControllers() {
61785      const controllers = [];
61786      this.inputs.forEach((input => {
61787        toArray(input.files).forEach((file => {
61788          const controller = new DirectUploadController(input, file);
61789          controllers.push(controller);
61790        }));
61791      }));
61792      return controllers;
61793    }
61794    dispatch(name, detail = {}) {
61795      return dispatchEvent(this.form, `direct-uploads:${name}`, {
61796        detail: detail
61797      });
61798    }
61799  }
61800  const processingAttribute = "data-direct-uploads-processing";
61801  const submitButtonsByForm = new WeakMap;
61802  let started = false;
61803  function start() {
61804    if (!started) {
61805      started = true;
61806      document.addEventListener("click", didClick, true);
61807      document.addEventListener("submit", didSubmitForm, true);
61808      document.addEventListener("ajax:before", didSubmitRemoteElement);
61809    }
61810  }
61811  function didClick(event) {
61812    const {target: target} = event;
61813    if ((target.tagName == "INPUT" || target.tagName == "BUTTON") && target.type == "submit" && target.form) {
61814      submitButtonsByForm.set(target.form, target);
61815    }
61816  }
61817  function didSubmitForm(event) {
61818    handleFormSubmissionEvent(event);
61819  }
61820  function didSubmitRemoteElement(event) {
61821    if (event.target.tagName == "FORM") {
61822      handleFormSubmissionEvent(event);
61823    }
61824  }
61825  function handleFormSubmissionEvent(event) {
61826    const form = event.target;
61827    if (form.hasAttribute(processingAttribute)) {
61828      event.preventDefault();
61829      return;
61830    }
61831    const controller = new DirectUploadsController(form);
61832    const {inputs: inputs} = controller;
61833    if (inputs.length) {
61834      event.preventDefault();
61835      form.setAttribute(processingAttribute, "");
61836      inputs.forEach(disable);
61837      controller.start((error => {
61838        form.removeAttribute(processingAttribute);
61839        if (error) {
61840          inputs.forEach(enable);
61841        } else {
61842          submitForm(form);
61843        }
61844      }));
61845    }
61846  }
61847  function submitForm(form) {
61848    let button = submitButtonsByForm.get(form) || findElement(form, "input[type=submit], button[type=submit]");
61849    if (button) {
61850      const {disabled: disabled} = button;
61851      button.disabled = false;
61852      button.focus();
61853      button.click();
61854      button.disabled = disabled;
61855    } else {
61856      button = document.createElement("input");
61857      button.type = "submit";
61858      button.style.display = "none";
61859      form.appendChild(button);
61860      button.click();
61861      form.removeChild(button);
61862    }
61863    submitButtonsByForm.delete(form);
61864  }
61865  function disable(input) {
61866    input.disabled = true;
61867  }
61868  function enable(input) {
61869    input.disabled = false;
61870  }
61871  function autostart() {
61872    if (window.ActiveStorage) {
61873      start();
61874    }
61875  }
61876  setTimeout(autostart, 1);
61877  exports.DirectUpload = DirectUpload;
61878  exports.start = start;
61879  Object.defineProperty(exports, "__esModule", {
61880    value: true
61881  });
61882}));
vendor: 269,308 bytes, lines 61883-61897
61883/**
61884 * simplemde v1.11.2
61885 * Copyright Next Step Webs, Inc.
61886 * @link https://github.com/NextStepWebs/simplemde-markdown-editor
61887 * @license MIT
61888 */
61889!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.SimpleMDE=e()}}(function(){var e;return function t(e,n,r){function i(a,l){if(!n[a]){if(!e[a]){var s="function"==typeof require&&require;if(!l&&s)return s(a,!0);if(o)return o(a,!0);var c=new Error("Cannot find module '"+a+"'");throw c.code="MODULE_NOT_FOUND",c}var u=n[a]={exports:{}};e[a][0].call(u.exports,function(t){var n=e[a][1][t];return i(n?n:t)},u,u.exports,t,e,n,r)}return n[a].exports}for(var o="function"==typeof require&&require,a=0;a<r.length;a++)i(r[a]);return i}({1:[function(e,t,n){"use strict";function r(){for(var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",t=0,n=e.length;n>t;++t)s[t]=e[t],c[e.charCodeAt(t)]=t;c["-".charCodeAt(0)]=62,c["_".charCodeAt(0)]=63}function i(e){var t,n,r,i,o,a,l=e.length;if(l%4>0)throw new Error("Invalid string. Length must be a multiple of 4");o="="===e[l-2]?2:"="===e[l-1]?1:0,a=new u(3*l/4-o),r=o>0?l-4:l;var s=0;for(t=0,n=0;r>t;t+=4,n+=3)i=c[e.charCodeAt(t)]<<18|c[e.charCodeAt(t+1)]<<12|c[e.charCodeAt(t+2)]<<6|c[e.charCodeAt(t+3)],a[s++]=i>>16&255,a[s++]=i>>8&255,a[s++]=255&i;return 2===o?(i=c[e.charCodeAt(t)]<<2|c[e.charCodeAt(t+1)]>>4,a[s++]=255&i):1===o&&(i=c[e.charCodeAt(t)]<<10|c[e.charCodeAt(t+1)]<<4|c[e.charCodeAt(t+2)]>>2,a[s++]=i>>8&255,a[s++]=255&i),a}function o(e){return s[e>>18&63]+s[e>>12&63]+s[e>>6&63]+s[63&e]}function a(e,t,n){for(var r,i=[],a=t;n>a;a+=3)r=(e[a]<<16)+(e[a+1]<<8)+e[a+2],i.push(o(r));return i.join("")}function l(e){for(var t,n=e.length,r=n%3,i="",o=[],l=16383,c=0,u=n-r;u>c;c+=l)o.push(a(e,c,c+l>u?u:c+l));return 1===r?(t=e[n-1],i+=s[t>>2],i+=s[t<<4&63],i+="=="):2===r&&(t=(e[n-2]<<8)+e[n-1],i+=s[t>>10],i+=s[t>>4&63],i+=s[t<<2&63],i+="="),o.push(i),o.join("")}n.toByteArray=i,n.fromByteArray=l;var s=[],c=[],u="undefined"!=typeof Uint8Array?Uint8Array:Array;r()},{}],2:[function(e,t,n){},{}],3:[function(e,t,n){(function(t){"use strict";function r(){try{var e=new Uint8Array(1);return e.foo=function(){return 42},42===e.foo()&&"function"==typeof e.subarray&&0===e.subarray(1,1).byteLength}catch(t){return!1}}function i(){return a.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function o(e,t){if(i()<t)throw new RangeError("Invalid typed array length");return a.TYPED_ARRAY_SUPPORT?(e=new Uint8Array(t),e.__proto__=a.prototype):(null===e&&(e=new a(t)),e.length=t),e}function a(e,t,n){if(!(a.TYPED_ARRAY_SUPPORT||this instanceof a))return new a(e,t,n);if("number"==typeof e){if("string"==typeof t)throw new Error("If encoding is specified then the first argument must be a string");return u(this,e)}return l(this,e,t,n)}function l(e,t,n,r){if("number"==typeof t)throw new TypeError('"value" argument must not be a number');return"undefined"!=typeof ArrayBuffer&&t instanceof ArrayBuffer?d(e,t,n,r):"string"==typeof t?f(e,t,n):p(e,t)}function s(e){if("number"!=typeof e)throw new TypeError('"size" argument must be a number')}function c(e,t,n,r){return s(t),0>=t?o(e,t):void 0!==n?"string"==typeof r?o(e,t).fill(n,r):o(e,t).fill(n):o(e,t)}function u(e,t){if(s(t),e=o(e,0>t?0:0|m(t)),!a.TYPED_ARRAY_SUPPORT)for(var n=0;t>n;n++)e[n]=0;return e}function f(e,t,n){if("string"==typeof n&&""!==n||(n="utf8"),!a.isEncoding(n))throw new TypeError('"encoding" must be a valid string encoding');var r=0|v(t,n);return e=o(e,r),e.write(t,n),e}function h(e,t){var n=0|m(t.length);e=o(e,n);for(var r=0;n>r;r+=1)e[r]=255&t[r];return e}function d(e,t,n,r){if(t.byteLength,0>n||t.byteLength<n)throw new RangeError("'offset' is out of bounds");if(t.byteLength<n+(r||0))throw new RangeError("'length' is out of bounds");return t=void 0===r?new Uint8Array(t,n):new Uint8Array(t,n,r),a.TYPED_ARRAY_SUPPORT?(e=t,e.__proto__=a.prototype):e=h(e,t),e}function p(e,t){if(a.isBuffer(t)){var n=0|m(t.length);return e=o(e,n),0===e.length?e:(t.copy(e,0,0,n),e)}if(t){if("undefined"!=typeof ArrayBuffer&&t.buffer instanceof ArrayBuffer||"length"in t)return"number"!=typeof t.length||K(t.length)?o(e,0):h(e,t);if("Buffer"===t.type&&J(t.data))return h(e,t.data)}throw new TypeError("First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.")}function m(e){if(e>=i())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+i().toString(16)+" bytes");return 0|e}function g(e){return+e!=e&&(e=0),a.alloc(+e)}function v(e,t){if(a.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"binary":case"raw":case"raws":return n;case"utf8":case"utf-8":case void 0:return q(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return $(e).length;default:if(r)return q(e).length;t=(""+t).toLowerCase(),r=!0}}function y(e,t,n){var r=!1;if((void 0===t||0>t)&&(t=0),t>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),0>=n)return"";if(n>>>=0,t>>>=0,t>=n)return"";for(e||(e="utf8");;)switch(e){case"hex":return I(this,t,n);case"utf8":case"utf-8":return N(this,t,n);case"ascii":return E(this,t,n);case"binary":return O(this,t,n);case"base64":return M(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return P(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}function x(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function b(e,t,n,r){function i(e,t){return 1===o?e[t]:e.readUInt16BE(t*o)}var o=1,a=e.length,l=t.length;if(void 0!==r&&(r=String(r).toLowerCase(),"ucs2"===r||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;o=2,a/=2,l/=2,n/=2}for(var s=-1,c=0;a>n+c;c++)if(i(e,n+c)===i(t,-1===s?0:c-s)){if(-1===s&&(s=c),c-s+1===l)return(n+s)*o}else-1!==s&&(c-=c-s),s=-1;return-1}function w(e,t,n,r){n=Number(n)||0;var i=e.length-n;r?(r=Number(r),r>i&&(r=i)):r=i;var o=t.length;if(o%2!==0)throw new Error("Invalid hex string");r>o/2&&(r=o/2);for(var a=0;r>a;a++){var l=parseInt(t.substr(2*a,2),16);if(isNaN(l))return a;e[n+a]=l}return a}function k(e,t,n,r){return V(q(t,e.length-n),e,n,r)}function S(e,t,n,r){return V(G(t),e,n,r)}function C(e,t,n,r){return S(e,t,n,r)}function L(e,t,n,r){return V($(t),e,n,r)}function T(e,t,n,r){return V(Y(t,e.length-n),e,n,r)}function M(e,t,n){return 0===t&&n===e.length?X.fromByteArray(e):X.fromByteArray(e.slice(t,n))}function N(e,t,n){n=Math.min(e.length,n);for(var r=[],i=t;n>i;){var o=e[i],a=null,l=o>239?4:o>223?3:o>191?2:1;if(n>=i+l){var s,c,u,f;switch(l){case 1:128>o&&(a=o);break;case 2:s=e[i+1],128===(192&s)&&(f=(31&o)<<6|63&s,f>127&&(a=f));break;case 3:s=e[i+1],c=e[i+2],128===(192&s)&&128===(192&c)&&(f=(15&o)<<12|(63&s)<<6|63&c,f>2047&&(55296>f||f>57343)&&(a=f));break;case 4:s=e[i+1],c=e[i+2],u=e[i+3],128===(192&s)&&128===(192&c)&&128===(192&u)&&(f=(15&o)<<18|(63&s)<<12|(63&c)<<6|63&u,f>65535&&1114112>f&&(a=f))}}null===a?(a=65533,l=1):a>65535&&(a-=65536,r.push(a>>>10&1023|55296),a=56320|1023&a),r.push(a),i+=l}return A(r)}function A(e){var t=e.length;if(Q>=t)return String.fromCharCode.apply(String,e);for(var n="",r=0;t>r;)n+=String.fromCharCode.apply(String,e.slice(r,r+=Q));return n}function E(e,t,n){var r="";n=Math.min(e.length,n);for(var i=t;n>i;i++)r+=String.fromCharCode(127&e[i]);return r}function O(e,t,n){var r="";n=Math.min(e.length,n);for(var i=t;n>i;i++)r+=String.fromCharCode(e[i]);return r}function I(e,t,n){var r=e.length;(!t||0>t)&&(t=0),(!n||0>n||n>r)&&(n=r);for(var i="",o=t;n>o;o++)i+=U(e[o]);return i}function P(e,t,n){for(var r=e.slice(t,n),i="",o=0;o<r.length;o+=2)i+=String.fromCharCode(r[o]+256*r[o+1]);return i}function R(e,t,n){if(e%1!==0||0>e)throw new RangeError("offset is not uint");if(e+t>n)throw new RangeError("Trying to access beyond buffer length")}function D(e,t,n,r,i,o){if(!a.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>i||o>t)throw new RangeError('"value" argument is out of bounds');if(n+r>e.length)throw new RangeError("Index out of range")}function H(e,t,n,r){0>t&&(t=65535+t+1);for(var i=0,o=Math.min(e.length-n,2);o>i;i++)e[n+i]=(t&255<<8*(r?i:1-i))>>>8*(r?i:1-i)}function W(e,t,n,r){0>t&&(t=4294967295+t+1);for(var i=0,o=Math.min(e.length-n,4);o>i;i++)e[n+i]=t>>>8*(r?i:3-i)&255}function B(e,t,n,r,i,o){if(n+r>e.length)throw new RangeError("Index out of range");if(0>n)throw new RangeError("Index out of range")}function _(e,t,n,r,i){return i||B(e,t,n,4,3.4028234663852886e38,-3.4028234663852886e38),Z.write(e,t,n,r,23,4),n+4}function F(e,t,n,r,i){return i||B(e,t,n,8,1.7976931348623157e308,-1.7976931348623157e308),Z.write(e,t,n,r,52,8),n+8}function z(e){if(e=j(e).replace(ee,""),e.length<2)return"";for(;e.length%4!==0;)e+="=";return e}function j(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}function U(e){return 16>e?"0"+e.toString(16):e.toString(16)}function q(e,t){t=t||1/0;for(var n,r=e.length,i=null,o=[],a=0;r>a;a++){if(n=e.charCodeAt(a),n>55295&&57344>n){if(!i){if(n>56319){(t-=3)>-1&&o.push(239,191,189);continue}if(a+1===r){(t-=3)>-1&&o.push(239,191,189);continue}i=n;continue}if(56320>n){(t-=3)>-1&&o.push(239,191,189),i=n;continue}n=(i-55296<<10|n-56320)+65536}else i&&(t-=3)>-1&&o.push(239,191,189);if(i=null,128>n){if((t-=1)<0)break;o.push(n)}else if(2048>n){if((t-=2)<0)break;o.push(n>>6|192,63&n|128)}else if(65536>n){if((t-=3)<0)break;o.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(1114112>n))throw new Error("Invalid code point");if((t-=4)<0)break;o.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return o}function G(e){for(var t=[],n=0;n<e.length;n++)t.push(255&e.charCodeAt(n));return t}function Y(e,t){for(var n,r,i,o=[],a=0;a<e.length&&!((t-=2)<0);a++)n=e.charCodeAt(a),r=n>>8,i=n%256,o.push(i),o.push(r);return o}function $(e){return X.toByteArray(z(e))}function V(e,t,n,r){for(var i=0;r>i&&!(i+n>=t.length||i>=e.length);i++)t[i+n]=e[i];return i}function K(e){return e!==e}var X=e("base64-js"),Z=e("ieee754"),J=e("isarray");n.Buffer=a,n.SlowBuffer=g,n.INSPECT_MAX_BYTES=50,a.TYPED_ARRAY_SUPPORT=void 0!==t.TYPED_ARRAY_SUPPORT?t.TYPED_ARRAY_SUPPORT:r(),n.kMaxLength=i(),a.poolSize=8192,a._augment=function(e){return e.__proto__=a.prototype,e},a.from=function(e,t,n){return l(null,e,t,n)},a.TYPED_ARRAY_SUPPORT&&(a.prototype.__proto__=Uint8Array.prototype,a.__proto__=Uint8Array,"undefined"!=typeof Symbol&&Symbol.species&&a[Symbol.species]===a&&Object.defineProperty(a,Symbol.species,{value:null,configurable:!0})),a.alloc=function(e,t,n){return c(null,e,t,n)},a.allocUnsafe=function(e){return u(null,e)},a.allocUnsafeSlow=function(e){return u(null,e)},a.isBuffer=function(e){return!(null==e||!e._isBuffer)},a.compare=function(e,t){if(!a.isBuffer(e)||!a.isBuffer(t))throw new TypeError("Arguments must be Buffers");if(e===t)return 0;for(var n=e.length,r=t.length,i=0,o=Math.min(n,r);o>i;++i)if(e[i]!==t[i]){n=e[i],r=t[i];break}return r>n?-1:n>r?1:0},a.isEncoding=function(e){switch(String(e).toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"raw":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return!0;default:return!1}},a.concat=function(e,t){if(!J(e))throw new TypeError('"list" argument must be an Array of Buffers');if(0===e.length)return a.alloc(0);var n;if(void 0===t)for(t=0,n=0;n<e.length;n++)t+=e[n].length;var r=a.allocUnsafe(t),i=0;for(n=0;n<e.length;n++){var o=e[n];if(!a.isBuffer(o))throw new TypeError('"list" argument must be an Array of Buffers');o.copy(r,i),i+=o.length}return r},a.byteLength=v,a.prototype._isBuffer=!0,a.prototype.swap16=function(){var e=this.length;if(e%2!==0)throw new RangeError("Buffer size must be a multiple of 16-bits");for(var t=0;e>t;t+=2)x(this,t,t+1);return this},a.prototype.swap32=function(){var e=this.length;if(e%4!==0)throw new RangeError("Buffer size must be a multiple of 32-bits");for(var t=0;e>t;t+=4)x(this,t,t+3),x(this,t+1,t+2);return this},a.prototype.toString=function(){var e=0|this.length;return 0===e?"":0===arguments.length?N(this,0,e):y.apply(this,arguments)},a.prototype.equals=function(e){if(!a.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e?!0:0===a.compare(this,e)},a.prototype.inspect=function(){var e="",t=n.INSPECT_MAX_BYTES;return this.length>0&&(e=this.toString("hex",0,t).match(/.{2}/g).join(" "),this.length>t&&(e+=" ... ")),"<Buffer "+e+">"},a.prototype.compare=function(e,t,n,r,i){if(!a.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===i&&(i=this.length),0>t||n>e.length||0>r||i>this.length)throw new RangeError("out of range index");if(r>=i&&t>=n)return 0;if(r>=i)return-1;if(t>=n)return 1;if(t>>>=0,n>>>=0,r>>>=0,i>>>=0,this===e)return 0;for(var o=i-r,l=n-t,s=Math.min(o,l),c=this.slice(r,i),u=e.slice(t,n),f=0;s>f;++f)if(c[f]!==u[f]){o=c[f],l=u[f];break}return l>o?-1:o>l?1:0},a.prototype.indexOf=function(e,t,n){if("string"==typeof t?(n=t,t=0):t>2147483647?t=2147483647:-2147483648>t&&(t=-2147483648),t>>=0,0===this.length)return-1;if(t>=this.length)return-1;if(0>t&&(t=Math.max(this.length+t,0)),"string"==typeof e&&(e=a.from(e,n)),a.isBuffer(e))return 0===e.length?-1:b(this,e,t,n);if("number"==typeof e)return a.TYPED_ARRAY_SUPPORT&&"function"===Uint8Array.prototype.indexOf?Uint8Array.prototype.indexOf.call(this,e,t):b(this,[e],t,n);throw new TypeError("val must be string, number or Buffer")},a.prototype.includes=function(e,t,n){return-1!==this.indexOf(e,t,n)},a.prototype.write=function(e,t,n,r){if(void 0===t)r="utf8",n=this.length,t=0;else if(void 0===n&&"string"==typeof t)r=t,n=this.length,t=0;else{if(!isFinite(t))throw new Error("Buffer.write(string, encoding, offset[, length]) is no longer supported");t=0|t,isFinite(n)?(n=0|n,void 0===r&&(r="utf8")):(r=n,n=void 0)}var i=this.length-t;if((void 0===n||n>i)&&(n=i),e.length>0&&(0>n||0>t)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var o=!1;;)switch(r){case"hex":return w(this,e,t,n);case"utf8":case"utf-8":return k(this,e,t,n);case"ascii":return S(this,e,t,n);case"binary":return C(this,e,t,n);case"base64":return L(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return T(this,e,t,n);default:if(o)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),o=!0}},a.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var Q=4096;a.prototype.slice=function(e,t){var n=this.length;e=~~e,t=void 0===t?n:~~t,0>e?(e+=n,0>e&&(e=0)):e>n&&(e=n),0>t?(t+=n,0>t&&(t=0)):t>n&&(t=n),e>t&&(t=e);var r;if(a.TYPED_ARRAY_SUPPORT)r=this.subarray(e,t),r.__proto__=a.prototype;else{var i=t-e;r=new a(i,void 0);for(var o=0;i>o;o++)r[o]=this[o+e]}return r},a.prototype.readUIntLE=function(e,t,n){e=0|e,t=0|t,n||R(e,t,this.length);for(var r=this[e],i=1,o=0;++o<t&&(i*=256);)r+=this[e+o]*i;return r},a.prototype.readUIntBE=function(e,t,n){e=0|e,t=0|t,n||R(e,t,this.length);for(var r=this[e+--t],i=1;t>0&&(i*=256);)r+=this[e+--t]*i;return r},a.prototype.readUInt8=function(e,t){return t||R(e,1,this.length),this[e]},a.prototype.readUInt16LE=function(e,t){return t||R(e,2,this.length),this[e]|this[e+1]<<8},a.prototype.readUInt16BE=function(e,t){return t||R(e,2,this.length),this[e]<<8|this[e+1]},a.prototype.readUInt32LE=function(e,t){return t||R(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},a.prototype.readUInt32BE=function(e,t){return t||R(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},a.prototype.readIntLE=function(e,t,n){e=0|e,t=0|t,n||R(e,t,this.length);for(var r=this[e],i=1,o=0;++o<t&&(i*=256);)r+=this[e+o]*i;return i*=128,r>=i&&(r-=Math.pow(2,8*t)),r},a.prototype.readIntBE=function(e,t,n){e=0|e,t=0|t,n||R(e,t,this.length);for(var r=t,i=1,o=this[e+--r];r>0&&(i*=256);)o+=this[e+--r]*i;return i*=128,o>=i&&(o-=Math.pow(2,8*t)),o},a.prototype.readInt8=function(e,t){return t||R(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},a.prototype.readInt16LE=function(e,t){t||R(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},a.prototype.readInt16BE=function(e,t){t||R(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},a.prototype.readInt32LE=function(e,t){return t||R(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},a.prototype.readInt32BE=function(e,t){return t||R(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},a.prototype.readFloatLE=function(e,t){return t||R(e,4,this.length),Z.read(this,e,!0,23,4)},a.prototype.readFloatBE=function(e,t){return t||R(e,4,this.length),Z.read(this,e,!1,23,4)},a.prototype.readDoubleLE=function(e,t){return t||R(e,8,this.length),Z.read(this,e,!0,52,8)},a.prototype.readDoubleBE=function(e,t){return t||R(e,8,this.length),Z.read(this,e,!1,52,8)},a.prototype.writeUIntLE=function(e,t,n,r){if(e=+e,t=0|t,n=0|n,!r){var i=Math.pow(2,8*n)-1;D(this,e,t,n,i,0)}var o=1,a=0;for(this[t]=255&e;++a<n&&(o*=256);)this[t+a]=e/o&255;return t+n},a.prototype.writeUIntBE=function(e,t,n,r){if(e=+e,t=0|t,n=0|n,!r){var i=Math.pow(2,8*n)-1;D(this,e,t,n,i,0)}var o=n-1,a=1;for(this[t+o]=255&e;--o>=0&&(a*=256);)this[t+o]=e/a&255;return t+n},a.prototype.writeUInt8=function(e,t,n){return e=+e,t=0|t,n||D(this,e,t,1,255,0),a.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},a.prototype.writeUInt16LE=function(e,t,n){return e=+e,t=0|t,n||D(this,e,t,2,65535,0),a.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):H(this,e,t,!0),t+2},a.prototype.writeUInt16BE=function(e,t,n){return e=+e,t=0|t,n||D(this,e,t,2,65535,0),a.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):H(this,e,t,!1),t+2},a.prototype.writeUInt32LE=function(e,t,n){return e=+e,t=0|t,n||D(this,e,t,4,4294967295,0),a.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):W(this,e,t,!0),t+4},a.prototype.writeUInt32BE=function(e,t,n){return e=+e,t=0|t,n||D(this,e,t,4,4294967295,0),a.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):W(this,e,t,!1),t+4},a.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t=0|t,!r){var i=Math.pow(2,8*n-1);D(this,e,t,n,i-1,-i)}var o=0,a=1,l=0;for(this[t]=255&e;++o<n&&(a*=256);)0>e&&0===l&&0!==this[t+o-1]&&(l=1),this[t+o]=(e/a>>0)-l&255;return t+n},a.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t=0|t,!r){var i=Math.pow(2,8*n-1);D(this,e,t,n,i-1,-i)}var o=n-1,a=1,l=0;for(this[t+o]=255&e;--o>=0&&(a*=256);)0>e&&0===l&&0!==this[t+o+1]&&(l=1),this[t+o]=(e/a>>0)-l&255;return t+n},a.prototype.writeInt8=function(e,t,n){return e=+e,t=0|t,n||D(this,e,t,1,127,-128),a.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),0>e&&(e=255+e+1),this[t]=255&e,t+1},a.prototype.writeInt16LE=function(e,t,n){return e=+e,t=0|t,n||D(this,e,t,2,32767,-32768),a.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):H(this,e,t,!0),t+2},a.prototype.writeInt16BE=function(e,t,n){return e=+e,t=0|t,n||D(this,e,t,2,32767,-32768),a.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):H(this,e,t,!1),t+2},a.prototype.writeInt32LE=function(e,t,n){return e=+e,t=0|t,n||D(this,e,t,4,2147483647,-2147483648),a.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):W(this,e,t,!0),t+4},a.prototype.writeInt32BE=function(e,t,n){return e=+e,t=0|t,n||D(this,e,t,4,2147483647,-2147483648),0>e&&(e=4294967295+e+1),a.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):W(this,e,t,!1),t+4},a.prototype.writeFloatLE=function(e,t,n){return _(this,e,t,!0,n)},a.prototype.writeFloatBE=function(e,t,n){return _(this,e,t,!1,n)},a.prototype.writeDoubleLE=function(e,t,n){return F(this,e,t,!0,n)},a.prototype.writeDoubleBE=function(e,t,n){return F(this,e,t,!1,n)},a.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&n>r&&(r=n),r===n)return 0;if(0===e.length||0===this.length)return 0;if(0>t)throw new RangeError("targetStart out of bounds");if(0>n||n>=this.length)throw new RangeError("sourceStart out of bounds");if(0>r)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t<r-n&&(r=e.length-t+n);var i,o=r-n;if(this===e&&t>n&&r>t)for(i=o-1;i>=0;i--)e[i+t]=this[i+n];else if(1e3>o||!a.TYPED_ARRAY_SUPPORT)for(i=0;o>i;i++)e[i+t]=this[i+n];else Uint8Array.prototype.set.call(e,this.subarray(n,n+o),t);return o},a.prototype.fill=function(e,t,n,r){if("string"==typeof e){if("string"==typeof t?(r=t,t=0,n=this.length):"string"==typeof n&&(r=n,n=this.length),1===e.length){var i=e.charCodeAt(0);256>i&&(e=i)}if(void 0!==r&&"string"!=typeof r)throw new TypeError("encoding must be a string");if("string"==typeof r&&!a.isEncoding(r))throw new TypeError("Unknown encoding: "+r)}else"number"==typeof e&&(e=255&e);if(0>t||this.length<t||this.length<n)throw new RangeError("Out of range index");if(t>=n)return this;t>>>=0,n=void 0===n?this.length:n>>>0,e||(e=0);var o;if("number"==typeof e)for(o=t;n>o;o++)this[o]=e;else{var l=a.isBuffer(e)?e:q(new a(e,r).toString()),s=l.length;for(o=0;n-t>o;o++)this[o+t]=l[o%s]}return this};var ee=/[^+\/0-9A-Za-z-_]/g}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"base64-js":1,ieee754:15,isarray:16}],4:[function(e,t,n){"use strict";function r(e){return e=e||{},"function"!=typeof e.codeMirrorInstance||"function"!=typeof e.codeMirrorInstance.defineMode?void console.log("CodeMirror Spell Checker: You must provide an instance of CodeMirror via the option `codeMirrorInstance`"):(String.prototype.includes||(String.prototype.includes=function(){return-1!==String.prototype.indexOf.apply(this,arguments)}),void e.codeMirrorInstance.defineMode("spell-checker",function(t){if(!r.aff_loading){r.aff_loading=!0;var n=new XMLHttpRequest;n.open("GET","https://cdn.jsdelivr.net/codemirror.spell-checker/latest/en_US.aff",!0),n.onload=function(){4===n.readyState&&200===n.status&&(r.aff_data=n.responseText,r.num_loaded++,2==r.num_loaded&&(r.typo=new i("en_US",r.aff_data,r.dic_data,{platform:"any"})))},n.send(null)}if(!r.dic_loading){r.dic_loading=!0;var o=new XMLHttpRequest;o.open("GET","https://cdn.jsdelivr.net/codemirror.spell-checker/latest/en_US.dic",!0),o.onload=function(){4===o.readyState&&200===o.status&&(r.dic_data=o.responseText,r.num_loaded++,2==r.num_loaded&&(r.typo=new i("en_US",r.aff_data,r.dic_data,{platform:"any"})))},o.send(null)}var a='!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~ ',l={token:function(e){var t=e.peek(),n="";if(a.includes(t))return e.next(),null;for(;null!=(t=e.peek())&&!a.includes(t);)n+=t,e.next();return r.typo&&!r.typo.check(n)?"spell-error":null}},s=e.codeMirrorInstance.getMode(t,t.backdrop||"text/plain");return e.codeMirrorInstance.overlayMode(s,l,!0)}))}var i=e("typo-js");r.num_loaded=0,r.aff_loading=!1,r.dic_loading=!1,r.aff_data="",r.dic_data="",r.typo,t.exports=r},{"typo-js":18}],5:[function(t,n,r){!function(i){"object"==typeof r&&"object"==typeof n?i(t("../../lib/codemirror")):"function"==typeof e&&e.amd?e(["../../lib/codemirror"],i):i(CodeMirror)}(function(e){"use strict";function t(e){var t=e.getWrapperElement();e.state.fullScreenRestore={scrollTop:window.pageYOffset,scrollLeft:window.pageXOffset,width:t.style.width,height:t.style.height},t.style.width="",t.style.height="auto",t.className+=" CodeMirror-fullscreen",document.documentElement.style.overflow="hidden",e.refresh()}function n(e){var t=e.getWrapperElement();t.className=t.className.replace(/\s*CodeMirror-fullscreen\b/,""),document.documentElement.style.overflow="";var n=e.state.fullScreenRestore;t.style.width=n.width,t.style.height=n.height,window.scrollTo(n.scrollLeft,n.scrollTop),e.refresh()}e.defineOption("fullScreen",!1,function(r,i,o){o==e.Init&&(o=!1),!o!=!i&&(i?t(r):n(r))})})},{"../../lib/codemirror":10}],6:[function(t,n,r){!function(i){"object"==typeof r&&"object"==typeof n?i(t("../../lib/codemirror")):"function"==typeof e&&e.amd?e(["../../lib/codemirror"],i):i(CodeMirror)}(function(e){function t(e){e.state.placeholder&&(e.state.placeholder.parentNode.removeChild(e.state.placeholder),e.state.placeholder=null)}function n(e){t(e);var n=e.state.placeholder=document.createElement("pre");n.style.cssText="height: 0; overflow: visible",n.className="CodeMirror-placeholder";var r=e.getOption("placeholder");"string"==typeof r&&(r=document.createTextNode(r)),n.appendChild(r),e.display.lineSpace.insertBefore(n,e.display.lineSpace.firstChild)}function r(e){o(e)&&n(e)}function i(e){var r=e.getWrapperElement(),i=o(e);r.className=r.className.replace(" CodeMirror-empty","")+(i?" CodeMirror-empty":""),i?n(e):t(e)}function o(e){return 1===e.lineCount()&&""===e.getLine(0)}e.defineOption("placeholder","",function(n,o,a){var l=a&&a!=e.Init;if(o&&!l)n.on("blur",r),n.on("change",i),n.on("swapDoc",i),i(n);else if(!o&&l){n.off("blur",r),n.off("change",i),n.off("swapDoc",i),t(n);var s=n.getWrapperElement();s.className=s.className.replace(" CodeMirror-empty","")}o&&!n.hasFocus()&&r(n)})})},{"../../lib/codemirror":10}],7:[function(t,n,r){!function(i){"object"==typeof r&&"object"==typeof n?i(t("../../lib/codemirror")):"function"==typeof e&&e.amd?e(["../../lib/codemirror"],i):i(CodeMirror)}(function(e){"use strict";var t=/^(\s*)(>[> ]*|[*+-]\s|(\d+)([.)]))(\s*)/,n=/^(\s*)(>[> ]*|[*+-]|(\d+)[.)])(\s*)$/,r=/[*+-]\s/;e.commands.newlineAndIndentContinueMarkdownList=function(i){if(i.getOption("disableInput"))return e.Pass;for(var o=i.listSelections(),a=[],l=0;l<o.length;l++){var s=o[l].head,c=i.getStateAfter(s.line),u=c.list!==!1,f=0!==c.quote,h=i.getLine(s.line),d=t.exec(h);if(!o[l].empty()||!u&&!f||!d)return void i.execCommand("newlineAndIndent");if(n.test(h))i.replaceRange("",{line:s.line,ch:0},{line:s.line,ch:s.ch+1}),a[l]="\n";else{var p=d[1],m=d[5],g=r.test(d[2])||d[2].indexOf(">")>=0?d[2]:parseInt(d[3],10)+1+d[4];a[l]="\n"+p+g+m}}i.replaceSelections(a)}})},{"../../lib/codemirror":10}],8:[function(t,n,r){!function(i){"object"==typeof r&&"object"==typeof n?i(t("../../lib/codemirror")):"function"==typeof e&&e.amd?e(["../../lib/codemirror"],i):i(CodeMirror)}(function(e){"use strict";e.overlayMode=function(t,n,r){return{startState:function(){return{base:e.startState(t),overlay:e.startState(n),basePos:0,baseCur:null,overlayPos:0,overlayCur:null,streamSeen:null}},copyState:function(r){return{base:e.copyState(t,r.base),overlay:e.copyState(n,r.overlay),basePos:r.basePos,baseCur:null,overlayPos:r.overlayPos,overlayCur:null}},token:function(e,i){return(e!=i.streamSeen||Math.min(i.basePos,i.overlayPos)<e.start)&&(i.streamSeen=e,i.basePos=i.overlayPos=e.start),e.start==i.basePos&&(i.baseCur=t.token(e,i.base),i.basePos=e.pos),e.start==i.overlayPos&&(e.pos=e.start,i.overlayCur=n.token(e,i.overlay),i.overlayPos=e.pos),e.pos=Math.min(i.basePos,i.overlayPos),null==i.overlayCur?i.baseCur:null!=i.baseCur&&i.overlay.combineTokens||r&&null==i.overlay.combineTokens?i.baseCur+" "+i.overlayCur:i.overlayCur},indent:t.indent&&function(e,n){return t.indent(e.base,n)},electricChars:t.electricChars,innerMode:function(e){return{state:e.base,mode:t}},blankLine:function(e){t.blankLine&&t.blankLine(e.base),n.blankLine&&n.blankLine(e.overlay)}}}})},{"../../lib/codemirror":10}],9:[function(t,n,r){!function(i){"object"==typeof r&&"object"==typeof n?i(t("../../lib/codemirror")):"function"==typeof e&&e.amd?e(["../../lib/codemirror"],i):i(CodeMirror)}(function(e){"use strict";function t(e){e.operation(function(){a(e)})}function n(e){e.state.markedSelection.length&&e.operation(function(){i(e)})}function r(e,t,n,r){if(0!=c(t,n))for(var i=e.state.markedSelection,o=e.state.markedSelectionStyle,a=t.line;;){var u=a==t.line?t:s(a,0),f=a+l,h=f>=n.line,d=h?n:s(f,0),p=e.markText(u,d,{className:o});if(null==r?i.push(p):i.splice(r++,0,p),h)break;a=f}}function i(e){for(var t=e.state.markedSelection,n=0;n<t.length;++n)t[n].clear();t.length=0}function o(e){i(e);for(var t=e.listSelections(),n=0;n<t.length;n++)r(e,t[n].from(),t[n].to())}function a(e){if(!e.somethingSelected())return i(e);if(e.listSelections().length>1)return o(e);var t=e.getCursor("start"),n=e.getCursor("end"),a=e.state.markedSelection;if(!a.length)return r(e,t,n);var s=a[0].find(),u=a[a.length-1].find();if(!s||!u||n.line-t.line<l||c(t,u.to)>=0||c(n,s.from)<=0)return o(e);for(;c(t,s.from)>0;)a.shift().clear(),s=a[0].find();for(c(t,s.from)<0&&(s.to.line-t.line<l?(a.shift().clear(),r(e,t,s.to,0)):r(e,t,s.from,0));c(n,u.to)<0;)a.pop().clear(),u=a[a.length-1].find();c(n,u.to)>0&&(n.line-u.from.line<l?(a.pop().clear(),r(e,u.from,n)):r(e,u.to,n))}e.defineOption("styleSelectedText",!1,function(r,a,l){var s=l&&l!=e.Init;a&&!s?(r.state.markedSelection=[],r.state.markedSelectionStyle="string"==typeof a?a:"CodeMirror-selectedtext",o(r),r.on("cursorActivity",t),r.on("change",n)):!a&&s&&(r.off("cursorActivity",t),r.off("change",n),i(r),r.state.markedSelection=r.state.markedSelectionStyle=null)});var l=8,s=e.Pos,c=e.cmpPos})},{"../../lib/codemirror":10}],10:[function(t,n,r){!function(t){if("object"==typeof r&&"object"==typeof n)n.exports=t();else{if("function"==typeof e&&e.amd)return e([],t);(this||window).CodeMirror=t()}}(function(){"use strict";function e(n,r){if(!(this instanceof e))return new e(n,r);this.options=r=r?Wi(r):{},Wi(ea,r,!1),d(r);var i=r.value;"string"==typeof i&&(i=new Ca(i,r.mode,null,r.lineSeparator)),this.doc=i;var o=new e.inputStyles[r.inputStyle](this),a=this.display=new t(n,i,o);a.wrapper.CodeMirror=this,c(this),l(this),r.lineWrapping&&(this.display.wrapper.className+=" CodeMirror-wrap"),r.autofocus&&!Ao&&a.input.focus(),v(this),this.state={keyMaps:[],overlays:[],modeGen:0,overwrite:!1,delayingBlurEvent:!1,focused:!1,suppressEdits:!1,pasteIncoming:!1,cutIncoming:!1,selectingText:!1,draggingText:!1,highlight:new Ei,keySeq:null,specialChars:null};var s=this;xo&&11>bo&&setTimeout(function(){s.display.input.reset(!0)},20),jt(this),Ki(),bt(this),this.curOp.forceUpdate=!0,Xr(this,i),r.autofocus&&!Ao||s.hasFocus()?setTimeout(Bi(vn,this),20):yn(this);for(var u in ta)ta.hasOwnProperty(u)&&ta[u](this,r[u],na);k(this),r.finishInit&&r.finishInit(this);for(var f=0;f<aa.length;++f)aa[f](this);kt(this),wo&&r.lineWrapping&&"optimizelegibility"==getComputedStyle(a.lineDiv).textRendering&&(a.lineDiv.style.textRendering="auto")}function t(e,t,n){var r=this;this.input=n,r.scrollbarFiller=ji("div",null,"CodeMirror-scrollbar-filler"),r.scrollbarFiller.setAttribute("cm-not-content","true"),r.gutterFiller=ji("div",null,"CodeMirror-gutter-filler"),r.gutterFiller.setAttribute("cm-not-content","true"),r.lineDiv=ji("div",null,"CodeMirror-code"),r.selectionDiv=ji("div",null,null,"position: relative; z-index: 1"),r.cursorDiv=ji("div",null,"CodeMirror-cursors"),r.measure=ji("div",null,"CodeMirror-measure"),r.lineMeasure=ji("div",null,"CodeMirror-measure"),r.lineSpace=ji("div",[r.measure,r.lineMeasure,r.selectionDiv,r.cursorDiv,r.lineDiv],null,"position: relative; outline: none"),r.mover=ji("div",[ji("div",[r.lineSpace],"CodeMirror-lines")],null,"position: relative"),r.sizer=ji("div",[r.mover],"CodeMirror-sizer"),r.sizerWidth=null,r.heightForcer=ji("div",null,null,"position: absolute; height: "+Da+"px; width: 1px;"),r.gutters=ji("div",null,"CodeMirror-gutters"),r.lineGutter=null,r.scroller=ji("div",[r.sizer,r.heightForcer,r.gutters],"CodeMirror-scroll"),r.scroller.setAttribute("tabIndex","-1"),r.wrapper=ji("div",[r.scrollbarFiller,r.gutterFiller,r.scroller],"CodeMirror"),xo&&8>bo&&(r.gutters.style.zIndex=-1,r.scroller.style.paddingRight=0),wo||go&&Ao||(r.scroller.draggable=!0),e&&(e.appendChild?e.appendChild(r.wrapper):e(r.wrapper)),r.viewFrom=r.viewTo=t.first,r.reportedViewFrom=r.reportedViewTo=t.first,r.view=[],r.renderedView=null,r.externalMeasured=null,r.viewOffset=0,r.lastWrapHeight=r.lastWrapWidth=0,r.updateLineNumbers=null,r.nativeBarWidth=r.barHeight=r.barWidth=0,r.scrollbarsClipped=!1,r.lineNumWidth=r.lineNumInnerWidth=r.lineNumChars=null,r.alignWidgets=!1,r.cachedCharWidth=r.cachedTextHeight=r.cachedPaddingH=null,
61890r.maxLine=null,r.maxLineLength=0,r.maxLineChanged=!1,r.wheelDX=r.wheelDY=r.wheelStartX=r.wheelStartY=null,r.shift=!1,r.selForContextMenu=null,r.activeTouch=null,n.init(r)}function n(t){t.doc.mode=e.getMode(t.options,t.doc.modeOption),r(t)}function r(e){e.doc.iter(function(e){e.stateAfter&&(e.stateAfter=null),e.styles&&(e.styles=null)}),e.doc.frontier=e.doc.first,_e(e,100),e.state.modeGen++,e.curOp&&Dt(e)}function i(e){e.options.lineWrapping?(Ja(e.display.wrapper,"CodeMirror-wrap"),e.display.sizer.style.minWidth="",e.display.sizerWidth=null):(Za(e.display.wrapper,"CodeMirror-wrap"),h(e)),a(e),Dt(e),lt(e),setTimeout(function(){y(e)},100)}function o(e){var t=yt(e.display),n=e.options.lineWrapping,r=n&&Math.max(5,e.display.scroller.clientWidth/xt(e.display)-3);return function(i){if(kr(e.doc,i))return 0;var o=0;if(i.widgets)for(var a=0;a<i.widgets.length;a++)i.widgets[a].height&&(o+=i.widgets[a].height);return n?o+(Math.ceil(i.text.length/r)||1)*t:o+t}}function a(e){var t=e.doc,n=o(e);t.iter(function(e){var t=n(e);t!=e.height&&ei(e,t)})}function l(e){e.display.wrapper.className=e.display.wrapper.className.replace(/\s*cm-s-\S+/g,"")+e.options.theme.replace(/(^|\s)\s*/g," cm-s-"),lt(e)}function s(e){c(e),Dt(e),setTimeout(function(){w(e)},20)}function c(e){var t=e.display.gutters,n=e.options.gutters;Ui(t);for(var r=0;r<n.length;++r){var i=n[r],o=t.appendChild(ji("div",null,"CodeMirror-gutter "+i));"CodeMirror-linenumbers"==i&&(e.display.lineGutter=o,o.style.width=(e.display.lineNumWidth||1)+"px")}t.style.display=r?"":"none",u(e)}function u(e){var t=e.display.gutters.offsetWidth;e.display.sizer.style.marginLeft=t+"px"}function f(e){if(0==e.height)return 0;for(var t,n=e.text.length,r=e;t=mr(r);){var i=t.find(0,!0);r=i.from.line,n+=i.from.ch-i.to.ch}for(r=e;t=gr(r);){var i=t.find(0,!0);n-=r.text.length-i.from.ch,r=i.to.line,n+=r.text.length-i.to.ch}return n}function h(e){var t=e.display,n=e.doc;t.maxLine=Zr(n,n.first),t.maxLineLength=f(t.maxLine),t.maxLineChanged=!0,n.iter(function(e){var n=f(e);n>t.maxLineLength&&(t.maxLineLength=n,t.maxLine=e)})}function d(e){var t=Pi(e.gutters,"CodeMirror-linenumbers");-1==t&&e.lineNumbers?e.gutters=e.gutters.concat(["CodeMirror-linenumbers"]):t>-1&&!e.lineNumbers&&(e.gutters=e.gutters.slice(0),e.gutters.splice(t,1))}function p(e){var t=e.display,n=t.gutters.offsetWidth,r=Math.round(e.doc.height+qe(e.display));return{clientHeight:t.scroller.clientHeight,viewHeight:t.wrapper.clientHeight,scrollWidth:t.scroller.scrollWidth,clientWidth:t.scroller.clientWidth,viewWidth:t.wrapper.clientWidth,barLeft:e.options.fixedGutter?n:0,docHeight:r,scrollHeight:r+Ye(e)+t.barHeight,nativeBarWidth:t.nativeBarWidth,gutterWidth:n}}function m(e,t,n){this.cm=n;var r=this.vert=ji("div",[ji("div",null,null,"min-width: 1px")],"CodeMirror-vscrollbar"),i=this.horiz=ji("div",[ji("div",null,null,"height: 100%; min-height: 1px")],"CodeMirror-hscrollbar");e(r),e(i),Ea(r,"scroll",function(){r.clientHeight&&t(r.scrollTop,"vertical")}),Ea(i,"scroll",function(){i.clientWidth&&t(i.scrollLeft,"horizontal")}),this.checkedZeroWidth=!1,xo&&8>bo&&(this.horiz.style.minHeight=this.vert.style.minWidth="18px")}function g(){}function v(t){t.display.scrollbars&&(t.display.scrollbars.clear(),t.display.scrollbars.addClass&&Za(t.display.wrapper,t.display.scrollbars.addClass)),t.display.scrollbars=new e.scrollbarModel[t.options.scrollbarStyle](function(e){t.display.wrapper.insertBefore(e,t.display.scrollbarFiller),Ea(e,"mousedown",function(){t.state.focused&&setTimeout(function(){t.display.input.focus()},0)}),e.setAttribute("cm-not-content","true")},function(e,n){"horizontal"==n?on(t,e):rn(t,e)},t),t.display.scrollbars.addClass&&Ja(t.display.wrapper,t.display.scrollbars.addClass)}function y(e,t){t||(t=p(e));var n=e.display.barWidth,r=e.display.barHeight;x(e,t);for(var i=0;4>i&&n!=e.display.barWidth||r!=e.display.barHeight;i++)n!=e.display.barWidth&&e.options.lineWrapping&&O(e),x(e,p(e)),n=e.display.barWidth,r=e.display.barHeight}function x(e,t){var n=e.display,r=n.scrollbars.update(t);n.sizer.style.paddingRight=(n.barWidth=r.right)+"px",n.sizer.style.paddingBottom=(n.barHeight=r.bottom)+"px",n.heightForcer.style.borderBottom=r.bottom+"px solid transparent",r.right&&r.bottom?(n.scrollbarFiller.style.display="block",n.scrollbarFiller.style.height=r.bottom+"px",n.scrollbarFiller.style.width=r.right+"px"):n.scrollbarFiller.style.display="",r.bottom&&e.options.coverGutterNextToScrollbar&&e.options.fixedGutter?(n.gutterFiller.style.display="block",n.gutterFiller.style.height=r.bottom+"px",n.gutterFiller.style.width=t.gutterWidth+"px"):n.gutterFiller.style.display=""}function b(e,t,n){var r=n&&null!=n.top?Math.max(0,n.top):e.scroller.scrollTop;r=Math.floor(r-Ue(e));var i=n&&null!=n.bottom?n.bottom:r+e.wrapper.clientHeight,o=ni(t,r),a=ni(t,i);if(n&&n.ensure){var l=n.ensure.from.line,s=n.ensure.to.line;o>l?(o=l,a=ni(t,ri(Zr(t,l))+e.wrapper.clientHeight)):Math.min(s,t.lastLine())>=a&&(o=ni(t,ri(Zr(t,s))-e.wrapper.clientHeight),a=s)}return{from:o,to:Math.max(a,o+1)}}function w(e){var t=e.display,n=t.view;if(t.alignWidgets||t.gutters.firstChild&&e.options.fixedGutter){for(var r=C(t)-t.scroller.scrollLeft+e.doc.scrollLeft,i=t.gutters.offsetWidth,o=r+"px",a=0;a<n.length;a++)if(!n[a].hidden){e.options.fixedGutter&&n[a].gutter&&(n[a].gutter.style.left=o);var l=n[a].alignable;if(l)for(var s=0;s<l.length;s++)l[s].style.left=o}e.options.fixedGutter&&(t.gutters.style.left=r+i+"px")}}function k(e){if(!e.options.lineNumbers)return!1;var t=e.doc,n=S(e.options,t.first+t.size-1),r=e.display;if(n.length!=r.lineNumChars){var i=r.measure.appendChild(ji("div",[ji("div",n)],"CodeMirror-linenumber CodeMirror-gutter-elt")),o=i.firstChild.offsetWidth,a=i.offsetWidth-o;return r.lineGutter.style.width="",r.lineNumInnerWidth=Math.max(o,r.lineGutter.offsetWidth-a)+1,r.lineNumWidth=r.lineNumInnerWidth+a,r.lineNumChars=r.lineNumInnerWidth?n.length:-1,r.lineGutter.style.width=r.lineNumWidth+"px",u(e),!0}return!1}function S(e,t){return String(e.lineNumberFormatter(t+e.firstLineNumber))}function C(e){return e.scroller.getBoundingClientRect().left-e.sizer.getBoundingClientRect().left}function L(e,t,n){var r=e.display;this.viewport=t,this.visible=b(r,e.doc,t),this.editorIsHidden=!r.wrapper.offsetWidth,this.wrapperHeight=r.wrapper.clientHeight,this.wrapperWidth=r.wrapper.clientWidth,this.oldDisplayWidth=$e(e),this.force=n,this.dims=P(e),this.events=[]}function T(e){var t=e.display;!t.scrollbarsClipped&&t.scroller.offsetWidth&&(t.nativeBarWidth=t.scroller.offsetWidth-t.scroller.clientWidth,t.heightForcer.style.height=Ye(e)+"px",t.sizer.style.marginBottom=-t.nativeBarWidth+"px",t.sizer.style.borderRightWidth=Ye(e)+"px",t.scrollbarsClipped=!0)}function M(e,t){var n=e.display,r=e.doc;if(t.editorIsHidden)return Wt(e),!1;if(!t.force&&t.visible.from>=n.viewFrom&&t.visible.to<=n.viewTo&&(null==n.updateLineNumbers||n.updateLineNumbers>=n.viewTo)&&n.renderedView==n.view&&0==zt(e))return!1;k(e)&&(Wt(e),t.dims=P(e));var i=r.first+r.size,o=Math.max(t.visible.from-e.options.viewportMargin,r.first),a=Math.min(i,t.visible.to+e.options.viewportMargin);n.viewFrom<o&&o-n.viewFrom<20&&(o=Math.max(r.first,n.viewFrom)),n.viewTo>a&&n.viewTo-a<20&&(a=Math.min(i,n.viewTo)),Wo&&(o=br(e.doc,o),a=wr(e.doc,a));var l=o!=n.viewFrom||a!=n.viewTo||n.lastWrapHeight!=t.wrapperHeight||n.lastWrapWidth!=t.wrapperWidth;Ft(e,o,a),n.viewOffset=ri(Zr(e.doc,n.viewFrom)),e.display.mover.style.top=n.viewOffset+"px";var s=zt(e);if(!l&&0==s&&!t.force&&n.renderedView==n.view&&(null==n.updateLineNumbers||n.updateLineNumbers>=n.viewTo))return!1;var c=Gi();return s>4&&(n.lineDiv.style.display="none"),R(e,n.updateLineNumbers,t.dims),s>4&&(n.lineDiv.style.display=""),n.renderedView=n.view,c&&Gi()!=c&&c.offsetHeight&&c.focus(),Ui(n.cursorDiv),Ui(n.selectionDiv),n.gutters.style.height=n.sizer.style.minHeight=0,l&&(n.lastWrapHeight=t.wrapperHeight,n.lastWrapWidth=t.wrapperWidth,_e(e,400)),n.updateLineNumbers=null,!0}function N(e,t){for(var n=t.viewport,r=!0;(r&&e.options.lineWrapping&&t.oldDisplayWidth!=$e(e)||(n&&null!=n.top&&(n={top:Math.min(e.doc.height+qe(e.display)-Ve(e),n.top)}),t.visible=b(e.display,e.doc,n),!(t.visible.from>=e.display.viewFrom&&t.visible.to<=e.display.viewTo)))&&M(e,t);r=!1){O(e);var i=p(e);Re(e),y(e,i),E(e,i)}t.signal(e,"update",e),e.display.viewFrom==e.display.reportedViewFrom&&e.display.viewTo==e.display.reportedViewTo||(t.signal(e,"viewportChange",e,e.display.viewFrom,e.display.viewTo),e.display.reportedViewFrom=e.display.viewFrom,e.display.reportedViewTo=e.display.viewTo)}function A(e,t){var n=new L(e,t);if(M(e,n)){O(e),N(e,n);var r=p(e);Re(e),y(e,r),E(e,r),n.finish()}}function E(e,t){e.display.sizer.style.minHeight=t.docHeight+"px",e.display.heightForcer.style.top=t.docHeight+"px",e.display.gutters.style.height=t.docHeight+e.display.barHeight+Ye(e)+"px"}function O(e){for(var t=e.display,n=t.lineDiv.offsetTop,r=0;r<t.view.length;r++){var i,o=t.view[r];if(!o.hidden){if(xo&&8>bo){var a=o.node.offsetTop+o.node.offsetHeight;i=a-n,n=a}else{var l=o.node.getBoundingClientRect();i=l.bottom-l.top}var s=o.line.height-i;if(2>i&&(i=yt(t)),(s>.001||-.001>s)&&(ei(o.line,i),I(o.line),o.rest))for(var c=0;c<o.rest.length;c++)I(o.rest[c])}}}function I(e){if(e.widgets)for(var t=0;t<e.widgets.length;++t)e.widgets[t].height=e.widgets[t].node.parentNode.offsetHeight}function P(e){for(var t=e.display,n={},r={},i=t.gutters.clientLeft,o=t.gutters.firstChild,a=0;o;o=o.nextSibling,++a)n[e.options.gutters[a]]=o.offsetLeft+o.clientLeft+i,r[e.options.gutters[a]]=o.clientWidth;return{fixedPos:C(t),gutterTotalWidth:t.gutters.offsetWidth,gutterLeft:n,gutterWidth:r,wrapperWidth:t.wrapper.clientWidth}}function R(e,t,n){function r(t){var n=t.nextSibling;return wo&&Eo&&e.display.currentWheelTarget==t?t.style.display="none":t.parentNode.removeChild(t),n}for(var i=e.display,o=e.options.lineNumbers,a=i.lineDiv,l=a.firstChild,s=i.view,c=i.viewFrom,u=0;u<s.length;u++){var f=s[u];if(f.hidden);else if(f.node&&f.node.parentNode==a){for(;l!=f.node;)l=r(l);var h=o&&null!=t&&c>=t&&f.lineNumber;f.changes&&(Pi(f.changes,"gutter")>-1&&(h=!1),D(e,f,c,n)),h&&(Ui(f.lineNumber),f.lineNumber.appendChild(document.createTextNode(S(e.options,c)))),l=f.node.nextSibling}else{var d=U(e,f,c,n);a.insertBefore(d,l)}c+=f.size}for(;l;)l=r(l)}function D(e,t,n,r){for(var i=0;i<t.changes.length;i++){var o=t.changes[i];"text"==o?_(e,t):"gutter"==o?z(e,t,n,r):"class"==o?F(t):"widget"==o&&j(e,t,r)}t.changes=null}function H(e){return e.node==e.text&&(e.node=ji("div",null,null,"position: relative"),e.text.parentNode&&e.text.parentNode.replaceChild(e.node,e.text),e.node.appendChild(e.text),xo&&8>bo&&(e.node.style.zIndex=2)),e.node}function W(e){var t=e.bgClass?e.bgClass+" "+(e.line.bgClass||""):e.line.bgClass;if(t&&(t+=" CodeMirror-linebackground"),e.background)t?e.background.className=t:(e.background.parentNode.removeChild(e.background),e.background=null);else if(t){var n=H(e);e.background=n.insertBefore(ji("div",null,t),n.firstChild)}}function B(e,t){var n=e.display.externalMeasured;return n&&n.line==t.line?(e.display.externalMeasured=null,t.measure=n.measure,n.built):Br(e,t)}function _(e,t){var n=t.text.className,r=B(e,t);t.text==t.node&&(t.node=r.pre),t.text.parentNode.replaceChild(r.pre,t.text),t.text=r.pre,r.bgClass!=t.bgClass||r.textClass!=t.textClass?(t.bgClass=r.bgClass,t.textClass=r.textClass,F(t)):n&&(t.text.className=n)}function F(e){W(e),e.line.wrapClass?H(e).className=e.line.wrapClass:e.node!=e.text&&(e.node.className="");var t=e.textClass?e.textClass+" "+(e.line.textClass||""):e.line.textClass;e.text.className=t||""}function z(e,t,n,r){if(t.gutter&&(t.node.removeChild(t.gutter),t.gutter=null),t.gutterBackground&&(t.node.removeChild(t.gutterBackground),t.gutterBackground=null),t.line.gutterClass){var i=H(t);t.gutterBackground=ji("div",null,"CodeMirror-gutter-background "+t.line.gutterClass,"left: "+(e.options.fixedGutter?r.fixedPos:-r.gutterTotalWidth)+"px; width: "+r.gutterTotalWidth+"px"),i.insertBefore(t.gutterBackground,t.text)}var o=t.line.gutterMarkers;if(e.options.lineNumbers||o){var i=H(t),a=t.gutter=ji("div",null,"CodeMirror-gutter-wrapper","left: "+(e.options.fixedGutter?r.fixedPos:-r.gutterTotalWidth)+"px");if(e.display.input.setUneditable(a),i.insertBefore(a,t.text),t.line.gutterClass&&(a.className+=" "+t.line.gutterClass),!e.options.lineNumbers||o&&o["CodeMirror-linenumbers"]||(t.lineNumber=a.appendChild(ji("div",S(e.options,n),"CodeMirror-linenumber CodeMirror-gutter-elt","left: "+r.gutterLeft["CodeMirror-linenumbers"]+"px; width: "+e.display.lineNumInnerWidth+"px"))),o)for(var l=0;l<e.options.gutters.length;++l){var s=e.options.gutters[l],c=o.hasOwnProperty(s)&&o[s];c&&a.appendChild(ji("div",[c],"CodeMirror-gutter-elt","left: "+r.gutterLeft[s]+"px; width: "+r.gutterWidth[s]+"px"))}}}function j(e,t,n){t.alignable&&(t.alignable=null);for(var r,i=t.node.firstChild;i;i=r){var r=i.nextSibling;"CodeMirror-linewidget"==i.className&&t.node.removeChild(i)}q(e,t,n)}function U(e,t,n,r){var i=B(e,t);return t.text=t.node=i.pre,i.bgClass&&(t.bgClass=i.bgClass),i.textClass&&(t.textClass=i.textClass),F(t),z(e,t,n,r),q(e,t,r),t.node}function q(e,t,n){if(G(e,t.line,t,n,!0),t.rest)for(var r=0;r<t.rest.length;r++)G(e,t.rest[r],t,n,!1)}function G(e,t,n,r,i){if(t.widgets)for(var o=H(n),a=0,l=t.widgets;a<l.length;++a){var s=l[a],c=ji("div",[s.node],"CodeMirror-linewidget");s.handleMouseEvents||c.setAttribute("cm-ignore-events","true"),Y(s,c,n,r),e.display.input.setUneditable(c),i&&s.above?o.insertBefore(c,n.gutter||n.text):o.appendChild(c),Ci(s,"redraw")}}function Y(e,t,n,r){if(e.noHScroll){(n.alignable||(n.alignable=[])).push(t);var i=r.wrapperWidth;t.style.left=r.fixedPos+"px",e.coverGutter||(i-=r.gutterTotalWidth,t.style.paddingLeft=r.gutterTotalWidth+"px"),t.style.width=i+"px"}e.coverGutter&&(t.style.zIndex=5,t.style.position="relative",e.noHScroll||(t.style.marginLeft=-r.gutterTotalWidth+"px"))}function $(e){return Bo(e.line,e.ch)}function V(e,t){return _o(e,t)<0?t:e}function K(e,t){return _o(e,t)<0?e:t}function X(e){e.state.focused||(e.display.input.focus(),vn(e))}function Z(e,t,n,r,i){var o=e.doc;e.display.shift=!1,r||(r=o.sel);var a=e.state.pasteIncoming||"paste"==i,l=o.splitLines(t),s=null;if(a&&r.ranges.length>1)if(Fo&&Fo.text.join("\n")==t){if(r.ranges.length%Fo.text.length==0){s=[];for(var c=0;c<Fo.text.length;c++)s.push(o.splitLines(Fo.text[c]))}}else l.length==r.ranges.length&&(s=Ri(l,function(e){return[e]}));for(var c=r.ranges.length-1;c>=0;c--){var u=r.ranges[c],f=u.from(),h=u.to();u.empty()&&(n&&n>0?f=Bo(f.line,f.ch-n):e.state.overwrite&&!a?h=Bo(h.line,Math.min(Zr(o,h.line).text.length,h.ch+Ii(l).length)):Fo&&Fo.lineWise&&Fo.text.join("\n")==t&&(f=h=Bo(f.line,0)));var d=e.curOp.updateInput,p={from:f,to:h,text:s?s[c%s.length]:l,origin:i||(a?"paste":e.state.cutIncoming?"cut":"+input")};Tn(e.doc,p),Ci(e,"inputRead",e,p)}t&&!a&&Q(e,t),Bn(e),e.curOp.updateInput=d,e.curOp.typing=!0,e.state.pasteIncoming=e.state.cutIncoming=!1}function J(e,t){var n=e.clipboardData&&e.clipboardData.getData("text/plain");return n?(e.preventDefault(),t.isReadOnly()||t.options.disableInput||At(t,function(){Z(t,n,0,null,"paste")}),!0):void 0}function Q(e,t){if(e.options.electricChars&&e.options.smartIndent)for(var n=e.doc.sel,r=n.ranges.length-1;r>=0;r--){var i=n.ranges[r];if(!(i.head.ch>100||r&&n.ranges[r-1].head.line==i.head.line)){var o=e.getModeAt(i.head),a=!1;if(o.electricChars){for(var l=0;l<o.electricChars.length;l++)if(t.indexOf(o.electricChars.charAt(l))>-1){a=Fn(e,i.head.line,"smart");break}}else o.electricInput&&o.electricInput.test(Zr(e.doc,i.head.line).text.slice(0,i.head.ch))&&(a=Fn(e,i.head.line,"smart"));a&&Ci(e,"electricInput",e,i.head.line)}}}function ee(e){for(var t=[],n=[],r=0;r<e.doc.sel.ranges.length;r++){var i=e.doc.sel.ranges[r].head.line,o={anchor:Bo(i,0),head:Bo(i+1,0)};n.push(o),t.push(e.getRange(o.anchor,o.head))}return{text:t,ranges:n}}function te(e){e.setAttribute("autocorrect","off"),e.setAttribute("autocapitalize","off"),e.setAttribute("spellcheck","false")}function ne(e){this.cm=e,this.prevInput="",this.pollingFast=!1,this.polling=new Ei,this.inaccurateSelection=!1,this.hasSelection=!1,this.composing=null}function re(){var e=ji("textarea",null,null,"position: absolute; padding: 0; width: 1px; height: 1em; outline: none"),t=ji("div",[e],null,"overflow: hidden; position: relative; width: 3px; height: 0px;");return wo?e.style.width="1000px":e.setAttribute("wrap","off"),No&&(e.style.border="1px solid black"),te(e),t}function ie(e){this.cm=e,this.lastAnchorNode=this.lastAnchorOffset=this.lastFocusNode=this.lastFocusOffset=null,this.polling=new Ei,this.gracePeriod=!1}function oe(e,t){var n=Qe(e,t.line);if(!n||n.hidden)return null;var r=Zr(e.doc,t.line),i=Xe(n,r,t.line),o=ii(r),a="left";if(o){var l=co(o,t.ch);a=l%2?"right":"left"}var s=nt(i.map,t.ch,a);return s.offset="right"==s.collapse?s.end:s.start,s}function ae(e,t){return t&&(e.bad=!0),e}function le(e,t,n){var r;if(t==e.display.lineDiv){if(r=e.display.lineDiv.childNodes[n],!r)return ae(e.clipPos(Bo(e.display.viewTo-1)),!0);t=null,n=0}else for(r=t;;r=r.parentNode){if(!r||r==e.display.lineDiv)return null;if(r.parentNode&&r.parentNode==e.display.lineDiv)break}for(var i=0;i<e.display.view.length;i++){var o=e.display.view[i];if(o.node==r)return se(o,t,n)}}function se(e,t,n){function r(t,n,r){for(var i=-1;i<(u?u.length:0);i++)for(var o=0>i?c.map:u[i],a=0;a<o.length;a+=3){var l=o[a+2];if(l==t||l==n){var s=ti(0>i?e.line:e.rest[i]),f=o[a]+r;return(0>r||l!=t)&&(f=o[a+(r?1:0)]),Bo(s,f)}}}var i=e.text.firstChild,o=!1;if(!t||!Va(i,t))return ae(Bo(ti(e.line),0),!0);if(t==i&&(o=!0,t=i.childNodes[n],n=0,!t)){var a=e.rest?Ii(e.rest):e.line;return ae(Bo(ti(a),a.text.length),o)}var l=3==t.nodeType?t:null,s=t;for(l||1!=t.childNodes.length||3!=t.firstChild.nodeType||(l=t.firstChild,n&&(n=l.nodeValue.length));s.parentNode!=i;)s=s.parentNode;var c=e.measure,u=c.maps,f=r(l,s,n);if(f)return ae(f,o);for(var h=s.nextSibling,d=l?l.nodeValue.length-n:0;h;h=h.nextSibling){if(f=r(h,h.firstChild,0))return ae(Bo(f.line,f.ch-d),o);d+=h.textContent.length}for(var p=s.previousSibling,d=n;p;p=p.previousSibling){if(f=r(p,p.firstChild,-1))return ae(Bo(f.line,f.ch+d),o);d+=h.textContent.length}}function ce(e,t,n,r,i){function o(e){return function(t){return t.id==e}}function a(t){if(1==t.nodeType){var n=t.getAttribute("cm-text");if(null!=n)return""==n&&(n=t.textContent.replace(/\u200b/g,"")),void(l+=n);var u,f=t.getAttribute("cm-marker");if(f){var h=e.findMarks(Bo(r,0),Bo(i+1,0),o(+f));return void(h.length&&(u=h[0].find())&&(l+=Jr(e.doc,u.from,u.to).join(c)))}if("false"==t.getAttribute("contenteditable"))return;for(var d=0;d<t.childNodes.length;d++)a(t.childNodes[d]);/^(pre|div|p)$/i.test(t.nodeName)&&(s=!0)}else if(3==t.nodeType){var p=t.nodeValue;if(!p)return;s&&(l+=c,s=!1),l+=p}}for(var l="",s=!1,c=e.doc.lineSeparator();a(t),t!=n;)t=t.nextSibling;return l}function ue(e,t){this.ranges=e,this.primIndex=t}function fe(e,t){this.anchor=e,this.head=t}function he(e,t){var n=e[t];e.sort(function(e,t){return _o(e.from(),t.from())}),t=Pi(e,n);for(var r=1;r<e.length;r++){var i=e[r],o=e[r-1];if(_o(o.to(),i.from())>=0){var a=K(o.from(),i.from()),l=V(o.to(),i.to()),s=o.empty()?i.from()==i.head:o.from()==o.head;t>=r&&--t,e.splice(--r,2,new fe(s?l:a,s?a:l))}}return new ue(e,t)}function de(e,t){return new ue([new fe(e,t||e)],0)}function pe(e,t){return Math.max(e.first,Math.min(t,e.first+e.size-1))}function me(e,t){if(t.line<e.first)return Bo(e.first,0);var n=e.first+e.size-1;return t.line>n?Bo(n,Zr(e,n).text.length):ge(t,Zr(e,t.line).text.length)}function ge(e,t){var n=e.ch;return null==n||n>t?Bo(e.line,t):0>n?Bo(e.line,0):e}function ve(e,t){return t>=e.first&&t<e.first+e.size}function ye(e,t){for(var n=[],r=0;r<t.length;r++)n[r]=me(e,t[r]);return n}function xe(e,t,n,r){if(e.cm&&e.cm.display.shift||e.extend){var i=t.anchor;if(r){var o=_o(n,i)<0;o!=_o(r,i)<0?(i=n,n=r):o!=_o(n,r)<0&&(n=r)}return new fe(i,n)}return new fe(r||n,n)}function be(e,t,n,r){Te(e,new ue([xe(e,e.sel.primary(),t,n)],0),r)}function we(e,t,n){for(var r=[],i=0;i<e.sel.ranges.length;i++)r[i]=xe(e,e.sel.ranges[i],t[i],null);var o=he(r,e.sel.primIndex);Te(e,o,n)}function ke(e,t,n,r){var i=e.sel.ranges.slice(0);i[t]=n,Te(e,he(i,e.sel.primIndex),r)}function Se(e,t,n,r){Te(e,de(t,n),r)}function Ce(e,t,n){var r={ranges:t.ranges,update:function(t){this.ranges=[];for(var n=0;n<t.length;n++)this.ranges[n]=new fe(me(e,t[n].anchor),me(e,t[n].head))},origin:n&&n.origin};return Pa(e,"beforeSelectionChange",e,r),e.cm&&Pa(e.cm,"beforeSelectionChange",e.cm,r),r.ranges!=t.ranges?he(r.ranges,r.ranges.length-1):t}function Le(e,t,n){var r=e.history.done,i=Ii(r);i&&i.ranges?(r[r.length-1]=t,Me(e,t,n)):Te(e,t,n)}function Te(e,t,n){Me(e,t,n),fi(e,e.sel,e.cm?e.cm.curOp.id:NaN,n)}function Me(e,t,n){(Ni(e,"beforeSelectionChange")||e.cm&&Ni(e.cm,"beforeSelectionChange"))&&(t=Ce(e,t,n));var r=n&&n.bias||(_o(t.primary().head,e.sel.primary().head)<0?-1:1);Ne(e,Ee(e,t,r,!0)),n&&n.scroll===!1||!e.cm||Bn(e.cm)}function Ne(e,t){t.equals(e.sel)||(e.sel=t,e.cm&&(e.cm.curOp.updateInput=e.cm.curOp.selectionChanged=!0,Mi(e.cm)),Ci(e,"cursorActivity",e))}function Ae(e){Ne(e,Ee(e,e.sel,null,!1),Wa)}function Ee(e,t,n,r){for(var i,o=0;o<t.ranges.length;o++){var a=t.ranges[o],l=t.ranges.length==e.sel.ranges.length&&e.sel.ranges[o],s=Ie(e,a.anchor,l&&l.anchor,n,r),c=Ie(e,a.head,l&&l.head,n,r);(i||s!=a.anchor||c!=a.head)&&(i||(i=t.ranges.slice(0,o)),i[o]=new fe(s,c))}return i?he(i,t.primIndex):t}function Oe(e,t,n,r,i){var o=Zr(e,t.line);if(o.markedSpans)for(var a=0;a<o.markedSpans.length;++a){var l=o.markedSpans[a],s=l.marker;if((null==l.from||(s.inclusiveLeft?l.from<=t.ch:l.from<t.ch))&&(null==l.to||(s.inclusiveRight?l.to>=t.ch:l.to>t.ch))){if(i&&(Pa(s,"beforeCursorEnter"),s.explicitlyCleared)){if(o.markedSpans){--a;continue}break}if(!s.atomic)continue;if(n){var c,u=s.find(0>r?1:-1);if((0>r?s.inclusiveRight:s.inclusiveLeft)&&(u=Pe(e,u,-r,u&&u.line==t.line?o:null)),u&&u.line==t.line&&(c=_o(u,n))&&(0>r?0>c:c>0))return Oe(e,u,t,r,i)}var f=s.find(0>r?-1:1);return(0>r?s.inclusiveLeft:s.inclusiveRight)&&(f=Pe(e,f,r,f.line==t.line?o:null)),f?Oe(e,f,t,r,i):null}}return t}function Ie(e,t,n,r,i){var o=r||1,a=Oe(e,t,n,o,i)||!i&&Oe(e,t,n,o,!0)||Oe(e,t,n,-o,i)||!i&&Oe(e,t,n,-o,!0);return a?a:(e.cantEdit=!0,Bo(e.first,0))}function Pe(e,t,n,r){return 0>n&&0==t.ch?t.line>e.first?me(e,Bo(t.line-1)):null:n>0&&t.ch==(r||Zr(e,t.line)).text.length?t.line<e.first+e.size-1?Bo(t.line+1,0):null:new Bo(t.line,t.ch+n)}function Re(e){e.display.input.showSelection(e.display.input.prepareSelection())}function De(e,t){for(var n=e.doc,r={},i=r.cursors=document.createDocumentFragment(),o=r.selection=document.createDocumentFragment(),a=0;a<n.sel.ranges.length;a++)if(t!==!1||a!=n.sel.primIndex){var l=n.sel.ranges[a];if(!(l.from().line>=e.display.viewTo||l.to().line<e.display.viewFrom)){var s=l.empty();(s||e.options.showCursorWhenSelecting)&&He(e,l.head,i),s||We(e,l,o)}}return r}function He(e,t,n){var r=dt(e,t,"div",null,null,!e.options.singleCursorHeightPerLine),i=n.appendChild(ji("div"," ","CodeMirror-cursor"));if(i.style.left=r.left+"px",i.style.top=r.top+"px",i.style.height=Math.max(0,r.bottom-r.top)*e.options.cursorHeight+"px",r.other){var o=n.appendChild(ji("div"," ","CodeMirror-cursor CodeMirror-secondarycursor"));o.style.display="",o.style.left=r.other.left+"px",o.style.top=r.other.top+"px",o.style.height=.85*(r.other.bottom-r.other.top)+"px"}}function We(e,t,n){function r(e,t,n,r){0>t&&(t=0),t=Math.round(t),r=Math.round(r),l.appendChild(ji("div",null,"CodeMirror-selected","position: absolute; left: "+e+"px; top: "+t+"px; width: "+(null==n?u-e:n)+"px; height: "+(r-t)+"px"))}function i(t,n,i){function o(n,r){return ht(e,Bo(t,n),"div",f,r)}var l,s,f=Zr(a,t),h=f.text.length;return eo(ii(f),n||0,null==i?h:i,function(e,t,a){var f,d,p,m=o(e,"left");if(e==t)f=m,d=p=m.left;else{if(f=o(t-1,"right"),"rtl"==a){var g=m;m=f,f=g}d=m.left,p=f.right}null==n&&0==e&&(d=c),f.top-m.top>3&&(r(d,m.top,null,m.bottom),d=c,m.bottom<f.top&&r(d,m.bottom,null,f.top)),null==i&&t==h&&(p=u),(!l||m.top<l.top||m.top==l.top&&m.left<l.left)&&(l=m),(!s||f.bottom>s.bottom||f.bottom==s.bottom&&f.right>s.right)&&(s=f),c+1>d&&(d=c),r(d,f.top,p-d,f.bottom)}),{start:l,end:s}}var o=e.display,a=e.doc,l=document.createDocumentFragment(),s=Ge(e.display),c=s.left,u=Math.max(o.sizerWidth,$e(e)-o.sizer.offsetLeft)-s.right,f=t.from(),h=t.to();if(f.line==h.line)i(f.line,f.ch,h.ch);else{var d=Zr(a,f.line),p=Zr(a,h.line),m=yr(d)==yr(p),g=i(f.line,f.ch,m?d.text.length+1:null).end,v=i(h.line,m?0:null,h.ch).start;m&&(g.top<v.top-2?(r(g.right,g.top,null,g.bottom),r(c,v.top,v.left,v.bottom)):r(g.right,g.top,v.left-g.right,g.bottom)),g.bottom<v.top&&r(c,g.bottom,null,v.top)}n.appendChild(l)}function Be(e){if(e.state.focused){var t=e.display;clearInterval(t.blinker);var n=!0;t.cursorDiv.style.visibility="",e.options.cursorBlinkRate>0?t.blinker=setInterval(function(){t.cursorDiv.style.visibility=(n=!n)?"":"hidden"},e.options.cursorBlinkRate):e.options.cursorBlinkRate<0&&(t.cursorDiv.style.visibility="hidden")}}function _e(e,t){e.doc.mode.startState&&e.doc.frontier<e.display.viewTo&&e.state.highlight.set(t,Bi(Fe,e))}function Fe(e){var t=e.doc;if(t.frontier<t.first&&(t.frontier=t.first),!(t.frontier>=e.display.viewTo)){var n=+new Date+e.options.workTime,r=sa(t.mode,je(e,t.frontier)),i=[];t.iter(t.frontier,Math.min(t.first+t.size,e.display.viewTo+500),function(o){if(t.frontier>=e.display.viewFrom){var a=o.styles,l=o.text.length>e.options.maxHighlightLength,s=Rr(e,o,l?sa(t.mode,r):r,!0);o.styles=s.styles;var c=o.styleClasses,u=s.classes;u?o.styleClasses=u:c&&(o.styleClasses=null);for(var f=!a||a.length!=o.styles.length||c!=u&&(!c||!u||c.bgClass!=u.bgClass||c.textClass!=u.textClass),h=0;!f&&h<a.length;++h)f=a[h]!=o.styles[h];f&&i.push(t.frontier),o.stateAfter=l?r:sa(t.mode,r)}else o.text.length<=e.options.maxHighlightLength&&Hr(e,o.text,r),o.stateAfter=t.frontier%5==0?sa(t.mode,r):null;return++t.frontier,+new Date>n?(_e(e,e.options.workDelay),!0):void 0}),i.length&&At(e,function(){for(var t=0;t<i.length;t++)Ht(e,i[t],"text")})}}function ze(e,t,n){for(var r,i,o=e.doc,a=n?-1:t-(e.doc.mode.innerMode?1e3:100),l=t;l>a;--l){if(l<=o.first)return o.first;var s=Zr(o,l-1);if(s.stateAfter&&(!n||l<=o.frontier))return l;var c=Fa(s.text,null,e.options.tabSize);(null==i||r>c)&&(i=l-1,r=c)}return i}function je(e,t,n){var r=e.doc,i=e.display;if(!r.mode.startState)return!0;var o=ze(e,t,n),a=o>r.first&&Zr(r,o-1).stateAfter;return a=a?sa(r.mode,a):ca(r.mode),r.iter(o,t,function(n){Hr(e,n.text,a);var l=o==t-1||o%5==0||o>=i.viewFrom&&o<i.viewTo;n.stateAfter=l?sa(r.mode,a):null,++o}),n&&(r.frontier=o),a}function Ue(e){return e.lineSpace.offsetTop}function qe(e){return e.mover.offsetHeight-e.lineSpace.offsetHeight}function Ge(e){if(e.cachedPaddingH)return e.cachedPaddingH;var t=qi(e.measure,ji("pre","x")),n=window.getComputedStyle?window.getComputedStyle(t):t.currentStyle,r={left:parseInt(n.paddingLeft),right:parseInt(n.paddingRight)};return isNaN(r.left)||isNaN(r.right)||(e.cachedPaddingH=r),r}function Ye(e){return Da-e.display.nativeBarWidth}function $e(e){return e.display.scroller.clientWidth-Ye(e)-e.display.barWidth}function Ve(e){return e.display.scroller.clientHeight-Ye(e)-e.display.barHeight}function Ke(e,t,n){var r=e.options.lineWrapping,i=r&&$e(e);if(!t.measure.heights||r&&t.measure.width!=i){var o=t.measure.heights=[];if(r){t.measure.width=i;for(var a=t.text.firstChild.getClientRects(),l=0;l<a.length-1;l++){var s=a[l],c=a[l+1];Math.abs(s.bottom-c.bottom)>2&&o.push((s.bottom+c.top)/2-n.top)}}o.push(n.bottom-n.top)}}function Xe(e,t,n){if(e.line==t)return{map:e.measure.map,cache:e.measure.cache};for(var r=0;r<e.rest.length;r++)if(e.rest[r]==t)return{map:e.measure.maps[r],cache:e.measure.caches[r]};for(var r=0;r<e.rest.length;r++)if(ti(e.rest[r])>n)return{map:e.measure.maps[r],cache:e.measure.caches[r],before:!0}}function Ze(e,t){t=yr(t);var n=ti(t),r=e.display.externalMeasured=new Pt(e.doc,t,n);r.lineN=n;var i=r.built=Br(e,r);return r.text=i.pre,qi(e.display.lineMeasure,i.pre),r}function Je(e,t,n,r){return tt(e,et(e,t),n,r)}function Qe(e,t){if(t>=e.display.viewFrom&&t<e.display.viewTo)return e.display.view[Bt(e,t)];var n=e.display.externalMeasured;return n&&t>=n.lineN&&t<n.lineN+n.size?n:void 0}function et(e,t){var n=ti(t),r=Qe(e,n);r&&!r.text?r=null:r&&r.changes&&(D(e,r,n,P(e)),e.curOp.forceUpdate=!0),r||(r=Ze(e,t));var i=Xe(r,t,n);return{line:t,view:r,rect:null,map:i.map,cache:i.cache,before:i.before,hasHeights:!1}}function tt(e,t,n,r,i){t.before&&(n=-1);var o,a=n+(r||"");return t.cache.hasOwnProperty(a)?o=t.cache[a]:(t.rect||(t.rect=t.view.text.getBoundingClientRect()),t.hasHeights||(Ke(e,t.view,t.rect),t.hasHeights=!0),o=rt(e,t,n,r),o.bogus||(t.cache[a]=o)),{left:o.left,right:o.right,top:i?o.rtop:o.top,bottom:i?o.rbottom:o.bottom}}function nt(e,t,n){for(var r,i,o,a,l=0;l<e.length;l+=3){var s=e[l],c=e[l+1];if(s>t?(i=0,o=1,a="left"):c>t?(i=t-s,o=i+1):(l==e.length-3||t==c&&e[l+3]>t)&&(o=c-s,i=o-1,t>=c&&(a="right")),null!=i){if(r=e[l+2],s==c&&n==(r.insertLeft?"left":"right")&&(a=n),"left"==n&&0==i)for(;l&&e[l-2]==e[l-3]&&e[l-1].insertLeft;)r=e[(l-=3)+2],a="left";if("right"==n&&i==c-s)for(;l<e.length-3&&e[l+3]==e[l+4]&&!e[l+5].insertLeft;)r=e[(l+=3)+2],a="right";break}}return{node:r,start:i,end:o,collapse:a,coverStart:s,coverEnd:c}}function rt(e,t,n,r){var i,o=nt(t.map,n,r),a=o.node,l=o.start,s=o.end,c=o.collapse;if(3==a.nodeType){for(var u=0;4>u;u++){for(;l&&zi(t.line.text.charAt(o.coverStart+l));)--l;for(;o.coverStart+s<o.coverEnd&&zi(t.line.text.charAt(o.coverStart+s));)++s;if(xo&&9>bo&&0==l&&s==o.coverEnd-o.coverStart)i=a.parentNode.getBoundingClientRect();else if(xo&&e.options.lineWrapping){var f=qa(a,l,s).getClientRects();i=f.length?f["right"==r?f.length-1:0]:qo}else i=qa(a,l,s).getBoundingClientRect()||qo;if(i.left||i.right||0==l)break;s=l,l-=1,c="right"}xo&&11>bo&&(i=it(e.display.measure,i))}else{l>0&&(c=r="right");var f;i=e.options.lineWrapping&&(f=a.getClientRects()).length>1?f["right"==r?f.length-1:0]:a.getBoundingClientRect()}if(xo&&9>bo&&!l&&(!i||!i.left&&!i.right)){var h=a.parentNode.getClientRects()[0];i=h?{left:h.left,right:h.left+xt(e.display),top:h.top,bottom:h.bottom}:qo}for(var d=i.top-t.rect.top,p=i.bottom-t.rect.top,m=(d+p)/2,g=t.view.measure.heights,u=0;u<g.length-1&&!(m<g[u]);u++);var v=u?g[u-1]:0,y=g[u],x={left:("right"==c?i.right:i.left)-t.rect.left,right:("left"==c?i.left:i.right)-t.rect.left,top:v,bottom:y};return i.left||i.right||(x.bogus=!0),e.options.singleCursorHeightPerLine||(x.rtop=d,x.rbottom=p),x}function it(e,t){if(!window.screen||null==screen.logicalXDPI||screen.logicalXDPI==screen.deviceXDPI||!Qi(e))return t;var n=screen.logicalXDPI/screen.deviceXDPI,r=screen.logicalYDPI/screen.deviceYDPI;return{left:t.left*n,right:t.right*n,top:t.top*r,bottom:t.bottom*r}}function ot(e){if(e.measure&&(e.measure.cache={},e.measure.heights=null,e.rest))for(var t=0;t<e.rest.length;t++)e.measure.caches[t]={}}function at(e){e.display.externalMeasure=null,Ui(e.display.lineMeasure);for(var t=0;t<e.display.view.length;t++)ot(e.display.view[t])}function lt(e){at(e),e.display.cachedCharWidth=e.display.cachedTextHeight=e.display.cachedPaddingH=null,e.options.lineWrapping||(e.display.maxLineChanged=!0),e.display.lineNumChars=null}function st(){return window.pageXOffset||(document.documentElement||document.body).scrollLeft}function ct(){return window.pageYOffset||(document.documentElement||document.body).scrollTop}function ut(e,t,n,r){if(t.widgets)for(var i=0;i<t.widgets.length;++i)if(t.widgets[i].above){var o=Lr(t.widgets[i]);n.top+=o,n.bottom+=o}if("line"==r)return n;r||(r="local");var a=ri(t);if("local"==r?a+=Ue(e.display):a-=e.display.viewOffset,"page"==r||"window"==r){var l=e.display.lineSpace.getBoundingClientRect();a+=l.top+("window"==r?0:ct());var s=l.left+("window"==r?0:st());n.left+=s,n.right+=s}return n.top+=a,n.bottom+=a,n}function ft(e,t,n){if("div"==n)return t;var r=t.left,i=t.top;if("page"==n)r-=st(),
61891i-=ct();else if("local"==n||!n){var o=e.display.sizer.getBoundingClientRect();r+=o.left,i+=o.top}var a=e.display.lineSpace.getBoundingClientRect();return{left:r-a.left,top:i-a.top}}function ht(e,t,n,r,i){return r||(r=Zr(e.doc,t.line)),ut(e,r,Je(e,r,t.ch,i),n)}function dt(e,t,n,r,i,o){function a(t,a){var l=tt(e,i,t,a?"right":"left",o);return a?l.left=l.right:l.right=l.left,ut(e,r,l,n)}function l(e,t){var n=s[t],r=n.level%2;return e==to(n)&&t&&n.level<s[t-1].level?(n=s[--t],e=no(n)-(n.level%2?0:1),r=!0):e==no(n)&&t<s.length-1&&n.level<s[t+1].level&&(n=s[++t],e=to(n)-n.level%2,r=!1),r&&e==n.to&&e>n.from?a(e-1):a(e,r)}r=r||Zr(e.doc,t.line),i||(i=et(e,r));var s=ii(r),c=t.ch;if(!s)return a(c);var u=co(s,c),f=l(c,u);return null!=al&&(f.other=l(c,al)),f}function pt(e,t){var n=0,t=me(e.doc,t);e.options.lineWrapping||(n=xt(e.display)*t.ch);var r=Zr(e.doc,t.line),i=ri(r)+Ue(e.display);return{left:n,right:n,top:i,bottom:i+r.height}}function mt(e,t,n,r){var i=Bo(e,t);return i.xRel=r,n&&(i.outside=!0),i}function gt(e,t,n){var r=e.doc;if(n+=e.display.viewOffset,0>n)return mt(r.first,0,!0,-1);var i=ni(r,n),o=r.first+r.size-1;if(i>o)return mt(r.first+r.size-1,Zr(r,o).text.length,!0,1);0>t&&(t=0);for(var a=Zr(r,i);;){var l=vt(e,a,i,t,n),s=gr(a),c=s&&s.find(0,!0);if(!s||!(l.ch>c.from.ch||l.ch==c.from.ch&&l.xRel>0))return l;i=ti(a=c.to.line)}}function vt(e,t,n,r,i){function o(r){var i=dt(e,Bo(n,r),"line",t,c);return l=!0,a>i.bottom?i.left-s:a<i.top?i.left+s:(l=!1,i.left)}var a=i-ri(t),l=!1,s=2*e.display.wrapper.clientWidth,c=et(e,t),u=ii(t),f=t.text.length,h=ro(t),d=io(t),p=o(h),m=l,g=o(d),v=l;if(r>g)return mt(n,d,v,1);for(;;){if(u?d==h||d==fo(t,h,1):1>=d-h){for(var y=p>r||g-r>=r-p?h:d,x=r-(y==h?p:g);zi(t.text.charAt(y));)++y;var b=mt(n,y,y==h?m:v,-1>x?-1:x>1?1:0);return b}var w=Math.ceil(f/2),k=h+w;if(u){k=h;for(var S=0;w>S;++S)k=fo(t,k,1)}var C=o(k);C>r?(d=k,g=C,(v=l)&&(g+=1e3),f=w):(h=k,p=C,m=l,f-=w)}}function yt(e){if(null!=e.cachedTextHeight)return e.cachedTextHeight;if(null==zo){zo=ji("pre");for(var t=0;49>t;++t)zo.appendChild(document.createTextNode("x")),zo.appendChild(ji("br"));zo.appendChild(document.createTextNode("x"))}qi(e.measure,zo);var n=zo.offsetHeight/50;return n>3&&(e.cachedTextHeight=n),Ui(e.measure),n||1}function xt(e){if(null!=e.cachedCharWidth)return e.cachedCharWidth;var t=ji("span","xxxxxxxxxx"),n=ji("pre",[t]);qi(e.measure,n);var r=t.getBoundingClientRect(),i=(r.right-r.left)/10;return i>2&&(e.cachedCharWidth=i),i||10}function bt(e){e.curOp={cm:e,viewChanged:!1,startHeight:e.doc.height,forceUpdate:!1,updateInput:null,typing:!1,changeObjs:null,cursorActivityHandlers:null,cursorActivityCalled:0,selectionChanged:!1,updateMaxLine:!1,scrollLeft:null,scrollTop:null,scrollToPos:null,focus:!1,id:++Yo},Go?Go.ops.push(e.curOp):e.curOp.ownsGroup=Go={ops:[e.curOp],delayedCallbacks:[]}}function wt(e){var t=e.delayedCallbacks,n=0;do{for(;n<t.length;n++)t[n].call(null);for(var r=0;r<e.ops.length;r++){var i=e.ops[r];if(i.cursorActivityHandlers)for(;i.cursorActivityCalled<i.cursorActivityHandlers.length;)i.cursorActivityHandlers[i.cursorActivityCalled++].call(null,i.cm)}}while(n<t.length)}function kt(e){var t=e.curOp,n=t.ownsGroup;if(n)try{wt(n)}finally{Go=null;for(var r=0;r<n.ops.length;r++)n.ops[r].cm.curOp=null;St(n)}}function St(e){for(var t=e.ops,n=0;n<t.length;n++)Ct(t[n]);for(var n=0;n<t.length;n++)Lt(t[n]);for(var n=0;n<t.length;n++)Tt(t[n]);for(var n=0;n<t.length;n++)Mt(t[n]);for(var n=0;n<t.length;n++)Nt(t[n])}function Ct(e){var t=e.cm,n=t.display;T(t),e.updateMaxLine&&h(t),e.mustUpdate=e.viewChanged||e.forceUpdate||null!=e.scrollTop||e.scrollToPos&&(e.scrollToPos.from.line<n.viewFrom||e.scrollToPos.to.line>=n.viewTo)||n.maxLineChanged&&t.options.lineWrapping,e.update=e.mustUpdate&&new L(t,e.mustUpdate&&{top:e.scrollTop,ensure:e.scrollToPos},e.forceUpdate)}function Lt(e){e.updatedDisplay=e.mustUpdate&&M(e.cm,e.update)}function Tt(e){var t=e.cm,n=t.display;e.updatedDisplay&&O(t),e.barMeasure=p(t),n.maxLineChanged&&!t.options.lineWrapping&&(e.adjustWidthTo=Je(t,n.maxLine,n.maxLine.text.length).left+3,t.display.sizerWidth=e.adjustWidthTo,e.barMeasure.scrollWidth=Math.max(n.scroller.clientWidth,n.sizer.offsetLeft+e.adjustWidthTo+Ye(t)+t.display.barWidth),e.maxScrollLeft=Math.max(0,n.sizer.offsetLeft+e.adjustWidthTo-$e(t))),(e.updatedDisplay||e.selectionChanged)&&(e.preparedSelection=n.input.prepareSelection(e.focus))}function Mt(e){var t=e.cm;null!=e.adjustWidthTo&&(t.display.sizer.style.minWidth=e.adjustWidthTo+"px",e.maxScrollLeft<t.doc.scrollLeft&&on(t,Math.min(t.display.scroller.scrollLeft,e.maxScrollLeft),!0),t.display.maxLineChanged=!1);var n=e.focus&&e.focus==Gi()&&(!document.hasFocus||document.hasFocus());e.preparedSelection&&t.display.input.showSelection(e.preparedSelection,n),(e.updatedDisplay||e.startHeight!=t.doc.height)&&y(t,e.barMeasure),e.updatedDisplay&&E(t,e.barMeasure),e.selectionChanged&&Be(t),t.state.focused&&e.updateInput&&t.display.input.reset(e.typing),n&&X(e.cm)}function Nt(e){var t=e.cm,n=t.display,r=t.doc;if(e.updatedDisplay&&N(t,e.update),null==n.wheelStartX||null==e.scrollTop&&null==e.scrollLeft&&!e.scrollToPos||(n.wheelStartX=n.wheelStartY=null),null==e.scrollTop||n.scroller.scrollTop==e.scrollTop&&!e.forceScroll||(r.scrollTop=Math.max(0,Math.min(n.scroller.scrollHeight-n.scroller.clientHeight,e.scrollTop)),n.scrollbars.setScrollTop(r.scrollTop),n.scroller.scrollTop=r.scrollTop),null==e.scrollLeft||n.scroller.scrollLeft==e.scrollLeft&&!e.forceScroll||(r.scrollLeft=Math.max(0,Math.min(n.scroller.scrollWidth-n.scroller.clientWidth,e.scrollLeft)),n.scrollbars.setScrollLeft(r.scrollLeft),n.scroller.scrollLeft=r.scrollLeft,w(t)),e.scrollToPos){var i=Rn(t,me(r,e.scrollToPos.from),me(r,e.scrollToPos.to),e.scrollToPos.margin);e.scrollToPos.isCursor&&t.state.focused&&Pn(t,i)}var o=e.maybeHiddenMarkers,a=e.maybeUnhiddenMarkers;if(o)for(var l=0;l<o.length;++l)o[l].lines.length||Pa(o[l],"hide");if(a)for(var l=0;l<a.length;++l)a[l].lines.length&&Pa(a[l],"unhide");n.wrapper.offsetHeight&&(r.scrollTop=t.display.scroller.scrollTop),e.changeObjs&&Pa(t,"changes",t,e.changeObjs),e.update&&e.update.finish()}function At(e,t){if(e.curOp)return t();bt(e);try{return t()}finally{kt(e)}}function Et(e,t){return function(){if(e.curOp)return t.apply(e,arguments);bt(e);try{return t.apply(e,arguments)}finally{kt(e)}}}function Ot(e){return function(){if(this.curOp)return e.apply(this,arguments);bt(this);try{return e.apply(this,arguments)}finally{kt(this)}}}function It(e){return function(){var t=this.cm;if(!t||t.curOp)return e.apply(this,arguments);bt(t);try{return e.apply(this,arguments)}finally{kt(t)}}}function Pt(e,t,n){this.line=t,this.rest=xr(t),this.size=this.rest?ti(Ii(this.rest))-n+1:1,this.node=this.text=null,this.hidden=kr(e,t)}function Rt(e,t,n){for(var r,i=[],o=t;n>o;o=r){var a=new Pt(e.doc,Zr(e.doc,o),o);r=o+a.size,i.push(a)}return i}function Dt(e,t,n,r){null==t&&(t=e.doc.first),null==n&&(n=e.doc.first+e.doc.size),r||(r=0);var i=e.display;if(r&&n<i.viewTo&&(null==i.updateLineNumbers||i.updateLineNumbers>t)&&(i.updateLineNumbers=t),e.curOp.viewChanged=!0,t>=i.viewTo)Wo&&br(e.doc,t)<i.viewTo&&Wt(e);else if(n<=i.viewFrom)Wo&&wr(e.doc,n+r)>i.viewFrom?Wt(e):(i.viewFrom+=r,i.viewTo+=r);else if(t<=i.viewFrom&&n>=i.viewTo)Wt(e);else if(t<=i.viewFrom){var o=_t(e,n,n+r,1);o?(i.view=i.view.slice(o.index),i.viewFrom=o.lineN,i.viewTo+=r):Wt(e)}else if(n>=i.viewTo){var o=_t(e,t,t,-1);o?(i.view=i.view.slice(0,o.index),i.viewTo=o.lineN):Wt(e)}else{var a=_t(e,t,t,-1),l=_t(e,n,n+r,1);a&&l?(i.view=i.view.slice(0,a.index).concat(Rt(e,a.lineN,l.lineN)).concat(i.view.slice(l.index)),i.viewTo+=r):Wt(e)}var s=i.externalMeasured;s&&(n<s.lineN?s.lineN+=r:t<s.lineN+s.size&&(i.externalMeasured=null))}function Ht(e,t,n){e.curOp.viewChanged=!0;var r=e.display,i=e.display.externalMeasured;if(i&&t>=i.lineN&&t<i.lineN+i.size&&(r.externalMeasured=null),!(t<r.viewFrom||t>=r.viewTo)){var o=r.view[Bt(e,t)];if(null!=o.node){var a=o.changes||(o.changes=[]);-1==Pi(a,n)&&a.push(n)}}}function Wt(e){e.display.viewFrom=e.display.viewTo=e.doc.first,e.display.view=[],e.display.viewOffset=0}function Bt(e,t){if(t>=e.display.viewTo)return null;if(t-=e.display.viewFrom,0>t)return null;for(var n=e.display.view,r=0;r<n.length;r++)if(t-=n[r].size,0>t)return r}function _t(e,t,n,r){var i,o=Bt(e,t),a=e.display.view;if(!Wo||n==e.doc.first+e.doc.size)return{index:o,lineN:n};for(var l=0,s=e.display.viewFrom;o>l;l++)s+=a[l].size;if(s!=t){if(r>0){if(o==a.length-1)return null;i=s+a[o].size-t,o++}else i=s-t;t+=i,n+=i}for(;br(e.doc,n)!=n;){if(o==(0>r?0:a.length-1))return null;n+=r*a[o-(0>r?1:0)].size,o+=r}return{index:o,lineN:n}}function Ft(e,t,n){var r=e.display,i=r.view;0==i.length||t>=r.viewTo||n<=r.viewFrom?(r.view=Rt(e,t,n),r.viewFrom=t):(r.viewFrom>t?r.view=Rt(e,t,r.viewFrom).concat(r.view):r.viewFrom<t&&(r.view=r.view.slice(Bt(e,t))),r.viewFrom=t,r.viewTo<n?r.view=r.view.concat(Rt(e,r.viewTo,n)):r.viewTo>n&&(r.view=r.view.slice(0,Bt(e,n)))),r.viewTo=n}function zt(e){for(var t=e.display.view,n=0,r=0;r<t.length;r++){var i=t[r];i.hidden||i.node&&!i.changes||++n}return n}function jt(e){function t(){i.activeTouch&&(o=setTimeout(function(){i.activeTouch=null},1e3),a=i.activeTouch,a.end=+new Date)}function n(e){if(1!=e.touches.length)return!1;var t=e.touches[0];return t.radiusX<=1&&t.radiusY<=1}function r(e,t){if(null==t.left)return!0;var n=t.left-e.left,r=t.top-e.top;return n*n+r*r>400}var i=e.display;Ea(i.scroller,"mousedown",Et(e,$t)),xo&&11>bo?Ea(i.scroller,"dblclick",Et(e,function(t){if(!Ti(e,t)){var n=Yt(e,t);if(n&&!Jt(e,t)&&!Gt(e.display,t)){Ma(t);var r=e.findWordAt(n);be(e.doc,r.anchor,r.head)}}})):Ea(i.scroller,"dblclick",function(t){Ti(e,t)||Ma(t)}),Do||Ea(i.scroller,"contextmenu",function(t){xn(e,t)});var o,a={end:0};Ea(i.scroller,"touchstart",function(t){if(!Ti(e,t)&&!n(t)){clearTimeout(o);var r=+new Date;i.activeTouch={start:r,moved:!1,prev:r-a.end<=300?a:null},1==t.touches.length&&(i.activeTouch.left=t.touches[0].pageX,i.activeTouch.top=t.touches[0].pageY)}}),Ea(i.scroller,"touchmove",function(){i.activeTouch&&(i.activeTouch.moved=!0)}),Ea(i.scroller,"touchend",function(n){var o=i.activeTouch;if(o&&!Gt(i,n)&&null!=o.left&&!o.moved&&new Date-o.start<300){var a,l=e.coordsChar(i.activeTouch,"page");a=!o.prev||r(o,o.prev)?new fe(l,l):!o.prev.prev||r(o,o.prev.prev)?e.findWordAt(l):new fe(Bo(l.line,0),me(e.doc,Bo(l.line+1,0))),e.setSelection(a.anchor,a.head),e.focus(),Ma(n)}t()}),Ea(i.scroller,"touchcancel",t),Ea(i.scroller,"scroll",function(){i.scroller.clientHeight&&(rn(e,i.scroller.scrollTop),on(e,i.scroller.scrollLeft,!0),Pa(e,"scroll",e))}),Ea(i.scroller,"mousewheel",function(t){an(e,t)}),Ea(i.scroller,"DOMMouseScroll",function(t){an(e,t)}),Ea(i.wrapper,"scroll",function(){i.wrapper.scrollTop=i.wrapper.scrollLeft=0}),i.dragFunctions={enter:function(t){Ti(e,t)||Aa(t)},over:function(t){Ti(e,t)||(tn(e,t),Aa(t))},start:function(t){en(e,t)},drop:Et(e,Qt),leave:function(t){Ti(e,t)||nn(e)}};var l=i.input.getField();Ea(l,"keyup",function(t){pn.call(e,t)}),Ea(l,"keydown",Et(e,hn)),Ea(l,"keypress",Et(e,mn)),Ea(l,"focus",Bi(vn,e)),Ea(l,"blur",Bi(yn,e))}function Ut(t,n,r){var i=r&&r!=e.Init;if(!n!=!i){var o=t.display.dragFunctions,a=n?Ea:Ia;a(t.display.scroller,"dragstart",o.start),a(t.display.scroller,"dragenter",o.enter),a(t.display.scroller,"dragover",o.over),a(t.display.scroller,"dragleave",o.leave),a(t.display.scroller,"drop",o.drop)}}function qt(e){var t=e.display;t.lastWrapHeight==t.wrapper.clientHeight&&t.lastWrapWidth==t.wrapper.clientWidth||(t.cachedCharWidth=t.cachedTextHeight=t.cachedPaddingH=null,t.scrollbarsClipped=!1,e.setSize())}function Gt(e,t){for(var n=wi(t);n!=e.wrapper;n=n.parentNode)if(!n||1==n.nodeType&&"true"==n.getAttribute("cm-ignore-events")||n.parentNode==e.sizer&&n!=e.mover)return!0}function Yt(e,t,n,r){var i=e.display;if(!n&&"true"==wi(t).getAttribute("cm-not-content"))return null;var o,a,l=i.lineSpace.getBoundingClientRect();try{o=t.clientX-l.left,a=t.clientY-l.top}catch(t){return null}var s,c=gt(e,o,a);if(r&&1==c.xRel&&(s=Zr(e.doc,c.line).text).length==c.ch){var u=Fa(s,s.length,e.options.tabSize)-s.length;c=Bo(c.line,Math.max(0,Math.round((o-Ge(e.display).left)/xt(e.display))-u))}return c}function $t(e){var t=this,n=t.display;if(!(Ti(t,e)||n.activeTouch&&n.input.supportsTouch())){if(n.shift=e.shiftKey,Gt(n,e))return void(wo||(n.scroller.draggable=!1,setTimeout(function(){n.scroller.draggable=!0},100)));if(!Jt(t,e)){var r=Yt(t,e);switch(window.focus(),ki(e)){case 1:t.state.selectingText?t.state.selectingText(e):r?Vt(t,e,r):wi(e)==n.scroller&&Ma(e);break;case 2:wo&&(t.state.lastMiddleDown=+new Date),r&&be(t.doc,r),setTimeout(function(){n.input.focus()},20),Ma(e);break;case 3:Do?xn(t,e):gn(t)}}}}function Vt(e,t,n){xo?setTimeout(Bi(X,e),0):e.curOp.focus=Gi();var r,i=+new Date;Uo&&Uo.time>i-400&&0==_o(Uo.pos,n)?r="triple":jo&&jo.time>i-400&&0==_o(jo.pos,n)?(r="double",Uo={time:i,pos:n}):(r="single",jo={time:i,pos:n});var o,a=e.doc.sel,l=Eo?t.metaKey:t.ctrlKey;e.options.dragDrop&&el&&!e.isReadOnly()&&"single"==r&&(o=a.contains(n))>-1&&(_o((o=a.ranges[o]).from(),n)<0||n.xRel>0)&&(_o(o.to(),n)>0||n.xRel<0)?Kt(e,t,n,l):Xt(e,t,n,r,l)}function Kt(e,t,n,r){var i=e.display,o=+new Date,a=Et(e,function(l){wo&&(i.scroller.draggable=!1),e.state.draggingText=!1,Ia(document,"mouseup",a),Ia(i.scroller,"drop",a),Math.abs(t.clientX-l.clientX)+Math.abs(t.clientY-l.clientY)<10&&(Ma(l),!r&&+new Date-200<o&&be(e.doc,n),wo||xo&&9==bo?setTimeout(function(){document.body.focus(),i.input.focus()},20):i.input.focus())});wo&&(i.scroller.draggable=!0),e.state.draggingText=a,i.scroller.dragDrop&&i.scroller.dragDrop(),Ea(document,"mouseup",a),Ea(i.scroller,"drop",a)}function Xt(e,t,n,r,i){function o(t){if(0!=_o(g,t))if(g=t,"rect"==r){for(var i=[],o=e.options.tabSize,a=Fa(Zr(c,n.line).text,n.ch,o),l=Fa(Zr(c,t.line).text,t.ch,o),s=Math.min(a,l),d=Math.max(a,l),p=Math.min(n.line,t.line),m=Math.min(e.lastLine(),Math.max(n.line,t.line));m>=p;p++){var v=Zr(c,p).text,y=za(v,s,o);s==d?i.push(new fe(Bo(p,y),Bo(p,y))):v.length>y&&i.push(new fe(Bo(p,y),Bo(p,za(v,d,o))))}i.length||i.push(new fe(n,n)),Te(c,he(h.ranges.slice(0,f).concat(i),f),{origin:"*mouse",scroll:!1}),e.scrollIntoView(t)}else{var x=u,b=x.anchor,w=t;if("single"!=r){if("double"==r)var k=e.findWordAt(t);else var k=new fe(Bo(t.line,0),me(c,Bo(t.line+1,0)));_o(k.anchor,b)>0?(w=k.head,b=K(x.from(),k.anchor)):(w=k.anchor,b=V(x.to(),k.head))}var i=h.ranges.slice(0);i[f]=new fe(me(c,b),w),Te(c,he(i,f),Ba)}}function a(t){var n=++y,i=Yt(e,t,!0,"rect"==r);if(i)if(0!=_o(i,g)){e.curOp.focus=Gi(),o(i);var l=b(s,c);(i.line>=l.to||i.line<l.from)&&setTimeout(Et(e,function(){y==n&&a(t)}),150)}else{var u=t.clientY<v.top?-20:t.clientY>v.bottom?20:0;u&&setTimeout(Et(e,function(){y==n&&(s.scroller.scrollTop+=u,a(t))}),50)}}function l(t){e.state.selectingText=!1,y=1/0,Ma(t),s.input.focus(),Ia(document,"mousemove",x),Ia(document,"mouseup",w),c.history.lastSelOrigin=null}var s=e.display,c=e.doc;Ma(t);var u,f,h=c.sel,d=h.ranges;if(i&&!t.shiftKey?(f=c.sel.contains(n),u=f>-1?d[f]:new fe(n,n)):(u=c.sel.primary(),f=c.sel.primIndex),Oo?t.shiftKey&&t.metaKey:t.altKey)r="rect",i||(u=new fe(n,n)),n=Yt(e,t,!0,!0),f=-1;else if("double"==r){var p=e.findWordAt(n);u=e.display.shift||c.extend?xe(c,u,p.anchor,p.head):p}else if("triple"==r){var m=new fe(Bo(n.line,0),me(c,Bo(n.line+1,0)));u=e.display.shift||c.extend?xe(c,u,m.anchor,m.head):m}else u=xe(c,u,n);i?-1==f?(f=d.length,Te(c,he(d.concat([u]),f),{scroll:!1,origin:"*mouse"})):d.length>1&&d[f].empty()&&"single"==r&&!t.shiftKey?(Te(c,he(d.slice(0,f).concat(d.slice(f+1)),0),{scroll:!1,origin:"*mouse"}),h=c.sel):ke(c,f,u,Ba):(f=0,Te(c,new ue([u],0),Ba),h=c.sel);var g=n,v=s.wrapper.getBoundingClientRect(),y=0,x=Et(e,function(e){ki(e)?a(e):l(e)}),w=Et(e,l);e.state.selectingText=w,Ea(document,"mousemove",x),Ea(document,"mouseup",w)}function Zt(e,t,n,r){try{var i=t.clientX,o=t.clientY}catch(t){return!1}if(i>=Math.floor(e.display.gutters.getBoundingClientRect().right))return!1;r&&Ma(t);var a=e.display,l=a.lineDiv.getBoundingClientRect();if(o>l.bottom||!Ni(e,n))return bi(t);o-=l.top-a.viewOffset;for(var s=0;s<e.options.gutters.length;++s){var c=a.gutters.childNodes[s];if(c&&c.getBoundingClientRect().right>=i){var u=ni(e.doc,o),f=e.options.gutters[s];return Pa(e,n,e,u,f,t),bi(t)}}}function Jt(e,t){return Zt(e,t,"gutterClick",!0)}function Qt(e){var t=this;if(nn(t),!Ti(t,e)&&!Gt(t.display,e)){Ma(e),xo&&($o=+new Date);var n=Yt(t,e,!0),r=e.dataTransfer.files;if(n&&!t.isReadOnly())if(r&&r.length&&window.FileReader&&window.File)for(var i=r.length,o=Array(i),a=0,l=function(e,r){if(!t.options.allowDropFileTypes||-1!=Pi(t.options.allowDropFileTypes,e.type)){var l=new FileReader;l.onload=Et(t,function(){var e=l.result;if(/[\x00-\x08\x0e-\x1f]{2}/.test(e)&&(e=""),o[r]=e,++a==i){n=me(t.doc,n);var s={from:n,to:n,text:t.doc.splitLines(o.join(t.doc.lineSeparator())),origin:"paste"};Tn(t.doc,s),Le(t.doc,de(n,Qo(s)))}}),l.readAsText(e)}},s=0;i>s;++s)l(r[s],s);else{if(t.state.draggingText&&t.doc.sel.contains(n)>-1)return t.state.draggingText(e),void setTimeout(function(){t.display.input.focus()},20);try{var o=e.dataTransfer.getData("Text");if(o){if(t.state.draggingText&&!(Eo?e.altKey:e.ctrlKey))var c=t.listSelections();if(Me(t.doc,de(n,n)),c)for(var s=0;s<c.length;++s)In(t.doc,"",c[s].anchor,c[s].head,"drag");t.replaceSelection(o,"around","paste"),t.display.input.focus()}}catch(e){}}}}function en(e,t){if(xo&&(!e.state.draggingText||+new Date-$o<100))return void Aa(t);if(!Ti(e,t)&&!Gt(e.display,t)&&(t.dataTransfer.setData("Text",e.getSelection()),t.dataTransfer.effectAllowed="copyMove",t.dataTransfer.setDragImage&&!Lo)){var n=ji("img",null,null,"position: fixed; left: 0; top: 0;");n.src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==",Co&&(n.width=n.height=1,e.display.wrapper.appendChild(n),n._top=n.offsetTop),t.dataTransfer.setDragImage(n,0,0),Co&&n.parentNode.removeChild(n)}}function tn(e,t){var n=Yt(e,t);if(n){var r=document.createDocumentFragment();He(e,n,r),e.display.dragCursor||(e.display.dragCursor=ji("div",null,"CodeMirror-cursors CodeMirror-dragcursors"),e.display.lineSpace.insertBefore(e.display.dragCursor,e.display.cursorDiv)),qi(e.display.dragCursor,r)}}function nn(e){e.display.dragCursor&&(e.display.lineSpace.removeChild(e.display.dragCursor),e.display.dragCursor=null)}function rn(e,t){Math.abs(e.doc.scrollTop-t)<2||(e.doc.scrollTop=t,go||A(e,{top:t}),e.display.scroller.scrollTop!=t&&(e.display.scroller.scrollTop=t),e.display.scrollbars.setScrollTop(t),go&&A(e),_e(e,100))}function on(e,t,n){(n?t==e.doc.scrollLeft:Math.abs(e.doc.scrollLeft-t)<2)||(t=Math.min(t,e.display.scroller.scrollWidth-e.display.scroller.clientWidth),e.doc.scrollLeft=t,w(e),e.display.scroller.scrollLeft!=t&&(e.display.scroller.scrollLeft=t),e.display.scrollbars.setScrollLeft(t))}function an(e,t){var n=Xo(t),r=n.x,i=n.y,o=e.display,a=o.scroller,l=a.scrollWidth>a.clientWidth,s=a.scrollHeight>a.clientHeight;if(r&&l||i&&s){if(i&&Eo&&wo)e:for(var c=t.target,u=o.view;c!=a;c=c.parentNode)for(var f=0;f<u.length;f++)if(u[f].node==c){e.display.currentWheelTarget=c;break e}if(r&&!go&&!Co&&null!=Ko)return i&&s&&rn(e,Math.max(0,Math.min(a.scrollTop+i*Ko,a.scrollHeight-a.clientHeight))),on(e,Math.max(0,Math.min(a.scrollLeft+r*Ko,a.scrollWidth-a.clientWidth))),(!i||i&&s)&&Ma(t),void(o.wheelStartX=null);if(i&&null!=Ko){var h=i*Ko,d=e.doc.scrollTop,p=d+o.wrapper.clientHeight;0>h?d=Math.max(0,d+h-50):p=Math.min(e.doc.height,p+h+50),A(e,{top:d,bottom:p})}20>Vo&&(null==o.wheelStartX?(o.wheelStartX=a.scrollLeft,o.wheelStartY=a.scrollTop,o.wheelDX=r,o.wheelDY=i,setTimeout(function(){if(null!=o.wheelStartX){var e=a.scrollLeft-o.wheelStartX,t=a.scrollTop-o.wheelStartY,n=t&&o.wheelDY&&t/o.wheelDY||e&&o.wheelDX&&e/o.wheelDX;o.wheelStartX=o.wheelStartY=null,n&&(Ko=(Ko*Vo+n)/(Vo+1),++Vo)}},200)):(o.wheelDX+=r,o.wheelDY+=i))}}function ln(e,t,n){if("string"==typeof t&&(t=ua[t],!t))return!1;e.display.input.ensurePolled();var r=e.display.shift,i=!1;try{e.isReadOnly()&&(e.state.suppressEdits=!0),n&&(e.display.shift=!1),i=t(e)!=Ha}finally{e.display.shift=r,e.state.suppressEdits=!1}return i}function sn(e,t,n){for(var r=0;r<e.state.keyMaps.length;r++){var i=ha(t,e.state.keyMaps[r],n,e);if(i)return i}return e.options.extraKeys&&ha(t,e.options.extraKeys,n,e)||ha(t,e.options.keyMap,n,e)}function cn(e,t,n,r){var i=e.state.keySeq;if(i){if(da(t))return"handled";Zo.set(50,function(){e.state.keySeq==i&&(e.state.keySeq=null,e.display.input.reset())}),t=i+" "+t}var o=sn(e,t,r);return"multi"==o&&(e.state.keySeq=t),"handled"==o&&Ci(e,"keyHandled",e,t,n),"handled"!=o&&"multi"!=o||(Ma(n),Be(e)),i&&!o&&/\'$/.test(t)?(Ma(n),!0):!!o}function un(e,t){var n=pa(t,!0);return n?t.shiftKey&&!e.state.keySeq?cn(e,"Shift-"+n,t,function(t){return ln(e,t,!0)})||cn(e,n,t,function(t){return("string"==typeof t?/^go[A-Z]/.test(t):t.motion)?ln(e,t):void 0}):cn(e,n,t,function(t){return ln(e,t)}):!1}function fn(e,t,n){return cn(e,"'"+n+"'",t,function(t){return ln(e,t,!0)})}function hn(e){var t=this;if(t.curOp.focus=Gi(),!Ti(t,e)){xo&&11>bo&&27==e.keyCode&&(e.returnValue=!1);var n=e.keyCode;t.display.shift=16==n||e.shiftKey;var r=un(t,e);Co&&(Jo=r?n:null,!r&&88==n&&!rl&&(Eo?e.metaKey:e.ctrlKey)&&t.replaceSelection("",null,"cut")),18!=n||/\bCodeMirror-crosshair\b/.test(t.display.lineDiv.className)||dn(t)}}function dn(e){function t(e){18!=e.keyCode&&e.altKey||(Za(n,"CodeMirror-crosshair"),Ia(document,"keyup",t),Ia(document,"mouseover",t))}var n=e.display.lineDiv;Ja(n,"CodeMirror-crosshair"),Ea(document,"keyup",t),Ea(document,"mouseover",t)}function pn(e){16==e.keyCode&&(this.doc.sel.shift=!1),Ti(this,e)}function mn(e){var t=this;if(!(Gt(t.display,e)||Ti(t,e)||e.ctrlKey&&!e.altKey||Eo&&e.metaKey)){var n=e.keyCode,r=e.charCode;if(Co&&n==Jo)return Jo=null,void Ma(e);if(!Co||e.which&&!(e.which<10)||!un(t,e)){var i=String.fromCharCode(null==r?n:r);fn(t,e,i)||t.display.input.onKeyPress(e)}}}function gn(e){e.state.delayingBlurEvent=!0,setTimeout(function(){e.state.delayingBlurEvent&&(e.state.delayingBlurEvent=!1,yn(e))},100)}function vn(e){e.state.delayingBlurEvent&&(e.state.delayingBlurEvent=!1),"nocursor"!=e.options.readOnly&&(e.state.focused||(Pa(e,"focus",e),e.state.focused=!0,Ja(e.display.wrapper,"CodeMirror-focused"),e.curOp||e.display.selForContextMenu==e.doc.sel||(e.display.input.reset(),wo&&setTimeout(function(){e.display.input.reset(!0)},20)),e.display.input.receivedFocus()),Be(e))}function yn(e){e.state.delayingBlurEvent||(e.state.focused&&(Pa(e,"blur",e),e.state.focused=!1,Za(e.display.wrapper,"CodeMirror-focused")),clearInterval(e.display.blinker),setTimeout(function(){e.state.focused||(e.display.shift=!1)},150))}function xn(e,t){Gt(e.display,t)||bn(e,t)||Ti(e,t,"contextmenu")||e.display.input.onContextMenu(t)}function bn(e,t){return Ni(e,"gutterContextMenu")?Zt(e,t,"gutterContextMenu",!1):!1}function wn(e,t){if(_o(e,t.from)<0)return e;if(_o(e,t.to)<=0)return Qo(t);var n=e.line+t.text.length-(t.to.line-t.from.line)-1,r=e.ch;return e.line==t.to.line&&(r+=Qo(t).ch-t.to.ch),Bo(n,r)}function kn(e,t){for(var n=[],r=0;r<e.sel.ranges.length;r++){var i=e.sel.ranges[r];n.push(new fe(wn(i.anchor,t),wn(i.head,t)))}return he(n,e.sel.primIndex)}function Sn(e,t,n){return e.line==t.line?Bo(n.line,e.ch-t.ch+n.ch):Bo(n.line+(e.line-t.line),e.ch)}function Cn(e,t,n){for(var r=[],i=Bo(e.first,0),o=i,a=0;a<t.length;a++){var l=t[a],s=Sn(l.from,i,o),c=Sn(Qo(l),i,o);if(i=l.to,o=c,"around"==n){var u=e.sel.ranges[a],f=_o(u.head,u.anchor)<0;r[a]=new fe(f?c:s,f?s:c)}else r[a]=new fe(s,s)}return new ue(r,e.sel.primIndex)}function Ln(e,t,n){var r={canceled:!1,from:t.from,to:t.to,text:t.text,origin:t.origin,cancel:function(){this.canceled=!0}};return n&&(r.update=function(t,n,r,i){t&&(this.from=me(e,t)),n&&(this.to=me(e,n)),r&&(this.text=r),void 0!==i&&(this.origin=i)}),Pa(e,"beforeChange",e,r),e.cm&&Pa(e.cm,"beforeChange",e.cm,r),r.canceled?null:{from:r.from,to:r.to,text:r.text,origin:r.origin}}function Tn(e,t,n){if(e.cm){if(!e.cm.curOp)return Et(e.cm,Tn)(e,t,n);if(e.cm.state.suppressEdits)return}if(!(Ni(e,"beforeChange")||e.cm&&Ni(e.cm,"beforeChange"))||(t=Ln(e,t,!0))){var r=Ho&&!n&&sr(e,t.from,t.to);if(r)for(var i=r.length-1;i>=0;--i)Mn(e,{from:r[i].from,to:r[i].to,text:i?[""]:t.text});else Mn(e,t)}}function Mn(e,t){if(1!=t.text.length||""!=t.text[0]||0!=_o(t.from,t.to)){var n=kn(e,t);ci(e,t,n,e.cm?e.cm.curOp.id:NaN),En(e,t,n,or(e,t));var r=[];Kr(e,function(e,n){n||-1!=Pi(r,e.history)||(xi(e.history,t),r.push(e.history)),En(e,t,null,or(e,t))})}}function Nn(e,t,n){if(!e.cm||!e.cm.state.suppressEdits){for(var r,i=e.history,o=e.sel,a="undo"==t?i.done:i.undone,l="undo"==t?i.undone:i.done,s=0;s<a.length&&(r=a[s],n?!r.ranges||r.equals(e.sel):r.ranges);s++);if(s!=a.length){for(i.lastOrigin=i.lastSelOrigin=null;r=a.pop(),r.ranges;){if(hi(r,l),n&&!r.equals(e.sel))return void Te(e,r,{clearRedo:!1});o=r}var c=[];hi(o,l),l.push({changes:c,generation:i.generation}),i.generation=r.generation||++i.maxGeneration;for(var u=Ni(e,"beforeChange")||e.cm&&Ni(e.cm,"beforeChange"),s=r.changes.length-1;s>=0;--s){var f=r.changes[s];if(f.origin=t,u&&!Ln(e,f,!1))return void(a.length=0);c.push(ai(e,f));var h=s?kn(e,f):Ii(a);En(e,f,h,lr(e,f)),!s&&e.cm&&e.cm.scrollIntoView({from:f.from,to:Qo(f)});var d=[];Kr(e,function(e,t){t||-1!=Pi(d,e.history)||(xi(e.history,f),d.push(e.history)),En(e,f,null,lr(e,f))})}}}}function An(e,t){if(0!=t&&(e.first+=t,e.sel=new ue(Ri(e.sel.ranges,function(e){return new fe(Bo(e.anchor.line+t,e.anchor.ch),Bo(e.head.line+t,e.head.ch))}),e.sel.primIndex),e.cm)){Dt(e.cm,e.first,e.first-t,t);for(var n=e.cm.display,r=n.viewFrom;r<n.viewTo;r++)Ht(e.cm,r,"gutter")}}function En(e,t,n,r){if(e.cm&&!e.cm.curOp)return Et(e.cm,En)(e,t,n,r);if(t.to.line<e.first)return void An(e,t.text.length-1-(t.to.line-t.from.line));if(!(t.from.line>e.lastLine())){if(t.from.line<e.first){var i=t.text.length-1-(e.first-t.from.line);An(e,i),t={from:Bo(e.first,0),to:Bo(t.to.line+i,t.to.ch),text:[Ii(t.text)],origin:t.origin}}var o=e.lastLine();t.to.line>o&&(t={from:t.from,to:Bo(o,Zr(e,o).text.length),text:[t.text[0]],origin:t.origin}),t.removed=Jr(e,t.from,t.to),n||(n=kn(e,t)),e.cm?On(e.cm,t,r):Yr(e,t,r),Me(e,n,Wa)}}function On(e,t,n){var r=e.doc,i=e.display,a=t.from,l=t.to,s=!1,c=a.line;e.options.lineWrapping||(c=ti(yr(Zr(r,a.line))),r.iter(c,l.line+1,function(e){return e==i.maxLine?(s=!0,!0):void 0})),r.sel.contains(t.from,t.to)>-1&&Mi(e),Yr(r,t,n,o(e)),e.options.lineWrapping||(r.iter(c,a.line+t.text.length,function(e){var t=f(e);t>i.maxLineLength&&(i.maxLine=e,i.maxLineLength=t,i.maxLineChanged=!0,s=!1)}),s&&(e.curOp.updateMaxLine=!0)),r.frontier=Math.min(r.frontier,a.line),_e(e,400);var u=t.text.length-(l.line-a.line)-1;t.full?Dt(e):a.line!=l.line||1!=t.text.length||Gr(e.doc,t)?Dt(e,a.line,l.line+1,u):Ht(e,a.line,"text");var h=Ni(e,"changes"),d=Ni(e,"change");if(d||h){var p={from:a,to:l,text:t.text,removed:t.removed,origin:t.origin};d&&Ci(e,"change",e,p),h&&(e.curOp.changeObjs||(e.curOp.changeObjs=[])).push(p)}e.display.selForContextMenu=null}function In(e,t,n,r,i){if(r||(r=n),_o(r,n)<0){var o=r;r=n,n=o}"string"==typeof t&&(t=e.splitLines(t)),Tn(e,{from:n,to:r,text:t,origin:i})}function Pn(e,t){if(!Ti(e,"scrollCursorIntoView")){var n=e.display,r=n.sizer.getBoundingClientRect(),i=null;if(t.top+r.top<0?i=!0:t.bottom+r.top>(window.innerHeight||document.documentElement.clientHeight)&&(i=!1),null!=i&&!Mo){var o=ji("div","​",null,"position: absolute; top: "+(t.top-n.viewOffset-Ue(e.display))+"px; height: "+(t.bottom-t.top+Ye(e)+n.barHeight)+"px; left: "+t.left+"px; width: 2px;");e.display.lineSpace.appendChild(o),o.scrollIntoView(i),e.display.lineSpace.removeChild(o)}}}function Rn(e,t,n,r){null==r&&(r=0);for(var i=0;5>i;i++){var o=!1,a=dt(e,t),l=n&&n!=t?dt(e,n):a,s=Hn(e,Math.min(a.left,l.left),Math.min(a.top,l.top)-r,Math.max(a.left,l.left),Math.max(a.bottom,l.bottom)+r),c=e.doc.scrollTop,u=e.doc.scrollLeft;if(null!=s.scrollTop&&(rn(e,s.scrollTop),Math.abs(e.doc.scrollTop-c)>1&&(o=!0)),null!=s.scrollLeft&&(on(e,s.scrollLeft),Math.abs(e.doc.scrollLeft-u)>1&&(o=!0)),!o)break}return a}function Dn(e,t,n,r,i){var o=Hn(e,t,n,r,i);null!=o.scrollTop&&rn(e,o.scrollTop),null!=o.scrollLeft&&on(e,o.scrollLeft)}function Hn(e,t,n,r,i){var o=e.display,a=yt(e.display);0>n&&(n=0);var l=e.curOp&&null!=e.curOp.scrollTop?e.curOp.scrollTop:o.scroller.scrollTop,s=Ve(e),c={};i-n>s&&(i=n+s);var u=e.doc.height+qe(o),f=a>n,h=i>u-a;if(l>n)c.scrollTop=f?0:n;else if(i>l+s){var d=Math.min(n,(h?u:i)-s);d!=l&&(c.scrollTop=d)}var p=e.curOp&&null!=e.curOp.scrollLeft?e.curOp.scrollLeft:o.scroller.scrollLeft,m=$e(e)-(e.options.fixedGutter?o.gutters.offsetWidth:0),g=r-t>m;return g&&(r=t+m),10>t?c.scrollLeft=0:p>t?c.scrollLeft=Math.max(0,t-(g?0:10)):r>m+p-3&&(c.scrollLeft=r+(g?0:10)-m),c}function Wn(e,t,n){null==t&&null==n||_n(e),null!=t&&(e.curOp.scrollLeft=(null==e.curOp.scrollLeft?e.doc.scrollLeft:e.curOp.scrollLeft)+t),null!=n&&(e.curOp.scrollTop=(null==e.curOp.scrollTop?e.doc.scrollTop:e.curOp.scrollTop)+n)}function Bn(e){_n(e);var t=e.getCursor(),n=t,r=t;e.options.lineWrapping||(n=t.ch?Bo(t.line,t.ch-1):t,r=Bo(t.line,t.ch+1)),e.curOp.scrollToPos={from:n,to:r,margin:e.options.cursorScrollMargin,isCursor:!0}}function _n(e){var t=e.curOp.scrollToPos;if(t){e.curOp.scrollToPos=null;var n=pt(e,t.from),r=pt(e,t.to),i=Hn(e,Math.min(n.left,r.left),Math.min(n.top,r.top)-t.margin,Math.max(n.right,r.right),Math.max(n.bottom,r.bottom)+t.margin);e.scrollTo(i.scrollLeft,i.scrollTop)}}function Fn(e,t,n,r){var i,o=e.doc;null==n&&(n="add"),"smart"==n&&(o.mode.indent?i=je(e,t):n="prev");var a=e.options.tabSize,l=Zr(o,t),s=Fa(l.text,null,a);l.stateAfter&&(l.stateAfter=null);var c,u=l.text.match(/^\s*/)[0];if(r||/\S/.test(l.text)){if("smart"==n&&(c=o.mode.indent(i,l.text.slice(u.length),l.text),c==Ha||c>150)){if(!r)return;n="prev"}}else c=0,n="not";"prev"==n?c=t>o.first?Fa(Zr(o,t-1).text,null,a):0:"add"==n?c=s+e.options.indentUnit:"subtract"==n?c=s-e.options.indentUnit:"number"==typeof n&&(c=s+n),c=Math.max(0,c);var f="",h=0;if(e.options.indentWithTabs)for(var d=Math.floor(c/a);d;--d)h+=a,f+="	";if(c>h&&(f+=Oi(c-h)),f!=u)return In(o,f,Bo(t,0),Bo(t,u.length),"+input"),l.stateAfter=null,!0;for(var d=0;d<o.sel.ranges.length;d++){var p=o.sel.ranges[d];if(p.head.line==t&&p.head.ch<u.length){var h=Bo(t,u.length);ke(o,d,new fe(h,h));break}}}function zn(e,t,n,r){var i=t,o=t;return"number"==typeof t?o=Zr(e,pe(e,t)):i=ti(t),null==i?null:(r(o,i)&&e.cm&&Ht(e.cm,i,n),o)}function jn(e,t){for(var n=e.doc.sel.ranges,r=[],i=0;i<n.length;i++){for(var o=t(n[i]);r.length&&_o(o.from,Ii(r).to)<=0;){var a=r.pop();if(_o(a.from,o.from)<0){o.from=a.from;break}}r.push(o)}At(e,function(){for(var t=r.length-1;t>=0;t--)In(e.doc,"",r[t].from,r[t].to,"+delete");Bn(e)})}function Un(e,t,n,r,i){function o(){var t=l+n;return t<e.first||t>=e.first+e.size?!1:(l=t,u=Zr(e,t))}function a(e){var t=(i?fo:ho)(u,s,n,!0);if(null==t){if(e||!o())return!1;s=i?(0>n?io:ro)(u):0>n?u.text.length:0}else s=t;return!0}var l=t.line,s=t.ch,c=n,u=Zr(e,l);if("char"==r)a();else if("column"==r)a(!0);else if("word"==r||"group"==r)for(var f=null,h="group"==r,d=e.cm&&e.cm.getHelper(t,"wordChars"),p=!0;!(0>n)||a(!p);p=!1){var m=u.text.charAt(s)||"\n",g=_i(m,d)?"w":h&&"\n"==m?"n":!h||/\s/.test(m)?null:"p";if(!h||p||g||(g="s"),f&&f!=g){0>n&&(n=1,a());break}if(g&&(f=g),n>0&&!a(!p))break}var v=Ie(e,Bo(l,s),t,c,!0);return _o(t,v)||(v.hitSide=!0),v}function qn(e,t,n,r){var i,o=e.doc,a=t.left;if("page"==r){var l=Math.min(e.display.wrapper.clientHeight,window.innerHeight||document.documentElement.clientHeight);i=t.top+n*(l-(0>n?1.5:.5)*yt(e.display))}else"line"==r&&(i=n>0?t.bottom+3:t.top-3);for(;;){var s=gt(e,a,i);if(!s.outside)break;if(0>n?0>=i:i>=o.height){s.hitSide=!0;break}i+=5*n}return s}function Gn(t,n,r,i){e.defaults[t]=n,r&&(ta[t]=i?function(e,t,n){n!=na&&r(e,t,n)}:r)}function Yn(e){for(var t,n,r,i,o=e.split(/-(?!$)/),e=o[o.length-1],a=0;a<o.length-1;a++){var l=o[a];if(/^(cmd|meta|m)$/i.test(l))i=!0;else if(/^a(lt)?$/i.test(l))t=!0;else if(/^(c|ctrl|control)$/i.test(l))n=!0;else{
61892if(!/^s(hift)$/i.test(l))throw new Error("Unrecognized modifier name: "+l);r=!0}}return t&&(e="Alt-"+e),n&&(e="Ctrl-"+e),i&&(e="Cmd-"+e),r&&(e="Shift-"+e),e}function $n(e){return"string"==typeof e?fa[e]:e}function Vn(e,t,n,r,i){if(r&&r.shared)return Kn(e,t,n,r,i);if(e.cm&&!e.cm.curOp)return Et(e.cm,Vn)(e,t,n,r,i);var o=new va(e,i),a=_o(t,n);if(r&&Wi(r,o,!1),a>0||0==a&&o.clearWhenEmpty!==!1)return o;if(o.replacedWith&&(o.collapsed=!0,o.widgetNode=ji("span",[o.replacedWith],"CodeMirror-widget"),r.handleMouseEvents||o.widgetNode.setAttribute("cm-ignore-events","true"),r.insertLeft&&(o.widgetNode.insertLeft=!0)),o.collapsed){if(vr(e,t.line,t,n,o)||t.line!=n.line&&vr(e,n.line,t,n,o))throw new Error("Inserting collapsed marker partially overlapping an existing one");Wo=!0}o.addToHistory&&ci(e,{from:t,to:n,origin:"markText"},e.sel,NaN);var l,s=t.line,c=e.cm;if(e.iter(s,n.line+1,function(e){c&&o.collapsed&&!c.options.lineWrapping&&yr(e)==c.display.maxLine&&(l=!0),o.collapsed&&s!=t.line&&ei(e,0),nr(e,new Qn(o,s==t.line?t.ch:null,s==n.line?n.ch:null)),++s}),o.collapsed&&e.iter(t.line,n.line+1,function(t){kr(e,t)&&ei(t,0)}),o.clearOnEnter&&Ea(o,"beforeCursorEnter",function(){o.clear()}),o.readOnly&&(Ho=!0,(e.history.done.length||e.history.undone.length)&&e.clearHistory()),o.collapsed&&(o.id=++ga,o.atomic=!0),c){if(l&&(c.curOp.updateMaxLine=!0),o.collapsed)Dt(c,t.line,n.line+1);else if(o.className||o.title||o.startStyle||o.endStyle||o.css)for(var u=t.line;u<=n.line;u++)Ht(c,u,"text");o.atomic&&Ae(c.doc),Ci(c,"markerAdded",c,o)}return o}function Kn(e,t,n,r,i){r=Wi(r),r.shared=!1;var o=[Vn(e,t,n,r,i)],a=o[0],l=r.widgetNode;return Kr(e,function(e){l&&(r.widgetNode=l.cloneNode(!0)),o.push(Vn(e,me(e,t),me(e,n),r,i));for(var s=0;s<e.linked.length;++s)if(e.linked[s].isParent)return;a=Ii(o)}),new ya(o,a)}function Xn(e){return e.findMarks(Bo(e.first,0),e.clipPos(Bo(e.lastLine())),function(e){return e.parent})}function Zn(e,t){for(var n=0;n<t.length;n++){var r=t[n],i=r.find(),o=e.clipPos(i.from),a=e.clipPos(i.to);if(_o(o,a)){var l=Vn(e,o,a,r.primary,r.primary.type);r.markers.push(l),l.parent=r}}}function Jn(e){for(var t=0;t<e.length;t++){var n=e[t],r=[n.primary.doc];Kr(n.primary.doc,function(e){r.push(e)});for(var i=0;i<n.markers.length;i++){var o=n.markers[i];-1==Pi(r,o.doc)&&(o.parent=null,n.markers.splice(i--,1))}}}function Qn(e,t,n){this.marker=e,this.from=t,this.to=n}function er(e,t){if(e)for(var n=0;n<e.length;++n){var r=e[n];if(r.marker==t)return r}}function tr(e,t){for(var n,r=0;r<e.length;++r)e[r]!=t&&(n||(n=[])).push(e[r]);return n}function nr(e,t){e.markedSpans=e.markedSpans?e.markedSpans.concat([t]):[t],t.marker.attachLine(e)}function rr(e,t,n){if(e)for(var r,i=0;i<e.length;++i){var o=e[i],a=o.marker,l=null==o.from||(a.inclusiveLeft?o.from<=t:o.from<t);if(l||o.from==t&&"bookmark"==a.type&&(!n||!o.marker.insertLeft)){var s=null==o.to||(a.inclusiveRight?o.to>=t:o.to>t);(r||(r=[])).push(new Qn(a,o.from,s?null:o.to))}}return r}function ir(e,t,n){if(e)for(var r,i=0;i<e.length;++i){var o=e[i],a=o.marker,l=null==o.to||(a.inclusiveRight?o.to>=t:o.to>t);if(l||o.from==t&&"bookmark"==a.type&&(!n||o.marker.insertLeft)){var s=null==o.from||(a.inclusiveLeft?o.from<=t:o.from<t);(r||(r=[])).push(new Qn(a,s?null:o.from-t,null==o.to?null:o.to-t))}}return r}function or(e,t){if(t.full)return null;var n=ve(e,t.from.line)&&Zr(e,t.from.line).markedSpans,r=ve(e,t.to.line)&&Zr(e,t.to.line).markedSpans;if(!n&&!r)return null;var i=t.from.ch,o=t.to.ch,a=0==_o(t.from,t.to),l=rr(n,i,a),s=ir(r,o,a),c=1==t.text.length,u=Ii(t.text).length+(c?i:0);if(l)for(var f=0;f<l.length;++f){var h=l[f];if(null==h.to){var d=er(s,h.marker);d?c&&(h.to=null==d.to?null:d.to+u):h.to=i}}if(s)for(var f=0;f<s.length;++f){var h=s[f];if(null!=h.to&&(h.to+=u),null==h.from){var d=er(l,h.marker);d||(h.from=u,c&&(l||(l=[])).push(h))}else h.from+=u,c&&(l||(l=[])).push(h)}l&&(l=ar(l)),s&&s!=l&&(s=ar(s));var p=[l];if(!c){var m,g=t.text.length-2;if(g>0&&l)for(var f=0;f<l.length;++f)null==l[f].to&&(m||(m=[])).push(new Qn(l[f].marker,null,null));for(var f=0;g>f;++f)p.push(m);p.push(s)}return p}function ar(e){for(var t=0;t<e.length;++t){var n=e[t];null!=n.from&&n.from==n.to&&n.marker.clearWhenEmpty!==!1&&e.splice(t--,1)}return e.length?e:null}function lr(e,t){var n=mi(e,t),r=or(e,t);if(!n)return r;if(!r)return n;for(var i=0;i<n.length;++i){var o=n[i],a=r[i];if(o&&a)e:for(var l=0;l<a.length;++l){for(var s=a[l],c=0;c<o.length;++c)if(o[c].marker==s.marker)continue e;o.push(s)}else a&&(n[i]=a)}return n}function sr(e,t,n){var r=null;if(e.iter(t.line,n.line+1,function(e){if(e.markedSpans)for(var t=0;t<e.markedSpans.length;++t){var n=e.markedSpans[t].marker;!n.readOnly||r&&-1!=Pi(r,n)||(r||(r=[])).push(n)}}),!r)return null;for(var i=[{from:t,to:n}],o=0;o<r.length;++o)for(var a=r[o],l=a.find(0),s=0;s<i.length;++s){var c=i[s];if(!(_o(c.to,l.from)<0||_o(c.from,l.to)>0)){var u=[s,1],f=_o(c.from,l.from),h=_o(c.to,l.to);(0>f||!a.inclusiveLeft&&!f)&&u.push({from:c.from,to:l.from}),(h>0||!a.inclusiveRight&&!h)&&u.push({from:l.to,to:c.to}),i.splice.apply(i,u),s+=u.length-1}}return i}function cr(e){var t=e.markedSpans;if(t){for(var n=0;n<t.length;++n)t[n].marker.detachLine(e);e.markedSpans=null}}function ur(e,t){if(t){for(var n=0;n<t.length;++n)t[n].marker.attachLine(e);e.markedSpans=t}}function fr(e){return e.inclusiveLeft?-1:0}function hr(e){return e.inclusiveRight?1:0}function dr(e,t){var n=e.lines.length-t.lines.length;if(0!=n)return n;var r=e.find(),i=t.find(),o=_o(r.from,i.from)||fr(e)-fr(t);if(o)return-o;var a=_o(r.to,i.to)||hr(e)-hr(t);return a?a:t.id-e.id}function pr(e,t){var n,r=Wo&&e.markedSpans;if(r)for(var i,o=0;o<r.length;++o)i=r[o],i.marker.collapsed&&null==(t?i.from:i.to)&&(!n||dr(n,i.marker)<0)&&(n=i.marker);return n}function mr(e){return pr(e,!0)}function gr(e){return pr(e,!1)}function vr(e,t,n,r,i){var o=Zr(e,t),a=Wo&&o.markedSpans;if(a)for(var l=0;l<a.length;++l){var s=a[l];if(s.marker.collapsed){var c=s.marker.find(0),u=_o(c.from,n)||fr(s.marker)-fr(i),f=_o(c.to,r)||hr(s.marker)-hr(i);if(!(u>=0&&0>=f||0>=u&&f>=0)&&(0>=u&&(s.marker.inclusiveRight&&i.inclusiveLeft?_o(c.to,n)>=0:_o(c.to,n)>0)||u>=0&&(s.marker.inclusiveRight&&i.inclusiveLeft?_o(c.from,r)<=0:_o(c.from,r)<0)))return!0}}}function yr(e){for(var t;t=mr(e);)e=t.find(-1,!0).line;return e}function xr(e){for(var t,n;t=gr(e);)e=t.find(1,!0).line,(n||(n=[])).push(e);return n}function br(e,t){var n=Zr(e,t),r=yr(n);return n==r?t:ti(r)}function wr(e,t){if(t>e.lastLine())return t;var n,r=Zr(e,t);if(!kr(e,r))return t;for(;n=gr(r);)r=n.find(1,!0).line;return ti(r)+1}function kr(e,t){var n=Wo&&t.markedSpans;if(n)for(var r,i=0;i<n.length;++i)if(r=n[i],r.marker.collapsed){if(null==r.from)return!0;if(!r.marker.widgetNode&&0==r.from&&r.marker.inclusiveLeft&&Sr(e,t,r))return!0}}function Sr(e,t,n){if(null==n.to){var r=n.marker.find(1,!0);return Sr(e,r.line,er(r.line.markedSpans,n.marker))}if(n.marker.inclusiveRight&&n.to==t.text.length)return!0;for(var i,o=0;o<t.markedSpans.length;++o)if(i=t.markedSpans[o],i.marker.collapsed&&!i.marker.widgetNode&&i.from==n.to&&(null==i.to||i.to!=n.from)&&(i.marker.inclusiveLeft||n.marker.inclusiveRight)&&Sr(e,t,i))return!0}function Cr(e,t,n){ri(t)<(e.curOp&&e.curOp.scrollTop||e.doc.scrollTop)&&Wn(e,null,n)}function Lr(e){if(null!=e.height)return e.height;var t=e.doc.cm;if(!t)return 0;if(!Va(document.body,e.node)){var n="position: relative;";e.coverGutter&&(n+="margin-left: -"+t.display.gutters.offsetWidth+"px;"),e.noHScroll&&(n+="width: "+t.display.wrapper.clientWidth+"px;"),qi(t.display.measure,ji("div",[e.node],null,n))}return e.height=e.node.parentNode.offsetHeight}function Tr(e,t,n,r){var i=new xa(e,n,r),o=e.cm;return o&&i.noHScroll&&(o.display.alignWidgets=!0),zn(e,t,"widget",function(t){var n=t.widgets||(t.widgets=[]);if(null==i.insertAt?n.push(i):n.splice(Math.min(n.length-1,Math.max(0,i.insertAt)),0,i),i.line=t,o&&!kr(e,t)){var r=ri(t)<e.scrollTop;ei(t,t.height+Lr(i)),r&&Wn(o,null,i.height),o.curOp.forceUpdate=!0}return!0}),i}function Mr(e,t,n,r){e.text=t,e.stateAfter&&(e.stateAfter=null),e.styles&&(e.styles=null),null!=e.order&&(e.order=null),cr(e),ur(e,n);var i=r?r(e):1;i!=e.height&&ei(e,i)}function Nr(e){e.parent=null,cr(e)}function Ar(e,t){if(e)for(;;){var n=e.match(/(?:^|\s+)line-(background-)?(\S+)/);if(!n)break;e=e.slice(0,n.index)+e.slice(n.index+n[0].length);var r=n[1]?"bgClass":"textClass";null==t[r]?t[r]=n[2]:new RegExp("(?:^|s)"+n[2]+"(?:$|s)").test(t[r])||(t[r]+=" "+n[2])}return e}function Er(t,n){if(t.blankLine)return t.blankLine(n);if(t.innerMode){var r=e.innerMode(t,n);return r.mode.blankLine?r.mode.blankLine(r.state):void 0}}function Or(t,n,r,i){for(var o=0;10>o;o++){i&&(i[0]=e.innerMode(t,r).mode);var a=t.token(n,r);if(n.pos>n.start)return a}throw new Error("Mode "+t.name+" failed to advance stream.")}function Ir(e,t,n,r){function i(e){return{start:f.start,end:f.pos,string:f.current(),type:o||null,state:e?sa(a.mode,u):u}}var o,a=e.doc,l=a.mode;t=me(a,t);var s,c=Zr(a,t.line),u=je(e,t.line,n),f=new ma(c.text,e.options.tabSize);for(r&&(s=[]);(r||f.pos<t.ch)&&!f.eol();)f.start=f.pos,o=Or(l,f,u),r&&s.push(i(!0));return r?s:i()}function Pr(e,t,n,r,i,o,a){var l=n.flattenSpans;null==l&&(l=e.options.flattenSpans);var s,c=0,u=null,f=new ma(t,e.options.tabSize),h=e.options.addModeClass&&[null];for(""==t&&Ar(Er(n,r),o);!f.eol();){if(f.pos>e.options.maxHighlightLength?(l=!1,a&&Hr(e,t,r,f.pos),f.pos=t.length,s=null):s=Ar(Or(n,f,r,h),o),h){var d=h[0].name;d&&(s="m-"+(s?d+" "+s:d))}if(!l||u!=s){for(;c<f.start;)c=Math.min(f.start,c+5e4),i(c,u);u=s}f.start=f.pos}for(;c<f.pos;){var p=Math.min(f.pos,c+5e4);i(p,u),c=p}}function Rr(e,t,n,r){var i=[e.state.modeGen],o={};Pr(e,t.text,e.doc.mode,n,function(e,t){i.push(e,t)},o,r);for(var a=0;a<e.state.overlays.length;++a){var l=e.state.overlays[a],s=1,c=0;Pr(e,t.text,l.mode,!0,function(e,t){for(var n=s;e>c;){var r=i[s];r>e&&i.splice(s,1,e,i[s+1],r),s+=2,c=Math.min(e,r)}if(t)if(l.opaque)i.splice(n,s-n,e,"cm-overlay "+t),s=n+2;else for(;s>n;n+=2){var o=i[n+1];i[n+1]=(o?o+" ":"")+"cm-overlay "+t}},o)}return{styles:i,classes:o.bgClass||o.textClass?o:null}}function Dr(e,t,n){if(!t.styles||t.styles[0]!=e.state.modeGen){var r=je(e,ti(t)),i=Rr(e,t,t.text.length>e.options.maxHighlightLength?sa(e.doc.mode,r):r);t.stateAfter=r,t.styles=i.styles,i.classes?t.styleClasses=i.classes:t.styleClasses&&(t.styleClasses=null),n===e.doc.frontier&&e.doc.frontier++}return t.styles}function Hr(e,t,n,r){var i=e.doc.mode,o=new ma(t,e.options.tabSize);for(o.start=o.pos=r||0,""==t&&Er(i,n);!o.eol();)Or(i,o,n),o.start=o.pos}function Wr(e,t){if(!e||/^\s*$/.test(e))return null;var n=t.addModeClass?ka:wa;return n[e]||(n[e]=e.replace(/\S+/g,"cm-$&"))}function Br(e,t){var n=ji("span",null,null,wo?"padding-right: .1px":null),r={pre:ji("pre",[n],"CodeMirror-line"),content:n,col:0,pos:0,cm:e,splitSpaces:(xo||wo)&&e.getOption("lineWrapping")};t.measure={};for(var i=0;i<=(t.rest?t.rest.length:0);i++){var o,a=i?t.rest[i-1]:t.line;r.pos=0,r.addToken=Fr,Ji(e.display.measure)&&(o=ii(a))&&(r.addToken=jr(r.addToken,o)),r.map=[];var l=t!=e.display.externalMeasured&&ti(a);qr(a,r,Dr(e,a,l)),a.styleClasses&&(a.styleClasses.bgClass&&(r.bgClass=$i(a.styleClasses.bgClass,r.bgClass||"")),a.styleClasses.textClass&&(r.textClass=$i(a.styleClasses.textClass,r.textClass||""))),0==r.map.length&&r.map.push(0,0,r.content.appendChild(Zi(e.display.measure))),0==i?(t.measure.map=r.map,t.measure.cache={}):((t.measure.maps||(t.measure.maps=[])).push(r.map),(t.measure.caches||(t.measure.caches=[])).push({}))}if(wo){var s=r.content.lastChild;(/\bcm-tab\b/.test(s.className)||s.querySelector&&s.querySelector(".cm-tab"))&&(r.content.className="cm-tab-wrap-hack")}return Pa(e,"renderLine",e,t.line,r.pre),r.pre.className&&(r.textClass=$i(r.pre.className,r.textClass||"")),r}function _r(e){var t=ji("span","•","cm-invalidchar");return t.title="\\u"+e.charCodeAt(0).toString(16),t.setAttribute("aria-label",t.title),t}function Fr(e,t,n,r,i,o,a){if(t){var l=e.splitSpaces?t.replace(/ {3,}/g,zr):t,s=e.cm.state.specialChars,c=!1;if(s.test(t))for(var u=document.createDocumentFragment(),f=0;;){s.lastIndex=f;var h=s.exec(t),d=h?h.index-f:t.length-f;if(d){var p=document.createTextNode(l.slice(f,f+d));xo&&9>bo?u.appendChild(ji("span",[p])):u.appendChild(p),e.map.push(e.pos,e.pos+d,p),e.col+=d,e.pos+=d}if(!h)break;if(f+=d+1,"	"==h[0]){var m=e.cm.options.tabSize,g=m-e.col%m,p=u.appendChild(ji("span",Oi(g),"cm-tab"));p.setAttribute("role","presentation"),p.setAttribute("cm-text","	"),e.col+=g}else if("\r"==h[0]||"\n"==h[0]){var p=u.appendChild(ji("span","\r"==h[0]?"␍":"␤","cm-invalidchar"));p.setAttribute("cm-text",h[0]),e.col+=1}else{var p=e.cm.options.specialCharPlaceholder(h[0]);p.setAttribute("cm-text",h[0]),xo&&9>bo?u.appendChild(ji("span",[p])):u.appendChild(p),e.col+=1}e.map.push(e.pos,e.pos+1,p),e.pos++}else{e.col+=t.length;var u=document.createTextNode(l);e.map.push(e.pos,e.pos+t.length,u),xo&&9>bo&&(c=!0),e.pos+=t.length}if(n||r||i||c||a){var v=n||"";r&&(v+=r),i&&(v+=i);var y=ji("span",[u],v,a);return o&&(y.title=o),e.content.appendChild(y)}e.content.appendChild(u)}}function zr(e){for(var t=" ",n=0;n<e.length-2;++n)t+=n%2?" ":" ";return t+=" "}function jr(e,t){return function(n,r,i,o,a,l,s){i=i?i+" cm-force-border":"cm-force-border";for(var c=n.pos,u=c+r.length;;){for(var f=0;f<t.length;f++){var h=t[f];if(h.to>c&&h.from<=c)break}if(h.to>=u)return e(n,r,i,o,a,l,s);e(n,r.slice(0,h.to-c),i,o,null,l,s),o=null,r=r.slice(h.to-c),c=h.to}}}function Ur(e,t,n,r){var i=!r&&n.widgetNode;i&&e.map.push(e.pos,e.pos+t,i),!r&&e.cm.display.input.needsContentAttribute&&(i||(i=e.content.appendChild(document.createElement("span"))),i.setAttribute("cm-marker",n.id)),i&&(e.cm.display.input.setUneditable(i),e.content.appendChild(i)),e.pos+=t}function qr(e,t,n){var r=e.markedSpans,i=e.text,o=0;if(r)for(var a,l,s,c,u,f,h,d=i.length,p=0,m=1,g="",v=0;;){if(v==p){s=c=u=f=l="",h=null,v=1/0;for(var y,x=[],b=0;b<r.length;++b){var w=r[b],k=w.marker;"bookmark"==k.type&&w.from==p&&k.widgetNode?x.push(k):w.from<=p&&(null==w.to||w.to>p||k.collapsed&&w.to==p&&w.from==p)?(null!=w.to&&w.to!=p&&v>w.to&&(v=w.to,c=""),k.className&&(s+=" "+k.className),k.css&&(l=(l?l+";":"")+k.css),k.startStyle&&w.from==p&&(u+=" "+k.startStyle),k.endStyle&&w.to==v&&(y||(y=[])).push(k.endStyle,w.to),k.title&&!f&&(f=k.title),k.collapsed&&(!h||dr(h.marker,k)<0)&&(h=w)):w.from>p&&v>w.from&&(v=w.from)}if(y)for(var b=0;b<y.length;b+=2)y[b+1]==v&&(c+=" "+y[b]);if(!h||h.from==p)for(var b=0;b<x.length;++b)Ur(t,0,x[b]);if(h&&(h.from||0)==p){if(Ur(t,(null==h.to?d+1:h.to)-p,h.marker,null==h.from),null==h.to)return;h.to==p&&(h=!1)}}if(p>=d)break;for(var S=Math.min(d,v);;){if(g){var C=p+g.length;if(!h){var L=C>S?g.slice(0,S-p):g;t.addToken(t,L,a?a+s:s,u,p+L.length==v?c:"",f,l)}if(C>=S){g=g.slice(S-p),p=S;break}p=C,u=""}g=i.slice(o,o=n[m++]),a=Wr(n[m++],t.cm.options)}}else for(var m=1;m<n.length;m+=2)t.addToken(t,i.slice(o,o=n[m]),Wr(n[m+1],t.cm.options))}function Gr(e,t){return 0==t.from.ch&&0==t.to.ch&&""==Ii(t.text)&&(!e.cm||e.cm.options.wholeLineUpdateBefore)}function Yr(e,t,n,r){function i(e){return n?n[e]:null}function o(e,n,i){Mr(e,n,i,r),Ci(e,"change",e,t)}function a(e,t){for(var n=e,o=[];t>n;++n)o.push(new ba(c[n],i(n),r));return o}var l=t.from,s=t.to,c=t.text,u=Zr(e,l.line),f=Zr(e,s.line),h=Ii(c),d=i(c.length-1),p=s.line-l.line;if(t.full)e.insert(0,a(0,c.length)),e.remove(c.length,e.size-c.length);else if(Gr(e,t)){var m=a(0,c.length-1);o(f,f.text,d),p&&e.remove(l.line,p),m.length&&e.insert(l.line,m)}else if(u==f)if(1==c.length)o(u,u.text.slice(0,l.ch)+h+u.text.slice(s.ch),d);else{var m=a(1,c.length-1);m.push(new ba(h+u.text.slice(s.ch),d,r)),o(u,u.text.slice(0,l.ch)+c[0],i(0)),e.insert(l.line+1,m)}else if(1==c.length)o(u,u.text.slice(0,l.ch)+c[0]+f.text.slice(s.ch),i(0)),e.remove(l.line+1,p);else{o(u,u.text.slice(0,l.ch)+c[0],i(0)),o(f,h+f.text.slice(s.ch),d);var m=a(1,c.length-1);p>1&&e.remove(l.line+1,p-1),e.insert(l.line+1,m)}Ci(e,"change",e,t)}function $r(e){this.lines=e,this.parent=null;for(var t=0,n=0;t<e.length;++t)e[t].parent=this,n+=e[t].height;this.height=n}function Vr(e){this.children=e;for(var t=0,n=0,r=0;r<e.length;++r){var i=e[r];t+=i.chunkSize(),n+=i.height,i.parent=this}this.size=t,this.height=n,this.parent=null}function Kr(e,t,n){function r(e,i,o){if(e.linked)for(var a=0;a<e.linked.length;++a){var l=e.linked[a];if(l.doc!=i){var s=o&&l.sharedHist;n&&!s||(t(l.doc,s),r(l.doc,e,s))}}}r(e,null,!0)}function Xr(e,t){if(t.cm)throw new Error("This document is already in use.");e.doc=t,t.cm=e,a(e),n(e),e.options.lineWrapping||h(e),e.options.mode=t.modeOption,Dt(e)}function Zr(e,t){if(t-=e.first,0>t||t>=e.size)throw new Error("There is no line "+(t+e.first)+" in the document.");for(var n=e;!n.lines;)for(var r=0;;++r){var i=n.children[r],o=i.chunkSize();if(o>t){n=i;break}t-=o}return n.lines[t]}function Jr(e,t,n){var r=[],i=t.line;return e.iter(t.line,n.line+1,function(e){var o=e.text;i==n.line&&(o=o.slice(0,n.ch)),i==t.line&&(o=o.slice(t.ch)),r.push(o),++i}),r}function Qr(e,t,n){var r=[];return e.iter(t,n,function(e){r.push(e.text)}),r}function ei(e,t){var n=t-e.height;if(n)for(var r=e;r;r=r.parent)r.height+=n}function ti(e){if(null==e.parent)return null;for(var t=e.parent,n=Pi(t.lines,e),r=t.parent;r;t=r,r=r.parent)for(var i=0;r.children[i]!=t;++i)n+=r.children[i].chunkSize();return n+t.first}function ni(e,t){var n=e.first;e:do{for(var r=0;r<e.children.length;++r){var i=e.children[r],o=i.height;if(o>t){e=i;continue e}t-=o,n+=i.chunkSize()}return n}while(!e.lines);for(var r=0;r<e.lines.length;++r){var a=e.lines[r],l=a.height;if(l>t)break;t-=l}return n+r}function ri(e){e=yr(e);for(var t=0,n=e.parent,r=0;r<n.lines.length;++r){var i=n.lines[r];if(i==e)break;t+=i.height}for(var o=n.parent;o;n=o,o=n.parent)for(var r=0;r<o.children.length;++r){var a=o.children[r];if(a==n)break;t+=a.height}return t}function ii(e){var t=e.order;return null==t&&(t=e.order=ll(e.text)),t}function oi(e){this.done=[],this.undone=[],this.undoDepth=1/0,this.lastModTime=this.lastSelTime=0,this.lastOp=this.lastSelOp=null,this.lastOrigin=this.lastSelOrigin=null,this.generation=this.maxGeneration=e||1}function ai(e,t){var n={from:$(t.from),to:Qo(t),text:Jr(e,t.from,t.to)};return di(e,n,t.from.line,t.to.line+1),Kr(e,function(e){di(e,n,t.from.line,t.to.line+1)},!0),n}function li(e){for(;e.length;){var t=Ii(e);if(!t.ranges)break;e.pop()}}function si(e,t){return t?(li(e.done),Ii(e.done)):e.done.length&&!Ii(e.done).ranges?Ii(e.done):e.done.length>1&&!e.done[e.done.length-2].ranges?(e.done.pop(),Ii(e.done)):void 0}function ci(e,t,n,r){var i=e.history;i.undone.length=0;var o,a=+new Date;if((i.lastOp==r||i.lastOrigin==t.origin&&t.origin&&("+"==t.origin.charAt(0)&&e.cm&&i.lastModTime>a-e.cm.options.historyEventDelay||"*"==t.origin.charAt(0)))&&(o=si(i,i.lastOp==r))){var l=Ii(o.changes);0==_o(t.from,t.to)&&0==_o(t.from,l.to)?l.to=Qo(t):o.changes.push(ai(e,t))}else{var s=Ii(i.done);for(s&&s.ranges||hi(e.sel,i.done),o={changes:[ai(e,t)],generation:i.generation},i.done.push(o);i.done.length>i.undoDepth;)i.done.shift(),i.done[0].ranges||i.done.shift()}i.done.push(n),i.generation=++i.maxGeneration,i.lastModTime=i.lastSelTime=a,i.lastOp=i.lastSelOp=r,i.lastOrigin=i.lastSelOrigin=t.origin,l||Pa(e,"historyAdded")}function ui(e,t,n,r){var i=t.charAt(0);return"*"==i||"+"==i&&n.ranges.length==r.ranges.length&&n.somethingSelected()==r.somethingSelected()&&new Date-e.history.lastSelTime<=(e.cm?e.cm.options.historyEventDelay:500)}function fi(e,t,n,r){var i=e.history,o=r&&r.origin;n==i.lastSelOp||o&&i.lastSelOrigin==o&&(i.lastModTime==i.lastSelTime&&i.lastOrigin==o||ui(e,o,Ii(i.done),t))?i.done[i.done.length-1]=t:hi(t,i.done),i.lastSelTime=+new Date,i.lastSelOrigin=o,i.lastSelOp=n,r&&r.clearRedo!==!1&&li(i.undone)}function hi(e,t){var n=Ii(t);n&&n.ranges&&n.equals(e)||t.push(e)}function di(e,t,n,r){var i=t["spans_"+e.id],o=0;e.iter(Math.max(e.first,n),Math.min(e.first+e.size,r),function(n){n.markedSpans&&((i||(i=t["spans_"+e.id]={}))[o]=n.markedSpans),++o})}function pi(e){if(!e)return null;for(var t,n=0;n<e.length;++n)e[n].marker.explicitlyCleared?t||(t=e.slice(0,n)):t&&t.push(e[n]);return t?t.length?t:null:e}function mi(e,t){var n=t["spans_"+e.id];if(!n)return null;for(var r=0,i=[];r<t.text.length;++r)i.push(pi(n[r]));return i}function gi(e,t,n){for(var r=0,i=[];r<e.length;++r){var o=e[r];if(o.ranges)i.push(n?ue.prototype.deepCopy.call(o):o);else{var a=o.changes,l=[];i.push({changes:l});for(var s=0;s<a.length;++s){var c,u=a[s];if(l.push({from:u.from,to:u.to,text:u.text}),t)for(var f in u)(c=f.match(/^spans_(\d+)$/))&&Pi(t,Number(c[1]))>-1&&(Ii(l)[f]=u[f],delete u[f])}}}return i}function vi(e,t,n,r){n<e.line?e.line+=r:t<e.line&&(e.line=t,e.ch=0)}function yi(e,t,n,r){for(var i=0;i<e.length;++i){var o=e[i],a=!0;if(o.ranges){o.copied||(o=e[i]=o.deepCopy(),o.copied=!0);for(var l=0;l<o.ranges.length;l++)vi(o.ranges[l].anchor,t,n,r),vi(o.ranges[l].head,t,n,r)}else{for(var l=0;l<o.changes.length;++l){var s=o.changes[l];if(n<s.from.line)s.from=Bo(s.from.line+r,s.from.ch),s.to=Bo(s.to.line+r,s.to.ch);else if(t<=s.to.line){a=!1;break}}a||(e.splice(0,i+1),i=0)}}}function xi(e,t){var n=t.from.line,r=t.to.line,i=t.text.length-(r-n)-1;yi(e.done,n,r,i),yi(e.undone,n,r,i)}function bi(e){return null!=e.defaultPrevented?e.defaultPrevented:0==e.returnValue}function wi(e){return e.target||e.srcElement}function ki(e){var t=e.which;return null==t&&(1&e.button?t=1:2&e.button?t=3:4&e.button&&(t=2)),Eo&&e.ctrlKey&&1==t&&(t=3),t}function Si(e,t,n){var r=e._handlers&&e._handlers[t];return n?r&&r.length>0?r.slice():Oa:r||Oa}function Ci(e,t){function n(e){return function(){e.apply(null,o)}}var r=Si(e,t,!1);if(r.length){var i,o=Array.prototype.slice.call(arguments,2);Go?i=Go.delayedCallbacks:Ra?i=Ra:(i=Ra=[],setTimeout(Li,0));for(var a=0;a<r.length;++a)i.push(n(r[a]))}}function Li(){var e=Ra;Ra=null;for(var t=0;t<e.length;++t)e[t]()}function Ti(e,t,n){return"string"==typeof t&&(t={type:t,preventDefault:function(){this.defaultPrevented=!0}}),Pa(e,n||t.type,e,t),bi(t)||t.codemirrorIgnore}function Mi(e){var t=e._handlers&&e._handlers.cursorActivity;if(t)for(var n=e.curOp.cursorActivityHandlers||(e.curOp.cursorActivityHandlers=[]),r=0;r<t.length;++r)-1==Pi(n,t[r])&&n.push(t[r])}function Ni(e,t){return Si(e,t).length>0}function Ai(e){e.prototype.on=function(e,t){Ea(this,e,t)},e.prototype.off=function(e,t){Ia(this,e,t)}}function Ei(){this.id=null}function Oi(e){for(;ja.length<=e;)ja.push(Ii(ja)+" ");return ja[e]}function Ii(e){return e[e.length-1]}function Pi(e,t){for(var n=0;n<e.length;++n)if(e[n]==t)return n;return-1}function Ri(e,t){for(var n=[],r=0;r<e.length;r++)n[r]=t(e[r],r);return n}function Di(){}function Hi(e,t){var n;return Object.create?n=Object.create(e):(Di.prototype=e,n=new Di),t&&Wi(t,n),n}function Wi(e,t,n){t||(t={});for(var r in e)!e.hasOwnProperty(r)||n===!1&&t.hasOwnProperty(r)||(t[r]=e[r]);return t}function Bi(e){var t=Array.prototype.slice.call(arguments,1);return function(){return e.apply(null,t)}}function _i(e,t){return t?t.source.indexOf("\\w")>-1&&Ya(e)?!0:t.test(e):Ya(e)}function Fi(e){for(var t in e)if(e.hasOwnProperty(t)&&e[t])return!1;return!0}function zi(e){return e.charCodeAt(0)>=768&&$a.test(e)}function ji(e,t,n,r){var i=document.createElement(e);if(n&&(i.className=n),r&&(i.style.cssText=r),"string"==typeof t)i.appendChild(document.createTextNode(t));else if(t)for(var o=0;o<t.length;++o)i.appendChild(t[o]);return i}function Ui(e){for(var t=e.childNodes.length;t>0;--t)e.removeChild(e.firstChild);return e}function qi(e,t){return Ui(e).appendChild(t)}function Gi(){for(var e=document.activeElement;e&&e.root&&e.root.activeElement;)e=e.root.activeElement;return e}function Yi(e){return new RegExp("(^|\\s)"+e+"(?:$|\\s)\\s*")}function $i(e,t){for(var n=e.split(" "),r=0;r<n.length;r++)n[r]&&!Yi(n[r]).test(t)&&(t+=" "+n[r]);return t}function Vi(e){if(document.body.getElementsByClassName)for(var t=document.body.getElementsByClassName("CodeMirror"),n=0;n<t.length;n++){var r=t[n].CodeMirror;r&&e(r)}}function Ki(){Qa||(Xi(),Qa=!0)}function Xi(){var e;Ea(window,"resize",function(){null==e&&(e=setTimeout(function(){e=null,Vi(qt)},100))}),Ea(window,"blur",function(){Vi(yn)})}function Zi(e){if(null==Ka){var t=ji("span","​");qi(e,ji("span",[t,document.createTextNode("x")])),0!=e.firstChild.offsetHeight&&(Ka=t.offsetWidth<=1&&t.offsetHeight>2&&!(xo&&8>bo))}var n=Ka?ji("span","​"):ji("span"," ",null,"display: inline-block; width: 1px; margin-right: -1px");return n.setAttribute("cm-text",""),n}function Ji(e){if(null!=Xa)return Xa;var t=qi(e,document.createTextNode("AخA")),n=qa(t,0,1).getBoundingClientRect();if(!n||n.left==n.right)return!1;var r=qa(t,1,2).getBoundingClientRect();return Xa=r.right-n.right<3}function Qi(e){if(null!=il)return il;var t=qi(e,ji("span","x")),n=t.getBoundingClientRect(),r=qa(t,0,1).getBoundingClientRect();return il=Math.abs(n.left-r.left)>1}function eo(e,t,n,r){if(!e)return r(t,n,"ltr");for(var i=!1,o=0;o<e.length;++o){var a=e[o];(a.from<n&&a.to>t||t==n&&a.to==t)&&(r(Math.max(a.from,t),Math.min(a.to,n),1==a.level?"rtl":"ltr"),i=!0)}i||r(t,n,"ltr")}function to(e){return e.level%2?e.to:e.from}function no(e){return e.level%2?e.from:e.to}function ro(e){var t=ii(e);return t?to(t[0]):0}function io(e){var t=ii(e);return t?no(Ii(t)):e.text.length}function oo(e,t){var n=Zr(e.doc,t),r=yr(n);r!=n&&(t=ti(r));var i=ii(r),o=i?i[0].level%2?io(r):ro(r):0;return Bo(t,o)}function ao(e,t){for(var n,r=Zr(e.doc,t);n=gr(r);)r=n.find(1,!0).line,t=null;var i=ii(r),o=i?i[0].level%2?ro(r):io(r):r.text.length;return Bo(null==t?ti(r):t,o)}function lo(e,t){var n=oo(e,t.line),r=Zr(e.doc,n.line),i=ii(r);if(!i||0==i[0].level){var o=Math.max(0,r.text.search(/\S/)),a=t.line==n.line&&t.ch<=o&&t.ch;return Bo(n.line,a?0:o)}return n}function so(e,t,n){var r=e[0].level;return t==r?!0:n==r?!1:n>t}function co(e,t){al=null;for(var n,r=0;r<e.length;++r){var i=e[r];if(i.from<t&&i.to>t)return r;if(i.from==t||i.to==t){if(null!=n)return so(e,i.level,e[n].level)?(i.from!=i.to&&(al=n),r):(i.from!=i.to&&(al=r),n);n=r}}return n}function uo(e,t,n,r){if(!r)return t+n;do t+=n;while(t>0&&zi(e.text.charAt(t)));return t}function fo(e,t,n,r){var i=ii(e);if(!i)return ho(e,t,n,r);for(var o=co(i,t),a=i[o],l=uo(e,t,a.level%2?-n:n,r);;){if(l>a.from&&l<a.to)return l;if(l==a.from||l==a.to)return co(i,l)==o?l:(a=i[o+=n],n>0==a.level%2?a.to:a.from);if(a=i[o+=n],!a)return null;l=n>0==a.level%2?uo(e,a.to,-1,r):uo(e,a.from,1,r)}}function ho(e,t,n,r){var i=t+n;if(r)for(;i>0&&zi(e.text.charAt(i));)i+=n;return 0>i||i>e.text.length?null:i}var po=navigator.userAgent,mo=navigator.platform,go=/gecko\/\d/i.test(po),vo=/MSIE \d/.test(po),yo=/Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(po),xo=vo||yo,bo=xo&&(vo?document.documentMode||6:yo[1]),wo=/WebKit\//.test(po),ko=wo&&/Qt\/\d+\.\d+/.test(po),So=/Chrome\//.test(po),Co=/Opera\//.test(po),Lo=/Apple Computer/.test(navigator.vendor),To=/Mac OS X 1\d\D([8-9]|\d\d)\D/.test(po),Mo=/PhantomJS/.test(po),No=/AppleWebKit/.test(po)&&/Mobile\/\w+/.test(po),Ao=No||/Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(po),Eo=No||/Mac/.test(mo),Oo=/\bCrOS\b/.test(po),Io=/win/i.test(mo),Po=Co&&po.match(/Version\/(\d*\.\d*)/);Po&&(Po=Number(Po[1])),Po&&Po>=15&&(Co=!1,wo=!0);var Ro=Eo&&(ko||Co&&(null==Po||12.11>Po)),Do=go||xo&&bo>=9,Ho=!1,Wo=!1;m.prototype=Wi({update:function(e){var t=e.scrollWidth>e.clientWidth+1,n=e.scrollHeight>e.clientHeight+1,r=e.nativeBarWidth;if(n){this.vert.style.display="block",this.vert.style.bottom=t?r+"px":"0";var i=e.viewHeight-(t?r:0);this.vert.firstChild.style.height=Math.max(0,e.scrollHeight-e.clientHeight+i)+"px"}else this.vert.style.display="",this.vert.firstChild.style.height="0";if(t){this.horiz.style.display="block",this.horiz.style.right=n?r+"px":"0",this.horiz.style.left=e.barLeft+"px";var o=e.viewWidth-e.barLeft-(n?r:0);this.horiz.firstChild.style.width=e.scrollWidth-e.clientWidth+o+"px"}else this.horiz.style.display="",this.horiz.firstChild.style.width="0";return!this.checkedZeroWidth&&e.clientHeight>0&&(0==r&&this.zeroWidthHack(),this.checkedZeroWidth=!0),{right:n?r:0,bottom:t?r:0}},setScrollLeft:function(e){this.horiz.scrollLeft!=e&&(this.horiz.scrollLeft=e),this.disableHoriz&&this.enableZeroWidthBar(this.horiz,this.disableHoriz)},setScrollTop:function(e){this.vert.scrollTop!=e&&(this.vert.scrollTop=e),this.disableVert&&this.enableZeroWidthBar(this.vert,this.disableVert)},zeroWidthHack:function(){var e=Eo&&!To?"12px":"18px";this.horiz.style.height=this.vert.style.width=e,this.horiz.style.pointerEvents=this.vert.style.pointerEvents="none",this.disableHoriz=new Ei,this.disableVert=new Ei},enableZeroWidthBar:function(e,t){function n(){var r=e.getBoundingClientRect(),i=document.elementFromPoint(r.left+1,r.bottom-1);i!=e?e.style.pointerEvents="none":t.set(1e3,n)}e.style.pointerEvents="auto",t.set(1e3,n)},clear:function(){var e=this.horiz.parentNode;e.removeChild(this.horiz),e.removeChild(this.vert)}},m.prototype),g.prototype=Wi({update:function(){return{bottom:0,right:0}},setScrollLeft:function(){},setScrollTop:function(){},clear:function(){}},g.prototype),e.scrollbarModel={"native":m,"null":g},L.prototype.signal=function(e,t){Ni(e,t)&&this.events.push(arguments)},L.prototype.finish=function(){for(var e=0;e<this.events.length;e++)Pa.apply(null,this.events[e])};var Bo=e.Pos=function(e,t){return this instanceof Bo?(this.line=e,void(this.ch=t)):new Bo(e,t)},_o=e.cmpPos=function(e,t){return e.line-t.line||e.ch-t.ch},Fo=null;ne.prototype=Wi({init:function(e){function t(e){if(!Ti(r,e)){if(r.somethingSelected())Fo={lineWise:!1,text:r.getSelections()},n.inaccurateSelection&&(n.prevInput="",n.inaccurateSelection=!1,o.value=Fo.text.join("\n"),Ua(o));else{if(!r.options.lineWiseCopyCut)return;var t=ee(r);Fo={lineWise:!0,text:t.text},"cut"==e.type?r.setSelections(t.ranges,null,Wa):(n.prevInput="",o.value=t.text.join("\n"),Ua(o))}"cut"==e.type&&(r.state.cutIncoming=!0)}}var n=this,r=this.cm,i=this.wrapper=re(),o=this.textarea=i.firstChild;e.wrapper.insertBefore(i,e.wrapper.firstChild),No&&(o.style.width="0px"),Ea(o,"input",function(){xo&&bo>=9&&n.hasSelection&&(n.hasSelection=null),n.poll()}),Ea(o,"paste",function(e){Ti(r,e)||J(e,r)||(r.state.pasteIncoming=!0,n.fastPoll())}),Ea(o,"cut",t),Ea(o,"copy",t),Ea(e.scroller,"paste",function(t){Gt(e,t)||Ti(r,t)||(r.state.pasteIncoming=!0,n.focus())}),Ea(e.lineSpace,"selectstart",function(t){Gt(e,t)||Ma(t)}),Ea(o,"compositionstart",function(){var e=r.getCursor("from");n.composing&&n.composing.range.clear(),n.composing={start:e,range:r.markText(e,r.getCursor("to"),{className:"CodeMirror-composing"})}}),Ea(o,"compositionend",function(){n.composing&&(n.poll(),n.composing.range.clear(),n.composing=null)})},prepareSelection:function(){var e=this.cm,t=e.display,n=e.doc,r=De(e);if(e.options.moveInputWithCursor){var i=dt(e,n.sel.primary().head,"div"),o=t.wrapper.getBoundingClientRect(),a=t.lineDiv.getBoundingClientRect();r.teTop=Math.max(0,Math.min(t.wrapper.clientHeight-10,i.top+a.top-o.top)),r.teLeft=Math.max(0,Math.min(t.wrapper.clientWidth-10,i.left+a.left-o.left))}return r},showSelection:function(e){var t=this.cm,n=t.display;qi(n.cursorDiv,e.cursors),qi(n.selectionDiv,e.selection),null!=e.teTop&&(this.wrapper.style.top=e.teTop+"px",this.wrapper.style.left=e.teLeft+"px")},reset:function(e){if(!this.contextMenuPending){var t,n,r=this.cm,i=r.doc;if(r.somethingSelected()){this.prevInput="";var o=i.sel.primary();t=rl&&(o.to().line-o.from().line>100||(n=r.getSelection()).length>1e3);var a=t?"-":n||r.getSelection();this.textarea.value=a,r.state.focused&&Ua(this.textarea),xo&&bo>=9&&(this.hasSelection=a)}else e||(this.prevInput=this.textarea.value="",xo&&bo>=9&&(this.hasSelection=null));this.inaccurateSelection=t}},getField:function(){return this.textarea},supportsTouch:function(){return!1},focus:function(){if("nocursor"!=this.cm.options.readOnly&&(!Ao||Gi()!=this.textarea))try{this.textarea.focus()}catch(e){}},blur:function(){this.textarea.blur()},resetPosition:function(){this.wrapper.style.top=this.wrapper.style.left=0;
61893},receivedFocus:function(){this.slowPoll()},slowPoll:function(){var e=this;e.pollingFast||e.polling.set(this.cm.options.pollInterval,function(){e.poll(),e.cm.state.focused&&e.slowPoll()})},fastPoll:function(){function e(){var r=n.poll();r||t?(n.pollingFast=!1,n.slowPoll()):(t=!0,n.polling.set(60,e))}var t=!1,n=this;n.pollingFast=!0,n.polling.set(20,e)},poll:function(){var e=this.cm,t=this.textarea,n=this.prevInput;if(this.contextMenuPending||!e.state.focused||nl(t)&&!n&&!this.composing||e.isReadOnly()||e.options.disableInput||e.state.keySeq)return!1;var r=t.value;if(r==n&&!e.somethingSelected())return!1;if(xo&&bo>=9&&this.hasSelection===r||Eo&&/[\uf700-\uf7ff]/.test(r))return e.display.input.reset(),!1;if(e.doc.sel==e.display.selForContextMenu){var i=r.charCodeAt(0);if(8203!=i||n||(n="​"),8666==i)return this.reset(),this.cm.execCommand("undo")}for(var o=0,a=Math.min(n.length,r.length);a>o&&n.charCodeAt(o)==r.charCodeAt(o);)++o;var l=this;return At(e,function(){Z(e,r.slice(o),n.length-o,null,l.composing?"*compose":null),r.length>1e3||r.indexOf("\n")>-1?t.value=l.prevInput="":l.prevInput=r,l.composing&&(l.composing.range.clear(),l.composing.range=e.markText(l.composing.start,e.getCursor("to"),{className:"CodeMirror-composing"}))}),!0},ensurePolled:function(){this.pollingFast&&this.poll()&&(this.pollingFast=!1)},onKeyPress:function(){xo&&bo>=9&&(this.hasSelection=null),this.fastPoll()},onContextMenu:function(e){function t(){if(null!=a.selectionStart){var e=i.somethingSelected(),t="​"+(e?a.value:"");a.value="⇚",a.value=t,r.prevInput=e?"":"​",a.selectionStart=1,a.selectionEnd=t.length,o.selForContextMenu=i.doc.sel}}function n(){if(r.contextMenuPending=!1,r.wrapper.style.cssText=f,a.style.cssText=u,xo&&9>bo&&o.scrollbars.setScrollTop(o.scroller.scrollTop=s),null!=a.selectionStart){(!xo||xo&&9>bo)&&t();var e=0,n=function(){o.selForContextMenu==i.doc.sel&&0==a.selectionStart&&a.selectionEnd>0&&"​"==r.prevInput?Et(i,ua.selectAll)(i):e++<10?o.detectingSelectAll=setTimeout(n,500):o.input.reset()};o.detectingSelectAll=setTimeout(n,200)}}var r=this,i=r.cm,o=i.display,a=r.textarea,l=Yt(i,e),s=o.scroller.scrollTop;if(l&&!Co){var c=i.options.resetSelectionOnContextMenu;c&&-1==i.doc.sel.contains(l)&&Et(i,Te)(i.doc,de(l),Wa);var u=a.style.cssText,f=r.wrapper.style.cssText;r.wrapper.style.cssText="position: absolute";var h=r.wrapper.getBoundingClientRect();if(a.style.cssText="position: absolute; width: 30px; height: 30px; top: "+(e.clientY-h.top-5)+"px; left: "+(e.clientX-h.left-5)+"px; z-index: 1000; background: "+(xo?"rgba(255, 255, 255, .05)":"transparent")+"; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);",wo)var d=window.scrollY;if(o.input.focus(),wo&&window.scrollTo(null,d),o.input.reset(),i.somethingSelected()||(a.value=r.prevInput=" "),r.contextMenuPending=!0,o.selForContextMenu=i.doc.sel,clearTimeout(o.detectingSelectAll),xo&&bo>=9&&t(),Do){Aa(e);var p=function(){Ia(window,"mouseup",p),setTimeout(n,20)};Ea(window,"mouseup",p)}else setTimeout(n,50)}},readOnlyChanged:function(e){e||this.reset()},setUneditable:Di,needsContentAttribute:!1},ne.prototype),ie.prototype=Wi({init:function(e){function t(e){if(!Ti(r,e)){if(r.somethingSelected())Fo={lineWise:!1,text:r.getSelections()},"cut"==e.type&&r.replaceSelection("",null,"cut");else{if(!r.options.lineWiseCopyCut)return;var t=ee(r);Fo={lineWise:!0,text:t.text},"cut"==e.type&&r.operation(function(){r.setSelections(t.ranges,0,Wa),r.replaceSelection("",null,"cut")})}if(e.clipboardData&&!No)e.preventDefault(),e.clipboardData.clearData(),e.clipboardData.setData("text/plain",Fo.text.join("\n"));else{var n=re(),i=n.firstChild;r.display.lineSpace.insertBefore(n,r.display.lineSpace.firstChild),i.value=Fo.text.join("\n");var o=document.activeElement;Ua(i),setTimeout(function(){r.display.lineSpace.removeChild(n),o.focus()},50)}}}var n=this,r=n.cm,i=n.div=e.lineDiv;te(i),Ea(i,"paste",function(e){Ti(r,e)||J(e,r)}),Ea(i,"compositionstart",function(e){var t=e.data;if(n.composing={sel:r.doc.sel,data:t,startData:t},t){var i=r.doc.sel.primary(),o=r.getLine(i.head.line),a=o.indexOf(t,Math.max(0,i.head.ch-t.length));a>-1&&a<=i.head.ch&&(n.composing.sel=de(Bo(i.head.line,a),Bo(i.head.line,a+t.length)))}}),Ea(i,"compositionupdate",function(e){n.composing.data=e.data}),Ea(i,"compositionend",function(e){var t=n.composing;t&&(e.data==t.startData||/\u200b/.test(e.data)||(t.data=e.data),setTimeout(function(){t.handled||n.applyComposition(t),n.composing==t&&(n.composing=null)},50))}),Ea(i,"touchstart",function(){n.forceCompositionEnd()}),Ea(i,"input",function(){n.composing||!r.isReadOnly()&&n.pollContent()||At(n.cm,function(){Dt(r)})}),Ea(i,"copy",t),Ea(i,"cut",t)},prepareSelection:function(){var e=De(this.cm,!1);return e.focus=this.cm.state.focused,e},showSelection:function(e,t){e&&this.cm.display.view.length&&((e.focus||t)&&this.showPrimarySelection(),this.showMultipleSelections(e))},showPrimarySelection:function(){var e=window.getSelection(),t=this.cm.doc.sel.primary(),n=le(this.cm,e.anchorNode,e.anchorOffset),r=le(this.cm,e.focusNode,e.focusOffset);if(!n||n.bad||!r||r.bad||0!=_o(K(n,r),t.from())||0!=_o(V(n,r),t.to())){var i=oe(this.cm,t.from()),o=oe(this.cm,t.to());if(i||o){var a=this.cm.display.view,l=e.rangeCount&&e.getRangeAt(0);if(i){if(!o){var s=a[a.length-1].measure,c=s.maps?s.maps[s.maps.length-1]:s.map;o={node:c[c.length-1],offset:c[c.length-2]-c[c.length-3]}}}else i={node:a[0].measure.map[2],offset:0};try{var u=qa(i.node,i.offset,o.offset,o.node)}catch(f){}u&&(!go&&this.cm.state.focused?(e.collapse(i.node,i.offset),u.collapsed||e.addRange(u)):(e.removeAllRanges(),e.addRange(u)),l&&null==e.anchorNode?e.addRange(l):go&&this.startGracePeriod()),this.rememberSelection()}}},startGracePeriod:function(){var e=this;clearTimeout(this.gracePeriod),this.gracePeriod=setTimeout(function(){e.gracePeriod=!1,e.selectionChanged()&&e.cm.operation(function(){e.cm.curOp.selectionChanged=!0})},20)},showMultipleSelections:function(e){qi(this.cm.display.cursorDiv,e.cursors),qi(this.cm.display.selectionDiv,e.selection)},rememberSelection:function(){var e=window.getSelection();this.lastAnchorNode=e.anchorNode,this.lastAnchorOffset=e.anchorOffset,this.lastFocusNode=e.focusNode,this.lastFocusOffset=e.focusOffset},selectionInEditor:function(){var e=window.getSelection();if(!e.rangeCount)return!1;var t=e.getRangeAt(0).commonAncestorContainer;return Va(this.div,t)},focus:function(){"nocursor"!=this.cm.options.readOnly&&this.div.focus()},blur:function(){this.div.blur()},getField:function(){return this.div},supportsTouch:function(){return!0},receivedFocus:function(){function e(){t.cm.state.focused&&(t.pollSelection(),t.polling.set(t.cm.options.pollInterval,e))}var t=this;this.selectionInEditor()?this.pollSelection():At(this.cm,function(){t.cm.curOp.selectionChanged=!0}),this.polling.set(this.cm.options.pollInterval,e)},selectionChanged:function(){var e=window.getSelection();return e.anchorNode!=this.lastAnchorNode||e.anchorOffset!=this.lastAnchorOffset||e.focusNode!=this.lastFocusNode||e.focusOffset!=this.lastFocusOffset},pollSelection:function(){if(!this.composing&&!this.gracePeriod&&this.selectionChanged()){var e=window.getSelection(),t=this.cm;this.rememberSelection();var n=le(t,e.anchorNode,e.anchorOffset),r=le(t,e.focusNode,e.focusOffset);n&&r&&At(t,function(){Te(t.doc,de(n,r),Wa),(n.bad||r.bad)&&(t.curOp.selectionChanged=!0)})}},pollContent:function(){var e=this.cm,t=e.display,n=e.doc.sel.primary(),r=n.from(),i=n.to();if(r.line<t.viewFrom||i.line>t.viewTo-1)return!1;var o;if(r.line==t.viewFrom||0==(o=Bt(e,r.line)))var a=ti(t.view[0].line),l=t.view[0].node;else var a=ti(t.view[o].line),l=t.view[o-1].node.nextSibling;var s=Bt(e,i.line);if(s==t.view.length-1)var c=t.viewTo-1,u=t.lineDiv.lastChild;else var c=ti(t.view[s+1].line)-1,u=t.view[s+1].node.previousSibling;for(var f=e.doc.splitLines(ce(e,l,u,a,c)),h=Jr(e.doc,Bo(a,0),Bo(c,Zr(e.doc,c).text.length));f.length>1&&h.length>1;)if(Ii(f)==Ii(h))f.pop(),h.pop(),c--;else{if(f[0]!=h[0])break;f.shift(),h.shift(),a++}for(var d=0,p=0,m=f[0],g=h[0],v=Math.min(m.length,g.length);v>d&&m.charCodeAt(d)==g.charCodeAt(d);)++d;for(var y=Ii(f),x=Ii(h),b=Math.min(y.length-(1==f.length?d:0),x.length-(1==h.length?d:0));b>p&&y.charCodeAt(y.length-p-1)==x.charCodeAt(x.length-p-1);)++p;f[f.length-1]=y.slice(0,y.length-p),f[0]=f[0].slice(d);var w=Bo(a,d),k=Bo(c,h.length?Ii(h).length-p:0);return f.length>1||f[0]||_o(w,k)?(In(e.doc,f,w,k,"+input"),!0):void 0},ensurePolled:function(){this.forceCompositionEnd()},reset:function(){this.forceCompositionEnd()},forceCompositionEnd:function(){this.composing&&!this.composing.handled&&(this.applyComposition(this.composing),this.composing.handled=!0,this.div.blur(),this.div.focus())},applyComposition:function(e){this.cm.isReadOnly()?Et(this.cm,Dt)(this.cm):e.data&&e.data!=e.startData&&Et(this.cm,Z)(this.cm,e.data,0,e.sel)},setUneditable:function(e){e.contentEditable="false"},onKeyPress:function(e){e.preventDefault(),this.cm.isReadOnly()||Et(this.cm,Z)(this.cm,String.fromCharCode(null==e.charCode?e.keyCode:e.charCode),0)},readOnlyChanged:function(e){this.div.contentEditable=String("nocursor"!=e)},onContextMenu:Di,resetPosition:Di,needsContentAttribute:!0},ie.prototype),e.inputStyles={textarea:ne,contenteditable:ie},ue.prototype={primary:function(){return this.ranges[this.primIndex]},equals:function(e){if(e==this)return!0;if(e.primIndex!=this.primIndex||e.ranges.length!=this.ranges.length)return!1;for(var t=0;t<this.ranges.length;t++){var n=this.ranges[t],r=e.ranges[t];if(0!=_o(n.anchor,r.anchor)||0!=_o(n.head,r.head))return!1}return!0},deepCopy:function(){for(var e=[],t=0;t<this.ranges.length;t++)e[t]=new fe($(this.ranges[t].anchor),$(this.ranges[t].head));return new ue(e,this.primIndex)},somethingSelected:function(){for(var e=0;e<this.ranges.length;e++)if(!this.ranges[e].empty())return!0;return!1},contains:function(e,t){t||(t=e);for(var n=0;n<this.ranges.length;n++){var r=this.ranges[n];if(_o(t,r.from())>=0&&_o(e,r.to())<=0)return n}return-1}},fe.prototype={from:function(){return K(this.anchor,this.head)},to:function(){return V(this.anchor,this.head)},empty:function(){return this.head.line==this.anchor.line&&this.head.ch==this.anchor.ch}};var zo,jo,Uo,qo={left:0,right:0,top:0,bottom:0},Go=null,Yo=0,$o=0,Vo=0,Ko=null;xo?Ko=-.53:go?Ko=15:So?Ko=-.7:Lo&&(Ko=-1/3);var Xo=function(e){var t=e.wheelDeltaX,n=e.wheelDeltaY;return null==t&&e.detail&&e.axis==e.HORIZONTAL_AXIS&&(t=e.detail),null==n&&e.detail&&e.axis==e.VERTICAL_AXIS?n=e.detail:null==n&&(n=e.wheelDelta),{x:t,y:n}};e.wheelEventPixels=function(e){var t=Xo(e);return t.x*=Ko,t.y*=Ko,t};var Zo=new Ei,Jo=null,Qo=e.changeEnd=function(e){return e.text?Bo(e.from.line+e.text.length-1,Ii(e.text).length+(1==e.text.length?e.from.ch:0)):e.to};e.prototype={constructor:e,focus:function(){window.focus(),this.display.input.focus()},setOption:function(e,t){var n=this.options,r=n[e];n[e]==t&&"mode"!=e||(n[e]=t,ta.hasOwnProperty(e)&&Et(this,ta[e])(this,t,r))},getOption:function(e){return this.options[e]},getDoc:function(){return this.doc},addKeyMap:function(e,t){this.state.keyMaps[t?"push":"unshift"]($n(e))},removeKeyMap:function(e){for(var t=this.state.keyMaps,n=0;n<t.length;++n)if(t[n]==e||t[n].name==e)return t.splice(n,1),!0},addOverlay:Ot(function(t,n){var r=t.token?t:e.getMode(this.options,t);if(r.startState)throw new Error("Overlays may not be stateful.");this.state.overlays.push({mode:r,modeSpec:t,opaque:n&&n.opaque}),this.state.modeGen++,Dt(this)}),removeOverlay:Ot(function(e){for(var t=this.state.overlays,n=0;n<t.length;++n){var r=t[n].modeSpec;if(r==e||"string"==typeof e&&r.name==e)return t.splice(n,1),this.state.modeGen++,void Dt(this)}}),indentLine:Ot(function(e,t,n){"string"!=typeof t&&"number"!=typeof t&&(t=null==t?this.options.smartIndent?"smart":"prev":t?"add":"subtract"),ve(this.doc,e)&&Fn(this,e,t,n)}),indentSelection:Ot(function(e){for(var t=this.doc.sel.ranges,n=-1,r=0;r<t.length;r++){var i=t[r];if(i.empty())i.head.line>n&&(Fn(this,i.head.line,e,!0),n=i.head.line,r==this.doc.sel.primIndex&&Bn(this));else{var o=i.from(),a=i.to(),l=Math.max(n,o.line);n=Math.min(this.lastLine(),a.line-(a.ch?0:1))+1;for(var s=l;n>s;++s)Fn(this,s,e);var c=this.doc.sel.ranges;0==o.ch&&t.length==c.length&&c[r].from().ch>0&&ke(this.doc,r,new fe(o,c[r].to()),Wa)}}}),getTokenAt:function(e,t){return Ir(this,e,t)},getLineTokens:function(e,t){return Ir(this,Bo(e),t,!0)},getTokenTypeAt:function(e){e=me(this.doc,e);var t,n=Dr(this,Zr(this.doc,e.line)),r=0,i=(n.length-1)/2,o=e.ch;if(0==o)t=n[2];else for(;;){var a=r+i>>1;if((a?n[2*a-1]:0)>=o)i=a;else{if(!(n[2*a+1]<o)){t=n[2*a+2];break}r=a+1}}var l=t?t.indexOf("cm-overlay "):-1;return 0>l?t:0==l?null:t.slice(0,l-1)},getModeAt:function(t){var n=this.doc.mode;return n.innerMode?e.innerMode(n,this.getTokenAt(t).state).mode:n},getHelper:function(e,t){return this.getHelpers(e,t)[0]},getHelpers:function(e,t){var n=[];if(!la.hasOwnProperty(t))return n;var r=la[t],i=this.getModeAt(e);if("string"==typeof i[t])r[i[t]]&&n.push(r[i[t]]);else if(i[t])for(var o=0;o<i[t].length;o++){var a=r[i[t][o]];a&&n.push(a)}else i.helperType&&r[i.helperType]?n.push(r[i.helperType]):r[i.name]&&n.push(r[i.name]);for(var o=0;o<r._global.length;o++){var l=r._global[o];l.pred(i,this)&&-1==Pi(n,l.val)&&n.push(l.val)}return n},getStateAfter:function(e,t){var n=this.doc;return e=pe(n,null==e?n.first+n.size-1:e),je(this,e+1,t)},cursorCoords:function(e,t){var n,r=this.doc.sel.primary();return n=null==e?r.head:"object"==typeof e?me(this.doc,e):e?r.from():r.to(),dt(this,n,t||"page")},charCoords:function(e,t){return ht(this,me(this.doc,e),t||"page")},coordsChar:function(e,t){return e=ft(this,e,t||"page"),gt(this,e.left,e.top)},lineAtHeight:function(e,t){return e=ft(this,{top:e,left:0},t||"page").top,ni(this.doc,e+this.display.viewOffset)},heightAtLine:function(e,t){var n,r=!1;if("number"==typeof e){var i=this.doc.first+this.doc.size-1;e<this.doc.first?e=this.doc.first:e>i&&(e=i,r=!0),n=Zr(this.doc,e)}else n=e;return ut(this,n,{top:0,left:0},t||"page").top+(r?this.doc.height-ri(n):0)},defaultTextHeight:function(){return yt(this.display)},defaultCharWidth:function(){return xt(this.display)},setGutterMarker:Ot(function(e,t,n){return zn(this.doc,e,"gutter",function(e){var r=e.gutterMarkers||(e.gutterMarkers={});return r[t]=n,!n&&Fi(r)&&(e.gutterMarkers=null),!0})}),clearGutter:Ot(function(e){var t=this,n=t.doc,r=n.first;n.iter(function(n){n.gutterMarkers&&n.gutterMarkers[e]&&(n.gutterMarkers[e]=null,Ht(t,r,"gutter"),Fi(n.gutterMarkers)&&(n.gutterMarkers=null)),++r})}),lineInfo:function(e){if("number"==typeof e){if(!ve(this.doc,e))return null;var t=e;if(e=Zr(this.doc,e),!e)return null}else{var t=ti(e);if(null==t)return null}return{line:t,handle:e,text:e.text,gutterMarkers:e.gutterMarkers,textClass:e.textClass,bgClass:e.bgClass,wrapClass:e.wrapClass,widgets:e.widgets}},getViewport:function(){return{from:this.display.viewFrom,to:this.display.viewTo}},addWidget:function(e,t,n,r,i){var o=this.display;e=dt(this,me(this.doc,e));var a=e.bottom,l=e.left;if(t.style.position="absolute",t.setAttribute("cm-ignore-events","true"),this.display.input.setUneditable(t),o.sizer.appendChild(t),"over"==r)a=e.top;else if("above"==r||"near"==r){var s=Math.max(o.wrapper.clientHeight,this.doc.height),c=Math.max(o.sizer.clientWidth,o.lineSpace.clientWidth);("above"==r||e.bottom+t.offsetHeight>s)&&e.top>t.offsetHeight?a=e.top-t.offsetHeight:e.bottom+t.offsetHeight<=s&&(a=e.bottom),l+t.offsetWidth>c&&(l=c-t.offsetWidth)}t.style.top=a+"px",t.style.left=t.style.right="","right"==i?(l=o.sizer.clientWidth-t.offsetWidth,t.style.right="0px"):("left"==i?l=0:"middle"==i&&(l=(o.sizer.clientWidth-t.offsetWidth)/2),t.style.left=l+"px"),n&&Dn(this,l,a,l+t.offsetWidth,a+t.offsetHeight)},triggerOnKeyDown:Ot(hn),triggerOnKeyPress:Ot(mn),triggerOnKeyUp:pn,execCommand:function(e){return ua.hasOwnProperty(e)?ua[e].call(null,this):void 0},triggerElectric:Ot(function(e){Q(this,e)}),findPosH:function(e,t,n,r){var i=1;0>t&&(i=-1,t=-t);for(var o=0,a=me(this.doc,e);t>o&&(a=Un(this.doc,a,i,n,r),!a.hitSide);++o);return a},moveH:Ot(function(e,t){var n=this;n.extendSelectionsBy(function(r){return n.display.shift||n.doc.extend||r.empty()?Un(n.doc,r.head,e,t,n.options.rtlMoveVisually):0>e?r.from():r.to()},_a)}),deleteH:Ot(function(e,t){var n=this.doc.sel,r=this.doc;n.somethingSelected()?r.replaceSelection("",null,"+delete"):jn(this,function(n){var i=Un(r,n.head,e,t,!1);return 0>e?{from:i,to:n.head}:{from:n.head,to:i}})}),findPosV:function(e,t,n,r){var i=1,o=r;0>t&&(i=-1,t=-t);for(var a=0,l=me(this.doc,e);t>a;++a){var s=dt(this,l,"div");if(null==o?o=s.left:s.left=o,l=qn(this,s,i,n),l.hitSide)break}return l},moveV:Ot(function(e,t){var n=this,r=this.doc,i=[],o=!n.display.shift&&!r.extend&&r.sel.somethingSelected();if(r.extendSelectionsBy(function(a){if(o)return 0>e?a.from():a.to();var l=dt(n,a.head,"div");null!=a.goalColumn&&(l.left=a.goalColumn),i.push(l.left);var s=qn(n,l,e,t);return"page"==t&&a==r.sel.primary()&&Wn(n,null,ht(n,s,"div").top-l.top),s},_a),i.length)for(var a=0;a<r.sel.ranges.length;a++)r.sel.ranges[a].goalColumn=i[a]}),findWordAt:function(e){var t=this.doc,n=Zr(t,e.line).text,r=e.ch,i=e.ch;if(n){var o=this.getHelper(e,"wordChars");(e.xRel<0||i==n.length)&&r?--r:++i;for(var a=n.charAt(r),l=_i(a,o)?function(e){return _i(e,o)}:/\s/.test(a)?function(e){return/\s/.test(e)}:function(e){return!/\s/.test(e)&&!_i(e)};r>0&&l(n.charAt(r-1));)--r;for(;i<n.length&&l(n.charAt(i));)++i}return new fe(Bo(e.line,r),Bo(e.line,i))},toggleOverwrite:function(e){null!=e&&e==this.state.overwrite||((this.state.overwrite=!this.state.overwrite)?Ja(this.display.cursorDiv,"CodeMirror-overwrite"):Za(this.display.cursorDiv,"CodeMirror-overwrite"),Pa(this,"overwriteToggle",this,this.state.overwrite))},hasFocus:function(){return this.display.input.getField()==Gi()},isReadOnly:function(){return!(!this.options.readOnly&&!this.doc.cantEdit)},scrollTo:Ot(function(e,t){null==e&&null==t||_n(this),null!=e&&(this.curOp.scrollLeft=e),null!=t&&(this.curOp.scrollTop=t)}),getScrollInfo:function(){var e=this.display.scroller;return{left:e.scrollLeft,top:e.scrollTop,height:e.scrollHeight-Ye(this)-this.display.barHeight,width:e.scrollWidth-Ye(this)-this.display.barWidth,clientHeight:Ve(this),clientWidth:$e(this)}},scrollIntoView:Ot(function(e,t){if(null==e?(e={from:this.doc.sel.primary().head,to:null},null==t&&(t=this.options.cursorScrollMargin)):"number"==typeof e?e={from:Bo(e,0),to:null}:null==e.from&&(e={from:e,to:null}),e.to||(e.to=e.from),e.margin=t||0,null!=e.from.line)_n(this),this.curOp.scrollToPos=e;else{var n=Hn(this,Math.min(e.from.left,e.to.left),Math.min(e.from.top,e.to.top)-e.margin,Math.max(e.from.right,e.to.right),Math.max(e.from.bottom,e.to.bottom)+e.margin);this.scrollTo(n.scrollLeft,n.scrollTop)}}),setSize:Ot(function(e,t){function n(e){return"number"==typeof e||/^\d+$/.test(String(e))?e+"px":e}var r=this;null!=e&&(r.display.wrapper.style.width=n(e)),null!=t&&(r.display.wrapper.style.height=n(t)),r.options.lineWrapping&&at(this);var i=r.display.viewFrom;r.doc.iter(i,r.display.viewTo,function(e){if(e.widgets)for(var t=0;t<e.widgets.length;t++)if(e.widgets[t].noHScroll){Ht(r,i,"widget");break}++i}),r.curOp.forceUpdate=!0,Pa(r,"refresh",this)}),operation:function(e){return At(this,e)},refresh:Ot(function(){var e=this.display.cachedTextHeight;Dt(this),this.curOp.forceUpdate=!0,lt(this),this.scrollTo(this.doc.scrollLeft,this.doc.scrollTop),u(this),(null==e||Math.abs(e-yt(this.display))>.5)&&a(this),Pa(this,"refresh",this)}),swapDoc:Ot(function(e){var t=this.doc;return t.cm=null,Xr(this,e),lt(this),this.display.input.reset(),this.scrollTo(e.scrollLeft,e.scrollTop),this.curOp.forceScroll=!0,Ci(this,"swapDoc",this,t),t}),getInputField:function(){return this.display.input.getField()},getWrapperElement:function(){return this.display.wrapper},getScrollerElement:function(){return this.display.scroller},getGutterElement:function(){return this.display.gutters}},Ai(e);var ea=e.defaults={},ta=e.optionHandlers={},na=e.Init={toString:function(){return"CodeMirror.Init"}};Gn("value","",function(e,t){e.setValue(t)},!0),Gn("mode",null,function(e,t){e.doc.modeOption=t,n(e)},!0),Gn("indentUnit",2,n,!0),Gn("indentWithTabs",!1),Gn("smartIndent",!0),Gn("tabSize",4,function(e){r(e),lt(e),Dt(e)},!0),Gn("lineSeparator",null,function(e,t){if(e.doc.lineSep=t,t){var n=[],r=e.doc.first;e.doc.iter(function(e){for(var i=0;;){var o=e.text.indexOf(t,i);if(-1==o)break;i=o+t.length,n.push(Bo(r,o))}r++});for(var i=n.length-1;i>=0;i--)In(e.doc,t,n[i],Bo(n[i].line,n[i].ch+t.length))}}),Gn("specialChars",/[\u0000-\u001f\u007f\u00ad\u200b-\u200f\u2028\u2029\ufeff]/g,function(t,n,r){t.state.specialChars=new RegExp(n.source+(n.test("	")?"":"|	"),"g"),r!=e.Init&&t.refresh()}),Gn("specialCharPlaceholder",_r,function(e){e.refresh()},!0),Gn("electricChars",!0),Gn("inputStyle",Ao?"contenteditable":"textarea",function(){throw new Error("inputStyle can not (yet) be changed in a running editor")},!0),Gn("rtlMoveVisually",!Io),Gn("wholeLineUpdateBefore",!0),Gn("theme","default",function(e){l(e),s(e)},!0),Gn("keyMap","default",function(t,n,r){var i=$n(n),o=r!=e.Init&&$n(r);o&&o.detach&&o.detach(t,i),i.attach&&i.attach(t,o||null)}),Gn("extraKeys",null),Gn("lineWrapping",!1,i,!0),Gn("gutters",[],function(e){d(e.options),s(e)},!0),Gn("fixedGutter",!0,function(e,t){e.display.gutters.style.left=t?C(e.display)+"px":"0",e.refresh()},!0),Gn("coverGutterNextToScrollbar",!1,function(e){y(e)},!0),Gn("scrollbarStyle","native",function(e){v(e),y(e),e.display.scrollbars.setScrollTop(e.doc.scrollTop),e.display.scrollbars.setScrollLeft(e.doc.scrollLeft)},!0),Gn("lineNumbers",!1,function(e){d(e.options),s(e)},!0),Gn("firstLineNumber",1,s,!0),Gn("lineNumberFormatter",function(e){return e},s,!0),Gn("showCursorWhenSelecting",!1,Re,!0),Gn("resetSelectionOnContextMenu",!0),Gn("lineWiseCopyCut",!0),Gn("readOnly",!1,function(e,t){"nocursor"==t?(yn(e),e.display.input.blur(),e.display.disabled=!0):e.display.disabled=!1,e.display.input.readOnlyChanged(t)}),Gn("disableInput",!1,function(e,t){t||e.display.input.reset()},!0),Gn("dragDrop",!0,Ut),Gn("allowDropFileTypes",null),Gn("cursorBlinkRate",530),Gn("cursorScrollMargin",0),Gn("cursorHeight",1,Re,!0),Gn("singleCursorHeightPerLine",!0,Re,!0),Gn("workTime",100),Gn("workDelay",100),Gn("flattenSpans",!0,r,!0),Gn("addModeClass",!1,r,!0),Gn("pollInterval",100),Gn("undoDepth",200,function(e,t){e.doc.history.undoDepth=t}),Gn("historyEventDelay",1250),Gn("viewportMargin",10,function(e){e.refresh()},!0),Gn("maxHighlightLength",1e4,r,!0),Gn("moveInputWithCursor",!0,function(e,t){t||e.display.input.resetPosition()}),Gn("tabindex",null,function(e,t){e.display.input.getField().tabIndex=t||""}),Gn("autofocus",null);var ra=e.modes={},ia=e.mimeModes={};e.defineMode=function(t,n){e.defaults.mode||"null"==t||(e.defaults.mode=t),arguments.length>2&&(n.dependencies=Array.prototype.slice.call(arguments,2)),ra[t]=n},e.defineMIME=function(e,t){ia[e]=t},e.resolveMode=function(t){if("string"==typeof t&&ia.hasOwnProperty(t))t=ia[t];else if(t&&"string"==typeof t.name&&ia.hasOwnProperty(t.name)){var n=ia[t.name];"string"==typeof n&&(n={name:n}),t=Hi(n,t),t.name=n.name}else if("string"==typeof t&&/^[\w\-]+\/[\w\-]+\+xml$/.test(t))return e.resolveMode("application/xml");return"string"==typeof t?{name:t}:t||{name:"null"}},e.getMode=function(t,n){var n=e.resolveMode(n),r=ra[n.name];if(!r)return e.getMode(t,"text/plain");var i=r(t,n);if(oa.hasOwnProperty(n.name)){var o=oa[n.name];for(var a in o)o.hasOwnProperty(a)&&(i.hasOwnProperty(a)&&(i["_"+a]=i[a]),i[a]=o[a])}if(i.name=n.name,n.helperType&&(i.helperType=n.helperType),n.modeProps)for(var a in n.modeProps)i[a]=n.modeProps[a];return i},e.defineMode("null",function(){return{token:function(e){e.skipToEnd()}}}),e.defineMIME("text/plain","null");var oa=e.modeExtensions={};e.extendMode=function(e,t){var n=oa.hasOwnProperty(e)?oa[e]:oa[e]={};Wi(t,n)},e.defineExtension=function(t,n){e.prototype[t]=n},e.defineDocExtension=function(e,t){Ca.prototype[e]=t},e.defineOption=Gn;var aa=[];e.defineInitHook=function(e){aa.push(e)};var la=e.helpers={};e.registerHelper=function(t,n,r){la.hasOwnProperty(t)||(la[t]=e[t]={_global:[]}),la[t][n]=r},e.registerGlobalHelper=function(t,n,r,i){e.registerHelper(t,n,i),la[t]._global.push({pred:r,val:i})};var sa=e.copyState=function(e,t){if(t===!0)return t;if(e.copyState)return e.copyState(t);var n={};for(var r in t){var i=t[r];i instanceof Array&&(i=i.concat([])),n[r]=i}return n},ca=e.startState=function(e,t,n){return e.startState?e.startState(t,n):!0};e.innerMode=function(e,t){for(;e.innerMode;){var n=e.innerMode(t);if(!n||n.mode==e)break;t=n.state,e=n.mode}return n||{mode:e,state:t}};var ua=e.commands={selectAll:function(e){e.setSelection(Bo(e.firstLine(),0),Bo(e.lastLine()),Wa)},singleSelection:function(e){e.setSelection(e.getCursor("anchor"),e.getCursor("head"),Wa)},killLine:function(e){jn(e,function(t){if(t.empty()){var n=Zr(e.doc,t.head.line).text.length;return t.head.ch==n&&t.head.line<e.lastLine()?{from:t.head,to:Bo(t.head.line+1,0)}:{from:t.head,to:Bo(t.head.line,n)}}return{from:t.from(),to:t.to()}})},deleteLine:function(e){jn(e,function(t){return{from:Bo(t.from().line,0),to:me(e.doc,Bo(t.to().line+1,0))}})},delLineLeft:function(e){jn(e,function(e){return{from:Bo(e.from().line,0),to:e.from()}})},delWrappedLineLeft:function(e){jn(e,function(t){var n=e.charCoords(t.head,"div").top+5,r=e.coordsChar({left:0,top:n},"div");return{from:r,to:t.from()}})},delWrappedLineRight:function(e){jn(e,function(t){var n=e.charCoords(t.head,"div").top+5,r=e.coordsChar({left:e.display.lineDiv.offsetWidth+100,top:n},"div");return{from:t.from(),to:r}})},undo:function(e){e.undo()},redo:function(e){e.redo()},undoSelection:function(e){e.undoSelection()},redoSelection:function(e){e.redoSelection()},goDocStart:function(e){e.extendSelection(Bo(e.firstLine(),0))},goDocEnd:function(e){e.extendSelection(Bo(e.lastLine()))},goLineStart:function(e){e.extendSelectionsBy(function(t){return oo(e,t.head.line)},{origin:"+move",bias:1})},goLineStartSmart:function(e){e.extendSelectionsBy(function(t){return lo(e,t.head)},{origin:"+move",bias:1})},goLineEnd:function(e){e.extendSelectionsBy(function(t){return ao(e,t.head.line)},{origin:"+move",bias:-1})},goLineRight:function(e){e.extendSelectionsBy(function(t){var n=e.charCoords(t.head,"div").top+5;return e.coordsChar({left:e.display.lineDiv.offsetWidth+100,top:n},"div")},_a)},goLineLeft:function(e){e.extendSelectionsBy(function(t){var n=e.charCoords(t.head,"div").top+5;return e.coordsChar({left:0,top:n},"div")},_a)},goLineLeftSmart:function(e){e.extendSelectionsBy(function(t){var n=e.charCoords(t.head,"div").top+5,r=e.coordsChar({left:0,top:n},"div");return r.ch<e.getLine(r.line).search(/\S/)?lo(e,t.head):r},_a)},goLineUp:function(e){e.moveV(-1,"line")},goLineDown:function(e){e.moveV(1,"line")},goPageUp:function(e){e.moveV(-1,"page")},goPageDown:function(e){e.moveV(1,"page")},goCharLeft:function(e){e.moveH(-1,"char")},goCharRight:function(e){e.moveH(1,"char")},goColumnLeft:function(e){e.moveH(-1,"column")},goColumnRight:function(e){e.moveH(1,"column")},goWordLeft:function(e){e.moveH(-1,"word")},goGroupRight:function(e){e.moveH(1,"group")},goGroupLeft:function(e){e.moveH(-1,"group")},goWordRight:function(e){e.moveH(1,"word")},delCharBefore:function(e){e.deleteH(-1,"char")},delCharAfter:function(e){e.deleteH(1,"char")},delWordBefore:function(e){e.deleteH(-1,"word")},delWordAfter:function(e){e.deleteH(1,"word")},delGroupBefore:function(e){e.deleteH(-1,"group")},delGroupAfter:function(e){e.deleteH(1,"group")},indentAuto:function(e){e.indentSelection("smart")},indentMore:function(e){e.indentSelection("add")},indentLess:function(e){e.indentSelection("subtract")},insertTab:function(e){e.replaceSelection("	")},insertSoftTab:function(e){for(var t=[],n=e.listSelections(),r=e.options.tabSize,i=0;i<n.length;i++){var o=n[i].from(),a=Fa(e.getLine(o.line),o.ch,r);t.push(Oi(r-a%r))}e.replaceSelections(t)},defaultTab:function(e){e.somethingSelected()?e.indentSelection("add"):e.execCommand("insertTab")},transposeChars:function(e){At(e,function(){for(var t=e.listSelections(),n=[],r=0;r<t.length;r++){var i=t[r].head,o=Zr(e.doc,i.line).text;if(o)if(i.ch==o.length&&(i=new Bo(i.line,i.ch-1)),i.ch>0)i=new Bo(i.line,i.ch+1),e.replaceRange(o.charAt(i.ch-1)+o.charAt(i.ch-2),Bo(i.line,i.ch-2),i,"+transpose");else if(i.line>e.doc.first){var a=Zr(e.doc,i.line-1).text;a&&e.replaceRange(o.charAt(0)+e.doc.lineSeparator()+a.charAt(a.length-1),Bo(i.line-1,a.length-1),Bo(i.line,1),"+transpose")}n.push(new fe(i,i))}e.setSelections(n)})},newlineAndIndent:function(e){At(e,function(){for(var t=e.listSelections().length,n=0;t>n;n++){var r=e.listSelections()[n];e.replaceRange(e.doc.lineSeparator(),r.anchor,r.head,"+input"),e.indentLine(r.from().line+1,null,!0)}Bn(e)})},openLine:function(e){e.replaceSelection("\n","start")},toggleOverwrite:function(e){e.toggleOverwrite()}},fa=e.keyMap={};fa.basic={Left:"goCharLeft",Right:"goCharRight",Up:"goLineUp",Down:"goLineDown",End:"goLineEnd",Home:"goLineStartSmart",PageUp:"goPageUp",PageDown:"goPageDown",Delete:"delCharAfter",Backspace:"delCharBefore","Shift-Backspace":"delCharBefore",Tab:"defaultTab","Shift-Tab":"indentAuto",Enter:"newlineAndIndent",Insert:"toggleOverwrite",Esc:"singleSelection"},fa.pcDefault={"Ctrl-A":"selectAll","Ctrl-D":"deleteLine","Ctrl-Z":"undo","Shift-Ctrl-Z":"redo","Ctrl-Y":"redo","Ctrl-Home":"goDocStart","Ctrl-End":"goDocEnd","Ctrl-Up":"goLineUp","Ctrl-Down":"goLineDown","Ctrl-Left":"goGroupLeft","Ctrl-Right":"goGroupRight","Alt-Left":"goLineStart","Alt-Right":"goLineEnd","Ctrl-Backspace":"delGroupBefore","Ctrl-Delete":"delGroupAfter","Ctrl-S":"save","Ctrl-F":"find","Ctrl-G":"findNext","Shift-Ctrl-G":"findPrev","Shift-Ctrl-F":"replace","Shift-Ctrl-R":"replaceAll","Ctrl-[":"indentLess","Ctrl-]":"indentMore","Ctrl-U":"undoSelection","Shift-Ctrl-U":"redoSelection","Alt-U":"redoSelection",fallthrough:"basic"},fa.emacsy={"Ctrl-F":"goCharRight","Ctrl-B":"goCharLeft","Ctrl-P":"goLineUp","Ctrl-N":"goLineDown","Alt-F":"goWordRight","Alt-B":"goWordLeft","Ctrl-A":"goLineStart","Ctrl-E":"goLineEnd","Ctrl-V":"goPageDown","Shift-Ctrl-V":"goPageUp","Ctrl-D":"delCharAfter","Ctrl-H":"delCharBefore","Alt-D":"delWordAfter","Alt-Backspace":"delWordBefore","Ctrl-K":"killLine","Ctrl-T":"transposeChars","Ctrl-O":"openLine"},fa.macDefault={"Cmd-A":"selectAll","Cmd-D":"deleteLine","Cmd-Z":"undo","Shift-Cmd-Z":"redo","Cmd-Y":"redo","Cmd-Home":"goDocStart","Cmd-Up":"goDocStart","Cmd-End":"goDocEnd","Cmd-Down":"goDocEnd","Alt-Left":"goGroupLeft","Alt-Right":"goGroupRight","Cmd-Left":"goLineLeft","Cmd-Right":"goLineRight","Alt-Backspace":"delGroupBefore","Ctrl-Alt-Backspace":"delGroupAfter","Alt-Delete":"delGroupAfter","Cmd-S":"save","Cmd-F":"find","Cmd-G":"findNext","Shift-Cmd-G":"findPrev","Cmd-Alt-F":"replace","Shift-Cmd-Alt-F":"replaceAll","Cmd-[":"indentLess","Cmd-]":"indentMore","Cmd-Backspace":"delWrappedLineLeft","Cmd-Delete":"delWrappedLineRight","Cmd-U":"undoSelection","Shift-Cmd-U":"redoSelection","Ctrl-Up":"goDocStart","Ctrl-Down":"goDocEnd",fallthrough:["basic","emacsy"]},fa["default"]=Eo?fa.macDefault:fa.pcDefault,e.normalizeKeyMap=function(e){var t={};for(var n in e)if(e.hasOwnProperty(n)){var r=e[n];if(/^(name|fallthrough|(de|at)tach)$/.test(n))continue;if("..."==r){delete e[n];continue}for(var i=Ri(n.split(" "),Yn),o=0;o<i.length;o++){var a,l;o==i.length-1?(l=i.join(" "),a=r):(l=i.slice(0,o+1).join(" "),a="...");var s=t[l];if(s){if(s!=a)throw new Error("Inconsistent bindings for "+l)}else t[l]=a}delete e[n]}for(var c in t)e[c]=t[c];return e};var ha=e.lookupKey=function(e,t,n,r){t=$n(t);var i=t.call?t.call(e,r):t[e];if(i===!1)return"nothing";if("..."===i)return"multi";if(null!=i&&n(i))return"handled";if(t.fallthrough){if("[object Array]"!=Object.prototype.toString.call(t.fallthrough))return ha(e,t.fallthrough,n,r);for(var o=0;o<t.fallthrough.length;o++){var a=ha(e,t.fallthrough[o],n,r);
61894if(a)return a}}},da=e.isModifierKey=function(e){var t="string"==typeof e?e:ol[e.keyCode];return"Ctrl"==t||"Alt"==t||"Shift"==t||"Mod"==t},pa=e.keyName=function(e,t){if(Co&&34==e.keyCode&&e["char"])return!1;var n=ol[e.keyCode],r=n;return null==r||e.altGraphKey?!1:(e.altKey&&"Alt"!=n&&(r="Alt-"+r),(Ro?e.metaKey:e.ctrlKey)&&"Ctrl"!=n&&(r="Ctrl-"+r),(Ro?e.ctrlKey:e.metaKey)&&"Cmd"!=n&&(r="Cmd-"+r),!t&&e.shiftKey&&"Shift"!=n&&(r="Shift-"+r),r)};e.fromTextArea=function(t,n){function r(){t.value=c.getValue()}if(n=n?Wi(n):{},n.value=t.value,!n.tabindex&&t.tabIndex&&(n.tabindex=t.tabIndex),!n.placeholder&&t.placeholder&&(n.placeholder=t.placeholder),null==n.autofocus){var i=Gi();n.autofocus=i==t||null!=t.getAttribute("autofocus")&&i==document.body}if(t.form&&(Ea(t.form,"submit",r),!n.leaveSubmitMethodAlone)){var o=t.form,a=o.submit;try{var l=o.submit=function(){r(),o.submit=a,o.submit(),o.submit=l}}catch(s){}}n.finishInit=function(e){e.save=r,e.getTextArea=function(){return t},e.toTextArea=function(){e.toTextArea=isNaN,r(),t.parentNode.removeChild(e.getWrapperElement()),t.style.display="",t.form&&(Ia(t.form,"submit",r),"function"==typeof t.form.submit&&(t.form.submit=a))}},t.style.display="none";var c=e(function(e){t.parentNode.insertBefore(e,t.nextSibling)},n);return c};var ma=e.StringStream=function(e,t){this.pos=this.start=0,this.string=e,this.tabSize=t||8,this.lastColumnPos=this.lastColumnValue=0,this.lineStart=0};ma.prototype={eol:function(){return this.pos>=this.string.length},sol:function(){return this.pos==this.lineStart},peek:function(){return this.string.charAt(this.pos)||void 0},next:function(){return this.pos<this.string.length?this.string.charAt(this.pos++):void 0},eat:function(e){var t=this.string.charAt(this.pos);if("string"==typeof e)var n=t==e;else var n=t&&(e.test?e.test(t):e(t));return n?(++this.pos,t):void 0},eatWhile:function(e){for(var t=this.pos;this.eat(e););return this.pos>t},eatSpace:function(){for(var e=this.pos;/[\s\u00a0]/.test(this.string.charAt(this.pos));)++this.pos;return this.pos>e},skipToEnd:function(){this.pos=this.string.length},skipTo:function(e){var t=this.string.indexOf(e,this.pos);return t>-1?(this.pos=t,!0):void 0},backUp:function(e){this.pos-=e},column:function(){return this.lastColumnPos<this.start&&(this.lastColumnValue=Fa(this.string,this.start,this.tabSize,this.lastColumnPos,this.lastColumnValue),this.lastColumnPos=this.start),this.lastColumnValue-(this.lineStart?Fa(this.string,this.lineStart,this.tabSize):0)},indentation:function(){return Fa(this.string,null,this.tabSize)-(this.lineStart?Fa(this.string,this.lineStart,this.tabSize):0)},match:function(e,t,n){if("string"!=typeof e){var r=this.string.slice(this.pos).match(e);return r&&r.index>0?null:(r&&t!==!1&&(this.pos+=r[0].length),r)}var i=function(e){return n?e.toLowerCase():e},o=this.string.substr(this.pos,e.length);return i(o)==i(e)?(t!==!1&&(this.pos+=e.length),!0):void 0},current:function(){return this.string.slice(this.start,this.pos)},hideFirstChars:function(e,t){this.lineStart+=e;try{return t()}finally{this.lineStart-=e}}};var ga=0,va=e.TextMarker=function(e,t){this.lines=[],this.type=t,this.doc=e,this.id=++ga};Ai(va),va.prototype.clear=function(){if(!this.explicitlyCleared){var e=this.doc.cm,t=e&&!e.curOp;if(t&&bt(e),Ni(this,"clear")){var n=this.find();n&&Ci(this,"clear",n.from,n.to)}for(var r=null,i=null,o=0;o<this.lines.length;++o){var a=this.lines[o],l=er(a.markedSpans,this);e&&!this.collapsed?Ht(e,ti(a),"text"):e&&(null!=l.to&&(i=ti(a)),null!=l.from&&(r=ti(a))),a.markedSpans=tr(a.markedSpans,l),null==l.from&&this.collapsed&&!kr(this.doc,a)&&e&&ei(a,yt(e.display))}if(e&&this.collapsed&&!e.options.lineWrapping)for(var o=0;o<this.lines.length;++o){var s=yr(this.lines[o]),c=f(s);c>e.display.maxLineLength&&(e.display.maxLine=s,e.display.maxLineLength=c,e.display.maxLineChanged=!0)}null!=r&&e&&this.collapsed&&Dt(e,r,i+1),this.lines.length=0,this.explicitlyCleared=!0,this.atomic&&this.doc.cantEdit&&(this.doc.cantEdit=!1,e&&Ae(e.doc)),e&&Ci(e,"markerCleared",e,this),t&&kt(e),this.parent&&this.parent.clear()}},va.prototype.find=function(e,t){null==e&&"bookmark"==this.type&&(e=1);for(var n,r,i=0;i<this.lines.length;++i){var o=this.lines[i],a=er(o.markedSpans,this);if(null!=a.from&&(n=Bo(t?o:ti(o),a.from),-1==e))return n;if(null!=a.to&&(r=Bo(t?o:ti(o),a.to),1==e))return r}return n&&{from:n,to:r}},va.prototype.changed=function(){var e=this.find(-1,!0),t=this,n=this.doc.cm;e&&n&&At(n,function(){var r=e.line,i=ti(e.line),o=Qe(n,i);if(o&&(ot(o),n.curOp.selectionChanged=n.curOp.forceUpdate=!0),n.curOp.updateMaxLine=!0,!kr(t.doc,r)&&null!=t.height){var a=t.height;t.height=null;var l=Lr(t)-a;l&&ei(r,r.height+l)}})},va.prototype.attachLine=function(e){if(!this.lines.length&&this.doc.cm){var t=this.doc.cm.curOp;t.maybeHiddenMarkers&&-1!=Pi(t.maybeHiddenMarkers,this)||(t.maybeUnhiddenMarkers||(t.maybeUnhiddenMarkers=[])).push(this)}this.lines.push(e)},va.prototype.detachLine=function(e){if(this.lines.splice(Pi(this.lines,e),1),!this.lines.length&&this.doc.cm){var t=this.doc.cm.curOp;(t.maybeHiddenMarkers||(t.maybeHiddenMarkers=[])).push(this)}};var ga=0,ya=e.SharedTextMarker=function(e,t){this.markers=e,this.primary=t;for(var n=0;n<e.length;++n)e[n].parent=this};Ai(ya),ya.prototype.clear=function(){if(!this.explicitlyCleared){this.explicitlyCleared=!0;for(var e=0;e<this.markers.length;++e)this.markers[e].clear();Ci(this,"clear")}},ya.prototype.find=function(e,t){return this.primary.find(e,t)};var xa=e.LineWidget=function(e,t,n){if(n)for(var r in n)n.hasOwnProperty(r)&&(this[r]=n[r]);this.doc=e,this.node=t};Ai(xa),xa.prototype.clear=function(){var e=this.doc.cm,t=this.line.widgets,n=this.line,r=ti(n);if(null!=r&&t){for(var i=0;i<t.length;++i)t[i]==this&&t.splice(i--,1);t.length||(n.widgets=null);var o=Lr(this);ei(n,Math.max(0,n.height-o)),e&&At(e,function(){Cr(e,n,-o),Ht(e,r,"widget")})}},xa.prototype.changed=function(){var e=this.height,t=this.doc.cm,n=this.line;this.height=null;var r=Lr(this)-e;r&&(ei(n,n.height+r),t&&At(t,function(){t.curOp.forceUpdate=!0,Cr(t,n,r)}))};var ba=e.Line=function(e,t,n){this.text=e,ur(this,t),this.height=n?n(this):1};Ai(ba),ba.prototype.lineNo=function(){return ti(this)};var wa={},ka={};$r.prototype={chunkSize:function(){return this.lines.length},removeInner:function(e,t){for(var n=e,r=e+t;r>n;++n){var i=this.lines[n];this.height-=i.height,Nr(i),Ci(i,"delete")}this.lines.splice(e,t)},collapse:function(e){e.push.apply(e,this.lines)},insertInner:function(e,t,n){this.height+=n,this.lines=this.lines.slice(0,e).concat(t).concat(this.lines.slice(e));for(var r=0;r<t.length;++r)t[r].parent=this},iterN:function(e,t,n){for(var r=e+t;r>e;++e)if(n(this.lines[e]))return!0}},Vr.prototype={chunkSize:function(){return this.size},removeInner:function(e,t){this.size-=t;for(var n=0;n<this.children.length;++n){var r=this.children[n],i=r.chunkSize();if(i>e){var o=Math.min(t,i-e),a=r.height;if(r.removeInner(e,o),this.height-=a-r.height,i==o&&(this.children.splice(n--,1),r.parent=null),0==(t-=o))break;e=0}else e-=i}if(this.size-t<25&&(this.children.length>1||!(this.children[0]instanceof $r))){var l=[];this.collapse(l),this.children=[new $r(l)],this.children[0].parent=this}},collapse:function(e){for(var t=0;t<this.children.length;++t)this.children[t].collapse(e)},insertInner:function(e,t,n){this.size+=t.length,this.height+=n;for(var r=0;r<this.children.length;++r){var i=this.children[r],o=i.chunkSize();if(o>=e){if(i.insertInner(e,t,n),i.lines&&i.lines.length>50){for(var a=i.lines.length%25+25,l=a;l<i.lines.length;){var s=new $r(i.lines.slice(l,l+=25));i.height-=s.height,this.children.splice(++r,0,s),s.parent=this}i.lines=i.lines.slice(0,a),this.maybeSpill()}break}e-=o}},maybeSpill:function(){if(!(this.children.length<=10)){var e=this;do{var t=e.children.splice(e.children.length-5,5),n=new Vr(t);if(e.parent){e.size-=n.size,e.height-=n.height;var r=Pi(e.parent.children,e);e.parent.children.splice(r+1,0,n)}else{var i=new Vr(e.children);i.parent=e,e.children=[i,n],e=i}n.parent=e.parent}while(e.children.length>10);e.parent.maybeSpill()}},iterN:function(e,t,n){for(var r=0;r<this.children.length;++r){var i=this.children[r],o=i.chunkSize();if(o>e){var a=Math.min(t,o-e);if(i.iterN(e,a,n))return!0;if(0==(t-=a))break;e=0}else e-=o}}};var Sa=0,Ca=e.Doc=function(e,t,n,r){if(!(this instanceof Ca))return new Ca(e,t,n,r);null==n&&(n=0),Vr.call(this,[new $r([new ba("",null)])]),this.first=n,this.scrollTop=this.scrollLeft=0,this.cantEdit=!1,this.cleanGeneration=1,this.frontier=n;var i=Bo(n,0);this.sel=de(i),this.history=new oi(null),this.id=++Sa,this.modeOption=t,this.lineSep=r,this.extend=!1,"string"==typeof e&&(e=this.splitLines(e)),Yr(this,{from:i,to:i,text:e}),Te(this,de(i),Wa)};Ca.prototype=Hi(Vr.prototype,{constructor:Ca,iter:function(e,t,n){n?this.iterN(e-this.first,t-e,n):this.iterN(this.first,this.first+this.size,e)},insert:function(e,t){for(var n=0,r=0;r<t.length;++r)n+=t[r].height;this.insertInner(e-this.first,t,n)},remove:function(e,t){this.removeInner(e-this.first,t)},getValue:function(e){var t=Qr(this,this.first,this.first+this.size);return e===!1?t:t.join(e||this.lineSeparator())},setValue:It(function(e){var t=Bo(this.first,0),n=this.first+this.size-1;Tn(this,{from:t,to:Bo(n,Zr(this,n).text.length),text:this.splitLines(e),origin:"setValue",full:!0},!0),Te(this,de(t))}),replaceRange:function(e,t,n,r){t=me(this,t),n=n?me(this,n):t,In(this,e,t,n,r)},getRange:function(e,t,n){var r=Jr(this,me(this,e),me(this,t));return n===!1?r:r.join(n||this.lineSeparator())},getLine:function(e){var t=this.getLineHandle(e);return t&&t.text},getLineHandle:function(e){return ve(this,e)?Zr(this,e):void 0},getLineNumber:function(e){return ti(e)},getLineHandleVisualStart:function(e){return"number"==typeof e&&(e=Zr(this,e)),yr(e)},lineCount:function(){return this.size},firstLine:function(){return this.first},lastLine:function(){return this.first+this.size-1},clipPos:function(e){return me(this,e)},getCursor:function(e){var t,n=this.sel.primary();return t=null==e||"head"==e?n.head:"anchor"==e?n.anchor:"end"==e||"to"==e||e===!1?n.to():n.from()},listSelections:function(){return this.sel.ranges},somethingSelected:function(){return this.sel.somethingSelected()},setCursor:It(function(e,t,n){Se(this,me(this,"number"==typeof e?Bo(e,t||0):e),null,n)}),setSelection:It(function(e,t,n){Se(this,me(this,e),me(this,t||e),n)}),extendSelection:It(function(e,t,n){be(this,me(this,e),t&&me(this,t),n)}),extendSelections:It(function(e,t){we(this,ye(this,e),t)}),extendSelectionsBy:It(function(e,t){var n=Ri(this.sel.ranges,e);we(this,ye(this,n),t)}),setSelections:It(function(e,t,n){if(e.length){for(var r=0,i=[];r<e.length;r++)i[r]=new fe(me(this,e[r].anchor),me(this,e[r].head));null==t&&(t=Math.min(e.length-1,this.sel.primIndex)),Te(this,he(i,t),n)}}),addSelection:It(function(e,t,n){var r=this.sel.ranges.slice(0);r.push(new fe(me(this,e),me(this,t||e))),Te(this,he(r,r.length-1),n)}),getSelection:function(e){for(var t,n=this.sel.ranges,r=0;r<n.length;r++){var i=Jr(this,n[r].from(),n[r].to());t=t?t.concat(i):i}return e===!1?t:t.join(e||this.lineSeparator())},getSelections:function(e){for(var t=[],n=this.sel.ranges,r=0;r<n.length;r++){var i=Jr(this,n[r].from(),n[r].to());e!==!1&&(i=i.join(e||this.lineSeparator())),t[r]=i}return t},replaceSelection:function(e,t,n){for(var r=[],i=0;i<this.sel.ranges.length;i++)r[i]=e;this.replaceSelections(r,t,n||"+input")},replaceSelections:It(function(e,t,n){for(var r=[],i=this.sel,o=0;o<i.ranges.length;o++){var a=i.ranges[o];r[o]={from:a.from(),to:a.to(),text:this.splitLines(e[o]),origin:n}}for(var l=t&&"end"!=t&&Cn(this,r,t),o=r.length-1;o>=0;o--)Tn(this,r[o]);l?Le(this,l):this.cm&&Bn(this.cm)}),undo:It(function(){Nn(this,"undo")}),redo:It(function(){Nn(this,"redo")}),undoSelection:It(function(){Nn(this,"undo",!0)}),redoSelection:It(function(){Nn(this,"redo",!0)}),setExtending:function(e){this.extend=e},getExtending:function(){return this.extend},historySize:function(){for(var e=this.history,t=0,n=0,r=0;r<e.done.length;r++)e.done[r].ranges||++t;for(var r=0;r<e.undone.length;r++)e.undone[r].ranges||++n;return{undo:t,redo:n}},clearHistory:function(){this.history=new oi(this.history.maxGeneration)},markClean:function(){this.cleanGeneration=this.changeGeneration(!0)},changeGeneration:function(e){return e&&(this.history.lastOp=this.history.lastSelOp=this.history.lastOrigin=null),this.history.generation},isClean:function(e){return this.history.generation==(e||this.cleanGeneration)},getHistory:function(){return{done:gi(this.history.done),undone:gi(this.history.undone)}},setHistory:function(e){var t=this.history=new oi(this.history.maxGeneration);t.done=gi(e.done.slice(0),null,!0),t.undone=gi(e.undone.slice(0),null,!0)},addLineClass:It(function(e,t,n){return zn(this,e,"gutter"==t?"gutter":"class",function(e){var r="text"==t?"textClass":"background"==t?"bgClass":"gutter"==t?"gutterClass":"wrapClass";if(e[r]){if(Yi(n).test(e[r]))return!1;e[r]+=" "+n}else e[r]=n;return!0})}),removeLineClass:It(function(e,t,n){return zn(this,e,"gutter"==t?"gutter":"class",function(e){var r="text"==t?"textClass":"background"==t?"bgClass":"gutter"==t?"gutterClass":"wrapClass",i=e[r];if(!i)return!1;if(null==n)e[r]=null;else{var o=i.match(Yi(n));if(!o)return!1;var a=o.index+o[0].length;e[r]=i.slice(0,o.index)+(o.index&&a!=i.length?" ":"")+i.slice(a)||null}return!0})}),addLineWidget:It(function(e,t,n){return Tr(this,e,t,n)}),removeLineWidget:function(e){e.clear()},markText:function(e,t,n){return Vn(this,me(this,e),me(this,t),n,n&&n.type||"range")},setBookmark:function(e,t){var n={replacedWith:t&&(null==t.nodeType?t.widget:t),insertLeft:t&&t.insertLeft,clearWhenEmpty:!1,shared:t&&t.shared,handleMouseEvents:t&&t.handleMouseEvents};return e=me(this,e),Vn(this,e,e,n,"bookmark")},findMarksAt:function(e){e=me(this,e);var t=[],n=Zr(this,e.line).markedSpans;if(n)for(var r=0;r<n.length;++r){var i=n[r];(null==i.from||i.from<=e.ch)&&(null==i.to||i.to>=e.ch)&&t.push(i.marker.parent||i.marker)}return t},findMarks:function(e,t,n){e=me(this,e),t=me(this,t);var r=[],i=e.line;return this.iter(e.line,t.line+1,function(o){var a=o.markedSpans;if(a)for(var l=0;l<a.length;l++){var s=a[l];null!=s.to&&i==e.line&&e.ch>=s.to||null==s.from&&i!=e.line||null!=s.from&&i==t.line&&s.from>=t.ch||n&&!n(s.marker)||r.push(s.marker.parent||s.marker)}++i}),r},getAllMarks:function(){var e=[];return this.iter(function(t){var n=t.markedSpans;if(n)for(var r=0;r<n.length;++r)null!=n[r].from&&e.push(n[r].marker)}),e},posFromIndex:function(e){var t,n=this.first,r=this.lineSeparator().length;return this.iter(function(i){var o=i.text.length+r;return o>e?(t=e,!0):(e-=o,void++n)}),me(this,Bo(n,t))},indexFromPos:function(e){e=me(this,e);var t=e.ch;if(e.line<this.first||e.ch<0)return 0;var n=this.lineSeparator().length;return this.iter(this.first,e.line,function(e){t+=e.text.length+n}),t},copy:function(e){var t=new Ca(Qr(this,this.first,this.first+this.size),this.modeOption,this.first,this.lineSep);return t.scrollTop=this.scrollTop,t.scrollLeft=this.scrollLeft,t.sel=this.sel,t.extend=!1,e&&(t.history.undoDepth=this.history.undoDepth,t.setHistory(this.getHistory())),t},linkedDoc:function(e){e||(e={});var t=this.first,n=this.first+this.size;null!=e.from&&e.from>t&&(t=e.from),null!=e.to&&e.to<n&&(n=e.to);var r=new Ca(Qr(this,t,n),e.mode||this.modeOption,t,this.lineSep);return e.sharedHist&&(r.history=this.history),(this.linked||(this.linked=[])).push({doc:r,sharedHist:e.sharedHist}),r.linked=[{doc:this,isParent:!0,sharedHist:e.sharedHist}],Zn(r,Xn(this)),r},unlinkDoc:function(t){if(t instanceof e&&(t=t.doc),this.linked)for(var n=0;n<this.linked.length;++n){var r=this.linked[n];if(r.doc==t){this.linked.splice(n,1),t.unlinkDoc(this),Jn(Xn(this));break}}if(t.history==this.history){var i=[t.id];Kr(t,function(e){i.push(e.id)},!0),t.history=new oi(null),t.history.done=gi(this.history.done,i),t.history.undone=gi(this.history.undone,i)}},iterLinkedDocs:function(e){Kr(this,e)},getMode:function(){return this.mode},getEditor:function(){return this.cm},splitLines:function(e){return this.lineSep?e.split(this.lineSep):tl(e)},lineSeparator:function(){return this.lineSep||"\n"}}),Ca.prototype.eachLine=Ca.prototype.iter;var La="iter insert remove copy getEditor constructor".split(" ");for(var Ta in Ca.prototype)Ca.prototype.hasOwnProperty(Ta)&&Pi(La,Ta)<0&&(e.prototype[Ta]=function(e){return function(){return e.apply(this.doc,arguments)}}(Ca.prototype[Ta]));Ai(Ca);var Ma=e.e_preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},Na=e.e_stopPropagation=function(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0},Aa=e.e_stop=function(e){Ma(e),Na(e)},Ea=e.on=function(e,t,n){if(e.addEventListener)e.addEventListener(t,n,!1);else if(e.attachEvent)e.attachEvent("on"+t,n);else{var r=e._handlers||(e._handlers={}),i=r[t]||(r[t]=[]);i.push(n)}},Oa=[],Ia=e.off=function(e,t,n){if(e.removeEventListener)e.removeEventListener(t,n,!1);else if(e.detachEvent)e.detachEvent("on"+t,n);else for(var r=Si(e,t,!1),i=0;i<r.length;++i)if(r[i]==n){r.splice(i,1);break}},Pa=e.signal=function(e,t){var n=Si(e,t,!0);if(n.length)for(var r=Array.prototype.slice.call(arguments,2),i=0;i<n.length;++i)n[i].apply(null,r)},Ra=null,Da=30,Ha=e.Pass={toString:function(){return"CodeMirror.Pass"}},Wa={scroll:!1},Ba={origin:"*mouse"},_a={origin:"+move"};Ei.prototype.set=function(e,t){clearTimeout(this.id),this.id=setTimeout(t,e)};var Fa=e.countColumn=function(e,t,n,r,i){null==t&&(t=e.search(/[^\s\u00a0]/),-1==t&&(t=e.length));for(var o=r||0,a=i||0;;){var l=e.indexOf("	",o);if(0>l||l>=t)return a+(t-o);a+=l-o,a+=n-a%n,o=l+1}},za=e.findColumn=function(e,t,n){for(var r=0,i=0;;){var o=e.indexOf("	",r);-1==o&&(o=e.length);var a=o-r;if(o==e.length||i+a>=t)return r+Math.min(a,t-i);if(i+=o-r,i+=n-i%n,r=o+1,i>=t)return r}},ja=[""],Ua=function(e){e.select()};No?Ua=function(e){e.selectionStart=0,e.selectionEnd=e.value.length}:xo&&(Ua=function(e){try{e.select()}catch(t){}});var qa,Ga=/[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/,Ya=e.isWordChar=function(e){return/\w/.test(e)||e>"€"&&(e.toUpperCase()!=e.toLowerCase()||Ga.test(e))},$a=/[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/;qa=document.createRange?function(e,t,n,r){var i=document.createRange();return i.setEnd(r||e,n),i.setStart(e,t),i}:function(e,t,n){var r=document.body.createTextRange();try{r.moveToElementText(e.parentNode)}catch(i){return r}return r.collapse(!0),r.moveEnd("character",n),r.moveStart("character",t),r};var Va=e.contains=function(e,t){if(3==t.nodeType&&(t=t.parentNode),e.contains)return e.contains(t);do if(11==t.nodeType&&(t=t.host),t==e)return!0;while(t=t.parentNode)};xo&&11>bo&&(Gi=function(){try{return document.activeElement}catch(e){return document.body}});var Ka,Xa,Za=e.rmClass=function(e,t){var n=e.className,r=Yi(t).exec(n);if(r){var i=n.slice(r.index+r[0].length);e.className=n.slice(0,r.index)+(i?r[1]+i:"")}},Ja=e.addClass=function(e,t){var n=e.className;Yi(t).test(n)||(e.className+=(n?" ":"")+t)},Qa=!1,el=function(){if(xo&&9>bo)return!1;var e=ji("div");return"draggable"in e||"dragDrop"in e}(),tl=e.splitLines=3!="\n\nb".split(/\n/).length?function(e){for(var t=0,n=[],r=e.length;r>=t;){var i=e.indexOf("\n",t);-1==i&&(i=e.length);var o=e.slice(t,"\r"==e.charAt(i-1)?i-1:i),a=o.indexOf("\r");-1!=a?(n.push(o.slice(0,a)),t+=a+1):(n.push(o),t=i+1)}return n}:function(e){return e.split(/\r\n?|\n/)},nl=window.getSelection?function(e){try{return e.selectionStart!=e.selectionEnd}catch(t){return!1}}:function(e){try{var t=e.ownerDocument.selection.createRange()}catch(n){}return t&&t.parentElement()==e?0!=t.compareEndPoints("StartToEnd",t):!1},rl=function(){var e=ji("div");return"oncopy"in e?!0:(e.setAttribute("oncopy","return;"),"function"==typeof e.oncopy)}(),il=null,ol=e.keyNames={3:"Enter",8:"Backspace",9:"Tab",13:"Enter",16:"Shift",17:"Ctrl",18:"Alt",19:"Pause",20:"CapsLock",27:"Esc",32:"Space",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"Left",38:"Up",39:"Right",40:"Down",44:"PrintScrn",45:"Insert",46:"Delete",59:";",61:"=",91:"Mod",92:"Mod",93:"Mod",106:"*",107:"=",109:"-",110:".",111:"/",127:"Delete",173:"-",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'",63232:"Up",63233:"Down",63234:"Left",63235:"Right",63272:"Delete",63273:"Home",63275:"End",63276:"PageUp",63277:"PageDown",63302:"Insert"};!function(){for(var e=0;10>e;e++)ol[e+48]=ol[e+96]=String(e);for(var e=65;90>=e;e++)ol[e]=String.fromCharCode(e);for(var e=1;12>=e;e++)ol[e+111]=ol[e+63235]="F"+e}();var al,ll=function(){function e(e){return 247>=e?n.charAt(e):e>=1424&&1524>=e?"R":e>=1536&&1773>=e?r.charAt(e-1536):e>=1774&&2220>=e?"r":e>=8192&&8203>=e?"w":8204==e?"b":"L"}function t(e,t,n){this.level=e,this.from=t,this.to=n}var n="bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN",r="rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmm",i=/[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/,o=/[stwN]/,a=/[LRr]/,l=/[Lb1n]/,s=/[1n]/,c="L";return function(n){if(!i.test(n))return!1;for(var r,u=n.length,f=[],h=0;u>h;++h)f.push(r=e(n.charCodeAt(h)));for(var h=0,d=c;u>h;++h){var r=f[h];"m"==r?f[h]=d:d=r}for(var h=0,p=c;u>h;++h){var r=f[h];"1"==r&&"r"==p?f[h]="n":a.test(r)&&(p=r,"r"==r&&(f[h]="R"))}for(var h=1,d=f[0];u-1>h;++h){var r=f[h];"+"==r&&"1"==d&&"1"==f[h+1]?f[h]="1":","!=r||d!=f[h+1]||"1"!=d&&"n"!=d||(f[h]=d),d=r}for(var h=0;u>h;++h){var r=f[h];if(","==r)f[h]="N";else if("%"==r){for(var m=h+1;u>m&&"%"==f[m];++m);for(var g=h&&"!"==f[h-1]||u>m&&"1"==f[m]?"1":"N",v=h;m>v;++v)f[v]=g;h=m-1}}for(var h=0,p=c;u>h;++h){var r=f[h];"L"==p&&"1"==r?f[h]="L":a.test(r)&&(p=r)}for(var h=0;u>h;++h)if(o.test(f[h])){for(var m=h+1;u>m&&o.test(f[m]);++m);for(var y="L"==(h?f[h-1]:c),x="L"==(u>m?f[m]:c),g=y||x?"L":"R",v=h;m>v;++v)f[v]=g;h=m-1}for(var b,w=[],h=0;u>h;)if(l.test(f[h])){var k=h;for(++h;u>h&&l.test(f[h]);++h);w.push(new t(0,k,h))}else{var S=h,C=w.length;for(++h;u>h&&"L"!=f[h];++h);for(var v=S;h>v;)if(s.test(f[v])){v>S&&w.splice(C,0,new t(1,S,v));var L=v;for(++v;h>v&&s.test(f[v]);++v);w.splice(C,0,new t(2,L,v)),S=v}else++v;h>S&&w.splice(C,0,new t(1,S,h))}return 1==w[0].level&&(b=n.match(/^\s+/))&&(w[0].from=b[0].length,w.unshift(new t(0,0,b[0].length))),1==Ii(w).level&&(b=n.match(/\s+$/))&&(Ii(w).to-=b[0].length,w.push(new t(0,u-b[0].length,u))),2==w[0].level&&w.unshift(new t(1,w[0].to,w[0].to)),w[0].level!=Ii(w).level&&w.push(new t(w[0].level,u,u)),w}}();return e.version="5.15.2",e})},{}],11:[function(t,n,r){!function(i){"object"==typeof r&&"object"==typeof n?i(t("../../lib/codemirror"),t("../markdown/markdown"),t("../../addon/mode/overlay")):"function"==typeof e&&e.amd?e(["../../lib/codemirror","../markdown/markdown","../../addon/mode/overlay"],i):i(CodeMirror)}(function(e){"use strict";var t=/^((?:(?:aaas?|about|acap|adiumxtra|af[ps]|aim|apt|attachment|aw|beshare|bitcoin|bolo|callto|cap|chrome(?:-extension)?|cid|coap|com-eventbrite-attendee|content|crid|cvs|data|dav|dict|dlna-(?:playcontainer|playsingle)|dns|doi|dtn|dvb|ed2k|facetime|feed|file|finger|fish|ftp|geo|gg|git|gizmoproject|go|gopher|gtalk|h323|hcp|https?|iax|icap|icon|im|imap|info|ipn|ipp|irc[6s]?|iris(?:\.beep|\.lwz|\.xpc|\.xpcs)?|itms|jar|javascript|jms|keyparc|lastfm|ldaps?|magnet|mailto|maps|market|message|mid|mms|ms-help|msnim|msrps?|mtqp|mumble|mupdate|mvn|news|nfs|nih?|nntp|notes|oid|opaquelocktoken|palm|paparazzi|platform|pop|pres|proxy|psyc|query|res(?:ource)?|rmi|rsync|rtmp|rtsp|secondlife|service|session|sftp|sgn|shttp|sieve|sips?|skype|sm[bs]|snmp|soap\.beeps?|soldat|spotify|ssh|steam|svn|tag|teamspeak|tel(?:net)?|tftp|things|thismessage|tip|tn3270|tv|udp|unreal|urn|ut2004|vemmi|ventrilo|view-source|webcal|wss?|wtai|wyciwyg|xcon(?:-userid)?|xfire|xmlrpc\.beeps?|xmpp|xri|ymsgr|z39\.50[rs]?):(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]|\([^\s()<>]*\))+(?:\([^\s()<>]*\)|[^\s`*!()\[\]{};:'".,<>?«»“”‘’]))/i;e.defineMode("gfm",function(n,r){function i(e){return e.code=!1,null}var o=0,a={startState:function(){return{code:!1,codeBlock:!1,ateSpace:!1}},copyState:function(e){return{code:e.code,codeBlock:e.codeBlock,ateSpace:e.ateSpace}},token:function(e,n){if(n.combineTokens=null,n.codeBlock)return e.match(/^```+/)?(n.codeBlock=!1,null):(e.skipToEnd(),null);if(e.sol()&&(n.code=!1),e.sol()&&e.match(/^```+/))return e.skipToEnd(),n.codeBlock=!0,null;if("`"===e.peek()){e.next();var i=e.pos;e.eatWhile("`");var a=1+e.pos-i;return n.code?a===o&&(n.code=!1):(o=a,n.code=!0),null}if(n.code)return e.next(),null;if(e.eatSpace())return n.ateSpace=!0,null;if((e.sol()||n.ateSpace)&&(n.ateSpace=!1,r.gitHubSpice!==!1)){if(e.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+@)?(?:[a-f0-9]{7,40}\b)/))return n.combineTokens=!0,"link";if(e.match(/^(?:[a-zA-Z0-9\-_]+\/)?(?:[a-zA-Z0-9\-_]+)?#[0-9]+\b/))return n.combineTokens=!0,"link"}return e.match(t)&&"]("!=e.string.slice(e.start-2,e.start)&&(0==e.start||/\W/.test(e.string.charAt(e.start-1)))?(n.combineTokens=!0,"link"):(e.next(),null)},blankLine:i},l={underscoresBreakWords:!1,taskLists:!0,fencedCodeBlocks:"```",strikethrough:!0};for(var s in r)l[s]=r[s];return l.name="markdown",e.overlayMode(e.getMode(n,l),a)},"markdown"),e.defineMIME("text/x-gfm","gfm")})},{"../../addon/mode/overlay":8,"../../lib/codemirror":10,"../markdown/markdown":12}],12:[function(t,n,r){!function(i){"object"==typeof r&&"object"==typeof n?i(t("../../lib/codemirror"),t("../xml/xml"),t("../meta")):"function"==typeof e&&e.amd?e(["../../lib/codemirror","../xml/xml","../meta"],i):i(CodeMirror)}(function(e){"use strict";e.defineMode("markdown",function(t,n){function r(n){if(e.findModeByName){var r=e.findModeByName(n);r&&(n=r.mime||r.mimes[0])}var i=e.getMode(t,n);return"null"==i.name?null:i}function i(e,t,n){return t.f=t.inline=n,n(e,t)}function o(e,t,n){return t.f=t.block=n,n(e,t)}function a(e){return!e||!/\S/.test(e.string)}function l(e){return e.linkTitle=!1,e.em=!1,e.strong=!1,e.strikethrough=!1,e.quote=0,e.indentedCode=!1,k&&e.f==c&&(e.f=p,e.block=s),e.trailingSpace=0,e.trailingSpaceNewLine=!1,e.prevLine=e.thisLine,e.thisLine=null,null}function s(t,o){var l=t.sol(),s=o.list!==!1,c=o.indentedCode;o.indentedCode=!1,s&&(o.indentationDiff>=0?(o.indentationDiff<4&&(o.indentation-=o.indentationDiff),o.list=null):o.indentation>0?o.list=null:o.list=!1);var f=null;if(o.indentationDiff>=4)return t.skipToEnd(),c||a(o.prevLine)?(o.indentation-=4,o.indentedCode=!0,S.code):null;if(t.eatSpace())return null;if((f=t.match(A))&&f[1].length<=6)return o.header=f[1].length,n.highlightFormatting&&(o.formatting="header"),o.f=o.inline,h(o);if(!(a(o.prevLine)||o.quote||s||c)&&(f=t.match(E)))return o.header="="==f[0].charAt(0)?1:2,n.highlightFormatting&&(o.formatting="header"),o.f=o.inline,h(o);if(t.eat(">"))return o.quote=l?1:o.quote+1,n.highlightFormatting&&(o.formatting="quote"),t.eatSpace(),h(o);if("["===t.peek())return i(t,o,y);if(t.match(L,!0))return o.hr=!0,S.hr;if((a(o.prevLine)||s)&&(t.match(T,!1)||t.match(M,!1))){var d=null;for(t.match(T,!0)?d="ul":(t.match(M,!0),d="ol"),o.indentation=t.column()+t.current().length,o.list=!0;o.listStack&&t.column()<o.listStack[o.listStack.length-1];)o.listStack.pop();return o.listStack.push(o.indentation),n.taskLists&&t.match(N,!1)&&(o.taskList=!0),o.f=o.inline,n.highlightFormatting&&(o.formatting=["list","list-"+d]),h(o)}return n.fencedCodeBlocks&&(f=t.match(I,!0))?(o.fencedChars=f[1],o.localMode=r(f[2]),o.localMode&&(o.localState=e.startState(o.localMode)),o.f=o.block=u,n.highlightFormatting&&(o.formatting="code-block"),o.code=-1,h(o)):i(t,o,o.inline)}function c(t,n){var r=w.token(t,n.htmlState);if(!k){var i=e.innerMode(w,n.htmlState);("xml"==i.mode.name&&null===i.state.tagStart&&!i.state.context&&i.state.tokenize.isInText||n.md_inside&&t.current().indexOf(">")>-1)&&(n.f=p,n.block=s,n.htmlState=null)}return r}function u(e,t){return t.fencedChars&&e.match(t.fencedChars,!1)?(t.localMode=t.localState=null,t.f=t.block=f,null):t.localMode?t.localMode.token(e,t.localState):(e.skipToEnd(),S.code)}function f(e,t){e.match(t.fencedChars),t.block=s,t.f=p,t.fencedChars=null,n.highlightFormatting&&(t.formatting="code-block"),t.code=1;var r=h(t);return t.code=0,r}function h(e){var t=[];if(e.formatting){t.push(S.formatting),"string"==typeof e.formatting&&(e.formatting=[e.formatting]);for(var r=0;r<e.formatting.length;r++)t.push(S.formatting+"-"+e.formatting[r]),"header"===e.formatting[r]&&t.push(S.formatting+"-"+e.formatting[r]+"-"+e.header),"quote"===e.formatting[r]&&(!n.maxBlockquoteDepth||n.maxBlockquoteDepth>=e.quote?t.push(S.formatting+"-"+e.formatting[r]+"-"+e.quote):t.push("error"))}if(e.taskOpen)return t.push("meta"),t.length?t.join(" "):null;if(e.taskClosed)return t.push("property"),t.length?t.join(" "):null;if(e.linkHref?t.push(S.linkHref,"url"):(e.strong&&t.push(S.strong),e.em&&t.push(S.em),e.strikethrough&&t.push(S.strikethrough),e.linkText&&t.push(S.linkText),e.code&&t.push(S.code)),e.header&&t.push(S.header,S.header+"-"+e.header),e.quote&&(t.push(S.quote),!n.maxBlockquoteDepth||n.maxBlockquoteDepth>=e.quote?t.push(S.quote+"-"+e.quote):t.push(S.quote+"-"+n.maxBlockquoteDepth)),e.list!==!1){var i=(e.listStack.length-1)%3;i?1===i?t.push(S.list2):t.push(S.list3):t.push(S.list1)}return e.trailingSpaceNewLine?t.push("trailing-space-new-line"):e.trailingSpace&&t.push("trailing-space-"+(e.trailingSpace%2?"a":"b")),t.length?t.join(" "):null}function d(e,t){return e.match(O,!0)?h(t):void 0}function p(t,r){var i=r.text(t,r);if("undefined"!=typeof i)return i;if(r.list)return r.list=null,h(r);if(r.taskList){var a="x"!==t.match(N,!0)[1];return a?r.taskOpen=!0:r.taskClosed=!0,n.highlightFormatting&&(r.formatting="task"),r.taskList=!1,h(r)}if(r.taskOpen=!1,r.taskClosed=!1,r.header&&t.match(/^#+$/,!0))return n.highlightFormatting&&(r.formatting="header"),
61895h(r);var l=t.sol(),s=t.next();if(r.linkTitle){r.linkTitle=!1;var u=s;"("===s&&(u=")"),u=(u+"").replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1");var f="^\\s*(?:[^"+u+"\\\\]+|\\\\\\\\|\\\\.)"+u;if(t.match(new RegExp(f),!0))return S.linkHref}if("`"===s){var d=r.formatting;n.highlightFormatting&&(r.formatting="code"),t.eatWhile("`");var p=t.current().length;if(0==r.code)return r.code=p,h(r);if(p==r.code){var v=h(r);return r.code=0,v}return r.formatting=d,h(r)}if(r.code)return h(r);if("\\"===s&&(t.next(),n.highlightFormatting)){var y=h(r),x=S.formatting+"-escape";return y?y+" "+x:x}if("!"===s&&t.match(/\[[^\]]*\] ?(?:\(|\[)/,!1))return t.match(/\[[^\]]*\]/),r.inline=r.f=g,S.image;if("["===s&&t.match(/[^\]]*\](\(.*\)| ?\[.*?\])/,!1))return r.linkText=!0,n.highlightFormatting&&(r.formatting="link"),h(r);if("]"===s&&r.linkText&&t.match(/\(.*?\)| ?\[.*?\]/,!1)){n.highlightFormatting&&(r.formatting="link");var y=h(r);return r.linkText=!1,r.inline=r.f=g,y}if("<"===s&&t.match(/^(https?|ftps?):\/\/(?:[^\\>]|\\.)+>/,!1)){r.f=r.inline=m,n.highlightFormatting&&(r.formatting="link");var y=h(r);return y?y+=" ":y="",y+S.linkInline}if("<"===s&&t.match(/^[^> \\]+@(?:[^\\>]|\\.)+>/,!1)){r.f=r.inline=m,n.highlightFormatting&&(r.formatting="link");var y=h(r);return y?y+=" ":y="",y+S.linkEmail}if("<"===s&&t.match(/^(!--|\w)/,!1)){var b=t.string.indexOf(">",t.pos);if(-1!=b){var k=t.string.substring(t.start,b);/markdown\s*=\s*('|"){0,1}1('|"){0,1}/.test(k)&&(r.md_inside=!0)}return t.backUp(1),r.htmlState=e.startState(w),o(t,r,c)}if("<"===s&&t.match(/^\/\w*?>/))return r.md_inside=!1,"tag";var C=!1;if(!n.underscoresBreakWords&&"_"===s&&"_"!==t.peek()&&t.match(/(\w)/,!1)){var L=t.pos-2;if(L>=0){var T=t.string.charAt(L);"_"!==T&&T.match(/(\w)/,!1)&&(C=!0)}}if("*"===s||"_"===s&&!C)if(l&&" "===t.peek());else{if(r.strong===s&&t.eat(s)){n.highlightFormatting&&(r.formatting="strong");var v=h(r);return r.strong=!1,v}if(!r.strong&&t.eat(s))return r.strong=s,n.highlightFormatting&&(r.formatting="strong"),h(r);if(r.em===s){n.highlightFormatting&&(r.formatting="em");var v=h(r);return r.em=!1,v}if(!r.em)return r.em=s,n.highlightFormatting&&(r.formatting="em"),h(r)}else if(" "===s&&(t.eat("*")||t.eat("_"))){if(" "===t.peek())return h(r);t.backUp(1)}if(n.strikethrough)if("~"===s&&t.eatWhile(s)){if(r.strikethrough){n.highlightFormatting&&(r.formatting="strikethrough");var v=h(r);return r.strikethrough=!1,v}if(t.match(/^[^\s]/,!1))return r.strikethrough=!0,n.highlightFormatting&&(r.formatting="strikethrough"),h(r)}else if(" "===s&&t.match(/^~~/,!0)){if(" "===t.peek())return h(r);t.backUp(2)}return" "===s&&(t.match(/ +$/,!1)?r.trailingSpace++:r.trailingSpace&&(r.trailingSpaceNewLine=!0)),h(r)}function m(e,t){var r=e.next();if(">"===r){t.f=t.inline=p,n.highlightFormatting&&(t.formatting="link");var i=h(t);return i?i+=" ":i="",i+S.linkInline}return e.match(/^[^>]+/,!0),S.linkInline}function g(e,t){if(e.eatSpace())return null;var r=e.next();return"("===r||"["===r?(t.f=t.inline=v("("===r?")":"]",0),n.highlightFormatting&&(t.formatting="link-string"),t.linkHref=!0,h(t)):"error"}function v(e){return function(t,r){var i=t.next();if(i===e){r.f=r.inline=p,n.highlightFormatting&&(r.formatting="link-string");var o=h(r);return r.linkHref=!1,o}return t.match(P[e]),r.linkHref=!0,h(r)}}function y(e,t){return e.match(/^([^\]\\]|\\.)*\]:/,!1)?(t.f=x,e.next(),n.highlightFormatting&&(t.formatting="link"),t.linkText=!0,h(t)):i(e,t,p)}function x(e,t){if(e.match(/^\]:/,!0)){t.f=t.inline=b,n.highlightFormatting&&(t.formatting="link");var r=h(t);return t.linkText=!1,r}return e.match(/^([^\]\\]|\\.)+/,!0),S.linkText}function b(e,t){return e.eatSpace()?null:(e.match(/^[^\s]+/,!0),void 0===e.peek()?t.linkTitle=!0:e.match(/^(?:\s+(?:"(?:[^"\\]|\\\\|\\.)+"|'(?:[^'\\]|\\\\|\\.)+'|\((?:[^)\\]|\\\\|\\.)+\)))?/,!0),t.f=t.inline=p,S.linkHref+" url")}var w=e.getMode(t,"text/html"),k="null"==w.name;void 0===n.highlightFormatting&&(n.highlightFormatting=!1),void 0===n.maxBlockquoteDepth&&(n.maxBlockquoteDepth=0),void 0===n.underscoresBreakWords&&(n.underscoresBreakWords=!0),void 0===n.taskLists&&(n.taskLists=!1),void 0===n.strikethrough&&(n.strikethrough=!1),void 0===n.tokenTypeOverrides&&(n.tokenTypeOverrides={});var S={header:"header",code:"comment",quote:"quote",list1:"variable-2",list2:"variable-3",list3:"keyword",hr:"hr",image:"tag",formatting:"formatting",linkInline:"link",linkEmail:"link",linkText:"link",linkHref:"string",em:"em",strong:"strong",strikethrough:"strikethrough"};for(var C in S)S.hasOwnProperty(C)&&n.tokenTypeOverrides[C]&&(S[C]=n.tokenTypeOverrides[C]);var L=/^([*\-_])(?:\s*\1){2,}\s*$/,T=/^[*\-+]\s+/,M=/^[0-9]+([.)])\s+/,N=/^\[(x| )\](?=\s)/,A=n.allowAtxHeaderWithoutSpace?/^(#+)/:/^(#+)(?: |$)/,E=/^ *(?:\={1,}|-{1,})\s*$/,O=/^[^#!\[\]*_\\<>` "'(~]+/,I=new RegExp("^("+(n.fencedCodeBlocks===!0?"~~~+|```+":n.fencedCodeBlocks)+")[ \\t]*([\\w+#-]*)"),P={")":/^(?:[^\\\(\)]|\\.|\((?:[^\\\(\)]|\\.)*\))*?(?=\))/,"]":/^(?:[^\\\[\]]|\\.|\[(?:[^\\\[\\]]|\\.)*\])*?(?=\])/},R={startState:function(){return{f:s,prevLine:null,thisLine:null,block:s,htmlState:null,indentation:0,inline:p,text:d,formatting:!1,linkText:!1,linkHref:!1,linkTitle:!1,code:0,em:!1,strong:!1,header:0,hr:!1,taskList:!1,list:!1,listStack:[],quote:0,trailingSpace:0,trailingSpaceNewLine:!1,strikethrough:!1,fencedChars:null}},copyState:function(t){return{f:t.f,prevLine:t.prevLine,thisLine:t.thisLine,block:t.block,htmlState:t.htmlState&&e.copyState(w,t.htmlState),indentation:t.indentation,localMode:t.localMode,localState:t.localMode?e.copyState(t.localMode,t.localState):null,inline:t.inline,text:t.text,formatting:!1,linkTitle:t.linkTitle,code:t.code,em:t.em,strong:t.strong,strikethrough:t.strikethrough,header:t.header,hr:t.hr,taskList:t.taskList,list:t.list,listStack:t.listStack.slice(0),quote:t.quote,indentedCode:t.indentedCode,trailingSpace:t.trailingSpace,trailingSpaceNewLine:t.trailingSpaceNewLine,md_inside:t.md_inside,fencedChars:t.fencedChars}},token:function(e,t){if(t.formatting=!1,e!=t.thisLine){var n=t.header||t.hr;if(t.header=0,t.hr=!1,e.match(/^\s*$/,!0)||n){if(l(t),!n)return null;t.prevLine=null}t.prevLine=t.thisLine,t.thisLine=e,t.taskList=!1,t.trailingSpace=0,t.trailingSpaceNewLine=!1,t.f=t.block;var r=e.match(/^\s*/,!0)[0].replace(/\t/g,"    ").length;if(t.indentationDiff=Math.min(r-t.indentation,4),t.indentation=t.indentation+t.indentationDiff,r>0)return null}return t.f(e,t)},innerMode:function(e){return e.block==c?{state:e.htmlState,mode:w}:e.localState?{state:e.localState,mode:e.localMode}:{state:e,mode:R}},blankLine:l,getType:h,fold:"markdown"};return R},"xml"),e.defineMIME("text/x-markdown","markdown")})},{"../../lib/codemirror":10,"../meta":13,"../xml/xml":14}],13:[function(t,n,r){!function(i){"object"==typeof r&&"object"==typeof n?i(t("../lib/codemirror")):"function"==typeof e&&e.amd?e(["../lib/codemirror"],i):i(CodeMirror)}(function(e){"use strict";e.modeInfo=[{name:"APL",mime:"text/apl",mode:"apl",ext:["dyalog","apl"]},{name:"PGP",mimes:["application/pgp","application/pgp-keys","application/pgp-signature"],mode:"asciiarmor",ext:["pgp"]},{name:"ASN.1",mime:"text/x-ttcn-asn",mode:"asn.1",ext:["asn","asn1"]},{name:"Asterisk",mime:"text/x-asterisk",mode:"asterisk",file:/^extensions\.conf$/i},{name:"Brainfuck",mime:"text/x-brainfuck",mode:"brainfuck",ext:["b","bf"]},{name:"C",mime:"text/x-csrc",mode:"clike",ext:["c","h"]},{name:"C++",mime:"text/x-c++src",mode:"clike",ext:["cpp","c++","cc","cxx","hpp","h++","hh","hxx"],alias:["cpp"]},{name:"Cobol",mime:"text/x-cobol",mode:"cobol",ext:["cob","cpy"]},{name:"C#",mime:"text/x-csharp",mode:"clike",ext:["cs"],alias:["csharp"]},{name:"Clojure",mime:"text/x-clojure",mode:"clojure",ext:["clj","cljc","cljx"]},{name:"ClojureScript",mime:"text/x-clojurescript",mode:"clojure",ext:["cljs"]},{name:"Closure Stylesheets (GSS)",mime:"text/x-gss",mode:"css",ext:["gss"]},{name:"CMake",mime:"text/x-cmake",mode:"cmake",ext:["cmake","cmake.in"],file:/^CMakeLists.txt$/},{name:"CoffeeScript",mime:"text/x-coffeescript",mode:"coffeescript",ext:["coffee"],alias:["coffee","coffee-script"]},{name:"Common Lisp",mime:"text/x-common-lisp",mode:"commonlisp",ext:["cl","lisp","el"],alias:["lisp"]},{name:"Cypher",mime:"application/x-cypher-query",mode:"cypher",ext:["cyp","cypher"]},{name:"Cython",mime:"text/x-cython",mode:"python",ext:["pyx","pxd","pxi"]},{name:"Crystal",mime:"text/x-crystal",mode:"crystal",ext:["cr"]},{name:"CSS",mime:"text/css",mode:"css",ext:["css"]},{name:"CQL",mime:"text/x-cassandra",mode:"sql",ext:["cql"]},{name:"D",mime:"text/x-d",mode:"d",ext:["d"]},{name:"Dart",mimes:["application/dart","text/x-dart"],mode:"dart",ext:["dart"]},{name:"diff",mime:"text/x-diff",mode:"diff",ext:["diff","patch"]},{name:"Django",mime:"text/x-django",mode:"django"},{name:"Dockerfile",mime:"text/x-dockerfile",mode:"dockerfile",file:/^Dockerfile$/},{name:"DTD",mime:"application/xml-dtd",mode:"dtd",ext:["dtd"]},{name:"Dylan",mime:"text/x-dylan",mode:"dylan",ext:["dylan","dyl","intr"]},{name:"EBNF",mime:"text/x-ebnf",mode:"ebnf"},{name:"ECL",mime:"text/x-ecl",mode:"ecl",ext:["ecl"]},{name:"edn",mime:"application/edn",mode:"clojure",ext:["edn"]},{name:"Eiffel",mime:"text/x-eiffel",mode:"eiffel",ext:["e"]},{name:"Elm",mime:"text/x-elm",mode:"elm",ext:["elm"]},{name:"Embedded Javascript",mime:"application/x-ejs",mode:"htmlembedded",ext:["ejs"]},{name:"Embedded Ruby",mime:"application/x-erb",mode:"htmlembedded",ext:["erb"]},{name:"Erlang",mime:"text/x-erlang",mode:"erlang",ext:["erl"]},{name:"Factor",mime:"text/x-factor",mode:"factor",ext:["factor"]},{name:"FCL",mime:"text/x-fcl",mode:"fcl"},{name:"Forth",mime:"text/x-forth",mode:"forth",ext:["forth","fth","4th"]},{name:"Fortran",mime:"text/x-fortran",mode:"fortran",ext:["f","for","f77","f90"]},{name:"F#",mime:"text/x-fsharp",mode:"mllike",ext:["fs"],alias:["fsharp"]},{name:"Gas",mime:"text/x-gas",mode:"gas",ext:["s"]},{name:"Gherkin",mime:"text/x-feature",mode:"gherkin",ext:["feature"]},{name:"GitHub Flavored Markdown",mime:"text/x-gfm",mode:"gfm",file:/^(readme|contributing|history).md$/i},{name:"Go",mime:"text/x-go",mode:"go",ext:["go"]},{name:"Groovy",mime:"text/x-groovy",mode:"groovy",ext:["groovy","gradle"]},{name:"HAML",mime:"text/x-haml",mode:"haml",ext:["haml"]},{name:"Haskell",mime:"text/x-haskell",mode:"haskell",ext:["hs"]},{name:"Haskell (Literate)",mime:"text/x-literate-haskell",mode:"haskell-literate",ext:["lhs"]},{name:"Haxe",mime:"text/x-haxe",mode:"haxe",ext:["hx"]},{name:"HXML",mime:"text/x-hxml",mode:"haxe",ext:["hxml"]},{name:"ASP.NET",mime:"application/x-aspx",mode:"htmlembedded",ext:["aspx"],alias:["asp","aspx"]},{name:"HTML",mime:"text/html",mode:"htmlmixed",ext:["html","htm"],alias:["xhtml"]},{name:"HTTP",mime:"message/http",mode:"http"},{name:"IDL",mime:"text/x-idl",mode:"idl",ext:["pro"]},{name:"Jade",mime:"text/x-jade",mode:"jade",ext:["jade"]},{name:"Java",mime:"text/x-java",mode:"clike",ext:["java"]},{name:"Java Server Pages",mime:"application/x-jsp",mode:"htmlembedded",ext:["jsp"],alias:["jsp"]},{name:"JavaScript",mimes:["text/javascript","text/ecmascript","application/javascript","application/x-javascript","application/ecmascript"],mode:"javascript",ext:["js"],alias:["ecmascript","js","node"]},{name:"JSON",mimes:["application/json","application/x-json"],mode:"javascript",ext:["json","map"],alias:["json5"]},{name:"JSON-LD",mime:"application/ld+json",mode:"javascript",ext:["jsonld"],alias:["jsonld"]},{name:"JSX",mime:"text/jsx",mode:"jsx",ext:["jsx"]},{name:"Jinja2",mime:"null",mode:"jinja2"},{name:"Julia",mime:"text/x-julia",mode:"julia",ext:["jl"]},{name:"Kotlin",mime:"text/x-kotlin",mode:"clike",ext:["kt"]},{name:"LESS",mime:"text/x-less",mode:"css",ext:["less"]},{name:"LiveScript",mime:"text/x-livescript",mode:"livescript",ext:["ls"],alias:["ls"]},{name:"Lua",mime:"text/x-lua",mode:"lua",ext:["lua"]},{name:"Markdown",mime:"text/x-markdown",mode:"markdown",ext:["markdown","md","mkd"]},{name:"mIRC",mime:"text/mirc",mode:"mirc"},{name:"MariaDB SQL",mime:"text/x-mariadb",mode:"sql"},{name:"Mathematica",mime:"text/x-mathematica",mode:"mathematica",ext:["m","nb"]},{name:"Modelica",mime:"text/x-modelica",mode:"modelica",ext:["mo"]},{name:"MUMPS",mime:"text/x-mumps",mode:"mumps",ext:["mps"]},{name:"MS SQL",mime:"text/x-mssql",mode:"sql"},{name:"mbox",mime:"application/mbox",mode:"mbox",ext:["mbox"]},{name:"MySQL",mime:"text/x-mysql",mode:"sql"},{name:"Nginx",mime:"text/x-nginx-conf",mode:"nginx",file:/nginx.*\.conf$/i},{name:"NSIS",mime:"text/x-nsis",mode:"nsis",ext:["nsh","nsi"]},{name:"NTriples",mime:"text/n-triples",mode:"ntriples",ext:["nt"]},{name:"Objective C",mime:"text/x-objectivec",mode:"clike",ext:["m","mm"],alias:["objective-c","objc"]},{name:"OCaml",mime:"text/x-ocaml",mode:"mllike",ext:["ml","mli","mll","mly"]},{name:"Octave",mime:"text/x-octave",mode:"octave",ext:["m"]},{name:"Oz",mime:"text/x-oz",mode:"oz",ext:["oz"]},{name:"Pascal",mime:"text/x-pascal",mode:"pascal",ext:["p","pas"]},{name:"PEG.js",mime:"null",mode:"pegjs",ext:["jsonld"]},{name:"Perl",mime:"text/x-perl",mode:"perl",ext:["pl","pm"]},{name:"PHP",mime:"application/x-httpd-php",mode:"php",ext:["php","php3","php4","php5","phtml"]},{name:"Pig",mime:"text/x-pig",mode:"pig",ext:["pig"]},{name:"Plain Text",mime:"text/plain",mode:"null",ext:["txt","text","conf","def","list","log"]},{name:"PLSQL",mime:"text/x-plsql",mode:"sql",ext:["pls"]},{name:"PowerShell",mime:"application/x-powershell",mode:"powershell",ext:["ps1","psd1","psm1"]},{name:"Properties files",mime:"text/x-properties",mode:"properties",ext:["properties","ini","in"],alias:["ini","properties"]},{name:"ProtoBuf",mime:"text/x-protobuf",mode:"protobuf",ext:["proto"]},{name:"Python",mime:"text/x-python",mode:"python",ext:["BUILD","bzl","py","pyw"],file:/^(BUCK|BUILD)$/},{name:"Puppet",mime:"text/x-puppet",mode:"puppet",ext:["pp"]},{name:"Q",mime:"text/x-q",mode:"q",ext:["q"]},{name:"R",mime:"text/x-rsrc",mode:"r",ext:["r"],alias:["rscript"]},{name:"reStructuredText",mime:"text/x-rst",mode:"rst",ext:["rst"],alias:["rst"]},{name:"RPM Changes",mime:"text/x-rpm-changes",mode:"rpm"},{name:"RPM Spec",mime:"text/x-rpm-spec",mode:"rpm",ext:["spec"]},{name:"Ruby",mime:"text/x-ruby",mode:"ruby",ext:["rb"],alias:["jruby","macruby","rake","rb","rbx"]},{name:"Rust",mime:"text/x-rustsrc",mode:"rust",ext:["rs"]},{name:"SAS",mime:"text/x-sas",mode:"sas",ext:["sas"]},{name:"Sass",mime:"text/x-sass",mode:"sass",ext:["sass"]},{name:"Scala",mime:"text/x-scala",mode:"clike",ext:["scala"]},{name:"Scheme",mime:"text/x-scheme",mode:"scheme",ext:["scm","ss"]},{name:"SCSS",mime:"text/x-scss",mode:"css",ext:["scss"]},{name:"Shell",mime:"text/x-sh",mode:"shell",ext:["sh","ksh","bash"],alias:["bash","sh","zsh"],file:/^PKGBUILD$/},{name:"Sieve",mime:"application/sieve",mode:"sieve",ext:["siv","sieve"]},{name:"Slim",mimes:["text/x-slim","application/x-slim"],mode:"slim",ext:["slim"]},{name:"Smalltalk",mime:"text/x-stsrc",mode:"smalltalk",ext:["st"]},{name:"Smarty",mime:"text/x-smarty",mode:"smarty",ext:["tpl"]},{name:"Solr",mime:"text/x-solr",mode:"solr"},{name:"Soy",mime:"text/x-soy",mode:"soy",ext:["soy"],alias:["closure template"]},{name:"SPARQL",mime:"application/sparql-query",mode:"sparql",ext:["rq","sparql"],alias:["sparul"]},{name:"Spreadsheet",mime:"text/x-spreadsheet",mode:"spreadsheet",alias:["excel","formula"]},{name:"SQL",mime:"text/x-sql",mode:"sql",ext:["sql"]},{name:"Squirrel",mime:"text/x-squirrel",mode:"clike",ext:["nut"]},{name:"Swift",mime:"text/x-swift",mode:"swift",ext:["swift"]},{name:"sTeX",mime:"text/x-stex",mode:"stex"},{name:"LaTeX",mime:"text/x-latex",mode:"stex",ext:["text","ltx"],alias:["tex"]},{name:"SystemVerilog",mime:"text/x-systemverilog",mode:"verilog",ext:["v"]},{name:"Tcl",mime:"text/x-tcl",mode:"tcl",ext:["tcl"]},{name:"Textile",mime:"text/x-textile",mode:"textile",ext:["textile"]},{name:"TiddlyWiki ",mime:"text/x-tiddlywiki",mode:"tiddlywiki"},{name:"Tiki wiki",mime:"text/tiki",mode:"tiki"},{name:"TOML",mime:"text/x-toml",mode:"toml",ext:["toml"]},{name:"Tornado",mime:"text/x-tornado",mode:"tornado"},{name:"troff",mime:"text/troff",mode:"troff",ext:["1","2","3","4","5","6","7","8","9"]},{name:"TTCN",mime:"text/x-ttcn",mode:"ttcn",ext:["ttcn","ttcn3","ttcnpp"]},{name:"TTCN_CFG",mime:"text/x-ttcn-cfg",mode:"ttcn-cfg",ext:["cfg"]},{name:"Turtle",mime:"text/turtle",mode:"turtle",ext:["ttl"]},{name:"TypeScript",mime:"application/typescript",mode:"javascript",ext:["ts"],alias:["ts"]},{name:"Twig",mime:"text/x-twig",mode:"twig"},{name:"Web IDL",mime:"text/x-webidl",mode:"webidl",ext:["webidl"]},{name:"VB.NET",mime:"text/x-vb",mode:"vb",ext:["vb"]},{name:"VBScript",mime:"text/vbscript",mode:"vbscript",ext:["vbs"]},{name:"Velocity",mime:"text/velocity",mode:"velocity",ext:["vtl"]},{name:"Verilog",mime:"text/x-verilog",mode:"verilog",ext:["v"]},{name:"VHDL",mime:"text/x-vhdl",mode:"vhdl",ext:["vhd","vhdl"]},{name:"XML",mimes:["application/xml","text/xml"],mode:"xml",ext:["xml","xsl","xsd"],alias:["rss","wsdl","xsd"]},{name:"XQuery",mime:"application/xquery",mode:"xquery",ext:["xy","xquery"]},{name:"Yacas",mime:"text/x-yacas",mode:"yacas",ext:["ys"]},{name:"YAML",mime:"text/x-yaml",mode:"yaml",ext:["yaml","yml"],alias:["yml"]},{name:"Z80",mime:"text/x-z80",mode:"z80",ext:["z80"]},{name:"mscgen",mime:"text/x-mscgen",mode:"mscgen",ext:["mscgen","mscin","msc"]},{name:"xu",mime:"text/x-xu",mode:"mscgen",ext:["xu"]},{name:"msgenny",mime:"text/x-msgenny",mode:"mscgen",ext:["msgenny"]}];for(var t=0;t<e.modeInfo.length;t++){var n=e.modeInfo[t];n.mimes&&(n.mime=n.mimes[0])}e.findModeByMIME=function(t){t=t.toLowerCase();for(var n=0;n<e.modeInfo.length;n++){var r=e.modeInfo[n];if(r.mime==t)return r;if(r.mimes)for(var i=0;i<r.mimes.length;i++)if(r.mimes[i]==t)return r}},e.findModeByExtension=function(t){for(var n=0;n<e.modeInfo.length;n++){var r=e.modeInfo[n];if(r.ext)for(var i=0;i<r.ext.length;i++)if(r.ext[i]==t)return r}},e.findModeByFileName=function(t){for(var n=0;n<e.modeInfo.length;n++){var r=e.modeInfo[n];if(r.file&&r.file.test(t))return r}var i=t.lastIndexOf("."),o=i>-1&&t.substring(i+1,t.length);return o?e.findModeByExtension(o):void 0},e.findModeByName=function(t){t=t.toLowerCase();for(var n=0;n<e.modeInfo.length;n++){var r=e.modeInfo[n];if(r.name.toLowerCase()==t)return r;if(r.alias)for(var i=0;i<r.alias.length;i++)if(r.alias[i].toLowerCase()==t)return r}}})},{"../lib/codemirror":10}],14:[function(t,n,r){!function(i){"object"==typeof r&&"object"==typeof n?i(t("../../lib/codemirror")):"function"==typeof e&&e.amd?e(["../../lib/codemirror"],i):i(CodeMirror)}(function(e){"use strict";var t={autoSelfClosers:{area:!0,base:!0,br:!0,col:!0,command:!0,embed:!0,frame:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0,menuitem:!0},implicitlyClosed:{dd:!0,li:!0,optgroup:!0,option:!0,p:!0,rp:!0,rt:!0,tbody:!0,td:!0,tfoot:!0,th:!0,tr:!0},contextGrabbers:{dd:{dd:!0,dt:!0},dt:{dd:!0,dt:!0},li:{li:!0},option:{option:!0,optgroup:!0},optgroup:{optgroup:!0},p:{address:!0,article:!0,aside:!0,blockquote:!0,dir:!0,div:!0,dl:!0,fieldset:!0,footer:!0,form:!0,h1:!0,h2:!0,h3:!0,h4:!0,h5:!0,h6:!0,header:!0,hgroup:!0,hr:!0,menu:!0,nav:!0,ol:!0,p:!0,pre:!0,section:!0,table:!0,ul:!0},rp:{rp:!0,rt:!0},rt:{rp:!0,rt:!0},tbody:{tbody:!0,tfoot:!0},td:{td:!0,th:!0},tfoot:{tbody:!0},th:{td:!0,th:!0},thead:{tbody:!0,tfoot:!0},tr:{tr:!0}},doNotIndent:{pre:!0},allowUnquoted:!0,allowMissing:!0,caseFold:!0},n={autoSelfClosers:{},implicitlyClosed:{},contextGrabbers:{},doNotIndent:{},allowUnquoted:!1,allowMissing:!1,caseFold:!1};e.defineMode("xml",function(r,i){function o(e,t){function n(n){return t.tokenize=n,n(e,t)}var r=e.next();if("<"==r)return e.eat("!")?e.eat("[")?e.match("CDATA[")?n(s("atom","]]>")):null:e.match("--")?n(s("comment","-->")):e.match("DOCTYPE",!0,!0)?(e.eatWhile(/[\w\._\-]/),n(c(1))):null:e.eat("?")?(e.eatWhile(/[\w\._\-]/),t.tokenize=s("meta","?>"),"meta"):(T=e.eat("/")?"closeTag":"openTag",t.tokenize=a,"tag bracket");if("&"==r){var i;return i=e.eat("#")?e.eat("x")?e.eatWhile(/[a-fA-F\d]/)&&e.eat(";"):e.eatWhile(/[\d]/)&&e.eat(";"):e.eatWhile(/[\w\.\-:]/)&&e.eat(";"),i?"atom":"error"}return e.eatWhile(/[^&<]/),null}function a(e,t){var n=e.next();if(">"==n||"/"==n&&e.eat(">"))return t.tokenize=o,T=">"==n?"endTag":"selfcloseTag","tag bracket";if("="==n)return T="equals",null;if("<"==n){t.tokenize=o,t.state=d,t.tagName=t.tagStart=null;var r=t.tokenize(e,t);return r?r+" tag error":"tag error"}return/[\'\"]/.test(n)?(t.tokenize=l(n),t.stringStartCol=e.column(),t.tokenize(e,t)):(e.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/),"word")}function l(e){var t=function(t,n){for(;!t.eol();)if(t.next()==e){n.tokenize=a;break}return"string"};return t.isInAttribute=!0,t}function s(e,t){return function(n,r){for(;!n.eol();){if(n.match(t)){r.tokenize=o;break}n.next()}return e}}function c(e){return function(t,n){for(var r;null!=(r=t.next());){if("<"==r)return n.tokenize=c(e+1),n.tokenize(t,n);if(">"==r){if(1==e){n.tokenize=o;break}return n.tokenize=c(e-1),n.tokenize(t,n)}}return"meta"}}function u(e,t,n){this.prev=e.context,this.tagName=t,this.indent=e.indented,this.startOfLine=n,(S.doNotIndent.hasOwnProperty(t)||e.context&&e.context.noIndent)&&(this.noIndent=!0)}function f(e){e.context&&(e.context=e.context.prev)}function h(e,t){for(var n;;){if(!e.context)return;if(n=e.context.tagName,!S.contextGrabbers.hasOwnProperty(n)||!S.contextGrabbers[n].hasOwnProperty(t))return;f(e)}}function d(e,t,n){return"openTag"==e?(n.tagStart=t.column(),p):"closeTag"==e?m:d}function p(e,t,n){return"word"==e?(n.tagName=t.current(),M="tag",y):(M="error",p)}function m(e,t,n){if("word"==e){var r=t.current();return n.context&&n.context.tagName!=r&&S.implicitlyClosed.hasOwnProperty(n.context.tagName)&&f(n),n.context&&n.context.tagName==r||S.matchClosing===!1?(M="tag",g):(M="tag error",v)}return M="error",v}function g(e,t,n){return"endTag"!=e?(M="error",g):(f(n),d)}function v(e,t,n){return M="error",g(e,t,n)}function y(e,t,n){if("word"==e)return M="attribute",x;if("endTag"==e||"selfcloseTag"==e){var r=n.tagName,i=n.tagStart;return n.tagName=n.tagStart=null,"selfcloseTag"==e||S.autoSelfClosers.hasOwnProperty(r)?h(n,r):(h(n,r),n.context=new u(n,r,i==n.indented)),d}return M="error",y}function x(e,t,n){return"equals"==e?b:(S.allowMissing||(M="error"),y(e,t,n))}function b(e,t,n){return"string"==e?w:"word"==e&&S.allowUnquoted?(M="string",y):(M="error",y(e,t,n))}function w(e,t,n){return"string"==e?w:y(e,t,n)}var k=r.indentUnit,S={},C=i.htmlMode?t:n;for(var L in C)S[L]=C[L];for(var L in i)S[L]=i[L];var T,M;return o.isInText=!0,{startState:function(e){var t={tokenize:o,state:d,indented:e||0,tagName:null,tagStart:null,context:null};return null!=e&&(t.baseIndent=e),t},token:function(e,t){if(!t.tagName&&e.sol()&&(t.indented=e.indentation()),e.eatSpace())return null;T=null;var n=t.tokenize(e,t);return(n||T)&&"comment"!=n&&(M=null,t.state=t.state(T||n,e,t),M&&(n="error"==M?n+" error":M)),n},indent:function(t,n,r){var i=t.context;if(t.tokenize.isInAttribute)return t.tagStart==t.indented?t.stringStartCol+1:t.indented+k;if(i&&i.noIndent)return e.Pass;if(t.tokenize!=a&&t.tokenize!=o)return r?r.match(/^(\s*)/)[0].length:0;if(t.tagName)return S.multilineTagIndentPastTag!==!1?t.tagStart+t.tagName.length+2:t.tagStart+k*(S.multilineTagIndentFactor||1);if(S.alignCDATA&&/<!\[CDATA\[/.test(n))return 0;var l=n&&/^<(\/)?([\w_:\.-]*)/.exec(n);if(l&&l[1])for(;i;){if(i.tagName==l[2]){i=i.prev;break}if(!S.implicitlyClosed.hasOwnProperty(i.tagName))break;i=i.prev}else if(l)for(;i;){var s=S.contextGrabbers[i.tagName];if(!s||!s.hasOwnProperty(l[2]))break;i=i.prev}for(;i&&i.prev&&!i.startOfLine;)i=i.prev;return i?i.indent+k:t.baseIndent||0},electricInput:/<\/[\s\w:]+>$/,blockCommentStart:"<!--",blockCommentEnd:"-->",configuration:S.htmlMode?"html":"xml",helperType:S.htmlMode?"html":"xml",skipAttribute:function(e){e.state==b&&(e.state=y)}}}),e.defineMIME("text/xml","xml"),e.defineMIME("application/xml","xml"),e.mimeModes.hasOwnProperty("text/html")||e.defineMIME("text/html",{name:"xml",htmlMode:!0})})},{"../../lib/codemirror":10}],15:[function(e,t,n){n.read=function(e,t,n,r,i){var o,a,l=8*i-r-1,s=(1<<l)-1,c=s>>1,u=-7,f=n?i-1:0,h=n?-1:1,d=e[t+f];for(f+=h,o=d&(1<<-u)-1,d>>=-u,u+=l;u>0;o=256*o+e[t+f],f+=h,u-=8);for(a=o&(1<<-u)-1,o>>=-u,u+=r;u>0;a=256*a+e[t+f],f+=h,u-=8);if(0===o)o=1-c;else{if(o===s)return a?NaN:(d?-1:1)*(1/0);a+=Math.pow(2,r),o-=c}return(d?-1:1)*a*Math.pow(2,o-r)},n.write=function(e,t,n,r,i,o){var a,l,s,c=8*o-i-1,u=(1<<c)-1,f=u>>1,h=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,d=r?0:o-1,p=r?1:-1,m=0>t||0===t&&0>1/t?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(l=isNaN(t)?1:0,a=u):(a=Math.floor(Math.log(t)/Math.LN2),t*(s=Math.pow(2,-a))<1&&(a--,s*=2),t+=a+f>=1?h/s:h*Math.pow(2,1-f),t*s>=2&&(a++,s/=2),a+f>=u?(l=0,a=u):a+f>=1?(l=(t*s-1)*Math.pow(2,i),a+=f):(l=t*Math.pow(2,f-1)*Math.pow(2,i),a=0));i>=8;e[n+d]=255&l,d+=p,l/=256,i-=8);for(a=a<<i|l,c+=i;c>0;e[n+d]=255&a,d+=p,a/=256,c-=8);e[n+d-p]|=128*m}},{}],16:[function(e,t,n){var r={}.toString;t.exports=Array.isArray||function(e){return"[object Array]"==r.call(e)}},{}],17:[function(t,n,r){(function(t){(function(){function t(e){this.tokens=[],this.tokens.links={},this.options=e||h.defaults,this.rules=d.normal,this.options.gfm&&(this.options.tables?this.rules=d.tables:this.rules=d.gfm)}function i(e,t){if(this.options=t||h.defaults,this.links=e,this.rules=p.normal,this.renderer=this.options.renderer||new o,this.renderer.options=this.options,!this.links)throw new Error("Tokens array requires a `links` property.");this.options.gfm?this.options.breaks?this.rules=p.breaks:this.rules=p.gfm:this.options.pedantic&&(this.rules=p.pedantic)}function o(e){this.options=e||{}}function a(e){this.tokens=[],this.token=null,this.options=e||h.defaults,this.options.renderer=this.options.renderer||new o,this.renderer=this.options.renderer,this.renderer.options=this.options}function l(e,t){return e.replace(t?/&/g:/&(?!#?\w+;)/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function s(e){return e.replace(/&([#\w]+);/g,function(e,t){return t=t.toLowerCase(),"colon"===t?":":"#"===t.charAt(0)?"x"===t.charAt(1)?String.fromCharCode(parseInt(t.substring(2),16)):String.fromCharCode(+t.substring(1)):""})}function c(e,t){return e=e.source,t=t||"",function n(r,i){return r?(i=i.source||i,i=i.replace(/(^|[^\[])\^/g,"$1"),e=e.replace(r,i),n):new RegExp(e,t)}}function u(){}function f(e){for(var t,n,r=1;r<arguments.length;r++){t=arguments[r];for(n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])}return e}function h(e,n,r){if(r||"function"==typeof n){r||(r=n,n=null),n=f({},h.defaults,n||{});var i,o,s=n.highlight,c=0;try{i=t.lex(e,n)}catch(u){return r(u)}o=i.length;var d=function(e){if(e)return n.highlight=s,r(e);var t;try{t=a.parse(i,n)}catch(o){e=o}return n.highlight=s,e?r(e):r(null,t)};if(!s||s.length<3)return d();if(delete n.highlight,!o)return d();for(;c<i.length;c++)!function(e){return"code"!==e.type?--o||d():s(e.text,e.lang,function(t,n){return t?d(t):null==n||n===e.text?--o||d():(e.text=n,e.escaped=!0,void(--o||d()))})}(i[c])}else try{return n&&(n=f({},h.defaults,n)),a.parse(t.lex(e,n),n)}catch(u){if(u.message+="\nPlease report this to https://github.com/chjj/marked.",(n||h.defaults).silent)return"<p>An error occured:</p><pre>"+l(u.message+"",!0)+"</pre>";throw u}}var d={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:u,hr:/^( *[-*_]){3,} *(?:\n+|$)/,heading:/^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,nptable:u,lheading:/^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,blockquote:/^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,list:/^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:/^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,table:u,paragraph:/^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,text:/^[^\n]+/};d.bullet=/(?:[*+-]|\d+\.)/,d.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/,d.item=c(d.item,"gm")(/bull/g,d.bullet)(),d.list=c(d.list)(/bull/g,d.bullet)("hr","\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))")("def","\\n+(?="+d.def.source+")")(),d.blockquote=c(d.blockquote)("def",d.def)(),d._tag="(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b",d.html=c(d.html)("comment",/<!--[\s\S]*?-->/)("closed",/<(tag)[\s\S]+?<\/\1>/)("closing",/<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)(/tag/g,d._tag)(),d.paragraph=c(d.paragraph)("hr",d.hr)("heading",d.heading)("lheading",d.lheading)("blockquote",d.blockquote)("tag","<"+d._tag)("def",d.def)(),d.normal=f({},d),d.gfm=f({},d.normal,{fences:/^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/,paragraph:/^/,heading:/^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/}),d.gfm.paragraph=c(d.paragraph)("(?!","(?!"+d.gfm.fences.source.replace("\\1","\\2")+"|"+d.list.source.replace("\\1","\\3")+"|")(),d.tables=f({},d.gfm,{nptable:/^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,table:/^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/}),t.rules=d,t.lex=function(e,n){var r=new t(n);return r.lex(e)},t.prototype.lex=function(e){return e=e.replace(/\r\n|\r/g,"\n").replace(/\t/g,"    ").replace(/\u00a0/g," ").replace(/\u2424/g,"\n"),this.token(e,!0)},t.prototype.token=function(e,t,n){for(var r,i,o,a,l,s,c,u,f,e=e.replace(/^ +$/gm,"");e;)if((o=this.rules.newline.exec(e))&&(e=e.substring(o[0].length),o[0].length>1&&this.tokens.push({type:"space"})),o=this.rules.code.exec(e))e=e.substring(o[0].length),o=o[0].replace(/^ {4}/gm,""),this.tokens.push({type:"code",text:this.options.pedantic?o:o.replace(/\n+$/,"")});else if(o=this.rules.fences.exec(e))e=e.substring(o[0].length),this.tokens.push({type:"code",lang:o[2],text:o[3]||""});else if(o=this.rules.heading.exec(e))e=e.substring(o[0].length),this.tokens.push({type:"heading",depth:o[1].length,text:o[2]});else if(t&&(o=this.rules.nptable.exec(e))){for(e=e.substring(o[0].length),s={type:"table",header:o[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:o[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:o[3].replace(/\n$/,"").split("\n")},u=0;u<s.align.length;u++)/^ *-+: *$/.test(s.align[u])?s.align[u]="right":/^ *:-+: *$/.test(s.align[u])?s.align[u]="center":/^ *:-+ *$/.test(s.align[u])?s.align[u]="left":s.align[u]=null;for(u=0;u<s.cells.length;u++)s.cells[u]=s.cells[u].split(/ *\| */);this.tokens.push(s)}else if(o=this.rules.lheading.exec(e))e=e.substring(o[0].length),this.tokens.push({type:"heading",depth:"="===o[2]?1:2,text:o[1]});else if(o=this.rules.hr.exec(e))e=e.substring(o[0].length),this.tokens.push({type:"hr"});else if(o=this.rules.blockquote.exec(e))e=e.substring(o[0].length),this.tokens.push({type:"blockquote_start"}),o=o[0].replace(/^ *> ?/gm,""),this.token(o,t,!0),this.tokens.push({type:"blockquote_end"});else if(o=this.rules.list.exec(e)){for(e=e.substring(o[0].length),a=o[2],this.tokens.push({type:"list_start",ordered:a.length>1}),o=o[0].match(this.rules.item),r=!1,f=o.length,u=0;f>u;u++)s=o[u],c=s.length,s=s.replace(/^ *([*+-]|\d+\.) +/,""),~s.indexOf("\n ")&&(c-=s.length,s=this.options.pedantic?s.replace(/^ {1,4}/gm,""):s.replace(new RegExp("^ {1,"+c+"}","gm"),"")),this.options.smartLists&&u!==f-1&&(l=d.bullet.exec(o[u+1])[0],a===l||a.length>1&&l.length>1||(e=o.slice(u+1).join("\n")+e,u=f-1)),i=r||/\n\n(?!\s*$)/.test(s),u!==f-1&&(r="\n"===s.charAt(s.length-1),i||(i=r)),this.tokens.push({type:i?"loose_item_start":"list_item_start"}),this.token(s,!1,n),this.tokens.push({type:"list_item_end"});this.tokens.push({type:"list_end"})}else if(o=this.rules.html.exec(e))e=e.substring(o[0].length),this.tokens.push({type:this.options.sanitize?"paragraph":"html",pre:!this.options.sanitizer&&("pre"===o[1]||"script"===o[1]||"style"===o[1]),text:o[0]});else if(!n&&t&&(o=this.rules.def.exec(e)))e=e.substring(o[0].length),this.tokens.links[o[1].toLowerCase()]={href:o[2],title:o[3]};else if(t&&(o=this.rules.table.exec(e))){for(e=e.substring(o[0].length),s={type:"table",
61896header:o[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:o[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:o[3].replace(/(?: *\| *)?\n$/,"").split("\n")},u=0;u<s.align.length;u++)/^ *-+: *$/.test(s.align[u])?s.align[u]="right":/^ *:-+: *$/.test(s.align[u])?s.align[u]="center":/^ *:-+ *$/.test(s.align[u])?s.align[u]="left":s.align[u]=null;for(u=0;u<s.cells.length;u++)s.cells[u]=s.cells[u].replace(/^ *\| *| *\| *$/g,"").split(/ *\| */);this.tokens.push(s)}else if(t&&(o=this.rules.paragraph.exec(e)))e=e.substring(o[0].length),this.tokens.push({type:"paragraph",text:"\n"===o[1].charAt(o[1].length-1)?o[1].slice(0,-1):o[1]});else if(o=this.rules.text.exec(e))e=e.substring(o[0].length),this.tokens.push({type:"text",text:o[0]});else if(e)throw new Error("Infinite loop on byte: "+e.charCodeAt(0));return this.tokens};var p={escape:/^\\([\\`*{}\[\]()#+\-.!_>])/,autolink:/^<([^ >]+(@|:\/)[^ >]+)>/,url:u,tag:/^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,link:/^!?\[(inside)\]\(href\)/,reflink:/^!?\[(inside)\]\s*\[([^\]]*)\]/,nolink:/^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,strong:/^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,em:/^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,code:/^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,br:/^ {2,}\n(?!\s*$)/,del:u,text:/^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/};p._inside=/(?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*/,p._href=/\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/,p.link=c(p.link)("inside",p._inside)("href",p._href)(),p.reflink=c(p.reflink)("inside",p._inside)(),p.normal=f({},p),p.pedantic=f({},p.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/}),p.gfm=f({},p.normal,{escape:c(p.escape)("])","~|])")(),url:/^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,del:/^~~(?=\S)([\s\S]*?\S)~~/,text:c(p.text)("]|","~]|")("|","|https?://|")()}),p.breaks=f({},p.gfm,{br:c(p.br)("{2,}","*")(),text:c(p.gfm.text)("{2,}","*")()}),i.rules=p,i.output=function(e,t,n){var r=new i(t,n);return r.output(e)},i.prototype.output=function(e){for(var t,n,r,i,o="";e;)if(i=this.rules.escape.exec(e))e=e.substring(i[0].length),o+=i[1];else if(i=this.rules.autolink.exec(e))e=e.substring(i[0].length),"@"===i[2]?(n=":"===i[1].charAt(6)?this.mangle(i[1].substring(7)):this.mangle(i[1]),r=this.mangle("mailto:")+n):(n=l(i[1]),r=n),o+=this.renderer.link(r,null,n);else if(this.inLink||!(i=this.rules.url.exec(e))){if(i=this.rules.tag.exec(e))!this.inLink&&/^<a /i.test(i[0])?this.inLink=!0:this.inLink&&/^<\/a>/i.test(i[0])&&(this.inLink=!1),e=e.substring(i[0].length),o+=this.options.sanitize?this.options.sanitizer?this.options.sanitizer(i[0]):l(i[0]):i[0];else if(i=this.rules.link.exec(e))e=e.substring(i[0].length),this.inLink=!0,o+=this.outputLink(i,{href:i[2],title:i[3]}),this.inLink=!1;else if((i=this.rules.reflink.exec(e))||(i=this.rules.nolink.exec(e))){if(e=e.substring(i[0].length),t=(i[2]||i[1]).replace(/\s+/g," "),t=this.links[t.toLowerCase()],!t||!t.href){o+=i[0].charAt(0),e=i[0].substring(1)+e;continue}this.inLink=!0,o+=this.outputLink(i,t),this.inLink=!1}else if(i=this.rules.strong.exec(e))e=e.substring(i[0].length),o+=this.renderer.strong(this.output(i[2]||i[1]));else if(i=this.rules.em.exec(e))e=e.substring(i[0].length),o+=this.renderer.em(this.output(i[2]||i[1]));else if(i=this.rules.code.exec(e))e=e.substring(i[0].length),o+=this.renderer.codespan(l(i[2],!0));else if(i=this.rules.br.exec(e))e=e.substring(i[0].length),o+=this.renderer.br();else if(i=this.rules.del.exec(e))e=e.substring(i[0].length),o+=this.renderer.del(this.output(i[1]));else if(i=this.rules.text.exec(e))e=e.substring(i[0].length),o+=this.renderer.text(l(this.smartypants(i[0])));else if(e)throw new Error("Infinite loop on byte: "+e.charCodeAt(0))}else e=e.substring(i[0].length),n=l(i[1]),r=n,o+=this.renderer.link(r,null,n);return o},i.prototype.outputLink=function(e,t){var n=l(t.href),r=t.title?l(t.title):null;return"!"!==e[0].charAt(0)?this.renderer.link(n,r,this.output(e[1])):this.renderer.image(n,r,l(e[1]))},i.prototype.smartypants=function(e){return this.options.smartypants?e.replace(/---/g,"—").replace(/--/g,"–").replace(/(^|[-\u2014\/(\[{"\s])'/g,"$1‘").replace(/'/g,"’").replace(/(^|[-\u2014\/(\[{\u2018\s])"/g,"$1“").replace(/"/g,"”").replace(/\.{3}/g,"…"):e},i.prototype.mangle=function(e){if(!this.options.mangle)return e;for(var t,n="",r=e.length,i=0;r>i;i++)t=e.charCodeAt(i),Math.random()>.5&&(t="x"+t.toString(16)),n+="&#"+t+";";return n},o.prototype.code=function(e,t,n){if(this.options.highlight){var r=this.options.highlight(e,t);null!=r&&r!==e&&(n=!0,e=r)}return t?'<pre><code class="'+this.options.langPrefix+l(t,!0)+'">'+(n?e:l(e,!0))+"\n</code></pre>\n":"<pre><code>"+(n?e:l(e,!0))+"\n</code></pre>"},o.prototype.blockquote=function(e){return"<blockquote>\n"+e+"</blockquote>\n"},o.prototype.html=function(e){return e},o.prototype.heading=function(e,t,n){return"<h"+t+' id="'+this.options.headerPrefix+n.toLowerCase().replace(/[^\w]+/g,"-")+'">'+e+"</h"+t+">\n"},o.prototype.hr=function(){return this.options.xhtml?"<hr/>\n":"<hr>\n"},o.prototype.list=function(e,t){var n=t?"ol":"ul";return"<"+n+">\n"+e+"</"+n+">\n"},o.prototype.listitem=function(e){return"<li>"+e+"</li>\n"},o.prototype.paragraph=function(e){return"<p>"+e+"</p>\n"},o.prototype.table=function(e,t){return"<table>\n<thead>\n"+e+"</thead>\n<tbody>\n"+t+"</tbody>\n</table>\n"},o.prototype.tablerow=function(e){return"<tr>\n"+e+"</tr>\n"},o.prototype.tablecell=function(e,t){var n=t.header?"th":"td",r=t.align?"<"+n+' style="text-align:'+t.align+'">':"<"+n+">";return r+e+"</"+n+">\n"},o.prototype.strong=function(e){return"<strong>"+e+"</strong>"},o.prototype.em=function(e){return"<em>"+e+"</em>"},o.prototype.codespan=function(e){return"<code>"+e+"</code>"},o.prototype.br=function(){return this.options.xhtml?"<br/>":"<br>"},o.prototype.del=function(e){return"<del>"+e+"</del>"},o.prototype.link=function(e,t,n){if(this.options.sanitize){try{var r=decodeURIComponent(s(e)).replace(/[^\w:]/g,"").toLowerCase()}catch(i){return""}if(0===r.indexOf("javascript:")||0===r.indexOf("vbscript:"))return""}var o='<a href="'+e+'"';return t&&(o+=' title="'+t+'"'),o+=">"+n+"</a>"},o.prototype.image=function(e,t,n){var r='<img src="'+e+'" alt="'+n+'"';return t&&(r+=' title="'+t+'"'),r+=this.options.xhtml?"/>":">"},o.prototype.text=function(e){return e},a.parse=function(e,t,n){var r=new a(t,n);return r.parse(e)},a.prototype.parse=function(e){this.inline=new i(e.links,this.options,this.renderer),this.tokens=e.reverse();for(var t="";this.next();)t+=this.tok();return t},a.prototype.next=function(){return this.token=this.tokens.pop()},a.prototype.peek=function(){return this.tokens[this.tokens.length-1]||0},a.prototype.parseText=function(){for(var e=this.token.text;"text"===this.peek().type;)e+="\n"+this.next().text;return this.inline.output(e)},a.prototype.tok=function(){switch(this.token.type){case"space":return"";case"hr":return this.renderer.hr();case"heading":return this.renderer.heading(this.inline.output(this.token.text),this.token.depth,this.token.text);case"code":return this.renderer.code(this.token.text,this.token.lang,this.token.escaped);case"table":var e,t,n,r,i,o="",a="";for(n="",e=0;e<this.token.header.length;e++)r={header:!0,align:this.token.align[e]},n+=this.renderer.tablecell(this.inline.output(this.token.header[e]),{header:!0,align:this.token.align[e]});for(o+=this.renderer.tablerow(n),e=0;e<this.token.cells.length;e++){for(t=this.token.cells[e],n="",i=0;i<t.length;i++)n+=this.renderer.tablecell(this.inline.output(t[i]),{header:!1,align:this.token.align[i]});a+=this.renderer.tablerow(n)}return this.renderer.table(o,a);case"blockquote_start":for(var a="";"blockquote_end"!==this.next().type;)a+=this.tok();return this.renderer.blockquote(a);case"list_start":for(var a="",l=this.token.ordered;"list_end"!==this.next().type;)a+=this.tok();return this.renderer.list(a,l);case"list_item_start":for(var a="";"list_item_end"!==this.next().type;)a+="text"===this.token.type?this.parseText():this.tok();return this.renderer.listitem(a);case"loose_item_start":for(var a="";"list_item_end"!==this.next().type;)a+=this.tok();return this.renderer.listitem(a);case"html":var s=this.token.pre||this.options.pedantic?this.token.text:this.inline.output(this.token.text);return this.renderer.html(s);case"paragraph":return this.renderer.paragraph(this.inline.output(this.token.text));case"text":return this.renderer.paragraph(this.parseText())}},u.exec=u,h.options=h.setOptions=function(e){return f(h.defaults,e),h},h.defaults={gfm:!0,tables:!0,breaks:!1,pedantic:!1,sanitize:!1,sanitizer:null,mangle:!0,smartLists:!1,silent:!1,highlight:null,langPrefix:"lang-",smartypants:!1,headerPrefix:"",renderer:new o,xhtml:!1},h.Parser=a,h.parser=a.parse,h.Renderer=o,h.Lexer=t,h.lexer=t.lex,h.InlineLexer=i,h.inlineLexer=i.output,h.parse=h,"undefined"!=typeof n&&"object"==typeof r?n.exports=h:"function"==typeof e&&e.amd?e(function(){return h}):this.marked=h}).call(function(){return this||("undefined"!=typeof window?window:t)}())}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],18:[function(e,t,n){(function(n,r){"use strict";var i=function(e,t,n,i){if(i=i||{},this.dictionary=null,this.rules={},this.dictionaryTable={},this.compoundRules=[],this.compoundRuleCodes={},this.replacementTable=[],this.flags=i.flags||{},e){if(this.dictionary=e,"undefined"!=typeof window&&"chrome"in window&&"extension"in window.chrome&&"getURL"in window.chrome.extension)t||(t=this._readFile(chrome.extension.getURL("lib/typo/dictionaries/"+e+"/"+e+".aff"))),n||(n=this._readFile(chrome.extension.getURL("lib/typo/dictionaries/"+e+"/"+e+".dic")));else{if(i.dictionaryPath)var o=i.dictionaryPath;else if("undefined"!=typeof r)var o=r+"/dictionaries";else var o="./dictionaries";t||(t=this._readFile(o+"/"+e+"/"+e+".aff")),n||(n=this._readFile(o+"/"+e+"/"+e+".dic"))}this.rules=this._parseAFF(t),this.compoundRuleCodes={};for(var a=0,l=this.compoundRules.length;l>a;a++)for(var s=this.compoundRules[a],c=0,u=s.length;u>c;c++)this.compoundRuleCodes[s[c]]=[];"ONLYINCOMPOUND"in this.flags&&(this.compoundRuleCodes[this.flags.ONLYINCOMPOUND]=[]),this.dictionaryTable=this._parseDIC(n);for(var a in this.compoundRuleCodes)0==this.compoundRuleCodes[a].length&&delete this.compoundRuleCodes[a];for(var a=0,l=this.compoundRules.length;l>a;a++){for(var f=this.compoundRules[a],h="",c=0,u=f.length;u>c;c++){var d=f[c];h+=d in this.compoundRuleCodes?"("+this.compoundRuleCodes[d].join("|")+")":d}this.compoundRules[a]=new RegExp(h,"i")}}return this};i.prototype={load:function(e){for(var t in e)this[t]=e[t];return this},_readFile:function(t,r){if(r||(r="utf8"),"undefined"!=typeof XMLHttpRequest){var i=new XMLHttpRequest;return i.open("GET",t,!1),i.overrideMimeType&&i.overrideMimeType("text/plain; charset="+r),i.send(null),i.responseText}if("undefined"!=typeof e){var o=e("fs");try{if(o.existsSync(t)){var a=o.statSync(t),l=o.openSync(t,"r"),s=new n(a.size);return o.readSync(l,s,0,s.length,null),s.toString(r,0,s.length)}console.log("Path "+t+" does not exist.")}catch(c){return console.log(c),""}}},_parseAFF:function(e){var t={};e=this._removeAffixComments(e);for(var n=e.split("\n"),r=0,i=n.length;i>r;r++){var o=n[r],a=o.split(/\s+/),l=a[0];if("PFX"==l||"SFX"==l){for(var s=a[1],c=a[2],u=parseInt(a[3],10),f=[],h=r+1,d=r+1+u;d>h;h++){var o=n[h],p=o.split(/\s+/),m=p[2],g=p[3].split("/"),v=g[0];"0"===v&&(v="");var y=this.parseRuleCodes(g[1]),x=p[4],b={};b.add=v,y.length>0&&(b.continuationClasses=y),"."!==x&&("SFX"===l?b.match=new RegExp(x+"$"):b.match=new RegExp("^"+x)),"0"!=m&&("SFX"===l?b.remove=new RegExp(m+"$"):b.remove=m),f.push(b)}t[s]={type:l,combineable:"Y"==c,entries:f},r+=u}else if("COMPOUNDRULE"===l){for(var u=parseInt(a[1],10),h=r+1,d=r+1+u;d>h;h++){var o=n[h],p=o.split(/\s+/);this.compoundRules.push(p[1])}r+=u}else if("REP"===l){var p=o.split(/\s+/);3===p.length&&this.replacementTable.push([p[1],p[2]])}else this.flags[l]=a[1]}return t},_removeAffixComments:function(e){return e=e.replace(/#.*$/gm,""),e=e.replace(/^\s\s*/m,"").replace(/\s\s*$/m,""),e=e.replace(/\n{2,}/g,"\n"),e=e.replace(/^\s\s*/,"").replace(/\s\s*$/,"")},_parseDIC:function(e){function t(e,t){e in r&&"object"==typeof r[e]||(r[e]=[]),r[e].push(t)}e=this._removeDicComments(e);for(var n=e.split("\n"),r={},i=1,o=n.length;o>i;i++){var a=n[i],l=a.split("/",2),s=l[0];if(l.length>1){var c=this.parseRuleCodes(l[1]);"NEEDAFFIX"in this.flags&&-1!=c.indexOf(this.flags.NEEDAFFIX)||t(s,c);for(var u=0,f=c.length;f>u;u++){var h=c[u],d=this.rules[h];if(d)for(var p=this._applyRule(s,d),m=0,g=p.length;g>m;m++){var v=p[m];if(t(v,[]),d.combineable)for(var y=u+1;f>y;y++){var x=c[y],b=this.rules[x];if(b&&b.combineable&&d.type!=b.type)for(var w=this._applyRule(v,b),k=0,S=w.length;S>k;k++){var C=w[k];t(C,[])}}}h in this.compoundRuleCodes&&this.compoundRuleCodes[h].push(s)}}else t(s.trim(),[])}return r},_removeDicComments:function(e){return e=e.replace(/^\t.*$/gm,"")},parseRuleCodes:function(e){if(!e)return[];if(!("FLAG"in this.flags))return e.split("");if("long"===this.flags.FLAG){for(var t=[],n=0,r=e.length;r>n;n+=2)t.push(e.substr(n,2));return t}return"num"===this.flags.FLAG?textCode.split(","):void 0},_applyRule:function(e,t){for(var n=t.entries,r=[],i=0,o=n.length;o>i;i++){var a=n[i];if(!a.match||e.match(a.match)){var l=e;if(a.remove&&(l=l.replace(a.remove,"")),"SFX"===t.type?l+=a.add:l=a.add+l,r.push(l),"continuationClasses"in a)for(var s=0,c=a.continuationClasses.length;c>s;s++){var u=this.rules[a.continuationClasses[s]];u&&(r=r.concat(this._applyRule(l,u)))}}}return r},check:function(e){var t=e.replace(/^\s\s*/,"").replace(/\s\s*$/,"");if(this.checkExact(t))return!0;if(t.toUpperCase()===t){var n=t[0]+t.substring(1).toLowerCase();if(this.hasFlag(n,"KEEPCASE"))return!1;if(this.checkExact(n))return!0}var r=t.toLowerCase();if(r!==t){if(this.hasFlag(r,"KEEPCASE"))return!1;if(this.checkExact(r))return!0}return!1},checkExact:function(e){var t=this.dictionaryTable[e];if("undefined"==typeof t){if("COMPOUNDMIN"in this.flags&&e.length>=this.flags.COMPOUNDMIN)for(var n=0,r=this.compoundRules.length;r>n;n++)if(e.match(this.compoundRules[n]))return!0;return!1}if("object"==typeof t){for(var n=0,r=t.length;r>n;n++)if(!this.hasFlag(e,"ONLYINCOMPOUND",t[n]))return!0;return!1}},hasFlag:function(e,t,n){if(t in this.flags){if("undefined"==typeof n)var n=Array.prototype.concat.apply([],this.dictionaryTable[e]);if(n&&-1!==n.indexOf(this.flags[t]))return!0}return!1},alphabet:"",suggest:function(e,t){function n(e){for(var t=[],n=0,r=e.length;r>n;n++){for(var i=e[n],o=[],a=0,l=i.length+1;l>a;a++)o.push([i.substring(0,a),i.substring(a,i.length)]);for(var s=[],a=0,l=o.length;l>a;a++){var u=o[a];u[1]&&s.push(u[0]+u[1].substring(1))}for(var f=[],a=0,l=o.length;l>a;a++){var u=o[a];u[1].length>1&&f.push(u[0]+u[1][1]+u[1][0]+u[1].substring(2))}for(var h=[],a=0,l=o.length;l>a;a++){var u=o[a];if(u[1])for(var d=0,p=c.alphabet.length;p>d;d++)h.push(u[0]+c.alphabet[d]+u[1].substring(1))}for(var m=[],a=0,l=o.length;l>a;a++){var u=o[a];if(u[1])for(var d=0,p=c.alphabet.length;p>d;d++)h.push(u[0]+c.alphabet[d]+u[1])}t=t.concat(s),t=t.concat(f),t=t.concat(h),t=t.concat(m)}return t}function r(e){for(var t=[],n=0;n<e.length;n++)c.check(e[n])&&t.push(e[n]);return t}function i(e){function i(e,t){return e[1]<t[1]?-1:1}for(var o=n([e]),a=n(o),l=r(o).concat(r(a)),s={},u=0,f=l.length;f>u;u++)l[u]in s?s[l[u]]+=1:s[l[u]]=1;var h=[];for(var u in s)h.push([u,s[u]]);h.sort(i).reverse();for(var d=[],u=0,f=Math.min(t,h.length);f>u;u++)c.hasFlag(h[u][0],"NOSUGGEST")||d.push(h[u][0]);return d}if(t||(t=5),this.check(e))return[];for(var o=0,a=this.replacementTable.length;a>o;o++){var l=this.replacementTable[o];if(-1!==e.indexOf(l[0])){var s=e.replace(l[0],l[1]);if(this.check(s))return[s]}}var c=this;return c.alphabet="abcdefghijklmnopqrstuvwxyz",i(e)}},"undefined"!=typeof t&&(t.exports=i)}).call(this,e("buffer").Buffer,"/node_modules/typo-js")},{buffer:3,fs:2}],19:[function(e,t,n){var r=e("codemirror");r.commands.tabAndIndentMarkdownList=function(e){var t=e.listSelections(),n=t[0].head,r=e.getStateAfter(n.line),i=r.list!==!1;if(i)return void e.execCommand("indentMore");if(e.options.indentWithTabs)e.execCommand("insertTab");else{var o=Array(e.options.tabSize+1).join(" ");e.replaceSelection(o)}},r.commands.shiftTabAndUnindentMarkdownList=function(e){var t=e.listSelections(),n=t[0].head,r=e.getStateAfter(n.line),i=r.list!==!1;if(i)return void e.execCommand("indentLess");if(e.options.indentWithTabs)e.execCommand("insertTab");else{var o=Array(e.options.tabSize+1).join(" ");e.replaceSelection(o)}}},{codemirror:10}],20:[function(e,t,n){"use strict";function r(e){return e=U?e.replace("Ctrl","Cmd"):e.replace("Cmd","Ctrl")}function i(e,t,n){e=e||{};var r=document.createElement("a");return t=void 0==t?!0:t,e.title&&t&&(r.title=a(e.title,e.action,n),U&&(r.title=r.title.replace("Ctrl","⌘"),r.title=r.title.replace("Alt","⌥"))),r.tabIndex=-1,r.className=e.className,r}function o(){var e=document.createElement("i");return e.className="separator",e.innerHTML="|",e}function a(e,t,n){var i,o=e;return t&&(i=Y(t),n[i]&&(o+=" ("+r(n[i])+")")),o}function l(e,t){t=t||e.getCursor("start");var n=e.getTokenAt(t);if(!n.type)return{};for(var r,i,o=n.type.split(" "),a={},l=0;l<o.length;l++)r=o[l],"strong"===r?a.bold=!0:"variable-2"===r?(i=e.getLine(t.line),/^\s*\d+\.\s/.test(i)?a["ordered-list"]=!0:a["unordered-list"]=!0):"atom"===r?a.quote=!0:"em"===r?a.italic=!0:"quote"===r?a.quote=!0:"strikethrough"===r?a.strikethrough=!0:"comment"===r?a.code=!0:"link"===r?a.link=!0:"tag"===r?a.image=!0:r.match(/^header(\-[1-6])?$/)&&(a[r.replace("header","heading")]=!0);return a}function s(e){var t=e.codemirror;t.setOption("fullScreen",!t.getOption("fullScreen")),t.getOption("fullScreen")?(V=document.body.style.overflow,document.body.style.overflow="hidden"):document.body.style.overflow=V;var n=t.getWrapperElement();/fullscreen/.test(n.previousSibling.className)?n.previousSibling.className=n.previousSibling.className.replace(/\s*fullscreen\b/,""):n.previousSibling.className+=" fullscreen";var r=e.toolbarElements.fullscreen;/active/.test(r.className)?r.className=r.className.replace(/\s*active\s*/g,""):r.className+=" active";var i=t.getWrapperElement().nextSibling;/editor-preview-active-side/.test(i.className)&&N(e)}function c(e){P(e,"bold",e.options.blockStyles.bold)}function u(e){P(e,"italic",e.options.blockStyles.italic)}function f(e){P(e,"strikethrough","~~")}function h(e){function t(e){if("object"!=typeof e)throw"fencing_line() takes a 'line' object (not a line number, or line text).  Got: "+typeof e+": "+e;return e.styles&&e.styles[2]&&-1!==e.styles[2].indexOf("formatting-code-block")}function n(e){return e.state.base.base||e.state.base}function r(e,r,i,o,a){i=i||e.getLineHandle(r),o=o||e.getTokenAt({line:r,ch:1}),a=a||!!i.text&&e.getTokenAt({line:r,ch:i.text.length-1});var l=o.type?o.type.split(" "):[];return a&&n(a).indentedCode?"indented":-1===l.indexOf("comment")?!1:n(o).fencedChars||n(a).fencedChars||t(i)?"fenced":"single"}function i(e,t,n,r){var i=t.line+1,o=n.line+1,a=t.line!==n.line,l=r+"\n",s="\n"+r;a&&o++,a&&0===n.ch&&(s=r+"\n",o--),E(e,!1,[l,s]),e.setSelection({line:i,ch:0},{line:o,ch:0})}var o,a,l,s=e.options.blockStyles.code,c=e.codemirror,u=c.getCursor("start"),f=c.getCursor("end"),h=c.getTokenAt({line:u.line,ch:u.ch||1}),d=c.getLineHandle(u.line),p=r(c,u.line,d,h);if("single"===p){var m=d.text.slice(0,u.ch).replace("`",""),g=d.text.slice(u.ch).replace("`","");c.replaceRange(m+g,{line:u.line,ch:0},{line:u.line,ch:99999999999999}),u.ch--,u!==f&&f.ch--,c.setSelection(u,f),c.focus()}else if("fenced"===p)if(u.line!==f.line||u.ch!==f.ch){for(o=u.line;o>=0&&(d=c.getLineHandle(o),!t(d));o--);var v,y,x,b,w=c.getTokenAt({line:o,ch:1}),k=n(w).fencedChars;t(c.getLineHandle(u.line))?(v="",y=u.line):t(c.getLineHandle(u.line-1))?(v="",y=u.line-1):(v=k+"\n",y=u.line),t(c.getLineHandle(f.line))?(x="",b=f.line,0===f.ch&&(b+=1)):0!==f.ch&&t(c.getLineHandle(f.line+1))?(x="",b=f.line+1):(x=k+"\n",b=f.line+1),0===f.ch&&(b-=1),c.operation(function(){c.replaceRange(x,{line:b,ch:0},{line:b+(x?0:1),ch:0}),c.replaceRange(v,{line:y,ch:0},{line:y+(v?0:1),ch:0})}),c.setSelection({line:y+(v?1:0),ch:0},{line:b+(v?1:-1),ch:0}),c.focus()}else{var S=u.line;if(t(c.getLineHandle(u.line))&&("fenced"===r(c,u.line+1)?(o=u.line,S=u.line+1):(a=u.line,S=u.line-1)),void 0===o)for(o=S;o>=0&&(d=c.getLineHandle(o),!t(d));o--);if(void 0===a)for(l=c.lineCount(),a=S;l>a&&(d=c.getLineHandle(a),!t(d));a++);c.operation(function(){c.replaceRange("",{line:o,ch:0},{line:o+1,ch:0}),c.replaceRange("",{line:a-1,ch:0},{line:a,ch:0})}),c.focus()}else if("indented"===p){if(u.line!==f.line||u.ch!==f.ch)o=u.line,a=f.line,0===f.ch&&a--;else{for(o=u.line;o>=0;o--)if(d=c.getLineHandle(o),!d.text.match(/^\s*$/)&&"indented"!==r(c,o,d)){o+=1;break}for(l=c.lineCount(),a=u.line;l>a;a++)if(d=c.getLineHandle(a),!d.text.match(/^\s*$/)&&"indented"!==r(c,a,d)){a-=1;break}}var C=c.getLineHandle(a+1),L=C&&c.getTokenAt({line:a+1,ch:C.text.length-1}),T=L&&n(L).indentedCode;T&&c.replaceRange("\n",{line:a+1,ch:0});for(var M=o;a>=M;M++)c.indentLine(M,"subtract");c.focus()}else{var N=u.line===f.line&&u.ch===f.ch&&0===u.ch,A=u.line!==f.line;N||A?i(c,u,f,s):E(c,!1,["`","`"])}}function d(e){var t=e.codemirror;I(t,"quote")}function p(e){var t=e.codemirror;O(t,"smaller")}function m(e){var t=e.codemirror;O(t,"bigger")}function g(e){var t=e.codemirror;O(t,void 0,1)}function v(e){var t=e.codemirror;O(t,void 0,2)}function y(e){var t=e.codemirror;O(t,void 0,3)}function x(e){var t=e.codemirror;I(t,"unordered-list")}function b(e){var t=e.codemirror;I(t,"ordered-list")}function w(e){var t=e.codemirror;R(t)}function k(e){var t=e.codemirror,n=l(t),r=e.options,i="http://";return r.promptURLs&&(i=prompt(r.promptTexts.link),!i)?!1:void E(t,n.link,r.insertTexts.link,i)}function S(e){var t=e.codemirror,n=l(t),r=e.options,i="http://";return r.promptURLs&&(i=prompt(r.promptTexts.image),!i)?!1:void E(t,n.image,r.insertTexts.image,i)}function C(e){var t=e.codemirror,n=l(t),r=e.options;E(t,n.table,r.insertTexts.table)}function L(e){var t=e.codemirror,n=l(t),r=e.options;E(t,n.image,r.insertTexts.horizontalRule)}function T(e){var t=e.codemirror;t.undo(),t.focus()}function M(e){var t=e.codemirror;t.redo(),t.focus()}function N(e){var t=e.codemirror,n=t.getWrapperElement(),r=n.nextSibling,i=e.toolbarElements["side-by-side"],o=!1;/editor-preview-active-side/.test(r.className)?(r.className=r.className.replace(/\s*editor-preview-active-side\s*/g,""),i.className=i.className.replace(/\s*active\s*/g,""),n.className=n.className.replace(/\s*CodeMirror-sided\s*/g," ")):(setTimeout(function(){t.getOption("fullScreen")||s(e),r.className+=" editor-preview-active-side"},1),i.className+=" active",n.className+=" CodeMirror-sided",o=!0);var a=n.lastChild;if(/editor-preview-active/.test(a.className)){a.className=a.className.replace(/\s*editor-preview-active\s*/g,"");var l=e.toolbarElements.preview,c=n.previousSibling;l.className=l.className.replace(/\s*active\s*/g,""),c.className=c.className.replace(/\s*disabled-for-preview*/g,"")}var u=function(){r.innerHTML=e.options.previewRender(e.value(),r)};t.sideBySideRenderingFunction||(t.sideBySideRenderingFunction=u),o?(r.innerHTML=e.options.previewRender(e.value(),r),t.on("update",t.sideBySideRenderingFunction)):t.off("update",t.sideBySideRenderingFunction),t.refresh()}function A(e){var t=e.codemirror,n=t.getWrapperElement(),r=n.previousSibling,i=e.options.toolbar?e.toolbarElements.preview:!1,o=n.lastChild;o&&/editor-preview/.test(o.className)||(o=document.createElement("div"),o.className="editor-preview",n.appendChild(o)),/editor-preview-active/.test(o.className)?(o.className=o.className.replace(/\s*editor-preview-active\s*/g,""),i&&(i.className=i.className.replace(/\s*active\s*/g,""),r.className=r.className.replace(/\s*disabled-for-preview*/g,""))):(setTimeout(function(){o.className+=" editor-preview-active"},1),i&&(i.className+=" active",r.className+=" disabled-for-preview")),o.innerHTML=e.options.previewRender(e.value(),o);var a=t.getWrapperElement().nextSibling;/editor-preview-active-side/.test(a.className)&&N(e)}function E(e,t,n,r){if(!/editor-preview-active/.test(e.getWrapperElement().lastChild.className)){var i,o=n[0],a=n[1],l=e.getCursor("start"),s=e.getCursor("end");r&&(a=a.replace("#url#",r)),t?(i=e.getLine(l.line),o=i.slice(0,l.ch),a=i.slice(l.ch),e.replaceRange(o+a,{line:l.line,ch:0})):(i=e.getSelection(),e.replaceSelection(o+i+a),l.ch+=o.length,l!==s&&(s.ch+=o.length)),e.setSelection(l,s),e.focus()}}function O(e,t,n){if(!/editor-preview-active/.test(e.getWrapperElement().lastChild.className)){for(var r=e.getCursor("start"),i=e.getCursor("end"),o=r.line;o<=i.line;o++)!function(r){var i=e.getLine(r),o=i.search(/[^#]/);i=void 0!==t?0>=o?"bigger"==t?"###### "+i:"# "+i:6==o&&"smaller"==t?i.substr(7):1==o&&"bigger"==t?i.substr(2):"bigger"==t?i.substr(1):"#"+i:1==n?0>=o?"# "+i:o==n?i.substr(o+1):"# "+i.substr(o+1):2==n?0>=o?"## "+i:o==n?i.substr(o+1):"## "+i.substr(o+1):0>=o?"### "+i:o==n?i.substr(o+1):"### "+i.substr(o+1),e.replaceRange(i,{line:r,ch:0},{line:r,ch:99999999999999})}(o);e.focus()}}function I(e,t){if(!/editor-preview-active/.test(e.getWrapperElement().lastChild.className)){for(var n=l(e),r=e.getCursor("start"),i=e.getCursor("end"),o={quote:/^(\s*)\>\s+/,"unordered-list":/^(\s*)(\*|\-|\+)\s+/,"ordered-list":/^(\s*)\d+\.\s+/},a={quote:"> ","unordered-list":"* ","ordered-list":"1. "},s=r.line;s<=i.line;s++)!function(r){var i=e.getLine(r);i=n[t]?i.replace(o[t],"$1"):a[t]+i,e.replaceRange(i,{line:r,ch:0},{line:r,ch:99999999999999})}(s);e.focus()}}function P(e,t,n,r){if(!/editor-preview-active/.test(e.codemirror.getWrapperElement().lastChild.className)){r="undefined"==typeof r?n:r;var i,o=e.codemirror,a=l(o),s=n,c=r,u=o.getCursor("start"),f=o.getCursor("end");a[t]?(i=o.getLine(u.line),s=i.slice(0,u.ch),c=i.slice(u.ch),"bold"==t?(s=s.replace(/(\*\*|__)(?![\s\S]*(\*\*|__))/,""),c=c.replace(/(\*\*|__)/,"")):"italic"==t?(s=s.replace(/(\*|_)(?![\s\S]*(\*|_))/,""),c=c.replace(/(\*|_)/,"")):"strikethrough"==t&&(s=s.replace(/(\*\*|~~)(?![\s\S]*(\*\*|~~))/,""),c=c.replace(/(\*\*|~~)/,"")),o.replaceRange(s+c,{line:u.line,ch:0},{line:u.line,ch:99999999999999}),"bold"==t||"strikethrough"==t?(u.ch-=2,u!==f&&(f.ch-=2)):"italic"==t&&(u.ch-=1,u!==f&&(f.ch-=1))):(i=o.getSelection(),"bold"==t?(i=i.split("**").join(""),i=i.split("__").join("")):"italic"==t?(i=i.split("*").join(""),i=i.split("_").join("")):"strikethrough"==t&&(i=i.split("~~").join("")),o.replaceSelection(s+i+c),u.ch+=n.length,f.ch=u.ch+i.length),o.setSelection(u,f),o.focus()}}function R(e){if(!/editor-preview-active/.test(e.getWrapperElement().lastChild.className))for(var t,n=e.getCursor("start"),r=e.getCursor("end"),i=n.line;i<=r.line;i++)t=e.getLine(i),t=t.replace(/^[ ]*([# ]+|\*|\-|[> ]+|[0-9]+(.|\)))[ ]*/,""),e.replaceRange(t,{line:i,ch:0},{line:i,ch:99999999999999})}function D(e,t){for(var n in t)t.hasOwnProperty(n)&&(t[n]instanceof Array?e[n]=t[n].concat(e[n]instanceof Array?e[n]:[]):null!==t[n]&&"object"==typeof t[n]&&t[n].constructor===Object?e[n]=D(e[n]||{},t[n]):e[n]=t[n]);return e}function H(e){for(var t=1;t<arguments.length;t++)e=D(e,arguments[t]);return e}function W(e){var t=/[a-zA-Z0-9_\u0392-\u03c9\u0410-\u04F9]+|[\u4E00-\u9FFF\u3400-\u4dbf\uf900-\ufaff\u3040-\u309f\uac00-\ud7af]+/g,n=e.match(t),r=0;if(null===n)return r;for(var i=0;i<n.length;i++)r+=n[i].charCodeAt(0)>=19968?n[i].length:1;return r}function B(e){e=e||{},e.parent=this;var t=!0;if(e.autoDownloadFontAwesome===!1&&(t=!1),e.autoDownloadFontAwesome!==!0)for(var n=document.styleSheets,r=0;r<n.length;r++)n[r].href&&n[r].href.indexOf("//maxcdn.bootstrapcdn.com/font-awesome/")>-1&&(t=!1);if(t){var i=document.createElement("link");i.rel="stylesheet",i.href="https://maxcdn.bootstrapcdn.com/font-awesome/latest/css/font-awesome.min.css",document.getElementsByTagName("head")[0].appendChild(i)}if(e.element)this.element=e.element;else if(null===e.element)return void console.log("SimpleMDE: Error. No element was found.");if(void 0===e.toolbar){e.toolbar=[];for(var o in K)K.hasOwnProperty(o)&&(-1!=o.indexOf("separator-")&&e.toolbar.push("|"),(K[o]["default"]===!0||e.showIcons&&e.showIcons.constructor===Array&&-1!=e.showIcons.indexOf(o))&&e.toolbar.push(o))}e.hasOwnProperty("status")||(e.status=["autosave","lines","words","cursor"]),e.previewRender||(e.previewRender=function(e){return this.parent.markdown(e)}),e.parsingConfig=H({highlightFormatting:!0},e.parsingConfig||{}),e.insertTexts=H({},X,e.insertTexts||{}),e.promptTexts=Z,e.blockStyles=H({},J,e.blockStyles||{}),e.shortcuts=H({},G,e.shortcuts||{}),void 0!=e.autosave&&void 0!=e.autosave.unique_id&&""!=e.autosave.unique_id&&(e.autosave.uniqueId=e.autosave.unique_id),this.options=e,this.render(),!e.initialValue||this.options.autosave&&this.options.autosave.foundSavedValue===!0||this.value(e.initialValue)}function _(){if("object"!=typeof localStorage)return!1;try{localStorage.setItem("smde_localStorage",1),localStorage.removeItem("smde_localStorage")}catch(e){return!1}return!0}var F=e("codemirror");e("codemirror/addon/edit/continuelist.js"),e("./codemirror/tablist"),e("codemirror/addon/display/fullscreen.js"),e("codemirror/mode/markdown/markdown.js"),e("codemirror/addon/mode/overlay.js"),e("codemirror/addon/display/placeholder.js"),e("codemirror/addon/selection/mark-selection.js"),e("codemirror/mode/gfm/gfm.js"),e("codemirror/mode/xml/xml.js");var z=e("codemirror-spell-checker"),j=e("marked"),U=/Mac/.test(navigator.platform),q={toggleBold:c,toggleItalic:u,drawLink:k,toggleHeadingSmaller:p,toggleHeadingBigger:m,drawImage:S,toggleBlockquote:d,toggleOrderedList:b,toggleUnorderedList:x,toggleCodeBlock:h,togglePreview:A,toggleStrikethrough:f,toggleHeading1:g,toggleHeading2:v,toggleHeading3:y,cleanBlock:w,drawTable:C,drawHorizontalRule:L,undo:T,redo:M,toggleSideBySide:N,toggleFullScreen:s},G={toggleBold:"Cmd-B",toggleItalic:"Cmd-I",drawLink:"Cmd-K",toggleHeadingSmaller:"Cmd-H",toggleHeadingBigger:"Shift-Cmd-H",cleanBlock:"Cmd-E",drawImage:"Cmd-Alt-I",toggleBlockquote:"Cmd-'",toggleOrderedList:"Cmd-Alt-L",toggleUnorderedList:"Cmd-L",toggleCodeBlock:"Cmd-Alt-C",togglePreview:"Cmd-P",toggleSideBySide:"F9",toggleFullScreen:"F11"},Y=function(e){for(var t in q)if(q[t]===e)return t;return null},$=function(){var e=!1;return function(t){(/(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.test(t)||/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.test(t.substr(0,4)))&&(e=!0);
61897}(navigator.userAgent||navigator.vendor||window.opera),e},V="",K={bold:{name:"bold",action:c,className:"fa fa-bold",title:"Bold","default":!0},italic:{name:"italic",action:u,className:"fa fa-italic",title:"Italic","default":!0},strikethrough:{name:"strikethrough",action:f,className:"fa fa-strikethrough",title:"Strikethrough"},heading:{name:"heading",action:p,className:"fa fa-header",title:"Heading","default":!0},"heading-smaller":{name:"heading-smaller",action:p,className:"fa fa-header fa-header-x fa-header-smaller",title:"Smaller Heading"},"heading-bigger":{name:"heading-bigger",action:m,className:"fa fa-header fa-header-x fa-header-bigger",title:"Bigger Heading"},"heading-1":{name:"heading-1",action:g,className:"fa fa-header fa-header-x fa-header-1",title:"Big Heading"},"heading-2":{name:"heading-2",action:v,className:"fa fa-header fa-header-x fa-header-2",title:"Medium Heading"},"heading-3":{name:"heading-3",action:y,className:"fa fa-header fa-header-x fa-header-3",title:"Small Heading"},"separator-1":{name:"separator-1"},code:{name:"code",action:h,className:"fa fa-code",title:"Code"},quote:{name:"quote",action:d,className:"fa fa-quote-left",title:"Quote","default":!0},"unordered-list":{name:"unordered-list",action:x,className:"fa fa-list-ul",title:"Generic List","default":!0},"ordered-list":{name:"ordered-list",action:b,className:"fa fa-list-ol",title:"Numbered List","default":!0},"clean-block":{name:"clean-block",action:w,className:"fa fa-eraser fa-clean-block",title:"Clean block"},"separator-2":{name:"separator-2"},link:{name:"link",action:k,className:"fa fa-link",title:"Create Link","default":!0},image:{name:"image",action:S,className:"fa fa-picture-o",title:"Insert Image","default":!0},table:{name:"table",action:C,className:"fa fa-table",title:"Insert Table"},"horizontal-rule":{name:"horizontal-rule",action:L,className:"fa fa-minus",title:"Insert Horizontal Line"},"separator-3":{name:"separator-3"},preview:{name:"preview",action:A,className:"fa fa-eye no-disable",title:"Toggle Preview","default":!0},"side-by-side":{name:"side-by-side",action:N,className:"fa fa-columns no-disable no-mobile",title:"Toggle Side by Side","default":!0},fullscreen:{name:"fullscreen",action:s,className:"fa fa-arrows-alt no-disable no-mobile",title:"Toggle Fullscreen","default":!0},"separator-4":{name:"separator-4"},guide:{name:"guide",action:"https://simplemde.com/markdown-guide",className:"fa fa-question-circle",title:"Markdown Guide","default":!0},"separator-5":{name:"separator-5"},undo:{name:"undo",action:T,className:"fa fa-undo no-disable",title:"Undo"},redo:{name:"redo",action:M,className:"fa fa-repeat no-disable",title:"Redo"}},X={link:["[","](#url#)"],image:["![](","#url#)"],table:["","\n\n| Column 1 | Column 2 | Column 3 |\n| -------- | -------- | -------- |\n| Text     | Text     | Text     |\n\n"],horizontalRule:["","\n\n-----\n\n"]},Z={link:"URL for the link:",image:"URL of the image:"},J={bold:"**",code:"```",italic:"*"};B.prototype.markdown=function(e){if(j){var t={};return this.options&&this.options.renderingConfig&&this.options.renderingConfig.singleLineBreaks===!1?t.breaks=!1:t.breaks=!0,this.options&&this.options.renderingConfig&&this.options.renderingConfig.codeSyntaxHighlighting===!0&&window.hljs&&(t.highlight=function(e){return window.hljs.highlightAuto(e).value}),j.setOptions(t),j(e)}},B.prototype.render=function(e){if(e||(e=this.element||document.getElementsByTagName("textarea")[0]),!this._rendered||this._rendered!==e){this.element=e;var t=this.options,n=this,i={};for(var o in t.shortcuts)null!==t.shortcuts[o]&&null!==q[o]&&!function(e){i[r(t.shortcuts[e])]=function(){q[e](n)}}(o);i.Enter="newlineAndIndentContinueMarkdownList",i.Tab="tabAndIndentMarkdownList",i["Shift-Tab"]="shiftTabAndUnindentMarkdownList",i.Esc=function(e){e.getOption("fullScreen")&&s(n)},document.addEventListener("keydown",function(e){e=e||window.event,27==e.keyCode&&n.codemirror.getOption("fullScreen")&&s(n)},!1);var a,l;if(t.spellChecker!==!1?(a="spell-checker",l=t.parsingConfig,l.name="gfm",l.gitHubSpice=!1,z({codeMirrorInstance:F})):(a=t.parsingConfig,a.name="gfm",a.gitHubSpice=!1),this.codemirror=F.fromTextArea(e,{mode:a,backdrop:l,theme:"paper",tabSize:void 0!=t.tabSize?t.tabSize:2,indentUnit:void 0!=t.tabSize?t.tabSize:2,indentWithTabs:t.indentWithTabs!==!1,lineNumbers:!1,autofocus:t.autofocus===!0,extraKeys:i,lineWrapping:t.lineWrapping!==!1,allowDropFileTypes:["text/plain"],placeholder:t.placeholder||e.getAttribute("placeholder")||"",styleSelectedText:void 0!=t.styleSelectedText?t.styleSelectedText:!0}),t.forceSync===!0){var c=this.codemirror;c.on("change",function(){c.save()})}this.gui={},t.toolbar!==!1&&(this.gui.toolbar=this.createToolbar()),t.status!==!1&&(this.gui.statusbar=this.createStatusbar()),void 0!=t.autosave&&t.autosave.enabled===!0&&this.autosave(),this.gui.sideBySide=this.createSideBySide(),this._rendered=this.element;var u=this.codemirror;setTimeout(function(){u.refresh()}.bind(u),0)}},B.prototype.autosave=function(){if(_()){var e=this;if(void 0==this.options.autosave.uniqueId||""==this.options.autosave.uniqueId)return void console.log("SimpleMDE: You must set a uniqueId to use the autosave feature");null!=e.element.form&&void 0!=e.element.form&&e.element.form.addEventListener("submit",function(){localStorage.removeItem("smde_"+e.options.autosave.uniqueId)}),this.options.autosave.loaded!==!0&&("string"==typeof localStorage.getItem("smde_"+this.options.autosave.uniqueId)&&""!=localStorage.getItem("smde_"+this.options.autosave.uniqueId)&&(this.codemirror.setValue(localStorage.getItem("smde_"+this.options.autosave.uniqueId)),this.options.autosave.foundSavedValue=!0),this.options.autosave.loaded=!0),localStorage.setItem("smde_"+this.options.autosave.uniqueId,e.value());var t=document.getElementById("autosaved");if(null!=t&&void 0!=t&&""!=t){var n=new Date,r=n.getHours(),i=n.getMinutes(),o="am",a=r;a>=12&&(a=r-12,o="pm"),0==a&&(a=12),i=10>i?"0"+i:i,t.innerHTML="Autosaved: "+a+":"+i+" "+o}this.autosaveTimeoutId=setTimeout(function(){e.autosave()},this.options.autosave.delay||1e4)}else console.log("SimpleMDE: localStorage not available, cannot autosave")},B.prototype.clearAutosavedValue=function(){if(_()){if(void 0==this.options.autosave||void 0==this.options.autosave.uniqueId||""==this.options.autosave.uniqueId)return void console.log("SimpleMDE: You must set a uniqueId to clear the autosave value");localStorage.removeItem("smde_"+this.options.autosave.uniqueId)}else console.log("SimpleMDE: localStorage not available, cannot autosave")},B.prototype.createSideBySide=function(){var e=this.codemirror,t=e.getWrapperElement(),n=t.nextSibling;n&&/editor-preview-side/.test(n.className)||(n=document.createElement("div"),n.className="editor-preview-side",t.parentNode.insertBefore(n,t.nextSibling));var r=!1,i=!1;return e.on("scroll",function(e){if(r)return void(r=!1);i=!0;var t=e.getScrollInfo().height-e.getScrollInfo().clientHeight,o=parseFloat(e.getScrollInfo().top)/t,a=(n.scrollHeight-n.clientHeight)*o;n.scrollTop=a}),n.onscroll=function(){if(i)return void(i=!1);r=!0;var t=n.scrollHeight-n.clientHeight,o=parseFloat(n.scrollTop)/t,a=(e.getScrollInfo().height-e.getScrollInfo().clientHeight)*o;e.scrollTo(0,a)},n},B.prototype.createToolbar=function(e){if(e=e||this.options.toolbar,e&&0!==e.length){var t;for(t=0;t<e.length;t++)void 0!=K[e[t]]&&(e[t]=K[e[t]]);var n=document.createElement("div");n.className="editor-toolbar";var r=this,a={};for(r.toolbar=e,t=0;t<e.length;t++)if(("guide"!=e[t].name||r.options.toolbarGuideIcon!==!1)&&!(r.options.hideIcons&&-1!=r.options.hideIcons.indexOf(e[t].name)||("fullscreen"==e[t].name||"side-by-side"==e[t].name)&&$())){if("|"===e[t]){for(var s=!1,c=t+1;c<e.length;c++)"|"===e[c]||r.options.hideIcons&&-1!=r.options.hideIcons.indexOf(e[c].name)||(s=!0);if(!s)continue}!function(e){var t;t="|"===e?o():i(e,r.options.toolbarTips,r.options.shortcuts),e.action&&("function"==typeof e.action?t.onclick=function(t){t.preventDefault(),e.action(r)}:"string"==typeof e.action&&(t.href=e.action,t.target="_blank")),a[e.name||e]=t,n.appendChild(t)}(e[t])}r.toolbarElements=a;var u=this.codemirror;u.on("cursorActivity",function(){var e=l(u);for(var t in a)!function(t){var n=a[t];e[t]?n.className+=" active":"fullscreen"!=t&&"side-by-side"!=t&&(n.className=n.className.replace(/\s*active\s*/g,""))}(t)});var f=u.getWrapperElement();return f.parentNode.insertBefore(n,f),n}},B.prototype.createStatusbar=function(e){e=e||this.options.status;var t=this.options,n=this.codemirror;if(e&&0!==e.length){var r,i,o,a=[];for(r=0;r<e.length;r++)if(i=void 0,o=void 0,"object"==typeof e[r])a.push({className:e[r].className,defaultValue:e[r].defaultValue,onUpdate:e[r].onUpdate});else{var l=e[r];"words"===l?(o=function(e){e.innerHTML=W(n.getValue())},i=function(e){e.innerHTML=W(n.getValue())}):"lines"===l?(o=function(e){e.innerHTML=n.lineCount()},i=function(e){e.innerHTML=n.lineCount()}):"cursor"===l?(o=function(e){e.innerHTML="0:0"},i=function(e){var t=n.getCursor();e.innerHTML=t.line+":"+t.ch}):"autosave"===l&&(o=function(e){void 0!=t.autosave&&t.autosave.enabled===!0&&e.setAttribute("id","autosaved")}),a.push({className:l,defaultValue:o,onUpdate:i})}var s=document.createElement("div");for(s.className="editor-statusbar",r=0;r<a.length;r++){var c=a[r],u=document.createElement("span");u.className=c.className,"function"==typeof c.defaultValue&&c.defaultValue(u),"function"==typeof c.onUpdate&&this.codemirror.on("update",function(e,t){return function(){t.onUpdate(e)}}(u,c)),s.appendChild(u)}var f=this.codemirror.getWrapperElement();return f.parentNode.insertBefore(s,f.nextSibling),s}},B.prototype.value=function(e){return void 0===e?this.codemirror.getValue():(this.codemirror.getDoc().setValue(e),this)},B.toggleBold=c,B.toggleItalic=u,B.toggleStrikethrough=f,B.toggleBlockquote=d,B.toggleHeadingSmaller=p,B.toggleHeadingBigger=m,B.toggleHeading1=g,B.toggleHeading2=v,B.toggleHeading3=y,B.toggleCodeBlock=h,B.toggleUnorderedList=x,B.toggleOrderedList=b,B.cleanBlock=w,B.drawLink=k,B.drawImage=S,B.drawTable=C,B.drawHorizontalRule=L,B.undo=T,B.redo=M,B.togglePreview=A,B.toggleSideBySide=N,B.toggleFullScreen=s,B.prototype.toggleBold=function(){c(this)},B.prototype.toggleItalic=function(){u(this)},B.prototype.toggleStrikethrough=function(){f(this)},B.prototype.toggleBlockquote=function(){d(this)},B.prototype.toggleHeadingSmaller=function(){p(this)},B.prototype.toggleHeadingBigger=function(){m(this)},B.prototype.toggleHeading1=function(){g(this)},B.prototype.toggleHeading2=function(){v(this)},B.prototype.toggleHeading3=function(){y(this)},B.prototype.toggleCodeBlock=function(){h(this)},B.prototype.toggleUnorderedList=function(){x(this)},B.prototype.toggleOrderedList=function(){b(this)},B.prototype.cleanBlock=function(){w(this)},B.prototype.drawLink=function(){k(this)},B.prototype.drawImage=function(){S(this)},B.prototype.drawTable=function(){C(this)},B.prototype.drawHorizontalRule=function(){L(this)},B.prototype.undo=function(){T(this)},B.prototype.redo=function(){M(this)},B.prototype.togglePreview=function(){A(this)},B.prototype.toggleSideBySide=function(){N(this)},B.prototype.toggleFullScreen=function(){s(this)},B.prototype.isPreviewActive=function(){var e=this.codemirror,t=e.getWrapperElement(),n=t.lastChild;return/editor-preview-active/.test(n.className)},B.prototype.isSideBySideActive=function(){var e=this.codemirror,t=e.getWrapperElement(),n=t.nextSibling;return/editor-preview-active-side/.test(n.className)},B.prototype.isFullscreenActive=function(){var e=this.codemirror;return e.getOption("fullScreen")},B.prototype.getState=function(){var e=this.codemirror;return l(e)},B.prototype.toTextArea=function(){var e=this.codemirror,t=e.getWrapperElement();t.parentNode&&(this.gui.toolbar&&t.parentNode.removeChild(this.gui.toolbar),this.gui.statusbar&&t.parentNode.removeChild(this.gui.statusbar),this.gui.sideBySide&&t.parentNode.removeChild(this.gui.sideBySide)),e.toTextArea(),this.autosaveTimeoutId&&(clearTimeout(this.autosaveTimeoutId),this.autosaveTimeoutId=void 0,this.clearAutosavedValue())},t.exports=B},{"./codemirror/tablist":19,codemirror:10,"codemirror-spell-checker":4,"codemirror/addon/display/fullscreen.js":5,"codemirror/addon/display/placeholder.js":6,"codemirror/addon/edit/continuelist.js":7,"codemirror/addon/mode/overlay.js":8,"codemirror/addon/selection/mark-selection.js":9,"codemirror/mode/gfm/gfm.js":11,"codemirror/mode/markdown/markdown.js":12,"codemirror/mode/xml/xml.js":14,marked:17}]},{},[20])(20)});
61897
61898/*!
61899 * ApexCharts v3.33.0
61900 * (c) 2018-2022 ApexCharts
61901 * Released under the MIT License.
61902 */
61903!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).ApexCharts=e()}(this,(function(){"use strict";function t(t,e){var i=Object.keys(t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);e&&(a=a.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),i.push.apply(i,a)}return i}function e(e){for(var i=1;i<arguments.length;i++){var a=null!=arguments[i]?arguments[i]:{};
vendor: 1,285 bytes, line 61903
61903i%2?t(Object(a),!0).forEach((function(t){o(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):t(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function i(t){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function a(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function s(t,e){for(var i=0;i<e.length;i++){var a=e[i];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(t,a.key,a)}}function r(t,e,i){return e&&s(t.prototype,e),i&&s(t,i),t}function o(t,e,i){return e in t?Object.defineProperty(t,e,{value:i,enumerable:!0,configurable:!0,writable:!0}):t[e]=i,t}function n(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&h(t,e)}function l(t){return(l=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}
61903function h(t,e){return(h=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,e)}function c(t,e){if(e&&("object"==typeof e||"function"==typeof e))return e;if(void 0!==e)throw new TypeError("Derived constructors may only return object or undefined");return function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t)}function d(t){var e=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(t){return!1}}();return function(){var i,a=l(t);if(e){var s=l(this).constructor;i=Reflect.construct(a,arguments,s)}else i=a.apply(this,arguments);return c(this,i)}}function g(t){return function(t){if(Array.isArray(t))return u(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,e){if(!t)return;if("string"==typeof t)return u(t,e);var i=Object.prototype.toString.call(t).slice(8,-1);"Object"===i&&t.constructor&&(i=t.constructor.name);if("Map"===i||"Set"===i)return Array.from(t);if("Arguments"===i||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(i))return u(t,e)}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function u(t,e){(null==e||e>t.length)&&(e=t.length);for(var i=0,a=new Array(e);i<e;i++)a[i]=t[i];return a}var p=function(){function t(){a(this,t)}return r(t,[{key:"shadeRGBColor",value:function(t,e){var i=e.split(","),a=t<0?0:255,s=t<0?-1*t:t,r=parseInt(i[0].slice(4),10),o=parseInt(i[1],10),n=parseInt(i[2],10);return"rgb("+(Math.round((a-r)*s)+r)+","+(Math.round((a-o)*s)+o)+","+(Math.round((a-n)*s)+n)+")"}},{key:"shadeHexColor",value:function(t,e){var i=parseInt(e.slice(1),16),a=t<0?0:255,s=t<0?-1*t:t,r=i>>16,o=i>>8&255,n=255&i;return"#"+(16777216+65536*(Math.round((a-r)*s)+r)+256*(Math.round((a-o)*s)+o)+(Math.round((a-n)*s)+n)).toString(16).slice(1)}},{key:"shadeColor",value:function(e,i){return t.isColorHex(i)?this.shadeHexColor(e,i):this.shadeRGBColor(e,i)}}],[{key:"bind",value:function(t,e){return function(){return t.apply(e,arguments)}}},{key:"isObject",value:function(t){return t&&"object"===i(t)&&!Array.isArray(t)&&null!=t}},{key:"is",value:function(t,e){return Object.prototype.toString.call(e)==="[object "+t+"]"}},{key:"listToArray",value:function(t){var e,i=[];for(e=0;e<t.length;e++)i[e]=t[e];return i}},{key:"extend",value:function(t,e){var i=this;"function"!=typeof Object.assign&&(Object.assign=function(t){if(null==t)throw new TypeError("Cannot convert undefined or null to object");for(var e=Object(t),i=1;i<arguments.length;i++){var a=arguments[i];if(null!=a)for(var s in a)a.hasOwnProperty(s)&&(e[s]=a[s])}return e});var a=Object.assign({},t);return this.isObject(t)&&this.isObject(e)&&Object.keys(e).forEach((function(s){i.isObject(e[s])&&s in t?a[s]=i.extend(t[s],e[s]):Object.assign(a,o({},s,e[s]))})),a}},{key:"extendArray",value:function(e,i){var a=[];return e.map((function(e){a.push(t.extend(i,e))})),e=a}},{key:"monthMod",value:function(t){return t%12}},{key:"clone",value:function(e){if(t.is("Array",e)){for(var a=[],s=0;s<e.length;s++)a[s]=this.clone(e[s]);return a}if(t.is("Null",e))return null;if(t.is("Date",e))return e;if("object"===i(e)){var r={};for(var o in e)e.hasOwnProperty(o)&&(r[o]=this.clone(e[o]));return r}return e}},{key:"log10",value:function(t){return Math.log(t)/Math.LN10}},{key:"roundToBase10",value:function(t){return Math.pow(10,Math.floor(Math.log10(t)))}},{key:"roundToBase",value:function(t,e){return Math.pow(e,Math.floor(Math.log(t)/Math.log(e)))}},{key:"parseNumber",value:function(t){return null===t?t:parseFloat(t)}},{key:"randomId",value:function(){return(Math.random()+1).toString(36).substring(4)}},{key:"noExponents",value:function(t){var e=String(t).split(/[eE]/);if(1===e.length)return e[0];var i="",a=t<0?"-":"",s=e[0].replace(".",""),r=Number(e[1])+1;if(r<0){for(i=a+"0.";r++;)i+="0";return i+s.replace(/^-/,"")}for(r-=s.length;r--;)i+="0";return s+i}},{key:"getDimensions",value:function(t){var e=getComputedStyle(t,null),i=t.clientHeight,a=t.clientWidth;return i-=parseFloat(e.paddingTop)+parseFloat(e.paddingBottom),[a-=parseFloat(e.paddingLeft)+parseFloat(e.paddingRight),i]}},{key:"getBoundingClientRect",value:function(t){var e=t.getBoundingClientRect();return{top:e.top,right:e.right,bottom:e.bottom,left:e.left,width:t.clientWidth,height:t.clientHeight,x:e.left,y:e.top}}},{key:"getLargestStringFromArr",value:function(t){return t.reduce((function(t,e){return Array.isArray(e)&&(e=e.reduce((function(t,e){return t.length>e.length?t:e}))),t.length>e.length?t:e}),0)}},{key:"hexToRgba",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"#999999",e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:.6;"#"!==t.substring(0,1)&&(t="#999999");var i=t.replace("#","");i=i.match(new RegExp("(.{"+i.length/3+"})","g"));for(var a=0;a<i.length;a++)i[a]=parseInt(1===i[a].length?i[a]+i[a]:i[a],16);return void 0!==e&&i.push(e),"rgba("+i.join(",")+")"}},{key:"getOpacityFromRGBA",value:function(t){return parseFloat(t.replace(/^.*,(.
61903+)\)/,"$1"))}},{key:"rgb2hex",value:function(t){return(t=t.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i))&&4===t.length?"#"+("0"+parseInt(t[1],10).toString(16)).slice(-2)+("0"+parseInt(t[2],10).toString(16)).slice(-2)+("0"+parseInt(t[3],10).toString(16)).slice(-2):""}},{key:"isColorHex",value:function(t){return/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)|(^#[0-9A-F]{8}$)/i.test(t)}},{key:"getPolygonPos",value:function(t,e){for(var i=[],a=2*Math.PI/e,s=0;s<e;s++){var r={};r.x=t*Math.sin(s*a),r.y=-t*Math.cos(s*a),i.push(r)}return i}},{key:"polarToCartesian",value:function(t,e,i,a){var s=(a-90)*Math.PI/180;return{x:t+i*Math.cos(s),y:e+i*Math.sin(s)}}},{key:"escapeString",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"x",i=t.toString().slice();return i=i.replace(/[` ~!@#$%^&*()_|+\-=?;:'",.<>{}[\]\\/]/gi,e)}},{key:"negToZero",value:function(t){return t<0?0:t}},{key:"moveIndexInArray",value:function(t,e,i){if(i>=t.length)for(var a=i-t.length+1;a--;)t.push(void 0);return t.splice(i,0,t.splice(e,1)[0]),t}},{key:"extractNumber",value:function(t){return parseFloat(t.replace(/[^\d.]*/g,""))}},{key:"findAncestor",value:function(t,e){for(;(t=t.parentElement)&&!t.classList.contains(e););return t}},{key:"setELstyles",value:function(t,e){for(var i in e)e.hasOwnProperty(i)&&(t.style.key=e[i])}},{key:"isNumber",value:function(t){return!isNaN(t)&&parseFloat(Number(t))===t&&!isNaN(parseInt(t,10))}},{key:"isFloat",value:function(t){return Number(t)===t&&t%1!=0}},{key:"isSafari",value:function(){return/^((?!chrome|android).)*safari/i.test(navigator.userAgent)}},{key:"isFirefox",value:function(){return navigator.userAgent.toLowerCase().indexOf("firefox")>-1}},{key:"isIE11",value:function(){if(-1!==window.navigator.userAgent.indexOf("MSIE")||window.navigator.appVersion.indexOf("Trident/")>-1)return!0}},{key:"isIE",value:function(){var t=window.navigator.userAgent,e=t.indexOf("MSIE ");if(e>0)return parseInt(t.substring(e+5,t.indexOf(".",e)),10);if(t.indexOf("Trident/")>0){var i=t.indexOf("rv:");return parseInt(t.substring(i+3,t.indexOf(".",i)),10)}var a=t.indexOf("Edge/");return a>0&&parseInt(t.substring(a+5,t.indexOf(".",a)),10)}}]),t}(),f=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w,this.setEasingFunctions()}return r(t,[{key:"setEasingFunctions",value:function(){var t;if(!this.w.globals.easing){switch(this.w.config.chart.animations.easing){case"linear":t="-";break;case"easein":t="<";break;case"easeout":t=">";break;case"easeinout":t="<>";break;case"swing":t=function(t){var e=1.70158;return(t-=1)*t*((e+1)*t+e)+1};break;case"bounce":t=function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375};break;case"elastic":t=function(t){return t===!!t?t:Math.pow(2,-10*t)*Math.sin((t-.075)*(2*Math.PI)/.3)+1};break;default:t="<>"}this.w.globals.easing=t}}},{key:"animateLine",value:function(t,e,i,a){t.attr(e).animate(a).attr(i)}},{key:"animateMarker",value:function(t,e,i,a,s,r){e||(e=0),t.attr({r:e,width:e,height:e}).animate(a,s).attr({r:i,width:i.width,height:i.height}).afterAll((function(){r()}))}},{key:"animateCircle",value:function(t,e,i,a,s){t.attr({r:e.r,cx:e.cx,cy:e.cy}).animate(a,s).attr({r:i.r,cx:i.cx,cy:i.cy})}},{key:"animateRect",value:function(t,e,i,a,s){t.attr(e).animate(a).attr(i).afterAll((function(){return s()}))}},{key:"animatePathsGradually",value:function(t){var e=t.el,i=t.realIndex,a=t.j,s=t.fill,r=t.pathFrom,o=t.pathTo,n=t.speed,l=t.delay,h=this.w,c=0;h.config.chart.animations.animateGradually.enabled&&(c=h.config.chart.animations.animateGradually.delay),h.config.chart.animations.dynamicAnimation.enabled&&h.globals.dataChanged&&"bar"!==h.config.chart.type&&(c=0),this.morphSVG(e,i,a,"line"!==h.config.chart.type||h.globals.comboCharts?s:"stroke",r,o,n,l*c)}},{key:"showDelayedElements",value:function(){this.w.globals.delayedElements.forEach((function(t){t.el.classList.remove("apexcharts-element-hidden")}))}},{key:"animationCompleted",value:function(t){var e=this.w;e.globals.animationEnded||(e.globals.animationEnded=!0,this.showDelayedElements(),"function"==typeof e.config.chart.events.animationEnd&&e.config.chart.events.animationEnd(this.ctx,{el:t,w:e}))}}
61903,{key:"morphSVG",value:function(t,e,i,a,s,r,o,n){var l=this,h=this.w;s||(s=t.attr("pathFrom")),r||(r=t.attr("pathTo"));var c=function(t){return"radar"===h.config.chart.type&&(o=1),"M 0 ".concat(h.globals.gridHeight)};(!s||s.indexOf("undefined")>-1||s.indexOf("NaN")>-1)&&(s=c()),(!r||r.indexOf("undefined")>-1||r.indexOf("NaN")>-1)&&(r=c()),h.globals.shouldAnimate||(o=1),t.plot(s).animate(1,h.globals.easing,n).plot(s).animate(o,h.globals.easing,n).plot(r).afterAll((function(){p.isNumber(i)?i===h.globals.series[h.globals.maxValsInArrayIndex].length-2&&h.globals.shouldAnimate&&l.animationCompleted(t):"none"!==a&&h.globals.shouldAnimate&&(!h.globals.comboCharts&&e===h.globals.series.length-1||h.globals.comboCharts)&&l.animationCompleted(t),l.showDelayedElements()}))}}]),t}(),x=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w}return r(t,[{key:"getDefaultFilter",value:function(t,e){var i=this.w;t.unfilter(!0),(new window.SVG.Filter).size("120%","180%","-5%","-40%"),"none"!==i.config.states.normal.filter?this.applyFilter(t,e,i.config.states.normal.filter.type,i.config.states.normal.filter.value):i.config.chart.dropShadow.enabled&&this.dropShadow(t,i.config.chart.dropShadow,e)}},{key:"addNormalFilter",value:function(t,e){var i=this.w;i.config.chart.dropShadow.enabled&&!t.node.classList.contains("apexcharts-marker")&&this.dropShadow(t,i.config.chart.dropShadow,e)}},{key:"addLightenFilter",value:function(t,e,i){var a=this,s=this.w,r=i.intensity;t.unfilter(!0);new window.SVG.Filter;t.filter((function(t){var i=s.config.chart.dropShadow;(i.enabled?a.addShadow(t,e,i):t).componentTransfer({rgb:{type:"linear",slope:1.5,intercept:r}})})),t.filterer.node.setAttribute("filterUnits","userSpaceOnUse"),this._scaleFilterSize(t.filterer.node)}},{key:"addDarkenFilter",value:function(t,e,i){var a=this,s=this.w,r=i.intensity;t.unfilter(!0);new window.SVG.Filter;t.filter((function(t){var i=s.config.chart.dropShadow;(i.enabled?a.addShadow(t,e,i):t).componentTransfer({rgb:{type:"linear",slope:r}})})),t.filterer.node.setAttribute("filterUnits","userSpaceOnUse"),this._scaleFilterSize(t.filterer.node)}},{key:"applyFilter",value:function(t,e,i){var a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:.5;switch(i){case"none":this.addNormalFilter(t,e);break;case"lighten":this.addLightenFilter(t,e,{intensity:a});break;case"darken":this.addDarkenFilter(t,e,{intensity:a})}}},{key:"addShadow",value:function(t,e,i){var a=i.blur,s=i.top,r=i.left,o=i.color,n=i.opacity,l=t.flood(Array.isArray(o)?o[e]:o,n).composite(t.sourceAlpha,"in").offset(r,s).gaussianBlur(a).merge(t.source);return t.blend(t.source,l)}},{key:"dropShadow",value:function(t,e){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,a=e.top,s=e.left,r=e.blur,o=e.color,n=e.opacity,l=e.noUserSpaceOnUse,h=this.w;return t.unfilter(!0),p.isIE()&&"radialBar"===h.config.chart.type||(o=Array.isArray(o)?o[i]:o,t.filter((function(t){var e=null;e=p.isSafari()||p.isFirefox()||p.isIE()?t.flood(o,n).composite(t.sourceAlpha,"in").offset(s,a).gaussianBlur(r):t.flood(o,n).composite(t.sourceAlpha,"in").offset(s,a).gaussianBlur(r).merge(t.source),t.blend(t.source,e)})),l||t.filterer.node.setAttribute("filterUnits","userSpaceOnUse"),this._scaleFilterSize(t.filterer.node)),t}},{key:"setSelectionFilter",value:function(t,e,i){var a=this.w;if(void 0!==a.globals.selectedDataPoints[e]&&a.globals.selectedDataPoints[e].indexOf(i)>-1){t.node.setAttribute("selected",!0);var s=a.config.states.active.filter;"none"!==s&&this.applyFilter(t,e,s.type,s.value)}}},{key:"_scaleFilterSize",value:function(t){!function(e){for(var i in e)e.hasOwnProperty(i)&&t.setAttribute(i,e[i])}({width:"200%",height:"200%",x:"-50%",y:"-50%"})}}]),t}(),b=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w}return r(t,[{key:"drawLine",value:function(t,e,i,a){var s=arguments.length>4&&void 0!==arguments[4]?arguments[4]:"#a8a8a8",r=arguments.length>5&&void 0!==arguments[5]?arguments[5]:0,o=arguments.length>6&&void 0!==arguments[6]?arguments[6]:null,n=arguments.length>7&&void 0!==arguments[7]?arguments[7]:"butt",l=this.w,h=l.globals.dom.Paper.line().attr({x1:t,y1:e,x2:i,y2:a,stroke:s,"stroke-dasharray":r,"stroke-width":o,"stroke-linecap":n});return h}},{key:"drawRect",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0,s=arguments.length>4&&void 0!==arguments[4]?arguments[4]:0,r=arguments.length>5&&void 0!==arguments[5]?arguments[5]:"#fefefe",o=arguments.length>6&&void 0!==arguments[6]?arguments[6]:1,n=arguments.length>7&&void 0!==arguments[7]?arguments[7]:null,l=arguments.length>8&&void 0!==arguments[8]?arguments[8]:null,h=arguments.length>9&&void 0!==arguments[9]?arguments[9]:0,c=this.w,d=c.globals.dom.Paper.rect();return d.attr({x:t,y:e,width:i>0?i:0,height:a>0?a:0,rx:s,ry:s,opacity:o,"stroke-width":null!==n?n:0,stroke:null!==l?l:"none","stroke-dasharray":h}),d.node.setAttribute("fill",r),d}},{key:"drawPolygon",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"#e1e1e1",i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1,a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"none",s=this.w,r=s.globals.dom.Paper.polygon(t).attr({fill:a,stroke:e,"stroke-width":i});return r}},{key:"drawCircle",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,i=this.w;t<0&&(t=0);var a=i.globals.dom.Paper.circle(2*t);return null!==e&&a.attr(e),a}},{key:"drawPath",value:function(t){var e=t.d,i=void 0===e?"":e,a=t.stroke,s=void 0===a?"#a8a8a8":a,r=t.strokeWidth,o=void 0===r?1:r,n=t.fill,l=t.fillOpacity,h=void 0===l?1:l,c=t.strokeOpacity,d=void 0===c?1:c,g=t.classes,u=t.strokeLinecap,p=void 0===u?null:u,f=t.strokeDashArray,x=void 0===f?0:f,b=this.w;return null===p&&(p=b.config.stroke.lineCap),(i.indexOf("undefined")>-1||i.indexOf("NaN")>-1)&&(i="M 0 ".concat(b.globals.gridHeight)),b.globals.dom.Paper.path(i).attr({fill:n,"fill-opacity":h,stroke:s,"stroke-opacity":d,"stroke-linecap":p,"stroke-width":o,"stroke-dasharray":x,class:g})}},{key:"group",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,e=this.w,i=e.globals.dom.Paper.group();return null!==t&&i.attr(t),i}},{key:"move",value:function(t,e){var i=["M",t,e].join(" ");return i}},{key:"line",value:function(t,e){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,a=null;return null===i?a=["L",t,e].join(" "):"H"===i?a=["H",t].join(" "):"V"===i&&(a=["V",e].join(" ")),a}}
61903,{key:"curve",value:function(t,e,i,a,s,r){var o=["C",t,e,i,a,s,r].join(" ");return o}},{key:"quadraticCurve",value:function(t,e,i,a){return["Q",t,e,i,a].join(" ")}},{key:"arc",value:function(t,e,i,a,s,r,o){var n=arguments.length>7&&void 0!==arguments[7]&&arguments[7],l="A";n&&(l="a");var h=[l,t,e,i,a,s,r,o].join(" ");return h}},{key:"renderPaths",value:function(t){var i,a=t.j,s=t.realIndex,r=t.pathFrom,o=t.pathTo,n=t.stroke,l=t.strokeWidth,h=t.strokeLinecap,c=t.fill,d=t.animationDelay,g=t.initialSpeed,u=t.dataChangeSpeed,p=t.className,b=t.shouldClipToGrid,v=void 0===b||b,m=t.bindEventsOnPaths,y=void 0===m||m,w=t.drawShadow,k=void 0===w||w,A=this.w,S=new x(this.ctx),C=new f(this.ctx),L=this.w.config.chart.animations.enabled,P=L&&this.w.config.chart.animations.dynamicAnimation.enabled,T=!!(L&&!A.globals.resized||P&&A.globals.dataChanged&&A.globals.shouldAnimate);T?i=r:(i=o,A.globals.animationEnded=!0);var M=A.config.stroke.dashArray,I=0;I=Array.isArray(M)?M[s]:A.config.stroke.dashArray;var z=this.drawPath({d:i,stroke:n,strokeWidth:l,fill:c,fillOpacity:1,classes:p,strokeLinecap:h,strokeDashArray:I});if(z.attr("index",s),v&&z.attr({"clip-path":"url(#gridRectMask".concat(A.globals.cuid,")")}),"none"!==A.config.states.normal.filter.type)S.getDefaultFilter(z,s);else if(A.config.chart.dropShadow.enabled&&k&&(!A.config.chart.dropShadow.enabledOnSeries||A.config.chart.dropShadow.enabledOnSeries&&-1!==A.config.chart.dropShadow.enabledOnSeries.indexOf(s))){var X=A.config.chart.dropShadow;S.dropShadow(z,X,s)}y&&(z.node.addEventListener("mouseenter",this.pathMouseEnter.bind(this,z)),z.node.addEventListener("mouseleave",this.pathMouseLeave.bind(this,z)),z.node.addEventListener("mousedown",this.pathMouseDown.bind(this,z))),z.attr({pathTo:o,pathFrom:r});var E={el:z,j:a,realIndex:s,pathFrom:r,pathTo:o,fill:c,strokeWidth:l,delay:d};return!L||A.globals.resized||A.globals.dataChanged?!A.globals.resized&&A.globals.dataChanged||C.showDelayedElements():C.animatePathsGradually(e(e({},E),{},{speed:g})),A.globals.dataChanged&&P&&T&&C.animatePathsGradually(e(e({},E),{},{speed:u})),z}},{key:"drawPattern",value:function(t,e,i){var a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"#a8a8a8",s=arguments.length>4&&void 0!==arguments[4]?arguments[4]:0,r=this.w,o=r.globals.dom.Paper.pattern(e,i,(function(r){"horizontalLines"===t?r.line(0,0,i,0).stroke({color:a,width:s+1}):"verticalLines"===t?r.line(0,0,0,e).stroke({color:a,width:s+1}):"slantedLines"===t?r.line(0,0,e,i).stroke({color:a,width:s}):"squares"===t?r.rect(e,i).fill("none").stroke({color:a,width:s}):"circles"===t&&r.circle(e).fill("none").stroke({color:a,width:s})}));return o}},{key:"drawGradient",value:function(t,e,i,a,s){var r,o=arguments.length>5&&void 0!==arguments[5]?arguments[5]:null,n=arguments.length>6&&void 0!==arguments[6]?arguments[6]:null,l=arguments.length>7&&void 0!==arguments[7]?arguments[7]:null,h=arguments.length>8&&void 0!==arguments[8]?arguments[8]:0,c=this.w;e.length<9&&0===e.indexOf("#")&&(e=p.hexToRgba(e,a)),i.length<9&&0===i.indexOf("#")&&(i=p.hexToRgba(i,s));var d=0,g=1,u=1,f=null;null!==n&&(d=void 0!==n[0]?n[0]/100:0,g=void 0!==n[1]?n[1]/100:1,u=void 0!==n[2]?n[2]/100:1,f=void 0!==n[3]?n[3]/100:null);var x=!("donut"!==c.config.chart.type&&"pie"!==c.config.chart.type&&"polarArea"!==c.config.chart.type&&"bubble"!==c.config.chart.type);if(r=null===l||0===l.length?c.globals.dom.Paper.gradient(x?"radial":"linear",(function(t){t.at(d,e,a),t.at(g,i,s),t.at(u,i,s),null!==f&&t.at(f,e,a)})):c.globals.dom.Paper.gradient(x?"radial":"linear",(function(t){(Array.isArray(l[h])?l[h]:l).forEach((function(e){t.at(e.offset/100,e.color,e.opacity)}))})),x){var b=c.globals.gridWidth/2,v=c.globals.gridHeight/2;"bubble"!==c.config.chart.type?r.attr({gradientUnits:"userSpaceOnUse",cx:b,cy:v,r:o}):r.attr({cx:.5,cy:.5,r:.8,fx:.2,fy:.2})}else"vertical"===t?r.from(0,0).to(0,1):"diagonal"===t?r.from(0,0).to(1,1):"horizontal"===t?r.from(0,1).to(1,1):"diagonal2"===t&&r.from(1,0).to(0,1);return r}},{key:"drawText",value:function(t){var e,i=t.x,a=t.y,s=t.text,r=t.textAnchor,o=t.fontSize,n=t.fontFamily,l=t.fontWeight,h=t.foreColor,c=t.o
61903pacity,d=t.cssClass,g=void 0===d?"":d,u=t.isPlainText,p=void 0===u||u,f=this.w;return void 0===s&&(s=""),r||(r="start"),h&&h.length||(h=f.config.chart.foreColor),n=n||f.config.chart.fontFamily,l=l||"regular",(e=Array.isArray(s)?f.globals.dom.Paper.text((function(t){for(var e=0;e<s.length;e++)0===e?t.tspan(s[e]):t.tspan(s[e]).newLine()})):p?f.globals.dom.Paper.plain(s):f.globals.dom.Paper.text((function(t){return t.tspan(s)}))).attr({x:i,y:a,"text-anchor":r,"dominant-baseline":"auto","font-size":o,"font-family":n,"font-weight":l,fill:h,class:"apexcharts-text "+g}),e.node.style.fontFamily=n,e.node.style.opacity=c,e}},{key:"drawMarker",value:function(t,e,i){t=t||0;var a=i.pSize||0,s=null;if("square"===i.shape||"rect"===i.shape){var r=void 0===i.pRadius?a/2:i.pRadius;null!==e&&a||(a=0,r=0);var o=1.2*a+r,n=this.drawRect(o,o,o,o,r);n.attr({x:t-o/2,y:e-o/2,cx:t,cy:e,class:i.class?i.class:"",fill:i.pointFillColor,"fill-opacity":i.pointFillOpacity?i.pointFillOpacity:1,stroke:i.pointStrokeColor,"stroke-width":i.pointStrokeWidth?i.pointStrokeWidth:0,"stroke-opacity":i.pointStrokeOpacity?i.pointStrokeOpacity:1}),s=n}else"circle"!==i.shape&&i.shape||(p.isNumber(e)||(a=0,e=0),s=this.drawCircle(a,{cx:t,cy:e,class:i.class?i.class:"",stroke:i.pointStrokeColor,fill:i.pointFillColor,"fill-opacity":i.pointFillOpacity?i.pointFillOpacity:1,"stroke-width":i.pointStrokeWidth?i.pointStrokeWidth:0,"stroke-opacity":i.pointStrokeOpacity?i.pointStrokeOpacity:1}));return s}},{key:"pathMouseEnter",value:function(t,e){var i=this.w,a=new x(this.ctx),s=parseInt(t.node.getAttribute("index"),10),r=parseInt(t.node.getAttribute("j"),10);if("function"==typeof i.config.chart.events.dataPointMouseEnter&&i.config.chart.events.dataPointMouseEnter(e,this.ctx,{seriesIndex:s,dataPointIndex:r,w:i}),this.ctx.events.fireEvent("dataPointMouseEnter",[e,this.ctx,{seriesIndex:s,dataPointIndex:r,w:i}]),("none"===i.config.states.active.filter.type||"true"!==t.node.getAttribute("selected"))&&"none"!==i.config.states.hover.filter.type&&!i.globals.isTouchDevice){var o=i.config.states.hover.filter;a.applyFilter(t,s,o.type,o.value)}}},{key:"pathMouseLeave",value:function(t,e){var i=this.w,a=new x(this.ctx),s=parseInt(t.node.getAttribute("index"),10),r=parseInt(t.node.getAttribute("j"),10);"function"==typeof i.config.chart.events.dataPointMouseLeave&&i.config.chart.events.dataPointMouseLeave(e,this.ctx,{seriesIndex:s,dataPointIndex:r,w:i}),this.ctx.events.fireEvent("dataPointMouseLeave",[e,this.ctx,{seriesIndex:s,dataPointIndex:r,w:i}]),"none"!==i.config.states.active.filter.type&&"true"===t.node.getAttribute("selected")||"none"!==i.config.states.hover.filter.type&&a.getDefaultFilter(t,s)}},{key:"pathMouseDown",value:function(t,e){var i=this.w,a=new x(this.ctx),s=parseInt(t.node.getAttribute("index"),10),r=parseInt(t.node.getAttribute("j"),10),o="false";if("true"===t.node.getAttribute("selected")){if(t.node.setAttribute("selected","false"),i.globals.selectedDataPoints[s].indexOf(r)>-1){var n=i.globals.selectedDataPoints[s].indexOf(r);i.globals.selectedDataPoints[s].splice(n,1)}}else{if(!i.config.states.active.allowMultipleDataPointsSelection&&i.globals.selectedDataPoints.length>0){i.globals.selectedDataPoints=[];var l=i.globals.dom.Paper.select(".apexcharts-series path").members,h=i.globals.dom.Paper.select(".apexcharts-series circle, .apexcharts-series rect").members,c=function(t){Array.prototype.forEach.call(t,(function(t){t.node.setAttribute("selected","false"),a.getDefaultFilter(t,s)}))};c(l),c(h)}t.node.setAttribute("selected","true"),o="true",void 0===i.globals.selectedDataPoints[s]&&(i.globals.selectedDataPoints[s]=[]),i.globals.selectedDataPoints[s].push(r)}if("true"===o){var d=i.config.states.active.filter;"none"!==d&&a.applyFilter(t,s,d.type,d.value)}else"none"!==i.config.states.active.filter.type&&a.getDefaultFilter(t,s);"function"==typeof i.config.chart.events.dataPointSelection&&i.config.chart.events.dataPointSelection(e,this.ctx,{selectedDataPoints:i.globals.selectedDataPoints,seriesIndex:s,dataPointIndex:r,w:i}),e&&this.ctx.events.fireEvent("dataPointSelection",[e,this.ctx,{selectedDataPoints:i.globals.selectedDataPoints,seriesIndex:s,dataPointIndex:r,w:i}])}}
61903,{key:"rotateAroundCenter",value:function(t){var e={};return t&&"function"==typeof t.getBBox&&(e=t.getBBox()),{x:e.x+e.width/2,y:e.y+e.height/2}}},{key:"getTextRects",value:function(t,e,i,a){var s=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],r=this.w,o=this.drawText({x:-200,y:-200,text:t,textAnchor:"start",fontSize:e,fontFamily:i,foreColor:"#fff",opacity:0});a&&o.attr("transform",a),r.globals.dom.Paper.add(o);var n=o.bbox();return s||(n=o.node.getBoundingClientRect()),o.remove(),{width:n.width,height:n.height}}},{key:"placeTextWithEllipsis",value:function(t,e,i){if("function"==typeof t.getComputedTextLength&&(t.textContent=e,e.length>0&&t.getComputedTextLength()>=i/1.1)){for(var a=e.length-3;a>0;a-=3)if(t.getSubStringLength(0,a)<=i/1.1)return void(t.textContent=e.substring(0,a)+"...");t.textContent="."}}}],[{key:"setAttrs",value:function(t,e){for(var i in e)e.hasOwnProperty(i)&&t.setAttribute(i,e[i])}}]),t}(),v=function(){function t(e){a(this,t),this.w=e.w,this.annoCtx=e}return r(t,[{key:"setOrientations",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,i=this.w;if("vertical"===t.label.orientation){var a=null!==e?e:0,s=i.globals.dom.baseEl.querySelector(".apexcharts-xaxis-annotations .apexcharts-xaxis-annotation-label[rel='".concat(a,"']"));if(null!==s){var r=s.getBoundingClientRect();s.setAttribute("x",parseFloat(s.getAttribute("x"))-r.height+4),"top"===t.label.position?s.setAttribute("y",parseFloat(s.getAttribute("y"))+r.width):s.setAttribute("y",parseFloat(s.getAttribute("y"))-r.width);var o=this.annoCtx.graphics.rotateAroundCenter(s),n=o.x,l=o.y;s.setAttribute("transform","rotate(-90 ".concat(n," ").concat(l,")"))}}}},{key:"addBackgroundToAnno",value:function(t,e){var i=this.w;if(!t||void 0===e.label.text||void 0!==e.label.text&&!String(e.label.text).trim())return null;var a=i.globals.dom.baseEl.querySelector(".apexcharts-grid").getBoundingClientRect(),s=t.getBoundingClientRect(),r=e.label.style.padding.left,o=e.label.style.padding.right,n=e.label.style.padding.top,l=e.label.style.padding.bottom;"vertical"===e.label.orientation&&(n=e.label.style.padding.left,l=e.label.style.padding.right,r=e.label.style.padding.top,o=e.label.style.padding.bottom);var h=s.left-a.left-r,c=s.top-a.top-n,d=this.annoCtx.graphics.drawRect(h-i.globals.barPadForNumericAxis,c,s.width+r+o,s.height+n+l,e.label.borderRadius,e.label.style.background,1,e.label.borderWidth,e.label.borderColor,0);return e.id&&d.node.classList.add(p.escapeString(e.id)),d}},{key:"annotationsBackground",value:function(){var t=this,e=this.w,i=function(i,a,s){var r=e.globals.dom.baseEl.querySelector(".apexcharts-".concat(s,"-annotations .apexcharts-").concat(s,"-annotation-label[rel='").concat(a,"']"));if(r){var o=r.parentNode,n=t.addBackgroundToAnno(r,i);n&&(o.insertBefore(n.node,r),i.label.mouseEnter&&n.node.addEventListener("mouseenter",i.label.mouseEnter.bind(t,i)),i.label.mouseLeave&&n.node.addEventListener("mouseleave",i.label.mouseLeave.bind(t,i)))}};e.config.annotations.xaxis.map((function(t,e){i(t,e,"xaxis")})),e.config.annotations.yaxis.map((function(t,e){i(t,e,"yaxis")})),e.config.annotations.points.map((function(t,e){i(t,e,"point")}))}},{key:"getStringX",value:function(t){var e=this.w,i=t;e.config.xaxis.convertedCatToNumeric&&e.globals.categoryLabels.length&&(t=e.globals.categoryLabels.indexOf(t)+1);var a=e.globals.labels.indexOf(t),s=e.globals.dom.baseEl.querySelector(".apexcharts-xaxis-texts-g text:nth-child("+(a+1)+")");return s&&(i=parseFloat(s.getAttribute("x"))),i}}]),t}(),m=function(){function t(e){a(this,t),this.w=e.w,this.annoCtx=e,this.invertAxis=this.annoCtx.invertAxis}return r(t,[{key:"addXaxisAnnotation",value:function(t,e,i){var a=this.w,s=this.invertAxis?a.globals.minY:a.globals.minX,r=this.invertAxis?a.globals.maxY:a.globals.maxX,o=this.invertAxis?a.globals.yRange[0]:a.globals.xRange,n=(t.x-s)/(o/a.globals.gridWidth);this.annoCtx.inversedReversedAxis&&(n=(r-t.x)/(o/a.globals.gridWidth));var l=t.label.text;"category"!==a.config.xaxis.type&&!a.config.xaxis.convertedCatToNumeric||this.invertAxis||a.globals.dataFormatXNumeric||(n=this.annoCtx.helpers.getStringX(t.x));var h=t.strokeDashArray;if(p.isNumber(n)){if(null===t.x2||void 0===t.x2){var c=this.annoCtx.graphics.drawLine(n+t.offsetX,0+t.offsetY,n+t.offsetX,a.globals.gridHeight+t.offsetY,t.borderColor,h,t.borderWidth);e.appendChild(c.node),t.id&&c.node.classList.add(t.id)}else{var d=(t.x2-s)/(o/a.globals.gridWidth);if(this.annoCtx.inversedReversedAxis&&(d=(r-t.x2)/(o/a.globals.gridWidth)),"category"!==a.config.xaxis.type&&!a.config.xaxis.convertedCatToNumeric||this.invertAxis||a.globals.dataFormatXNumeric||(d=this.annoCtx.helpers.getStringX(t.x2)),d<n){var g=n;n=d,d=g}var u=this.annoCtx.graphics.drawRect(n+t.offsetX,0+t.offsetY,d-n,a.globals.gridHeight+t.offsetY,0,t.fillColor,t.opacity,1,t.borderColor,h);u.node.classList.add("apexcharts-annotation-rect"),u.attr("clip-path","url(#gridRectMask".concat(a.globals.cuid,")")),e.appendChild(u.node),t.id&&u.node.classList.add(t.id)}var f="top"===t.label.position?4:a.globals.gridHeight,x=this.annoCtx.graphics.getTextRects(l,parseFloat(t.label.style.fontSize)),b=this.annoCtx.graphics.drawText({x:n+t.label.offsetX,y:f+t.label.offsetY-("vertical"===t.label.orientation?"top"===t.label.position?x.width/2-12:-x.width/2:0),text:l,textAnchor:t.label.textAnchor,fontSize:t.label.style.fontSize,fontFamily:t.label.style.fontFamily,fontWeight:t.label.style.fontWeight,foreColor:t.label.style.color,cssClass:"apexcharts-xaxis-annotation-label ".concat(t.label.style.cssClass," ").concat(t.id?t.id:"")});b.attr({rel:i}),e.appendChild(b.node),this.annoCtx.helpers.setOrientations(t,i)}}},{key:"drawXAxisAnnotations",value:function(){var t=this,e=this.w,i=this.annoCtx.graphics.group({class:"apexcharts-xaxis-annotations"});return e.config.annotations.xaxis.map((function(e,a){t.addXaxisAnnotation(e,i.node,a)})),i}}]),t}(),y=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w}return r(t,[{key:"getStackedSeriesTotals",value:function(){var t=this.w,e=[];
61903if(0===t.globals.series.length)return e;for(var i=0;i<t.globals.series[t.globals.maxValsInArrayIndex].length;i++){for(var a=0,s=0;s<t.globals.series.length;s++)void 0!==t.globals.series[s][i]&&(a+=t.globals.series[s][i]);e.push(a)}return t.globals.stackedSeriesTotals=e,e}},{key:"getSeriesTotalByIndex",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;return null===t?this.w.config.series.reduce((function(t,e){return t+e}),0):this.w.globals.series[t].reduce((function(t,e){return t+e}),0)}},{key:"isSeriesNull",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;return 0===(null===t?this.w.config.series.filter((function(t){return null!==t})):this.w.config.series[t].data.filter((function(t){return null!==t}))).length}},{key:"seriesHaveSameValues",value:function(t){return this.w.globals.series[t].every((function(t,e,i){return t===i[0]}))}},{key:"getCategoryLabels",value:function(t){var e=this.w,i=t.slice();return e.config.xaxis.convertedCatToNumeric&&(i=t.map((function(t,i){return e.config.xaxis.labels.formatter(t-e.globals.minX+1)}))),i}},{key:"getLargestSeries",value:function(){var t=this.w;t.globals.maxValsInArrayIndex=t.globals.series.map((function(t){return t.length})).indexOf(Math.max.apply(Math,t.globals.series.map((function(t){return t.length}))))}},{key:"getLargestMarkerSize",value:function(){var t=this.w,e=0;return t.globals.markers.size.forEach((function(t){e=Math.max(e,t)})),t.globals.markers.largestSize=e,e}},{key:"getSeriesTotals",value:function(){var t=this.w;t.globals.seriesTotals=t.globals.series.map((function(t,e){var i=0;if(Array.isArray(t))for(var a=0;a<t.length;a++)i+=t[a];else i+=t;return i}))}},{key:"getSeriesTotalsXRange",value:function(t,e){var i=this.w;return i.globals.series.map((function(a,s){for(var r=0,o=0;o<a.length;o++)i.globals.seriesX[s][o]>t&&i.globals.seriesX[s][o]<e&&(r+=a[o]);return r}))}},{key:"getPercentSeries",value:function(){var t=this.w;t.globals.seriesPercent=t.globals.series.map((function(e,i){var a=[];if(Array.isArray(e))for(var s=0;s<e.length;s++){var r=t.globals.stackedSeriesTotals[s],o=0;r&&(o=100*e[s]/r),a.push(o)}else{var n=100*e/t.globals.seriesTotals.reduce((function(t,e){return t+e}),0);a.push(n)}return a}))}},{key:"getCalculatedRatios",value:function(){var t,e,i,a,s=this.w.globals,r=[],o=0,n=[],l=.1,h=0;if(s.yRange=[],s.isMultipleYAxis)for(var c=0;c<s.minYArr.length;c++)s.yRange.push(Math.abs(s.minYArr[c]-s.maxYArr[c])),n.push(0);else s.yRange.push(Math.abs(s.minY-s.maxY));s.xRange=Math.abs(s.maxX-s.minX),s.zRange=Math.abs(s.maxZ-s.minZ);for(var d=0;d<s.yRange.length;d++)r.push(s.yRange[d]/s.gridHeight);if(e=s.xRange/s.gridWidth,i=Math.abs(s.initialMaxX-s.initialMinX)/s.gridWidth,t=s.yRange/s.gridWidth,a=s.xRange/s.gridHeight,(o=s.zRange/s.gridHeight*16)||(o=1),s.minY!==Number.MIN_VALUE&&0!==Math.abs(s.minY)&&(s.hasNegs=!0),s.isMultipleYAxis){n=[];for(var g=0;g<r.length;g++)n.push(-s.minYArr[g]/r[g])}else n.push(-s.minY/r[0]),s.minY!==Number.MIN_VALUE&&0!==Math.abs(s.minY)&&(l=-s.minY/t,h=s.minX/e);return{yRatio:r,invertedYRatio:t,zRatio:o,xRatio:e,initialXRatio:i,invertedXRatio:a,baseLineInvertedY:l,baseLineY:n,baseLineX:h}}},{key:"getLogSeries",value:function(t){var e=this,i=this.w;return i.globals.seriesLog=t.map((function(t,a){return i.config.yaxis[a]&&i.config.yaxis[a].logarithmic?t.map((function(t){return null===t?null:e.getLogVal(t,a)})):t})),i.globals.invalidLogScale?t:i.globals.seriesLog}},{key:"getLogVal",value:function(t,e){var i=this.w,a=(Math.log(t)-Math.log(i.globals.minYArr[e]))/(Math.log(i.globals.maxYArr[e])-Math.log(i.globals.minYArr[e]));return isNaN(a)?t:a}},{key:"getLogYRatios",value:function(t){var e=this,i=this.w,a=this.w.globals;return a.yLogRatio=t.slice(),a.logYRange=a.yRange.map((function(t,s){if(i.config.yaxis[s]&&e.w.config.yaxis[s].logarithmic){var r,o=-Number.MAX_VALUE,n=Number.MIN_VALUE;return a.seriesLog.forEach((function(t,e){t.forEach((function(t){i.config.yaxis[e]&&i.config.yaxis[e].logarithmic&&(o=Math.max(t,o),n=Math.min(t,n))}))})),r=Math.pow(a.yRange[s],Math.abs(n-o)/a.yRange[s]),a.yLogRatio[s]=r/a.gridHeight,r}}
61903)),a.invalidLogScale?t.slice():a.yLogRatio}}],[{key:"checkComboSeries",value:function(t){var e=!1,i=0,a=0;return t.length&&void 0!==t[0].type&&t.forEach((function(t){"bar"!==t.type&&"column"!==t.type&&"candlestick"!==t.type&&"boxPlot"!==t.type||i++,void 0!==t.type&&a++})),a>0&&(e=!0),{comboBarCount:i,comboCharts:e}}},{key:"extendArrayProps",value:function(t,e,i){return e.yaxis&&(e=t.extendYAxis(e,i)),e.annotations&&(e.annotations.yaxis&&(e=t.extendYAxisAnnotations(e)),e.annotations.xaxis&&(e=t.extendXAxisAnnotations(e)),e.annotations.points&&(e=t.extendPointAnnotations(e))),e}}]),t}(),w=function(){function t(e){a(this,t),this.w=e.w,this.annoCtx=e}return r(t,[{key:"addYaxisAnnotation",value:function(t,e,i){var a,s=this.w,r=t.strokeDashArray,o=this._getY1Y2("y1",t),n=t.label.text;if(null===t.y2||void 0===t.y2){var l=this.annoCtx.graphics.drawLine(0+t.offsetX,o+t.offsetY,this._getYAxisAnnotationWidth(t),o+t.offsetY,t.borderColor,r,t.borderWidth);e.appendChild(l.node),t.id&&l.node.classList.add(t.id)}else{if((a=this._getY1Y2("y2",t))>o){var h=o;o=a,a=h}var c=this.annoCtx.graphics.drawRect(0+t.offsetX,a+t.offsetY,this._getYAxisAnnotationWidth(t),o-a,0,t.fillColor,t.opacity,1,t.borderColor,r);c.node.classList.add("apexcharts-annotation-rect"),c.attr("clip-path","url(#gridRectMask".concat(s.globals.cuid,")")),e.appendChild(c.node),t.id&&c.node.classList.add(t.id)}var d="right"===t.label.position?s.globals.gridWidth:0,g=this.annoCtx.graphics.drawText({x:d+t.label.offsetX,y:(null!=a?a:o)+t.label.offsetY-3,text:n,textAnchor:t.label.textAnchor,fontSize:t.label.style.fontSize,fontFamily:t.label.style.fontFamily,fontWeight:t.label.style.fontWeight,foreColor:t.label.style.color,cssClass:"apexcharts-yaxis-annotation-label ".concat(t.label.style.cssClass," ").concat(t.id?t.id:"")});g.attr({rel:i}),e.appendChild(g.node)}},{key:"_getY1Y2",value:function(t,e){var i,a="y1"===t?e.y:e.y2,s=this.w;if(this.annoCtx.invertAxis){var r=s.globals.labels.indexOf(a);s.config.xaxis.convertedCatToNumeric&&(r=s.globals.categoryLabels.indexOf(a));var o=s.globals.dom.baseEl.querySelector(".apexcharts-yaxis-texts-g text:nth-child("+(r+1)+")");o&&(i=parseFloat(o.getAttribute("y")))}else{var n;if(s.config.yaxis[e.yAxisIndex].logarithmic)n=(a=new y(this.annoCtx.ctx).getLogVal(a,e.yAxisIndex))/s.globals.yLogRatio[e.yAxisIndex];else n=(a-s.globals.minYArr[e.yAxisIndex])/(s.globals.yRange[e.yAxisIndex]/s.globals.gridHeight);i=s.globals.gridHeight-n,s.config.yaxis[e.yAxisIndex]&&s.config.yaxis[e.yAxisIndex].reversed&&(i=n)}return i}},{key:"_getYAxisAnnotationWidth",value:function(t){var e=this.w;e.globals.gridWidth;return(t.width.indexOf("%")>-1?e.globals.gridWidth*parseInt(t.width,10)/100:parseInt(t.width,10))+t.offsetX}},{key:"drawYAxisAnnotations",value:function(){var t=this,e=this.w,i=this.annoCtx.graphics.group({class:"apexcharts-yaxis-annotations"});return e.config.annotations.yaxis.map((function(e,a){t.addYaxisAnnotation(e,i.node,a)})),i}}]),t}(),k=function(){function t(e){a(this,t),this.w=e.w,this.annoCtx=e}return r(t,[{key:"addPointAnnotation",value:function(t,e,i){var a=this.w,s=0,r=0,o=0;this.annoCtx.invertAxis&&console.warn("Point annotation is not supported in horizontal bar charts.");var n=parseFloat(t.y);if("string"==typeof t.x||"category"===a.config.xaxis.type||a.config.xaxis.convertedCatToNumeric){var l=a.globals.labels.indexOf(t.x);a.config.xaxis.convertedCatToNumeric&&(l=a.globals.categoryLabels.indexOf(t.x)),s=this.annoCtx.helpers.getStringX(t.x),null===t.y&&(n=a.globals.series[t.seriesIndex][l])}else s=(t.x-a.globals.minX)/(a.globals.xRange/a.globals.gridWidth);for(var h,c=[],d=0,g=0;g<=t.seriesIndex;g++){var u=a.config.yaxis[g].seriesName;if(u)for(var f=g+1;f<=t.seriesIndex;f++)a.config.yaxis[f].seriesName===u&&-1===c.indexOf(u)&&(d++,c.push(u))}
vendor: 11,966 bytes, line 61903
61903if(a.config.yaxis[t.yAxisIndex].logarithmic){h=(n=new y(this.annoCtx.ctx).getLogVal(n,t.yAxisIndex))/a.globals.yLogRatio[t.yAxisIndex]}else{var x=t.yAxisIndex+d;h=(n-a.globals.minYArr[x])/(a.globals.yRange[x]/a.globals.gridHeight)}if(r=a.globals.gridHeight-h-parseFloat(t.label.style.fontSize)-t.marker.size,o=a.globals.gridHeight-h,a.config.yaxis[t.yAxisIndex]&&a.config.yaxis[t.yAxisIndex].reversed&&(r=h+parseFloat(t.label.style.fontSize)+t.marker.size,o=h),p.isNumber(s)){var b={pSize:t.marker.size,pointStrokeWidth:t.marker.strokeWidth,pointFillColor:t.marker.fillColor,pointStrokeColor:t.marker.strokeColor,shape:t.marker.shape,pRadius:t.marker.radius,class:"apexcharts-point-annotation-marker ".concat(t.marker.cssClass," ").concat(t.id?t.id:"")},v=this.annoCtx.graphics.drawMarker(s+t.marker.offsetX,o+t.marker.offsetY,b);e.appendChild(v.node);var m=t.label.text?t.label.text:"",w=this.annoCtx.graphics.drawText({x:s+t.label.offsetX,y:r+t.label.offsetY,text:m,textAnchor:t.label.textAnchor,fontSize:t.label.style.fontSize,fontFamily:t.label.style.fontFamily,fontWeight:t.label.style.fontWeight,foreColor:t.label.style.color,cssClass:"apexcharts-point-annotation-label ".concat(t.label.style.cssClass," ").concat(t.id?t.id:"")});if(w.attr({rel:i}),e.appendChild(w.node),t.customSVG.SVG){var k=this.annoCtx.graphics.group({class:"apexcharts-point-annotations-custom-svg "+t.customSVG.cssClass});k.attr({transform:"translate(".concat(s+t.customSVG.offsetX,", ").concat(r+t.customSVG.offsetY,")")}),k.node.innerHTML=t.customSVG.SVG,e.appendChild(k.node)}if(t.image.path){var A=t.image.width?t.image.width:20,S=t.image.height?t.image.height:20;v=this.annoCtx.addImage({x:s+t.image.offsetX-A/2,y:r+t.image.offsetY-S/2,width:A,height:S,path:t.image.path,appendTo:".apexcharts-point-annotations"})}t.mouseEnter&&v.node.addEventListener("mouseenter",t.mouseEnter.bind(this,t)),t.mouseLeave&&v.node.addEventListener("mouseleave",t.mouseLeave.bind(this,t))}}},{key:"drawPointAnnotations",value:function(){var t=this,e=this.w,i=this.annoCtx.graphics.group({class:"apexcharts-point-annotations"});return e.config.annotations.points.map((function(e,a){t.addPointAnnotation(e,i.node,a)})),i}}]),t}();var A={name:"en",options:{months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],toolbar:{exportToSVG:"Download SVG",exportToPNG:"Download PNG",exportToCSV:"Download CSV",menu:"Menu",selection:"Selection",selectionZoom:"Selection Zoom",zoomIn:"Zoom In",zoomOut:"Zoom Out",pan:"Panning",reset:"Reset Zoom"}}},S=function(){function t(){a(this,t),this.yAxis={show:!0,showAlways:!1,showForNullSeries:!0,seriesName:void 0,opposite:!1,reversed:!1,logarithmic:!1,logBase:10,tickAmount:void 0,forceNiceScale:!1,max:void 0,min:void 0,floating:!1,decimalsInFloat:void 0,labels:{show:!0,minWidth:0,maxWidth:160,offsetX:0,offsetY:0,align:void 0,rotate:0,padding:20,style:{colors:[],fontSize:"11px",fontWeight:400,fontFamily:void 0,cssClass:""},formatter:void 0},axisBorder:{show:!1,color:"#e0e0e0",width:1,offsetX:0,offsetY:0},axisTicks:{show:!1,color:"#e0e0e0",width:6,offsetX:0,offsetY:0},title:{text:void 0,rotate:-90,offsetY:0,offsetX:0,style:{color:void 0,fontSize:"11px",fontWeight:900,fontFamily:void 0,cssClass:""}},tooltip:{enabled:!1,offsetX:0},crosshairs:{show:!0,position:"front",stroke:{color:"#b6b6b6",width:1,dashArray:0}}},this.pointAnnotation={id:void 0,x:0,y:null,yAxisIndex:0,seriesIndex:0,mouseEnter:void 0,mouseLeave:void 0,marker:{size:4,fillColor:"#fff",strokeWidth:2,strokeColor:"#333",shape:"circle",offsetX:0,offsetY:0,radius:2,cssClass:""},label:{borderColor:"#c2c2c2",borderWidth:1,borderRadius:2,text:void 0,textAnchor:"middle",offsetX:0,offsetY:0,mouseEnter:void 0,mouseLeave:void 0,style:{background:"#fff",color:void 0,fontSize:"11px",fontFamily:void 0,fontWeight:400,cssClass:"",padding:{left:5,right:5,top:2,bottom:2}}},customSVG:{SVG:void 0,cssClass:void 0,offsetX:0,offsetY:0},image:{path:void 0,width:20,height:20,offsetX:0,offsetY:0}},this.yAxisAnnotation={id:void 0,y:0,y2:null,strokeDashArray:1,fillColor:"#c2c2c2",borderColor:"#c2c2c2",borderWidth:1,opacity:.3,offsetX:0,offsetY:0,width:"100%",yAxisIndex:0,label:{borderColor:"#c2c2c2",borderWidth:1,borderRadius:2,text:void 0,textAnchor:"end",position:"right",offsetX:0,offsetY:-3,mouseEnter:void 0,mouseLeave:void 0,style:{background:"#fff",color:void 0,fontSize:"11px",fontFamily:void 0,fontWeight:400,cssClass:"",padding:{left:5,right:5,top:2,bottom:2}}}},this.xAxisAnnotation={id:void 0,x:0,x2:null,strokeDashArray:1,fillColor:"#c2c2c2",borderColor:"#c2c2c2",borderWidth:1,opacity:.3,offsetX:0,offsetY:0,label:{borderColor:"#c2c2c2",borderWidth:1,borderRadius:2,text:void 0,textAnchor:"middle",orientation:"vertical",position:"top",offsetX:0,offsetY:0,mouseEnter:void 0,mouseLeave:void 0,style:{background:"#fff",color:void 0,fontSize:"11px",fontFamily:void 0,fontWeight:400,cssClass:"",padding:{left:5,right:5,top:2,bottom:2}}}},this.text={x:0,y:0,text:"",textAnchor:"start",foreColor:void 0,fontSize:"13px",fontFamily:void 0,fontWeight:400,appendTo:".apexcharts-annotations",backgroundColor:"transparent",borderColor:"#c2c2c2",borderRadius:0,borderWidth:0,paddingLeft:4,paddingRight:4,paddingTop:2,paddingBottom:2}}return r(t,[{key:"init",value:function(){return{annotations:{position:"front",yaxis:[this.yAxisAnnotation],xaxis:[this.xAxisAnnotation],points:[this.pointAnnotation],texts:[],images:[],shapes:[]},chart:{animations:{enabled:!0,easing:"easeinout",speed:800,animateGradually:{delay:150,enabled:!0},dynamicAnimation:{enabled:!0,speed:350}},background:"transparent",locales:[A],defaultLocale:"en",dropShadow:{enabled:!1,enabledOnSeries:void 0,top:2,left:2,blur:4,color:"#000",opacity:.35},events:{animationEnd:void 0,beforeMount:void 0,mounted:void 0,updated:void 0,click:void 0,mouseMove:void 0,mouseLeave:void 0,legendClick:void 0,markerClick:void 0,selection:void 0,dataPointSelection:void 0,dataPointMouseEnter:void 0,dataPointMouseLeave:void 0,beforeZoom:void 0,beforeResetZoom:void 0,zoomed:void 0,scrolled:void 0,brushScrolled:void 0},foreColor:"#373d3f",fontFamily:"Helvetica, Arial, sans-serif",height:"auto",parentHeightOffset:15,redrawOnParentResize:!0,redrawOnWindowResize:!0,id:void 0,group:void 0,offsetX:0,offsetY:0,selection:{enabled:!1,type:"x",fill:{color:"#24292e",opacity:.1},stroke:{width:1,color:"#24292e",opacity:.4,dashArray:3},xaxis:{min:void 0,max:void 0},yaxis:{min:void 0,max:void 0}},sparkline:{enabled:!1},brush:{enabled:!1,autoScaleYaxis:!0,target:void 0},stacked:!1,stackType:"normal",toolbar:{show:!0,offsetX:0,offsetY:0,tools:{download:!0,selection:!0,zoom:!0,zoomin:!0,zoomout:!0,pan:!0,reset:!0,customIcons:[]},export:{csv:{filename:void 0,columnDelimiter:",",headerCategory:"category",headerValue:"value",dateFormatter:function(t){return new Date(t).toDateString()}},png:{filename:void 0},svg:{filename:void 0}},autoSelected:"zoom"},type:"line",width:"100%",zoom:{enabled:!0,type:"x",autoScaleYaxis:!1,zoomedArea:{fill:{color:"#90CAF9",opacity:.4},stroke:{color:"#0D47A1",opacity:.4,width:1}}}},plotOptions:{area:{fillTo:"origin"},bar:{horizontal:!1,columnWidth:"70%",barHeight:"70%",distributed:!1,borderRadius:0,rangeBarOverlap:!0,rangeBarGroupRows:!1,colors:{ranges:[],backgroundBarColors:[],backgroundBarOpacity:1,backgroundBarRadius:0},dataLabels:{position:"top",maxItems:100,hideOverflowingLabels:!0,orientation:"horizontal"}},bubble:{minBubbleRadius:void 0,maxBubbleRadius:void 0},candlestick:{colors:{upward:"#00B746",downward:"#EF403C"},wick:{useFillColor:!0}},boxPlot:{colors:{upper:"#00E396",lower:"#008FFB"}},heatmap:{radius:2,enableShades:!0,shadeIntensity:.5,reverseNegativeShade:!1,distributed:!1,useFillColorAsStroke:!1,colorScale:{inverse:!1,ranges:[],min:void 0,max:void 0}},treemap:{enableShades:!0,shadeIntensity:.5,distributed:!1,reverseNegativeShade:!1,useFillColorAsStroke:!1,colorScale:{inverse:!1,ranges:[],min:void 0,max:void 0}},radialBar:{inverseOrder:!1,startAngle:0,endAngle:360,offsetX:0,offsetY:0,hollow:{margin:5,size:"50%",background:"transparent",image:void 0,imageWidth:150,imageHeight:150,imageOffsetX:0,imageOffsetY:0,imageClipped:!0,position:"front",dropShadow:{enabled:!1,top:0,left:0,blur:3,color:"#000",opacity:.5}},track:{show:!0,startAngle:void 0,endAngle:void 0,background:"#f2f2f2",strokeWidth:"97%",opacity:1,margin:5,dropShadow:{enabled:!1,top:0,left:0,blur:3,color:"#000",opacity:.5}},dataLabels:{show:!0,name:{show:!0,fontSize:"16px",fontFamily:void 0,fontWeight:600,color:void 0,offsetY:0,formatter:function(t){return t}},value:{show:!0,fontSize:"14px",fontFamily:void 0,fontWeight:400,color:void 0,offsetY:16,formatter:function(t){return t+"%"}},total:{show:!1,label:"Total",fontSize:"16px",fontWeight:600,fontFamily:void 0,color:void 0,formatter:function(t){return t.globals.seriesTotals.reduce((function(t,e){return t+e}),0)/t.globals.series.length+"%"}}}},pie:{customScale:1,offsetX:0,offsetY:0,startAngle:0,endAngle:360,expandOnClick:!0,dataLabels:{offset:0,minAngleToShowLabel:10},donut:{size:"65%",background:"transparent",labels:{show:!1,name:{show:!0,fontSize:"16px",fontFamily:void 0,fontWeight:600,color:void 0,offsetY:-10,formatter:function(t){return t}},value:{show:!0,fontSize:"20px",fontFamily:void 0,fontWeight:400,color:void 0,offsetY:10,formatter:function(t){return t}},total:{show:!1,showAlways:!1,label:"Total",fontSize:"16px",fontWeight:400,fontFamily:void 0,color:void 0,formatter:function(t){return t.globals.seriesTotals.reduce((function(t,e){return t+e}),0)}}}}},polarArea:{rings:{strokeWidth:1,strokeColor:"#e8e8e8"},spokes:{strokeWidth:1,connectorColors:"#e8e8e8"}},radar:{size:void 0,offsetX:0,offsetY:0,polygons:{strokeWidth:1,strokeColors:"#e8e8e8",connectorColors:"#e8e8e8",fill:{colors:void 0}}}},colors:void 0,dataLabels:{enabled:!0,enabledOnSeries:void 0,formatter:function(t){return null!==t?t:""},textAnchor:"middle",distributed:!1,offsetX:0,offsetY:0,style:{fontSize:"12px",fontFamily:void 0,fontWeight:600,colors:void 0},background:{enabled:!0,foreColor:"#fff",borderRadius:2,padding:4,opacity:.9,borderWidth:1,borderColor:"#fff",dropShadow:{enabled:!1,top:1,left:1,blur:1,color:"#000",opacity:.45}},dropShadow:{enabled:!1,top:1,left:1,blur:1,color:"#000",opacity:.45}},fill:{type:"solid",colors:void 0,opacity:.85,gradient:{shade:"dark",type:"horizontal",shadeIntensity:.5,gradientToColors:void 0,inverseColors:!0,opacityFrom:1,opacityTo:1,stops:[0,50,100],colorStops:[]},image:{src:[],width:void 0,height:void 0},pattern:{style:"squares",width:6,height:6,strokeWidth:2}},forecastDataPoints:{count:0,fillOpacity:.5,strokeWidth:void 0,dashArray:4},grid:{show:!0,borderColor:"#e0e0e0",strokeDashArray:0,position:"back",xaxis:{lines:{show:!1}},yaxis:{lines:{show:!0}},row:{colors:void 0,opacity:.5},column:{colors:void 0,opacity:.5},padding:{top:0,right:10,bottom:0,left:12}},labels:[],legend:{show:!0,showForSingleSeries:!1,showForNullSeries:!0,showForZeroSeries:!0,floating:!1,position:"bottom",horizontalAlign:"center",inverseOrder:!1,fontSize:"12px",fontFamily:void 0,fontWeight:400,width:void 0,height:void 0,formatter:void 0,tooltipHoverFormatter:void 0,offsetX:-20,offsetY:4,customLegendItems:[],labels:{colors:void 0,useSeriesColors:!1},markers:{width:12,height:12,strokeWidth:0,fillColors:void 0,strokeColor:"#fff",radius:12,customHTML:void 0,offsetX:0,offsetY:0,onClick:void 0},itemMargin:{horizontal:5,vertical:2},onItemClick:{toggleDataSeries:!0},onItemHover:{highlightDataSeries:!0}},markers:{discrete:[],size:0,colors:void 0,strokeColors:"#fff",strokeWidth:2,strokeOpacity:.9,strokeDashArray:0,fillOpacity:1,shape:"circle",width:8,height:8,radius:2,offsetX:0,offsetY:0,onClick:void 0,onDblClick:void 0,showNullDataPoints:!0,hover:{size:void 0,sizeOffset:3}}
vendor: 4,097 bytes, line 61903
61903,noData:{text:void 0,align:"center",verticalAlign:"middle",offsetX:0,offsetY:0,style:{color:void 0,fontSize:"14px",fontFamily:void 0}},responsive:[],series:void 0,states:{normal:{filter:{type:"none",value:0}},hover:{filter:{type:"lighten",value:.1}},active:{allowMultipleDataPointsSelection:!1,filter:{type:"darken",value:.5}}},title:{text:void 0,align:"left",margin:5,offsetX:0,offsetY:0,floating:!1,style:{fontSize:"14px",fontWeight:900,fontFamily:void 0,color:void 0}},subtitle:{text:void 0,align:"left",margin:5,offsetX:0,offsetY:30,floating:!1,style:{fontSize:"12px",fontWeight:400,fontFamily:void 0,color:void 0}},stroke:{show:!0,curve:"smooth",lineCap:"butt",width:2,colors:void 0,dashArray:0},tooltip:{enabled:!0,enabledOnSeries:void 0,shared:!0,followCursor:!1,intersect:!1,inverseOrder:!1,custom:void 0,fillSeriesColor:!1,theme:"light",style:{fontSize:"12px",fontFamily:void 0},onDatasetHover:{highlightDataSeries:!1},x:{show:!0,format:"dd MMM",formatter:void 0},y:{formatter:void 0,title:{formatter:function(t){return t?t+": ":""}}},z:{formatter:void 0,title:"Size: "},marker:{show:!0,fillColors:void 0},items:{display:"flex"},fixed:{enabled:!1,position:"topRight",offsetX:0,offsetY:0}},xaxis:{type:"category",categories:[],convertedCatToNumeric:!1,offsetX:0,offsetY:0,overwriteCategories:void 0,labels:{show:!0,rotate:-45,rotateAlways:!1,hideOverlappingLabels:!0,trim:!1,minHeight:void 0,maxHeight:120,showDuplicates:!0,style:{colors:[],fontSize:"12px",fontWeight:400,fontFamily:void 0,cssClass:""},offsetX:0,offsetY:0,format:void 0,formatter:void 0,datetimeUTC:!0,datetimeFormatter:{year:"yyyy",month:"MMM 'yy",day:"dd MMM",hour:"HH:mm",minute:"HH:mm:ss",second:"HH:mm:ss"}},axisBorder:{show:!0,color:"#e0e0e0",width:"100%",height:1,offsetX:0,offsetY:0},axisTicks:{show:!0,color:"#e0e0e0",height:6,offsetX:0,offsetY:0},tickAmount:void 0,tickPlacement:"on",min:void 0,max:void 0,range:void 0,floating:!1,decimalsInFloat:void 0,position:"bottom",title:{text:void 0,offsetX:0,offsetY:0,style:{color:void 0,fontSize:"12px",fontWeight:900,fontFamily:void 0,cssClass:""}},crosshairs:{show:!0,width:1,position:"back",opacity:.9,stroke:{color:"#b6b6b6",width:1,dashArray:3},fill:{type:"solid",color:"#B1B9C4",gradient:{colorFrom:"#D8E3F0",colorTo:"#BED1E6",stops:[0,100],opacityFrom:.4,opacityTo:.5}},dropShadow:{enabled:!1,left:0,top:0,blur:1,opacity:.4}},tooltip:{enabled:!0,offsetY:0,formatter:void 0,style:{fontSize:"12px",fontFamily:void 0}}},yaxis:this.yAxis,theme:{mode:"light",palette:"palette1",monochrome:{enabled:!1,color:"#008FFB",shadeTo:"light",shadeIntensity:.65}}}}}]),t}(),C=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w,this.graphics=new b(this.ctx),this.w.globals.isBarHorizontal&&(this.invertAxis=!0),this.helpers=new v(this),this.xAxisAnnotations=new m(this),this.yAxisAnnotations=new w(this),this.pointsAnnotations=new k(this),this.w.globals.isBarHorizontal&&this.w.config.yaxis[0].reversed&&(this.inversedReversedAxis=!0),this.xDivision=this.w.globals.gridWidth/this.w.globals.dataPoints}return r(t,[{key:"drawAxesAnnotations",value:function(){var t=this.w;if(t.globals.axisCharts){for(var e=this.yAxisAnnotations.drawYAxisAnnotations(),i=this.xAxisAnnotations.drawXAxisAnnotations(),a=this.pointsAnnotations.drawPointAnnotations(),s=t.config.chart.animations.enabled,r=[e,i,a],o=[i.node,e.node,a.node],n=0;n<3;n++)t.globals.dom.elGraphical.add(r[n]),!s||t.globals.resized||t.globals.dataChanged||"scatter"!==t.config.chart.type&&"bubble"!==t.config.chart.type&&t.globals.dataPoints>1&&o[n].classList.add("apexcharts-element-hidden"),t.globals.delayedElements.push({el:o[n],index:0});this.helpers.annotationsBackground()}}},{key:"drawImageAnnos",value:function(){var t=this;this.w.config.annotations.images.map((function(e,i){t.addImage(e,i)}))}},{key:"drawTextAnnos",value:function(){var t=this;this.w.config.annotations.texts.map((function(e,i){t.addText(e,i)}))}},{key:"addXaxisAnnotation",value:function(t,e,i){this.xAxisAnnotations.addXaxisAnnotation(t,e,i)}},{key:"addYaxisAnnotation",value:function(t,e,i){this.yAxisAnnotations.addYaxisAnnotation(t,e,
61903i)}},{key:"addPointAnnotation",value:function(t,e,i){this.pointsAnnotations.addPointAnnotation(t,e,i)}},{key:"addText",value:function(t,e){var i=t.x,a=t.y,s=t.text,r=t.textAnchor,o=t.foreColor,n=t.fontSize,l=t.fontFamily,h=t.fontWeight,c=t.cssClass,d=t.backgroundColor,g=t.borderWidth,u=t.strokeDashArray,p=t.borderRadius,f=t.borderColor,x=t.appendTo,b=void 0===x?".apexcharts-annotations":x,v=t.paddingLeft,m=void 0===v?4:v,y=t.paddingRight,w=void 0===y?4:y,k=t.paddingBottom,A=void 0===k?2:k,S=t.paddingTop,C=void 0===S?2:S,L=this.w,P=this.graphics.drawText({x:i,y:a,text:s,textAnchor:r||"start",fontSize:n||"12px",fontWeight:h||"regular",fontFamily:l||L.config.chart.fontFamily,foreColor:o||L.config.chart.foreColor,cssClass:c}),T=L.globals.dom.baseEl.querySelector(b);T&&T.appendChild(P.node);var M=P.bbox();if(s){var I=this.graphics.drawRect(M.x-m,M.y-C,M.width+m+w,M.height+A+C,p,d||"transparent",1,g,f,u);T.insertBefore(I.node,P.node)}}},{key:"addImage",value:function(t,e){var i=this.w,a=t.path,s=t.x,r=void 0===s?0:s,o=t.y,n=void 0===o?0:o,l=t.width,h=void 0===l?20:l,c=t.height,d=void 0===c?20:c,g=t.appendTo,u=void 0===g?".apexcharts-annotations":g,p=i.globals.dom.Paper.image(a);p.size(h,d).move(r,n);var f=i.globals.dom.baseEl.querySelector(u);return f&&f.appendChild(p.node),p}},{key:"addXaxisAnnotationExternal",value:function(t,e,i){return this.addAnnotationExternal({params:t,pushToMemory:e,context:i,type:"xaxis",contextMethod:i.addXaxisAnnotation}),i}},{key:"addYaxisAnnotationExternal",value:function(t,e,i){return this.addAnnotationExternal({params:t,pushToMemory:e,context:i,type:"yaxis",contextMethod:i.addYaxisAnnotation}),i}},{key:"addPointAnnotationExternal",value:function(t,e,i){return void 0===this.invertAxis&&(this.invertAxis=i.w.globals.isBarHorizontal),this.addAnnotationExternal({params:t,pushToMemory:e,context:i,type:"point",contextMethod:i.addPointAnnotation}),i}},{key:"addAnnotationExternal",value:function(t){var e=t.params,i=t.pushToMemory,a=t.context,s=t.type,r=t.contextMethod,o=a,n=o.w,l=n.globals.dom.baseEl.querySelector(".apexcharts-".concat(s,"-annotations")),h=l.childNodes.length+1,c=new S,d=Object.assign({},"xaxis"===s?c.xAxisAnnotation:"yaxis"===s?c.yAxisAnnotation:c.pointAnnotation),g=p.extend(d,e);switch(s){case"xaxis":this.addXaxisAnnotation(g,l,h);break;case"yaxis":this.addYaxisAnnotation(g,l,h);break;case"point":this.addPointAnnotation(g,l,h)}var u=n.globals.dom.baseEl.querySelector(".apexcharts-".concat(s,"-annotations .apexcharts-").concat(s,"-annotation-label[rel='").concat(h,"']")),f=this.helpers.addBackgroundToAnno(u,g);return f&&l.insertBefore(f.node,u),i&&n.globals.memory.methodsToExec.push({context:o,id:g.id?g.id:p.randomId(),method:r,label:"addAnnotation",params:e}),a}},{key:"clearAnnotations",value:function(t){var e=t.w,i=e.globals.dom.baseEl.querySelectorAll(".apexcharts-yaxis-annotations, .apexcharts-xaxis-annotations, .apexcharts-point-annotations");e.globals.memory.methodsToExec.map((function(t,i){"addText"!==t.label&&"addAnnotation"!==t.label||e.globals.memory.methodsToExec.splice(i,1)})),i=p.listToArray(i),Array.prototype.forEach.call(i,(function(t){for(;t.firstChild;)t.removeChild(t.firstChild)}))}},{key:"removeAnnotation",value:function(t,e){var i=t.w,a=i.globals.dom.baseEl.querySelectorAll(".".concat(e));a&&(i.globals.memory.methodsToExec.map((function(t,a){t.id===e&&i.globals.memory.methodsToExec.splice(a,1)})),Array.prototype.forEach.call(a,(function(t){t.parentElement.removeChild(t)})))}}]),t}(),L=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w,this.opts=null,this.seriesIndex=0}return r(t,[{key:"clippedImgArea",value:function(t){var e=this.w,i=e.config,a=parseInt(e.globals.gridWidth,10),s=parseInt(e.globals.gridHeight,10),r=a>s?a:s,o=t.image,n=0,l=0;void 0===t.width&&void 0===t.height?void 0!==i.fill.image.width&&void 0!==i.fill.image.height?(n=i.fill.image.width+1,l=i.fill.image.height):(n=r+1,l=r):(n=t.width,l=t.height);var h=document.createElementNS(e.globals.SVGNS,"pattern");b.setAttrs(h,{id:t.patternID,patternUnits:t.patternUnits?t.patternUnits:"userSpaceOnUse",width:n+"px",height:l+"px"});var c=document.createElementNS(e.globals.SVGNS,"image");h.appendChild(c),c.setAttributeNS(window.SVG.xlink,"href",o),b.setAttrs(c,{x:0,y:0,preserveAspectRatio:"none",width:n+"px",height:l+"px"}),c.style.opacity=t.opacity,e.globals.dom.elDefs.node.appendChild(h)}},{key:"getSeriesIndex",value:function(t){var e=this.w;return("bar"===e.config.chart.type||"rangeBar"===e.config.chart.type)&&e.config.plotOptions.bar.distributed||"heatmap"===e.config.chart.type||"treemap"===e.config.chart.type?this.seriesIndex=t.seriesNumber:this.seriesIndex=t.seriesNumber%e.globals.series.length,this.seriesIndex}},{key:"fillPath",value:function(t){var e=this.w;this.opts=t;var i,a,s,r=this.w.config;this.seriesIndex=this.getSeriesIndex(t);var o=this.getFillColors()[this.seriesIndex];void 0!==e.globals.seriesColors[this.seriesIndex]&&(o=e.globals.seriesColors[this.seriesIndex]),"function"==typeof o&&(o=o({seriesIndex:this.seriesIndex,dataPointIndex:t.dataPointIndex,value:t.value,w:e}));var n=this.getFillType(this.seriesIndex),l=Array.isArray(r.fill.opacity)?r.fill.opacity[this.seriesIndex]:r.fill.opacity;t.color&&(o=t.color);var h=o;if(-1===o.indexOf("rgb")?o.length<9&&(h=p.hexToRgba(o,l)):o.indexOf("rgba")>-1&&(l=p.getOpacityFromRGBA(o)),t.opacity&&(l=t.opacity),"pattern"===n&&(a=this.handlePatternFill(a,o,l,h)),"gradient"===n&&(s=this.handleGradientFill(o,l,this.seriesIndex)),"image"===n){var c=r.fill.image.src,d=t.patternID?t.patternID:"";this.clippedImgArea({opacity:l,image:Array.isArray(c)?t.seriesNumber<c.length?c[t.seriesNumber]:c[0]:c,width:t.width?t.width:void 0,height:t.height?t.height:void 0,patternUnits:t.patternUnits,patternID:"pattern".concat(e.globals.cuid).concat(t.seriesNumber+1).concat(d)}),i="url(#pattern".concat(e.globals.cuid).concat(t.seriesNumber+1).concat(d,")")}else i="gradient"===n?s:"pattern"===n?a:h;return t.solid&&(i=h),i}},{key:"getFillType",value:function(t){var e=this.w;return Array.isArray(e.config.fill.type)?e.config.fill.type[t]:e.config.fill.type}},{key:"getFillColors",value:function(){var t=this.w,e=t.config,i=this.opts,a=[];return t.globals.comboCharts?"line"===t.config.series[this.seriesIndex].type?Array.isArray(t.globals.stroke.colors)?a=t.globals.stroke.colors:a.push(t.globals.stroke.colors):Array.isArray(t.globals.fill.colors)?a=t.globals.fill.colors:a.push(t.globals.fill.colors):"line"===e.chart.type?Array.isArray(t.globals.stroke.colors)?a=t.globals.stroke.colors:a.push(t.globals.stroke.colors):Array.isArray(t.globals.fill.colors)?a=t.globals.fill.colors:a.push(t.globals.fill.colors),void 0!==i.fillColors&&(a=[],Array.isArray(i.fillColors)?a=i.fillColors.slice():a.push(i.fillColors)),a}}
61903,{key:"handlePatternFill",value:function(t,e,i,a){var s=this.w.config,r=this.opts,o=new b(this.ctx),n=void 0===s.fill.pattern.strokeWidth?Array.isArray(s.stroke.width)?s.stroke.width[this.seriesIndex]:s.stroke.width:Array.isArray(s.fill.pattern.strokeWidth)?s.fill.pattern.strokeWidth[this.seriesIndex]:s.fill.pattern.strokeWidth,l=e;Array.isArray(s.fill.pattern.style)?t=void 0!==s.fill.pattern.style[r.seriesNumber]?o.drawPattern(s.fill.pattern.style[r.seriesNumber],s.fill.pattern.width,s.fill.pattern.height,l,n,i):a:t=o.drawPattern(s.fill.pattern.style,s.fill.pattern.width,s.fill.pattern.height,l,n,i);return t}},{key:"handleGradientFill",value:function(t,e,i){var a,s=this.w.config,r=this.opts,o=new b(this.ctx),n=new p,l=s.fill.gradient.type,h=t,c=void 0===s.fill.gradient.opacityFrom?e:Array.isArray(s.fill.gradient.opacityFrom)?s.fill.gradient.opacityFrom[i]:s.fill.gradient.opacityFrom;h.indexOf("rgba")>-1&&(c=p.getOpacityFromRGBA(h));var d=void 0===s.fill.gradient.opacityTo?e:Array.isArray(s.fill.gradient.opacityTo)?s.fill.gradient.opacityTo[i]:s.fill.gradient.opacityTo;if(void 0===s.fill.gradient.gradientToColors||0===s.fill.gradient.gradientToColors.length)a="dark"===s.fill.gradient.shade?n.shadeColor(-1*parseFloat(s.fill.gradient.shadeIntensity),t.indexOf("rgb")>-1?p.rgb2hex(t):t):n.shadeColor(parseFloat(s.fill.gradient.shadeIntensity),t.indexOf("rgb")>-1?p.rgb2hex(t):t);else if(s.fill.gradient.gradientToColors[r.seriesNumber]){var g=s.fill.gradient.gradientToColors[r.seriesNumber];a=g,g.indexOf("rgba")>-1&&(d=p.getOpacityFromRGBA(g))}else a=t;if(s.fill.gradient.inverseColors){var u=h;h=a,a=u}return h.indexOf("rgb")>-1&&(h=p.rgb2hex(h)),a.indexOf("rgb")>-1&&(a=p.rgb2hex(a)),o.drawGradient(l,h,a,c,d,r.size,s.fill.gradient.stops,s.fill.gradient.colorStops,i)}}]),t}(),P=function(){function t(e,i){a(this,t),this.ctx=e,this.w=e.w}return r(t,[{key:"setGlobalMarkerSize",value:function(){var t=this.w;if(t.globals.markers.size=Array.isArray(t.config.markers.size)?t.config.markers.size:[t.config.markers.size],t.globals.markers.size.length>0){if(t.globals.markers.size.length<t.globals.series.length+1)for(var e=0;e<=t.globals.series.length;e++)void 0===t.globals.markers.size[e]&&t.globals.markers.size.push(t.globals.markers.size[0])}else t.globals.markers.size=t.config.series.map((function(e){return t.config.markers.size}))}},{key:"plotChartMarkers",value:function(t,e,i,a){var s,r=arguments.length>4&&void 0!==arguments[4]&&arguments[4],o=this.w,n=e,l=t,h=null,c=new b(this.ctx);if((o.globals.markers.size[e]>0||r)&&(h=c.group({class:r?"":"apexcharts-series-markers"})).attr("clip-path","url(#gridRectMarkerMask".concat(o.globals.cuid,")")),Array.isArray(l.x))for(var d=0;d<l.x.length;d++){var g=i;1===i&&0===d&&(g=0),1===i&&1===d&&(g=1);var u="apexcharts-marker";"line"!==o.config.chart.type&&"area"!==o.config.chart.type||o.globals.comboCharts||o.config.tooltip.intersect||(u+=" no-pointer-events");var f=Array.isArray(o.config.markers.size)?o.globals.markers.size[e]>0:o.config.markers.size>0;if(f||r){p.isNumber(l.y[d])?u+=" w".concat(p.randomId()):u="apexcharts-nullpoint";var v=this.getMarkerConfig({cssClass:u,seriesIndex:e,dataPointIndex:g});o.config.series[n].data[g]&&(o.config.series[n].data[g].fillColor&&(v.pointFillColor=o.config.series[n].data[g].fillColor),o.config.series[n].data[g].strokeColor&&(v.pointStrokeColor=o.config.series[n].data[g].strokeColor)),a&&(v.pSize=a),(s=c.drawMarker(l.x[d],l.y[d],v)).attr("rel",g),s.attr("j",g),s.attr("index",e),s.node.setAttribute("default-marker-size",v.pSize);var m=new x(this.ctx);m.setSelectionFilter(s,e,g),this.addEvents(s),h&&h.add(s)}else void 0===o.globals.pointsArray[e]&&(o.globals.pointsArray[e]=[]),o.globals.pointsArray[e].push([l.x[d],l.y[d]])}return h}},{key:"getMarkerConfig",value:function(t){var e=t.cssClass,i=t.seriesIndex,a=t.dataPointIndex,s=void 0===a?null:a,r=t.finishRadius,o=void 0===r?null:r,n=this.w,l=this.getMarkerStyle(i),h=n.globals.markers.size[i],c=n.config.markers;return null!==s&&c.discrete.length&&c.discrete.map((function(t){t.seriesIndex===i&&t.dataPointIndex===s&&(l.pointStrokeColor=t.strokeColor,l.pointFillColor=t.fillColor,h=t.size,l.pointShape=t.shape)})),{pSize:null===o?h:o,pRadius:c.radius,width:Array.isArray(c.width)?c.width[i]:c.width,height:Array.isArray(c.height)?c.height[i]:c.height,pointStrokeWidth:Array.isArray(c.strokeWidth)?c.strokeWidth[i]:c.strokeWidth,pointStrokeColor:l.pointStrokeColor,pointFillColor:l.pointFillColor,shape:l.pointShape||(Array.isArray(c.shape)?c.shape[i]:c.shape),class:e,pointStrokeOpacity:Array.isArray(c.strokeOpacity)?c.strokeOpacity[i]:c.strokeOpacity,pointStrokeDashArray:Array.isArray(c.strokeDashArray)?c.strokeDashArray[i]:c.strokeDashArray,pointFillOpacity:Array.isArray(c.fillOpacity)?c.fillOpacity[i]:c.fillOpacity,seriesIndex:i}}},{key:"addEvents",value:function(t){var e=this.w,i=new b(this.ctx);t.node.addEventListener("mouseenter",i.pathMouseEnter.bind(this.ctx,t)),t.node.addEventListener("mouseleave",i.pathMouseLeave.bind(this.ctx,t)),t.node.addEventListener("mousedown",i.pathMouseDown.bind(this.ctx,t)),t.node.addEventListener("click",e.config.markers.onClick),t.node.addEventListener("dblclick",e.config.markers.onDblClick),t.node.addEventListener("touchstart",i.pathMouseDown.bind(this.ctx,t),{passive:!0})}},{key:"getMarkerStyle",value:function(t){var e=this.w,i=e.globals.markers.colors,a=e.config.markers.strokeColor||e.config.markers.strokeColors;return{pointStrokeColor:Array.isArray(a)?a[t]:a,pointFillColor:Array.isArray(i)?i[t]:i}}}]),t}(),T=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w,this.initialAnim=this.w.config.chart.animations.enabled,this.dynamicAnim=this.initialAnim&&this.w.config.chart.animations.dynamicAnimation.enabled}
61903return r(t,[{key:"draw",value:function(t,e,i){var a=this.w,s=new b(this.ctx),r=i.realIndex,o=i.pointsPos,n=i.zRatio,l=i.elParent,h=s.group({class:"apexcharts-series-markers apexcharts-series-".concat(a.config.chart.type)});if(h.attr("clip-path","url(#gridRectMarkerMask".concat(a.globals.cuid,")")),Array.isArray(o.x))for(var c=0;c<o.x.length;c++){var d=e+1,g=!0;0===e&&0===c&&(d=0),0===e&&1===c&&(d=1);var u=0,p=a.globals.markers.size[r];if(n!==1/0){p=a.globals.seriesZ[r][d]/n;var f=a.config.plotOptions.bubble;f.minBubbleRadius&&p<f.minBubbleRadius&&(p=f.minBubbleRadius),f.maxBubbleRadius&&p>f.maxBubbleRadius&&(p=f.maxBubbleRadius)}a.config.chart.animations.enabled||(u=p);var x=o.x[c],v=o.y[c];if(u=u||0,null!==v&&void 0!==a.globals.series[r][d]||(g=!1),g){var m=this.drawPoint(x,v,u,p,r,d,e);h.add(m)}l.add(h)}}},{key:"drawPoint",value:function(t,e,i,a,s,r,o){var n=this.w,l=s,h=new f(this.ctx),c=new x(this.ctx),d=new L(this.ctx),g=new P(this.ctx),u=new b(this.ctx),p=g.getMarkerConfig({cssClass:"apexcharts-marker",seriesIndex:l,dataPointIndex:r,finishRadius:"bubble"===n.config.chart.type||n.globals.comboCharts&&n.config.series[s]&&"bubble"===n.config.series[s].type?a:null});a=p.pSize;var v,m=d.fillPath({seriesNumber:s,dataPointIndex:r,color:p.pointFillColor,patternUnits:"objectBoundingBox",value:n.globals.series[s][o]});if("circle"===p.shape?v=u.drawCircle(i):"square"!==p.shape&&"rect"!==p.shape||(v=u.drawRect(0,0,p.width-p.pointStrokeWidth/2,p.height-p.pointStrokeWidth/2,p.pRadius)),n.config.series[l].data[r]&&n.config.series[l].data[r].fillColor&&(m=n.config.series[l].data[r].fillColor),v.attr({x:t-p.width/2-p.pointStrokeWidth/2,y:e-p.height/2-p.pointStrokeWidth/2,cx:t,cy:e,fill:m,"fill-opacity":p.pointFillOpacity,stroke:p.pointStrokeColor,r:a,"stroke-width":p.pointStrokeWidth,"stroke-dasharray":p.pointStrokeDashArray,"stroke-opacity":p.pointStrokeOpacity}),n.config.chart.dropShadow.enabled){var y=n.config.chart.dropShadow;c.dropShadow(v,y,s)}if(!this.initialAnim||n.globals.dataChanged||n.globals.resized)n.globals.animationEnded=!0;else{var w=n.config.chart.animations.speed;h.animateMarker(v,0,"circle"===p.shape?a:{width:p.width,height:p.height},w,n.globals.easing,(function(){window.setTimeout((function(){h.animationCompleted(v)}),100)}))}if(n.globals.dataChanged&&"circle"===p.shape)if(this.dynamicAnim){var k,A,S,C,T=n.config.chart.animations.dynamicAnimation.speed;null!=(C=n.globals.previousPaths[s]&&n.globals.previousPaths[s][o])&&(k=C.x,A=C.y,S=void 0!==C.r?C.r:a);for(var M=0;M<n.globals.collapsedSeries.length;M++)n.globals.collapsedSeries[M].index===s&&(T=1,a=0);0===t&&0===e&&(a=0),h.animateCircle(v,{cx:k,cy:A,r:S},{cx:t,cy:e,r:a},T,n.globals.easing)}else v.attr({r:a});return v.attr({rel:r,j:r,index:s,"default-marker-size":a}),c.setSelectionFilter(v,s,r),g.addEvents(v),v.node.classList.add("apexcharts-marker"),v}},{key:"centerTextInBubble",value:function(t){var e=this.w;return{y:t+=parseInt(e.config.dataLabels.style.fontSize,10)/4}}}]),t}(),M=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w}return r(t,[{key:"dataLabelsCorrection",value:function(t,e,i,a,s,r,o){var n=this.w,l=!1,h=new b(this.ctx).getTextRects(i,o),c=h.width,d=h.height;e<0&&(e=0),e>n.globals.gridHeight+d&&(e=n.globals.gridHeight+d/2),void 0===n.globals.dataLabelsRects[a]&&(n.globals.dataLabelsRects[a]=[]),n.globals.dataLabelsRects[a].push({x:t,y:e,width:c,height:d});var g=n.globals.dataLabelsRects[a].length-2,u=void 0!==n.globals.lastDrawnDataLabelsIndexes[a]?n.globals.lastDrawnDataLabelsIndexes[a][n.globals.lastDrawnDataLabelsIndexes[a].length-1]:0;if(void 0!==n.globals.dataLabelsRects[a][g]){var p=n.globals.dataLabelsRects[a][u];(t>p.x+p.width+2||e>p.y+p.height+2||t+c<p.x)&&(l=!0)}return(0===s||r)&&(l=!0),{x:t,y:e,textRects:h,drawnextLabel:l}}},{key:"drawDataLabel",value:function(t,e,i){var a=this,s=arguments.length>4&&void 0!==arguments[4]?arguments[4]:2,r=this.w,o=new b(this.ctx),n=r.config.dataLabels,l=0,h=0,c=i,d=null;if(!n.enabled||!Array.isArray(t.x))return d;d=o.group({class:"apexcharts-data-labels"});for(var g=0;g<t.x.length;g++)if(l=t.x[g]+n.offsetX,h=t.y[g]+n.offsetY+s,!isNaN(l)){1===i&&0===g&&(c=0),1===i&&1===g&&(c=1);var u=r.globals.series[e][c],p="",f=function(t){return r.config.dataLabels.formatter(t,{ctx:a.ctx,seriesIndex:e,dataPointIndex:c,w:r})};if("bubble"===r.config.chart.type){p=f(u=r.globals.seriesZ[e][c]),h=t.y[g];var x=new T(this.ctx),v=x.centerTextInBubble(h,e,c);
61903h=v.y}else void 0!==u&&(p=f(u));this.plotDataLabelsText({x:l,y:h,text:p,i:e,j:c,parent:d,offsetCorrection:!0,dataLabelsConfig:r.config.dataLabels})}return d}},{key:"plotDataLabelsText",value:function(t){var e=this.w,i=new b(this.ctx),a=t.x,s=t.y,r=t.i,o=t.j,n=t.text,l=t.textAnchor,h=t.fontSize,c=t.parent,d=t.dataLabelsConfig,g=t.color,u=t.alwaysDrawDataLabel,p=t.offsetCorrection;if(!(Array.isArray(e.config.dataLabels.enabledOnSeries)&&e.config.dataLabels.enabledOnSeries.indexOf(r)<0)){var f={x:a,y:s,drawnextLabel:!0,textRects:null};p&&(f=this.dataLabelsCorrection(a,s,n,r,o,u,parseInt(d.style.fontSize,10))),e.globals.zoomed||(a=f.x,s=f.y),f.textRects&&(a<-10-f.textRects.width||a>e.globals.gridWidth+f.textRects.width+10)&&(n="");var v=e.globals.dataLabels.style.colors[r];(("bar"===e.config.chart.type||"rangeBar"===e.config.chart.type)&&e.config.plotOptions.bar.distributed||e.config.dataLabels.distributed)&&(v=e.globals.dataLabels.style.colors[o]),"function"==typeof v&&(v=v({series:e.globals.series,seriesIndex:r,dataPointIndex:o,w:e})),g&&(v=g);var m=d.offsetX,y=d.offsetY;if("bar"!==e.config.chart.type&&"rangeBar"!==e.config.chart.type||(m=0,y=0),f.drawnextLabel){var w=i.drawText({width:100,height:parseInt(d.style.fontSize,10),x:a+m,y:s+y,foreColor:v,textAnchor:l||d.textAnchor,text:n,fontSize:h||d.style.fontSize,fontFamily:d.style.fontFamily,fontWeight:d.style.fontWeight||"normal"});if(w.attr({class:"apexcharts-datalabel",cx:a,cy:s}),d.dropShadow.enabled){var k=d.dropShadow;new x(this.ctx).dropShadow(w,k)}c.add(w),void 0===e.globals.lastDrawnDataLabelsIndexes[r]&&(e.globals.lastDrawnDataLabelsIndexes[r]=[]),e.globals.lastDrawnDataLabelsIndexes[r].push(o)}}}},{key:"addBackgroundToDataLabel",value:function(t,e){var i=this.w,a=i.config.dataLabels.background,s=a.padding,r=a.padding/2,o=e.width,n=e.height,l=new b(this.ctx).drawRect(e.x-s,e.y-r/2,o+2*s,n+r,a.borderRadius,"transparent"===i.config.chart.background?"#fff":i.config.chart.background,a.opacity,a.borderWidth,a.borderColor);a.dropShadow.enabled&&new x(this.ctx).dropShadow(l,a.dropShadow);return l}},{key:"dataLabelsBackground",value:function(){var t=this.w;if("bubble"!==t.config.chart.type)for(var e=t.globals.dom.baseEl.querySelectorAll(".apexcharts-datalabels text"),i=0;i<e.length;i++){var a=e[i],s=a.getBBox(),r=null;if(s.width&&s.height&&(r=this.addBackgroundToDataLabel(a,s)),r){a.parentNode.insertBefore(r.node,a);var o=a.getAttribute("fill");t.config.chart.animations.enabled&&!t.globals.resized&&!t.globals.dataChanged?r.animate().attr({fill:o}):r.attr({fill:o}),a.setAttribute("fill",t.config.dataLabels.background.foreColor)}}}},{key:"bringForward",value:function(){for(var t=this.w,e=t.globals.dom.baseEl.querySelectorAll(".apexcharts-datalabels"),i=t.globals.dom.baseEl.querySelector(".apexcharts-plot-series:last-child"),a=0;a<e.length;a++)i&&i.insertBefore(e[a],i.nextSibling)}}]),t}(),I=function(){function t(e){a(this,t),this.w=e.w,this.barCtx=e}return r(t,[{key:"handleBarDataLabels",value:function(t){var e=t.x,i=t.y,a=t.y1,s=t.y2,r=t.i,o=t.j,n=t.realIndex,l=t.series,h=t.barHeight,c=t.barWidth,d=t.barYPosition,g=t.visibleSeries,u=t.renderedPath,p=this.w,f=new b(this.barCtx.ctx),x=Array.isArray(this.barCtx.strokeWidth)?this.barCtx.strokeWidth[n]:this.barCtx.strokeWidth,v=e+parseFloat(c*g),m=i+parseFloat(h*g);p.globals.isXNumeric&&!p.globals.isBarHorizontal&&(v=e+parseFloat(c*(g+1)),m=i+parseFloat(h*(g+1))-x);var y=e,w=i,k={},A=p.config.dataLabels,S=this.barCtx.barOptions.dataLabels;void 0!==d&&this.barCtx.isRangeBar&&(m=d,w=d);var C=A.offsetX,L=A.offsetY,P={width:0,height:0};if(p.config.dataLabels.enabled){var T=this.barCtx.series[r][o];P=f.getTextRects(p.globals.yLabelFormatters[0](T),parseFloat(A.style.fontSize))}var M={x:e,y:i,i:r,j:o,renderedPath:u,bcx:v,bcy:m,barHeight:h,barWidth:c,textRects:P,strokeWidth:x,dataLabelsX:y,dataLabelsY:w,barDataLabelsConfig:S,offX:C,offY:L};return k=this.barCtx.isHorizontal?this.calculateBarsDataLabelsPosition(M):this.calculateColumnsDataLabelsPosition(M),u.attr({cy:k.bcy,cx:k.bcx,j:o,val:l[r][o],barHeight:h,barWidth:c}),this.drawCalculatedDataLabels({x:k.dataLabelsX,y:k.dataLabelsY,val:this.barCtx.isRangeBar?[a,s]:l[r][o],i:n,j:o,barWidth:c,barHeight:h,textRects:P,dataLabelsConfig:A})}},{key:"calculateColumnsDataLabelsPosition",value:function(t){var e,i=this.w,a=t.i,s=t.j,r=t.y,o=t.bcx,n=t.barWidth,l=t.barHeight,h=t.textRects,c=t.dataLabelsY,d=t.barDataLabelsConfig,g=t.strokeWidth,u=t.offX,p=t.offY;l=Math.abs(l);var f="vertical"===i.config.plotOptions.bar.dataLabels.orientation;o-=g/2;var x=i.globals.gridWidth/i.globals.dataPoints;if(e=i.globals.isXNumeric?o-n/2+u:o-x+n/2+u,f){e=e+h.height/2-g/2-2}var b=this.barCtx.series[a][s]<0,v=r;switch(this.barCtx.isReversed&&(v=r-l+(b?2*l:0),r-=l),d.position){case"center":c=f?b?v+l/2+p:v+l/2-p:b?v-l/2+h.height/2+p:v+l/2+h.height/2-p;break;case"bottom":c=f?b?v+l+p:v+l-p:b?v-l+h.height+g+p:v+l-h.height/2+g-p;break;case"top":c=f?b?v+p:v-p:b?v-h.height/2-p:v+h.height+p}return i.config.chart.stacked||(c<0?c=0+g:c+h.height/3>i.globals.gridHeight&&(c=i.globals.gridHeight-g)),{bcx:o,bcy:r,dataLabelsX:e,dataLabelsY:c}}},{key:"calculateBarsDataLabelsPosition",value:function(t){var e=this.w,i=t.x,a=t.i,s=t.j,r=t.bcy,o=t.barHeight,n=t.barWidth,l=t.textRects,h=t.dataLabelsX,c=t.strokeWidth,d=t.barDataLabelsConfig,g=t.offX,u=t.offY,p=e.globals.gridHeight/e.globals.dataPoints;n=Math.abs(n);var f=r-(this.barCtx.isRangeBar?0:p)+o/2+l.height/2+u-3,x=this.barCtx.series[a][s]<0,b=i;switch(this.barCtx.isReversed&&(b=i+n-(x?2*n:0),i=e.globals.gridWidth-n),d.position){case"center":h=x?b+n/2-g:Math.max(l.width/2,b-n/2)+g;break;case"bottom":h=x?b+n-c-Math.round(l.width/2)-g:b-n+c+Math.round(l.width/2)+g;break;case"top":h=x?b-c+Math.round(l.width/2)-g:b-c-Math.round(l.width/2)+g}return e.config.chart.stacked||(h<0?h=h+l.width+c:h+l.width/2>e.globals.gridWidth&&(h=e.globals.gridWidth-l.width-c)),{bcx:i,bcy:r,dataLabelsX:h,dataLabelsY:f}}},{key:"drawCalculatedDataLabels",value:function(t){var i=t.x,a=t.y,s=t.val,r=t.i,o=t.j,n=t.textRects,l=t.barHeight,h=t.barWidth,c=t.dataLabelsConfig,d=this.w,g="rotate(0)";"vertical"===d.config.plotOptions.bar.dataLabels.orientation&&(g="rotate(-90, ".concat(i,", ").concat(a,")"));var u=new M(this.barCtx.ctx),p=new b(this.barCtx.ctx),f=c.formatter,x=null,v=d.globals.collapsedSeriesIndices.indexOf(r)>-1;if(c.enabled&&!v){x=p.group({class:"apexcharts-data-labels",transform:g});var m="";void 0!==s&&(m=f(s,{seriesIndex:r,dataPointIndex:o,w:d}));var y=d.globals.series[r][o]<0,w=d.config.plotOptions.bar.dataLabels.position;if("vertical"===d.config.plotOptions.bar.dataLabels.orientation&&("top"===w&&(c.textAnchor=y?"end":"start"),"center"===w&&(c.textAnchor="middle"),"bottom"===w&&(c.textAnchor=y?"end":"start")),this.barCtx.isRangeBar&&this.barCtx.barOptions.dataLabels.hideOverflowingLabels)h<p.getTextRects(m,parseFloat(c.style.fontSize)).width&&(m="");d.config.chart.stacked&&this.barCtx.barOptions.dataLabels.hideOverflowingLabels&&(this.barCtx.isHorizontal?n.width/1.6>Math.abs(h)&&(m=""):n.height/1.6>Math.abs(l)&&(m=""));var k=e({},c);this.barCtx.isHorizontal&&s<0&&("start"===c.textAnchor?k.textAnchor="end":"end"===c.textAnchor&&(k.textAnchor="start")),u.plotDataLabelsText({x:i,y:a,text:m,i:r,j:o,parent:x,dataLabelsConfig:k,alwaysDrawDataLabel:!0,offsetCorrection:!0}
61903)}return x}}]),t}(),z=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w,this.legendInactiveClass="legend-mouseover-inactive"}return r(t,[{key:"getAllSeriesEls",value:function(){return this.w.globals.dom.baseEl.getElementsByClassName("apexcharts-series")}},{key:"getSeriesByName",value:function(t){return this.w.globals.dom.baseEl.querySelector(".apexcharts-inner .apexcharts-series[seriesName='".concat(p.escapeString(t),"']"))}},{key:"isSeriesHidden",value:function(t){var e=this.getSeriesByName(t),i=parseInt(e.getAttribute("data:realIndex"),10);return{isHidden:e.classList.contains("apexcharts-series-collapsed"),realIndex:i}}},{key:"addCollapsedClassToSeries",value:function(t,e){var i=this.w;function a(i){for(var a=0;a<i.length;a++)i[a].index===e&&t.node.classList.add("apexcharts-series-collapsed")}a(i.globals.collapsedSeries),a(i.globals.ancillaryCollapsedSeries)}},{key:"toggleSeries",value:function(t){var e=this.isSeriesHidden(t);return this.ctx.legend.legendHelpers.toggleDataSeries(e.realIndex,e.isHidden),e.isHidden}},{key:"showSeries",value:function(t){var e=this.isSeriesHidden(t);e.isHidden&&this.ctx.legend.legendHelpers.toggleDataSeries(e.realIndex,!0)}},{key:"hideSeries",value:function(t){var e=this.isSeriesHidden(t);e.isHidden||this.ctx.legend.legendHelpers.toggleDataSeries(e.realIndex,!1)}},{key:"resetSeries",value:function(){var t=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],i=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],a=this.w,s=p.clone(a.globals.initialSeries);a.globals.previousPaths=[],i?(a.globals.collapsedSeries=[],a.globals.ancillaryCollapsedSeries=[],a.globals.collapsedSeriesIndices=[],a.globals.ancillaryCollapsedSeriesIndices=[]):s=this.emptyCollapsedSeries(s),a.config.series=s,t&&(e&&(a.globals.zoomed=!1,this.ctx.updateHelpers.revertDefaultAxisMinMax()),this.ctx.updateHelpers._updateSeries(s,a.config.chart.animations.dynamicAnimation.enabled))}},{key:"emptyCollapsedSeries",value:function(t){for(var e=this.w,i=0;i<t.length;i++)e.globals.collapsedSeriesIndices.indexOf(i)>-1&&(t[i].data=[]);return t}},{key:"toggleSeriesOnHover",value:function(t,e){var i=this.w;e||(e=t.target);var a=i.globals.dom.baseEl.querySelectorAll(".apexcharts-series, .apexcharts-datalabels");if("mousemove"===t.type){var s=parseInt(e.getAttribute("rel"),10)-1,r=null,o=null;i.globals.axisCharts||"radialBar"===i.config.chart.type?i.globals.axisCharts?(r=i.globals.dom.baseEl.querySelector(".apexcharts-series[data\\:realIndex='".concat(s,"']")),o=i.globals.dom.baseEl.querySelector(".apexcharts-datalabels[data\\:realIndex='".concat(s,"']"))):r=i.globals.dom.baseEl.querySelector(".apexcharts-series[rel='".concat(s+1,"']")):r=i.globals.dom.baseEl.querySelector(".apexcharts-series[rel='".concat(s+1,"'] path"));for(var n=0;n<a.length;n++)a[n].classList.add(this.legendInactiveClass);null!==r&&(i.globals.axisCharts||r.parentNode.classList.remove(this.legendInactiveClass),r.classList.remove(this.legendInactiveClass),null!==o&&o.classList.remove(this.legendInactiveClass))}else if("mouseout"===t.type)for(var l=0;l<a.length;l++)a[l].classList.remove(this.legendInactiveClass)}},{key:"highlightRangeInSeries",value:function(t,e){var i=this,a=this.w,s=a.globals.dom.baseEl.getElementsByClassName("apexcharts-heatmap-rect"),r=function(t){for(var e=0;e<s.length;e++)s[e].classList[t](i.legendInactiveClass)};if("mousemove"===t.type){var o=parseInt(e.getAttribute("rel"),10)-1;r("add"),function(t){for(var e=0;e<s.length;e++){var a=parseInt(s[e].getAttribute("val"),10);a>=t.from&&a<=t.to&&s[e].classList.remove(i.legendInactiveClass)}}(a.config.plotOptions.heatmap.colorScale.ranges[o])}else"mouseout"===t.type&&r("remove")}},{key:"getActiveConfigSeriesIndex",value:function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0],e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"asc",i=this.w,a=0;if(i.config.series.length>1)for(var s=i.config.series.map((function(e,a){var s=!1;return t&&(s="bar"===i.config.series[a].type||"column"===i.config.series[a].type),e.data&&e.data.length>0&&!s?a:-1})),r="asc"===e?0:s.length-1;"asc"===e?r<s.length:r>=0;"asc"===e?r++:r--)if(-1!==s[r]){a=s[r];break}return a}},{key:"getPreviousPaths",value:function(){var t=this.w;function e(e,i,a){for(var s=e[i].childNodes,r={type:a,paths:[],realIndex:e[
61903i].getAttribute("data:realIndex")},o=0;o<s.length;o++)if(s[o].hasAttribute("pathTo")){var n=s[o].getAttribute("pathTo");r.paths.push({d:n})}t.globals.previousPaths.push(r)}t.globals.previousPaths=[];["line","area","bar","rangebar","candlestick","radar"].forEach((function(i){for(var a,s=(a=i,t.globals.dom.baseEl.querySelectorAll(".apexcharts-".concat(a,"-series .apexcharts-series"))),r=0;r<s.length;r++)e(s,r,i)})),this.handlePrevBubbleScatterPaths("bubble"),this.handlePrevBubbleScatterPaths("scatter");var i=t.globals.dom.baseEl.querySelectorAll(".apexcharts-".concat(t.config.chart.type," .apexcharts-series"));if(i.length>0)for(var a=function(e){for(var i=t.globals.dom.baseEl.querySelectorAll(".apexcharts-".concat(t.config.chart.type," .apexcharts-series[data\\:realIndex='").concat(e,"'] rect")),a=[],s=function(t){var e=function(e){return i[t].getAttribute(e)},s={x:parseFloat(e("x")),y:parseFloat(e("y")),width:parseFloat(e("width")),height:parseFloat(e("height"))};a.push({rect:s,color:i[t].getAttribute("color")})},r=0;r<i.length;r++)s(r);t.globals.previousPaths.push(a)},s=0;s<i.length;s++)a(s);t.globals.axisCharts||(t.globals.previousPaths=t.globals.series)}},{key:"handlePrevBubbleScatterPaths",value:function(t){var e=this.w,i=e.globals.dom.baseEl.querySelectorAll(".apexcharts-".concat(t,"-series .apexcharts-series"));if(i.length>0)for(var a=0;a<i.length;a++){for(var s=e.globals.dom.baseEl.querySelectorAll(".apexcharts-".concat(t,"-series .apexcharts-series[data\\:realIndex='").concat(a,"'] circle")),r=[],o=0;o<s.length;o++)r.push({x:s[o].getAttribute("cx"),y:s[o].getAttribute("cy"),r:s[o].getAttribute("r")});e.globals.previousPaths.push(r)}}},{key:"clearPreviousPaths",value:function(){var t=this.w;t.globals.previousPaths=[],t.globals.allSeriesCollapsed=!1}},{key:"handleNoData",value:function(){var t=this.w,e=t.config.noData,i=new b(this.ctx),a=t.globals.svgWidth/2,s=t.globals.svgHeight/2,r="middle";if(t.globals.noData=!0,t.globals.animationEnded=!0,"left"===e.align?(a=10,r="start"):"right"===e.align&&(a=t.globals.svgWidth-10,r="end"),"top"===e.verticalAlign?s=50:"bottom"===e.verticalAlign&&(s=t.globals.svgHeight-50),a+=e.offsetX,s=s+parseInt(e.style.fontSize,10)+2+e.offsetY,void 0!==e.text&&""!==e.text){var o=i.drawText({x:a,y:s,text:e.text,textAnchor:r,fontSize:e.style.fontSize,fontFamily:e.style.fontFamily,foreColor:e.style.color,opacity:1,class:"apexcharts-text-nodata"});t.globals.dom.Paper.add(o)}}},{key:"setNullSeriesToZeroValues",value:function(t){for(var e=this.w,i=0;i<t.length;i++)if(0===t[i].length)for(var a=0;a<t[e.globals.maxValsInArrayIndex].length;a++)t[i].push(0);return t}},{key:"hasAllSeriesEqualX",value:function(){for(var t=!0,e=this.w,i=this.filteredSeriesX(),a=0;a<i.length-1;a++)if(i[a][0]!==i[a+1][0]){t=!1;break}return e.globals.allSeriesHasEqualX=t,t}},{key:"filteredSeriesX",value:function(){var t=this.w.globals.seriesX.map((function(t){return t.length>0?t:[]}));return t}}]),t}(),X=function(){function t(e){a(this,t),this.w=e.w,this.barCtx=e}return r(t,[{key:"initVariables",value:function(t){var e=this.w;this.barCtx.series=t,this.barCtx.totalItems=0,this.barCtx.seriesLen=0,this.barCtx.visibleI=-1,this.barCtx.visibleItems=1;for(var i=0;i<t.length;i++)if(t[i].length>0&&(this.barCtx.seriesLen=this.barCtx.seriesLen+1,this.barCtx.totalItems+=t[i].length),e.globals.isXNumeric)for(var a=0;a<t[i].length;a++)e.globals.seriesX[i][a]>e.globals.minX&&e.globals.seriesX[i][a]<e.globals.maxX&&this.barCtx.visibleItems++;else this.barCtx.visibleItems=e.globals.dataPoints;0===this.barCtx.seriesLen&&(this.barCtx.seriesLen=1),this.barCtx.zeroSerieses=[],this.barCtx.radiusOnSeriesNumber=t.length-1,e.globals.comboCharts||this.checkZeroSeries({series:t})}},{key:"initialPositions",value:function(){var t,e,i,a,s,r,o,n,l=this.w,h=l.globals.dataPoints;this.barCtx.isRangeBar&&(h=l.globals.labels.length);var c=this.barCtx.seriesLen;if(l.config.plotOptions.bar.rangeBarGroupRows&&(c=1),this.barCtx.isHorizontal)s=(i=l.globals.gridHeight/h)/c,l.globals.isXNumeric&&(s=(i=l.globals.gridHeight/this.barCtx.totalItems)/this.barCtx.seriesLen),s=s*parseInt(this.barCtx.barOptions.barHeight,10)/100,n=this.barCtx.baseLineInvertedY+l.globals.padHorizontal+(this.barCtx.isReversed?l.globals.gridWidth:0)-(this.barCtx.isReversed?2*this.barCtx.baseLineInvertedY:0),e=(i-s*this.barCtx.seriesLen)/2;else{if(a=l.globals.gridWidth/this.barCtx.visibleItems,l.config.xaxis.convertedCatToNumeric&&(a=l.globals.gridWidth/l.globals.dataPoints),r=a/this.barCtx.seriesLen*parseInt(this.barCtx.barOptions.columnWidth,10)/100,l.globals.isXNumeric){var d=this.barCtx.xRatio;l.config.xaxis.convertedCatToNumeric&&(d=this.barCtx.initialXRatio),l.globals.minXDiff&&.5!==l.globals.minXDiff&&l.globals.minXDiff/d>0&&(a=l.globals.minXDiff/d),(r=a/this.barCtx.seriesLen*parseInt(this.barCtx.barOptions.columnWidth,10)/100)<1&&(r=1)}o=l.globals.gridHeight-this.barCtx.baseLineY[this.barCtx.yaxisIndex]-(this.barCtx.isReversed?l.globals.gridHeight:0)+(this.barCtx.isReversed?2*this.barCtx.baseLineY[this.barCtx.yaxisIndex]:0),t=l.globals.padHorizontal+(a-r*this.barCtx.seriesLen)/2}return{x:t,y:e,yDivision:i,xDivision:a,barHeight:s,barWidth:r,zeroH:o,zeroW:n}}}
61903,{key:"getPathFillColor",value:function(t,e,i,a){var s=this.w,r=new L(this.barCtx.ctx),o=null,n=this.barCtx.barOptions.distributed?i:e;this.barCtx.barOptions.colors.ranges.length>0&&this.barCtx.barOptions.colors.ranges.map((function(a){t[e][i]>=a.from&&t[e][i]<=a.to&&(o=a.color)}));return s.config.series[e].data[i]&&s.config.series[e].data[i].fillColor&&(o=s.config.series[e].data[i].fillColor),r.fillPath({seriesNumber:this.barCtx.barOptions.distributed?n:a,dataPointIndex:i,color:o,value:t[e][i]})}},{key:"getStrokeWidth",value:function(t,e,i){var a=0,s=this.w;return void 0===this.barCtx.series[t][e]||null===this.barCtx.series[t][e]?this.barCtx.isNullValue=!0:this.barCtx.isNullValue=!1,s.config.stroke.show&&(this.barCtx.isNullValue||(a=Array.isArray(this.barCtx.strokeWidth)?this.barCtx.strokeWidth[i]:this.barCtx.strokeWidth)),a}},{key:"barBackground",value:function(t){var e=t.j,i=t.i,a=t.x1,s=t.x2,r=t.y1,o=t.y2,n=t.elSeries,l=this.w,h=new b(this.barCtx.ctx),c=new z(this.barCtx.ctx).getActiveConfigSeriesIndex();if(this.barCtx.barOptions.colors.backgroundBarColors.length>0&&c===i){e>=this.barCtx.barOptions.colors.backgroundBarColors.length&&(e-=this.barCtx.barOptions.colors.backgroundBarColors.length);var d=this.barCtx.barOptions.colors.backgroundBarColors[e],g=h.drawRect(void 0!==a?a:0,void 0!==r?r:0,void 0!==s?s:l.globals.gridWidth,void 0!==o?o:l.globals.gridHeight,this.barCtx.barOptions.colors.backgroundBarRadius,d,this.barCtx.barOptions.colors.backgroundBarOpacity);n.add(g),g.node.classList.add("apexcharts-backgroundBar")}}},{key:"getColumnPaths",value:function(t){var e=t.barWidth,i=t.barXPosition,a=t.yRatio,s=t.y1,r=t.y2,o=t.strokeWidth,n=t.series,l=t.realIndex,h=t.i,c=t.j,d=t.w,g=new b(this.barCtx.ctx);(o=Array.isArray(o)?o[l]:o)||(o=0);var u={barWidth:e,strokeWidth:o,yRatio:a,barXPosition:i,y1:s,y2:r},p=this.getRoundedBars(d,u,n,h,c),f=i,x=i+e,v=g.move(f,s),m=g.move(f,s),y=g.line(x-o,s);return d.globals.previousPaths.length>0&&(m=this.barCtx.getPreviousPath(l,c,!1)),v=v+g.line(f,p.y2)+p.pathWithRadius+g.line(x-o,p.y2)+y+y+"z",m=m+g.line(f,s)+y+y+y+y+y+g.line(f,s),d.config.chart.stacked&&(this.barCtx.yArrj.push(p.y2),this.barCtx.yArrjF.push(Math.abs(s-p.y2)),this.barCtx.yArrjVal.push(this.barCtx.series[h][c])),{pathTo:v,pathFrom:m}}},{key:"getBarpaths",value:function(t){var e=t.barYPosition,i=t.barHeight,a=t.x1,s=t.x2,r=t.strokeWidth,o=t.series,n=t.realIndex,l=t.i,h=t.j,c=t.w,d=new b(this.barCtx.ctx);(r=Array.isArray(r)?r[n]:r)||(r=0);var g={barHeight:i,strokeWidth:r,barYPosition:e,x2:s,x1:a},u=this.getRoundedBars(c,g,o,l,h),p=d.move(a,e),f=d.move(a,e);c.globals.previousPaths.length>0&&(f=this.barCtx.getPreviousPath(n,h,!1));var x=e,v=e+i,m=d.line(a,v-r);return p=p+d.line(u.x2,x)+u.pathWithRadius+d.line(u.x2,v-r)+m+m+"z",f=f+d.line(a,x)+m+m+m+m+m+d.line(a,x),c.config.chart.stacked&&(this.barCtx.xArrj.push(u.x2),this.barCtx.xArrjF.push(Math.abs(a-u.x2)),this.barCtx.xArrjVal.push(this.barCtx.series[l][h])),{pathTo:p,pathFrom:f}}},{key:"getRoundedBars",value:function(t,e,i,a,s){var r=new b(this.barCtx.ctx),o=0,n=t.config.plotOptions.bar.borderRadius,l=Array.isArray(n);l?o=n[a>n.length-1?n.length-1:a]:o=n;if(t.config.chart.stacked&&i.length>1&&a!==this.barCtx.radiusOnSeriesNumber&&!l&&(o=0),this.barCtx.isHorizontal){var h="",c=e.x2;if(Math.abs(e.x1-e.x2)<o&&(o=Math.abs(e.x1-e.x2)),void 0!==i[a][s]||null!==i[a][s]){var d=this.barCtx.isReversed?i[a][s]>0:i[a][s]<0;d&&(o*=-1),c-=o,h=r.quadraticCurve(c+o,e.barYPosition,c+o,e.barYPosition+(d?-1*o:o))+r.line(c+o,e.barYPosition+e.barHeight-e.strokeWidth-(d?-1*o:o))+r.quadraticCurve(c+o,e.barYPosition+e.barHeight-e.strokeWidth,c,e.barYPosition+e.barHeight-e.strokeWidth)}return{pathWithRadius:h,x2:c}}var g="",u=e.y2;if(Math.abs(e.y1-e.y2)<o&&(o=Math.abs(e.y1-e.y2)),void 0!==i[a][s]||null!==i[a][s]){var p=i[a][s]<0;p&&(o*=-1),u+=o,g=r.quadraticCurve(e.barXPosition,u-o,e.barXPosition+(p?-1*o:o),u-o)+r.line(e.barXPosition+e.barWidth-e.strokeWidth-(p?-1*o:o),u-o)+r.quadraticCurve(e.barXPosition+e.barWidth-e.strokeWidth,u-o,e.barXPosition+e.barWidth-e.strokeWidth,u)}return{pathWithRadius:g,y2:u}}},{key:"checkZeroSeries",value:function(t){for(var e=t.series,i=this.w,a=0;a<e.length;a++){for(var s=0,r=0;r<e[i.globals.maxValsInArrayIndex].length;r++)s+=e[a][r];0===s&&this.barCtx.zeroSerieses.push(a)}for(var o=e.length-1;o>=0;o--)this.barCtx.zeroSerieses.indexOf(o)>-1&&o===this.radiusOnSeriesNumber&&(this.barCtx.radiusOnSeriesNumber-=1);for(var n=e.length-1;n>=0;n--)i.globals.collapsedSeriesIndices.indexOf(this.barCtx.radiusOnSeriesNumber)>-1&&(this.barCtx.radiusOnSeriesNumber-=1)}},{key:"getXForValue",value:function(t,e){var i=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],a=i?e:null;return null!=t&&(a=e+t/this.barCtx.invertedYRatio-2*(this.barCtx.isReversed?t/this.barCtx.invertedYRatio:0)),a}},{key:"getYForValue",value:function(t,e){var i=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],a=i?e:null;return null!=t&&(a=e-t/this.barCtx.yRatio[this.barCtx.yaxisIndex]+2*(this.barCtx.isReversed?t/this.barCtx.yRatio[this.barCtx.yaxisIndex]:0)),a}}
61903,{key:"getGoalValues",value:function(t,e,i,a,s){var r=this,n=this.w,l=[];return n.globals.seriesGoals[a]&&n.globals.seriesGoals[a][s]&&Array.isArray(n.globals.seriesGoals[a][s])&&n.globals.seriesGoals[a][s].forEach((function(a){var s;l.push((o(s={},t,"x"===t?r.getXForValue(a.value,e,!1):r.getYForValue(a.value,i,!1)),o(s,"attrs",a),s))})),l}},{key:"drawGoalLine",value:function(t){var e=t.barXPosition,i=t.barYPosition,a=t.goalX,s=t.goalY,r=t.barWidth,o=t.barHeight,n=new b(this.barCtx.ctx),l=n.group({className:"apexcharts-bar-goals-groups"}),h=null;return this.barCtx.isHorizontal?Array.isArray(a)&&a.forEach((function(t){var e=void 0!==t.attrs.strokeHeight?t.attrs.strokeHeight:o/2,a=i+e+o/2;h=n.drawLine(t.x,a-2*e,t.x,a,t.attrs.strokeColor?t.attrs.strokeColor:void 0,t.attrs.strokeDashArray,t.attrs.strokeWidth?t.attrs.strokeWidth:2,t.attrs.strokeLineCap),l.add(h)})):Array.isArray(s)&&s.forEach((function(t){var i=void 0!==t.attrs.strokeWidth?t.attrs.strokeWidth:r/2,a=e+i+r/2;h=n.drawLine(a-2*i,t.y,a,t.y,t.attrs.strokeColor?t.attrs.strokeColor:void 0,t.attrs.strokeDashArray,t.attrs.strokeHeight?t.attrs.strokeHeight:2,t.attrs.strokeLineCap),l.add(h)})),l}}]),t}(),E=function(){function t(e,i){a(this,t),this.ctx=e,this.w=e.w;var s=this.w;this.barOptions=s.config.plotOptions.bar,this.isHorizontal=this.barOptions.horizontal,this.strokeWidth=s.config.stroke.width,this.isNullValue=!1,this.isRangeBar=s.globals.seriesRangeBar.length&&this.isHorizontal,this.xyRatios=i,null!==this.xyRatios&&(this.xRatio=i.xRatio,this.initialXRatio=i.initialXRatio,this.yRatio=i.yRatio,this.invertedXRatio=i.invertedXRatio,this.invertedYRatio=i.invertedYRatio,this.baseLineY=i.baseLineY,this.baseLineInvertedY=i.baseLineInvertedY),this.yaxisIndex=0,this.seriesLen=0,this.barHelpers=new X(this)}return r(t,[{key:"draw",value:function(t,i){var a=this.w,s=new b(this.ctx),r=new y(this.ctx,a);t=r.getLogSeries(t),this.series=t,this.yRatio=r.getLogYRatios(this.yRatio),this.barHelpers.initVariables(t);var o=s.group({class:"apexcharts-bar-series apexcharts-plot-series"});a.config.dataLabels.enabled&&this.totalItems>this.barOptions.dataLabels.maxItems&&console.warn("WARNING: DataLabels are enabled but there are too many to display. This may cause performance issue when rendering.");for(var n=0,l=0;n<t.length;n++,l++){var h,c,d,g,u=void 0,f=void 0,x=[],v=[],m=a.globals.comboCharts?i[n]:n,w=s.group({class:"apexcharts-series",rel:n+1,seriesName:p.escapeString(a.globals.seriesNames[m]),"data:realIndex":m});this.ctx.series.addCollapsedClassToSeries(w,m),t[n].length>0&&(this.visibleI=this.visibleI+1);var k=0,A=0;this.yRatio.length>1&&(this.yaxisIndex=m),this.isReversed=a.config.yaxis[this.yaxisIndex]&&a.config.yaxis[this.yaxisIndex].reversed;var S=this.barHelpers.initialPositions();f=S.y,k=S.barHeight,c=S.yDivision,g=S.zeroW,u=S.x,A=S.barWidth,h=S.xDivision,d=S.zeroH,this.horizontal||v.push(u+A/2);for(var C=s.group({class:"apexcharts-datalabels","data:realIndex":m}),L=s.group({class:"apexcharts-bar-goals-markers",style:"pointer-events: none"}),P=0;P<a.globals.dataPoints;P++){var T=this.barHelpers.getStrokeWidth(n,P,m),M=null,I={indexes:{i:n,j:P,realIndex:m,bc:l},x:u,y:f,strokeWidth:T,elSeries:w};this.isHorizontal?(M=this.drawBarPaths(e(e({},I),{},{barHeight:k,zeroW:g,yDivision:c})),A=this.series[n][P]/this.invertedYRatio):(M=this.drawColumnPaths(e(e({},I),{},{xDivision:h,barWidth:A,zeroH:d})),k=this.series[n][P]/this.yRatio[this.yaxisIndex]);var z=this.barHelpers.drawGoalLine({barXPosition:M.barXPosition,barYPosition:M.barYPosition,goalX:M.goalX,goalY:M.goalY,barHeight:k,barWidth:A});z&&L.add(z),f=M.y,u=M.x,P>0&&v.push(u+A/2),x.push(f);var X=this.barHelpers.getPathFillColor(t,n,P,m);this.renderSeries({realIndex:m,pathFill:X,j:P,i:n,pathFrom:M.pathFrom,pathTo:M.pathTo,strokeWidth:T,elSeries:w,x:u,y:f,series:t,barHeight:k,barWidth:A,elDataLabelsWrap:C,elGoalsMarkers:L,visibleSeries:this.visibleI,type:"bar"})}a.globals.seriesXvalues[m]=v,a.globals.seriesYvalues[m]=x,o.add(w)}return o}},{key:"renderSeries",value:function(t){var e=t.realIndex,i=t.pathFill,a=t.lineFill,s=t.j,r=t.i,o=t.pathFrom,n=t.pathTo,l=t.strokeWidth,h=t.elSeries,c=t.x,d=t.y,g=t.y1,u=t.y2,p=t.series,f=t.barHeight,v=t.barWidth,m=t.barYPosition,y=t.elDataLabelsWrap,w=t.elGoalsMarkers,k=t.visibleSeries,A=t.type,S=this.w,C=new b(this.ctx);a||(a=this.barOptions.distributed?S.globals.stroke.colors[s]:S.globals.stroke.colors[e]),S.config.series[r].data[s]&&S.config.series[r].data[s].strokeColor&&(a=S.config.series[r].data[s].strokeColor),this.isNullValue&&(i="none");var L=s/S.config.chart.animations.animateGradually.delay*(S.config.chart.animations.speed/S.globals.dataPoints)/2.4,P=C.renderPaths({i:r,j:s,realIndex:e,pathFrom:o,pathTo:n,stroke:a,strokeWidth:l,strokeLineCap:S.config.stroke.lineCap,fill:i,animationDelay:L,initialSpeed:S.config.chart.animations.speed,dataChangeSpeed:S.config.chart.animations.dynamicAnimation.speed,className:"apexcharts-".concat(A,"-area")});P.attr("clip-path","url(#gridRectMask".concat(S.globals.cuid,")"));var T=S.config.forecastDataPoints;T.count>0&&s>=S.globals.dataPoints-T.count&&(P.node.setAttribute("stroke-dasharray",T.dashArray),P.node.setAttribute("stroke-width",T.strokeWidth),P.node.setAttribute("fill-opacity",T.fillOpacity)),void 0!==g&&void 0!==u&&(P.attr("data-range-y1",g),P.attr("data-range-y2",u)),new x(this.ctx).setSelectionFilter(P,e,s),h.add(P);var M=new I(this).handleBarDataLabels({x:c,y:d,y1:g,y2:u,i:r,j:s,series:p,realIndex:e,barHeight:f,barWidth:v,barYPosition:m,renderedPath:P,visibleSeries:k});return null!==M&&y.add(M),h.add(y),w&&h.add(w),h}},{key:"drawBarPaths",value:function(t){var e=t.indexes,i=t.barHeight,a=t.strokeWidth,s=t.zeroW,r=t.x,o=t.y,n=t.yDivision,l=t.elSeries,h=this.w,c=e.i,d=e.j;h.globals.isXNumeric&&(o=(h.globals.seriesX[c][d]-h.globals.minX)/this.invertedXRatio-i);var g=o+i*this.visibleI;r=this.barHelpers.getXForValue(this.series[c][d],s);var u=this.barHelpers.getBarpaths({barYPosition:g,barHeight:i,x1:s,x2:r,strokeWidth:a,series:this.series,realIndex:e.realIndex,i:c,j:d,w:h});return h.globals.isXNumeric||(o+=n),this.barHelpers.barBackgroun
vendor: 20,991 bytes, line 61903
61903d({j:d,i:c,y1:g-i*this.visibleI,y2:i*this.seriesLen,elSeries:l}),{pathTo:u.pathTo,pathFrom:u.pathFrom,x:r,y:o,goalX:this.barHelpers.getGoalValues("x",s,null,c,d),barYPosition:g}}},{key:"drawColumnPaths",value:function(t){var e=t.indexes,i=t.x,a=t.y,s=t.xDivision,r=t.barWidth,o=t.zeroH,n=t.strokeWidth,l=t.elSeries,h=this.w,c=e.realIndex,d=e.i,g=e.j,u=e.bc;if(h.globals.isXNumeric){var p=c;h.globals.seriesX[c].length||(p=h.globals.maxValsInArrayIndex),i=(h.globals.seriesX[p][g]-h.globals.minX)/this.xRatio-r*this.seriesLen/2}var f=i+r*this.visibleI;a=this.barHelpers.getYForValue(this.series[d][g],o);var x=this.barHelpers.getColumnPaths({barXPosition:f,barWidth:r,y1:o,y2:a,strokeWidth:n,series:this.series,realIndex:e.realIndex,i:d,j:g,w:h});return h.globals.isXNumeric||(i+=s),this.barHelpers.barBackground({bc:u,j:g,i:d,x1:f-n/2-r*this.visibleI,x2:r*this.seriesLen+n/2,elSeries:l}),{pathTo:x.pathTo,pathFrom:x.pathFrom,x:i,y:a,goalY:this.barHelpers.getGoalValues("y",null,o,d,g),barXPosition:f}}},{key:"getPreviousPath",value:function(t,e){for(var i,a=this.w,s=0;s<a.globals.previousPaths.length;s++){var r=a.globals.previousPaths[s];r.paths&&r.paths.length>0&&parseInt(r.realIndex,10)===parseInt(t,10)&&void 0!==a.globals.previousPaths[s].paths[e]&&(i=a.globals.previousPaths[s].paths[e].d)}return i}}]),t}(),Y=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w,this.months31=[1,3,5,7,8,10,12],this.months30=[2,4,6,9,11],this.daysCntOfYear=[0,31,59,90,120,151,181,212,243,273,304,334]}return r(t,[{key:"isValidDate",value:function(t){return!isNaN(this.parseDate(t))}},{key:"getTimeStamp",value:function(t){return Date.parse(t)?this.w.config.xaxis.labels.datetimeUTC?new Date(new Date(t).toISOString().substr(0,25)).getTime():new Date(t).getTime():t}},{key:"getDate",value:function(t){return this.w.config.xaxis.labels.datetimeUTC?new Date(new Date(t).toUTCString()):new Date(t)}},{key:"parseDate",value:function(t){var e=Date.parse(t);if(!isNaN(e))return this.getTimeStamp(t);var i=Date.parse(t.replace(/-/g,"/").replace(/[a-z]+/gi," "));return i=this.getTimeStamp(i)}},{key:"parseDateWithTimezone",value:function(t){return Date.parse(t.replace(/-/g,"/").replace(/[a-z]+/gi," "))}},{key:"formatDate",value:function(t,e){var i=this.w.globals.locale,a=this.w.config.xaxis.labels.datetimeUTC,s=["\0"].concat(g(i.months)),r=["\x01"].concat(g(i.shortMonths)),o=["\x02"].concat(g(i.days)),n=["\x03"].concat(g(i.shortDays));function l(t,e){var i=t+"";for(e=e||2;i.length<e;)i="0"+i;return i}var h=a?t.getUTCFullYear():t.getFullYear();e=(e=(e=e.replace(/(^|[^\\])yyyy+/g,"$1"+h)).replace(/(^|[^\\])yy/g,"$1"+h.toString().substr(2,2))).replace(/(^|[^\\])y/g,"$1"+h);var c=(a?t.getUTCMonth():t.getMonth())+1;e=(e=(e=(e=e.replace(/(^|[^\\])MMMM+/g,"$1"+s[0])).replace(/(^|[^\\])MMM/g,"$1"+r[0])).replace(/(^|[^\\])MM/g,"$1"+l(c))).replace(/(^|[^\\])M/g,"$1"+c);var d=a?t.getUTCDate():t.getDate();e=(e=(e=(e=e.replace(/(^|[^\\])dddd+/g,"$1"+o[0])).replace(/(^|[^\\])ddd/g,"$1"+n[0])).replace(/(^|[^\\])dd/g,"$1"+l(d))).replace(/(^|[^\\])d/g,"$1"+d);var u=a?t.getUTCHours():t.getHours(),p=u>12?u-12:0===u?12:u;e=(e=(e=(e=e.replace(/(^|[^\\])HH+/g,"$1"+l(u))).replace(/(^|[^\\])H/g,"$1"+u)).replace(/(^|[^\\])hh+/g,"$1"+l(p))).replace(/(^|[^\\])h/g,"$1"+p);var f=a?t.getUTCMinutes():t.getMinutes();e=(e=e.replace(/(^|[^\\])mm+/g,"$1"+l(f))).replace(/(^|[^\\])m/g,"$1"+f);var x=a?t.getUTCSeconds():t.getSeconds();e=(e=e.replace(/(^|[^\\])ss+/g,"$1"+l(x))).replace(/(^|[^\\])s/g,"$1"+x);var b=a?t.getUTCMilliseconds():t.getMilliseconds();e=e.replace(/(^|[^\\])fff+/g,"$1"+l(b,3)),b=Math.round(b/10),e=e.replace(/(^|[^\\])ff/g,"$1"+l(b)),b=Math.round(b/10);var v=u<12?"AM":"PM";e=(e=(e=e.replace(/(^|[^\\])f/g,"$1"+b)).replace(/(^|[^\\])TT+/g,"$1"+v)).replace(/(^|[^\\])T/g,"$1"+v.charAt(0));var m=v.toLowerCase();e=(e=e.replace(/(^|[^\\])tt+/g,"$1"+m)).replace(/(^|[^\\])t/g,"$1"+m.charAt(0));var y=-t.getTimezoneOffset(),w=a||!y?"Z":y>0?"+":"-";if(!a){var k=(y=Math.abs(y))%60;w+=l(Math.floor(y/60))+":"+l(k)}e=e.replace(/(^|[^\\])K/g,"$1"+w);var A=(a?t.getUTCDay():t.getDay())+1;return e=(e=(e=(e=(e=e.replace(new RegExp(o[0],"g"),o[A])).replace(new RegExp(n[0],"g"),n[A])).replace(new RegExp(s[0],"g"),s[c])).replace(new RegExp(r[0],"g"),r[c])).replace(/\\(.)/g,"$1")}},{key:"getTimeUnitsfromTimestamp",value:function(t,e,i){var a=this.w;void 0!==a.config.xaxis.min&&(t=a.config.xaxis.min),void 0!==a.config.xaxis.max&&(e=a.config.xaxis.max);var s=this.getDate(t),r=this.getDate(e),o=this.formatDate(s,"yyyy MM dd HH mm ss fff").split(" "),n=this.formatDate(r,"yyyy MM dd HH mm ss fff").split(" ");return{minMillisecond:parseInt(o[6],10),maxMillisecond:parseInt(n[6],10),minSecond:parseInt(o[5],10),maxSecond:parseInt(n[5],10),minMinute:parseInt(o[4],10),maxMinute:parseInt(n[4],10),minHour:parseInt(o[3],10),maxHour:parseInt(n[3],10),minDate:parseInt(o[2],10),maxDate:parseInt(n[2],10),minMonth:parseInt(o[1],10)-1,maxMonth:parseInt(n[1],10)-1,minYear:parseInt(o[0],10),maxYear:parseInt(n[0],10)}}},{key:"isLeapYear",value:function(t){return t%4==0&&t%100!=0||t%400==0}},{key:"calculcateLastDaysOfMonth",value:function(t,e,i){return this.determineDaysOfMonths(t,e)-i}},{key:"determineDaysOfYear",value:function(t){var e=365;return this.isLeapYear(t)&&(e=366),e}},{key:"determineRemainingDaysOfYear",value:function(t,e,i){var a=this.daysCntOfYear[e]+i;return e>1&&this.isLeapYear()&&a++,a}},{key:"determineDaysOfMonths",value:function(t,e){var i=30;switch(t=p.monthMod(t),!0){case this.months30.indexOf(t)>-1:2===t&&(i=this.isLeapYear(e)?29:28);break;case this.months31.indexOf(t)>-1:default:i=31}return i}}]),t}(),F=function(t){n(s,t);var i=d(s);function s(){return a(this,s),i.apply(this,arguments)}return r(s,[{key:"draw",value:function(t,i){var a=this.w,s=new b(this.ctx);this.rangeBarOptions=this.w.config.plotOptions.rangeBar,this.series=t,this.seriesRangeStart=a.globals.seriesRangeStart,this.seriesRangeEnd=a.globals.seriesRangeEnd,this.barHelpers.initVariables(t);for(var r=s.group({class:"apexcharts-rangebar-series apexcharts-plot-series"}),o=0;o<t.length;o++){var n,l,h,c=void 0,d=void 0,g=void 0,u=a.globals.comboCharts?i[o]:o,f=s.group({class:"apexcharts-series",seriesName:p.escapeString(a.globals.seriesNames[u]),rel:o+1,"data:realIndex":u});this.ctx.series.addCollapsedClassToSeries(f,u),t[o].length>0&&(this.visibleI=this.visibleI+1);var x=0,v=0;this.yRatio.length>1&&(this.yaxisIndex=u);var m=this.barHelpers.initialPositions();d=m.y,h=m.zeroW,c=m.x,v=m.barWidth,n=m.xDivision,l=m.zeroH;for(var y=s.group({class:"apexcharts-datalabels","data:realIndex":u}),w=s.group({class:"apexcharts-rangebar-goals-markers",style:"pointer-events: none"}),k=0;k<a.globals.dataPoints;k++){var A=this.barHelpers.getStrokeWidth(o,k,u),S=this.seriesRangeStart[o][k],C=this.seriesRangeEnd[o][k],L=null,P=null,T={x:c,y:d,strokeWidth:A,elSeries:f};if(g=m.yDivision,x=m.barHeight,this.isHorizontal){P=d+x*this.visibleI;var M=this.seriesLen;a.config.plotOptions.bar.rangeBarGroupRows&&(M=1);var I=(g-x*M)/2;if(void 0===a.config.series[o].data[k])break;if(a.config.series[o].data[k].x){var z=this.detectOverlappingBars({i:o,j:k,barYPosition:P,srty:I,barHeight:x,yDivision:g,initPositions:m});x=z.barHeight,P=z.barYPosition}v=(L=this.drawRangeBarPaths(e({indexes:{i:o,j:k,realIndex:u},barHeight:x,barYPosition:P,zeroW:h,yDivision:g,y1:S,y2:C},T))).barWidth}else x=(L=this.drawRangeColumnPaths(e({indexes:{i:o,j:k,realIndex:u},zeroH:l,barWidth:v,xDivision:n},T))).barHeight;var X=this.barHelpers.drawGoalLine({barXPosition:L.barXPosition,barYPosition:P,goalX:L.goalX,goalY:L.goalY,barHeight:x,barWidth:v});X&&w.add(X),d=L.y,c=L.x;var E=this.barHelpers.getPathFillColor(t,o,k,u),Y=a.globals.stroke.colors[u];this.renderSeries({realIndex:u,pathFill:E,lineFill:Y,j:k,i:o,x:c,y:d,y1:S,y2:C,pathFrom:L.pathFrom,pathTo:L.pathTo,strokeWidth:A,elSeries:f,series:t,barHeight:x,barYPosition:P,barWidth:v,elDataLabelsWrap:y,elGoalsMarkers:w,visibleSeries:this.visibleI,type:"rangebar"})}r.add(f)}return r}},{key:"detectOverlappingBars",value:function(t){var e=t.i,i=t.j,a=t.barYPosition,s=t.srty,r=t.barHeight,o=t.yDivision,n=t.initPositions,l=this.w,h=[],c=l.config.series[e].data[i].rangeName,d=l.config.series[e].data[i].x,g=l.globals.labels.indexOf(d),u=l.globals.seriesRangeBar[e].findIndex((function(t){return t.x===d&&t.overlaps.length>0}));return a=l.config.plotOptions.bar.rangeBarGroupRows?s+o*g:s+r*this.visibleI+o*g,u>-1&&!l.config.plotOptions.bar.rangeBarOverlap&&(h=l.globals.seriesRangeBar[e][u].overlaps).indexOf(c)>-1&&(a=(r=n.barHeight/h.length)*this.visibleI+o*(100-parseInt(this.barOptions.barHeight,10))/100/2+r*(this.visibleI+h.indexOf(c))+o*g),{barYPosition:a,barHeight:r}}},{key:"drawRangeColumnPaths",value:function(t){var e=t.indexes,i=t.x;t.strokeWidth;var a=t.xDivision,s=t.barWidth,r=t.zeroH,o=this.w,n=e.i,l=e.j,h=this.yRatio[this.yaxisIndex],c=e.realIndex,d=this.getRangeValue(c,l),g=Math.min(d.start,d.end),u=Math.max(d.start,d.end);o.globals.isXNumeric&&(i=(o.globals.seriesX[n][l]-o.globals.minX)/this.xRatio-s/2);var p=i+s*this.visibleI;void 0===this.series[n][l]||null===this.series[n][l]?g=r:(g=r-g/h,u=r-u/h);var f=Math.abs(u-g),x=this.barHelpers.getColumnPaths({barXPosition:p,barWidth:s,y1:g,y2:u,strokeWidth:this.strokeWidth,series:this.seriesRangeEnd,realIndex:e.realIndex,i:c,j:l,w:o});return o.globals.isXNumeric||(i+=a),{pathTo:x.pathTo,pathFrom:x.pathFrom,barHeight:f,x:i,y:u,goalY:this.barHelpers.getGoalValues("y",null,r,n,l),barXPosition:p}}},{key:"drawRangeBarPaths",value:function(t){var e=t.indexes,i=t.y,a=t.y1,s=t.y2,r=t.yDivision,o=t.barHeight,n=t.barYPosition,l=t.zeroW,h=this.w,c=l+a/this.invertedYRatio,d=l+s/this.invertedYRatio,g=Math.abs(d-c),u=this.barHelpers.getBarpaths({barYPosition:n,barHeight:o,x1:c,x2:d,strokeWidth:this.strokeWidth,series:this.seriesRangeEnd,i:e.realIndex,realIndex:e.realIndex,j:e.j,w:h});return h.globals.isXNumeric||(i+=r),{pathTo:u.pathTo,pathFrom:u.pathFrom,barWidth:g,x:d,goalX:this.barHelpers.getGoalValues("x",l,null,e.realIndex,e.j),y:i}}},{key:"getRangeValue",value:function(t,e){var i=this.w;return{start:i.globals.seriesRangeStart[t][e],end:i.globals.seriesRangeEnd[t][e]}}},{key:"getTooltipValues",value:function(t){var e=t.ctx,i=t.seriesIndex,a=t.dataPointIndex,s=t.y1,r=t.y2,o=t.w,n=o.globals.seriesRangeStart[i][a],l=o.globals.seriesRangeEnd[i][a],h=o.globals.labels[a],c=o.config.series[i].name?o.config.series[i].name:"",d=o.config.tooltip.y.formatter,g=o.config.tooltip.y.title.formatter,u={w:o,seriesIndex:i,dataPointIndex:a,start:n,end:l};"function"==typeof g&&(c=g(c,u)),Number.isFinite(s)&&Number.isFinite(r)&&(n=s,l=r,o.config.series[i].data[a].x&&(h=o.config.series[i].data[a].x+":"),"function"==typeof d&&(h=d(h,u)));var p="",f="",x=o.globals.colors[i];if(void 0===o.config.tooltip.x.formatter)if("datetime"===o.config.xaxis.type){var b=new Y(e);p=b.formatDate(b.getDate(n),o.config.tooltip.x.format),f=b.formatDate(b.getDate(l),o.config.tooltip.x.format)}else p=n,f=l;else p=o.config.tooltip.x.formatter(n),f=o.config.tooltip.x.formatter(l);return{start:n,end:l,startVal:p,endVal:f,ylabel:h,color:x,seriesName:c}}},{key:"buildCustomTooltipHTML",value:function(t){var e=t.color,i=t.seriesName;return'<div class="apexcharts-tooltip-rangebar"><div> <span class="series-name" style="color: '+e+'">'+(i||"")+'</span></div><div> <span class="category">'+t.ylabel+' </span> <span class="value start-value">'+t.start+'</span> <span class="separator">-</span> <span class="value end-value">'+t.end+"</span></div></div>"}}]),s}(E),R=function(){function t(e){a(this,t),this.opts=e}return r(t,[{key:"line",value:function(){return{chart:{animations:{easing:"swing"}},dataLabels:{enabled:!1},stroke:{width:5,curve:"straight"},markers:{size:0,hover:{sizeOffset:6}},xaxis:{crosshairs:{width:1}}}}},{key:"sparkline",value:function(t){this.opts.yaxis[0].show=!1,this.opts.yaxis[0].title.text="",this.opts.yaxis[0].axisBorder.show=!1,this.opts.yaxis[0].axisTicks.show=!1,this.opts.yaxis[0].floating=!0;return p.extend(t,{grid:{show:!1,padding:{left:0,right:0,top:0,bottom:0}},legend:{show:!1},xaxis:{labels:{show:!1},tooltip:{enabled:!1},axisBorder:{show:!1},axisTicks:{show:!1}},chart:{toolbar:{show:!1},zoom:{enabled:!1}},dataLabels:{enabled:!1}})}},{key:"bar",value:function(){return{chart:{stacked:!1,animations:{easing:"swing"}},plotOptions:{bar:{dataLabels:{position:"center"}}},dataLabels:{style:{colors:["#fff"]},background:{enabled:!1}},stroke:{width:0,lineCap:"round"},fill:{opacity:.85},legend:{markers:{shape:"square",radius:2,size:8}},tooltip:{shared:!1,intersect:!0},xaxis:{tooltip:{enabled:!1},tickPlacement:"between",crosshairs:{width:"barWidth",position:"back",fill:{type:"gradient"},dropShadow:{enabled:!1},stroke:{width:0}}}}}},{key:"candlestick",value:function(){var t=this;return{stroke:{width:1,colors:["#333"]},fill:{opacity:1},dataLabels:{enabled:!1},tooltip:{shared:!0,custom:function(e){var i=e.seriesIndex,a=e.dataPointIndex,s=e.w;return t._getBoxTooltip(s,i,a,["Open","High","","Low","Close"],"candlestick")}},states:{active:{filter:{type:"none"}}},xaxis:{crosshairs:{width:1}}}}},{key:"boxPlot",value:function(){var t=this;return{chart:{animations:{dynamicAnimation:{enabled:!1}}},stroke:{width:1,colors:["#24292e"]},dataLabels:{enabled:!1},tooltip:{shared:!0,custom:function(e){var i=e.seriesIndex,a=e.dataPointIndex,s=e.w;return t._getBoxTooltip(s,i,a,["Minimum","Q1","Median","Q3","Maximum"],"boxPlot")}},markers:{size:5,strokeWidth:1,strokeColors:"#111"},xaxis:{crosshairs:{width:1}}}}},{key:"rangeBar",value:function(){return{stroke:{width:0,lineCap:"square"},plotOptions:{bar:{borderRadius:0,dataLabels:{position:"center"}}},dataLabels:{enabled:!1,formatter:function(t,e){e.ctx;var i=e.seriesIndex,a=e.dataPointIndex,s=e.w,r=s.globals.seriesRangeStart[i][a];return s.globals.seriesRangeEnd[i][a]-r},background:{enabled:!1},style:{colors:["#fff"]}},tooltip:{shared:!1,followCursor:!0,custom:function(t){return t.w.config.plotOptions&&t.w.config.plotOptions.bar&&t.w.config.plotOptions.bar.horizontal?function(t){var e=new F(t.ctx,null),i=e.getTooltipValues(t),a=i.color,s=i.seriesName,r=i.ylabel,o=i.startVal,n=i.endVal;return e.buildCustomTooltipHTML({color:a,seriesName:s,ylabel:r,start:o,end:n})}(t):function(t){var e=new F(t.ctx,null),i=e.getTooltipValues(t),a=i.color,s=i.seriesName,r=i.ylabel,o=i.start,n=i.end;return e.buildCustomTooltipHTML({color:a,seriesName:s,ylabel:r,start:o,end:n})}(t)}},xaxis:{tickPlacement:"between",tooltip:{enabled:!1},crosshairs:{stroke:{width:0}}}}}},{key:"area",value:function(){return{stroke:{width:4},fill:{type:"gradient",gradient:{inverseColors:!1,shade:"light",type:"vertical",opacityFrom:.65,opacityTo:.5,stops:[0,100,100]}},markers:{size:0,hover:{sizeOffset:6}},tooltip:{followCursor:!1}}}},{key:"brush",value:function(t){return p.extend(t,{chart:{toolbar:{autoSelected:"selection",show:!1},zoom:{enabled:!1}},dataLabels:{enabled:!1},stroke:{width:1},tooltip:{enabled:!1},xaxis:{tooltip:{enabled:!1}}})}},{key:"stacked100",value:function(t){t.dataLabels=t.dataLabels||{},t.dataLabels.formatter=t.dataLabels.formatter||void 0;var e=t.dataLabels.formatter;return t.yaxis.forEach((function(e,i){t.yaxis[i].min=0,t.yaxis[i].max=100})),"bar"===t.chart.type&&(t.dataLabels.formatter=e||function(t){return"number"==typeof t&&t?t.toFixed(0)+"%":t}),t}},{key:"convertCatToNumeric",value:function(t){return t.xaxis.convertedCatToNumeric=!0,t}},{key:"convertCatToNumericXaxis",value:function(t,e,i){t.xaxis.type="numeric",t.xaxis.labels=t.xaxis.labels||{},t.xaxis.labels.formatter=t.xaxis.labels.formatter||function(t){return p.isNumber(t)?Math.floor(t):t};var a=t.xaxis.labels.formatter,s=t.xaxis.categories&&t.xaxis.categories.length?t.xaxis.categories:t.labels;return i&&i.length&&(s=i.map((function(t){return Array.isArray(t)?t:String(t)}))),s&&s.length&&(t.xaxis.labels.formatter=function(t){return p.isNumber(t)?a(s[Math.floor(t)-1]):a(t)}),t.xaxis.categories=[],t.labels=[],t.xaxis.tickAmount=t.xaxis.tickAmount||"dataPoints",t}},{key:"bubble",value:function(){return{dataLabels:{style:{colors:["#fff"]}},tooltip:{shared:!1,intersect:!0},xaxis:{crosshairs:{width:0}},fill:{type:"solid",gradient:{shade:"light",inverse:!0,shadeIntensity:.55,opacityFrom:.4,opacityTo:.8}}}}},{key:"scatter",value:function(){return{dataLabels:{enabled:!1},tooltip:{shared:!1,intersect:!0},markers:{size:6,strokeWidth:1,hover:{sizeOffset:2}}}}},{key:"heatmap",value:function(){return{chart:{stacked:!1},fill:{opacity:1},dataLabels:{style:{colors:["#fff"]}},stroke:{colors:["#fff"]},tooltip:{followCursor:!0,marker:{show:!1},x:{show:!1}},legend:{position:"top",markers:{shape:"square",size:10,offsetY:2}},grid:{padding:{right:20}}}}},{key:"treemap",value:function(){return{chart:{zoom:{enabled:!1}},dataLabels:{style:{fontSize:14,fontWeight:600,colors:["#fff"]}},stroke:{show:!0,width:2,colors:["#fff"]},legend:{show:!1},fill:{gradient:{stops:[0,100]}},tooltip:{followCursor:!0,x:{show:!1}},grid:{padding:{left:0,right:0}},xaxis:{crosshairs:{show:!1},tooltip:{enabled:!1}}}}},{key:"pie",value:function(){return{chart:{toolbar:{show:!1}},plotOptions:{pie:{donut:{labels:{show:!1}}}},dataLabels:{formatter:function(t){return t.toFixed(1)+"%"},style:{colors:["#fff"]},background:{enabled:!1},dropShadow:{enabled:!0}},stroke:{colors:["#fff"]},fill:{opacity:1,gradient:{shade:"light",stops:[0,100]}},tooltip:{theme:"dark",fillSeriesColor:!0},legend:{position:"right"}}}},{key:"donut",value:function(){return{chart:{toolbar:{show:!1}},dataLabels:{formatter:function(t){return t.toFixed(1)+"%"},style:{colors:["#fff"]},background:{enabled:!1},dropShadow:{enabled:!0}},stroke:{colors:["#fff"]},fill:{opacity:1,gradient:{shade:"light",shadeIntensity:.35,stops:[80,100],opacityFrom:1,opacityTo:1}},tooltip:{theme:"dark",fillSeriesColor:!0},legend:{position:"right"}}}},{key:"polarArea",value:function(){return this.opts.yaxis[0].tickAmount=this.opts.yaxis[0].tickAmount?this.opts.yaxis[0].tickAmount:6,{chart:{toolbar:{show:!1}},dataLabels:{formatter:function(t){return t.toFixed(1)+"%"},enabled:!1},stroke:{show:!0,width:2},fill:{opacity:.7},tooltip:{theme:"dark",fillSeriesColor:!0},legend:{position:"right"}}}},{key:"radar",value:function(){return this.opts.yaxis[0].labels.offsetY=this.opts.yaxis[0].labels.offsetY?this.opts.yaxis[0].labels.offsetY:6,{dataLabels:{enabled:!1,style:{fontSize:"11px"}},stroke:{width:2},markers:{size:3,strokeWidth:1,strokeOpacity:1},fill:{opacity:.2},tooltip:{shared:!1,intersect:!0,followCursor:!0},grid:{show:!1},xaxis:{labels:{formatter:function(t){return t},style:{colors:["#a8a8a8"],fontSize:"11px"}},tooltip:{enabled:!1},crosshairs:{show:!1}}}}},{key:"radialBar",value:function(){return{chart:{animations:{dynamicAnimation:{enabled:!0,speed:800}},toolbar:{show:!1}},fill:{gradient:{shade:"dark",shadeIntensity:.4,inverseColors:!1,type:"diagonal2",opacityFrom:1,opacityTo:1,stops:[70,98,100]}},legend:{show:!1,position:"right"},tooltip:{enabled:!1,fillSeriesColor:!0}}}},{key:"_getBoxTooltip",value:function(t,e,i,a,s){var r=t.globals.seriesCandleO[e][i],o=t.globals.seriesCandleH[e][i],n=t.globals.seriesCandleM[e][i],l=t.globals.seriesCandleL[e][i],h=t.globals.seriesCandleC[e][i];return t.config.series[e].type&&t.config.series[e].type!==s?'<div class="apexcharts-custom-tooltip">\n          '.concat(t.config.series[e].name?t.config.series[e].name:"series-"+(e+1),": <strong>").concat(t.globals.series[e][i],"</strong>\n        </div>"):'<div class="apexcharts-tooltip-box apexcharts-tooltip-'.concat(t.config.chart.type,'">')+"<div>".concat(a[0],': <span class="value">')+r+"</span></div>"+"<div>".concat(a[1],': <span class="value">')+o+"</span></div>"+(n?"<div>".concat(a[2],': <span class="value">')+n+"</span></div>":"")+"<div>".concat(a[3],': <span class="value">')+l+"</span></div>"+"<div>".concat(a[4],': <span class="value">')+h+"</span></div></div>"}}]),t}(),H=function(){function t(e){a(this,t),this.opts=e}return r(t,[{key:"init",value:function(t){var e=t.responsiveOverride,a=this.opts,s=new S,r=new R(a);this.chartType=a.chart.type,"histogram"===this.chartType&&(a.chart.type="bar",a=p.extend({plotOptions:{bar:{columnWidth:"99.99%"}}},a)),a=this.extendYAxis(a),a=this.extendAnnotations(a);var o=s.init(),n={};if(a&&"object"===i(a)){var l={};l=-1!==["line","area","bar","candlestick","boxPlot","rangeBar","histogram","bubble","scatter","heatmap","treemap","pie","polarArea","donut","radar","radialBar"].indexOf(a.chart.type)?r[a.chart.type]():r.line(),a.chart.brush&&a.chart.brush.enabled&&(l=r.brush(l)),a.chart.stacked&&"100%"===a.chart.stackType&&(a=r.stacked100(a)),this.checkForDarkTheme(window.Apex),this.checkForDarkTheme(a),a.xaxis=a.xaxis||window.Apex.xaxis||{},e||(a.xaxis.convertedCatToNumeric=!1),((a=this.checkForCatToNumericXAxis(this.chartType,l,a)).chart.sparkline&&a.chart.sparkline.enabled||window.Apex.chart&&window.Apex.chart.sparkline&&window.Apex.chart.sparkline.enabled)&&(l=r.sparkline(l)),n=p.extend(o,l)}var h=p.extend(n,window.Apex);return o=p.extend(h,a),o=this.handleUserInputErrors(o)}}
61903,{key:"checkForCatToNumericXAxis",value:function(t,e,i){var a=new R(i),s=("bar"===t||"boxPlot"===t)&&i.plotOptions&&i.plotOptions.bar&&i.plotOptions.bar.horizontal,r="pie"===t||"polarArea"===t||"donut"===t||"radar"===t||"radialBar"===t||"heatmap"===t,o="datetime"!==i.xaxis.type&&"numeric"!==i.xaxis.type,n=i.xaxis.tickPlacement?i.xaxis.tickPlacement:e.xaxis&&e.xaxis.tickPlacement;return s||r||!o||"between"===n||(i=a.convertCatToNumeric(i)),i}},{key:"extendYAxis",value:function(t,e){var i=new S;(void 0===t.yaxis||!t.yaxis||Array.isArray(t.yaxis)&&0===t.yaxis.length)&&(t.yaxis={}),t.yaxis.constructor!==Array&&window.Apex.yaxis&&window.Apex.yaxis.constructor!==Array&&(t.yaxis=p.extend(t.yaxis,window.Apex.yaxis)),t.yaxis.constructor!==Array?t.yaxis=[p.extend(i.yAxis,t.yaxis)]:t.yaxis=p.extendArray(t.yaxis,i.yAxis);var a=!1;t.yaxis.forEach((function(t){t.logarithmic&&(a=!0)}));var s=t.series;return e&&!s&&(s=e.config.series),a&&s.length!==t.yaxis.length&&s.length&&(t.yaxis=s.map((function(e,a){if(e.name||(s[a].name="series-".concat(a+1)),t.yaxis[a])return t.yaxis[a].seriesName=s[a].name,t.yaxis[a];var r=p.extend(i.yAxis,t.yaxis[0]);return r.show=!1,r}))),a&&s.length>1&&s.length!==t.yaxis.length&&console.warn("A multi-series logarithmic chart should have equal number of series and y-axes. Please make sure to equalize both."),t}},{key:"extendAnnotations",value:function(t){return void 0===t.annotations&&(t.annotations={},t.annotations.yaxis=[],t.annotations.xaxis=[],t.annotations.points=[]),t=this.extendYAxisAnnotations(t),t=this.extendXAxisAnnotations(t),t=this.extendPointAnnotations(t)}},{key:"extendYAxisAnnotations",value:function(t){var e=new S;return t.annotations.yaxis=p.extendArray(void 0!==t.annotations.yaxis?t.annotations.yaxis:[],e.yAxisAnnotation),t}},{key:"extendXAxisAnnotations",value:function(t){var e=new S;return t.annotations.xaxis=p.extendArray(void 0!==t.annotations.xaxis?t.annotations.xaxis:[],e.xAxisAnnotation),t}},{key:"extendPointAnnotations",value:function(t){var e=new S;return t.annotations.points=p.extendArray(void 0!==t.annotations.points?t.annotations.points:[],e.pointAnnotation),t}},{key:"checkForDarkTheme",value:function(t){t.theme&&"dark"===t.theme.mode&&(t.tooltip||(t.tooltip={}),"light"!==t.tooltip.theme&&(t.tooltip.theme="dark"),t.chart.foreColor||(t.chart.foreColor="#f6f7f8"),t.chart.background||(t.chart.background="#424242"),t.theme.palette||(t.theme.palette="palette4"))}},{key:"handleUserInputErrors",value:function(t){var e=t;if(e.tooltip.shared&&e.tooltip.intersect)throw new Error("tooltip.shared cannot be enabled when tooltip.intersect is true. Turn off any other option by setting it to false.");if("bar"===e.chart.type&&e.plotOptions.bar.horizontal){if(e.yaxis.length>1)throw new Error("Multiple Y Axis for bars are not supported. Switch to column chart by setting plotOptions.bar.horizontal=false");e.yaxis[0].reversed&&(e.yaxis[0].opposite=!0),e.xaxis.tooltip.enabled=!1,e.yaxis[0].tooltip.enabled=!1,e.chart.zoom.enabled=!1}return"bar"!==e.chart.type&&"rangeBar"!==e.chart.type||e.tooltip.shared&&"barWidth"===e.xaxis.crosshairs.width&&e.series.length>1&&(e.xaxis.crosshairs.width="tickWidth"),"candlestick"!==e.chart.type&&"boxPlot"!==e.chart.type||e.yaxis[0].reversed&&(console.warn("Reversed y-axis in ".concat(e.chart.type," chart is not supported.")),e.yaxis[0].reversed=!1),Array.isArray(e.stroke.width)&&"line"!==e.chart.type&&"area"!==e.chart.type&&(console.warn("stroke.width option accepts array only for line and area charts. Reverted back to Number"),e.stroke.width=e.stroke.width[0]),e}}]),t}(),D=function(){function t(){a(this,t)}return r(t,[{key:"initGlobalVars",value:function(t){t.series=[],t.seriesCandleO=[],t.seriesCandleH=[],t.seriesCandleM=[],t.seriesCandleL=[],t.seriesCandleC=[],t.seriesRangeStart=[],t.seriesRangeEnd=[],t.seriesRangeBar=[],t.seriesPercent=[],t.seriesGoals=[],t.seriesX=[],t.seriesZ=[],t.seriesNames=[],t.seriesTotals=[],t.seriesLog=[],t.seriesColors=[],t.stackedSeriesTotals=[],t.seriesXvalues=[],t.seriesYvalues=[],t.labels=[],t.categoryLabels=[],t.timescaleLabels=[],t.noLabelsProvi
61903ded=!1,t.resizeTimer=null,t.selectionResizeTimer=null,t.delayedElements=[],t.pointsArray=[],t.dataLabelsRects=[],t.isXNumeric=!1,t.xaxisLabelsCount=0,t.skipLastTimelinelabel=!1,t.skipFirstTimelinelabel=!1,t.isDataXYZ=!1,t.isMultiLineX=!1,t.isMultipleYAxis=!1,t.maxY=-Number.MAX_VALUE,t.minY=Number.MIN_VALUE,t.minYArr=[],t.maxYArr=[],t.maxX=-Number.MAX_VALUE,t.minX=Number.MAX_VALUE,t.initialMaxX=-Number.MAX_VALUE,t.initialMinX=Number.MAX_VALUE,t.maxDate=0,t.minDate=Number.MAX_VALUE,t.minZ=Number.MAX_VALUE,t.maxZ=-Number.MAX_VALUE,t.minXDiff=Number.MAX_VALUE,t.yAxisScale=[],t.xAxisScale=null,t.xAxisTicksPositions=[],t.yLabelsCoords=[],t.yTitleCoords=[],t.barPadForNumericAxis=0,t.padHorizontal=0,t.xRange=0,t.yRange=[],t.zRange=0,t.dataPoints=0,t.xTickAmount=0}},{key:"globalVars",value:function(t){return{chartID:null,cuid:null,events:{beforeMount:[],mounted:[],updated:[],clicked:[],selection:[],dataPointSelection:[],zoomed:[],scrolled:[]},colors:[],clientX:null,clientY:null,fill:{colors:[]},stroke:{colors:[]},dataLabels:{style:{colors:[]}},radarPolygons:{fill:{colors:[]}},markers:{colors:[],size:t.markers.size,largestSize:0},animationEnded:!1,isTouchDevice:"ontouchstart"in window||navigator.msMaxTouchPoints,isDirty:!1,isExecCalled:!1,initialConfig:null,initialSeries:[],lastXAxis:[],lastYAxis:[],columnSeries:null,labels:[],timescaleLabels:[],noLabelsProvided:!1,allSeriesCollapsed:!1,collapsedSeries:[],collapsedSeriesIndices:[],ancillaryCollapsedSeries:[],ancillaryCollapsedSeriesIndices:[],risingSeries:[],dataFormatXNumeric:!1,capturedSeriesIndex:-1,capturedDataPointIndex:-1,selectedDataPoints:[],goldenPadding:35,invalidLogScale:!1,ignoreYAxisIndexes:[],yAxisSameScaleIndices:[],maxValsInArrayIndex:0,radialSize:0,selection:void 0,zoomEnabled:"zoom"===t.chart.toolbar.autoSelected&&t.chart.toolbar.tools.zoom&&t.chart.zoom.enabled,panEnabled:"pan"===t.chart.toolbar.autoSelected&&t.chart.toolbar.tools.pan,selectionEnabled:"selection"===t.chart.toolbar.autoSelected&&t.chart.toolbar.tools.selection,yaxis:null,mousedown:!1,lastClientPosition:{},visibleXRange:void 0,yValueDecimal:0,total:0,SVGNS:"http://www.w3.org/2000/svg",svgWidth:0,svgHeight:0,noData:!1,locale:{},dom:{},memory:{methodsToExec:[]},shouldAnimate:!0,skipLastTimelinelabel:!1,skipFirstTimelinelabel:!1,delayedElements:[],axisCharts:!0,isDataXYZ:!1,resized:!1,resizeTimer:null,comboCharts:!1,dataChanged:!1,previousPaths:[],allSeriesHasEqualX:!0,pointsArray:[],dataLabelsRects:[],lastDrawnDataLabelsIndexes:[],hasNullValues:!1,easing:null,zoomed:!1,gridWidth:0,gridHeight:0,rotateXLabels:!1,defaultLabels:!1,xLabelFormatter:void 0,yLabelFormatters:[],xaxisTooltipFormatter:void 0,ttKeyFormatter:void 0,ttVal:void 0,ttZFormatter:void 0,LINE_HEIGHT_RATIO:1.618,xAxisLabelsHeight:0,xAxisLabelsWidth:0,yAxisLabelsWidth:0,scaleX:1,scaleY:1,translateX:0,translateY:0,translateYAxisX:[],yAxisWidths:[],translateXAxisY:0,translateXAxisX:0,tooltip:null}}},{key:"init",value:function(t){var e=this.globalVars(t);return this.initGlobalVars(e),e.initialConfig=p.extend({},t),e.initialSeries=p.clone(t.series),e.lastXAxis=p.clone(e.initialConfig.xaxis),e.lastYAxis=p.clone(e.initialConfig.yaxis),e}}]),t}(),N=function(){function t(e){a(this,t),this.opts=e}return r(t,[{key:"init",value:function(){var t=new H(this.opts).init({responsiveOverride:!1});return{config:t,globals:(new D).init(t)}}}]),t}(),O=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w,this.twoDSeries=[],this.threeDSeries=[],this.twoDSeriesX=[],this.seriesGoals=[],this.coreUtils=new y(this.ctx)}return r(t,[{key:"isMultiFormat",value:function(){return this.isFormatXY()||this.isFormat2DArray()}},{key:"isFormatXY",value:function(){var t=this.w.config.series.slice(),e=new z(this.ctx);if(this.activeSeriesIndex=e.getActiveConfigSeriesIndex(),void 0!==t[this.activeSeriesIndex].data&&t[this.activeSeriesIndex].data.length>0&&null!==t[this.activeSeriesIndex].data[0]&&void 0!==t[this.activeSeriesIndex].data[0].x&&null!==t[this.activeSeriesIndex].data[0])return!0}},{key:"isFormat2DArray",value:function(){var t=this.w.config.series.slice(),e=new z(this.ctx);if(this.activeSeriesIndex=e.getActiveConfigSeriesIndex(),void 0!==t[this.activeSeriesIndex].data&&t[this.activeSeriesIndex].data.length>0&&void 0!==t[this.activeSeriesIndex].data[0]&&null!==t[this.activeSeriesIndex].data[0]&&t[this.activeSeriesIndex].data[0].constructor===Array)return!0}},{key:"handleFormat2DArray",value:function(t,e){for(var i=this.w.config,a=this.w.globals,s="boxPlot"===i.chart.type||"boxPlot"===i.series[e].type,r=0;r<t[e].data.length;r++)if(void 0!==t[e].data[r][1]&&(Array.isArray(t[e].data[r][1])&&4===t[e].data[r][1].length&&!s?this.twoDSeries.push(p.parseNumber(t[e].data[r][1][3])):t[e].data[r].length>=5?this.twoDSeries.push(p.parseNumber(t[e].data[r][4])):this.twoDSeries.push(p.parseNumber(t[e].data[r][1])),a.dataFormatXNumeric=!0),"datetime"===i.xaxis.type){var o=new Date(t[e].data[r][0]);o=new Date(o).getTime(),this.twoDSeriesX.push(o)}else this.twoDSeriesX.push(t[e].data[r][0]);for(var n=0;n<t[e].data.length;n++)void 0!==t[e].data[n][2]&&(this.threeDSeries.push(t[e].data[n][2]),a.isDataXYZ=!0)}},{key:"handleFormatXY",value:function(t,e){var i=this.w.config,a=this.w.globals,s=new Y(this.ctx),r=e;a.collapsedSeriesIndices.indexOf(e)>-1&&(r=this.activeSeriesIndex);for(var o=0;o<t[e].data.length;o++)void 0!==t[e].data[o].y&&(Array.isArray(t[e].data[o].y)?this.twoDSeries.push(p.parseNumber(t[e].data[o].y[t[e].data[o].y.length-1])):this.twoDSeries.push(p.parseNumber(t[e].data[o].y))),void 0!==t[e].data[o].goals&&Array.isArray(t[e].data[o].goals)?(void 0===this.seriesGoals[e]&&(this.seriesGoals[e]=[]),this.seriesGoals[e].push(t[e].data[o].goals)):(void 0===this.seriesGoals[e]&&(this.seriesGoals[e]=[]),this.seriesGoals[e].push(null));for(var n=0;n<t[r].data.length;n++){var l="string"==typeof t[r].data[n].x,h=Array.isArray(t[r].data[n].x),c=!h&&!!s.isValidDate(t[r].data[n].x.toString());if(l||c)if(l||i.xaxis.convertedCatToNumeric){var d=a.isBarHorizontal&&a.isRangeData;"datetime"!==i.xaxis.type||d?(this.fallbackToCategory=!0,this.twoDSeriesX.push(t[r].data[n].x)):this.twoDSeriesX.push(s.parseDate(t[r].data[n].x))}else"datetime"===i.xaxis.type?this.twoDSeriesX.push(s.parseDate(t[r].data[n].x.toString())):(a.dataFormatXNumeric=!0,a.isXNumeric=!0,this.twoDSeriesX.push(parseFloat(t[r].data[n].x)));else h?(this.fallbackToCategory=!0,this.twoDSeriesX.push(t[r].data[n].x)):(a.isXNumeric=!0,a.dataFormatXNumeric=!0,this.twoDSeriesX.push(t[r].data[n].x))}if(t[e].data[0]&&void 0!==t[e].data[0].z){for(var g=0;g<t[e].data.length;g++)this.threeDSeries.push(t[e].data[g].z);a.isDataXYZ=!0}}},{key:"handleRangeData",value:function(t,e){var i=this.w.globals,a={};return this.isFormat2DArray()?a=this.handleRangeDataFormat("array",t,e):this.isFormatXY()&&(a=this.handleRangeDataFormat("xy",t,e)),i.seriesRangeStart.push(a.start),i.seriesRangeEnd.push(a.end),i.seriesRangeBar.push(a.rangeUniques),i.seriesRangeBar.forEach((function(t,e){t&&t.forEach((function(t,e){t.y.forEac
61903h((function(e,i){for(var a=0;a<t.y.length;a++)if(i!==a){var s=e.y1,r=e.y2,o=t.y[a].y1;s<=t.y[a].y2&&o<=r&&(t.overlaps.indexOf(e.rangeName)<0&&t.overlaps.push(e.rangeName),t.overlaps.indexOf(t.y[a].rangeName)<0&&t.overlaps.push(t.y[a].rangeName))}}))}))})),a}},{key:"handleCandleStickBoxData",value:function(t,e){var i=this.w.globals,a={};return this.isFormat2DArray()?a=this.handleCandleStickBoxDataFormat("array",t,e):this.isFormatXY()&&(a=this.handleCandleStickBoxDataFormat("xy",t,e)),i.seriesCandleO[e]=a.o,i.seriesCandleH[e]=a.h,i.seriesCandleM[e]=a.m,i.seriesCandleL[e]=a.l,i.seriesCandleC[e]=a.c,a}},{key:"handleRangeDataFormat",value:function(t,e,i){var a=[],s=[],r=e[i].data.filter((function(t,e,i){return e===i.findIndex((function(e){return e.x===t.x}))})).map((function(t,e){return{x:t.x,overlaps:[],y:[]}})),o="Please provide [Start, End] values in valid format. Read more https://apexcharts.com/docs/series/#rangecharts",n=new z(this.ctx).getActiveConfigSeriesIndex();if("array"===t){if(2!==e[n].data[0][1].length)throw new Error(o);for(var l=0;l<e[i].data.length;l++)a.push(e[i].data[l][1][0]),s.push(e[i].data[l][1][1])}else if("xy"===t){if(2!==e[n].data[0].y.length)throw new Error(o);for(var h=function(t){var o=p.randomId(),n=e[i].data[t].x,l={y1:e[i].data[t].y[0],y2:e[i].data[t].y[1],rangeName:o};e[i].data[t].rangeName=o;var h=r.findIndex((function(t){return t.x===n}));r[h].y.push(l),a.push(l.y1),s.push(l.y2)},c=0;c<e[i].data.length;c++)h(c)}return{start:a,end:s,rangeUniques:r}}},{key:"handleCandleStickBoxDataFormat",value:function(t,e,i){var a=this.w,s="boxPlot"===a.config.chart.type||"boxPlot"===a.config.series[i].type,r=[],o=[],n=[],l=[],h=[];if("array"===t)if(s&&6===e[i].data[0].length||!s&&5===e[i].data[0].length)for(var c=0;c<e[i].data.length;c++)r.push(e[i].data[c][1]),o.push(e[i].data[c][2]),s?(n.push(e[i].data[c][3]),l.push(e[i].data[c][4]),h.push(e[i].data[c][5])):(l.push(e[i].data[c][3]),h.push(e[i].data[c][4]));else for(var d=0;d<e[i].data.length;d++)Array.isArray(e[i].data[d][1])&&(r.push(e[i].data[d][1][0]),o.push(e[i].data[d][1][1]),s?(n.push(e[i].data[d][1][2]),l.push(e[i].data[d][1][3]),h.push(e[i].data[d][1][4])):(l.push(e[i].data[d][1][2]),h.push(e[i].data[d][1][3])));else if("xy"===t)for(var g=0;g<e[i].data.length;g++)Array.isArray(e[i].data[g].y)&&(r.push(e[i].data[g].y[0]),o.push(e[i].data[g].y[1]),s?(n.push(e[i].data[g].y[2]),l.push(e[i].data[g].y[3]),h.push(e[i].data[g].y[4])):(l.push(e[i].data[g].y[2]),h.push(e[i].data[g].y[3])));return{o:r,h:o,m:n,l:l,c:h}}},{key:"parseDataAxisCharts",value:function(t){var e=this,i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.ctx,a=this.w.config,s=this.w.globals,r=new Y(i),o=a.labels.length>0?a.labels.slice():a.xaxis.categories.slice();s.isRangeBar="rangeBar"===a.chart.type&&s.isBarHorizontal;for(var n=function(){for(var t=0;t<o.length;t++)if("string"==typeof o[t]){if(!r.isValidDate(o[t]))throw new Error("You have provided invalid Date format. Please provide a valid JavaScript Date");e.twoDSeriesX.push(r.parseDate(o[t]))}else e.twoDSeriesX.push(o[t])},l=0;l<t.length;l++){if(this.twoDSeries=[],this.twoDSeriesX=[],this.threeDSeries=[],void 0===t[l].data)return void console.error("It is a possibility that you may have not included 'data' property in series.");if("rangeBar"!==a.chart.type&&"rangeArea"!==a.chart.type&&"rangeBar"!==t[l].type&&"rangeArea"!==t[l].type||(s.isRangeData=!0,this.handleRangeData(t,l)),this.isMultiFormat())this.isFormat2DArray()?this.handleFormat2DArray(t,l):this.isFormatXY()&&this.handleFormatXY(t,l),"candlestick"!==a.chart.type&&"candlestick"!==t[l].type&&"boxPlot"!==a.chart.type&&"boxPlot"!==t[l].type||this.handleCandleStickBoxData(t,l),s.series.push(this.twoDSeries),s.labels.push(this.twoDSeriesX),s.seriesX.push(this.twoDSeriesX),s.seriesGoals=this.seriesGoals,l!==this.activeSeriesIndex||this.fallbackToCategory||(s.isXNumeric=!0);else{"datetime"===a.xaxis.type?(s.isXNumeric=!0,n(),s.seriesX.push(this.twoDSeriesX)):"numeric"===a.xaxis.type&&(s.isXNumeric=!0,o.length>0&&(this.twoDSeriesX=o,s.seriesX.push(this.twoDSeriesX))),s.labels.push(this.twoDSeriesX);var h=t[l].data.map((function(t){return p.parseNumber(t)}));s.series.push(h)}
61903s.seriesZ.push(this.threeDSeries),void 0!==t[l].name?s.seriesNames.push(t[l].name):s.seriesNames.push("series-"+parseInt(l+1,10)),void 0!==t[l].color?s.seriesColors.push(t[l].color):s.seriesColors.push(void 0)}return this.w}},{key:"parseDataNonAxisCharts",value:function(t){var e=this.w.globals,i=this.w.config;e.series=t.slice(),e.seriesNames=i.labels.slice();for(var a=0;a<e.series.length;a++)void 0===e.seriesNames[a]&&e.seriesNames.push("series-"+(a+1));return this.w}},{key:"handleExternalLabelsData",value:function(t){var e=this.w.config,i=this.w.globals;if(e.xaxis.categories.length>0)i.labels=e.xaxis.categories;else if(e.labels.length>0)i.labels=e.labels.slice();else if(this.fallbackToCategory){if(i.labels=i.labels[0],i.seriesRangeBar.length&&(i.seriesRangeBar.map((function(t){t.forEach((function(t){i.labels.indexOf(t.x)<0&&t.x&&i.labels.push(t.x)}))})),i.labels=i.labels.filter((function(t,e,i){return i.indexOf(t)===e}))),e.xaxis.convertedCatToNumeric)new R(e).convertCatToNumericXaxis(e,this.ctx,i.seriesX[0]),this._generateExternalLabels(t)}else this._generateExternalLabels(t)}},{key:"_generateExternalLabels",value:function(t){var e=this.w.globals,i=this.w.config,a=[];if(e.axisCharts){if(e.series.length>0)if(this.isFormatXY())for(var s=i.series.map((function(t,e){return t.data.filter((function(t,e,i){return i.findIndex((function(e){return e.x===t.x}))===e}))})),r=s.reduce((function(t,e,i,a){return a[t].length>e.length?t:i}),0),o=0;o<s[r].length;o++)a.push(o+1);else for(var n=0;n<e.series[e.maxValsInArrayIndex].length;n++)a.push(n+1);e.seriesX=[];for(var l=0;l<t.length;l++)e.seriesX.push(a);e.isXNumeric=!0}if(0===a.length){a=e.axisCharts?[]:e.series.map((function(t,e){return e+1}));for(var h=0;h<t.length;h++)e.seriesX.push(a)}e.labels=a,i.xaxis.convertedCatToNumeric&&(e.categoryLabels=a.map((function(t){return i.xaxis.labels.formatter(t)}))),e.noLabelsProvided=!0}},{key:"parseData",value:function(t){var e=this.w,i=e.config,a=e.globals;if(this.excludeCollapsedSeriesInYAxis(),this.fallbackToCategory=!1,this.ctx.core.resetGlobals(),this.ctx.core.isMultipleY(),a.axisCharts?this.parseDataAxisCharts(t):this.parseDataNonAxisCharts(t),this.coreUtils.getLargestSeries(),"bar"===i.chart.type&&i.chart.stacked){var s=new z(this.ctx);a.series=s.setNullSeriesToZeroValues(a.series)}this.coreUtils.getSeriesTotals(),a.axisCharts&&this.coreUtils.getStackedSeriesTotals(),this.coreUtils.getPercentSeries(),a.dataFormatXNumeric||a.isXNumeric&&("numeric"!==i.xaxis.type||0!==i.labels.length||0!==i.xaxis.categories.length)||this.handleExternalLabelsData(t);for(var r=this.coreUtils.getCategoryLabels(a.labels),o=0;o<r.length;o++)if(Array.isArray(r[o])){a.isMultiLineX=!0;break}}},{key:"excludeCollapsedSeriesInYAxis",value:function(){var t=this,e=this.w;e.globals.ignoreYAxisIndexes=e.globals.collapsedSeries.map((function(i,a){if(t.w.globals.isMultipleYAxis&&!e.config.chart.stacked)return i.index}))}}]),t}(),W=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w,this.tooltipKeyFormat="dd MMM"}return r(t,[{key:"xLabelFormat",value:function(t,e,i,a){var s=this.w;if("datetime"===s.config.xaxis.type&&void 0===s.config.xaxis.labels.formatter&&void 0===s.config.tooltip.x.formatter){var r=new Y(this.ctx);return r.formatDate(r.getDate(e),s.config.tooltip.x.format)}return t(e,i,a)}},{key:"defaultGeneralFormatter",value:function(t){return Array.isArray(t)?t.map((function(t){return t})):t}},{key:"defaultYFormatter",value:function(t,e,i){var a=this.w;return p.isNumber(t)&&(t=0!==a.globals.yValueDecimal?t.toFixed(void 0!==e.decimalsInFloat?e.decimalsInFloat:a.globals.yValueDecimal):a.globals.maxYArr[i]-a.globals.minYArr[i]<5?t.toFixed(1):t.toFixed(0)),t}},{key:"setLabelFormatters",value:function(){var t=this,e=this.w;return e.globals.xaxisTooltipFormatter=function(e){return t.defaultGeneralFormatter(e)},e.globals.ttKeyFormatter=function(e){return t.defaultGeneralFormatter(e)},e.globals.ttZFormatter=function(t){return t},e.globals.legendFormatter=function(e){return t.defaultGeneralFormatter(e)},void 0!==e.config.xaxis.labels.formatter?e.globals.xLabelFormatter=e.config.xaxis.labels.formatter:e.globals.xLabelFormatter=function(t){if(p.isNumber(t)){if(!e.config.xaxis.convertedCatToNumeric&&"numeric"===e.config.xaxis.type){if(p.isNumber(e.config.xaxis.decimalsInFloat))return t.toFixed(e.config.xaxis.decimalsInFloat);var i=e.globals.maxX-e.globals.minX;return i>0&&i<100?t.toFixed(1):t.toFixed(0)}if(e.globals.isBarHorizontal)if(e.globals.maxY-e.globals.minYArr<4)return t.toFixed(1);return t.toFixed(0)}return t},"function"==typeof e.config.tooltip.x.formatter?e.globals.ttKeyFormatter=e.config.tooltip.x.formatter:e.globals.ttKeyFormatter=e.globals.xLabelFormatter,"function"==typeof e.config.xaxis.tooltip.formatter&&(e.globals.xaxisTooltipFormatter=e.config.xaxis.tooltip.formatter),(Array.isArray(e.config.tooltip.y)||void 0!==e.config.tooltip.y.formatter)&&(e.globals.ttVal=e.config.tooltip.y),void 0!==e.config.tooltip.z.formatter&&(e.globals.ttZFormatter=e.config.tooltip.z.formatter),void 0!==e.config.legend.formatter&&(e.globals.legendFormatter=e.config.legend.formatter),e.config.yaxis.forEach((function(i,a){void 0!==i.labels.formatter?e.globals.yLabelFormatters[a]=i.labels.formatter:e.globals.yLabelFormatters[a]=function(s){return e.globals.xyCh
61903arts?Array.isArray(s)?s.map((function(e){return t.defaultYFormatter(e,i,a)})):t.defaultYFormatter(s,i,a):s}})),e.globals}},{key:"heatmapLabelFormatters",value:function(){var t=this.w;if("heatmap"===t.config.chart.type){t.globals.yAxisScale[0].result=t.globals.seriesNames.slice();var e=t.globals.seriesNames.reduce((function(t,e){return t.length>e.length?t:e}),0);t.globals.yAxisScale[0].niceMax=e,t.globals.yAxisScale[0].niceMin=e}}}]),t}(),B=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w}return r(t,[{key:"getLabel",value:function(t,e,i,a){var s=arguments.length>4&&void 0!==arguments[4]?arguments[4]:[],r=arguments.length>5&&void 0!==arguments[5]?arguments[5]:"12px",o=this.w,n=void 0===t[a]?"":t[a],l=n,h=o.globals.xLabelFormatter,c=o.config.xaxis.labels.formatter,d=!1,g=new W(this.ctx),u=n;l=g.xLabelFormat(h,n,u,{i:a,dateFormatter:new Y(this.ctx).formatDate,w:o}),void 0!==c&&(l=c(n,t[a],{i:a,dateFormatter:new Y(this.ctx).formatDate,w:o}));var p=function(t){var i=null;return e.forEach((function(t){"month"===t.unit?i="year":"day"===t.unit?i="month":"hour"===t.unit?i="day":"minute"===t.unit&&(i="hour")})),i===t};e.length>0?(d=p(e[a].unit),i=e[a].position,l=e[a].value):"datetime"===o.config.xaxis.type&&void 0===c&&(l=""),void 0===l&&(l=""),l=Array.isArray(l)?l:l.toString();var f=new b(this.ctx),x={};x=o.globals.rotateXLabels?f.getTextRects(l,parseInt(r,10),null,"rotate(".concat(o.config.xaxis.labels.rotate," 0 0)"),!1):f.getTextRects(l,parseInt(r,10));var v=!o.config.xaxis.labels.showDuplicates&&this.ctx.timeScale;return!Array.isArray(l)&&(0===l.indexOf("NaN")||0===l.toLowerCase().indexOf("invalid")||l.toLowerCase().indexOf("infinity")>=0||s.indexOf(l)>=0&&v)&&(l=""),{x:i,text:l,textRect:x,isBold:d}}},{key:"checkLabelBasedOnTickamount",value:function(t,e,i){var a=this.w,s=a.config.xaxis.tickAmount;return"dataPoints"===s&&(s=Math.round(a.globals.gridWidth/120)),s>i||t%Math.round(i/(s+1))==0||(e.text=""),e}},{key:"checkForOverflowingLabels",value:function(t,e,i,a,s){var r=this.w;if(0===t&&r.globals.skipFirstTimelinelabel&&(e.text=""),t===i-1&&r.globals.skipLastTimelinelabel&&(e.text=""),r.config.xaxis.labels.hideOverlappingLabels&&a.length>0){var o=s[s.length-1];e.x<o.textRect.width/(r.globals.rotateXLabels?Math.abs(r.config.xaxis.labels.rotate)/12:1.01)+o.x&&(e.text="")}return e}},{key:"checkForReversedLabels",value:function(t,e){var i=this.w;return i.config.yaxis[t]&&i.config.yaxis[t].reversed&&e.reverse(),e}},{key:"isYAxisHidden",value:function(t){var e=this.w,i=new y(this.ctx);return!e.config.yaxis[t].show||!e.config.yaxis[t].showForNullSeries&&i.isSeriesNull(t)&&-1===e.globals.collapsedSeriesIndices.indexOf(t)}},{key:"getYAxisForeColor",value:function(t,e){var i=this.w;return Array.isArray(t)&&i.globals.yAxisScale[e]&&this.ctx.theme.pushExtraColors(t,i.globals.yAxisScale[e].result.length,!1),t}},{key:"drawYAxisTicks",value:function(t,e,i,a,s,r,o){var n=this.w,l=new b(this.ctx),h=n.globals.translateY;if(a.show&&e>0){!0===n.config.yaxis[s].opposite&&(t+=a.width);for(var c=e;c>=0;c--){var d=h+e/10+n.config.yaxis[s].labels.offsetY-1;n.globals.isBarHorizontal&&(d=r*c),"heatmap"===n.config.chart.type&&(d+=r/2);var g=l.drawLine(t+i.offsetX-a.width+a.offsetX,d+a.offsetY,t+i.offsetX+a.offsetX,d+a.offsetY,a.color);o.add(g),h+=r}}}}]),t}(),V=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w}return r(t,[{key:"scaleSvgNode",value:function(t,e){var i=parseFloat(t.getAttributeNS(null,"width")),a=parseFloat(t.getAttributeNS(null,"height"));t.setAttributeNS(null,"width",i*e),t.setAttributeNS(null,"height",a*e),t.setAttributeNS(null,"viewBox","0 0 "+i+" "+a)}},{key:"fixSvgStringForIe11",value:function(t){if(!p.isIE11())return t.replace(/&nbsp;/g,"&#160;");var e=0,i=t.replace(/xmlns="http:\/\/www.w3.org\/2000\/svg"/g,(function(t){return 2===++e?'xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.dev"':t}));return i=(i=i.replace(/xmlns:NS\d+=""/g,"")).replace(/NS\d+:(\w+:\w+=")/g,"$1")}},{key:"getSvgString",value:function(t){var e=this.w.globals.dom.Paper.svg();if(1!==t){var i=this.w.globals.dom.Paper.node.cloneNode(!0);this.scaleSvgNode(i,t),e=(new XMLSerializer).serializeToString(i)}return this.fixSvgStringForIe11(e)}},{key:"cleanup",value:function(){var t=this.w,e=t.globals.dom.baseEl.getElementsByClassName("apexcharts-xcrosshairs"),i=t.globals.dom.baseEl.getElementsByClassName("apexcharts-ycrosshairs"),a=t.globals.dom.baseEl.querySelectorAll(".apexcharts-zoom-rect, .apexcharts-selection-rect");Array.prototype.forEach.call(a,(function(t){t.setAttribute("width",0)})),e&&e[0]&&(e[0].setAttribute("x",-500),e[0].setAttribute("x1",-500),e[0].setAttribute("x2",-500)),i&&i[0]&&(i[0].setAttribute("y",-100),i[0].setAttribute("y1",-100),i[0].setAttribute("y2",-100))}},{key:"svgUrl",value:function(){this.cleanup();var t=this.getSvgString(),e=new Blob([t],{type:"image/svg+xml;charset=utf-8"});return URL.createObjectURL(e)}},{key:"dataURI",value:function(t){var e=this;return new Promise((function(i){var a=e.w,s=t?t.scale||t.width/a.globals.svgWidth:1;e.cleanup();var r=document.createElement("canvas");r.width=a.globals.svgWidth*s,r.height=parseInt(a.globals.dom.elWrap.style.height,10)*s;var o="transparent"===a.config.chart.background?"#fff":a.config.chart.background,n=r.getContext("2d");n.fillStyle=o,n.fillRect(0,0,r.width*s,r.height*s);var l=e.getSvgString(s);if(window.canvg&&p.isIE11()){var h=window.canvg.Canvg.fromString(n,l,{ignoreClear:!0,ignoreDimensions:!0});h.start();var c=r.msToBlob();h.stop(),i({blob:c})}else{var d="data:image/svg+xml,"+encodeURIComponent(l),g=new Image;g.crossOrigin="anonymous",g.onload=function(){if(n.drawImage(g,0,0),r.msToBlob){var t=r.msToBlob();i({blob:t})}else{var e=r.toDataURL("image/png");i({imgURI:e})}},g.src=d}}))}},{key:"exportToSVG",value:function(){this.triggerDownload(this.svgUrl(),this.w.config.chart.toolbar.export.svg.f
61903ilename,".svg")}},{key:"exportToPng",value:function(){var t=this;this.dataURI().then((function(e){var i=e.imgURI,a=e.blob;a?navigator.msSaveOrOpenBlob(a,t.w.globals.chartID+".png"):t.triggerDownload(i,t.w.config.chart.toolbar.export.png.filename,".png")}))}},{key:"exportToCSV",value:function(t){var e=this,i=t.series,a=t.columnDelimiter,s=t.lineDelimiter,r=void 0===s?"\n":s,o=this.w,n=[],l=[],h="",c=new O(this.ctx),d=new B(this.ctx),g=function(t){var i="";if(o.globals.axisCharts){if("category"===o.config.xaxis.type||o.config.xaxis.convertedCatToNumeric)if(o.globals.isBarHorizontal){var s=o.globals.yLabelFormatters[0],r=new z(e.ctx).getActiveConfigSeriesIndex();i=s(o.globals.labels[t],{seriesIndex:r,dataPointIndex:t,w:o})}else i=d.getLabel(o.globals.labels,o.globals.timescaleLabels,0,t).text;"datetime"===o.config.xaxis.type&&(o.config.xaxis.categories.length?i=o.config.xaxis.categories[t]:o.config.labels.length&&(i=o.config.labels[t]))}else i=o.config.labels[t];return Array.isArray(i)&&(i=i.join(" ")),p.isNumber(i)?i:i.split(a).join("")};n.push(o.config.chart.toolbar.export.csv.headerCategory),i.map((function(t,e){var i=t.name?t.name:"series-".concat(e);o.globals.axisCharts&&n.push(i.split(a).join("")?i.split(a).join(""):"series-".concat(e))})),o.globals.axisCharts||(n.push(o.config.chart.toolbar.export.csv.headerValue),l.push(n.join(a))),i.map((function(t,e){o.globals.axisCharts?function(t,e){if(n.length&&0===e&&l.push(n.join(a)),t.data&&t.data.length)for(var s=0;s<t.data.length;s++){n=[];var r=g(s);if(r||(c.isFormatXY()?r=i[e].data[s].x:c.isFormat2DArray()&&(r=i[e].data[s]?i[e].data[s][0]:"")),0===e){n.push((d=r,"datetime"===o.config.xaxis.type&&String(d).length>=10?o.config.chart.toolbar.export.csv.dateFormatter(r):p.isNumber(r)?r:r.split(a).join("")));for(var h=0;h<o.globals.series.length;h++)n.push(o.globals.series[h][s])}("candlestick"===o.config.chart.type||t.type&&"candlestick"===t.type)&&(n.pop(),n.push(o.globals.seriesCandleO[e][s]),n.push(o.globals.seriesCandleH[e][s]),n.push(o.globals.seriesCandleL[e][s]),n.push(o.globals.seriesCandleC[e][s])),("boxPlot"===o.config.chart.type||t.type&&"boxPlot"===t.type)&&(n.pop(),n.push(o.globals.seriesCandleO[e][s]),n.push(o.globals.seriesCandleH[e][s]),n.push(o.globals.seriesCandleM[e][s]),n.push(o.globals.seriesCandleL[e][s]),n.push(o.globals.seriesCandleC[e][s])),"rangeBar"===o.config.chart.type&&(n.pop(),n.push(o.globals.seriesRangeStart[e][s]),n.push(o.globals.seriesRangeEnd[e][s])),n.length&&l.push(n.join(a))}var d}(t,e):((n=[]).push(o.globals.labels[e].split(a).join("")),n.push(o.globals.series[e]),l.push(n.join(a)))})),h+=l.join(r),this.triggerDownload("data:text/csv; charset=utf-8,"+encodeURIComponent("\ufeff"+h),o.config.chart.toolbar.export.csv.filename,".csv")}},{key:"triggerDownload",value:function(t,e,i){var a=document.createElement("a");a.href=t,a.download=(e||this.w.globals.chartID)+i,document.body.appendChild(a),a.click(),document.body.removeChild(a)}}]),t}(),G=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w;var i=this.w;this.axesUtils=new B(e),this.xaxisLabels=i.globals.labels.slice(),i.globals.timescaleLabels.length>0&&!i.globals.isBarHorizontal&&(this.xaxisLabels=i.globals.timescaleLabels.slice()),i.config.xaxis.overwriteCategories&&(this.xaxisLabels=i.config.xaxis.overwriteCategories),this.drawnLabels=[],this.drawnLabelsRects=[],"top"===i.config.xaxis.position?this.offY=0:this.offY=i.globals.gridHeight+1,this.offY=this.offY+i.config.xaxis.axisBorder.offsetY,this.isCategoryBarHorizontal="bar"===i.config.chart.type&&i.config.plotOptions.bar.horizontal,this.xaxisFontSize=i.config.xaxis.labels.style.fontSize,this.xaxisFontFamily=i.config.xaxis.labels.style.fontFamily,this.xaxisForeColors=i.config.xaxis.labels.style.colors,this.xaxisBorderWidth=i.config.xaxis.axisBorder.width,this.isCategoryBarHorizontal&&(this.xaxisBorderWidth=i.config.yaxis[0].axisBorder.width.toString()),this.xaxisBorderWidth.indexOf("%")>-1?this.xaxisBorderWidth=i.globals.gridWidth*parseInt(this.xaxisBorderWidth,10)/100:this.xaxisBorderWidth=parseInt(this.xaxisBorderWidth,10),this.xaxisBorderHeight=i.config.xaxis.axisBorder.height,this.yaxis=i.config.yaxis[0]}return r(t,[{key:"drawXaxis",value:function(){var t,e=this,i=this.w,a=new b(this.ctx),s=a.group({class:"apexcharts-xaxis",transform:"translate(".concat(i.config.xaxis.offsetX,", ").concat(i.config.xaxis.offsetY,")")}),r=a.group({class:"apexcharts-xaxis-texts-g",transform:"translate(".concat(i.globals.translateXAxisX,", ").concat(i.globals.translateXAxisY,")")});s.add(r);for(var o=i.globals.padHorizontal,n=[],l=0;l<this.xaxisLabels.length;l++)n.push(this.xaxisLabels[l]);var h=n.length;if(i.globals.isXNumeric){var c=h>1?h-1:h;t=i.globals.gridWidth/c,o=o+t/2+i.config.xaxis.labels.offsetX}else t=i.globals.gridWidth/n.length,o=o+t+i.config.xaxis.labels.offsetX;for(var d=function(s){var l=o-t/2+i.config.xaxis.labels.offsetX;0===s&&1===h&&t/2===o&&1===i.globals.dataPoints&&(l=i.globals.gridWidth/2);var c=e.axesUtils.getLabel(n,i.globals.timescaleLabels,l,s,e.drawnLabels,e.xaxisFontSize),d=28;i.globals.rotateXLabels&&(d=22);if((c=void 0!==i.config.xaxis.tickAmount&&"dataPoints"!==i.config.xaxis.tickAmount&&"datetime"!==i.config.xaxis.type?e.axesUtils.checkLabelBasedOnTickamount(s,c,h):e.axesUtils.checkForOverflowingLabels(s,c,h,e.drawnLabels,e.drawnLabelsRects)).text&&i.globals.xaxisLabelsCount++,i.c
vendor: 5,412 bytes, line 61903
61903onfig.xaxis.labels.show){var g=a.drawText({x:c.x,y:e.offY+i.config.xaxis.labels.offsetY+d-("top"===i.config.xaxis.position?i.globals.xAxisHeight+i.config.xaxis.axisTicks.height-2:0),text:c.text,textAnchor:"middle",fontWeight:c.isBold?600:i.config.xaxis.labels.style.fontWeight,fontSize:e.xaxisFontSize,fontFamily:e.xaxisFontFamily,foreColor:Array.isArray(e.xaxisForeColors)?i.config.xaxis.convertedCatToNumeric?e.xaxisForeColors[i.globals.minX+s-1]:e.xaxisForeColors[s]:e.xaxisForeColors,isPlainText:!1,cssClass:"apexcharts-xaxis-label "+i.config.xaxis.labels.style.cssClass});r.add(g);var u=document.createElementNS(i.globals.SVGNS,"title");u.textContent=Array.isArray(c.text)?c.text.join(" "):c.text,g.node.appendChild(u),""!==c.text&&(e.drawnLabels.push(c.text),e.drawnLabelsRects.push(c))}o+=t},g=0;g<=h-1;g++)d(g);if(void 0!==i.config.xaxis.title.text){var u=a.group({class:"apexcharts-xaxis-title"}),p=a.drawText({x:i.globals.gridWidth/2+i.config.xaxis.title.offsetX,y:this.offY+parseFloat(this.xaxisFontSize)+i.globals.xAxisLabelsHeight+i.config.xaxis.title.offsetY,text:i.config.xaxis.title.text,textAnchor:"middle",fontSize:i.config.xaxis.title.style.fontSize,fontFamily:i.config.xaxis.title.style.fontFamily,fontWeight:i.config.xaxis.title.style.fontWeight,foreColor:i.config.xaxis.title.style.color,cssClass:"apexcharts-xaxis-title-text "+i.config.xaxis.title.style.cssClass});u.add(p),s.add(u)}if(i.config.xaxis.axisBorder.show){var f=i.globals.barPadForNumericAxis,x=a.drawLine(i.globals.padHorizontal+i.config.xaxis.axisBorder.offsetX-f,this.offY,this.xaxisBorderWidth+f,this.offY,i.config.xaxis.axisBorder.color,0,this.xaxisBorderHeight);s.add(x)}return s}},{key:"drawXaxisInversed",value:function(t){var e,i,a=this,s=this.w,r=new b(this.ctx),o=s.config.yaxis[0].opposite?s.globals.translateYAxisX[t]:0,n=r.group({class:"apexcharts-yaxis apexcharts-xaxis-inversed",rel:t}),l=r.group({class:"apexcharts-yaxis-texts-g apexcharts-xaxis-inversed-texts-g",transform:"translate("+o+", 0)"});n.add(l);var h=[];if(s.config.yaxis[t].show)for(var c=0;c<this.xaxisLabels.length;c++)h.push(this.xaxisLabels[c]);e=s.globals.gridHeight/h.length,i=-e/2.2;var d=s.globals.yLabelFormatters[0],g=s.config.yaxis[0].labels;if(g.show)for(var u=function(o){var n=void 0===h[o]?"":h[o];n=d(n,{seriesIndex:t,dataPointIndex:o,w:s});var c=a.axesUtils.getYAxisForeColor(g.style.colors,t),u=0;Array.isArray(n)&&(u=n.length/2*parseInt(g.style.fontSize,10));var p=r.drawText({x:g.offsetX-15,y:i+e+g.offsetY-u,text:n,textAnchor:a.yaxis.opposite?"start":"end",foreColor:Array.isArray(c)?c[o]:c,fontSize:g.style.fontSize,fontFamily:g.style.fontFamily,fontWeight:g.style.fontWeight,isPlainText:!1,cssClass:"apexcharts-yaxis-label "+g.style.cssClass});l.add(p);var f=document.createElementNS(s.globals.SVGNS,"title");if(f.textContent=Array.isArray(n)?n.join(" "):n,p.node.appendChild(f),0!==s.config.yaxis[t].labels.rotate){var x=r.rotateAroundCenter(p.node);p.node.setAttribute("transform","rotate(".concat(s.config.yaxis[t].labels.rotate," 0 ").concat(x.y,")"))}i+=e},p=0;p<=h.length-1;p++)u(p);if(void 0!==s.config.yaxis[0].title.text){var f=r.group({class:"apexcharts-yaxis-title apexcharts-xaxis-title-inversed",transform:"translate("+o+", 0)"}),x=r.drawText({x:0,y:s.globals.gridHeight/2,text:s.config.yaxis[0].title.text,textAnchor:"middle",foreColor:s.config.yaxis[0].title.style.color,fontSize:s.config.yaxis[0].title.style.fontSize,fontWeight:s.config.yaxis[0].title.style.fontWeight,fontFamily:s.config.yaxis[0].title.style.fontFamily,cssClass:"apexcharts-yaxis-title-text "+s.config.yaxis[0].title.style.cssClass});f.add(x),n.add(f)}var v=0;this.isCategoryBarHorizontal&&s.config.yaxis[0].opposite&&(v=s.globals.gridWidth);var m=s.config.xaxis.axisBorder;if(m.show){var y=r.drawLine(s.globals.padHorizontal+m.offsetX+v,1+m.offsetY,s.globals.padHorizontal+m.offsetX+v,s.globals.gridHeight+m.offsetY,m.color,0);n.add(y)}return s.config.yaxis[0].axisTicks.show&&this.axesUtils.drawYAxisTicks(v,h.length,s.config.yaxis[0].axisBorder,s.config.yaxis[0].axisTicks,0,e,n),n}},{key:"drawXaxisTicks",value:function(t,e){var i=this.w,a=t;if(!(t<0||t-2>i.globals.gridWidth)){var s=this.offY+i.config.xaxis.axisTicks.offsetY,r=s+i.config.xaxis.axisTicks.height;if("top"===i.config.xaxis.position&&(r=s-i.config.xaxis.axisTicks.height),i.config.xaxis.axisTicks.show){var o=new b(this.ctx).drawLine(t+i.config.xaxis.axisTicks.offsetX,s+i.config.xaxis.offsetY,a+i.config.xaxis.axisTicks.offsetX,r+i.config.xaxis.offsetY,i.config.xaxis.axisTicks.color);e.add(o),o.node.classList.add("apexcharts-xaxis-tick")}}}},{key:"getXAxisTicksPositions",value:function(){var t=this.w,e=[],i=this.xaxisLabels.length,a=t.globals.padHorizontal;if(t.globals.timescaleLabels.length>0)for(var s=0;s<i;s++)a=this.xaxisLabels[s].position,e.push(a);else for(var r=i,o=0;o<r;o++){var n=r;t.globals.isXNumeric&&"bar"!==t.config.chart.type&&(n-=1),a+=t.globals.gridWidth/n,e.push(a)}return e}},{key:"xAxisLabelCorrections",value:function(){var t=this.w,e=new b(this.ctx),i=t.globals.dom.baseEl.querySelector(".apexcharts-xaxis-texts-g"),a=t.globals.dom.baseEl.querySelectorAll(".apexcharts-xaxis-texts-g text"),s=t.globals.dom.baseEl.querySelectorAll(".apexcharts-yaxis-inversed text"),r=t.globals.dom.baseEl.querySelectorAll(".apexcharts-xaxis-inversed-texts-g text tspan");if(t.globals.rotateXLabels||t.config.xaxis.labels.rotateAlways)for(var o=0;o<a.length;
61903o++){var n=e.rotateAroundCenter(a[o]);n.y=n.y-1,n.x=n.x+1,a[o].setAttribute("transform","rotate(".concat(t.config.xaxis.labels.rotate," ").concat(n.x," ").concat(n.y,")")),a[o].setAttribute("text-anchor","end");i.setAttribute("transform","translate(0, ".concat(-10,")"));var l=a[o].childNodes;t.config.xaxis.labels.trim&&Array.prototype.forEach.call(l,(function(i){e.placeTextWithEllipsis(i,i.textContent,t.globals.xAxisLabelsHeight-("bottom"===t.config.legend.position?20:10))}))}else!function(){for(var i=t.globals.gridWidth/(t.globals.labels.length+1),s=0;s<a.length;s++){var r=a[s].childNodes;t.config.xaxis.labels.trim&&"datetime"!==t.config.xaxis.type&&Array.prototype.forEach.call(r,(function(t){e.placeTextWithEllipsis(t,t.textContent,i)}))}}();if(s.length>0){var h=s[s.length-1].getBBox(),c=s[0].getBBox();h.x<-20&&s[s.length-1].parentNode.removeChild(s[s.length-1]),c.x+c.width>t.globals.gridWidth&&!t.globals.isBarHorizontal&&s[0].parentNode.removeChild(s[0]);for(var d=0;d<r.length;d++)e.placeTextWithEllipsis(r[d],r[d].textContent,t.config.yaxis[0].labels.maxWidth-2*parseFloat(t.config.yaxis[0].title.style.fontSize)-20)}}}]),t}(),_=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w;var i=this.w;this.xaxisLabels=i.globals.labels.slice(),this.axesUtils=new B(e),this.isRangeBar=i.globals.seriesRangeBar.length,i.globals.timescaleLabels.length>0&&(this.xaxisLabels=i.globals.timescaleLabels.slice())}return r(t,[{key:"drawGridArea",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,e=this.w,i=new b(this.ctx);null===t&&(t=i.group({class:"apexcharts-grid"}));var a=i.drawLine(e.globals.padHorizontal,1,e.globals.padHorizontal,e.globals.gridHeight,"transparent"),s=i.drawLine(e.globals.padHorizontal,e.globals.gridHeight,e.globals.gridWidth,e.globals.gridHeight,"transparent");return t.add(s),t.add(a),t}},{key:"drawGrid",value:function(){var t=null;return this.w.globals.axisCharts&&(t=this.renderGrid(),this.drawGridArea(t.el)),t}},{key:"createGridMask",value:function(){var t=this.w,e=t.globals,i=new b(this.ctx),a=Array.isArray(t.config.stroke.width)?0:t.config.stroke.width;if(Array.isArray(t.config.stroke.width)){var s=0;t.config.stroke.width.forEach((function(t){s=Math.max(s,t)})),a=s}e.dom.elGridRectMask=document.createElementNS(e.SVGNS,"clipPath"),e.dom.elGridRectMask.setAttribute("id","gridRectMask".concat(e.cuid)),e.dom.elGridRectMarkerMask=document.createElementNS(e.SVGNS,"clipPath"),e.dom.elGridRectMarkerMask.setAttribute("id","gridRectMarkerMask".concat(e.cuid)),e.dom.elForecastMask=document.createElementNS(e.SVGNS,"clipPath"),e.dom.elForecastMask.setAttribute("id","forecastMask".concat(e.cuid)),e.dom.elNonForecastMask=document.createElementNS(e.SVGNS,"clipPath"),e.dom.elNonForecastMask.setAttribute("id","nonForecastMask".concat(e.cuid));var r=t.config.chart.type,o=0,n=0;("bar"===r||"rangeBar"===r||"candlestick"===r||"boxPlot"===r||t.globals.comboBarCount>
619030)&&t.globals.isXNumeric&&!t.globals.isBarHorizontal&&(o=t.config.grid.padding.left,n=t.config.grid.padding.right,e.barPadForNumericAxis>o&&(o=e.barPadForNumericAxis,n=e.barPadForNumericAxis)),e.dom.elGridRect=i.drawRect(-a/2-o-2,-a/2,e.gridWidth+a+n+o+4,e.gridHeight+a,0,"#fff"),new y(this).getLargestMarkerSize();var l=t.globals.markers.largestSize+1;e.dom.elGridRectMarker=i.drawRect(2*-l,2*-l,e.gridWidth+4*l,e.gridHeight+4*l,0,"#fff"),e.dom.elGridRectMask.appendChild(e.dom.elGridRect.node),e.dom.elGridRectMarkerMask.appendChild(e.dom.elGridRectMarker.node);var h=e.dom.baseEl.querySelector("defs");h.appendChild(e.dom.elGridRectMask),h.appendChild(e.dom.elForecastMask),h.appendChild(e.dom.elNonForecastMask),h.appendChild(e.dom.elGridRectMarkerMask)}},{key:"_drawGridLines",value:function(t){var e=t.i,i=t.x1,a=t.y1,s=t.x2,r=t.y2,o=t.xCount,n=t.parent,l=this.w;0===e&&l.globals.skipFirstTimelinelabel||e===o-1&&l.globals.skipLastTimelinelabel&&!l.config.xaxis.labels.formatter||"radar"===l.config.chart.type||(l.config.grid.xaxis.lines.show&&this._drawGridLine({x1:i,y1:a,x2:s,y2:r,parent:n}),new G(this.ctx).drawXaxisTicks(i,this.elg))}},{key:"_drawGridLine",value:function(t){var e=t.x1,i=t.y1,a=t.x2,s=t.y2,r=t.parent,o=this.w,n=r.node.classList.contains("apexcharts-gridlines-horizontal"),l=o.config.grid.strokeDashArray,h=o.globals.barPadForNumericAxis,c=new b(this).drawLine(e-(n?h:0),i,a+(n?h:0),s,o.config.grid.borderColor,l);c.node.classList.add("apexcharts-gridline"),r.add(c)}},{key:"_drawGridBandRect",value:function(t){var e=t.c,i=t.x1,a=t.y1,s=t.x2,r=t.y2,o=t.type,n=this.w,l=new b(this.ctx),h=n.globals.barPadForNumericAxis;if("column"!==o||"datetime"!==n.config.xaxis.type){var c=n.config.grid[o].colors[e],d=l.drawRect(i-("row"===o?h:0),a,s+("row"===o?2*h:0),r,0,c,n.config.grid[o].opacity);this.elg.add(d),d.attr("clip-path","url(#gridRectMask".concat(n.globals.cuid,")")),d.node.classList.add("apexcharts-grid-".concat(o))}}},{key:"_drawXYLines",value:function(t){var e=this,i=t.xCount,a=t.tickAmount,s=this.w;if(s.config.grid.xaxis.lines.show||s.config.xaxis.axisTicks.show){var r,o=s.globals.padHorizontal,n=s.globals.gridHeight;s.globals.timescaleLabels.length?function(t){for(var a=t.xC,s=t.x1,r=t.y1,o=t.x2,n=t.y2,l=0;l<a;l++)s=e.xaxisLabels[l].position,o=e.xaxisLabels[l].position,e._drawGridLines({i:l,x1:s,y1:r,x2:o,y2:n,xCount:i,parent:e.elgridLinesV})}({xC:i,x1:o,y1:0,x2:r,y2:n}):(s.globals.isXNumeric&&(i=s.globals.xAxisScale.result.length),s.config.xaxis.convertedCatToNumeric&&(i=s.globals.xaxisLabelsCount),function(t){var a=t.xC,r=t.x1,o=t.y1,n=t.x2,l=t.y2;if(void 0!==s.config.xaxis.tickAmount&&"dataPoints"!==s.config.xaxis.tickAmount)s.globals.dom.baseEl.querySelectorAll(".apexcharts-text.apexcharts-xaxis-label tspan:not(:empty)").forEach((function(t,a){var s=t.getBBox();e._drawGridLines({i:a,x1:s.x+s.width/2,y1:o,x2:s.x+s.width/2,y2:l,xCount:i,parent:e.elgridLinesV})}));else for(var h=0;h<a+(s.globals.isXNumeric?0:1);h++)0===h&&1===a&&1===s.globals.dataPoints&&(n=r=s.globals.gridWidth/2),e._drawGridLines({i:h,x1:r,y1:o,x2:n,y2:l,xCount:i,parent:e.elgridLinesV}),n=r+=s.globals.gridWidth/(s.globals.isXNumeric?a-1:a)}({xC:i,x1:o,y1:0,x2:r,y2:n}))}if(s.config.grid.yaxis.lines.show){var l=0,h=0,c=s.globals.gridWidth,d=a+1;this.isRangeBar&&(d=s.globals.labels.length);for(var g=0;g<d+(this.isRangeBar?1:0);g++)this._drawGridLine({x1:0,y1:l,x2:c,y2:h,parent:this.elgridLinesH}),h=l+=s.globals.gridHeight/(this.isRangeBar?d:a)}}},{key:"_drawInvertedXYLines",value:function(t){var e=t.xCount,i=this.w;if(i.config.grid.xaxis.lines.show||i.config.xaxis.axisTicks.show)for(var a,s=i.globals.padHorizontal,r=i.globals.gridHeight,o=0;o<e+1;o++){i.config.grid.xaxis.lines.show&&this._drawGridLine({x1:s,y1:0,x2:a,y2:r,parent:this.elgridLinesV}),new G(this.ctx).drawXaxisTicks(s,this.elg),a=s=s+i.globals.gridWidth/e+.3}if(i.config.grid.yaxis.lines.show)for(var n=0,l=0,h=i.globals.gridWidth,c=0;c<i.globals.dataPoints+1;c++)this._drawGridLine({x1:0,y1:n,x2:h,y2:l,parent:this.elgridLinesH}),l=n+=i.globals.gridHeight/i.globals.dataPoints}},{key:"renderGrid",value:function(){var t=this.w,e=new b(this.ctx);this.elg=e.group({class:"apexcharts-grid"}
61903),this.elgridLinesH=e.group({class:"apexcharts-gridlines-horizontal"}),this.elgridLinesV=e.group({class:"apexcharts-gridlines-vertical"}),this.elg.add(this.elgridLinesH),this.elg.add(this.elgridLinesV),t.config.grid.show||(this.elgridLinesV.hide(),this.elgridLinesH.hide());for(var i,a=t.globals.yAxisScale.length?t.globals.yAxisScale[0].result.length-1:5,s=0;s<t.globals.series.length&&(void 0!==t.globals.yAxisScale[s]&&(a=t.globals.yAxisScale[s].result.length-1),!(a>2));s++);return!t.globals.isBarHorizontal||this.isRangeBar?(i=this.xaxisLabels.length,this.isRangeBar&&(a=t.globals.labels.length,t.config.xaxis.tickAmount&&t.config.xaxis.labels.formatter&&(i=t.config.xaxis.tickAmount)),this._drawXYLines({xCount:i,tickAmount:a})):(i=a,a=t.globals.xTickAmount,this._drawInvertedXYLines({xCount:i,tickAmount:a})),this.drawGridBands(i,a),{el:this.elg,xAxisTickWidth:t.globals.gridWidth/i}}},{key:"drawGridBands",value:function(t,e){var i=this.w;if(void 0!==i.config.grid.row.colors&&i.config.grid.row.colors.length>0)for(var a=0,s=i.globals.gridHeight/e,r=i.globals.gridWidth,o=0,n=0;o<e;o++,n++)n>=i.config.grid.row.colors.length&&(n=0),this._drawGridBandRect({c:n,x1:0,y1:a,x2:r,y2:s,type:"row"}),a+=i.globals.gridHeight/e;if(void 0!==i.config.grid.column.colors&&i.config.grid.column.colors.length>0)for(var l=i.globals.isBarHorizontal||"category"!==i.config.xaxis.type&&!i.config.xaxis.convertedCatToNumeric?t:t-1,h=i.globals.padHorizontal,c=i.globals.padHorizontal+i.globals.gridWidth/l,d=i.globals.gridHeight,g=0,u=0;g<t;g++,u++)u>=i.config.grid.column.colors.length&&(u=0),this._drawGridBandRect({c:u,x1:h,y1:0,x2:c,y2:d,type:"column"}),h+=i.globals.gridWidth/l}}]),t}(),j=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w}return r(t,[{key:"niceScale",value:function(t,e){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:10,a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0,s=arguments.length>4?arguments[4]:void 0,r=this.w,o=Math.abs(e-t);if("dataPoints"===(i=this._adjustTicksForSmallRange(i,a,o))&&(i=r.globals.dataPoints-1),t===Number.MIN_VALUE&&0===e||!p.isNumber(t)&&!p.isNumber(e)||t===Number.MIN_VALUE&&e===-Number.MAX_VALUE){t=0,e=i;var n=this.linearScale(t,e,i);return n}t>e?(console.warn("axis.min cannot be greater than axis.max"),e=t+.1):t===e&&(t=0===t?0:t-.5,e=0===e?2:e+.5);var l=[];o<1&&s&&("candlestick"===r.config.chart.type||"candlestick"===r.config.series[a].type||"boxPlot"===r.config.chart.type||"boxPlot"===r.config.series[a].type||r.globals.isRangeData)&&(e*=1.01);var h=i+1;h<2?h=2:h>2&&(h-=2);var c=o/h,d=Math.floor(p.log10(c)),g=Math.pow(10,d),u=Math.round(c/g);u<1&&(u=1);var f=u*g,x=f*Math.floor(t/f),b=f*Math.ceil(e/f),v=x;if(s&&o>2){for(;l.push(v),!((v+=f)>b););return{result:l,niceMin:l[0],niceMax:l[l.length-1]}}var m=t;(l=[]).push(m);for(var y=Math.abs(e-t)/i,w=0;w<=i;w++)m+=y,l.push(m);return l[l.length-2]>=e&&l.pop(),{result:l,niceMin:l[0],niceMax:l[l.length-1]}}},{key:"linearScale",value:function(t,e){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:10,a=arguments.length>3?arguments[3]:void 0,s=Math.abs(e-t);"dataPoints"===(i=this._adjustTicksForSmallRange(i,a,s))&&(i=this.w.globals.dataPoints-1);var r=s/i;i===Number.MAX_VALUE&&(i=10,r=1);for(var o=[],n=t;i>=0;)o.push(n),n+=r,i-=1;return{result:o,niceMin:o[0],niceMax:o[o.length-1]}}},{key:"logarithmicScale",value:function(t,e,i){for(var a=[],s=Math.ceil(Math.log(e)/Math.log(i))+1,r=0;r<s;r++)a.push(Math.pow(i,r));return 0===t&&a.unshift(t),{result:a,niceMin:a[0],niceMax:a[a.length-1]}}},{key:"_adjustTicksForSmallRange",value:function(t,e,i){var a=t;if(void 0!==e&&this.w.config.yaxis[e].labels.formatter&&void 0===this.w.config.yaxis[e].tickAmount){var s=this.w.config.yaxis[e].labels.formatter(1);p.isNumber(Number(s))&&!p.isFloat(s)&&(a=Math.ceil(i))}return a<t?a:t}},{key:"setYScaleForIndex",value:function(t,e,i){var a=this.w.globals,s=this.w.config,r=a.isBarHorizontal?s.xaxis:s.yaxis[t];void 0===a.yAxisScale[t]&&(a.yAxisScale[t]=[]);var o=Math.abs(i-e);if(r.logarithmic&&o<=5&&(a.invalidLogScale=!0),r.logarithmic&&o>5)a.allSeriesCollapsed=!1,a.yAxisScale[t]=this.logarithmicScale(e,i,r.logBase);else if(i!==-Number.MAX_VALUE&&p.isNumber(i))if(a.allSeriesCollapsed=!1,void 0===r.min&&void 0===r.max||r.forceNiceScale){var n=void 0===s.yaxis[t].max&&void 0===s.yaxis[t].min||s.yaxis[t].forceNiceScale;a.yAxisScale[t]=this.niceScale(e,i,r.tickAmount?r.tickAmount:o<5&&o>1?o+1:5,t,n)}else a.yAxisScale[t]=this.linearScale(e,i,r.tickAmount,t);else a.yAxisScale[t]=this.linearScale(0,5,5)}},{key:"setXScale",value:function(t,e){var i=this.w,a=i.globals,s=i.config.xaxis,r=Math.abs(e-t);return e!==-Number.MAX_VALUE&&p.isNumber(e)?a.xAxisScale=this.linearScale(t,e,s.tickAmount?s.tickAmount:r<5&&r>1?r+1:5,0):a.xAxisScale=this.linearScale(0,5,5),a.xAxisScale}},{key:"setMultipleYScales",value:function(){var t=this,e=this.w.globals,i=this.w.config,a=e.minYArr.concat([]),s=e.maxYArr.concat([]),r=[];i.yaxis.forEach((function(e,o){var n=o;
61903i.series.forEach((function(t,i){t.name===e.seriesName&&(n=i,o!==i?r.push({index:i,similarIndex:o,alreadyExists:!0}):r.push({index:i}))}));var l=a[n],h=s[n];t.setYScaleForIndex(o,l,h)})),this.sameScaleInMultipleAxes(a,s,r)}},{key:"sameScaleInMultipleAxes",value:function(t,e,i){var a=this,s=this.w.config,r=this.w.globals,o=[];i.forEach((function(t){t.alreadyExists&&(void 0===o[t.index]&&(o[t.index]=[]),o[t.index].push(t.index),o[t.index].push(t.similarIndex))})),r.yAxisSameScaleIndices=o,o.forEach((function(t,e){o.forEach((function(i,a){var s,r;e!==a&&(s=t,r=i,s.filter((function(t){return-1!==r.indexOf(t)}))).length>0&&(o[e]=o[e].concat(o[a]))}))}));var n=o.map((function(t){return t.filter((function(e,i){return t.indexOf(e)===i}))})).map((function(t){return t.sort()}));o=o.filter((function(t){return!!t}));var l=n.slice(),h=l.map((function(t){return JSON.stringify(t)}));l=l.filter((function(t,e){return h.indexOf(JSON.stringify(t))===e}));var c=[],d=[];t.forEach((function(t,i){l.forEach((function(a,s){a.indexOf(i)>-1&&(void 0===c[s]&&(c[s]=[],d[s]=[]),c[s].push({key:i,value:t}),d[s].push({key:i,value:e[i]}))}))}));var g=Array.apply(null,Array(l.length)).map(Number.prototype.valueOf,Number.MIN_VALUE),u=Array.apply(null,Array(l.length)).map(Number.prototype.valueOf,-Number.MAX_VALUE);c.forEach((function(t,e){t.forEach((function(t,i){g[e]=Math.min(t.value,g[e])}))})),d.forEach((function(t,e){t.forEach((function(t,i){u[e]=Math.max(t.value,u[e])}))})),t.forEach((function(t,e){d.forEach((function(t,i){var o=g[i],n=u[i];s.chart.stacked&&(n=0,t.forEach((function(t,e){t.value!==-Number.MAX_VALUE&&(n+=t.value),o!==Number.MIN_VALUE&&(o+=c[i][e].value)}))),t.forEach((function(i,l){t[l].key===e&&(void 0!==s.yaxis[e].min&&(o="function"==typeof s.yaxis[e].min?s.yaxis[e].min(r.minY):s.yaxis[e].min),void 0!==s.yaxis[e].max&&(n="function"==typeof s.yaxis[e].max?s.yaxis[e].max(r.maxY):s.yaxis[e].max),a.setYScaleForIndex(e,o,n))}))}))}))}},{key:"autoScaleY",value:function(t,e,i){t||(t=this);var a=t.w;if(a.globals.isMultipleYAxis||a.globals.collapsedSeries.length)return console.warn("autoScaleYaxis is not supported in a multi-yaxis chart."),e;var s=a.globals.seriesX[0],r=a.config.chart.stacked;return e.forEach((function(t,o){for(var n=0,l=0;l<s.length;l++)if(s[l]>=i.xaxis.min){n=l;break}var h,c,d=a.globals.minYArr[o],g=a.globals.maxYArr[o],u=a.globals.stackedSeriesTotals;a.globals.series.forEach((function(o,l){var p=o[n];r?(p=u[n],h=c=p,u.forEach((function(t,e){s[e]<=i.xaxis.max&&s[e]>=i.xaxis.min&&(t>c&&null!==t&&(c=t),o[e]<h&&null!==o[e]&&(h=o[e]))}))):(h=c=p,o.forEach((function(t,e){if(s[e]<=i.xaxis.max&&s[e]>=i.xaxis.min){var r=t,o=t;a.globals.series.forEach((function(i,a){null!==t&&(r=Math.min(i[e],r),o=Math.max(i[e],o))})),o>c&&null!==o&&(c=o),r<h&&null!==r&&(h=r)}}))),void 0===h&&void 0===c&&(h=d,c=g),(c*=c<0?.9:1.1)<0&&c<g&&(c=g),(h*=h<0?1.1:.9)<0&&h>d&&(h=d),e.length>1?(e[l].min=void 0===t.min?h:t.min,e[l].max=void 0===t.max?c:t.max):(e[0].min=void 0===t.min?h:t.min,e[0].max=void 0===t.max?c:t.max)}))})),e}}]),t}(),U=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w,this.scales=new j(e)}return r(t,[{key:"init",value:function(){this.setYRange(),this.setXRange(),this.setZRange()}},{key:"getMinYMaxY",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:Number.MAX_VALUE,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:-Number.MAX_VALUE,a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,s=this.w.config,r=this.w.globals,o=-Number.MAX_VALUE,n=Number.MIN_VALUE;null===a&&(a=t+1);var l=r.series,h=l,c=l;"candlestick"===s.chart.type?(h=r.seriesCandleL,c=r.seriesCandleH):"boxPlot"===s.chart.type?(h=r.seriesCandleO,c=r.seriesCandleC):r.isRangeData&&(h=r.seriesRangeStart,c=r.seriesRangeEnd);for(var d=t;d<a;d++){r.dataPoints=Math.max(r.dataPoints,l[d].length),r.categoryLabels.length&&(r.dataPoints=r.categoryLabels.filter((function(t){return void 0!==t})).length);for(var g=0;g<r.series[d].length;g++){var u=l[d][g];null!==u&&p.isNumber(u)?(void 0!==c[d][g]&&(o=Math.max(o,c[d][g]),e=Math.min(e,c[d][g])),void 0!==h[d][g]&&(e=Math.min(e,h[d][g]),i=Math.max(i,h[d][g])),"candlestick"!==this.w.config.chart.type&&"boxPlot"!==this.w.config.chart.type||(void 0!==r.seriesCandleC[d][g]&&(o=Math.max(o,r.seriesCandleO[d][g]),o=Math.max(o,r.seriesCandleH[d][g]),o=Math.max(o,r.seriesCandleL[d][g]),o=Math.max(o,r.seriesCandleC[d][g]),"boxPlot"===this.w.config.chart.type&&(o=Math.max(o,r.seriesCandleM[d][g]))),!s.series[d].type||"candlestick"===s.series[d].type&&"boxPlot"===s.series[d].type||(o=Math.max(o,r.series[d][g]),e=Math.min(e,r.series[d][g])),i=o),r.seriesGoals[d]&&r.seriesGoals[d][g]&&Array.isArray(r.seriesGoals[d][g])&&r.seriesGoals[d][g].forEach((function(t){n!==Number.MIN_VALUE&&(n=Math.min(n,t.value),e=n),o=Math.max(o,t.value),i=o})),p.isFloat(u)&&(u=p.noExponents(u),r.yValueDecimal=Math.max(r.yValueDecimal,u.toString().split(".")[1].length)),n>h[d][g]&&h[d][g]<0&&(n=h[d][g])):r.hasNullValues=!0}}return"rangeBar"===s.chart.type&&r.seriesRangeStart.length&&r.isBarHorizontal&&(n=e),"bar"===s.chart.type&&(n<0&&o<0&&(o=0),n===Number.MIN_VALUE&&(n=0)),{minY:n,maxY:o,lowestY:e,highestY:i}}},{key:"setYRange",value:function(){var t=this.w.globals,e=this.w.config;t.maxY=-Number.MAX_VALUE,t.minY=Number.MIN_VALUE;var i=Number.MAX_VALUE;if(t.isMultipleYAxis)for(var a=0;a<t.series.length;a++){var s=this.getMinYMaxY(a,i,null,a+1);t.minYArr.push(s.minY),t.maxYArr.push(s.maxY),i=s.lowestY}var r=this.getMinYMaxY(0,i,null,t.series.length);if(t.minY=r.minY,t.maxY=r.maxY,i=r.lowestY,e.chart.stacked&&this._setStackedMinMax(),("line"===e.chart.type||"area"===e.chart.type||"candlestick"===e.chart.type||"boxPlot"===e.chart.type||"rangeBar"===e.chart.type&&!t.isBarHorizontal)&&t.minY===Number.MIN_VALUE&&i!==-Number.MAX_VALUE&&i!==t.maxY){var o=t.maxY-i;(i>=0&&i<=10||void 0!==e.yaxis[0].min||void 0!==e.yaxis[0].max)&&(o=0),t.minY=i-5*o/100,i>0&&t.minY<0&&(t.minY=0),t.maxY=t.maxY+5*o/100}if(e.yaxis.forEach((function(e,i){void 0!==e.max&&("number"==typeof e.max?t.maxYArr[i]=e.max:"function"==typeof e.max&&(t.maxYArr[i]=e.max(t.isMultipleYAxis?t.maxYArr[i]:t.maxY)),t.maxY=t.maxYArr[i]),void 0!==e.min&&("number"==typeof e.min?t.minYArr[i]=e.min:"function"==typeof e.min&&(t.minYArr[i]=e.min(t.isMultipleYAxis?t.minYArr[i]===Number.MIN_VALUE?0:t.minYArr[i]:t.minY)),t.minY=t.minYArr[i])})),t.isBarHorizontal){["min","max"].forEach((function(i){void 0!==e.xaxis[i]&&"number"==typeof e.xaxis[i]&&("min"===i?t.minY=e.xaxis[i]:t.maxY=e.xaxis[i])}))}return t.isMultipleYAxis?(this.scales.setMultipleYScales(),t.minY=i,t.yAxisScale.forEach((function(e,i){t.minYArr[i]=e.niceMin,t.maxYArr[i]=e.niceMax}))):(this.scales.setYScaleForIndex(0,t.minY,t.maxY),t.minY=t.yAxisScale[0].niceMin,t.maxY=t.yAxisScale[0].niceMax,t.minYArr[0]=t.yAxisScale[0].niceMin,t.maxYArr[0]=t.yAxisScale[0].niceMax),{minY:t.minY,maxY:t.maxY,minYArr:t.minYArr,maxYArr:t.maxYArr,yAxisScale:t.yAxisScale}}},{key:"setXRange",value:function(){var t=this.w.globals,e=this.w.config,i="numeric"===e.xaxis.type||"datetime"===e.xaxis.type||"category"===e.xaxis.type&&!t.noLabelsProvi
61903ded||t.noLabelsProvided||t.isXNumeric;if(t.isXNumeric&&function(){for(var e=0;e<t.series.length;e++)if(t.labels[e])for(var i=0;i<t.labels[e].length;i++)null!==t.labels[e][i]&&p.isNumber(t.labels[e][i])&&(t.maxX=Math.max(t.maxX,t.labels[e][i]),t.initialMaxX=Math.max(t.maxX,t.labels[e][i]),t.minX=Math.min(t.minX,t.labels[e][i]),t.initialMinX=Math.min(t.minX,t.labels[e][i]))}(),t.noLabelsProvided&&0===e.xaxis.categories.length&&(t.maxX=t.labels[t.labels.length-1],t.initialMaxX=t.labels[t.labels.length-1],t.minX=1,t.initialMinX=1),t.isXNumeric||t.noLabelsProvided||t.dataFormatXNumeric){var a;if(void 0===e.xaxis.tickAmount?(a=Math.round(t.svgWidth/150),"numeric"===e.xaxis.type&&t.dataPoints<30&&(a=t.dataPoints-1),a>t.dataPoints&&0!==t.dataPoints&&(a=t.dataPoints-1)):"dataPoints"===e.xaxis.tickAmount?(t.series.length>1&&(a=t.series[t.maxValsInArrayIndex].length-1),t.isXNumeric&&(a=t.maxX-t.minX-1)):a=e.xaxis.tickAmount,t.xTickAmount=a,void 0!==e.xaxis.max&&"number"==typeof e.xaxis.max&&(t.maxX=e.xaxis.max),void 0!==e.xaxis.min&&"number"==typeof e.xaxis.min&&(t.minX=e.xaxis.min),void 0!==e.xaxis.range&&(t.minX=t.maxX-e.xaxis.range),t.minX!==Number.MAX_VALUE&&t.maxX!==-Number.MAX_VALUE)if(e.xaxis.convertedCatToNumeric&&!t.dataFormatXNumeric){for(var s=[],r=t.minX-1;r<t.maxX;r++)s.push(r+1);t.xAxisScale={result:s,niceMin:s[0],niceMax:s[s.length-1]}}else t.xAxisScale=this.scales.setXScale(t.minX,t.maxX);else t.xAxisScale=this.scales.linearScale(1,a,a),t.noLabelsProvided&&t.labels.length>0&&(t.xAxisScale=this.scales.linearScale(1,t.labels.length,a-1),t.seriesX=t.labels.slice());i&&(t.labels=t.xAxisScale.result.slice())}return t.isBarHorizontal&&t.labels.length&&(t.xTickAmount=t.labels.length),this._handleSingleDataPoint(),this._getMinXDiff(),{minX:t.minX,maxX:t.maxX}}},{key:"setZRange",value:function(){var t=this.w.globals;if(t.isDataXYZ)for(var e=0;e<t.series.length;e++)if(void 0!==t.seriesZ[e])for(var i=0;i<t.seriesZ[e].length;i++)null!==t.seriesZ[e][i]&&p.isNumber(t.seriesZ[e][i])&&(t.maxZ=Math.max(t.maxZ,t.seriesZ[e][i]),t.minZ=Math.min(t.minZ,t.seriesZ[e][i]))}},{key:"_handleSingleDataPoint",value:function(){var t=this.w.globals,e=this.w.config;if(t.minX===t.maxX){var i=new Y(this.ctx);if("datetime"===e.xaxis.type){var a=i.getDate(t.minX);e.xaxis.labels.datetimeUTC?a.setUTCDate(a.getUTCDate()-2):a.setDate(a.getDate()-2),t.minX=new Date(a).getTime();var s=i.getDate(t.maxX);e.xaxis.labels.datetimeUTC?s.setUTCDate(s.getUTCDate()+2):s.setDate(s.getDate()+2),t.maxX=new Date(s).getTime()}else("numeric"===e.xaxis.type||"category"===e.xaxis.type&&!t.noLabelsProvided)&&(t.minX=t.minX-2,t.initialMinX=t.minX,t.maxX=t.maxX+2,t.initialMaxX=t.maxX)}}},{key:"_getMinXDiff",value:function(){var t=this.w.globals;t.isXNumeric&&t.seriesX.forEach((function(e,i){1===e.length&&e.push(t.seriesX[t.maxValsInArrayIndex][t.seriesX[t.maxValsInArrayIndex].length-1]);var a=e.slice();a.sort((function(t,e){return t-e})),a.forEach((function(e,i){if(i>0){var s=e-a[i-1];s>0&&(t.minXDiff=Math.min(s,t.minXDiff))}})),1!==t.dataPoints&&t.minXDiff!==Number.MAX_VALUE||(t.minXDiff=.5)}))}},{key:"_setStackedMinMax",value:function(){var t=this.w.globals,e=[],i=[];if(t.series.length)for(var a=0;a<t.series[t.maxValsInArrayIndex].length;a++)for(var s=0,r=0,o=0;o<t.series.length;o++)null!==t.series[o][a]&&p.isNumber(t.series[o][a])&&(t.series[o][a]>0?s=s+parseFloat(t.series[o][a])+1e-4:r+=parseFloat(t.series[o][a])),o===t.series.length-1&&(e.push(s),i.push(r));for(var n=0;n<e.length;n++)t.maxY=Math.max(t.maxY,e[n]),t.minY=Math.min(t.minY,i[n])}}]),t}(),q=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w;var i=this.w;this.xaxisFontSize=i.config.xaxis.labels.style.fontSize,this.axisFontFamily=i.config.xaxis.labels.style.fontFamily,this.xaxisForeColors=i.config.xaxis.labels.style.colors,this.isCategoryBarHorizontal="bar"===i.config.chart.type&&i.config.plotOptions.bar.horizontal,this.xAxisoffX=0,"bottom"===i.config.xaxis.position&&(this.xAxisoffX=i.globals.gridHeight),this.drawnLabels=[],this.axesUtils=new B(e)}return r(t,[{key:"drawYaxis",value:function(t){var e=this,i=this.w,a=new b(this.ctx),s=i.config.yaxis[t].labels.style,r=s.fontSize,o=s.fontFamily,n=s.fontWeight,l=a.group({class:"apexcharts-yaxis",rel:t,transform:"translate("+i.globals.translateYAxisX[t]+", 0)"});if(this.axesUtils.isYAxisHidden(t))return l;var h=a.group({class:"apexcharts-yaxis-texts-g"});l.add(h);var c=i.globals.yAxisScale[t].result.length-1,d=i.globals.gridHeight/c,g=i.globals.translateY,u=i.globals.yLabelFormatters[t],p=i.globals.yAxisScale[t].result.slice();
61903p=this.axesUtils.checkForReversedLabels(t,p);var f="";if(i.config.yaxis[t].labels.show)for(var x=function(l){var x=p[l];x=u(x,l,i);var b=i.config.yaxis[t].labels.padding;i.config.yaxis[t].opposite&&0!==i.config.yaxis.length&&(b*=-1);var v=e.axesUtils.getYAxisForeColor(s.colors,t),m=a.drawText({x:b,y:g+c/10+i.config.yaxis[t].labels.offsetY+1,text:x,textAnchor:i.config.yaxis[t].opposite?"start":"end",fontSize:r,fontFamily:o,fontWeight:n,foreColor:Array.isArray(v)?v[l]:v,isPlainText:!1,cssClass:"apexcharts-yaxis-label "+s.cssClass});l===c&&(f=m),h.add(m);var y=document.createElementNS(i.globals.SVGNS,"title");if(y.textContent=Array.isArray(x)?x.join(" "):x,m.node.appendChild(y),0!==i.config.yaxis[t].labels.rotate){var w=a.rotateAroundCenter(f.node),k=a.rotateAroundCenter(m.node);m.node.setAttribute("transform","rotate(".concat(i.config.yaxis[t].labels.rotate," ").concat(w.x," ").concat(k.y,")"))}g+=d},v=c;v>=0;v--)x(v);if(void 0!==i.config.yaxis[t].title.text){var m=a.group({class:"apexcharts-yaxis-title"}),y=0;i.config.yaxis[t].opposite&&(y=i.globals.translateYAxisX[t]);var w=a.drawText({x:y,y:i.globals.gridHeight/2+i.globals.translateY+i.config.yaxis[t].title.offsetY,text:i.config.yaxis[t].title.text,textAnchor:"end",foreColor:i.config.yaxis[t].title.style.color,fontSize:i.config.yaxis[t].title.style.fontSize,fontWeight:i.config.yaxis[t].title.style.fontWeight,fontFamily:i.config.yaxis[t].title.style.fontFamily,cssClass:"apexcharts-yaxis-title-text "+i.config.yaxis[t].title.style.cssClass});m.add(w),l.add(m)}var k=i.config.yaxis[t].axisBorder,A=31+k.offsetX;if(i.config.yaxis[t].opposite&&(A=-31-k.offsetX),k.show){var S=a.drawLine(A,i.globals.translateY+k.offsetY-2,A,i.globals.gridHeight+i.globals.translateY+k.offsetY+2,k.color,0,k.width);l.add(S)}return i.config.yaxis[t].axisTicks.show&&this.axesUtils.drawYAxisTicks(A,c,k,i.config.yaxis[t].axisTicks,t,d,l),l}},{key:"drawYaxisInversed",value:function(t){var e=this.w,i=new b(this.ctx),a=i.group({class:"apexcharts-xaxis apexcharts-yaxis-inversed"}),s=i.group({class:"apexcharts-xaxis-texts-g",transform:"translate(".concat(e.globals.translateXAxisX,", ").concat(e.globals.translateXAxisY,")")});a.add(s);var r=e.globals.yAxisScale[t].result.length-1,o=e.globals.gridWidth/r+.1,n=o+e.config.xaxis.labels.offsetX,l=e.globals.xLabelFormatter,h=e.globals.yAxisScale[t].result.slice(),c=e.globals.timescaleLabels;c.length>0&&(this.xaxisLabels=c.slice(),r=(h=c.slice()).length),h=this.axesUtils.checkForReversedLabels(t,h);var d=c.length;if(e.config.xaxis.labels.show)for(var g=d?0:r;d?g<d:g>=0;d?g++:g--){var u=h[g];u=l(u,g,e);var p=e.globals.gridWidth+e.globals.padHorizontal-(n-o+e.config.xaxis.labels.offsetX);if(c.length){var f=this.axesUtils.getLabel(h,c,p,g,this.drawnLabels,this.xaxisFontSize);p=f.x,u=f.text,this.drawnLabels.push(f.text),0===g&&e.globals.skipFirstTimelinelabel&&(u=""),g===h.length-1&&e.globals.skipLastTimelinelabel&&(u="")}var x=i.drawText({x:p,y:this.xAxisoffX+e.config.xaxis.labels.offsetY+30-("top"===e.config.xaxis.position?e.globals.xAxisHeight+e.config.xaxis.axisTicks.height-2:0),text:u,textAnchor:"middle",foreColor:Array.isArray(this.xaxisForeColors)?this.xaxisForeColors[t]:this.xaxisForeColors,fontSize:this.xaxisFontSize,fontFamily:this.xaxisFontFamily,fontWeight:e.config.xaxis.labels.style.fontWeight,isPlainText:!1,cssClass:"apexcharts-xaxis-label "+e.config.xaxis.labels.style.cssClass});s.add(x),x.tspan(u);var v=document.createElementNS(e.globals.SVGNS,"title");v.textContent=u,x.node.appendChild(v),n+=o}return this.inversedYAxisTitleText(a),this.inversedYAxisBorder(a),a}},{key:"inversedYAxisBorder",value:function(t){var e=this.w,i=new b(this.ctx),a=e.config.xaxis.axisBorder;if(a.show){var s=0;"bar"===e.config.chart.type&&e.globals.isXNumeric&&(s-=15);var r=i.drawLine(e.globals.padHorizontal+s+a.offsetX,this.xAxisoffX,e.globals.gridWidth,this.xAxisoffX,a.color,0,a.height);t.add(r)}}},{key:"inversedYAxisTitleText",value:function(t){var e=this.w,i=new b(this.ctx);if(void 0!==e.config.xaxis.title.text){var a=i.group({class:"apexcharts-xaxis-title apexcharts-yaxis-title-inversed"}),s=i.drawText({x:e.globals.gridWidth/2+e.config.xaxis.title.offsetX,y:this.xAxisoffX+parseFloat(this.xaxisFontSize)+parseFloat(e.config.xaxis.title.style.fontSize)+e.config.xaxis.title.offsetY+20,text:e.config.xaxis.title.text,textAnchor:"middle",fontSize:e.config.xaxis.title.style.fontSize,fontFamily:e.config.xaxis.title.style.fontFamily,fontWeight:e.config.xaxis.title.style.fontWeight,foreColor:e.config.xaxis.title.style.color,cssClass:"apexcharts-xaxis-title-text "+e.config.xaxis.title.style.cssClass});a.add(s),t.add(a)}}},{key:"yAxisTitleRotate",value:function(t,e){var i=this.w,a=new b(this.ctx),s={width:0,height:0},r={width:0,height:0},o=i.globals.dom.baseEl.querySelector(" .apexcharts-yaxis[rel='".concat(t,"'] .apexcharts-yaxis-texts-g"));null!==o&&(s=o.getBoundingClientRect());var n=i.globals.dom.baseEl.querySelector(".apexcharts-yaxis[rel='".concat(t,"'] .apexcharts-yaxis-title text"));if(null!==n&&(r=n.getBoundingClientRect()),null!==n){var l=this.xPaddingForYAxisTitle(t,s,r,e);n.setAttribute("x",l.xPos-(e?10:0))}
61903if(null!==n){var h=a.rotateAroundCenter(n);n.setAttribute("transform","rotate(".concat(e?-1*i.config.yaxis[t].title.rotate:i.config.yaxis[t].title.rotate," ").concat(h.x," ").concat(h.y,")"))}}},{key:"xPaddingForYAxisTitle",value:function(t,e,i,a){var s=this.w,r=0,o=0,n=10;return void 0===s.config.yaxis[t].title.text||t<0?{xPos:o,padd:0}:(a?(o=e.width+s.config.yaxis[t].title.offsetX+i.width/2+n/2,0===(r+=1)&&(o-=n/2)):(o=-1*e.width+s.config.yaxis[t].title.offsetX+n/2+i.width/2,s.globals.isBarHorizontal&&(n=25,o=-1*e.width-s.config.yaxis[t].title.offsetX-n)),{xPos:o,padd:n})}},{key:"setYAxisXPosition",value:function(t,e){var i=this.w,a=0,s=0,r=18,o=1;i.config.yaxis.length>1&&(this.multipleYs=!0),i.config.yaxis.map((function(n,l){var h=i.globals.ignoreYAxisIndexes.indexOf(l)>-1||!n.show||n.floating||0===t[l].width,c=t[l].width+e[l].width;n.opposite?i.globals.isBarHorizontal?(s=i.globals.gridWidth+i.globals.translateX-1,i.globals.translateYAxisX[l]=s-n.labels.offsetX):(s=i.globals.gridWidth+i.globals.translateX+o,h||(o=o+c+20),i.globals.translateYAxisX[l]=s-n.labels.offsetX+20):(a=i.globals.translateX-r,h||(r=r+c+20),i.globals.translateYAxisX[l]=a+n.labels.offsetX)}))}},{key:"setYAxisTextAlignments",value:function(){var t=this.w,e=t.globals.dom.baseEl.getElementsByClassName("apexcharts-yaxis");(e=p.listToArray(e)).forEach((function(e,i){var a=t.config.yaxis[i];if(a&&void 0!==a.labels.align){var s=t.globals.dom.baseEl.querySelector(".apexcharts-yaxis[rel='".concat(i,"'] .apexcharts-yaxis-texts-g")),r=t.globals.dom.baseEl.querySelectorAll(".apexcharts-yaxis[rel='".concat(i,"'] .apexcharts-yaxis-label"));r=p.listToArray(r);var o=s.getBoundingClientRect();"left"===a.labels.align?(r.forEach((function(t,e){t.setAttribute("text-anchor","start")})),a.opposite||s.setAttribute("transform","translate(-".concat(o.width,", 0)"))):"center"===a.labels.align?(r.forEach((function(t,e){t.setAttribute("text-anchor","middle")})),s.setAttribute("transform","translate(".concat(o.width/2*(a.opposite?1:-1),", 0)"))):"right"===a.labels.align&&(r.forEach((function(t,e){t.setAttribute("text-anchor","end")})),a.opposite&&s.setAttribute("transform","translate(".concat(o.width,", 0)")))}}))}}]),t}(),Z=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w,this.documentEvent=p.bind(this.documentEvent,this)}return r(t,[{key:"addEventListener",value:function(t,e){var i=this.w;i.globals.events.hasOwnProperty(t)?i.globals.events[t].push(e):i.globals.events[t]=[e]}},{key:"removeEventListener",value:function(t,e){var i=this.w;if(i.globals.events.hasOwnProperty(t)){var a=i.globals.events[t].indexOf(e);-1!==a&&i.globals.events[t].splice(a,1)}}},{key:"fireEvent",value:function(t,e){var i=this.w;if(i.globals.events.hasOwnProperty(t)){e&&e.length||(e=[]);for(var a=i.globals.events[t],s=a.length,r=0;r<s;r++)a[r].apply(null,e)}}},{key:"setupEventHandlers",value:function(){var t=this,e=this.w,i=this.ctx,a=e.globals.dom.baseEl.querySelector(e.globals.chartClass);this.ctx.eventList.forEach((function(t){a.addEventListener(t,(function(t){var a=Object.assign({},e,{seriesIndex:e.globals.capturedSeriesIndex,dataPointIndex:e.globals.capturedDataPointIndex});"mousemove"===t.type||"touchmove"===t.type?"function"==typeof e.config.chart.events.mouseMove&&e.config.chart.events.mouseMove(t,i,a):"mouseleave"===t.type||"touchleave"===t.type?"function"==typeof e.config.chart.events.mouseLeave&&e.config.chart.events.mouseLeave(t,i,a):("mouseup"===t.type&&1===t.which||"touchend"===t.type)&&("function"==typeof e.config.chart.events.click&&e.config.chart.events.click(t,i,a),i.ctx.events.fireEvent("click",[t,i,a]))}),{capture:!1,passive:!0})})),this.ctx.eventList.forEach((function(i){e.globals.dom.baseEl.addEventListener(i,t.documentEvent,{passive:!0})})),this.ctx.core.setupBrushHandler()}},{key:"documentEvent",value:function(t){var e=this.w,i=t.target.className;if("click"===t.type){var a=e.globals.dom.baseEl.querySelector(".apexcharts-menu");a&&a.classList.contains("apexcharts-menu-open")&&"apexcharts-menu-icon"!==i&&a.classList.remove("apexcharts-menu-open")}e.globals.clientX="touchmove"===t.type?t.touches[0].clientX:t.clientX,e.globals.clientY="touchmove"===t.type?t.touches[0].clientY:t.clientY}}]),t}(),$=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w}return r(t,[{key:"setCurrentLocaleValues",value:function(t){var e=this.w.config.chart.locales;window.Apex.chart&&window.Apex.chart.locales&&window.Apex.chart.locales.length>0&&(e=this.w.config.chart.locales.concat(window.Apex.chart.locales));var i=e.filter((function(e){return e.name===t}))[0];if(!i)throw new Error("Wrong locale name provided. Please make sure you set the correct locale name in options");var a=p.extend(A,i);this.w.globals.locale=a.options}}]),t}(),J=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w}return r(t,[{key:"drawAxis",value:function(t,e){var i,a,s=this.w.globals,r=this.w.config,o=new G(this.ctx),n=new q(this.ctx);s.axisCharts&&"radar"!==t&&(s.isBarHorizontal?(a=n.drawYaxisInversed(0),i=o.drawXaxisInversed(0),s.dom.elGraphical.add(i),s.dom.elGraphical.add(a)):(i=o.drawXaxis(),s.dom.elGraphical.add(i),r.yaxis.map((function(t,e){-1===s.ignoreYAxisIndexes.indexOf(e)&&(a=n.drawYaxis(e),s.dom.Paper.add(a))}))))}}]),t}(),Q=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w}return r(t,[{key:"drawXCrosshairs",value:function(){var t=this.w,e=new b(this.ctx),i=new x(this.ctx),a=t.config.xaxis.crosshairs.fill.gradient,s=t.config.xaxis.crosshairs.dropShadow,r=t.config.xaxis.crosshairs.fill.type,o=a.colorFrom,n=a.c
vendor: 1,080 bytes, line 61903
61903olorTo,l=a.opacityFrom,h=a.opacityTo,c=a.stops,d=s.enabled,g=s.left,u=s.top,f=s.blur,v=s.color,m=s.opacity,y=t.config.xaxis.crosshairs.fill.color;if(t.config.xaxis.crosshairs.show){"gradient"===r&&(y=e.drawGradient("vertical",o,n,l,h,null,c,null));var w=e.drawRect();1===t.config.xaxis.crosshairs.width&&(w=e.drawLine());var k=t.globals.gridHeight;(!p.isNumber(k)||k<0)&&(k=0);var A=t.config.xaxis.crosshairs.width;(!p.isNumber(A)||A<0)&&(A=0),w.attr({class:"apexcharts-xcrosshairs",x:0,y:0,y2:k,width:A,height:k,fill:y,filter:"none","fill-opacity":t.config.xaxis.crosshairs.opacity,stroke:t.config.xaxis.crosshairs.stroke.color,"stroke-width":t.config.xaxis.crosshairs.stroke.width,"stroke-dasharray":t.config.xaxis.crosshairs.stroke.dashArray}),d&&(w=i.dropShadow(w,{left:g,top:u,blur:f,color:v,opacity:m})),t.globals.dom.elGraphical.add(w)}}},{key:"drawYCrosshairs",value:function(){var t=this.w,e=new b(this.ctx),i=t.config.yaxis[0].crosshairs,a=t.globals.barPadForNumericAxis;if(t.config.yaxis[0].crosshairs.show){var s=e.drawLine(-a,0,t.globals.gridWidth+a,0,i.stroke.color,
61903i.stroke.dashArray,i.stroke.width);s.attr({class:"apexcharts-ycrosshairs"}),t.globals.dom.elGraphical.add(s)}var r=e.drawLine(-a,0,t.globals.gridWidth+a,0,i.stroke.color,0,0);r.attr({class:"apexcharts-ycrosshairs-hidden"}),t.globals.dom.elGraphical.add(r)}}]),t}(),K=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w}return r(t,[{key:"checkResponsiveConfig",value:function(t){var e=this,i=this.w,a=i.config;if(0!==a.responsive.length){var s=a.responsive.slice();s.sort((function(t,e){return t.breakpoint>e.breakpoint?1:e.breakpoint>t.breakpoint?-1:0})).reverse();var r=new H({}),o=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},a=s[0].breakpoint,o=window.innerWidth>0?window.innerWidth:screen.width;if(o>a){var n=y.extendArrayProps(r,i.globals.initialConfig,i);t=p.extend(n,t),t=p.extend(i.config,t),e.overrideResponsiveOptions(t)}else for(var l=0;l<s.length;l++)o<s[l].breakpoint&&(t=y.extendArrayProps(r,s[l].options,i),t=p.extend(i.config,t),e.overrideResponsiveOptions(t))};if(t){var n=y.extendArrayProps(r,t,i);n=p.extend(i.config,n),o(n=p.extend(n,t))}else o({})}}},{key:"overrideResponsiveOptions",value:function(t){var e=new H(t).init({responsiveOverride:!0});this.w.config=e}}]),t}(),tt=function(){function t(e){a(this,t),this.ctx=e,this.colors=[],this.w=e.w;var i=this.w;this.isColorFn=!1,this.isHeatmapDistributed="treemap"===i.config.chart.type&&i.config.plotOptions.treemap.distributed||"heatmap"===i.config.chart.type&&i.config.plotOptions.heatmap.distributed,this.isBarDistributed=i.config.plotOptions.bar.distributed&&("bar"===i.config.chart.type||"rangeBar"===i.config.chart.type)}return r(t,[{key:"init",value:function(){this.setDefaultColors()}},{key:"setDefaultColors",value:function(){var t=this,e=this.w,i=new p;if(e.globals.dom.elWrap.classList.add("apexcharts-theme-".concat(e.config.theme.mode)),void 0===e.config.colors?e.globals.colors=this.predefined():(e.globals.colors=e.config.colors,Array.isArray(e.config.colors)&&e.config.colors.length>0&&"function"==typeof e.config.colors[0]&&(e.globals.colors=e.config.series.map((function(i,a){var s=e.config.colors[a];return s||(s=e.config.colors[0]),"function"==typeof s?(t.isColorFn=!0,s({value:e.globals.axisCharts?e.globals.series[a][0]?e.globals.series[a][0]:0:e.globals.series[a],seriesIndex:a,dataPointIndex:a,w:e})):s})))),e.globals.seriesColors.map((function(t,i){t&&(e.globals.colors[i]=t)})),e.config.theme.monochrome.enabled){var a=[],s=e.globals.series.length;(this.isBarDistributed||this.isHeatmapDistributed)&&(s=e.globals.series[0].length*e.globals.series.length);for(var r=e.config.theme.monochrome.color,o=1/(s/e.config.theme.monochrome.shadeIntensity),n=e.config.theme.monochrome.shadeTo,l=0,h=0;h<s;h++){var c=void 0;"dark"===n?(c=i.shadeColor(-1*l,r),l+=o):(c=i.shadeColor(l,r),l+=o),a.push(c)}e.globals.colors=a.slice()}var d=e.globals.colors.slice();this.pushExtraColors(e.globals.colors);["fill","stroke"].forEach((function(i){void 0===e.config[i].colors?e.globals[i].colors=t.isColorFn?e.config.colors:d:e.globals[i].colors=e.config[i].colors.slice(),t.pushExtraColors(e.globals[i].colors)})),void 0===e.config.dataLabels.style.colors?e.globals.dataLabels.style.colors=d:e.globals.dataLabels.style.colors=e.config.dataLabels.style.colors.slice(),this.pushExtraColors(e.globals.dataLabels.style.colors,50),void 0===e.config.plotOptions.radar.polygons.fill.colors?e.globals.radarPolygons.fill.colors=["dark"===e.config.theme.mode?"#424242":"none"]:e.globals.radarPolygons.fill.colors=e.config.plotOptions.radar.polygons.fill.colors.slice(),this.pushExtraColors(e.globals.radarPolygons.fill.colors,20),void 0===e.config.markers.colors?e.globals.markers.colors=d:e.globals.markers.colors=e.config.markers.colors.slice(),this.pushExtraColors(e.globals.markers.colors)}},{key:"pushExtraColors",value:function(t,e){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,a=this.w,s=e||a.globals.series.length;if(null===i&&(i=this.isBarDistributed||this.isHeatmapDistributed||"heatmap"===a.config.chart.type&&a.config.plotOptions.heatmap.colorScale.inverse),i&&a.globals.series.length&&(s=a.globals.series[a.globals.maxValsInArrayIndex].length*a.globals.series.length),t.length<s)for(var r=s-t.length,o=0;o<r;o++)t.push(t[o])}},{key:"updateThemeOptions",value:function(t){t.chart=t.chart||{},t.tooltip=t.tooltip||{};var e=t.theme.mode||"light",i=t.theme.palette?t.theme.palette:"dark"===e?"palette4":"palette1",a=t.chart.foreColor?t.chart.foreColor:"dark"===e?"#f6f7f8":"#373d3f";return t.tooltip.theme=e,t.chart.foreColor=a,t.theme.palette=i,t}},{key:"predefined",value:function(){switch(this.w.config.theme.palette){case"palette1":this.colors=["#008FFB","#00E396","#FEB019","#FF4560","#775DD0"];break;case"palette2":this.colors=["#3f51b5","#03a9f4","#4caf50","#f9ce1d","#F
61903F9800"];break;case"palette3":this.colors=["#33b2df","#546E7A","#d4526e","#13d8aa","#A5978B"];break;case"palette4":this.colors=["#4ecdc4","#c7f464","#81D4FA","#fd6a6a","#546E7A"];break;case"palette5":this.colors=["#2b908f","#f9a3a4","#90ee7e","#fa4443","#69d2e7"];break;case"palette6":this.colors=["#449DD1","#F86624","#EA3546","#662E9B","#C5D86D"];break;case"palette7":this.colors=["#D7263D","#1B998B","#2E294E","#F46036","#E2C044"];break;case"palette8":this.colors=["#662E9B","#F86624","#F9C80E","#EA3546","#43BCCD"];break;case"palette9":this.colors=["#5C4742","#A5978B","#8D5B4C","#5A2A27","#C4BBAF"];break;case"palette10":this.colors=["#A300D6","#7D02EB","#5653FE","#2983FF","#00B1F2"];break;default:this.colors=["#008FFB","#00E396","#FEB019","#FF4560","#775DD0"]}return this.colors}}]),t}(),et=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w}return r(t,[{key:"draw",value:function(){this.drawTitleSubtitle("title"),this.drawTitleSubtitle("subtitle")}},{key:"drawTitleSubtitle",value:function(t){var e=this.w,i="title"===t?e.config.title:e.config.subtitle,a=e.globals.svgWidth/2,s=i.offsetY,r="middle";if("left"===i.align?(a=10,r="start"):"right"===i.align&&(a=e.globals.svgWidth-10,r="end"),a+=i.offsetX,s=s+parseInt(i.style.fontSize,10)+i.margin/2,void 0!==i.text){var o=new b(this.ctx).drawText({x:a,y:s,text:i.text,textAnchor:r,fontSize:i.style.fontSize,fontFamily:i.style.fontFamily,fontWeight:i.style.fontWeight,foreColor:i.style.color,opacity:1});o.node.setAttribute("class","apexcharts-".concat(t,"-text")),e.globals.dom.Paper.add(o)}}}]),t}(),it=function(){function t(e){a(this,t),this.w=e.w,this.dCtx=e}return r(t,[{key:"getTitleSubtitleCoords",value:function(t){var e=this.w,i=0,a=0,s="title"===t?e.config.title.floating:e.config.subtitle.floating,r=e.globals.dom.baseEl.querySelector(".apexcharts-".concat(t,"-text"));if(null!==r&&!s){var o=r.getBoundingClientRect();i=o.width,a=e.globals.axisCharts?o.height+5:o.height}return{width:i,height:a}}},{key:"getLegendsRect",value:function(){var t=this.w,e=t.globals.dom.baseEl.querySelector(".apexcharts-legend");t.config.legend.height||"top"!==t.config.legend.position&&"bottom"!==t.config.legend.position||(e.style.maxHeight=t.globals.svgHeight/2+"px");var i=Object.assign({},p.getBoundingClientRect(e));return null!==e&&!t.config.legend.floating&&t.config.legend.show?this.dCtx.lgRect={x:i.x,y:i.y,height:i.height,width:0===i.height?0:i.width}:this.dCtx.lgRect={x:0,y:0,height:0,width:0},"left"!==t.config.legend.position&&"right"!==t.config.legend.position||1.5*this.dCtx.lgRect.width>t.globals.svgWidth&&(this.dCtx.lgRect.width=t.globals.svgWidth/1.5),this.dCtx.lgRect}},{key:"getLargestStringFromMultiArr",value:function(t,e){var i=t;if(this.w.globals.isMultiLineX){var a=e.map((function(t,e){return Array.isArray(t)?t.length:1})),s=Math.max.apply(Math,g(a));i=e[a.indexOf(s)]}return i}}]),t}(),at=function(){function t(e){a(this,t),this.w=e.w,this.dCtx=e}return r(t,[{key:"getxAxisLabelsCoords",value:function(){var t,e=this.w,i=e.globals.labels.slice();if(e.config.xaxis.convertedCatToNumeric&&0===i.length&&(i=e.globals.categoryLabels),e.globals.timescaleLabels.length>0){var a=this.getxAxisTimeScaleLabelsCoords();t={width:a.width,height:a.height},e.globals.rotateXLabels=!1}else{this.dCtx.lgWidthForSideLegends="left"!==e.config.legend.position&&"right"!==e.config.legend.position||e.config.legend.floating?0:this.dCtx.lgRect.width;var s=e.globals.xLabelFormatter,r=p.getLargestStringFromArr(i),o=this.dCtx.dimHelpers.getLargestStringFromMultiArr(r,i);
61903e.globals.isBarHorizontal&&(o=r=e.globals.yAxisScale[0].result.reduce((function(t,e){return t.length>e.length?t:e}),0));var n=new W(this.dCtx.ctx),l=r;r=n.xLabelFormat(s,r,l,{i:void 0,dateFormatter:new Y(this.dCtx.ctx).formatDate,w:e}),o=n.xLabelFormat(s,o,l,{i:void 0,dateFormatter:new Y(this.dCtx.ctx).formatDate,w:e}),(e.config.xaxis.convertedCatToNumeric&&void 0===r||""===String(r).trim())&&(o=r="1");var h=new b(this.dCtx.ctx),c=h.getTextRects(r,e.config.xaxis.labels.style.fontSize),d=c;if(r!==o&&(d=h.getTextRects(o,e.config.xaxis.labels.style.fontSize)),(t={width:c.width>=d.width?c.width:d.width,height:c.height>=d.height?c.height:d.height}).width*i.length>e.globals.svgWidth-this.dCtx.lgWidthForSideLegends-this.dCtx.yAxisWidth-this.dCtx.gridPad.left-this.dCtx.gridPad.right&&0!==e.config.xaxis.labels.rotate||e.config.xaxis.labels.rotateAlways){if(!e.globals.isBarHorizontal){e.globals.rotateXLabels=!0;var g=function(t){return h.getTextRects(t,e.config.xaxis.labels.style.fontSize,e.config.xaxis.labels.style.fontFamily,"rotate(".concat(e.config.xaxis.labels.rotate," 0 0)"),!1)};c=g(r),r!==o&&(d=g(o)),t.height=(c.height>d.height?c.height:d.height)/1.5,t.width=c.width>d.width?c.width:d.width}}else e.globals.rotateXLabels=!1}return e.config.xaxis.labels.show||(t={width:0,height:0}),{width:t.width,height:t.height}}},{key:"getxAxisTitleCoords",value:function(){var t=this.w,e=0,i=0;if(void 0!==t.config.xaxis.title.text){var a=new b(this.dCtx.ctx).getTextRects(t.config.xaxis.title.text,t.config.xaxis.title.style.fontSize);e=a.width,i=a.height}return{width:e,height:i}}},{key:"getxAxisTimeScaleLabelsCoords",value:function(){var t,e=this.w;this.dCtx.timescaleLabels=e.globals.timescaleLabels.slice();var i=this.dCtx.timescaleLabels.map((function(t){return t.value})),a=i.reduce((function(t,e){return void 0===t?(console.error("You have possibly supplied invalid Date format. Please supply a valid JavaScript Date"),0):t.length>e.length?t:e}),0);return 1.05*(t=new b(this.dCtx.ctx).getTextRects(a,e.config.xaxis.labels.style.fontSize)).width*i.length>e.globals.gridWidth&&0!==e.config.xaxis.labels.rotate&&(e.globals.overlappingXLabels=!0),t}},{key:"additionalPaddingXLabels",value:function(t){var e=this,i=this.w,a=i.globals,s=i.config,r=s.xaxis.type,o=t.width;a.skipLastTimelinelabel=!1,a.skipFirstTimelinelabel=!1;var n=i.config.yaxis[0].opposite&&i.globals.isBarHorizontal,l=function(t,n){(function(t){return-1!==a.collapsedSeriesIndices.indexOf(t)})(n)||function(t){if(e.dCtx.timescaleLabels&&e.dCtx.timescaleLabels.length){var n=e.dCtx.timescaleLabels[0],l=e.dCtx.timescaleLabels[e.dCtx.timescaleLabels.length-1].position+o/1.75-e.dCtx.yAxisWidthRight,h=n.position-o/1.75+e.dCtx.yAxisWidthLeft,c="right"===i.config.legend.position&&e.dCtx.lgRect.width>0?e.dCtx.lgRect.width:0;l>a.svgWidth-a.translateX-c&&(a.skipLastTimelinelabel=!0),h<-(t.show&&!t.floating||"bar"!==s.chart.type&&"candlestick"!==s.chart.type&&"rangeBar"!==s.chart.type&&"boxPlot"!==s.chart.type?10:o/1.75)&&(a.skipFirstTimelinelabel=!0)}else"datetime"===r?e.dCtx.gridPad.right<o&&!a.rotateXLabels&&(a.skipLastTimelinelabel=!0):"datetime"!==r&&e.dCtx.gridPad.right<o/2-e.dCtx.yAxisWidthRight&&!a.rotateXLabels&&!i.config.xaxis.labels.trim&&("between"!==i.config.xaxis.tickPlacement||i.globals.isBarHorizontal)&&(e.dCtx.xPadRight=o/2+1)}(t)};s.yaxis.forEach((function(t,i){n?(e.dCtx.gridPad.left<o&&(e.dCtx.xPadLeft=o/2+1),e.dCtx.xPadRight=o/2+1):l(t,i)}))}}]),t}(),st=function(){function t(e){a(this,t),this.w=e.w,this.dCtx=e}return r(t,[{key:"getyAxisLabelsCoords",value:function(){var t=this,e=this.w,i=[],a=10,s=new B(this.dCtx.ctx);return e.config.yaxis.map((function(r,o){var n=e.globals.yAxisScale[o],l=0;if(!s.isYAxisHidden(o)&&r.labels.show&&void 0!==r.labels.minWidth&&(l=r.labels.minWidth),!s.isYAxisHidden(o)&&r.labels.show&&n.result.length){var h=e.globals.yLabelFormatters[o],c=n.niceMin===Number.MIN_VALUE?0:n.niceMin,d=String(c).length>String(n.niceMax).length?c:n.niceMax,g=h(d,{seriesIndex:o,dataPointIndex:-1,w:e}),u=g;if(void 0!==g&&0!==g.length||(g=d),e.globals.isBarHorizontal){a=0;var f=e.globals.labels.slice();g=h(g=p.getLargestStringFromArr(f),{seriesIndex:o,dataPointIndex:-1,w:e}),u=t.dCtx.dimHelpers.getLargestStringFromMultiArr(g,f)}var x=new b(t.dCtx.ctx),v="rotate(".concat(r.labels.rotate," 0 0)"),m=x.getTextRects(g,r.labels.style.fontSize,r.labels.style.fontFamily,v,!1),y=m;g!==u&&(y=x.getTextRects(u,r.labels.style.fontSize,r.labels.style.fontFamily,v,!1)),i.push({width:(l>y.width||l>m.width?l:y.width>m.width?y.width:m.width)+a,height:y.height>m.height?y.height:m.height})}else i.push({width:0,height:0})})),i}}
61903,{key:"getyAxisTitleCoords",value:function(){var t=this,e=this.w,i=[];return e.config.yaxis.map((function(e,a){if(e.show&&void 0!==e.title.text){var s=new b(t.dCtx.ctx),r="rotate(".concat(e.title.rotate," 0 0)"),o=s.getTextRects(e.title.text,e.title.style.fontSize,e.title.style.fontFamily,r,!1);i.push({width:o.width,height:o.height})}else i.push({width:0,height:0})})),i}},{key:"getTotalYAxisWidth",value:function(){var t=this.w,e=0,i=0,a=0,s=t.globals.yAxisScale.length>1?10:0,r=new B(this.dCtx.ctx),o=function(o,n){var l=t.config.yaxis[n].floating,h=0;o.width>0&&!l?(h=o.width+s,function(e){return t.globals.ignoreYAxisIndexes.indexOf(e)>-1}(n)&&(h=h-o.width-s)):h=l||r.isYAxisHidden(n)?0:5,t.config.yaxis[n].opposite?a+=h:i+=h,e+=h};return t.globals.yLabelsCoords.map((function(t,e){o(t,e)})),t.globals.yTitleCoords.map((function(t,e){o(t,e)})),t.globals.isBarHorizontal&&!t.config.yaxis[0].floating&&(e=t.globals.yLabelsCoords[0].width+t.globals.yTitleCoords[0].width+15),this.dCtx.yAxisWidthLeft=i,this.dCtx.yAxisWidthRight=a,e}}]),t}(),rt=function(){function t(e){a(this,t),this.w=e.w,this.dCtx=e}return r(t,[{key:"gridPadForColumnsInNumericAxis",value:function(t){var e=this.w;if(e.globals.noData||e.globals.allSeriesCollapsed)return 0;var i=function(t){return"bar"===t||"rangeBar"===t||"candlestick"===t||"boxPlot"===t},a=e.config.chart.type,s=0,r=i(a)?e.config.series.length:1;if(e.globals.comboBarCount>0&&(r=e.globals.comboBarCount),e.globals.collapsedSeries.forEach((function(t){i(t.type)&&(r-=1)})),e.config.chart.stacked&&(r=1),(i(a)||e.globals.comboBarCount>0)&&e.globals.isXNumeric&&!e.globals.isBarHorizontal&&r>0){var o,n,l=Math.abs(e.globals.initialMaxX-e.globals.initialMinX);l<=3&&(l=e.globals.dataPoints),o=l/t,e.globals.minXDiff&&e.globals.minXDiff/o>0&&(n=e.globals.minXDiff/o),n>t/2&&(n/=2),(s=n/r*parseInt(e.config.plotOptions.bar.columnWidth,10)/100)<1&&(s=1),s=s/(r>1?1:1.5)+5,e.globals.barPadForNumericAxis=s}return s}},{key:"gridPadFortitleSubtitle",value:function(){var t=this,e=this.w,i=e.globals,a=this.dCtx.isSparkline||!e.globals.axisCharts?0:10;["title","subtitle"].forEach((function(i){void 0!==e.config[i].text?a+=e.config[i].margin:a+=t.dCtx.isSparkline||!e.globals.axisCharts?0:5})),!e.config.legend.show||"bottom"!==e.config.legend.position||e.config.legend.floating||e.globals.axisCharts||(a+=10);var s=this.dCtx.dimHelpers.getTitleSubtitleCoords("title"),r=this.dCtx.dimHelpers.getTitleSubtitleCoords("subtitle");i.gridHeight=i.gridHeight-s.height-r.height-a,i.translateY=i.translateY+s.height+r.height+a}},{key:"setGridXPosForDualYAxis",value:function(t,e){var i=this.w,a=new B(this.dCtx.ctx);i.config.yaxis.map((function(s,r){-1!==i.globals.ignoreYAxisIndexes.indexOf(r)||s.floating||a.isYAxisHidden(r)||(s.opposite&&(i.globals.translateX=i.globals.translateX-(e[r].width+t[r].width)-parseInt(i.config.yaxis[r].labels.style.fontSize,10)/1.2-12),i.globals.translateX<2&&(i.globals.translateX=2))}))}}]),t}(),ot=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w,this.lgRect={},this.yAxisWidth=0,this.yAxisWidthLeft=0,this.yAxisWidthRight=0,this.xAxisHeight=0,this.isSparkline=this.w.config.chart.sparkline.enabled,this.dimHelpers=new it(this),this.dimYAxis=new st(this),this.dimXAxis=new at(this),this.dimGrid=new rt(this),this.lgWidthForSideLegends=0,this.gridPad=this.w.config.grid.padding,this.xPadRight=0,this.xPadLeft=0}return r(t,[{key:"plotCoords",value:function(){var t=this.w.globals;this.lgRect=this.dimHelpers.getLegendsRect(),t.axisCharts?this.setDimensionsForAxisCharts():this.setDimensionsForNonAxisCharts(),this.dimGrid.gridPadFortitleSubtitle(),t.gridHeight=t.gridHeight-this.gridPad.top-this.gridPad.bottom,t.gridWidth=t.gridWidth-this.gridPad.left-this.gridPad.right-this.xPadRight-this.xPadLeft;var e=this.dimGrid.gridPadForColumnsInNumericAxis(t.gridWidth);t.gridWidth=t.gridWidth-2*e,t.translateX=t.translateX+this.gridPad.left+this.xPadLeft+(e>0?e+4:0),t.translateY=t.translateY+this.gridPad.top}},{key:"setDimensionsForAxisCharts",value:function(){var t=this,e=this.w,i=e.globals,a=this.dimYAxis.getyAxisLabelsCoords(),s=this.dimYAxis.getyAxisTitleCoords();e.globals.yLabelsCoords=[],e.globals.yTitleCoords=[],e.config.yaxis.map((function(t,i){e.globals.yLabelsCoords.push({width:a[i].width,index:i}),e.globals.yTitleCoords.push({width:s[i].width,index:i})})),this.yAxisWidth=this.dimYAxis.getTotalYAxisWidth();var r=this.dimXAxis.getxAxisLabelsCoords(),o=this.dimXAxis.getxAxisTitleCoords();this.conditionalChecksForAxisCoords(r,o),i.translateXAxisY=e.globals.rotateXLabels?this.xAxisHeight/8:-4,i.translateXAxisX=e.globals.rotateXLabels&&e.globals.isXNumeric&&e.config.xaxis.labels.rotate<=-45?-this.xAxisWidth/4:0,e.globals.isBarHorizontal&&(i.rotateXLabels=!1,i.translateXAxisY=parseInt(e.config.xaxis.labels.style.fontSize,10)/1.5*-1),i.translateXAxisY=i.translateXAxisY+e.config.xaxis.labels.offsetY,i.translateXAxisX=i.translateXAxisX+e.config.xaxis.labels.offsetX;var n=this.yAxisWidth,l=this.xAxisHeight;i.xAxisLabelsHeight=this.xAxisHeight-o.height,i.xAxisLabelsWidth=this.xAxisWidth,i.xAxisHeight=this.xAxisHeight;var h=10;("radar"===e.config.chart.type||this.isSparkline)&&(n=0,l=i.goldenPadding),this.isSparkline&&(this.lgRect={height:0,width:0}),(this.isSparkline||"treemap"===e.config.chart.type)&&(n=0,l=0,h=0),this.isSparkline||this.dimXAxis.additionalPaddingXLabels(r);var c=function(){i.translateX=n,i.gridHeight=i.svgHeight-t.lgRect.height-l-(t.isSparkline||"treemap"===e.config.chart.type?0:e.globals.rotateXLabels?10:15),i.gridWidth=i.svgWidth-n};switch("top"===e.config.xaxis.position&&(h=i.xAxisHeight-e.config.xaxis.axisTicks.height-5),e.config.legend.position){case"bottom":i.translateY=h,c();break;case"top":i.translateY=this.lgRect.height+h,c();break;case"left":i.translateY=h,i.translateX=this.lgRect.width+n,i.gridHeight=i.svgHeight-l-12,i.gridWidth=i.svgWidth-this.lgRect.width-n;break;case"right":i.translateY=h,i.translateX=n,i.gridHeight=i.svgHeight-l-12,i.gridWidth=i.svgWidth-this.lgRect.width-n-5;break;default:throw new Error("Legend position not supported")}this.dimGrid.setGridXPosForDualYAxis(s,a),new q(this.ctx).setYAxisXPosition(a,s)}},{key:"setDimensionsForNonAxisCharts",value:function(){var t=this.w,e=t.globals,i=t.config,a=0;t.config.legend.show&&!t.config.legend.floating&&(a=20);var s="pie"===i.chart.type||"polarArea"===i.chart.type||"donut"===i.chart.type?"pie":"radialBar",r=i.plotOptions[s].offsetY,o=i.plotOptions[s].offsetX;if(!i.legend.show||i.legend.floating)return e.gridHeight=e.svgHeight-i.grid.padding.left+i.grid.padding.right,e.gridWidth=e.gridHeight,e.translateY=r,void(e.translateX=o+(e.svgWidth-e.gridWidth)/2);switch(i.legend.position){case"bottom":e.gridHeight=e.svgHeight-this.lgRect.height-e.goldenPadding,e.gridWidth=e.svgWidth,e.translateY=r-10,e.translateX=o+(e.svgWidth-e.gridWidth)/2;break;case"top":e.gridHeight=e.svgHeight-this.lgRect.height-e.goldenPadding,e.gridWidth=e.svgWidth,e.translateY=this.lgRect.height+r+10,e.translateX=o+(e.svgWidth-e.gridWidth)/2;break;case"left":e.gridWidth=e.svgWidth-this.lgRect.width-a,e.gridHeight="auto"!==i.chart.height?e.svgHeight:e.gridWidth,e.translateY=r,e.translateX=o+this.lgRect.width+a;break;case"right":e.gridWidth=e.svgWidth-this.lgRect.width-a-5,e.gridHeight="auto"!==i.chart.height?e.svgHeight:e.gridWidth,e.translateY=r,e.translateX=o+10;break;default:throw new Error("Legend position not supported")}}},{key:"conditionalChecksForAxisCoords",value:function(t,e){var i=this.w,a=t.height+e.height,s=i.globals.isMultiLineX?1.2:i.globals.LINE_HEIGHT_RATIO,r=i.globals.rotateXLabels?22:10,o=i.globals.rotateXLabels&&"bottom"===i.config.legend.position?10:0;this.xAxisHeight=a*s+r+o,this.xAxisWidth=t.width,this.xAxisHeight-e.height>i.config.xaxis.labels.maxHeight&&(this.xAxisHeight=i.config.xaxis.labels.maxHeight),i.config.xaxis.labels.minHeight&&this.xAxisHeight<i.config.xaxis.labels.minHeight&&(this.xAxisHeight=i.config.xaxis.labels.minHeight),i.config.xaxis.floating&&(this.xAxisHeight=0);var n=0,l=0;i.config.yaxis.forEach((function(t){n+=t.labels.minWidth,l+=t.labels.maxWidth})),this.yAxisWidth<n&&(this.yAxisWidth=n),this.yAxisWidth>l&&(this.yAxisWidth=l)}}]),t}(),nt=function(){function t(e){a(this,t),this.w=e.w,this.lgCtx=e}return r(t,[{key:"getLegendStyles",value:function(){var t=document.createElement("style");t.setAttribute("type","text/css");var e=document.createTextNode("\t\n    \t\n      .apexcharts-legend {\t\n        display: flex;\t\n        overflow: auto;\t\n        padding: 0 10px;\t\n      }\t\n      .apexcharts-legend.apx-legend-position-bottom, .apexcharts-legend.apx-legend-position-top {\t\n        flex-wrap: wrap\t\n      }\t\n      .apexcharts-legend.apx-legend-position-right, .apexcharts-legend.apx-legend-position-left {\t\n        flex-direction: column;\t\n        bottom: 0;\t\n      }\t\n      .apexcharts-legend.apx-legend-position-bottom.apexcharts-align-left, .apexcharts-legend.apx-legend-position-top.apexcharts-align-left, .apexcharts-legend.apx-legend-position-right, .apexcharts-legend.apx-legend-position-left {\t\n        justify-content: flex-start;\t\n      }\t\n      .apexcharts-legend.apx-legend-position-bottom.apexcharts-align-center, .apexcharts-legend.apx-legend-position-top.apexcharts-align-center {\t\n        justify-content: center;  \t\n      }\t\n      .apexcharts-legend.apx-legend-position-bottom.apexcharts-align-right, .apexcharts-legend.apx-legend-position-top.apexcharts-align-right {\t\n        justify-content: flex-end;\t\n      }\t\n      .apexcharts-legend-series {\t\n        cursor: pointer;\t\n        line-height: normal;\t\n      }\t\n      .apexcharts-legend.apx-legend-position-bottom .apexcharts-legend-series, .apexcharts-legend.apx-legend-position-top .apexcharts-legend-series{\t\n        display: flex;\t\n        align-items: center;\t\n      }\t\n      .apexcharts-legend-text {\t\n        position: relative;\t\n        font-size: 14px;\t\n      }\t\n      .apexcharts-legend-text *, .apexcharts-legend-marker * {\t\n        pointer-events: none;\t\n      }\t\n      .apexcharts-legend-marker {\t\n        position: relative;\t\n        display: inline-block;\t\n        cursor: pointer;\t\n        margin-right: 3px;\t\n        border-style: solid;\n      }\t\n      \t\n      .apexcharts-legend.apexcharts-align-right .apexcharts-legend-series, .apexcharts-legend.apexcharts-align-left .apexcharts-legend-series{\t\n        display: inline-block;\t\n      }\t\n      .apexcharts-legend-series.apexcharts-no-click {\t\n        cursor: auto;\t\n      }\t\n      .apexcharts-legend .apexcharts-hidden-zero-series, .apexcharts-legend .apexcharts-hidden-null-series {\t\n        display: none !important;\t\n      }\t\n      .apexcharts-inactive-legend {\t\n        opacity: 0.45;\t\n      }");return t.appendChild(e),t}},{key:"getLegendBBox",value:function(){var t=this.w.globals.dom.baseEl.querySelector(".apexcharts-legend").getBoundingClientRect(),e=t.width;return{clwh:t.height,clww:e}}},{key:"appendToForeignObject",value:function(){var t=this.w.globals;t.dom.elLegendForeign=document.createElementNS(t.SVGNS,"foreignObject");var e=t.dom.elLegendForeign;e.setAttribute("x",0),e.setAttribute("y",0),e.setAttribute("width",t.svgWidth),e.setAttribute("height",t.svgHeight),t.dom.elLegendWrap.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),e.appendChild(t.dom.elLegendWrap),e.appendChild(this.getLegendStyles()),t.dom.Paper.node.insertBefore(e,t.dom.elGraphical.node)}},{key:"toggleDataSeries",value:function(t,e){var i=this,a=this.w;if(a.globals.axisCharts||"radialBar"===a.config.chart.type){a.globals.resized=!0;var s=null,r=null;if(a.globals.risingSeries=[],a.globals.axisCharts?(s=a.globals.dom.baseEl.querySelector(".apexcharts-series[data\\:realIndex='".concat(t,"']")),r=parseInt(s.getAttribute("data:realIndex"),10)):(s=a.globals.dom.baseEl.querySelector(".apexcharts-series[rel='".concat(t+1,"']")),r=parseInt(s.getAttribute("rel"),10)-1),e)[{cs:a.globals.collapsedSeries,csi:a.globals.collapsedSeriesIndices},{cs:a.globals.ancillaryCollapsedSeries,csi:a.globals.ancillaryCollapsedSeriesIndices}
61903].forEach((function(t){i.riseCollapsedSeries(t.cs,t.csi,r)}));else this.hideSeries({seriesEl:s,realIndex:r})}else{var o=a.globals.dom.Paper.select(" .apexcharts-series[rel='".concat(t+1,"'] path")),n=a.config.chart.type;if("pie"===n||"polarArea"===n||"donut"===n){var l=a.config.plotOptions.pie.donut.labels;new b(this.lgCtx.ctx).pathMouseDown(o.members[0],null),this.lgCtx.ctx.pie.printDataLabelsInner(o.members[0].node,l)}o.fire("click")}}},{key:"hideSeries",value:function(t){var e=t.seriesEl,i=t.realIndex,a=this.w,s=p.clone(a.config.series);if(a.globals.axisCharts){var r=!1;if(a.config.yaxis[i]&&a.config.yaxis[i].show&&a.config.yaxis[i].showAlways&&(r=!0,a.globals.ancillaryCollapsedSeriesIndices.indexOf(i)<0&&(a.globals.ancillaryCollapsedSeries.push({index:i,data:s[i].data.slice(),type:e.parentNode.className.baseVal.split("-")[1]}),a.globals.ancillaryCollapsedSeriesIndices.push(i))),!r){a.globals.collapsedSeries.push({index:i,data:s[i].data.slice(),type:e.parentNode.className.baseVal.split("-")[1]}),a.globals.collapsedSeriesIndices.push(i);var o=a.globals.risingSeries.indexOf(i);a.globals.risingSeries.splice(o,1)}}else a.globals.collapsedSeries.push({index:i,data:s[i]}),a.globals.collapsedSeriesIndices.push(i);for(var n=e.childNodes,l=0;l<n.length;l++)n[l].classList.contains("apexcharts-series-markers-wrap")&&(n[l].classList.contains("apexcharts-hide")?n[l].classList.remove("apexcharts-hide"):n[l].classList.add("apexcharts-hide"));a.globals.allSeriesCollapsed=a.globals.collapsedSeries.length===a.config.series.length,s=this._getSeriesBasedOnCollapsedState(s),this.lgCtx.ctx.updateHelpers._updateSeries(s,a.config.chart.animations.dynamicAnimation.enabled)}},{key:"riseCollapsedSeries",value:function(t,e,i){var a=this.w,s=p.clone(a.config.series);if(t.length>0){for(var r=0;r<t.length;r++)t[r].index===i&&(a.globals.axisCharts?(s[i].data=t[r].data.slice(),t.splice(r,1),e.splice(r,1),a.globals.risingSeries.push(i)):(s[i]=t[r].data,t.splice(r,1),e.splice(r,1),a.globals.risingSeries.push(i)));s=this._getSeriesBasedOnCollapsedState(s),this.lgCtx.ctx.updateHelpers._updateSeries(s,a.config.chart.animations.dynamicAnimation.enabled)}}},{key:"_getSeriesBasedOnCollapsedState",value:function(t){var e=this.w;return e.globals.axisCharts?t.forEach((function(i,a){e.globals.collapsedSeriesIndices.indexOf(a)>-1&&(t[a].data=[])})):t.forEach((function(i,a){e.globals.collapsedSeriesIndices.indexOf(a)>-1&&(t[a]=0)})),t}}]),t}(),lt=function(){function t(e,i){a(this,t),this.ctx=e,this.w=e.w,this.onLegendClick=this.onLegendClick.bind(this),this.onLegendHovered=this.onLegendHovered.bind(this),this.isBarsDistributed="bar"===this.w.config.chart.type&&this.w.config.plotOptions.bar.distributed&&1===this.w.config.series.length,this.legendHelpers=new nt(this)}return r(t,[{key:"init",value:function(){var t=this.w,e=t.globals,i=t.config;if((i.legend.showForSingleSeries&&1===e.series.length||this.isBarsDistributed||e.series.length>1||!e.axisCharts)&&i.legend.show){for(;e.dom.elLegendWrap.firstChild;)e.dom.elLegendWrap.removeChild(e.dom.elLegendWrap.firstChild);this.drawLegends(),p.isIE11()?document.getElementsByTagName("head")[0].appendChild(this.legendHelpers.getLegendStyles()):this.legendHelpers.appendToForeignObject(),"bottom"===i.legend.position||"top"===i.legend.position?this.legendAlignHorizontal():"right"!==i.legend.position&&"left"!==i.legend.position||this.legendAlignVertical()}}},{key:"drawLegends",value:function(){var t=this,e=this.w,i=e.config.legend.fontFamily,a=e.globals.seriesNames,s=e.globals.colors.slice();if("heatmap"===e.config.chart.type){var r=e.config.plotOptions.heatmap.colorScale.ranges;a=r.map((function(t){return t.name?t.name:t.from+" - "+t.to})),s=r.map((function(t){return t.color}))}else this.isBarsDistributed&&(a=e.globals.labels.slice());e.config.legend.customLegendItems.length&&(a=e.config.legend.customLegendItems);for(var o=e.globals.legendFormatter,n=e.config.legend.inverseOrder,l=n?a.length-1:0;n?l>=0:l<=a.length-1;n?l--:l++){var h=o(a[l],{seriesIndex:l,w:e}),c=!1,d=!1;if(e.globals.collapsedSeries.length>0)for(var g=0;g<e.globals.collapsedSeries.length;g++)e.globals.collapsedSeries[g].index===l&&(c=!0);if(e.globals.ancillaryCollapsedSeriesIndices.length>0)for(var u=0;u<e.globals.ancillaryCollapsedSeriesIndices.length;u++)e.globals.ancillaryCollapsedSeriesIndices[u]===l&&(d=!0);var f=document.createElement("span");f.classList.add("apexcharts-legend-marker");var x=e.config.legend.markers.offsetX,v=e.config.legend.markers.offsetY,m=e.config.legend.markers.height,w=e.config.legend.markers.width,k=e.config.legend.markers.strokeWidth,A=e.config.legend.markers.strokeColor,S=e.config.legend.markers.radius,C=f.style;
61903C.background=s[l],C.color=s[l],C.setProperty("background",s[l],"important"),e.config.legend.markers.fillColors&&e.config.legend.markers.fillColors[l]&&(C.background=e.config.legend.markers.fillColors[l]),void 0!==e.globals.seriesColors[l]&&(C.background=e.globals.seriesColors[l],C.color=e.globals.seriesColors[l]),C.height=Array.isArray(m)?parseFloat(m[l])+"px":parseFloat(m)+"px",C.width=Array.isArray(w)?parseFloat(w[l])+"px":parseFloat(w)+"px",C.left=(Array.isArray(x)?parseFloat(x[l]):parseFloat(x))+"px",C.top=(Array.isArray(v)?parseFloat(v[l]):parseFloat(v))+"px",C.borderWidth=Array.isArray(k)?k[l]:k,C.borderColor=Array.isArray(A)?A[l]:A,C.borderRadius=Array.isArray(S)?parseFloat(S[l])+"px":parseFloat(S)+"px",e.config.legend.markers.customHTML&&(Array.isArray(e.config.legend.markers.customHTML)?e.config.legend.markers.customHTML[l]&&(f.innerHTML=e.config.legend.markers.customHTML[l]()):f.innerHTML=e.config.legend.markers.customHTML()),b.setAttrs(f,{rel:l+1,"data:collapsed":c||d}),(c||d)&&f.classList.add("apexcharts-inactive-legend");var L=document.createElement("div"),P=document.createElement("span");P.classList.add("apexcharts-legend-text"),P.innerHTML=Array.isArray(h)?h.join(" "):h;var T=e.config.legend.labels.useSeriesColors?e.globals.colors[l]:e.config.legend.labels.colors;T||(T=e.config.chart.foreColor),P.style.color=T,P.style.fontSize=parseFloat(e.config.legend.fontSize)+"px",P.style.fontWeight=e.config.legend.fontWeight,P.style.fontFamily=i||e.config.chart.fontFamily,b.setAttrs(P,{rel:l+1,i:l,"data:default-text":encodeURIComponent(h),"data:collapsed":c||d}),L.appendChild(f),L.appendChild(P);var M=new y(this.ctx);if(!e.config.legend.showForZeroSeries)0===M.getSeriesTotalByIndex(l)&&M.seriesHaveSameValues(l)&&!M.isSeriesNull(l)&&-1===e.globals.collapsedSeriesIndices.indexOf(l)&&-1===e.globals.ancillaryCollapsedSeriesIndices.indexOf(l)&&L.classList.add("apexcharts-hidden-zero-series");e.config.legend.showForNullSeries||M.isSeriesNull(l)&&-1===e.globals.collapsedSeriesIndices.indexOf(l)&&-1===e.globals.ancillaryCollapsedSeriesIndices.indexOf(l)&&L.classList.add("apexcharts-hidden-null-series"),e.globals.dom.elLegendWrap.appendChild(L),e.globals.dom.elLegendWrap.classList.add("apexcharts-align-".concat(e.config.legend.horizontalAlign)),e.globals.dom.elLegendWrap.classList.add("apx-legend-position-"+e.config.legend.position),L.classList.add("apexcharts-legend-series"),L.style.margin="".concat(e.config.legend.itemMargin.vertical,"px ").concat(e.config.legend.itemMargin.horizontal,"px"),e.globals.dom.elLegendWrap.style.width=e.config.legend.width?e.config.legend.width+"px":"",e.globals.dom.elLegendWrap.style.height=e.config.legend.height?e.config.legend.height+"px":"",b.setAttrs(L,{rel:l+1,seriesName:p.escapeString(a[l]),"data:collapsed":c||d}),(c||d)&&L.classList.add("apexcharts-inactive-legend"),e.config.legend.onItemClick.toggleDataSeries||L.classList.add("apexcharts-no-click")}e.globals.dom.elWrap.addEventListener("click",t.onLegendClick,!0),e.config.legend.onItemHover.highlightDataSeries&&0===e.config.legend.customLegendItems.length&&(e.globals.dom.elWrap.addEventListener("mousemove",t.onLegendHovered,!0),e.globals.dom.elWrap.addEventListener("mouseout",t.onLegendHovered,!0))}},{key:"setLegendWrapXY",value:function(t,e){var i=this.w,a=i.globals.dom.baseEl.querySelector(".apexcharts-legend"),s=a.getBoundingClientRect(),r=0,o=0;if("bottom"===i.config.legend.position)o+=i.globals.svgHeight-s.height/2;else if("top"===i.config.legend.position){var n=new ot(this.ctx),l=n.dimHelpers.getTitleSubtitleCoords("title").height,h=n.dimHelpers.getTitleSubtitleCoords("subtitle").height;o=o+(l>0?l-10:0)+(h>0?h-10:0)}a.style.position="absolute",r=r+t+i.config.legend.offsetX,o=o+e+i.config.legend.offsetY,a.style.left=r+"px",a.style.top=o+"px","bottom"===i.config.legend.position?(a.style.top="auto",a.style.bottom=5-i.config.legend.offsetY+"px"):"right"===i.config.legend.position&&(a.style.left="auto",a.style.right=25+i.config.legend.offsetX+"px");["width","height"].forEach((function(t){a.style[t]&&(a.style[t]=parseInt(i.config.legend[t],10)+"px")}))}},{key:"legendAlignHorizontal",value:function(){var t=this.w;t.globals.dom.baseEl.querySelector(".apexcharts-legend").style.right=0;var e=this.legendHelpers.getLegendBBox(),i=new ot(this.ctx),a=i.dimHelpers.getTitleSubtitleCoords("title"),s=i.dimHelpers.getTitleSubtitleCoords("subtitle"),r=0;"bottom"===t.config.legend.position?r=-e.clwh/1.8:"top"===t.config.legend.position&&(r=a.height+s.height+t.config.title.margin+t.config.subtitle.margin-10),this.setLegendWrapXY(20,r)}},{key:"legendAlignVertical",value:function(){var t=this.w,e=this.legendHelpers.getLegendBBox(),i=0;"left"===t.config.legend.position&&(i=20),"right"===t.config.legend.position&&(i=t.globals.svgWidth-e.clww-10),this.setLegendWrapXY(i,20)}},{key:"onLegendHovered",value:function(t){var e=this.w,i=t.target.classList.contains("apexcharts-legend-text")||t.target.classList.contains("apexcharts-legend-marker");if("heatmap"===e.config.chart.type||this.isBarsDistributed){if(i){var a=parseInt(t.target.getAttribute("rel"),10)-1;this.ctx.events.fireEvent("legendHover",[this.ctx,a,this.w]),new z(this.ctx).highlightRangeInSeries(t,t.target)}}else!t.target.classList.contains("apexcharts-inactive-legend")&&i&&new z(this.ctx).toggleSeriesOnHover(t,t.target)}},{key:"onLegendClick",value:function(t){var e=this.w;if(!e.config.legend.customLegendItems.length&&(t.target.classList.contains("apexcharts-legend-text")||t.target.classList.contains("apexcharts-legend-marker"))){var i=parseInt(t.target.getAttribute("rel"),10)-1,a="true"===t.target.getAttribute("data:collapsed"),s=this.w.config.chart.events.legendClick;"function"==typeof s&&s(this.ctx,i,this.w),this.ctx.events.fireEvent("legendClick",[this.ctx,i,this.w]);var r=this.w.config.legend.markers.onClick;"function"==typeof r&&t.target.classList.contains("apexcharts-legend-marker")&&(r(this.ctx,i,this.w),this.ctx.events.fireEvent("legendMarkerClick",[this.ctx,i,this.w])),"treemap"!==e.config.chart.type&&"heatmap"!==e.config.chart.type&&!this.isBarsDistributed&&e.config.legend.onItemClick.toggleDataSeries&&this.legendHelpers.toggleDataSeries(i,a)}}}]),t}(),ht=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w;var i=this.w;this.ev=this.w.config.chart.events,this.selectedClass="apexcharts-selected",this.localeValues=this.w.globals.locale.toolbar,this.minX=i.globals.minX,this.maxX=i.globals.maxX}return r(t,[{key:"createToolbar",value:function(){var t=this,e=this.w,i=function(){return document.createElement("div")},a=i();if(a.setAttribute("class","apexcharts-toolbar"),a.style.top=e.config.chart.toolbar.offsetY+"px",a.style.right=3-e.config.chart.toolbar.offsetX+"px",e.globals.dom.elWrap.appendChild(a),this.elZoom=i(),this.elZoomIn=i(),this.elZoomOut=i(),this.elPan=i(),this.elSelection=i(),this.elZoomReset=i(),this.elMenuIcon=i(),this.elMenu=i(),this.elCustomIcons=[],this.t=e.config.chart.toolbar.tools,Array.isArray(this.t.customIcons))for(var s=0;s<this.t.customIcons.length;s++)this.elCustomIcons.push(i());var r=[],o=function(i,a,s){var o=i.toLowerCase();t.t[o]&&e.config.chart.zoom.enabled&&r.push({el:a,icon:"string"==typeof t.t[o]?t.t[o]:s,title:t.localeValues[i],class:"apexcharts-".concat(o,"-icon")})};o("zoomIn",this.elZoomIn,'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">\n    <path d="M0 0h24v24H0z" fill="none"/>\n    <path d="M13 7h-2v4H7v2h4v4h2v-4h4v-2h-4V7zm-1-5C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/>\n</svg>\n'),o("zoomOut",this.elZoomOut,'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">\n    <path d="M0 0h24v24H0z" fill="none"/>\n    <path d="M7 11v2h10v-2H7zm5-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/>\n</svg>\n');var n=function(i){t.t[i]&&e.config.chart[i].enabled&&r.push({el:"zoom"===i?t.elZoom:t.elSelection,icon:"string"==typeof t.t[i]?t.t[i]:"zoom"===i?'<svg xmlns="http://www.w3.org/2000/svg" fill="#000000" height="24" viewBox="0 0 24 24" width="24">\n    <path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/>\n    <path d="M0 0h24v24H0V0z" fill="none"/>\n    <path d="M12 10h-2v2H9v-2H7V9h2V7h1v2h2v1z"/>\n</svg>':'<svg fill="#6E8192" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">\n    <path d="M0 0h24v24H0z" fill="none"/>\n    <path d="M3 5h2V3c-1.1 0-2 .9-2 2zm0 8h2v-2H3v2zm4 8h2v-2H7v2zM3 9h2V7H3v2zm10-6h-2v2h2V3zm6 0v2h2c0-1.1-.9-2-2-2zM5 21v-2H3c0 1.1.9 2 2 2zm-2-4h2v-2H3v2zM9 3H7v2h2V3zm2 18h2v-2h-2v2zm8-8h2v-2h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2zm0-12h2V7h-2v2zm0 8h2v-2h-2v2zm-4 4h2v-2h-2v2zm0-16h2V3h-2v2z"/>\n</svg>',title:t.localeValues["zoom"===i?"selectionZoom":"selection"],class:e.globals.isTouchDevice?"apexcharts-element-hidden":"apexcharts-".concat(i,"-icon")})};n("zoom"),n("selection"),this.t.pan&&e.config.chart.zoom.enabled&&r.push({el:this.elPan,icon:"string"==typeof this.t.pan?this.t.pan:'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#000000" height="24" viewBox="0 0 24 24" width="24">\n    <defs>\n        <path d="M0 0h24v24H0z" id="a"/>\n    </defs>\n    <clipPath id="b">\n        <use overflow="visible" xlink:href="#a"/>\n    </clipPath>\n    <path clip-path="url(#b)" d="M23 5.5V20c0 2.2-1.8 4-4 4h-7.3c-1.08 
619030-2.1-.43-2.85-1.19L1 14.83s1.26-1.23 1.3-1.25c.22-.19.49-.29.79-.29.22 0 .42.06.6.16.04.01 4.31 2.46 4.31 2.46V4c0-.83.67-1.5 1.5-1.5S11 3.17 11 4v7h1V1.5c0-.83.67-1.5 1.5-1.5S15 .67 15 1.5V11h1V2.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5V11h1V5.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5z"/>\n</svg>',title:this.localeValues.pan,class:e.globals.isTouchDevice?"apexcharts-element-hidden":"apexcharts-pan-icon"}),o("reset",this.elZoomReset,'<svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">\n    <path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/>\n    <path d="M0 0h24v24H0z" fill="none"/>\n</svg>'),this.t.download&&r.push({el:this.elMenuIcon,icon:"string"==typeof this.t.download?this.t.download:'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"/><path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"/></svg>',title:this.localeValues.menu,class:"apexcharts-menu-icon"});for(var l=0;l<this.elCustomIcons.length;l++)r.push({el:this.elCustomIcons[l],icon:this.t.customIcons[l].icon,title:this.t.customIcons[l].title,index:this.t.customIcons[l].index,class:"apexcharts-toolbar-custom-icon "+this.t.customIcons[l].class});r.forEach((function(t,e){t.index&&p.moveIndexInArray(r,e,t.index)}));for(var h=0;h<r.length;h++)b.setAttrs(r[h].el,{class:r[h].class,title:r[h].title}),r[h].el.innerHTML=r[h].icon,a.appendChild(r[h].el);this._createHamburgerMenu(a),e.globals.zoomEnabled?this.elZoom.classList.add(this.selectedClass):e.globals.panEnabled?this.elPan.classList.add(this.selectedClass):e.globals.selectionEnabled&&this.elSelection.classList.add(this.selectedClass),this.addToolbarEventListeners()}},{key:"_createHamburgerMenu",value:function(t){this.elMenuItems=[],t.appendChild(this.elMenu),b.setAttrs(this.elMenu,{class:"apexcharts-menu"});var e=[{name:"exportSVG",title:this.localeValues.exportToSVG},{name:"exportPNG",title:this.localeValues.exportToPNG},{name:"exportCSV",title:this.localeValues.exportToCSV}];this.w.globals.allSeriesHasEqualX||e.splice(2,1);for(var i=0;i<e.length;i++)this.elMenuItems.push(document.createElement("div")),this.elMenuItems[i].innerHTML=e[i].title,b.setAttrs(this.elMenuItems[i],{class:"apexcharts-menu-item ".concat(e[i].name),title:e[i].title}),this.elMenu.appendChild(this.elMenuItems[i])}},{key:"addToolbarEventListeners",value:function(){var t=this;this.elZoomReset.addEventListener("click",this.handleZoomReset.bind(this)),this.elSelection.addEventListener("click",this.toggleZoomSelection.bind(this,"selection")),this.elZoom.addEventListener("click",this.toggleZoomSelection.bind(this,"zoom")),this.elZoomIn.addEventListener("click",this.handleZoomIn.bind(this)),this.elZoomOut.addEventListener("click",this.handleZoomOut.bind(this)),this.elPan.addEventListener("click",this.togglePanning.bind(this)),this.elMenuIcon.addEventListener("click",this.toggleMenu.bind(this)),this.elMenuItems.forEach((function(e){e.classList.contains("exportSVG")?e.addEventListener("click",t.handleDownload.bind(t,"svg")):e.classList.contains("exportPNG")?e.addEventListener("click",t.handleDownload.bind(t,"png")):e.classList.contains("exportCSV")&&e.addEventListener("click",t.handleDownload.bind(t,"csv"))}));for(var e=0;e<this.t.customIcons.length;e++)this.elCustomIcons[e].addEventListener("click",this.t.customIcons[e].click.bind(this,this.ctx,this.ctx.w))}},{key:"toggleZoomSelection",value:function(t){this.ctx.getSyncedCharts().forEach((function(e){e.ctx.toolbar.toggleOtherControls();var i="selection"===t?e.ctx.toolbar.elSelection:e.ctx.toolbar.elZoom,a="selection"===t?"selectionEnabled":"zoomEnabled";e.w.globals[a]=!e.w.globals[a],i.classList.contains(e.ctx.toolbar.selectedClass)?i.classList.remove(e.ctx.toolbar.selectedClass):i.classList.add(e.ctx.toolbar.selectedClass)}))}},{key:"getToolbarIconsReference",value:function(){var t=this.w;this.elZoom||(this.elZoom=t.globals.dom.baseEl.querySelector(".apexcharts-zoom-icon")),this.elPan||(this.elPan=t.globals.dom.baseEl.querySelector(".apexcharts-pan-icon")),this.elSelection||(this.elSelection=t.globals.dom.baseEl.querySelector(".apexcharts-selection-icon"))}},{key:"enableZoomPanFromToolbar",value:function(t){this.toggleOtherControls(),"pan"===t?this.w.globals.panEnabled=!0:this.w.globals.zoomEnabled=!0;var e="pan"===t?this.elPan:this.elZoom,i="pan"===t?this.elZoom:this.elPan;e&&e.classList.add(this.selectedClass),i&&i.classList.remove(this.selectedClass)}},{key:"togglePanning",value:function(){this.ctx.getSyncedCharts().forEac
vendor: 5,234 bytes, line 61903
61903h((function(t){t.ctx.toolbar.toggleOtherControls(),t.w.globals.panEnabled=!t.w.globals.panEnabled,t.ctx.toolbar.elPan.classList.contains(t.ctx.toolbar.selectedClass)?t.ctx.toolbar.elPan.classList.remove(t.ctx.toolbar.selectedClass):t.ctx.toolbar.elPan.classList.add(t.ctx.toolbar.selectedClass)}))}},{key:"toggleOtherControls",value:function(){var t=this,e=this.w;e.globals.panEnabled=!1,e.globals.zoomEnabled=!1,e.globals.selectionEnabled=!1,this.getToolbarIconsReference(),[this.elPan,this.elSelection,this.elZoom].forEach((function(e){e&&e.classList.remove(t.selectedClass)}))}},{key:"handleZoomIn",value:function(){var t=this.w;t.globals.isRangeBar&&(this.minX=t.globals.minY,this.maxX=t.globals.maxY);var e=(this.minX+this.maxX)/2,i=(this.minX+e)/2,a=(this.maxX+e)/2,s=this._getNewMinXMaxX(i,a);t.globals.disableZoomIn||this.zoomUpdateOptions(s.minX,s.maxX)}},{key:"handleZoomOut",value:function(){var t=this.w;if(t.globals.isRangeBar&&(this.minX=t.globals.minY,this.maxX=t.globals.maxY),!("datetime"===t.config.xaxis.type&&new Date(this.minX).getUTCFullYear()<1e3)){var e=(this.minX+this.maxX)/2,i=this.minX-(e-this.minX),a=this.maxX-(e-this.maxX),s=this._getNewMinXMaxX(i,a);t.globals.disableZoomOut||this.zoomUpdateOptions(s.minX,s.maxX)}}},{key:"_getNewMinXMaxX",value:function(t,e){var i=this.w.config.xaxis.convertedCatToNumeric;return{minX:i?Math.floor(t):t,maxX:i?Math.floor(e):e}}},{key:"zoomUpdateOptions",value:function(t,e){var i=this.w;if(void 0!==t||void 0!==e){if(!(i.config.xaxis.convertedCatToNumeric&&(t<1&&(t=1,e=i.globals.dataPoints),e-t<2))){var a={min:t,max:e},s=this.getBeforeZoomRange(a);s&&(a=s.xaxis);var r={xaxis:a},o=p.clone(i.globals.initialConfig.yaxis);if(i.config.chart.zoom.autoScaleYaxis)o=new j(this.ctx).autoScaleY(this.ctx,o,{xaxis:a});i.config.chart.group||(r.yaxis=o),this.w.globals.zoomed=!0,this.ctx.updateHelpers._updateOptions(r,!1,this.w.config.chart.animations.dynamicAnimation.enabled),this.zoomCallback(a,o)}}else this.handleZoomReset()}},{key:"zoomCallback",value:function(t,e){"function"==typeof this.ev.zoomed&&this.ev.zoomed(this.ctx,{xaxis:t,yaxis:e})}},{key:"getBeforeZoomRange",value:function(t,e){var i=null;return"function"==typeof this.ev.beforeZoom&&(i=this.ev.beforeZoom(this,{xaxis:t,yaxis:e})),i}},{key:"toggleMenu",value:function(){var t=this;window.setTimeout((function(){t.elMenu.classList.contains("apexcharts-menu-open")?t.elMenu.classList.remove("apexcharts-menu-open"):t.elMenu.classList.add("apexcharts-menu-open")}),0)}},{key:"handleDownload",value:function(t){var e=this.w,i=new V(this.ctx);switch(t){case"svg":i.exportToSVG(this.ctx);break;case"png":i.exportToPng(this.ctx);break;case"csv":i.exportToCSV({series:e.config.series,columnDelimiter:e.config.chart.toolbar.export.csv.columnDelimiter})}}},{key:"handleZoomReset",value:function(t){this.ctx.getSyncedCharts().forEach((function(t){var e=t.w;if(e.globals.lastXAxis.min=void 0,e.globals.lastXAxis.max=void 0,t.updateHelpers.revertDefaultAxisMinMax(),"function"==typeof e.config.chart.events.beforeResetZoom){var i=e.config.chart.events.beforeResetZoom(t,e);i&&t.updateHelpers.revertDefaultAxisMinMax(i)}"function"==typeof e.config.chart.events.zoomed&&t.ctx.toolbar.zoomCallback({min:e.config.xaxis.min,max:e.config.xaxis.max}),e.globals.zoomed=!1;var a=t.ctx.series.emptyCollapsedSeries(p.clone(e.globals.initialSeries));t.updateHelpers._updateSeries(a,e.config.chart.animations.dynamicAnimation.enabled)}))}},{key:"destroy",value:function(){this.elZoom=null,this.elZoomIn=null,this.elZoomOut=null,this.elPan=null,this.elSelection=null,this.elZoomReset=null,this.elMenuIcon=null}}]),t}(),ct=function(t){n(i,t);var e=d(i);function i(t){var s;return a(this,i),(s=e.call(this,t)).ctx=t,s.w=t.w,s.dragged=!1,s.graphics=new b(s.ctx),s.eventList=["mousedown","mouseleave","mousemove","touchstart","touchmove","mouseup","touchend"],s.clientX=0,s.clientY=0,s.startX=0,s.endX=0,s.dragX=0,s.startY=0,s.endY=0,s.dragY=0,s.moveDirection="none",s}return r(i,[{key:"init",value:function(t){var e=this,i=t.xyRatios,a=this.w,s=this;this.xyRatios=i,this.zoomRect=this.graphics.drawRect(0,0,0,0),this.selectionRect=this.graphics.drawRect(0,0,0,0),this.gridRect=a.globals.dom.baseEl.querySelector(".apexcharts-grid"),this.zoomRect.node.classList.add("apexcharts-zoom-rect"),this.selectionRect.node.classList.add("apexcharts-selection-rect"),a.globals.dom.elGraphical.add(this.zoomRect),a.globals.dom.elGraphical.add(this.selectionRect),"x"===a.config.chart.selection.type?this.slDraggableRect=this.selectionRect.draggable({minX:0,minY:0,maxX:a.globals.gridWidth,maxY:a.globals.gridHeight}).on("dragmove",this.selectionDragging.bind(this,"dragging")):"y"===a.config.chart.selection.type?this.slDraggableRect=this.selectionRect.draggable({minX:0,maxX:a.globals.gridWidth}).on("dragmove",this.selectionDragging.bind(this,"dragging")):this.slDraggableRect=this.selectionRect.draggable().on("dragmove",this.selectionDragging.bind(this,"dragging")),this.preselectedSelection(),this.hoverArea=a.globals.dom.baseEl.querySelector("".concat(a.globals.chartClass," .apexcharts-svg")),this.hoverArea.classList.add("apexcharts-zoomable"),this.eventList.forEach((function(t){e.hoverArea.addEventListener(t,s.svgMouseEvents.bind(s,i),{
61903capture:!1,passive:!0})}))}},{key:"destroy",value:function(){this.slDraggableRect&&(this.slDraggableRect.draggable(!1),this.slDraggableRect.off(),this.selectionRect.off()),this.selectionRect=null,this.zoomRect=null,this.gridRect=null}},{key:"svgMouseEvents",value:function(t,e){var i=this.w,a=this,s=this.ctx.toolbar,r=i.globals.zoomEnabled?i.config.chart.zoom.type:i.config.chart.selection.type,o=i.config.chart.toolbar.autoSelected;if(e.shiftKey?(this.shiftWasPressed=!0,s.enableZoomPanFromToolbar("pan"===o?"zoom":"pan")):this.shiftWasPressed&&(s.enableZoomPanFromToolbar(o),this.shiftWasPressed=!1),e.target){var n,l=e.target.classList;if(e.target.parentNode&&null!==e.target.parentNode&&(n=e.target.parentNode.classList),!(l.contains("apexcharts-selection-rect")||l.contains("apexcharts-legend-marker")||l.contains("apexcharts-legend-text")||n&&n.contains("apexcharts-toolbar"))){if(a.clientX="touchmove"===e.type||"touchstart"===e.type?e.touches[0].clientX:"touchend"===e.type?e.changedTouches[0].clientX:e.clientX,a.clientY="touchmove"===e.type||"touchstart"===e.type?e.touches[0].clientY:"touchend"===e.type?e.changedTouches[0].clientY:e.clientY,"mousedown"===e.type&&1===e.which){var h=a.gridRect.getBoundingClientRect();a.startX=a.clientX-h.left,a.startY=a.clientY-h.top,a.dragged=!1,a.w.globals.mousedown=!0}if(("mousemove"===e.type&&1===e.which||"touchmove"===e.type)&&(a.dragged=!0,i.globals.panEnabled?(i.globals.selection=null,a.w.globals.mousedown&&a.panDragging({context:a,zoomtype:r,xyRatios:t})):(a.w.globals.mousedown&&i.globals.zoomEnabled||a.w.globals.mousedown&&i.globals.selectionEnabled)&&(a.selection=a.selectionDrawing({context:a,zoomtype:r}))),"mouseup"===e.type||"touchend"===e.type||"mouseleave"===e.type){var c=a.gridRect.getBoundingClientRect();a.w.globals.mousedown&&(a.endX=a.clientX-c.left,a.endY=a.clientY-c.top,a.dragX=Math.abs(a.endX-a.startX),a.dragY=Math.abs(a.endY-a.startY),(i.globals.zoomEnabled||i.globals.selectionEnabled)&&a.selectionDrawn({context:a,zoomtype:r}),i.globals.panEnabled&&i.config.xaxis.convertedCatToNumeric&&a.delayedPanScrolled()),i.globals.zoomEnabled&&a.hideSelectionRect(this.selectionRect),a.dragged=!1,a.w.globals.mousedown=!1}this.makeSelectionRectDraggable()}}}},{key:"makeSelectionRectDraggable",value:function(){var t=this.w;if(this.selectionRect){var e=this.selectionRect.node.getBoundingClientRect();e.width>0&&e.height>0&&this.slDraggableRect.selectize({points:"l, r",pointSize:8,pointType:"rect"}).resize({constraint:{minX:0,minY:0,maxX:t.globals.gridWidth,maxY:t.globals.gridHeight}}).on("resizing",this.selectionDragging.bind(this,"resizing"))}}},{key:"preselectedSelection",value:function(){var t=this.w,e=this.xyRatios;if(!t.globals.zoomEnabled)if(void 0!==t.globals.selection&&null!==t.globals.selection)this.drawSelectionRect(t.globals.selection);else if(void 0!==t.config.chart.selection.xaxis.min&&void 0!==t.config.chart.selection.xaxis.max){var i=(t.config.chart.selection.xaxis.min-t.globals.minX)/e.xRatio,a={x:i,y:0,width:t.globals.gridWidth-(t.globals.maxX-t.config.chart.selection.xaxis.max)/e.xRatio-i,height:t.globals.gridHeight,translateX:0,translateY:0,selectionEnabled:!0};this.drawSelectionRect(a),this.makeSelectionRectDraggable(),"function"==typeof t.config.chart.events.selection&&t.config.chart.events.selection(this.ctx,{xaxis:{min:t.config.chart.selection.xaxis.min,max:t.config.chart.selection.xaxis.max},yaxis:{}})}}},{key:"drawSelectionRect",value:function(t){var e=t.x,i=t.y,a=t.width,s=t.height,r=t.translateX,o=void 0===r?0:r,n=t.translateY,l=void 0===n?0:n,h=this.w,c=this.zoomRect,d=this.selectionRect;if(this.dragged||null!==h.globals.selection){var g={transform:"translate("+o+", "+l+")"};h.globals.zoomEnabled&&this.dragged&&(a<0&&(a=1),c.attr({x:e,y:i,width:a,height:s,fill:h.config.chart.zoom.zoomedArea.fill.color,"fill-opacity":h.config.chart.zoom.zoomedArea.fill.opacity,stroke:h.config.chart.zoom.zoomedArea.stroke.color,"stroke-width":h.config.chart.zoom.zoomedArea.stroke.width,"stroke-opacity":h.config.chart.zoom.zoomedArea.stroke.opacity}),b.setAttrs(c.node,g)),h.globals.selectionEnabled&&(d.attr({x:e,y:i,width:a>0?a:0,height:s>0?s:0,fill:h.config.chart.selection.fill.color,"fill-opacity":h.config.chart.selection.fill.opacity,stroke:h.config.chart.selection.stroke.color,"stroke-width":h.config.chart.selection.stroke.width,"stroke-dasharray":h.config.chart.selection.stroke.dashArray,"stroke-opacity":h.config.chart.selection.stroke.opacity}),b.setAttrs(d.node,g))}}},{key:"hideSelectionRect",value:function(t){t&&t.attr({x:0,y:0,width:0,height:0})}},{key:"selectionDrawing",value:function(t){var e=t.context,i=t.zoomtype,a=this.w,s=e,r=this.gridRect.getBoundingClientRect(),o=s.startX-1,n=s.startY,l=!1,h=!1,c=s.clientX-r.left-o,d=s.clientY-r.top-n,g={};return Math.abs(c+o)>a.globals.gridWidth?c=a.globals.gridWidth-o:s.clientX-r.left<0&&(c=o),o>s.clientX-r.left&&(l=!0,c=Math.abs(c)),n>s.clientY-r.top&&(h=!0,d=Math.abs(d)),g="x"===i?{x:l?o-c:o,y:0,width:c,height:a.globals.gridHeight}:"y"===i?{x:0,y:h?n-d:n,width:a.globals.gridWidth,height:d}:{x:l?o-c:o,y:h?n-d:n,width:c,height:d},s.drawSelectionRect(g),s.selectionDragging("resizing"),g}},{key:"selectionDragging",value:function(t,e){var i=this,a=this.w,s=this.xyRatios,r=this.selectionRect,o=0;"resizing"===t&&(o=30);var n=function(t){return parseFloat(r.node.getAttribute(t))},l={x:n("x"),y:n("y"),width:n("width"),height:n("height")};a.globals.selection=l,"function"==typeof a.config.chart.events.selection&&a.globals.selectionEnabled&&(clearTimeout(this.w.globals.selectionResizeTimer),this.w.globals.selectionResizeTimer=window.setTimeout((function(){var t=i.gridRect.getBoundingClientRect(),e=r.node.getBoundingClientRect(),o={xaxis:{min:a.globals.xAxisScale.niceMin+(e.left-t.left)*s.xRatio,max:a.globals.xAxisScale.niceMin+(e.right-t.left)*s.xRatio},yaxis:{min:a.globals.yAxisScale[0].niceMin+(t.bottom-e.bottom)*s.yRatio[0],max:a.globals.yAxisScale[0].niceMax-(e.top-t.top)*s.yRatio[0]}};
61903a.config.chart.events.selection(i.ctx,o),a.config.chart.brush.enabled&&void 0!==a.config.chart.events.brushScrolled&&a.config.chart.events.brushScrolled(i.ctx,o)}),o))}},{key:"selectionDrawn",value:function(t){var e=t.context,i=t.zoomtype,a=this.w,s=e,r=this.xyRatios,o=this.ctx.toolbar;if(s.startX>s.endX){var n=s.startX;s.startX=s.endX,s.endX=n}if(s.startY>s.endY){var l=s.startY;s.startY=s.endY,s.endY=l}var h=void 0,c=void 0;a.globals.isRangeBar?(h=a.globals.yAxisScale[0].niceMin+s.startX*r.invertedYRatio,c=a.globals.yAxisScale[0].niceMin+s.endX*r.invertedYRatio):(h=a.globals.xAxisScale.niceMin+s.startX*r.xRatio,c=a.globals.xAxisScale.niceMin+s.endX*r.xRatio);var d=[],g=[];if(a.config.yaxis.forEach((function(t,e){d.push(a.globals.yAxisScale[e].niceMax-r.yRatio[e]*s.startY),g.push(a.globals.yAxisScale[e].niceMax-r.yRatio[e]*s.endY)})),s.dragged&&(s.dragX>10||s.dragY>10)&&h!==c)if(a.globals.zoomEnabled){var u=p.clone(a.globals.initialConfig.yaxis),f=p.clone(a.globals.initialConfig.xaxis);if(a.globals.zoomed=!0,a.config.xaxis.convertedCatToNumeric&&(h=Math.floor(h),c=Math.floor(c),h<1&&(h=1,c=a.globals.dataPoints),c-h<2&&(c=h+1)),"xy"!==i&&"x"!==i||(f={min:h,max:c}),"xy"!==i&&"y"!==i||u.forEach((function(t,e){u[e].min=g[e],u[e].max=d[e]})),a.config.chart.zoom.autoScaleYaxis){var x=new j(s.ctx);u=x.autoScaleY(s.ctx,u,{xaxis:f})}if(o){var b=o.getBeforeZoomRange(f,u);b&&(f=b.xaxis?b.xaxis:f,u=b.yaxis?b.yaxis:u)}var v={xaxis:f};a.config.chart.group||(v.yaxis=u),s.ctx.updateHelpers._updateOptions(v,!1,s.w.config.chart.animations.dynamicAnimation.enabled),"function"==typeof a.config.chart.events.zoomed&&o.zoomCallback(f,u)}else if(a.globals.selectionEnabled){var m,y=null;m={min:h,max:c},"xy"!==i&&"y"!==i||(y=p.clone(a.config.yaxis)).forEach((function(t,e){y[e].min=g[e],y[e].max=d[e]})),a.globals.selection=s.selection,"function"==typeof a.config.chart.events.selection&&a.config.chart.events.selection(s.ctx,{xaxis:m,yaxis:y})}}},{key:"panDragging",value:function(t){var e=t.context,i=this.w,a=e;if(void 0!==i.globals.lastClientPosition.x){var s=i.globals.lastClientPosition.x-a.clientX,r=i.globals.lastClientPosition.y-a.clientY;Math.abs(s)>Math.abs(r)&&s>0?this.moveDirection="left":Math.abs(s)>Math.abs(r)&&s<0?this.moveDirection="right":Math.abs(r)>Math.abs(s)&&r>0?this.moveDirection="up":Math.abs(r)>Math.abs(s)&&r<0&&(this.moveDirection="down")}i.globals.lastClientPosition={x:a.clientX,y:a.clientY};var o=i.globals.isRangeBar?i.globals.minY:i.globals.minX,n=i.globals.isRangeBar?i.globals.maxY:i.globals.maxX;i.config.xaxis.convertedCatToNumeric||a.panScrolled(o,n)}},{key:"delayedPanScrolled",value:function(){var t=this.w,e=t.globals.minX,i=t.globals.maxX,a=(t.globals.maxX-t.globals.minX)/2;"left"===this.moveDirection?(e=t.globals.minX+a,i=t.globals.maxX+a):"right"===this.moveDirection&&(e=t.globals.minX-a,i=t.globals.maxX-a),e=Math.floor(e),i=Math.floor(i),this.updateScrolledChart({xaxis:{min:e,max:i}},e,i)}},{key:"panScrolled",value:function(t,e){var i=this.w,a=this.xyRatios,s=p.clone(i.globals.initialConfig.yaxis),r=a.xRatio,o=i.globals.minX,n=i.globals.maxX;i.globals.isRangeBar&&(r=a.invertedYRatio,o=i.globals.minY,n=i.globals.maxY),"left"===this.moveDirection?(t=o+i.globals.gridWidth/15*r,e=n+i.globals.gridWidth/15*r):"right"===this.moveDirection&&(t=o-i.globals.gridWidth/15*r,e=n-i.globals.gridWidth/15*r),i.globals.isRangeBar||(t<i.globals.initialMinX||e>i.globals.initialMaxX)&&(t=o,e=n);var l={min:t,max:e};i.config.chart.zoom.autoScaleYaxis&&(s=new j(this.ctx).autoScaleY(this.ctx,s,{xaxis:l}));var h={xaxis:{min:t,max:e}};i.config.chart.group||(h.yaxis=s),this.updateScrolledChart(h,t,e)}},{key:"updateScrolledChart",value:function(t,e,i){var a=this.w;this.ctx.updateHelpers._updateOptions(t,!1,!1),"function"==typeof a.config.chart.events.scrolled&&a.config.chart.events.scrolled(this.ctx,{xaxis:{min:e,max:i}})}}]),i}(ht),dt=function(){function t(e){a(this,t),this.w=e.w,this.ttCtx=e,this.ctx=e.ctx}return r(t,[{key:"getNearestValues",value:function(t){var e=t.hoverArea,i=t.elGrid,a=t.clientX,s=t.clientY,r=this.w,o=i.getBoundingClientRect(),n=o.width,l=o.height,h=n/(r.globals.dataPoints-1),c=l/r.globals.dataPoints,d=this.hasBars();!r.globals.comboCharts&&!d||r.config.xaxis.convertedCatToNumeric||(h=n/r.globals.dataPoints);var g=a-o.left-r.globals.barPadForNumericAxis,u=s-o.top;g<0||u<0||g>n||u>l?(e.classList.remove("hovering-zoom"),e.classList.remove("hovering-pan")):r.globals.zoomEnabled?(e.classList.remove("hovering-pan"),e.classList.add("hovering-zoom")):r.globals.panEnabled&&(e.classList.remove("hovering-zoom"),e.classList.add("hovering-pan"));var f=Math.round(g/h),x=Math.floor(u/c);d&&!r.config.xaxis.convertedCatToNumeric&&(f=Math.ceil(g/h),f-=1);for(var b,v=null,m=null,y=[],w=0;w<r.globals.seriesXvalues.length;w++)y.push([r.globals.seriesXvalues[w][0]-1e-6].concat(r.globals.seriesXvalues[w]));if(y=y.map((function(t){return t.filter((function(t){return t}))})),b=r.globals.seriesYvalues.map((function(t){return t.filter((function(t){return p.isNumber(t)}))}
61903)),r.globals.isXNumeric){var k=this.ttCtx.getElGrid().getBoundingClientRect(),A=g*(k.width/n),S=u*(k.height/l);v=(m=this.closestInMultiArray(A,S,y,b)).index,f=m.j,null!==v&&(y=r.globals.seriesXvalues[v],f=(m=this.closestInArray(A,y)).index)}return r.globals.capturedSeriesIndex=null===v?-1:v,(!f||f<1)&&(f=0),r.globals.isBarHorizontal?r.globals.capturedDataPointIndex=x:r.globals.capturedDataPointIndex=f,{capturedSeries:v,j:r.globals.isBarHorizontal?x:f,hoverX:g,hoverY:u}}},{key:"closestInMultiArray",value:function(t,e,i,a){var s=this.w,r=0,o=null,n=-1;s.globals.series.length>1?r=this.getFirstActiveXArray(i):o=0;var l=a[r][0],h=i[r][0],c=Math.abs(t-h),d=Math.abs(e-l),g=d+c;return a.map((function(s,r){s.map((function(s,l){var h=Math.abs(e-a[r][l]),u=Math.abs(t-i[r][l]),p=u+h;p<g&&(g=p,c=u,d=h,o=r,n=l)}))})),{index:o,j:n}}},{key:"getFirstActiveXArray",value:function(t){for(var e=this.w,i=0,a=t.map((function(t,e){return t.length>0?e:-1})),s=0;s<a.length;s++)if(-1!==a[s]&&-1===e.globals.collapsedSeriesIndices.indexOf(s)&&-1===e.globals.ancillaryCollapsedSeriesIndices.indexOf(s)){i=a[s];break}return i}},{key:"closestInArray",value:function(t,e){for(var i=e[0],a=null,s=Math.abs(t-i),r=0;r<e.length;r++){var o=Math.abs(t-e[r]);o<s&&(s=o,a=r)}return{index:a}}},{key:"isXoverlap",value:function(t){var e=[],i=this.w.globals.seriesX.filter((function(t){return void 0!==t[0]}));if(i.length>0)for(var a=0;a<i.length-1;a++)void 0!==i[a][t]&&void 0!==i[a+1][t]&&i[a][t]!==i[a+1][t]&&e.push("unEqual");return 0===e.length}},{key:"isInitialSeriesSameLen",value:function(){for(var t=!0,e=this.w.globals.initialSeries,i=0;i<e.length-1;i++)if(e[i].data.length!==e[i+1].data.length){t=!1;break}return t}},{key:"getBarsHeight",value:function(t){return g(t).reduce((function(t,e){return t+e.getBBox().height}),0)}},{key:"getElMarkers",value:function(){return this.w.globals.dom.baseEl.querySelectorAll(" .apexcharts-series-markers")}},{key:"getAllMarkers",value:function(){var t=this.w.globals.dom.baseEl.querySelectorAll(".apexcharts-series-markers-wrap");(t=g(t)).sort((function(t,e){return Number(e.getAttribute("data:realIndex"))<Number(t.getAttribute("data:realIndex"))?0:-1}));var e=[];return t.forEach((function(t){e.push(t.querySelector(".apexcharts-marker"))})),e}},{key:"hasMarkers",value:function(){return this.getElMarkers().length>0}},{key:"getElBars",value:function(){return this.w.globals.dom.baseEl.querySelectorAll(".apexcharts-bar-series,  .apexcharts-candlestick-series, .apexcharts-boxPlot-series, .apexcharts-rangebar-series")}},{key:"hasBars",value:function(){return this.getElBars().length>0}},{key:"getHoverMarkerSize",value:function(t){var e=this.w,i=e.config.markers.hover.size;return void 0===i&&(i=e.globals.markers.size[t]+e.config.markers.hover.sizeOffset),i}},{key:"toggleAllTooltipSeriesGroups",value:function(t){var e=this.w,i=this.ttCtx;0===i.allTooltipSeriesGroups.length&&(i.allTooltipSeriesGroups=e.globals.dom.baseEl.querySelectorAll(".apexcharts-tooltip-series-group"));for(var a=i.allTooltipSeriesGroups,s=0;s<a.length;s++)"enable"===t?(a[s].classList.add("apexcharts-active"),a[s].style.display=e.config.tooltip.items.display):(a[s].classList.remove("apexcharts-active"),a[s].style.display="none")}}]),t}(),gt=function(){function t(e){a(this,t),this.w=e.w,this.ctx=e.ctx,this.ttCtx=e,this.tooltipUtil=new dt(e)}return r(t,[{key:"drawSeriesTexts",value:function(t){var e=t.shared,i=void 0===e||e,a=t.ttItems,s=t.i,r=void 0===s?0:s,o=t.j,n=void 0===o?null:o,l=t.y1,h=t.y2,c=t.e,d=this.w;void 0!==d.config.tooltip.custom?this.handleCustomTooltip({i:r,j:n,y1:l,y2:h,w:d}):this.toggleActiveInactiveSeries(i);var g=this.getValuesToPrint({i:r,j:n});this.printLabels({i:r,j:n,values:g,ttItems:a,shared:i,e:c});var u=this.ttCtx.getElTooltip();this.ttCtx.tooltipRect.ttWidth=u.getBoundingClientRect().width,this.ttCtx.tooltipRect.ttHeight=u.getBoundingClientRect().height}},{key:"printLabels",value:function(t){var i,a=this,s=t.i,r=t.j,o=t.values,n=t.ttItems,l=t.shared,h=t.e,c=this.w,d=[],g=function(t){return c.globals.seriesGoals[t]&&c.globals.seriesGoals[t][r]&&Array.isArray(c.globals.seriesGoals[t][r])},u=o.xVal,p=o.zVal,f=o.xAxisTTVal,x="",b=c.globals.colors[s];null!==r&&c.config.plotOptions.bar.distributed&&(b=c.globals.colors[r]);for(var v=function(t,o){var v=a.getFormatters(s);
61903x=a.getSeriesName({fn:v.yLbTitleFormatter,index:s,seriesIndex:s,j:r}),"treemap"===c.config.chart.type&&(x=v.yLbTitleFormatter(String(c.config.series[s].data[r].x),{series:c.globals.series,seriesIndex:s,dataPointIndex:r,w:c}));var m=c.config.tooltip.inverseOrder?o:t;if(c.globals.axisCharts){var y=function(t){return v.yLbFormatter(c.globals.series[t][r],{series:c.globals.series,seriesIndex:t,dataPointIndex:r,w:c})};l?(v=a.getFormatters(m),x=a.getSeriesName({fn:v.yLbTitleFormatter,index:m,seriesIndex:s,j:r}),b=c.globals.colors[m],i=y(m),g(m)&&(d=c.globals.seriesGoals[m][r].map((function(t){return{attrs:t,val:v.yLbFormatter(t.value,{seriesIndex:m,dataPointIndex:r,w:c})}})))):(h&&h.target&&h.target.getAttribute("fill")&&(b=h.target.getAttribute("fill")),i=y(s),g(s)&&Array.isArray(c.globals.seriesGoals[s][r])&&(d=c.globals.seriesGoals[s][r].map((function(t){return{attrs:t,val:v.yLbFormatter(t.value,{seriesIndex:s,dataPointIndex:r,w:c})}}))))}null===r&&(i=v.yLbFormatter(c.globals.series[s],e(e({},c),{},{seriesIndex:s,dataPointIndex:s}))),a.DOMHandling({i:s,t:m,j:r,ttItems:n,values:{val:i,goalVals:d,xVal:u,xAxisTTVal:f,zVal:p},seriesName:x,shared:l,pColor:b})},m=0,y=c.globals.series.length-1;m<c.globals.series.length;m++,y--)v(m,y)}},{key:"getFormatters",value:function(t){var e,i=this.w,a=i.globals.yLabelFormatters[t];return void 0!==i.globals.ttVal?Array.isArray(i.globals.ttVal)?(a=i.globals.ttVal[t]&&i.globals.ttVal[t].formatter,e=i.globals.ttVal[t]&&i.globals.ttVal[t].title&&i.globals.ttVal[t].title.formatter):(a=i.globals.ttVal.formatter,"function"==typeof i.globals.ttVal.title.formatter&&(e=i.globals.ttVal.title.formatter)):e=i.config.tooltip.y.title.formatter,"function"!=typeof a&&(a=i.globals.yLabelFormatters[0]?i.globals.yLabelFormatters[0]:function(t){return t}),"function"!=typeof e&&(e=function(t){return t}),{yLbFormatter:a,yLbTitleFormatter:e}}},{key:"getSeriesName",value:function(t){var e=t.fn,i=t.index,a=t.seriesIndex,s=t.j,r=this.w;return e(String(r.globals.seriesNames[i]),{series:r.globals.series,seriesIndex:a,dataPointIndex:s,w:r})}},{key:"DOMHandling",value:function(t){t.i;var e=t.t,i=t.j,a=t.ttItems,s=t.values,r=t.seriesName,o=t.shared,n=t.pColor,l=this.w,h=this.ttCtx,c=s.val,d=s.goalVals,g=s.xVal,u=s.xAxisTTVal,p=s.zVal,f=null;f=a[e].children,l.config.tooltip.fillSeriesColor&&(a[e].style.backgroundColor=n,f[0].style.display="none"),h.showTooltipTitle&&(null===h.tooltipTitle&&(h.tooltipTitle=l.globals.dom.baseEl.querySelector(".apexcharts-tooltip-title")),h.tooltipTitle.innerHTML=g),h.isXAxisTooltipEnabled&&(h.xaxisTooltipText.innerHTML=""!==u?u:g);var x=a[e].querySelector(".apexcharts-tooltip-text-y-label");x&&(x.innerHTML=r||"");var b=a[e].querySelector(".apexcharts-tooltip-text-y-value");b&&(b.innerHTML=void 0!==c?c:""),f[0]&&f[0].classList.contains("apexcharts-tooltip-marker")&&(l.config.tooltip.marker.fillColors&&Array.isArray(l.config.tooltip.marker.fillColors)&&(n=l.config.tooltip.marker.fillColors[e]),f[0].style.backgroundColor=n),l.config.tooltip.marker.show||(f[0].style.display="none");var v=a[e].querySelector(".apexcharts-tooltip-text-goals-label"),m=a[e].querySelector(".apexcharts-tooltip-text-goals-value");if(d.length&&l.globals.seriesGoals[e]){var y=function(){var t="<div >",e="<div>";d.forEach((function(i,a){t+=' <div style="display: flex"><span class="apexcharts-tooltip-marker" style="background-color: '.concat(i.attrs.strokeColor,'; height: 3px; border-radius: 0; top: 5px;"></span> ').concat(i.attrs.name,"</div>"),e+="<div>".concat(i.val,"</div>")})),v.innerHTML=t+"</div>",m.innerHTML=e+"</div>"};o?l.globals.seriesGoals[e][i]&&Array.isArray(l.globals.seriesGoals[e][i])?y():(v.innerHTML="",m.innerHTML=""):y()}else v.innerHTML="",m.innerHTML="";null!==p&&(a[e].querySelector(".apexcharts-tooltip-text-z-label").innerHTML=l.config.tooltip.z.title,a[e].querySelector(".apexcharts-tooltip-text-z-value").innerHTML=void 0!==p?p:"");o&&f[0]&&(null==c||l.globals.ancillaryCollapsedSeriesIndices.indexOf(e)>-1||l.globals.collapsedSeriesIndices.indexOf(e)>-1?f[0].parentNode.style.display="none":f[0].parentNode.style.display=l.config.tooltip.items.display)}},{key:"toggleActiveInactiveSeries",value:function(t){var e=this.w;if(t)this.tooltipUtil.toggleAllTooltipSeriesGroups("enable");else{this.tooltipUtil.toggleAllTooltipSeriesGroups("disable");var i=e.globals.dom.baseEl.querySelector(".apexcharts-tooltip-series-group");i&&(i.classList.add("apexcharts-active"),i.style.display=e.config.tooltip.items.display)}}},{key:"getValuesToPrint",value:function(t){var e=t.i,i=t.j,a=this.w,s=this.ctx.series.filteredSeriesX(),r="",o="",n=null,l=null,h={series:a.globals.series,seriesIndex:e,dataPointIndex:i,w:a},c=a.globals.ttZFormatter;null===i?l=a.globals.series[e]:a.globals.isXNumeric&&"treemap"!==a.config.chart.type?(r=s[e][i],0===s[e].length&&(r=s[this.tooltipUtil.getFirstActiveXArray(s)][i])):r=void 0!==a.globals.labels[i]?a.globals.labels[i]:"";var d=r;a.globals.isXNumeric&&"datetime"===a.config.xaxis.type?r=new W(this.ctx).xLabelFormat(a.globals.ttKeyFormatter,d,d,{i:void 0,dateFormatter:new Y(this.ctx).formatDate,w:this.w}
61903):r=a.globals.isBarHorizontal?a.globals.yLabelFormatters[0](d,h):a.globals.xLabelFormatter(d,h);return void 0!==a.config.tooltip.x.formatter&&(r=a.globals.ttKeyFormatter(d,h)),a.globals.seriesZ.length>0&&a.globals.seriesZ[e].length>0&&(n=c(a.globals.seriesZ[e][i],a)),o="function"==typeof a.config.xaxis.tooltip.formatter?a.globals.xaxisTooltipFormatter(d,h):r,{val:Array.isArray(l)?l.join(" "):l,xVal:Array.isArray(r)?r.join(" "):r,xAxisTTVal:Array.isArray(o)?o.join(" "):o,zVal:n}}},{key:"handleCustomTooltip",value:function(t){var e=t.i,i=t.j,a=t.y1,s=t.y2,r=t.w,o=this.ttCtx.getElTooltip(),n=r.config.tooltip.custom;Array.isArray(n)&&n[e]&&(n=n[e]),o.innerHTML=n({ctx:this.ctx,series:r.globals.series,seriesIndex:e,dataPointIndex:i,y1:a,y2:s,w:r})}}]),t}(),ut=function(){function t(e){a(this,t),this.ttCtx=e,this.ctx=e.ctx,this.w=e.w}return r(t,[{key:"moveXCrosshairs",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,i=this.ttCtx,a=this.w,s=i.getElXCrosshairs(),r=t-i.xcrosshairsWidth/2,o=a.globals.labels.slice().length;if(null!==e&&(r=a.globals.gridWidth/o*e),null===s||a.globals.isBarHorizontal||(s.setAttribute("x",r),s.setAttribute("x1",r),s.setAttribute("x2",r),s.setAttribute("y2",a.globals.gridHeight),s.classList.add("apexcharts-active")),r<0&&(r=0),r>a.globals.gridWidth&&(r=a.globals.gridWidth),i.isXAxisTooltipEnabled){var n=r;"tickWidth"!==a.config.xaxis.crosshairs.width&&"barWidth"!==a.config.xaxis.crosshairs.width||(n=r+i.xcrosshairsWidth/2),this.moveXAxisTooltip(n)}}},{key:"moveYCrosshairs",value:function(t){var e=this.ttCtx;null!==e.ycrosshairs&&b.setAttrs(e.ycrosshairs,{y1:t,y2:t}),null!==e.ycrosshairsHidden&&b.setAttrs(e.ycrosshairsHidden,{y1:t,y2:t})}},{key:"moveXAxisTooltip",value:function(t){var e=this.w,i=this.ttCtx;if(null!==i.xaxisTooltip&&0!==i.xcrosshairsWidth){i.xaxisTooltip.classList.add("apexcharts-active");var a=i.xaxisOffY+e.config.xaxis.tooltip.offsetY+e.globals.translateY+1+e.config.xaxis.offsetY;if(t-=i.xaxisTooltip.getBoundingClientRect().width/2,!isNaN(t)){t+=e.globals.translateX;var s;s=new b(this.ctx).getTextRects(i.xaxisTooltipText.innerHTML),i.xaxisTooltipText.style.minWidth=s.width+"px",i.xaxisTooltip.style.left=t+"px",i.xaxisTooltip.style.top=a+"px"}}}},{key:"moveYAxisTooltip",value:function(t){var e=this.w,i=this.ttCtx;null===i.yaxisTTEls&&(i.yaxisTTEls=e.globals.dom.baseEl.querySelectorAll(".apexcharts-yaxistooltip"));var a=parseInt(i.ycrosshairsHidden.getAttribute("y1"),10),s=e.globals.translateY+a,r=i.yaxisTTEls[t].getBoundingClientRect().height,o=e.globals.translateYAxisX[t]-2;e.config.yaxis[t].opposite&&(o-=26),s-=r/2,-1===e.globals.ignoreYAxisIndexes.indexOf(t)?(i.yaxisTTEls[t].classList.add("apexcharts-active"),i.yaxisTTEls[t].style.top=s+"px",i.yaxisTTEls[t].style.left=o+e.config.yaxis[t].tooltip.offsetX+"px"):i.yaxisTTEls[t].classList.remove("apexcharts-active")}},{key:"moveTooltip",value:function(t,e){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,a=this.w,s=this.ttCtx,r=s.getElTooltip(),o=s.tooltipRect,n=null!==i?parseFloat(i):1,l=parseFloat(t)+n+5,h=parseFloat(e)+n/2;if(l>a.globals.gridWidth/2&&(l=l-o.ttWidth-n-15),l>a.globals.gridWidth-o.ttWidth-10&&(l=a.globals.gridWidth-o.ttWidth),l<-20&&(l=-20),a.config.tooltip.followCursor){var c=s.getElGrid(),d=c.getBoundingClientRect();h=s.e.clientY+a.globals.translateY-d.top-o.ttHeight/2}else a.globals.isBarHorizontal||(o.ttHeight/2+h>a.globals.gridHeight&&(h=a.globals.gridHeight-o.ttHeight+a.globals.translateY),h<0&&(h=0));isNaN(l)||(l+=a.globals.translateX,r.style.left=l+"px",r.style.top=h+"px")}},{key:"moveMarkers",value:function(t,e){var i=this.w,a=this.ttCtx;if(i.globals.markers.size[t]>0)for(var s=i.globals.dom.baseEl.querySelectorAll(" .apexcharts-series[data\\:realIndex='".concat(t,"'] .apexcharts-marker")),r=0;r<s.length;r++)parseInt(s[r].getAttribute("rel"),10)===e&&(a.marker.resetPointsSize(),a.marker.enlargeCurrentPoint(e,s[r]));else a.marker.resetPointsSize(),this.moveDynamicPointOnHover(e,t)}},{key:"moveDynamicPointOnHover",value:function(t,e){var i,a,s=this.w,r=this.ttCtx,o=s.globals.pointsArray,n=r.tooltipUtil.getHoverMarkerSize(e),l=s.config.series[e].type;if(!l||"column"!==l&&"candlestick"!==l&&"boxPlot"!==l){i=o[e][t][0],a=o[e][t][1]?o[e][t][1]:0;var h=s.globals.dom.baseEl.querySelector(".apexcharts-series[data\\:realIndex='".concat(e,"'] .apexcharts-series-markers circle"));h&&a<s.globals.gridHeight&&a>0&&(h.setAttribute("r",n),h.setAttribute("cx",i),h.setAttribute("cy",a)),this.moveXCrosshairs(i),r.fixedTooltip||this.moveTooltip(i,a,n)}}},{key:"moveDynamicPointsOnHover",value:function(t){var e,i=this.ttCtx,a=i.w,s=0,r=0,o=a.globals.pointsArray;e=new z(this.ctx).getActiveConfigSeriesIndex(!0);var n=i.tooltipUtil.getHoverMarkerSize(e);o[e]&&(s=o[e][t][0],r=o[e][t][1]);var l=i.tooltipUtil.getAllMarkers();if(null!==l)for(var h=0;h<a.globals.series.length;h++){var c=o[h];if(a.globals.comboCharts&&void 0===c&&l.splice(h,0,null),c&&c.length){var d=o[h][t][1];l[h].setAttribute("cx",s),null!==d&&!isNaN(d)&&d<a.globals.gridHeight+n&&d+n>0?(l[h]&&l[h].setAttribute("r",n),l[h]&&l[h].setAttribute("cy",d)):l[h]&&l[h].setAttribute("r",0)}}if(this.moveXCrosshairs(s),!i.fixedTooltip){var g=r||a.globals.gridHeight;this.moveTooltip(s,g,n)}}},{key:"moveStickyTooltipOverBars",value:function(t){var e=this.w,i=this.ttCtx,a=e.globals.columnSeries?e.globals.columnSeries.length:e.globals.series.length,s=a>=2&&a%2==0?Math.floor(a/2):Math.floor(a/2)+1;e.globals.isBarHorizontal&&(s=new z(this.ctx).getActiveConfigSeriesIndex(!1,"desc")+1);var r=e.globals.dom.baseEl.querySelector(".apexcharts-bar-series .apexcharts-series[rel='".concat(s,"'] path[j='").concat(t,"'], .apexcharts-candlestick-series .apexcharts-series[rel='").concat(s,"'] path[j='").concat(t,"'], .apexcharts-boxPlot-series .apexcharts-series[rel='").concat(s,"'] path[j='").concat(t,"'], .apexcharts-rangebar-series .apexcharts-series[rel='").concat(s,"'] path[j='").concat(t,"']")),o=r?parseFloat(r.getAttribute("cx")):0,n=r?parseFloat(r.getAttribute("cy")):0,l=r?parseFloat(r.getAttribute("barWidth")):0,h=r?parseFloat(r.getAttribute("barHeight")):0,c=i.getElGrid().getBoundingClientRect(),d=r.classList.contains("apexcharts-candlestick-area")||r.classList.contains("apexcharts-boxPlot-area");if(e.globals.isXNumeric?(r&&!d&&(o-=a%2!=0?l/2:0),r&&d&&e.globals.comboCharts&&(o-=l/2)):e.globals.isBarHorizontal||(o=i.xAxisTicksPositions[t
61903-1]+i.dataPointsDividedWidth/2,isNaN(o)&&(o=i.xAxisTicksPositions[t]-i.dataPointsDividedWidth/2)),e.globals.isBarHorizontal?n+=h/3:n=i.e.clientY-c.top-i.tooltipRect.ttHeight/2,e.globals.isBarHorizontal||this.moveXCrosshairs(o),!i.fixedTooltip){var g=n||e.globals.gridHeight;this.moveTooltip(o,g)}}}]),t}(),pt=function(){function t(e){a(this,t),this.w=e.w,this.ttCtx=e,this.ctx=e.ctx,this.tooltipPosition=new ut(e)}return r(t,[{key:"drawDynamicPoints",value:function(){var t=this.w,e=new b(this.ctx),i=new P(this.ctx),a=t.globals.dom.baseEl.querySelectorAll(".apexcharts-series");a=g(a),t.config.chart.stacked&&a.sort((function(t,e){return parseFloat(t.getAttribute("data:realIndex"))-parseFloat(e.getAttribute("data:realIndex"))}));for(var s=0;s<a.length;s++){var r=a[s].querySelector(".apexcharts-series-markers-wrap");if(null!==r){var o=void 0,n="apexcharts-marker w".concat((Math.random()+1).toString(36).substring(4));"line"!==t.config.chart.type&&"area"!==t.config.chart.type||t.globals.comboCharts||t.config.tooltip.intersect||(n+=" no-pointer-events");var l=i.getMarkerConfig({cssClass:n,seriesIndex:Number(r.getAttribute("data:realIndex"))});(o=e.drawMarker(0,0,l)).node.setAttribute("default-marker-size",0);var h=document.createElementNS(t.globals.SVGNS,"g");h.classList.add("apexcharts-series-markers"),h.appendChild(o.node),r.appendChild(h)}}}},{key:"enlargeCurrentPoint",value:function(t,e){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,s=this.w;"bubble"!==s.config.chart.type&&this.newPointSize(t,e);var r=e.getAttribute("cx"),o=e.getAttribute("cy");if(null!==i&&null!==a&&(r=i,o=a),this.tooltipPosition.moveXCrosshairs(r),!this.fixedTooltip){if("radar"===s.config.chart.type){var n=this.ttCtx.getElGrid(),l=n.getBoundingClientRect();r=this.ttCtx.e.clientX-l.left}this.tooltipPosition.moveTooltip(r,o,s.config.markers.hover.size)}}},{key:"enlargePoints",value:function(t){for(var e=this.w,i=this,a=this.ttCtx,s=t,r=e.globals.dom.baseEl.querySelectorAll(".apexcharts-series:not(.apexcharts-series-collapsed) .apexcharts-marker"),o=e.config.markers.hover.size,n=0;n<r.length;n++){var l=r[n].getAttribute("rel"),h=r[n].getAttribute("index");if(void 0===o&&(o=e.globals.markers.size[h]+e.config.markers.hover.sizeOffset),s===parseInt(l,10)){i.newPointSize(s,r[n]);var c=r[n].getAttribute("cx"),d=r[n].getAttribute("cy");i.tooltipPosition.moveXCrosshairs(c),a.fixedTooltip||i.tooltipPosition.moveTooltip(c,d,o)}else i.oldPointSize(r[n])}}},{key:"newPointSize",value:function(t,e){var i=this.w,a=i.config.markers.hover.size,s=0===t?e.parentNode.firstChild:e.parentNode.lastChild;if("0"!==s.getAttribute("default-marker-size")){var r=parseInt(s.getAttribute("index"),10);void 0===a&&(a=i.globals.markers.size[r]+i.config.markers.hover.sizeOffset),a<0&&(a=0),s.setAttribute("r",a)}}},{key:"oldPointSize",value:function(t){var e=parseFloat(t.getAttribute("default-marker-size"));t.setAttribute("r",e)}},{key:"resetPointsSize",value:function(){for(var t=this.w.globals.dom.baseEl.querySelectorAll(".apexcharts-series:not(.apexcharts-series-collapsed) .apexcharts-marker"),e=0;e<t.length;e++){var i=parseFloat(t[e].getAttribute("default-marker-size"));p.isNumber(i)&&i>=0?t[e].setAttribute("r",i):t[e].setAttribute("r",0)}}}]),t}(),ft=function(){function t(e){a(this,t),this.w=e.w,this.ttCtx=e}return r(t,[{key:"getAttr",value:function(t,e){return parseFloat(t.target.getAttribute(e))}},{key:"handleHeatTreeTooltip",value:function(t){var e=t.e,i=t.opt,a=t.x,s=t.y,r=t.type,o=this.ttCtx,n=this.w;if(e.target.classList.contains("apexcharts-".concat(r,"-rect"))){var l=this.getAttr(e,"i"),h=this.getAttr(e,"j"),c=this.getAttr(e,"cx"),d=this.getAttr(e,"cy"),g=this.getAttr(e,"width"),u=this.getAttr(e,"height");if(o.tooltipLabels.drawSeriesTexts({ttItems:i.ttItems,i:l,j:h,shared:!1,e:e}),n.globals.capturedSeriesIndex=l,n.globals.capturedDataPointIndex=h,a=c+o.tooltipRect.ttWidth/2+g,s=d+o.tooltipRect.ttHeight/2-u/2,o.tooltipPosition.moveXCrosshairs(c+g/2),a>n.globals.gridWidth/2&&(a=c-o.tooltipRect.ttWidth/2+g),o.w.config.tooltip.followCursor){var p=n.globals.dom.elWrap.getBoundingClientRect();a=n.globals.clientX-p.left-(a>n.globals.gridWidth/2?o.tooltipRect.ttWidth:0),s=n.globals.clientY-p.top}}return{x:a,y:s}}},{key:"handleMarkerTooltip",value:function(t){var e,i,a=t.e,s=t.opt,r=t.x,o=t.y,n=this.w,l=this.ttCtx;if(a.target.classList.contains("apexcharts-marker")){var h=parseInt(s.paths.getAttribute("cx"),10),c=parseInt(s.paths.getAttribute("cy"),10),d=parseFloat(s.paths.getAttribute("val"));if(i=parseInt(s.paths.getAttribute("rel"),10),e=parseInt(s.paths.parentNode.parentNode.parentNode.getAttribute("rel"),10)-1,l.intersect){var g=p.findAnce
61903stor(s.paths,"apexcharts-series");g&&(e=parseInt(g.getAttribute("data:realIndex"),10))}if(l.tooltipLabels.drawSeriesTexts({ttItems:s.ttItems,i:e,j:i,shared:!l.showOnIntersect&&n.config.tooltip.shared,e:a}),"mouseup"===a.type&&l.markerClick(a,e,i),n.globals.capturedSeriesIndex=e,n.globals.capturedDataPointIndex=i,r=h,o=c+n.globals.translateY-1.4*l.tooltipRect.ttHeight,l.w.config.tooltip.followCursor){var u=l.getElGrid().getBoundingClientRect();o=l.e.clientY+n.globals.translateY-u.top}d<0&&(o=c),l.marker.enlargeCurrentPoint(i,s.paths,r,o)}return{x:r,y:o}}},{key:"handleBarTooltip",value:function(t){var e,i,a=t.e,s=t.opt,r=this.w,o=this.ttCtx,n=o.getElTooltip(),l=0,h=0,c=0,d=this.getBarTooltipXY({e:a,opt:s});e=d.i;var g=d.barHeight,u=d.j;r.globals.capturedSeriesIndex=e,r.globals.capturedDataPointIndex=u,r.globals.isBarHorizontal&&o.tooltipUtil.hasBars()||!r.config.tooltip.shared?(h=d.x,c=d.y,i=Array.isArray(r.config.stroke.width)?r.config.stroke.width[e]:r.config.stroke.width,l=h):r.globals.comboCharts||r.config.tooltip.shared||(l/=2),isNaN(c)?c=r.globals.svgHeight-o.tooltipRect.ttHeight:c<0&&(c=0);var p=parseInt(s.paths.parentNode.getAttribute("data:realIndex"),10),f=r.globals.isMultipleYAxis?r.config.yaxis[p]&&r.config.yaxis[p].reversed:r.config.yaxis[0].reversed;if(h+o.tooltipRect.ttWidth>r.globals.gridWidth&&!f?h-=o.tooltipRect.ttWidth:h<0&&(h=0),o.w.config.tooltip.followCursor){var x=o.getElGrid().getBoundingClientRect();c=o.e.clientY-x.top}null===o.tooltip&&(o.tooltip=r.globals.dom.baseEl.querySelector(".apexcharts-tooltip")),r.config.tooltip.shared||(r.globals.comboBarCount>0?o.tooltipPosition.moveXCrosshairs(l+i/2):o.tooltipPosition.moveXCrosshairs(l)),!o.fixedTooltip&&(!r.config.tooltip.shared||r.globals.isBarHorizontal&&o.tooltipUtil.hasBars())&&(f&&(h-=o.tooltipRect.ttWidth)<0&&(h=0),!f||r.globals.isBarHorizontal&&o.tooltipUtil.hasBars()||(c=c+g-2*(r.globals.series[e][u]<0?g:0)),o.tooltipRect.ttHeight+c>r.globals.gridHeight?c=r.globals.gridHeight-o.tooltipRect.ttHeight+r.globals.translateY:(c=c+r.globals.translateY-o.tooltipRect.ttHeight/2)<0&&(c=0),n.style.left=h+r.globals.translateX+"px",n.style.top=c+"px")}},{key:"getBarTooltipXY",value:function(t){var e=t.e,i=t.opt,a=this.w,s=null,r=this.ttCtx,o=0,n=0,l=0,h=0,c=0,d=e.target.classList;if(d.contains("apexcharts-bar-area")||d.contains("apexcharts-candlestick-area")||d.contains("apexcharts-boxPlot-area")||d.contains("apexcharts-rangebar-area")){var g=e.target,u=g.getBoundingClientRect(),p=i.elGrid.getBoundingClientRect(),f=u.height;c=u.height;var x=u.width,b=parseInt(g.getAttribute("cx"),10),v=parseInt(g.getAttribute("cy"),10);h=parseFloat(g.getAttribute("barWidth"));var m="touchmove"===e.type?e.touches[0].clientX:e.clientX;s=parseInt(g.getAttribute("j"),10),o=parseInt(g.parentNode.getAttribute("rel"),10)-1;var y=g.getAttribute("data-range-y1"),w=g.getAttribute("data-range-y2");a.globals.comboCharts&&(o=parseInt(g.parentNode.getAttribute("data:realIndex"),10)),r.tooltipLabels.drawSeriesTexts({ttItems:i.ttItems,i:o,j:s,y1:y?parseInt(y,10):null,y2:w?parseInt(w,10):null,shared:!r.showOnIntersect&&a.config.tooltip.shared,e:e}),a.config.tooltip.followCursor?a.globals.isBarHorizontal?(n=m-p.left+15,l=v-r.dataPointsDividedHeight+f/2-r.tooltipRect.ttHeight/2):(n=a.globals.isXNumeric?b-x/2:b-r.dataPointsDividedWidth+x/2,l=e.clientY-p.top-r.tooltipRect.ttHeight/2-15):a.globals.isBarHorizontal?((n=b)<r.xyRatios.baseLineInvertedY&&(n=b-r.tooltipRect.ttWidth),l=v-r.dataPointsDividedHeight+f/2-r.tooltipRect.ttHeight/2):(n=a.globals.isXNumeric?b-x/2:b-r.dataPointsDividedWidth+x/2,l=v)}return{x:n,y:l,barHeight:c,barWidth:h,i:o,j:s}}}]),t}(),xt=function(){function t(e){a(this,t),this.w=e.w,this.ttCtx=e}return r(t,[{key:"drawXaxisTooltip",value:function(){var t=this.w,e=this.ttCtx,i="bottom"===t.config.xaxis.position;e.xaxisOffY=i?t.globals.gridHeight+1:-t.globals.xAxisHeight-t.config.xaxis.axisTicks.height+3;var a=i?"apexcharts-xaxistooltip apexcharts-xaxistooltip-bottom":"apexcharts-xaxistooltip apexcharts-xaxistooltip-top",s=t.globals.dom.elWrap;e.isXAxisTooltipEnabled&&(null===t.globals.dom.baseEl.querySelector(".apexcharts-xaxistooltip")&&(e.xaxisTooltip=document.createElement("div"),e.xaxisTooltip.setAttribute("class",a+" apexcharts-theme-"+t.config.tooltip.theme),s.appendChild(e.xaxisTooltip),e.xaxisTooltipText=document.createElement("div"),e.xaxisTooltipText.classList.add("apexcharts-xaxistooltip-text"),e.xaxisTooltipText.style.fontFamily=t.config.xaxis.tooltip.style.fontFamily||t.config.chart.fontFamily,e.xaxisTooltipText.style.fontSize=t.config.xaxis.tooltip.style.fontSize,e.xaxisTooltip.appendChild(e.xaxisTooltipText)))}},{key:"drawYaxisTooltip",value:function(){for(var t=this.w,e=this.ttCtx,i=function(i){var a=t.config.yaxis[i].opposite||t.config.yaxis[i].crosshairs.opposite;e.yaxisOffX=a?t.globals.gridWidth+1:1;var s="apexcharts-yaxistooltip apexcharts-yaxistooltip-".concat(i,a?" apexcharts-yaxistooltip-right":" apexcharts-yaxistooltip-left");t.globals.yAxisSameScaleIndices.map((function(e,a){e.map((function(e,a){a===i&&(s+=t.config.yaxis[a].show?" ":" apexcharts-yaxistooltip-hidden")}))}
61903));var r=t.globals.dom.elWrap;null===t.globals.dom.baseEl.querySelector(".apexcharts-yaxistooltip apexcharts-yaxistooltip-".concat(i))&&(e.yaxisTooltip=document.createElement("div"),e.yaxisTooltip.setAttribute("class",s+" apexcharts-theme-"+t.config.tooltip.theme),r.appendChild(e.yaxisTooltip),0===i&&(e.yaxisTooltipText=[]),e.yaxisTooltipText[i]=document.createElement("div"),e.yaxisTooltipText[i].classList.add("apexcharts-yaxistooltip-text"),e.yaxisTooltip.appendChild(e.yaxisTooltipText[i]))},a=0;a<t.config.yaxis.length;a++)i(a)}},{key:"setXCrosshairWidth",value:function(){var t=this.w,e=this.ttCtx,i=e.getElXCrosshairs();if(e.xcrosshairsWidth=parseInt(t.config.xaxis.crosshairs.width,10),t.globals.comboCharts){var a=t.globals.dom.baseEl.querySelector(".apexcharts-bar-area");if(null!==a&&"barWidth"===t.config.xaxis.crosshairs.width){var s=parseFloat(a.getAttribute("barWidth"));e.xcrosshairsWidth=s}else if("tickWidth"===t.config.xaxis.crosshairs.width){var r=t.globals.labels.length;e.xcrosshairsWidth=t.globals.gridWidth/r}}else if("tickWidth"===t.config.xaxis.crosshairs.width){var o=t.globals.labels.length;e.xcrosshairsWidth=t.globals.gridWidth/o}else if("barWidth"===t.config.xaxis.crosshairs.width){var n=t.globals.dom.baseEl.querySelector(".apexcharts-bar-area");if(null!==n){var l=parseFloat(n.getAttribute("barWidth"));e.xcrosshairsWidth=l}else e.xcrosshairsWidth=1}t.globals.isBarHorizontal&&(e.xcrosshairsWidth=0),null!==i&&e.xcrosshairsWidth>0&&i.setAttribute("width",e.xcrosshairsWidth)}},{key:"handleYCrosshair",value:function(){var t=this.w,e=this.ttCtx;e.ycrosshairs=t.globals.dom.baseEl.querySelector(".apexcharts-ycrosshairs"),e.ycrosshairsHidden=t.globals.dom.baseEl.querySelector(".apexcharts-ycrosshairs-hidden")}},{key:"drawYaxisTooltipText",value:function(t,e,i){var a=this.ttCtx,s=this.w,r=s.globals.yLabelFormatters[t];if(a.yaxisTooltips[t]){var o=a.getElGrid().getBoundingClientRect(),n=(e-o.top)*i.yRatio[t],l=s.globals.maxYArr[t]-s.globals.minYArr[t],h=s.globals.minYArr[t]+(l-n);a.tooltipPosition.moveYCrosshairs(e-o.top),a.yaxisTooltipText[t].innerHTML=r(h),a.tooltipPosition.moveYAxisTooltip(t)}}}]),t}(),bt=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w;var i=this.w;this.tConfig=i.config.tooltip,this.tooltipUtil=new dt(this),this.tooltipLabels=new gt(this),this.tooltipPosition=new ut(this),this.marker=new pt(this),this.intersect=new ft(this),this.axesTooltip=new xt(this),this.showOnIntersect=this.tConfig.intersect,this.showTooltipTitle=this.tConfig.x.show,this.fixedTooltip=this.tConfig.fixed.enabled,this.xaxisTooltip=null,this.yaxisTTEls=null,this.isBarShared=!i.globals.isBarHorizontal&&this.tConfig.shared,this.lastHoverTime=Date.now()}return r(t,[{key:"getElTooltip",value:function(t){return t||(t=this),t.w.globals.dom.baseEl?t.w.globals.dom.baseEl.querySelector(".apexcharts-tooltip"):null}},{key:"getElXCrosshairs",value:function(){return this.w.globals.dom.baseEl.querySelector(".apexcharts-xcrosshairs")}},{key:"getElGrid",value:function(){return this.w.globals.dom.baseEl.querySelector(".apexcharts-grid")}},{key:"drawTooltip",value:function(t){var e=this.w;this.xyRatios=t,this.isXAxisTooltipEnabled=e.config.xaxis.tooltip.enabled&&e.globals.axisCharts,this.yaxisTooltips=e.config.yaxis.map((function(t,i){return!!(t.show&&t.tooltip.enabled&&e.globals.axisCharts)})),this.allTooltipSeriesGroups=[],e.globals.axisCharts||(this.showTooltipTitle=!1);var i=document.createElement("div");if(i.classList.add("apexcharts-tooltip"),i.classList.add("apexcharts-theme-".concat(this.tConfig.theme)),e.globals.dom.elWrap.appendChild(i),e.globals.axisCharts){this.axesTooltip.drawXaxisTooltip(),this.axesTooltip.drawYaxisTooltip(),this.axesTooltip.setXCrosshairWidth(),this.axesTooltip.handleYCrosshair();var a=new G(this.ctx);this.xAxisTicksPositions=a.getXAxisTicksPositions()}if(!e.globals.comboCharts&&!this.tConfig.intersect&&"rangeBar"!==e.config.chart.type||this.tConfig.shared||(this.showOnIntersect=!0),0!==e.config.markers.size&&0!==e.globals.markers.largestSize||this.marker.drawDynamicPoints(this),e.globals.collapsedSeries.length!==e.globals.series.length){this.dataPointsDividedHeight=e.globals.gridHeight/e.globals.dataPoints,this.dataPointsDividedWidth=e.globals.gridWidth/e.globals.dataPoints,this.showTooltipTitle&&(this.tooltipTitle=document.createElement("div"),this.tooltipTitle.classList.add("apexcharts-tooltip-title"),this.tooltipTitle.style.fontFamily=this.tConfig.style.fontFamily||e.config.chart.fontFamily,this.tooltipTitle.style.fontSize=this.tConfig.style.fontSize,i.appendChild(this.tooltipTitle));var s=e.globals.series.length;
vendor: 4,340 bytes, line 61903
61903(e.globals.xyCharts||e.globals.comboCharts)&&this.tConfig.shared&&(s=this.showOnIntersect?1:e.globals.series.length),this.legendLabels=e.globals.dom.baseEl.querySelectorAll(".apexcharts-legend-text"),this.ttItems=this.createTTElements(s),this.addSVGEvents()}}},{key:"createTTElements",value:function(t){for(var e=this,i=this.w,a=[],s=this.getElTooltip(),r=function(r){var o=document.createElement("div");o.classList.add("apexcharts-tooltip-series-group"),o.style.order=i.config.tooltip.inverseOrder?t-r:r+1,e.tConfig.shared&&e.tConfig.enabledOnSeries&&Array.isArray(e.tConfig.enabledOnSeries)&&e.tConfig.enabledOnSeries.indexOf(r)<0&&o.classList.add("apexcharts-tooltip-series-group-hidden");var n=document.createElement("span");n.classList.add("apexcharts-tooltip-marker"),n.style.backgroundColor=i.globals.colors[r],o.appendChild(n);var l=document.createElement("div");l.classList.add("apexcharts-tooltip-text"),l.style.fontFamily=e.tConfig.style.fontFamily||i.config.chart.fontFamily,l.style.fontSize=e.tConfig.style.fontSize,["y","goals","z"].forEach((function(t){var e=document.createElement("div");e.classList.add("apexcharts-tooltip-".concat(t,"-group"));var i=document.createElement("span");i.classList.add("apexcharts-tooltip-text-".concat(t,"-label")),e.appendChild(i);var a=document.createElement("span");a.classList.add("apexcharts-tooltip-text-".concat(t,"-value")),e.appendChild(a),l.appendChild(e)})),o.appendChild(l),s.appendChild(o),a.push(o)},o=0;o<t;o++)r(o);return a}},{key:"addSVGEvents",value:function(){var t=this.w,e=t.config.chart.type,i=this.getElTooltip(),a=!("bar"!==e&&"candlestick"!==e&&"boxPlot"!==e&&"rangeBar"!==e),s="area"===e||"line"===e||"scatter"===e||"bubble"===e||"radar"===e,r=t.globals.dom.Paper.node,o=this.getElGrid();o&&(this.seriesBound=o.getBoundingClientRect());var n,l=[],h=[],c={hoverArea:r,elGrid:o,tooltipEl:i,tooltipY:l,tooltipX:h,ttItems:this.ttItems};if(t.globals.axisCharts&&(s?n=t.globals.dom.baseEl.querySelectorAll(".apexcharts-series[data\\:longestSeries='true'] .apexcharts-marker"):a?n=t.globals.dom.baseEl.querySelectorAll(".apexcharts-series .apexcharts-bar-area, .apexcharts-series .apexcharts-candlestick-area, .apexcharts-series .apexcharts-boxPlot-area, .apexcharts-series .apexcharts-rangebar-area"):"heatmap"!==e&&"treemap"!==e||(n=t.globals.dom.baseEl.querySelectorAll(".apexcharts-series .apexcharts-heatmap, .apexcharts-series .apexcharts-treemap")),n&&n.length))for(var d=0;d<n.length;d++)l.push(n[d].getAttribute("cy")),h.push(n[d].getAttribute("cx"));if(t.globals.xyCharts&&!this.showOnIntersect||t.globals.comboCharts&&!this.showOnIntersect||a&&this.tooltipUtil.hasBars()&&this.tConfig.shared)this.addPathsEventListeners([r],c);else if(a&&!t.globals.comboCharts||s&&this.showOnIntersect)this.addDatapointEventsListeners(c);else if(!t.globals.axisCharts||"heatmap"===e||"treemap"===e){var g=t.globals.dom.baseEl.querySelectorAll(".apexcharts-series");this.addPathsEventListeners(g,c)}if(this.showOnIntersect){var u=t.globals.dom.baseEl.querySelectorAll(".apexcharts-line-series .apexcharts-marker, .apexcharts-area-series .apexcharts-marker");u.length>0&&this.addPathsEventListeners(u,c),this.tooltipUtil.hasBars()&&!this.tConfig.shared&&this.addDatapointEventsListeners(c)}}},{key:"drawFixedTooltipRect",value:function(){var t=this.w,e=this.getElTooltip(),i=e.getBoundingClientRect(),a=i.width+10,s=i.height+10,r=this.tConfig.fixed.offsetX,o=this.tConfig.fixed.offsetY,n=this.tConfig.fixed.position.toLowerCase();return n.indexOf("right")>-1&&(r=r+t.globals.svgWidth-a+10),n.indexOf("bottom")>-1&&(o=o+t.globals.svgHeight-s-10),e.style.left=r+"px",e.style.top=o+"px",{x:r,y:o,ttWidth:a,ttHeight:s}}},{key:"addDatapointEventsListeners",value:function(t){var e=this.w.globals.dom.baseEl.querySelectorAll(".apexcharts-series-markers .apexcharts-marker, .apexcharts-bar-area, .apexcharts-candlestick-area, .apexcharts-boxPlot-area, .apexcharts-rangebar-area");this.addPathsEventListeners(e,t)}},{key:"addPathsEventListeners",value:function(t,e){for(var i=this,a=function(a){var s={paths:t[a],tooltipEl:e.tooltipEl,tooltipY:e.tooltipY,tooltipX:e.tooltipX,elGrid:e.elGrid,hoverArea:e.hoverArea,ttItems:e.ttItems};["mousemove","mouseup","touchmove","mouseout","touchend"].map((function(e){return t[a].addEventListener(e,i.onSeriesHover.bind(i,s),{capture:!1,passive:!0})}
61903))},s=0;s<t.length;s++)a(s)}},{key:"onSeriesHover",value:function(t,e){var i=this,a=Date.now()-this.lastHoverTime;a>=100?this.seriesHover(t,e):(clearTimeout(this.seriesHoverTimeout),this.seriesHoverTimeout=setTimeout((function(){i.seriesHover(t,e)}),100-a))}},{key:"seriesHover",value:function(t,e){var i=this;this.lastHoverTime=Date.now();var a=[],s=this.w;s.config.chart.group&&(a=this.ctx.getGroupedCharts()),s.globals.axisCharts&&(s.globals.minX===-1/0&&s.globals.maxX===1/0||0===s.globals.dataPoints)||(a.length?a.forEach((function(a){var s=i.getElTooltip(a),r={paths:t.paths,tooltipEl:s,tooltipY:t.tooltipY,tooltipX:t.tooltipX,elGrid:t.elGrid,hoverArea:t.hoverArea,ttItems:a.w.globals.tooltip.ttItems};a.w.globals.minX===i.w.globals.minX&&a.w.globals.maxX===i.w.globals.maxX&&a.w.globals.tooltip.seriesHoverByContext({chartCtx:a,ttCtx:a.w.globals.tooltip,opt:r,e:e})})):this.seriesHoverByContext({chartCtx:this.ctx,ttCtx:this.w.globals.tooltip,opt:t,e:e}))}},{key:"seriesHoverByContext",value:function(t){var e=t.chartCtx,i=t.ttCtx,a=t.opt,s=t.e,r=e.w,o=this.getElTooltip();if(o){if(i.tooltipRect={x:0,y:0,ttWidth:o.getBoundingClientRect().width,ttHeight:o.getBoundingClientRect().height},i.e=s,i.tooltipUtil.hasBars()&&!r.globals.comboCharts&&!i.isBarShared)if(this.tConfig.onDatasetHover.highlightDataSeries)new z(e).toggleSeriesOnHover(s,s.target.parentNode);i.fixedTooltip&&i.drawFixedTooltipRect(),r.globals.axisCharts?i.axisChartsTooltips({e:s,opt:a,tooltipRect:i.tooltipRect}):i.nonAxisChartsTooltips({e:s,opt:a,tooltipRect:i.tooltipRect})}}},{key:"axisChartsTooltips",value:function(t){var e,i,a=t.e,s=t.opt,r=this.w,o=s.elGrid.getBoundingClientRect(),n="touchmove"===a.type?a.touches[0].clientX:a.clientX,l="touchmove"===a.type?a.touches[0].clientY:a.clientY;if(this.clientY=l,this.clientX=n,r.globals.capturedSeriesIndex=-1,r.globals.capturedDataPointIndex=-1,l<o.top||l>o.top+o.height)this.handleMouseOut(s);else{if(Array.isArray(this.tConfig.enabledOnSeries)&&!r.config.tooltip.shared){var h=parseInt(s.paths.getAttribute("index"),10);if(this.tConfig.enabledOnSeries.indexOf(h)<0)return void this.handleMouseOut(s)}var c=this.getElTooltip(),d=this.getElXCrosshairs(),g=r.globals.xyCharts||"bar"===r.config.chart.type&&!r.globals.isBarHorizontal&&this.tooltipUtil.hasBars()&&this.tConfig.shared||r.globals.comboCharts&&this.tooltipUtil.hasBars();if("mousemove"===a.type||"touchmove"===a.type||"mouseup"===a.type){if(r.globals.collapsedSeries.length+r.globals.ancillaryCollapsedSeries.length===r.globals.series.length)return;null!==d&&d.classList.add("apexcharts-active");var u=this.yaxisTooltips.filter((function(t){return!0===t}));if(null!==this.ycrosshairs&&u.length&&this.ycrosshairs.classList.add("apexcharts-active"),g&&!this.showOnIntersect)this.handleStickyTooltip(a,n,l,s);else if("heatmap"===r.config.chart.type||"treemap"===r.config.chart.type){var p=this.intersect.handleHeatTreeTooltip({e:a,opt:s,x:e,y:i,type:r.config.chart.type});e=p.x,i=p.y,c.style.left=e+"px",c.style.top=i+"px"}else this.tooltipUtil.hasBars()&&this.intersect.handleBarTooltip({e:a,opt:s}),this.tooltipUtil.hasMarkers()&&this.intersect.handleMarkerTooltip({e:a,opt:s,x:e,y:i});if(this.yaxisTooltips.length)for(var f=0;f<r.config.yaxis.length;f++)this.axesTooltip.drawYaxisTooltipText(f,l,this.xyRatios);s.tooltipEl.classList.add("apexcharts-active")}else"mouseout"!==a.type&&"touchend"!==a.type||this.handleMouseOut(s)}}},{key:"nonAxisChartsTooltips",value:function(t){var e=t.e,i=t.opt,a=t.tooltipRect,s=this.w,r=i.paths.getAttribute("rel"),o=this.getElTooltip(),n=s.globals.dom.elWrap.getBoundingClientRect();if("mousemove"===e.type||"touchmove"===e.type){o.classList.add("apexcharts-active"),this.tooltipLabels.drawSeriesTexts({ttItems:i.ttItems,i:parseInt(r,10)-1,shared:!1});var l=s.globals.clientX-n.left-a.ttWidth/2,h=s.globals.clientY-n.top-a.ttHeight-10;if(o.style.left=l+"px",o.style.top=h+"px",s.config.legend.tooltipHoverFormatter){var c=r-1,d=(0,s.config.legend.tooltipHoverFormatter)(this.legendLabels[c].getAttribute("data:default-text"),{seriesIndex:c,dataPointIndex:c,w:s});this.legendLabels[c].innerHTML=d}}else"mouseout"!==e.type&&"touchend"!==e.type||(o.classList.remove("apexcharts-active"),s.config.legend.tooltipHoverFormatter&&this.legendLabels.forEac
61903h((function(t){var e=t.getAttribute("data:default-text");t.innerHTML=decodeURIComponent(e)})))}},{key:"handleStickyTooltip",value:function(t,e,i,a){var s=this.w,r=this.tooltipUtil.getNearestValues({context:this,hoverArea:a.hoverArea,elGrid:a.elGrid,clientX:e,clientY:i}),o=r.j,n=r.capturedSeries,l=a.elGrid.getBoundingClientRect();r.hoverX<0||r.hoverX>l.width?this.handleMouseOut(a):null!==n?this.handleStickyCapturedSeries(t,n,a,o):(this.tooltipUtil.isXoverlap(o)||s.globals.isBarHorizontal)&&this.create(t,this,0,o,a.ttItems)}},{key:"handleStickyCapturedSeries",value:function(t,e,i,a){var s=this.w;if(!this.tConfig.shared&&null===s.globals.series[e][a])return void this.handleMouseOut(i);void 0!==s.globals.series[e][a]?this.tConfig.shared&&this.tooltipUtil.isXoverlap(a)&&this.tooltipUtil.isInitialSeriesSameLen()?this.create(t,this,e,a,i.ttItems):this.create(t,this,e,a,i.ttItems,!1):this.tooltipUtil.isXoverlap(a)&&this.create(t,this,0,a,i.ttItems)}},{key:"deactivateHoverFilter",value:function(){for(var t=this.w,e=new b(this.ctx),i=t.globals.dom.Paper.select(".apexcharts-bar-area"),a=0;a<i.length;a++)e.pathMouseLeave(i[a])}},{key:"handleMouseOut",value:function(t){var e=this.w,i=this.getElXCrosshairs();if(t.tooltipEl.classList.remove("apexcharts-active"),this.deactivateHoverFilter(),"bubble"!==e.config.chart.type&&this.marker.resetPointsSize(),null!==i&&i.classList.remove("apexcharts-active"),null!==this.ycrosshairs&&this.ycrosshairs.classList.remove("apexcharts-active"),this.isXAxisTooltipEnabled&&this.xaxisTooltip.classList.remove("apexcharts-active"),this.yaxisTooltips.length){null===this.yaxisTTEls&&(this.yaxisTTEls=e.globals.dom.baseEl.querySelectorAll(".apexcharts-yaxistooltip"));for(var a=0;a<this.yaxisTTEls.length;a++)this.yaxisTTEls[a].classList.remove("apexcharts-active")}
61903e.config.legend.tooltipHoverFormatter&&this.legendLabels.forEach((function(t){var e=t.getAttribute("data:default-text");t.innerHTML=decodeURIComponent(e)}))}},{key:"markerClick",value:function(t,e,i){var a=this.w;"function"==typeof a.config.chart.events.markerClick&&a.config.chart.events.markerClick(t,this.ctx,{seriesIndex:e,dataPointIndex:i,w:a}),this.ctx.events.fireEvent("markerClick",[t,this.ctx,{seriesIndex:e,dataPointIndex:i,w:a}])}},{key:"create",value:function(t,e,i,a,s){var r=arguments.length>5&&void 0!==arguments[5]?arguments[5]:null,o=this.w,n=e;"mouseup"===t.type&&this.markerClick(t,i,a),null===r&&(r=this.tConfig.shared);var l=this.tooltipUtil.hasMarkers(),h=this.tooltipUtil.getElBars();if(o.config.legend.tooltipHoverFormatter){var c=o.config.legend.tooltipHoverFormatter,d=Array.from(this.legendLabels);d.forEach((function(t){var e=t.getAttribute("data:default-text");t.innerHTML=decodeURIComponent(e)}));for(var g=0;g<d.length;g++){var u=d[g],p=parseInt(u.getAttribute("i"),10),f=decodeURIComponent(u.getAttribute("data:default-text")),x=c(f,{seriesIndex:r?p:i,dataPointIndex:a,w:o});if(r)u.innerHTML=o.globals.collapsedSeriesIndices.indexOf(p)<0?x:f;else if(u.innerHTML=p===i?x:f,i===p)break}}if(r){if(n.tooltipLabels.drawSeriesTexts({ttItems:s,i:i,j:a,shared:!this.showOnIntersect&&this.tConfig.shared}),l&&(o.globals.markers.largestSize>0?n.marker.enlargePoints(a):n.tooltipPosition.moveDynamicPointsOnHover(a)),this.tooltipUtil.hasBars()&&(this.barSeriesHeight=this.tooltipUtil.getBarsHeight(h),this.barSeriesHeight>0)){var v=new b(this.ctx),m=o.globals.dom.Paper.select(".apexcharts-bar-area[j='".concat(a,"']"));this.deactivateHoverFilter(),this.tooltipPosition.moveStickyTooltipOverBars(a);for(var y=0;y<m.length;y++)v.pathMouseEnter(m[y])}}else n.tooltipLabels.drawSeriesTexts({shared:!1,ttItems:s,i:i,j:a}),this.tooltipUtil.hasBars()&&n.tooltipPosition.moveStickyTooltipOverBars(a),l&&n.tooltipPosition.moveMarkers(i,a)}}]),t}(),vt=function(t){n(s,t);var i=d(s);function s(){return a(this,s),i.apply(this,arguments)}return r(s,[{key:"draw",value:function(t,i){var a=this,s=this.w;this.graphics=new b(this.ctx),this.bar=new E(this.ctx,this.xyRatios);var r=new y(this.ctx,s);t=r.getLogSeries(t),this.yRatio=r.getLogYRatios(this.yRatio),this.barHelpers.initVariables(t),"100%"===s.config.chart.stackType&&(t=s.globals.seriesPercent.slice()),this.series=t,this.totalItems=0,this.prevY=[],this.prevX=[],this.prevYF=[],this.prevXF=[],this.prevYVal=[],this.prevXVal=[],this.xArrj=[],this.xArrjF=[],this.xArrjVal=[],this.yArrj=[],this.yArrjF=[],this.yArrjVal=[];for(var o=0;o<t.length;o++)t[o].length>0&&(this.totalItems+=t[o].length);for(var n=this.graphics.group({class:"apexcharts-bar-series apexcharts-plot-series"}),l=0,h=0,c=function(r,o){var c=void 0,d=void 0,g=void 0,u=void 0,f=[],x=[],b=s.globals.comboCharts?i[r]:r;a.yRatio.length>1&&(a.yaxisIndex=b),a.isReversed=s.config.yaxis[a.yaxisIndex]&&s.config.yaxis[a.yaxisIndex].reversed;var v=a.graphics.group({class:"apexcharts-series",seriesName:p.escapeString(s.globals.seriesNames[b]),rel:r+1,"data:realIndex":b});a.ctx.series.addCollapsedClassToSeries(v,b);var m=a.graphics.group({class:"apexcharts-datalabels","data:realIndex":b}),y=0,w=0,k=a.initialPositions(l,h,c,d,g,u);h=k.y,y=k.barHeight,d=k.yDivision,u=k.zeroW,l=k.x,w=k.barWidth,c=k.xDivision,g=k.zeroH,a.yArrj=[],a.yArrjF=[],a.yArrjVal=[],a.xArrj=[],a.xArrjF=[],a.xArrjVal=[],1===a.prevY.length&&a.prevY[0].every((function(t){return isNaN(t)}))&&(a.prevY[0]=a.prevY[0].map((function(t){return g})),a.prevYF[0]=a.prevYF[0].map((function(t){return 0})));for(var A=0;A<s.globals.dataPoints;A++){var S=a.barHelpers.getStrokeWidth(r,A,b),C={indexes:{i:r,j:A,realIndex:b,bc:o},strokeWidth:S,x:l,y:h,elSeries:v},L=null;a.isHorizontal?(L=a.drawStackedBarPaths(e(e({},C),{},{zeroW:u,barHeight:y,yDivision:d})),w=a.series[r][A]/a.invertedYRatio):(L=a.drawStackedColumnPaths(e(e({},C),{},{xDivision:c,barWidth:w,zeroH:g})),y=a.series[r][A]/a.yRatio[a.yaxisIndex]),h=L.y,l=L.x,f.push(l),x.push(h);var P=a.barHelpers.getPathFillColor(t,r,A,b);v=a.renderSeries({realIndex:b,pathFill:P,j:A,i:r,pathFrom:L.pathFrom,pathTo:L.pathTo,strokeWidth:S,elSeries:v,x:l,y:h,series:t,barHeight:y,barWidth:w,elDataLabelsWrap:m,type:"bar",visibleSeries:0})}s.globals.seriesXvalues[b]=f,s.globals.seriesYvalues[b]=x,a.prevY.push(a.yArrj),a.prevYF.push(a.yArrjF),a.prevYVal.push(a.yArrjVal),a.prevX.push(a.xArrj),a.prevXF.push(a.xArrjF),a.prevXVal.push(a.xArrjVal),n.add(v)},d=0,g=0;d<t.length;d++,g++)c(d,g);return n}}
61903,{key:"initialPositions",value:function(t,e,i,a,s,r){var o,n,l=this.w;return this.isHorizontal?(o=(o=a=l.globals.gridHeight/l.globals.dataPoints)*parseInt(l.config.plotOptions.bar.barHeight,10)/100,r=this.baseLineInvertedY+l.globals.padHorizontal+(this.isReversed?l.globals.gridWidth:0)-(this.isReversed?2*this.baseLineInvertedY:0),e=(a-o)/2):(n=i=l.globals.gridWidth/l.globals.dataPoints,n=l.globals.isXNumeric&&l.globals.dataPoints>1?(i=l.globals.minXDiff/this.xRatio)*parseInt(this.barOptions.columnWidth,10)/100:n*parseInt(l.config.plotOptions.bar.columnWidth,10)/100,s=this.baseLineY[this.yaxisIndex]+(this.isReversed?l.globals.gridHeight:0)-(this.isReversed?2*this.baseLineY[this.yaxisIndex]:0),t=l.globals.padHorizontal+(i-n)/2),{x:t,y:e,yDivision:a,xDivision:i,barHeight:o,barWidth:n,zeroH:s,zeroW:r}}},{key:"drawStackedBarPaths",value:function(t){for(var e,i=t.indexes,a=t.barHeight,s=t.strokeWidth,r=t.zeroW,o=t.x,n=t.y,l=t.yDivision,h=t.elSeries,c=this.w,d=n,g=i.i,u=i.j,p=0,f=0;f<this.prevXF.length;f++)p+=this.prevXF[f][u];if(g>0){var x=r;this.prevXVal[g-1][u]<0?x=this.series[g][u]>=0?this.prevX[g-1][u]+p-2*(this.isReversed?p:0):this.prevX[g-1][u]:this.prevXVal[g-1][u]>=0&&(x=this.series[g][u]>=0?this.prevX[g-1][u]:this.prevX[g-1][u]-p+2*(this.isReversed?p:0)),e=x}else e=r;o=null===this.series[g][u]?e:e+this.series[g][u]/this.invertedYRatio-2*(this.isReversed?this.series[g][u]/this.invertedYRatio:0);var b=this.barHelpers.getBarpaths({barYPosition:d,barHeight:a,x1:e,x2:o,strokeWidth:s,series:this.series,realIndex:i.realIndex,i:g,j:u,w:c});return this.barHelpers.barBackground({j:u,i:g,y1:d,y2:a,elSeries:h}),n+=l,{pathTo:b.pathTo,pathFrom:b.pathFrom,x:o,y:n}}},{key:"drawStackedColumnPaths",value:function(t){var e=t.indexes,i=t.x,a=t.y,s=t.xDivision,r=t.barWidth,o=t.zeroH;t.strokeWidth;var n=t.elSeries,l=this.w,h=e.i,c=e.j,d=e.bc;if(l.globals.isXNumeric){var g=l.globals.seriesX[h][c];g||(g=0),i=(g-l.globals.minX)/this.xRatio-r/2}for(var u,p=i,f=0,x=0;x<this.prevYF.length;x++)f+=isNaN(this.prevYF[x][c])?0:this.prevYF[x][c];if(h>0&&!l.globals.isXNumeric||h>0&&l.globals.isXNumeric&&l.globals.seriesX[h-1][c]===l.globals.seriesX[h][c]){var b,v,m=Math.min(this.yRatio.length+1,h+1);if(void 0!==this.prevY[h-1])for(var y=1;y<m;y++)if(!isNaN(this.prevY[h-y][c])){v=this.prevY[h-y][c];break}for(var w=1;w<m;w++){if(this.prevYVal[h-w][c]<0){b=this.series[h][c]>=0?v-f+2*(this.isReversed?f:0):v;break}if(this.prevYVal[h-w][c]>=0){b=this.series[h][c]>=0?v:v+f-2*(this.isReversed?f:0);break}}void 0===b&&(b=l.globals.gridHeight),u=this.prevYF[0].every((function(t){return 0===t}))&&this.prevYF.slice(1,h).every((function(t){return t.every((function(t){return isNaN(t)}))}))?l.globals.gridHeight-o:b}else u=l.globals.gridHeight-o;a=u-this.series[h][c]/this.yRatio[this.yaxisIndex]+2*(this.isReversed?this.series[h][c]/this.yRatio[this.yaxisIndex]:0);var k=this.barHelpers.getColumnPaths({barXPosition:p,barWidth:r,y1:u,y2:a,yRatio:this.yRatio[this.yaxisIndex],strokeWidth:this.strokeWidth,series:this.series,realIndex:e.realIndex,i:h,j:c,w:l});return this.barHelpers.barBackground({bc:d,j:c,i:h,x1:p,x2:r,elSeries:n}),i+=s,{pathTo:k.pathTo,pathFrom:k.pathFrom,x:l.globals.isXNumeric?i-s:i,y:a}}}]),s}(E),mt=function(t){n(s,t);var i=d(s);function s(){return a(this,s),i.apply(this,arguments)}return r(s,[{key:"draw",value:function(t,i){var a=this,s=this.w,r=new b(this.ctx),o=new L(this.ctx);this.candlestickOptions=this.w.config.plotOptions.candlestick,this.boxOptions=this.w.config.plotOptions.boxPlot,this.isHorizontal=s.config.plotOptions.bar.horizontal;var n=new y(this.ctx,s);t=n.getLogSeries(t),this.series=t,this.yRatio=n.getLogYRatios(this.yRatio),this.barHelpers.initVariables(t);for(var l=r.group({class:"apexcharts-".concat(s.config.chart.type,"-series apexcharts-plot-series")}),h=function(n){a.isBoxPlot="boxPlot"===s.config.chart.type||"boxPlot"===s.config.series[n].type;var h,c,d,g,u=void 0,f=void 0,x=[],b=[],v=s.globals.comboCharts?i[n]:n,m=r.group({class:"apexcharts-series",seriesName:p.escapeString(s.globals.seriesNames[v]),rel:n+1,"data:realIndex":v});a.ctx.series.addCollapsedClassToSeries(m,v),t[n].length>0&&(a.visibleI=a.visibleI+1);var y,w;a.yRatio.length>1&&(a.yaxisIndex=v);var k=a.barHelpers.initialPositions();f=k.y,y=k.barHeight,c=k.yDivision,g=k.zeroW,u=k.x,w=k.barWidth,h=k.xDivision,d=k.zeroH,b.pu
61903sh(u+w/2);for(var A=r.group({class:"apexcharts-datalabels","data:realIndex":v}),S=function(i){var r=a.barHelpers.getStrokeWidth(n,i,v),l=null,p={indexes:{i:n,j:i,realIndex:v},x:u,y:f,strokeWidth:r,elSeries:m};l=a.isHorizontal?a.drawHorizontalBoxPaths(e(e({},p),{},{yDivision:c,barHeight:y,zeroW:g})):a.drawVerticalBoxPaths(e(e({},p),{},{xDivision:h,barWidth:w,zeroH:d})),f=l.y,u=l.x,i>0&&b.push(u+w/2),x.push(f),l.pathTo.forEach((function(e,h){var c=!a.isBoxPlot&&a.candlestickOptions.wick.useFillColor?l.color[h]:s.globals.stroke.colors[n],d=o.fillPath({seriesNumber:v,dataPointIndex:i,color:l.color[h],value:t[n][i]});a.renderSeries({realIndex:v,pathFill:d,lineFill:c,j:i,i:n,pathFrom:l.pathFrom,pathTo:e,strokeWidth:r,elSeries:m,x:u,y:f,series:t,barHeight:y,barWidth:w,elDataLabelsWrap:A,visibleSeries:a.visibleI,type:s.config.chart.type})}))},C=0;C<s.globals.dataPoints;C++)S(C);s.globals.seriesXvalues[v]=b,s.globals.seriesYvalues[v]=x,l.add(m)},c=0;c<t.length;c++)h(c);return l}},{key:"drawVerticalBoxPaths",value:function(t){var e=t.indexes,i=t.x;t.y;var a=t.xDivision,s=t.barWidth,r=t.zeroH,o=t.strokeWidth,n=this.w,l=new b(this.ctx),h=e.i,c=e.j,d=!0,g=n.config.plotOptions.candlestick.colors.upward,u=n.config.plotOptions.candlestick.colors.downward,p="";this.isBoxPlot&&(p=[this.boxOptions.colors.lower,this.boxOptions.colors.upper]);var f=this.yRatio[this.yaxisIndex],x=e.realIndex,v=this.getOHLCValue(x,c),m=r,y=r;v.o>v.c&&(d=!1);var w=Math.min(v.o,v.c),k=Math.max(v.o,v.c),A=v.m;n.globals.isXNumeric&&(i=(n.globals.seriesX[x][c]-n.globals.minX)/this.xRatio-s/2);var S=i+s*this.visibleI;void 0===this.series[h][c]||null===this.series[h][c]?(w=r,k=r):(w=r-w/f,k=r-k/f,m=r-v.h/f,y=r-v.l/f,A=r-v.m/f);var C=l.move(S,r),L=l.move(S+s/2,w);return n.globals.previousPaths.length>0&&(L=this.getPreviousPath(x,c,!0)),C=this.isBoxPlot?[l.move(S,w)+l.line(S+s/2,w)+l.line(S+s/2,m)+l.line(S+s/4,m)+l.line(S+s-s/4,m)+l.line(S+s/2,m)+l.line(S+s/2,w)+l.line(S+s,w)+l.line(S+s,A)+l.line(S,A)+l.line(S,w+o/2),l.move(S,A)+l.line(S+s,A)+l.line(S+s,k)+l.line(S+s/2,k)+l.line(S+s/2,y)+l.line(S+s-s/4,y)+l.line(S+s/4,y)+l.line(S+s/2,y)+l.line(S+s/2,k)+l.line(S,k)+l.line(S,A)+"z"]:[l.move(S,k)+l.line(S+s/2,k)+l.line(S+s/2,m)+l.line(S+s/2,k)+l.line(S+s,k)+l.line(S+s,w)+l.line(S+s/2,w)+l.line(S+s/2,y)+l.line(S+s/2,w)+l.line(S,w)+l.line(S,k-o/2)],L+=l.move(S,w),n.globals.isXNumeric||(i+=a),{pathTo:C,pathFrom:L,x:i,y:k,barXPosition:S,color:this.isBoxPlot?p:d?[g]:[u]}}},{key:"drawHorizontalBoxPaths",value:function(t){var e=t.indexes;t.x;var i=t.y,a=t.yDivision,s=t.barHeight,r=t.zeroW,o=t.strokeWidth,n=this.w,l=new b(this.ctx),h=e.i,c=e.j,d=this.boxOptions.colors.lower;this.isBoxPlot&&(d=[this.boxOptions.colors.lower,this.boxOptions.colors.upper]);var g=this.invertedYRatio,u=e.realIndex,p=this.getOHLCValue(u,c),f=r,x=r,v=Math.min(p.o,p.c),m=Math.max(p.o,p.c),y=p.m;n.globals.isXNumeric&&(i=(n.globals.seriesX[u][c]-n.globals.minX)/this.invertedXRatio-s/2);var w=i+s*this.visibleI;void 0===this.series[h][c]||null===this.series[h][c]?(v=r,m=r):(v=r+v/g,m=r+m/g,f=r+p.h/g,x=r+p.l/g,y=r+p.m/g);var k=l.move(r,w),A=l.move(v,w+s/2);return n.globals.previousPaths.length>0&&(A=this.getPreviousPath(u,c,!0)),k=[l.move(v,w)+l.line(v,w+s/2)+l.line(f,w+s/2)+l.line(f,w+s/2-s/4)+l.line(f,w+s/2+s/4)+l.line(f,w+s/2)+l.line(v,w+s/2)+l.line(v,w+s)+l.line(y,w+s)+l.line(y,w)+l.line(v+o/2,w),l.move(y,w)+l.line(y,w+s)+l.line(m,w+s)+l.line(m,w+s/2)+l.line(x,w+s/2)+l.line(x,w+s-s/4)+l.line(x,w+s/4)+l.line(x,w+s/2)+l.line(m,w+s/2)+l.line(m,w)+l.line(y,w)+"z"],A+=l.move(v,w),n.globals.isXNumeric||(i+=a),{pathTo:k,pathFrom:A,x:m,y:i,barYPosition:w,color:d}}},{key:"getOHLCValue",value:function(t,e){var i=this.w;return{o:this.isBoxPlot?i.globals.seriesCandleH[t][e]:i.globals.seriesCandleO[t][e],h:this.isBoxPlot?i.globals.seriesCandleO[t][e]:i.globals.seriesCandleH[t][e],m:i.globals.seriesCandleM[t][e],l:this.isBoxPlot?i.globals.seriesCandleC[t][e]:i.globals.seriesCandleL[t][e],c:this.isBoxPlot?i.globals.seriesCandleL[t][e]:i.globals.seriesCandleC[t][e]}}}]),s}(E),yt=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w}return r(t,[{key:"checkColorRange",value:function(){var t=this.w,e=!1,i=t.config.plotOptions[t.config.chart.type];return i.colorScale.ranges.length>0&&i.colorScale.ranges.map((function(t,i){t.from<=0&&(e=!0)})),e}}
vendor: 5,050 bytes, line 61903
61903,{key:"getShadeColor",value:function(t,e,i,a){var s=this.w,r=1,o=s.config.plotOptions[t].shadeIntensity,n=this.determineColor(t,e,i);s.globals.hasNegs||a?r=s.config.plotOptions[t].reverseNegativeShade?n.percent<0?n.percent/100*(1.25*o):(1-n.percent/100)*(1.25*o):n.percent<=0?1-(1+n.percent/100)*o:(1-n.percent/100)*o:(r=1-n.percent/100,"treemap"===t&&(r=(1-n.percent/100)*(1.25*o)));var l=n.color,h=new p;return s.config.plotOptions[t].enableShades&&(l="dark"===this.w.config.theme.mode?p.hexToRgba(h.shadeColor(-1*r,n.color),s.config.fill.opacity):p.hexToRgba(h.shadeColor(r,n.color),s.config.fill.opacity)),{color:l,colorProps:n}}},{key:"determineColor",value:function(t,e,i){var a=this.w,s=a.globals.series[e][i],r=a.config.plotOptions[t],o=r.colorScale.inverse?i:e;r.distributed&&"treemap"===a.config.chart.type&&(o=i);var n=a.globals.colors[o],l=null,h=Math.min.apply(Math,g(a.globals.series[e])),c=Math.max.apply(Math,g(a.globals.series[e]));r.distributed||"heatmap"!==t||(h=a.globals.minY,c=a.globals.maxY),void 0!==r.colorScale.min&&(h=r.colorScale.min<a.globals.minY?r.colorScale.min:a.globals.minY,c=r.colorScale.max>a.globals.maxY?r.colorScale.max:a.globals.maxY);var d=Math.abs(c)+Math.abs(h),u=100*s/(0===d?d-1e-6:d);r.colorScale.ranges.length>0&&r.colorScale.ranges.map((function(t,e){if(s>=t.from&&s<=t.to){n=t.color,l=t.foreColor?t.foreColor:null,h=t.from,c=t.to;var i=Math.abs(c)+Math.abs(h);u=100*s/(0===i?i-1e-6:i)}}));return{color:n,foreColor:l,percent:u}}},{key:"calculateDataLabels",value:function(t){var e=t.text,i=t.x,a=t.y,s=t.i,r=t.j,o=t.colorProps,n=t.fontSize,l=this.w.config.dataLabels,h=new b(this.ctx),c=new M(this.ctx),d=null;if(l.enabled){d=h.group({class:"apexcharts-data-labels"});var g=l.offsetX,u=l.offsetY,p=i+g,f=a+parseFloat(l.style.fontSize)/3+u;c.plotDataLabelsText({x:p,y:f,text:e,i:s,j:r,color:o.foreColor,parent:d,fontSize:n,dataLabelsConfig:l})}return d}},{key:"addListeners",value:function(t){var e=new b(this.ctx);t.node.addEventListener("mouseenter",e.pathMouseEnter.bind(this,t)),t.node.addEventListener("mouseleave",e.pathMouseLeave.bind(this,t)),t.node.addEventListener("mousedown",e.pathMouseDown.bind(this,t))}}]),t}(),wt=function(){function t(e,i){a(this,t),this.ctx=e,this.w=e.w,this.xRatio=i.xRatio,this.yRatio=i.yRatio,this.dynamicAnim=this.w.config.chart.animations.dynamicAnimation,this.helpers=new yt(e),this.rectRadius=this.w.config.plotOptions.heatmap.radius,this.strokeWidth=this.w.config.stroke.show?this.w.config.stroke.width:0}return r(t,[{key:"draw",value:function(t){var e=this.w,i=new b(this.ctx),a=i.group({class:"apexcharts-heatmap"});a.attr("clip-path","url(#gridRectMask".concat(e.globals.cuid,")"));var s=e.globals.gridWidth/e.globals.dataPoints,r=e.globals.gridHeight/e.globals.series.length,o=0,n=!1;this.negRange=this.helpers.checkColorRange();var l=t.slice();e.config.yaxis[0].reversed&&(n=!0,l.reverse());for(var h=n?0:l.length-1;n?h<l.length:h>=0;n?h++:h--){var c=i.group({class:"apexcharts-series apexcharts-heatmap-series",seriesName:p.escapeString(e.globals.seriesNames[h]),rel:h+1,"data:realIndex":h});if(this.ctx.series.addCollapsedClassToSeries(c,h),e.config.chart.dropShadow.enabled){var d=e.config.chart.dropShadow;new x(this.ctx).dropShadow(c,d,h)}for(var g=0,u=e.config.plotOptions.heatmap.shadeIntensity,f=0;f<l[h].length;f++){var v=this.helpers.getShadeColor(e.config.chart.type,h,f,this.negRange),m=v.color,y=v.colorProps;if("image"===e.config.fill.type)m=new L(this.ctx).fillPath({seriesNumber:h,dataPointIndex:f,opacity:e.globals.hasNegs?y.percent<0?1-(1+y.percent/100):u+y.percent/100:y.percent/100,patternID:p.randomId(),width:e.config.fill.image.width?e.config.fill.image.width:s,height:e.config.fill.image.height?e.config.fill.image.height:r});var w=this.rectRadius,k=i.drawRect(g,o,s,r,w);if(k.attr({cx:g,cy:o}),k.node.classList.add("apexcharts-heatmap-rect"),c.add(k),k.attr({fill:m,i:h,index:h,j:f,val:l[h][f],"stroke-width":this.strokeWidth,stroke:e.config.plotOptions.heatmap.useFillColorAsStroke?m:e.globals.stroke.colors[0],color:m}),this.helpers.addListeners(k),e.config.chart.animations.enabled&&!e.globals.dataChanged){var A=1;e.globals.resized||(A=e.config.chart.animations.speed),this.animateHeatMap(k,g,o,s,r,A)}if(e.globals.dataChanged){var S=1;if(this.dynamicAnim.enabled&&e.globals.shouldAnimate){S=this.dynamicAnim.speed;var C=e.globals.previousPaths[h]&&e.globals.previousPaths[h][f]&&e.globals.previousPaths[h][f].color;C||(C="rgba(255, 255, 255, 0)"),this.animateHeatColor(k,p.isColorHex(C)?C:p.rgb2hex(C),p.isColorHex(m)?m:p.rgb2hex(m),S)}}var P=(0,e.config.dataLabels.formatter)(e.globals.series[h][f],{value:e.globals.series[h][f],seriesIndex:h,dataPointIndex:f,w:e}),T=this.helpers.calculateDataLabels({text:P,x:g+s/2,y:o+r/2,i:h,j:f,colorProps:y,series:l});null!==T&&c.add(T),g+=s}o+=r,a.add(c)}var M=e.globals.yAxisScale[0].result.slice();e.config.yaxis[0].reversed?M.unshift(""):M.push(""),e.globals.yAxisScale[0].result=M;var I=e.globals.gridHeight/e.globals.series.length;return e.config.yaxis[0].labels.offsetY=-I/2,a}}
61903,{key:"animateHeatMap",value:function(t,e,i,a,s,r){var o=new f(this.ctx);o.animateRect(t,{x:e+a/2,y:i+s/2,width:0,height:0},{x:e,y:i,width:a,height:s},r,(function(){o.animationCompleted(t)}))}},{key:"animateHeatColor",value:function(t,e,i,a){t.attr({fill:e}).animate(a).attr({fill:i})}}]),t}(),kt=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w}return r(t,[{key:"drawYAxisTexts",value:function(t,e,i,a){var s=this.w,r=s.config.yaxis[0],o=s.globals.yLabelFormatters[0];return new b(this.ctx).drawText({x:t+r.labels.offsetX,y:e+r.labels.offsetY,text:o(a,i),textAnchor:"middle",fontSize:r.labels.style.fontSize,fontFamily:r.labels.style.fontFamily,foreColor:Array.isArray(r.labels.style.colors)?r.labels.style.colors[i]:r.labels.style.colors})}}]),t}(),At=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w;var i=this.w;this.chartType=this.w.config.chart.type,this.initialAnim=this.w.config.chart.animations.enabled,this.dynamicAnim=this.initialAnim&&this.w.config.chart.animations.dynamicAnimation.enabled,this.animBeginArr=[0],this.animDur=0,this.donutDataLabels=this.w.config.plotOptions.pie.donut.labels,this.lineColorArr=void 0!==i.globals.stroke.colors?i.globals.stroke.colors:i.globals.colors,this.defaultSize=Math.min(i.globals.gridWidth,i.globals.gridHeight),this.centerY=this.defaultSize/2,this.centerX=i.globals.gridWidth/2,"radialBar"===i.config.chart.type?this.fullAngle=360:this.fullAngle=Math.abs(i.config.plotOptions.pie.endAngle-i.config.plotOptions.pie.startAngle),this.initialAngle=i.config.plotOptions.pie.startAngle%this.fullAngle,i.globals.radialSize=this.defaultSize/2.05-i.config.stroke.width-(i.config.chart.sparkline.enabled?0:i.config.chart.dropShadow.blur),this.donutSize=i.globals.radialSize*parseInt(i.config.plotOptions.pie.donut.size,10)/100,this.maxY=0,this.sliceLabels=[],this.sliceSizes=[],this.prevSectorAngleArr=[]}return r(t,[{key:"draw",value:function(t){var e=this,i=this.w,a=new b(this.ctx);if(this.ret=a.group({class:"apexcharts-pie"}),i.globals.noData)return this.ret;for(var s=0,r=0;r<t.length;r++)s+=p.negToZero(t[r]);var o=[],n=a.group();0===s&&(s=1e-5),t.forEach((function(t){e.maxY=Math.max(e.maxY,t)})),i.config.yaxis[0].max&&(this.maxY=i.config.yaxis[0].max),"back"===i.config.grid.position&&"polarArea"===this.chartType&&this.drawPolarElements(this.ret);for(var l=0;l<t.length;l++){var h=this.fullAngle*p.negToZero(t[l])/s;o.push(h),"polarArea"===this.chartType?(o[l]=this.fullAngle/t.length,this.sliceSizes.push(i.globals.radialSize*t[l]/this.maxY)):this.sliceSizes.push(i.globals.radialSize)}if(i.globals.dataChanged){for(var c,d=0,g=0;g<i.globals.previousPaths.length;g++)d+=p.negToZero(i.globals.previousPaths[g]);for(var u=0;u<i.globals.previousPaths.length;u++)c=this.fullAngle*p.negToZero(i.globals.previousPaths[u])/d,this.prevSectorAngleArr.push(c)}this.donutSize<0&&(this.donutSize=0);var f=i.config.plotOptions.pie.customScale,x=i.globals.gridWidth/2,v=i.globals.gridHeight/2,m=x-i.globals.gridWidth/2*f,y=v-i.globals.gridHeight/2*f;if("donut"===this.chartType){var w=a.drawCircle(this.donutSize);w.attr({cx:this.centerX,cy:this.centerY,fill:i.config.plotOptions.pie.donut.background?i.config.plotOptions.pie.donut.background:"transparent"}),n.add(w)}var k=this.drawArcs(o,t);
61903if(this.sliceLabels.forEach((function(t){k.add(t)})),n.attr({transform:"translate(".concat(m,", ").concat(y,") scale(").concat(f,")")}),n.add(k),this.ret.add(n),this.donutDataLabels.show){var A=this.renderInnerDataLabels(this.donutDataLabels,{hollowSize:this.donutSize,centerX:this.centerX,centerY:this.centerY,opacity:this.donutDataLabels.show,translateX:m,translateY:y});this.ret.add(A)}return"front"===i.config.grid.position&&"polarArea"===this.chartType&&this.drawPolarElements(this.ret),this.ret}},{key:"drawArcs",value:function(t,e){var i=this.w,a=new x(this.ctx),s=new b(this.ctx),r=new L(this.ctx),o=s.group({class:"apexcharts-slices"}),n=this.initialAngle,l=this.initialAngle,h=this.initialAngle,c=this.initialAngle;this.strokeWidth=i.config.stroke.show?i.config.stroke.width:0;for(var d=0;d<t.length;d++){var g=s.group({class:"apexcharts-series apexcharts-pie-series",seriesName:p.escapeString(i.globals.seriesNames[d]),rel:d+1,"data:realIndex":d});o.add(g),l=c,h=(n=h)+t[d],c=l+this.prevSectorAngleArr[d];var u=h<n?this.fullAngle+h-n:h-n,f=r.fillPath({seriesNumber:d,size:this.sliceSizes[d],value:e[d]}),v=this.getChangedPath(l,c),m=s.drawPath({d:v,stroke:Array.isArray(this.lineColorArr)?this.lineColorArr[d]:this.lineColorArr,strokeWidth:0,fill:f,fillOpacity:i.config.fill.opacity,classes:"apexcharts-pie-area apexcharts-".concat(this.chartType.toLowerCase(),"-slice-").concat(d)});if(m.attr({index:0,j:d}),a.setSelectionFilter(m,0,d),i.config.chart.dropShadow.enabled){var y=i.config.chart.dropShadow;a.dropShadow(m,y,d)}this.addListeners(m,this.donutDataLabels),b.setAttrs(m.node,{"data:angle":u,"data:startAngle":n,"data:strokeWidth":this.strokeWidth,"data:value":e[d]});var w={x:0,y:0};"pie"===this.chartType||"polarArea"===this.chartType?w=p.polarToCartesian(this.centerX,this.centerY,i.globals.radialSize/1.25+i.config.plotOptions.pie.dataLabels.offset,(n+u/2)%this.fullAngle):"donut"===this.chartType&&(w=p.polarToCartesian(this.centerX,this.centerY,(i.globals.radialSize+this.donutSize)/2+i.config.plotOptions.pie.dataLabels.offset,(n+u/2)%this.fullAngle)),g.add(m);var k=0;if(!this.initialAnim||i.globals.resized||i.globals.dataChanged?this.animBeginArr.push(0):(0===(k=u/this.fullAngle*i.config.chart.animations.speed)&&(k=1),this.animDur=k+this.animDur,this.animBeginArr.push(this.animDur)),this.dynamicAnim&&i.globals.dataChanged?this.animatePaths(m,{size:this.sliceSizes[d],endAngle:h,startAngle:n,prevStartAngle:l,prevEndAngle:c,animateStartingPos:!0,i:d,animBeginArr:this.animBeginArr,shouldSetPrevPaths:!0,dur:i.config.chart.animations.dynamicAnimation.speed}):this.animatePaths(m,{size:this.sliceSizes[d],endAngle:h,startAngle:n,i:d,totalItems:t.length-1,animBeginArr:this.animBeginArr,dur:k}),i.config.plotOptions.pie.expandOnClick&&"polarArea"!==this.chartType&&m.click(this.pieClicked.bind(this,d)),void 0!==i.globals.selectedDataPoints[0]&&i.globals.selectedDataPoints[0].indexOf(d)>-1&&this.pieClicked(d),i.config.dataLabels.enabled){var A=w.x,S=w.y,C=100*u/this.fullAngle+"%";if(0!==u&&i.config.plotOptions.pie.dataLabels.minAngleToShowLabel<t[d]){var P=i.config.dataLabels.formatter;
vendor: 5,283 bytes, line 61903
61903void 0!==P&&(C=P(i.globals.seriesPercent[d][0],{seriesIndex:d,w:i}));var T=i.globals.dataLabels.style.colors[d],M=s.group({class:"apexcharts-datalabels"}),I=s.drawText({x:A,y:S,text:C,textAnchor:"middle",fontSize:i.config.dataLabels.style.fontSize,fontFamily:i.config.dataLabels.style.fontFamily,fontWeight:i.config.dataLabels.style.fontWeight,foreColor:T});if(M.add(I),i.config.dataLabels.dropShadow.enabled){var z=i.config.dataLabels.dropShadow;a.dropShadow(I,z)}I.node.classList.add("apexcharts-pie-label"),i.config.chart.animations.animate&&!1===i.globals.resized&&(I.node.classList.add("apexcharts-pie-label-delay"),I.node.style.animationDelay=i.config.chart.animations.speed/940+"s"),this.sliceLabels.push(M)}}}return o}},{key:"addListeners",value:function(t,e){var i=new b(this.ctx);t.node.addEventListener("mouseenter",i.pathMouseEnter.bind(this,t)),t.node.addEventListener("mouseleave",i.pathMouseLeave.bind(this,t)),t.node.addEventListener("mouseleave",this.revertDataLabelsInner.bind(this,t.node,e)),t.node.addEventListener("mousedown",i.pathMouseDown.bind(this,t)),this.donutDataLabels.total.showAlways||(t.node.addEventListener("mouseenter",this.printDataLabelsInner.bind(this,t.node,e)),t.node.addEventListener("mousedown",this.printDataLabelsInner.bind(this,t.node,e)))}},{key:"animatePaths",value:function(t,e){var i=this.w,a=e.endAngle<e.startAngle?this.fullAngle+e.endAngle-e.startAngle:e.endAngle-e.startAngle,s=a,r=e.startAngle,o=e.startAngle;void 0!==e.prevStartAngle&&void 0!==e.prevEndAngle&&(r=e.prevEndAngle,s=e.prevEndAngle<e.prevStartAngle?this.fullAngle+e.prevEndAngle-e.prevStartAngle:e.prevEndAngle-e.prevStartAngle),e.i===i.config.series.length-1&&(a+o>this.fullAngle?e.endAngle=e.endAngle-(a+o):a+o<this.fullAngle&&(e.endAngle=e.endAngle+(this.fullAngle-(a+o)))),a===this.fullAngle&&(a=this.fullAngle-.01),this.animateArc(t,r,o,a,s,e)}},{key:"animateArc",value:function(t,e,i,a,s,r){var o,n=this,l=this.w,h=new f(this.ctx),c=r.size;(isNaN(e)||isNaN(s))&&(e=i,s=a,r.dur=0);var d=a,g=i,u=e<i?this.fullAngle+e-i:e-i;l.globals.dataChanged&&r.shouldSetPrevPaths&&r.prevEndAngle&&(o=n.getPiePath({me:n,startAngle:r.prevStartAngle,angle:r.prevEndAngle<r.prevStartAngle?this.fullAngle+r.prevEndAngle-r.prevStartAngle:r.prevEndAngle-r.prevStartAngle,size:c}),t.attr({d:o})),0!==r.dur?t.animate(r.dur,l.globals.easing,r.animBeginArr[r.i]).afterAll((function(){"pie"!==n.chartType&&"donut"!==n.chartType&&"polarArea"!==n.chartType||this.animate(l.config.chart.animations.dynamicAnimation.speed).attr({"stroke-width":n.strokeWidth}),r.i===l.config.series.length-1&&h.animationCompleted(t)})).during((function(l){d=u+(a-u)*l,r.animateStartingPos&&(d=s+(a-s)*l,g=e-s+(i-(e-s))*l),o=n.getPiePath({me:n,startAngle:g,angle:d,size:c}),t.node.setAttribute("data:pathOrig",o),t.attr({d:o})})):(o=n.getPiePath({me:n,startAngle:g,angle:a,size:c}),r.isTrack||(l.globals.animationEnded=!0),t.node.setAttribute("data:pathOrig",o),t.attr({d:o,"stroke-width":n.strokeWidth}))}},{key:"pieClicked",value:function(t){var e,i=this.w,a=this,s=a.sliceSizes[t]+(i.config.plotOptions.pie.expandOnClick?4:0),r=i.globals.dom.Paper.select(".apexcharts-".concat(a.chartType.toLowerCase(),"-slice-").concat(t)).members[0];if("true"!==r.attr("data:pieClicked")){var o=i.globals.dom.baseEl.getElementsByClassName("apexcharts-pie-area");Array.prototype.forEach.call(o,(function(t){t.setAttribute("data:pieClicked","false");var e=t.getAttribute("data:pathOrig");t.setAttribute("d",e)})),r.attr("data:pieClicked","true");var n=parseInt(r.attr("data:startAngle"),10),l=parseInt(r.attr("data:angle"),10);e=a.getPiePath({me:a,startAngle:n,angle:l,size:s}),360!==l&&r.plot(e)}else{r.attr({"data:pieClicked":"false"}),this.revertDataLabelsInner(r.node,this.donutDataLabels);var h=r.attr("data:pathOrig");r.attr({d:h})}}},{key:"getChangedPath",value:function(t,e){var i="";return this.dynamicAnim&&this.w.globals.dataChanged&&(i=this.getPiePath({me:this,startAngle:t,angle:e-t,size:this.size})),i}},{key:"getPiePath",value:function(t){var e=t.me,i=t.startAngle,a=t.angle,s=t.size,r=i,o=Math.PI*(r-90)/180,n=a+i;Math.ceil(n)>=this.fullAngle+this.w.config.plotOptions.pie.startAngle%this.fullAngle&&(n=this.fullAngle+this.w.config.plotOptions.pie.startAngle%this.fullAngle-.01),Math.ceil(n)>this.fullAngle&&(n-=this.fullAngle);var l=Math.PI*(n-90)/180,h=e.centerX+s*Math.cos(o),c=e.centerY+s*Math.sin(o),d=e.centerX+s*Math.cos(l),g=e.centerY+s*Math.sin(l),u=p.polarToCartesian(e.centerX,e.centerY,e.donutSize,n),f=p.polarToCartesian(e.centerX,e.centerY,e.donutSize,r),x=a>180?1:0,b=["M",h,c,"A",s,s,0,x,1,d,g];return"donut"===e.chartType?[].concat(b,["L",u.x,u.y,"A",e.donutSize,e.donutSize,0,x,0,f.x,f.y,"L",h,c,"z"]).join(" "):"pie"===e.chartType||"polarArea"===e.chartType?[].concat(b,["L",e.centerX,e.centerY,"L",h,c]).join(" "):[].concat(b).join(" ")}},{key:"drawPolarElements",value:function(t){var e=this.w,i=new j(this.ctx),a=new b(this.ctx),s=new kt(this.ctx),r=a.group(),o=a.group(),n=i.niceScale(0,Math.ceil(this.maxY),e.config.yaxis[0].tickAmount,0,!0),l=n.result.reverse(),h=n.result.length;this.maxY=n.niceMax;for(var c=e.globals.radialSize,d=c/(h-1),g=0;g<h-1;g++){var u=a.drawCircle(c);if(u.attr({cx:this.centerX,cy:this.centerY,fill:"none","stroke-width":e.config.plotOptions.polarArea.r
61903ings.strokeWidth,stroke:e.config.plotOptions.polarArea.rings.strokeColor}),e.config.yaxis[0].show){var p=s.drawYAxisTexts(this.centerX,this.centerY-c+parseInt(e.config.yaxis[0].labels.style.fontSize,10)/2,g,l[g]);o.add(p)}r.add(u),c-=d}this.drawSpokes(t),t.add(r),t.add(o)}},{key:"renderInnerDataLabels",value:function(t,e){var i=this.w,a=new b(this.ctx),s=a.group({class:"apexcharts-datalabels-group",transform:"translate(".concat(e.translateX?e.translateX:0,", ").concat(e.translateY?e.translateY:0,") scale(").concat(i.config.plotOptions.pie.customScale,")")}),r=t.total.show;s.node.style.opacity=e.opacity;var o,n,l=e.centerX,h=e.centerY;o=void 0===t.name.color?i.globals.colors[0]:t.name.color;var c=t.name.fontSize,d=t.name.fontFamily,g=t.name.fontWeight;n=void 0===t.value.color?i.config.chart.foreColor:t.value.color;var u=t.value.formatter,p="",f="";if(r?(o=t.total.color,c=t.total.fontSize,d=t.total.fontFamily,g=t.total.fontWeight,f=t.total.label,p=t.total.formatter(i)):1===i.globals.series.length&&(p=u(i.globals.series[0],i),f=i.globals.seriesNames[0]),f&&(f=t.name.formatter(f,t.total.show,i)),t.name.show){var x=a.drawText({x:l,y:h+parseFloat(t.name.offsetY),text:f,textAnchor:"middle",foreColor:o,fontSize:c,fontWeight:g,fontFamily:d});x.node.classList.add("apexcharts-datalabel-label"),s.add(x)}if(t.value.show){var v=t.name.show?parseFloat(t.value.offsetY)+16:t.value.offsetY,m=a.drawText({x:l,y:h+v,text:p,textAnchor:"middle",foreColor:n,fontWeight:t.value.fontWeight,fontSize:t.value.fontSize,fontFamily:t.value.fontFamily});m.node.classList.add("apexcharts-datalabel-value"),s.add(m)}return s}},{key:"printInnerLabels",value:function(t,e,i,a){var s,r=this.w;a?s=void 0===t.name.color?r.globals.colors[parseInt(a.parentNode.getAttribute("rel"),10)-1]:t.name.color:r.globals.series.length>1&&t.total.show&&(s=t.total.color);var o=r.globals.dom.baseEl.querySelector(".apexcharts-datalabel-label"),n=r.globals.dom.baseEl.querySelector(".apexcharts-datalabel-value");i=(0,t.value.formatter)(i,r),a||"function"!=typeof t.total.formatter||(i=t.total.formatter(r));var l=e===t.total.label;e=t.name.formatter(e,l,r),null!==o&&(o.textContent=e),null!==n&&(n.textContent=i),null!==o&&(o.style.fill=s)}},{key:"printDataLabelsInner",value:function(t,e){var i=this.w,a=t.getAttribute("data:value"),s=i.globals.seriesNames[parseInt(t.parentNode.getAttribute("rel"),10)-1];i.globals.series.length>1&&this.printInnerLabels(e,s,a,t);var r=i.globals.dom.baseEl.querySelector(".apexcharts-datalabels-group");null!==r&&(r.style.opacity=1)}},{key:"drawSpokes",value:function(t){var e=this,i=this.w,a=new b(this.ctx),s=i.config.plotOptions.polarArea.spokes;if(0!==s.strokeWidth){for(var r=[],o=360/i.globals.series.length,n=0;n<i.globals.series.length;n++)r.push(p.polarToCartesian(this.centerX,this.centerY,i.globals.radialSize,i.config.plotOptions.pie.startAngle+o*n));r.forEach((function(i,r){var o=a.drawLine(i.x,i.y,e.centerX,e.centerY,Array.isArray(s.connectorColors)?s.connectorColors[r]:s.connectorColors);t.add(o)}))}}},{key:"revertDataLabelsInner",value:function(t,e,i){var a=this,s=this.w,r=s.globals.dom.baseEl.querySelector(".apexcharts-datalabels-group"),o=!1,n=s.globals.dom.baseEl.getElementsByClassName("apexcharts-pie-area"),l=function(t){var i=t.makeSliceOut,s=t.printLabel;Array.prototype.forEach.call(n,(function(t){"true"===t.getAttribute("data:pieClicked")&&(i&&(o=!0),s&&a.printDataLabelsInner(t,e))}))};if(l({makeSliceOut:!0,printLabel:!1}),e.total.show&&s.globals.series.length>1)o&&!e.total.showAlways?l({makeSliceOut:!1,printLabel:!0}):this.printInnerLabels(e,e.total.label,e.total.formatter(s));else if(l({makeSliceOut:!1,printLabel:!0}),!o)if(s.globals.selectedDataPoints.length&&s.globals.series.length>1)if(s.globals.selectedDataPoints[0].length>0){var h=s.globals.selectedDataPoints[0],c=s.globals.dom.baseEl.querySelector(".apexcharts-".concat(this.chartType.toLowerCase(),"-slice-").concat(h));this.printDataLabelsInner(c,e)}else r&&s.globals.selectedDataPoints.length&&0===s.globals.selectedDataPoints[0].length&&(r.style.opacity=0);else r&&s.globals.series.length>1&&(r.style.opacity=0)}}]),t}(),St=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w,this.chartType=this.w.config.chart.type,this.initialAnim=this.w.config.chart.animations.enabled,this.dynamicAnim=this.initialAnim&&this.w.config.chart.animations.dynamicAnimation.enabled,this.animDur=0;var i=this.w;this.graphics=new b(this.ctx),this.lineColorArr=void 0!==i.globals.stroke.colors?i.globals.stroke.colors:i.globals.colors,this.defaultSize=i.globals.svgHeight<i.globals.svgWidth?i.globals.gridHeight+1.5*i.globals.goldenPadding:i.globals.gridWidth,this.isLog=i.config.yaxis[0].logarithmic,this.coreUtils=new y(this.ctx),this.maxValue=this.isLog?this.coreUtils.getLogVal(i.globals.maxY,0):i.globals.maxY,this.minValue=this.isLog?this.coreUtils.getLogVal(this.w.globals.minY,0):i.globals.minY,this.polygons=i.config.plotOptions.radar.polygons,this.strokeWidth=i.config.stroke.show?i.config.stroke.width:0,this.size=this.defaultSize/2.1-this.strokeWidth-i.config.chart.dropShadow.blur,i.config.xaxis.labels.show&&(this.size=this.size-i.globals.xAxisLabelsWidth/1.75),void 0!==i.config.plotOptions.radar.size&&(this.size=i.config.plotOptions.radar.size),this.dataRadiusOfPercent=[],this.dataRadius=[],this.angleArr=[],this.yaxisLabelsTextsPos=[]}return r(t,[{key:"draw",value:function(t){var i=this,a=this.w,s=new L(this.ctx),r=[],o=new M(this.ctx);t.length&&(this.dataPointsLen=t[a.globals.maxValsInArrayIndex].length),this.disAngle=2*Math.PI/this.dataPointsLen;var n=a.globals.gridWidth/2,l=a.globals.gridHeight/2,h=n+a.config.plotOptions.radar.offsetX,c=l+a.config.plotOptions.radar.offsetY,d=this.graphics.group({class:"apexcharts-radar-series apexcharts-plot-series",transform:"translate(".concat(h||0,", ").concat(c||0,")")}),g=[],u=null,f=null;if(this.yaxisLabels=this.graphics.group({class:"apexcharts-yaxis"}),t.forEach((function(t,n){var l=t.length===a.globals.dataPoints,h=i.graphics.group().attr({class:"apexcharts-series","data:longestSeries":l,seriesName:p.escapeString(a.globals.seriesNames[n]),rel:n+1,"data:realIndex":n});i.dataRadiusOfPercent[n]=[],i.dataRadius[n]=[],i.angleArr[n]=[],t.forEach((function(t,e){var a=Math.abs(i.maxValue-i.minValue);t+=Math.abs(i.minValue),i.isLog&&(t=i.coreUtils.getLogVal(t,0)),i.dataRadiusOfPercent[n][e]=t/a,i.dataRadius[n][e]=i.dataRadiusOfPercent[n][e]*i.size,i.angleArr[n][e]=e*i.disAngle})),g=i.getDataPointsPos(i.dataRadius[n],i.angleArr[n]);var c=i.createPaths(g,{x:0,y:0});u=i.graphics.group({class:"apexcharts-series-markers-wrap apexcharts-element-hidden"}),f=i.graphics.group({class:"apexcharts-datalabels","data:realIndex":n}),a.globals.delayedElements.push({el:u.node,index:n});var d={i:n,realIndex:n,animationDelay:n,initialSpeed:a.config.chart.animations.speed,dataChangeSpeed:a.config.chart.animations.dynamicAnimation.speed,className:"apexcharts-radar",shouldClipToGrid:!1,bindEventsOnPaths:!1,stroke:a.globals.stroke.colors[n],strokeLineCap:a.config.stroke.lineCap},b=null;a.globals.previousPaths.length>0&&(b=i.getPreviousPath(n));for(var v=0;v<c.linePathsTo.length;v++){var m=i.graphics.renderPaths(e(e({},d),{},{pathFrom:null===b?c.linePathsFrom[v]:b,pathTo:c.linePathsTo[v],strokeWidth:Array.isArray(i.strokeWidth)?i.strokeWidth[n]:i.strokeWidth,fill:"none",drawShadow:!1}));h.add(m);var y=s.fillPath({seriesNumber:n}),w=i.graphics.renderPaths(e(e({},d),{},{pathFrom:null===b?c.areaPathsFrom[v]:b,pathTo:c.areaPathsTo[v],strokeWidth:0,fill:y,drawShadow:!1}));if(a.config.chart.dropShadow.enabled){var k=new x(i.ctx),A=a.config.chart.dropShadow;k.dropShadow(w,Object.assign({},A,{noUserSpaceOnUse:!0}),n)}h.add(w)}t.forEach((function(t,s){var r=new P(i.ctx).getMarkerConfig({cssClass:"apexcharts-marker",seriesIndex:n,dataPointIndex:s}),l=i.graphics.drawMarker(g[s].x,g[s].y,r);l.attr("rel",s),l.attr("j",s),l.attr("index",n),l.node.setAttribute("default-marker-size",r.pSize);var c=i.graphics.group({class:"apexcharts-series-markers"});c&&c.add(l),u.add(c),h.add(u);var d=a.config.dataLabels;if(d.enabled){var p=d.formatter(a.globals.series[n][s],{seriesIndex:n,dataPointIndex:s,w:a});o.plotDataLabelsText({x:g[s].x,y:g[s].y,text:p,textAnchor:"middle",i:n,j:n,parent:f,offsetCorrection:!1,dataLabelsConfig:e({},d)})}h.add(f)})),r.push(h)})),this.drawPolygons({parent:d}),a.config.xaxis.labels.show){var b=this.drawXAxisTexts();d.add(b)}return r.forEach((function(t){d.add(t)})),d.add(this.yaxisLabels),d}},{key:"drawPolygons",value:function(t){for(var e=this,i=this.w,a=t.parent,s=new kt(this.ctx),r=i.globals.yAxisScale[0].result.reverse(),o=r.length,n=[],l=this.size/(o-1),h=0;h<o;h++)n[h]=l*h;n.reverse();var c=[],d=[];
vendor: 4,657 bytes, line 61903
61903n.forEach((function(t,i){var a=p.getPolygonPos(t,e.dataPointsLen),s="";a.forEach((function(t,a){if(0===i){var r=e.graphics.drawLine(t.x,t.y,0,0,Array.isArray(e.polygons.connectorColors)?e.polygons.connectorColors[a]:e.polygons.connectorColors);d.push(r)}0===a&&e.yaxisLabelsTextsPos.push({x:t.x,y:t.y}),s+=t.x+","+t.y+" "})),c.push(s)})),c.forEach((function(t,s){var r=e.polygons.strokeColors,o=e.polygons.strokeWidth,n=e.graphics.drawPolygon(t,Array.isArray(r)?r[s]:r,Array.isArray(o)?o[s]:o,i.globals.radarPolygons.fill.colors[s]);a.add(n)})),d.forEach((function(t){a.add(t)})),i.config.yaxis[0].show&&this.yaxisLabelsTextsPos.forEach((function(t,i){var a=s.drawYAxisTexts(t.x,t.y,i,r[i]);e.yaxisLabels.add(a)}))}},{key:"drawXAxisTexts",value:function(){var t=this,i=this.w,a=i.config.xaxis.labels,s=this.graphics.group({class:"apexcharts-xaxis"}),r=p.getPolygonPos(this.size,this.dataPointsLen);return i.globals.labels.forEach((function(o,n){var l=i.config.xaxis.labels.formatter,h=new M(t.ctx);if(r[n]){var c=t.getTextPos(r[n],t.size),d=l(o,{seriesIndex:-1,dataPointIndex:n,w:i});h.plotDataLabelsText({x:c.newX,y:c.newY,text:d,textAnchor:c.textAnchor,i:n,j:n,parent:s,color:Array.isArray(a.style.colors)&&a.style.colors[n]?a.style.colors[n]:"#a8a8a8",dataLabelsConfig:e({textAnchor:c.textAnchor,dropShadow:{enabled:!1}},a),offsetCorrection:!1})}})),s}},{key:"createPaths",value:function(t,e){var i=this,a=[],s=[],r=[],o=[];if(t.length){s=[this.graphics.move(e.x,e.y)],o=[this.graphics.move(e.x,e.y)];var n=this.graphics.move(t[0].x,t[0].y),l=this.graphics.move(t[0].x,t[0].y);t.forEach((function(e,a){n+=i.graphics.line(e.x,e.y),l+=i.graphics.line(e.x,e.y),a===t.length-1&&(n+="Z",l+="Z")})),a.push(n),r.push(l)}return{linePathsFrom:s,linePathsTo:a,areaPathsFrom:o,areaPathsTo:r}}},{key:"getTextPos",value:function(t,e){var i="middle",a=t.x,s=t.y;return Math.abs(t.x)>=10?t.x>0?(i="start",a+=10):t.x<0&&(i="end",a-=10):i="middle",Math.abs(t.y)>=e-10&&(t.y<0?s-=10:t.y>0&&(s+=10)),{textAnchor:i,newX:a,newY:s}}},{key:"getPreviousPath",value:function(t){for(var e=this.w,i=null,a=0;a<e.globals.previousPaths.length;a++){var s=e.globals.previousPaths[a];s.paths.length>0&&parseInt(s.realIndex,10)===parseInt(t,10)&&void 0!==e.globals.previousPaths[a].paths[0]&&(i=e.globals.previousPaths[a].paths[0].d)}return i}},{key:"getDataPointsPos",value:function(t,e){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.dataPointsLen;t=t||[],e=e||[];for(var a=[],s=0;s<i;s++){var r={};r.x=t[s]*Math.sin(e[s]),r.y=-t[s]*Math.cos(e[s]),a.push(r)}return a}}]),t}(),Ct=function(t){n(i,t);var e=d(i);function i(t){var s;a(this,i),(s=e.call(this,t)).ctx=t,s.w=t.w,s.animBeginArr=[0],s.animDur=0;var r=s.w;return s.startAngle=r.config.plotOptions.radialBar.startAngle,s.endAngle=r.config.plotOptions.radialBar.endAngle,s.totalAngle=Math.abs(r.config.plotOptions.radialBar.endAngle-r.config.plotOptions.radialBar.startAngle),s.trackStartAngle=r.config.plotOptions.radialBar.track.startAngle,s.trackEndAngle=r.config.plotOptions.radialBar.track.endAngle,s.donutDataLabels=s.w.config.plotOptions.radialBar.dataLabels,s.radialDataLabels=s.donutDataLabels,s.trackStartAngle||(s.trackStartAngle=s.startAngle),s.trackEndAngle||(s.trackEndAngle=s.endAngle),360===s.endAngle&&(s.endAngle=359.99),s.margin=parseInt(r.config.plotOptions.radialBar.track.margin,10),s}return r(i,[{key:"draw",value:function(t){var e=this.w,i=new b(this.ctx),a=i.group({class:"apexcharts-radialbar"});if(e.globals.noData)return a;var s=i.group(),r=this.defaultSize/2,o=e.globals.gridWidth/2,n=this.defaultSize/2.05;e.config.chart.sparkline.enabled||(n=n-e.config.stroke.width-e.config.chart.dropShadow.blur);var l=e.globals.fill.colors;if(e.config.plotOptions.radialBar.track.show){var h=this.drawTracks({size:n,centerX:o,centerY:r,colorArr:l,series:t});s.add(h)}var c=this.drawArcs({size:n,centerX:o,centerY:r,colorArr:l,series:t}),d=360;e.config.plotOptions.radialBar.startAngle<0&&(d=this.totalAngle);var g=(360-d)/360;if(e.globals.radialSize=n-n*g,this.radialDataLabels.value.show){var u=Math.max(this.radialDataLabels.value.offsetY,this.radialDataLabels.name.offsetY);e.globals.radialSize+=u*g}return s.add(c.g),"front"===e.config.plotOptions.radialBar.hollow.position&&(c.g.add(c.elHollow),c.dataLabels&&c.g.add(c.dataLabels)),a.add(s),a}},{key:"drawTracks",value:function(t){var e=this.w,i=new b(this.ctx),a=i.group({class:"apexcharts-tracks"}),s=new x(this.ctx),r=new L(this.ctx),o=this.getStrokeWidth(t);t.size=t.size-o/2;for(var n=0;n<t.series.length;n++){var l=i.group({class:"apexcharts-radialbar-track apexcharts-track"});a.add(l),l.attr({rel:n+1}),t.size=t.size-o-this.margin;
61903var h=e.config.plotOptions.radialBar.track,c=r.fillPath({seriesNumber:0,size:t.size,fillColors:Array.isArray(h.background)?h.background[n]:h.background,solid:!0}),d=this.trackStartAngle,g=this.trackEndAngle;Math.abs(g)+Math.abs(d)>=360&&(g=360-Math.abs(this.startAngle)-.1);var u=i.drawPath({d:"",stroke:c,strokeWidth:o*parseInt(h.strokeWidth,10)/100,fill:"none",strokeOpacity:h.opacity,classes:"apexcharts-radialbar-area"});if(h.dropShadow.enabled){var p=h.dropShadow;s.dropShadow(u,p)}l.add(u),u.attr("id","apexcharts-radialbarTrack-"+n),this.animatePaths(u,{centerX:t.centerX,centerY:t.centerY,endAngle:g,startAngle:d,size:t.size,i:n,totalItems:2,animBeginArr:0,dur:0,isTrack:!0,easing:e.globals.easing})}return a}},{key:"drawArcs",value:function(t){var e=this.w,i=new b(this.ctx),a=new L(this.ctx),s=new x(this.ctx),r=i.group(),o=this.getStrokeWidth(t);t.size=t.size-o/2;var n=e.config.plotOptions.radialBar.hollow.background,l=t.size-o*t.series.length-this.margin*t.series.length-o*parseInt(e.config.plotOptions.radialBar.track.strokeWidth,10)/100/2,h=l-e.config.plotOptions.radialBar.hollow.margin;void 0!==e.config.plotOptions.radialBar.hollow.image&&(n=this.drawHollowImage(t,r,l,n));var c=this.drawHollow({size:h,centerX:t.centerX,centerY:t.centerY,fill:n||"transparent"});if(e.config.plotOptions.radialBar.hollow.dropShadow.enabled){var d=e.config.plotOptions.radialBar.hollow.dropShadow;s.dropShadow(c,d)}var g=1;!this.radialDataLabels.total.show&&e.globals.series.length>1&&(g=0);var u=null;this.radialDataLabels.show&&(u=this.renderInnerDataLabels(this.radialDataLabels,{hollowSize:l,centerX:t.centerX,centerY:t.centerY,opacity:g})),"back"===e.config.plotOptions.radialBar.hollow.position&&(r.add(c),u&&r.add(u));var f=!1;e.config.plotOptions.radialBar.inverseOrder&&(f=!0);for(var v=f?t.series.length-1:0;f?v>=0:v<t.series.length;f?v--:v++){var m=i.group({class:"apexcharts-series apexcharts-radial-series",seriesName:p.escapeString(e.globals.seriesNames[v])});r.add(m),m.attr({rel:v+1,"data:realIndex":v}),this.ctx.series.addCollapsedClassToSeries(m,v),t.size=t.size-o-this.margin;var y=a.fillPath({seriesNumber:v,size:t.size,value:t.series[v]}),w=this.startAngle,k=void 0,A=p.negToZero(t.series[v]>100?100:t.series[v])/100,S=Math.round(this.totalAngle*A)+this.startAngle,C=void 0;e.globals.dataChanged&&(k=this.startAngle,C=Math.round(this.totalAngle*p.negToZero(e.globals.previousPaths[v])/100)+k),Math.abs(S)+Math.abs(w)>=360&&(S-=.01),Math.abs(C)+Math.abs(k)>=360&&(C-=.01);var P=S-w,T=Array.isArray(e.config.stroke.dashArray)?e.config.stroke.dashArray[v]:e.config.stroke.dashArray,M=i.drawPath({d:"",stroke:y,strokeWidth:o,fill:"none",fillOpacity:e.config.fill.opacity,classes:"apexcharts-radialbar-area apexcharts-radialbar-slice-"+v,strokeDashArray:T});if(b.setAttrs(M.node,{"data:angle":P,"data:value":t.series[v]}),e.config.chart.dropShadow.enabled){var I=e.config.chart.dropShadow;s.dropShadow(M,I,v)}s.setSelectionFilter(M,0,v),this.addListeners(M,this.radialDataLabels),m.add(M),M.attr({index:0,j:v});var z=0;!this.initialAnim||e.globals.resized||e.globals.dataChanged||(z=(S-w)/360*e.config.chart.animations.speed,this.animDur=z/(1.2*t.series.length)+this.animDur,this.animBeginArr.push(this.animDur)),e.globals.dataChanged&&(z=(S-w)/360*e.config.chart.animations.dynamicAnimation.speed,this.animDur=z/(1.2*t.series.length)+this.animDur,this.animBeginArr.push(this.animDur)),this.animatePaths(M,{centerX:t.centerX,centerY:t.centerY,endAngle:S,startAngle:w,prevEndAngle:C,prevStartAngle:k,size:t.size,i:v,totalItems:2,animBeginArr:this.animBeginArr,dur:z,shouldSetPrevPaths:!0,easing:e.globals.easing})}return{g:r,elHollow:c,dataLabels:u}}},{key:"drawHollow",value:function(t){var e=new b(this.ctx).drawCircle(2*t.size);return e.attr({class:"apexcharts-radialbar-hollow",cx:t.centerX,cy:t.centerY,r:t.size,fill:t.fill}),e}},{key:"drawHollowImage",value:function(t,e,i,a){var s=this.w,r=new L(this.ctx),o=p.randomId(),n=s.config.plotOptions.radialBar.hollow.image;if(s.config.plotOptions.radialBar.hollow.imageClipped)r.clippedImgArea({width:i,height:i,image:n,patternID:"pattern".concat(s.globals.cuid).concat(o)}),a="url(#pattern".concat(s.globals.cuid).concat(o,")");else{var l=s.config.plotOptions.radialBar.hollow.imageWidth,h=s.config.plotOptions.radialBar.hollow.imageHeight;if(void 0===l&&void 0===h){var c=s.globals.dom.Paper.image(n).loaded((function(e){this.move(t.centerX-e.width/2+s.config.plotOptions.radialBar.hollow.imageOffsetX,t.centerY-e.height/2+s.config.plotOptions.radialBar.hollow.imageOffsetY)}));e.add(c)}else{var d=s.globals.dom.Paper.image(n).loaded((function(e){this.move(t.centerX-l/2+s.config.plotOptions.radialBar.hollow.imageOffsetX,t.centerY-h/2+s.config.plotOptions.radialBar.hollow.imageOffsetY),this.size(l,h)}));e.add(d)}}return a}},{key:"getStrokeWidth",value:function(t){var e=this.w;return t.size*(100-parseInt(e.config.plotOptions.radialBar.hollow.size,10))/100/(t.series.length+1)-this.margin}}]),i}(At),Lt=function(){function t(e){a(this,t),this.w=e.w,this.lineCtx=e}return r(t,[{key:"sameValueSeriesFix",value:function(t,e){var i=this.w;if("line"===i.config.chart.type&&("gradient"===i.config.fill.type||"gradient"===i.config.fill.type[t])&&new y(this.lineCtx.ctx,i).seriesHaveSameValues(t)){var a=e[t].slice();a[a.length-1]=a[a.length-1]+1e-6,e[t]=a}return e}},{key:"calculatePoints",value:function(t){var e=t.series,i=t.realIndex,a=t.x,s=t.y,r=t.i,o=t.j,n=t.prevY,l=this.w,h=[],c=[];if(0===o){var d=this.lineCtx.categoryAxisCorrection+l.config.markers.offsetX;l.globals.isXNumeric&&(d=(l.globals.seriesX[i][0]-l.globals.minX)/this.lineCtx.xRatio+l.config.markers.offsetX),h.push(d),c.push(p.isNumber(e[r][0])?n+l.config.markers.offsetY:null),h.push(a+l.config.markers.offsetX),c.push(p.isNumber(e[r][o+1])?s+l.config.markers.offsetY:null)}else h.push(a+l.config.markers.offsetX),c.push(p.isNumber(e[r][o+1])?s+l.config.markers.offsetY:null);return{x:h,y:c}}},{key:"checkPreviousPaths",value:function(t){for(var e=t.pathFromLine,i=t.pathFromArea,a=t.realIndex,s=this.w,r=0;r<s.globals.previousPaths.length;r++){var o=s.globals.previousPaths[r];("line"===o.type||"area"===o.type)&&o.paths.length>0&&parseInt(o.realIndex,10)===parseInt(a,10)&&("line"===o.type?(this.lineCtx.appendPathFrom=!1,e=s.globals.previousPaths[r].paths[0].d):"area"===o.type&&(this.lineCtx.appendPathFrom=!1,i=s.globals.previousPaths[r].paths[0].d,s.config.stroke.show&&s.globals.previousPaths[r].paths[1]&&(e=s.globals.previousPaths[r].paths[1].d)))}return{pathFromLine:e,pathFromArea:i}}},{key:"determineFirstPrevY",value:function(t){var e=t.i,i=t.series,a=t.prevY,s=t.lineYPosition,r=this.w;if(void 0!==i[e][0])a=(s=r.config.chart.stacked&&e>0?this.lineCtx.prevSeriesY[e-1][0]:this.lineCtx.zeroY)-i[e][0]/this.lineCtx.yRatio[this.lineCtx.yaxisIndex]+2*(this.lineCtx.isReversed?i[e][0]/this.lineCtx.yRatio[this.lineCtx.yaxisIndex]:0);else if(r.config.chart.stacked&&e>0&&void 0===i[e][0])for(var o=e-1;o>=0;o--)if(null!==i[o][0]&&void 0!==i[o][0]){a=s=this.lineCtx.prevSeriesY[o][0];break}return{prevY:a,lineYPosition:s}}}]),t}(),Pt=function(){function t(e,i,s){a(this,t),this.ctx=e,this.w=e.w,this.xyRatios=i,this.pointsChart=!("bubble"!==this.w.config.chart.type&&"scatter"!==this.w.config.chart.type)||s,this.scatter=new T(this.ctx),this.noNegatives=this.w.globals.minX===Number.MAX_VALUE,this.lineHelpers=new Lt(this),this.markers=new P(this.ctx),this.prevSeriesY=[],this.categoryAxisCorrection=0,this.yaxisIndex=0}
61903return r(t,[{key:"draw",value:function(t,e,i){var a=this.w,s=new b(this.ctx),r=a.globals.comboCharts?e:a.config.chart.type,o=s.group({class:"apexcharts-".concat(r,"-series apexcharts-plot-series")}),n=new y(this.ctx,a);this.yRatio=this.xyRatios.yRatio,this.zRatio=this.xyRatios.zRatio,this.xRatio=this.xyRatios.xRatio,this.baseLineY=this.xyRatios.baseLineY,t=n.getLogSeries(t),this.yRatio=n.getLogYRatios(this.yRatio);for(var l=[],h=0;h<t.length;h++){t=this.lineHelpers.sameValueSeriesFix(h,t);var c=a.globals.comboCharts?i[h]:h;this._initSerieVariables(t,h,c);var d=[],g=[],u=a.globals.padHorizontal+this.categoryAxisCorrection;this.ctx.series.addCollapsedClassToSeries(this.elSeries,c),a.globals.isXNumeric&&a.globals.seriesX.length>0&&(u=(a.globals.seriesX[c][0]-a.globals.minX)/this.xRatio),g.push(u);var p,f=u,x=f,v=this.zeroY;v=this.lineHelpers.determineFirstPrevY({i:h,series:t,prevY:v,lineYPosition:0}).prevY,d.push(v),p=v;var m=this._calculatePathsFrom({series:t,i:h,realIndex:c,prevX:x,prevY:v}),w=this._iterateOverDataPoints({series:t,realIndex:c,i:h,x:u,y:1,pX:f,pY:p,pathsFrom:m,linePaths:[],areaPaths:[],seriesIndex:i,lineYPosition:0,xArrj:g,yArrj:d});this._handlePaths({type:r,realIndex:c,i:h,paths:w}),this.elSeries.add(this.elPointsMain),this.elSeries.add(this.elDataLabelsWrap),l.push(this.elSeries)}if(a.config.chart.stacked)for(var k=l.length;k>0;k--)o.add(l[k-1]);else for(var A=0;A<l.length;A++)o.add(l[A]);return o}},{key:"_initSerieVariables",value:function(t,e,i){var a=this.w,s=new b(this.ctx);this.xDivision=a.globals.gridWidth/(a.globals.dataPoints-("on"===a.config.xaxis.tickPlacement?1:0)),this.strokeWidth=Array.isArray(a.config.stroke.width)?a.config.stroke.width[i]:a.config.stroke.width,this.yRatio.length>1&&(this.yaxisIndex=i),this.isReversed=a.config.yaxis[this.yaxisIndex]&&a.config.yaxis[this.yaxisIndex].reversed,this.zeroY=a.globals.gridHeight-this.baseLineY[this.yaxisIndex]-(this.isReversed?a.globals.gridHeight:0)+(this.isReversed?2*this.baseLineY[this.yaxisIndex]:0),this.areaBottomY=this.zeroY,(this.zeroY>a.globals.gridHeight||"end"===a.config.plotOptions.area.fillTo)&&(this.areaBottomY=a.globals.gridHeight),this.categoryAxisCorrection=this.xDivision/2,this.elSeries=s.group({class:"apexcharts-series",seriesName:p.escapeString(a.globals.seriesNames[i])}),this.elPointsMain=s.group({class:"apexcharts-series-markers-wrap","data:realIndex":i}),this.elDataLabelsWrap=s.group({class:"apexcharts-datalabels","data:realIndex":i});var r=t[e].length===a.globals.dataPoints;this.elSeries.attr({"data:longestSeries":r,rel:e+1,"data:realIndex":i}),this.appendPathFrom=!0}},{key:"_calculatePathsFrom",value:function(t){var e,i,a,s,r=t.series,o=t.i,n=t.realIndex,l=t.prevX,h=t.prevY,c=this.w,d=new b(this.ctx);if(null===r[o][0]){for(var g=0;g<r[o].length;g++)if(null!==r[o][g]){l=this.xDivision*g,h=this.zeroY-r[o][g]/this.yRatio[this.yaxisIndex],e=d.move(l,h),i=d.move(l,this.areaBottomY);break}}else e=d.move(l,h),i=d.move(l,this.areaBottomY)+d.line(l,h);if(a=d.move(-1,this.zeroY)+d.line(-1,this.zeroY),s=d.move(-1,this.zeroY)+d.line(-1,this.zeroY),c.globals.previousPaths.length>0){var u=this.lineHelpers.checkPreviousPaths({pathFromLine:a,pathFromArea:s,realIndex:n});a=u.pathFromLine,s=u.pathFromArea}return{prevX:l,prevY:h,linePath:e,areaPath:i,pathFromLine:a,pathFromArea:s}}},{key:"_handlePaths",value:function(t){var i=t.type,a=t.realIndex,s=t.i,r=t.paths,o=this.w,n=new b(this.ctx),l=new L(this.ctx);this.prevSeriesY.push(r.yArrj),o.globals.seriesXvalues[a]=r.xArrj,o.globals.seriesYvalues[a]=r.yArrj;var h=o.config.forecastDataPoints;if(h.count>0){var c=o.globals.seriesXvalues[a][o.globals.seriesXvalues[a].length-h.count-1],d=n.drawRect(c,0,o.globals.gridWidth,o.globals.gridHeight,0);o.globals.dom.elForecastMask.appendChild(d.node);var g=n.drawRect(0,0,c,o.globals.gridHeight,0);o.globals.dom.elNonForecastMask.appendChild(g.node)}this.pointsChart||o.globals.delayedElements.push({el:this.elPointsMain.node,index:a});var u={i:s,realIndex:a,animationDelay:s,initialSpeed:o.config.chart.animations.speed,dataChangeSpeed:o.config.chart.animations.dynamicAnimation.speed,className:"apexcharts-".concat(i)};if("area"===i)for(var p=l.fillPath({seriesNumber:a}),f=0;f<r.areaPaths.length;f++){var x=n.renderPaths(e(e({},u),{},{pathFrom:r.pathFromArea,pathTo:r.areaPaths[f],stroke:"none",strokeWidth:0,strokeLineCap:null,fill:p}));this.elSeries.add(x)}if(o.config.stroke.show&&!this.pointsChart){var v=null;v="line"===i?l.fillPath({seriesNumber:a,i:s}):o.globals.stroke.colors[a];for(var m=0;m<r.linePaths.length;m++){var y=e(e({},u),{},{pathFrom:r.pathFromLine,pathTo:r.linePaths[m],stroke:v,strokeWidth:this.strokeWidth,strokeLineCap:o.config.stroke.lineCap,fill:"none"}),w=n.renderPaths(y);if(this.elSeries.add(w),h.count>0){var k=n.renderPaths(y);k.node.setAttribute("stroke-dasharray",h.dashArray),h.strokeWidth&&k.node.setAttribute("stroke-width",h.strokeWidth),this.elSeries.add(k),k.attr("clip-path","url(#forecastMask".concat(o.globals.cuid,")")),w.attr("clip-path","url(#nonForecastMask".concat(o.globals.cuid,")"))}}}}},{key:"_iterateOverDataPoints",value:function(t){for(var e=t.series,i=t.realIndex,a=t.i,s=t.x,r=t.y,o=t.pX,n=t.pY,l=t.pathsFrom,h=t.linePaths,c=t.areaPaths,d=t.seriesIndex,g=t.lineYPosition,u=t.xArrj,f=t.yArrj,x=this.w,v=new b(this.ctx),m=this.yRatio,y=l.prevY,
61903w=l.linePath,k=l.areaPath,A=l.pathFromLine,S=l.pathFromArea,C=p.isNumber(x.globals.minYArr[i])?x.globals.minYArr[i]:x.globals.minY,L=x.globals.dataPoints>1?x.globals.dataPoints-1:x.globals.dataPoints,P=0;P<L;P++){var T=void 0===e[a][P+1]||null===e[a][P+1];if(x.globals.isXNumeric){var M=x.globals.seriesX[i][P+1];void 0===x.globals.seriesX[i][P+1]&&(M=x.globals.seriesX[i][L-1]),s=(M-x.globals.minX)/this.xRatio}else s+=this.xDivision;if(x.config.chart.stacked)if(a>0&&x.globals.collapsedSeries.length<x.config.series.length-1){g=this.prevSeriesY[function(t){for(var e=t,i=0;i<x.globals.series.length;i++)if(x.globals.collapsedSeriesIndices.indexOf(t)>-1){e--;break}return e>=0?e:0}(a-1)][P+1]}else g=this.zeroY;else g=this.zeroY;r=T?g-C/m[this.yaxisIndex]+2*(this.isReversed?C/m[this.yaxisIndex]:0):g-e[a][P+1]/m[this.yaxisIndex]+2*(this.isReversed?e[a][P+1]/m[this.yaxisIndex]:0),u.push(s),f.push(r);var I=this.lineHelpers.calculatePoints({series:e,x:s,y:r,realIndex:i,i:a,j:P,prevY:y}),z=this._createPaths({series:e,i:a,realIndex:i,j:P,x:s,y:r,pX:o,pY:n,linePath:w,areaPath:k,linePaths:h,areaPaths:c,seriesIndex:d});c=z.areaPaths,h=z.linePaths,o=z.pX,n=z.pY,k=z.areaPath,w=z.linePath,this.appendPathFrom&&(A+=v.line(s,this.zeroY),S+=v.line(s,this.zeroY)),this.handleNullDataPoints(e,I,a,P,i),this._handleMarkersAndLabels({pointsPos:I,series:e,x:s,y:r,prevY:y,i:a,j:P,realIndex:i})}return{yArrj:f,xArrj:u,pathFromArea:S,areaPaths:c,pathFromLine:A,linePaths:h}}},{key:"_handleMarkersAndLabels",value:function(t){var e=t.pointsPos;t.series,t.x,t.y,t.prevY;var i=t.i,a=t.j,s=t.realIndex,r=this.w,o=new M(this.ctx);if(this.pointsChart)this.scatter.draw(this.elSeries,a,{realIndex:s,pointsPos:e,zRatio:this.zRatio,elParent:this.elPointsMain});else{r.globals.series[i].length>1&&this.elPointsMain.node.classList.add("apexcharts-element-hidden");var n=this.markers.plotChartMarkers(e,s,a+1);null!==n&&this.elPointsMain.add(n)}var l=o.drawDataLabel(e,s,a+1,null);null!==l&&this.elDataLabelsWrap.add(l)}},{key:"_createPaths",value:function(t){var e=t.series,i=t.i,a=t.realIndex,s=t.j,r=t.x,o=t.y,n=t.pX,l=t.pY,h=t.linePath,c=t.areaPath,d=t.linePaths,g=t.areaPaths,u=t.seriesIndex,p=this.w,f=new b(this.ctx),x=p.config.stroke.curve,v=this.areaBottomY;if(Array.isArray(p.config.stroke.curve)&&(x=Array.isArray(u)?p.config.stroke.curve[u[i]]:p.config.stroke.curve[i]),"smooth"===x){var m=.35*(r-n);p.globals.hasNullValues?(null!==e[i][s]&&(null!==e[i][s+1]?(h=f.move(n,l)+f.curve(n+m,l,r-m,o,r+1,o),c=f.move(n+1,l)+f.curve(n+m,l,r-m,o,r+1,o)+f.line(r,v)+f.line(n,v)+"z"):(h=f.move(n,l),c=f.move(n,l)+"z")),d.push(h),g.push(c)):(h+=f.curve(n+m,l,r-m,o,r,o),c+=f.curve(n+m,l,r-m,o,r,o)),n=r,l=o,s===e[i].length-2&&(c=c+f.curve(n,l,r,o,r,v)+f.move(r,o)+"z",p.globals.hasNullValues||(d.push(h),g.push(c)))}else{if(null===e[i][s+1]){h+=f.move(r,o);var y=p.globals.isXNumeric?(p.globals.seriesX[a][s]-p.globals.minX)/this.xRatio:r-this.xDivision;c=c+f.line(y,v)+f.move(r,o)+"z"}null===e[i][s]&&(h+=f.move(r,o),c+=f.move(r,v)),"stepline"===x?(h=h+f.line(r,null,"H")+f.line(null,o,"V"),c=c+f.line(r,null,"H")+f.line(null,o,"V")):"straight"===x&&(h+=f.line(r,o),c+=f.line(r,o)),s===e[i].length-2&&(c=c+f.line(r,v)+f.move(r,o)+"z",d.push(h),g.push(c))}return{linePaths:d,areaPaths:g,pX:n,pY:l,linePath:h,areaPath:c}}},{key:"handleNullDataPoints",value:function(t,e,i,a,s){var r=this.w;if(null===t[i][a]&&r.config.markers.showNullDataPoints||1===t[i].length){var o=this.markers.plotChartMarkers(e,s,a+1,this.strokeWidth-r.config.markers.strokeWidth/2,!0);null!==o&&this.elPointsMain.add(o)}}}]),t}();window.TreemapSquared={},window.TreemapSquared.generate=function(){function t(e,i,a,s){this.xoffset=e,this.yoffset=i,this.height=s,this.width=a,this.shortestEdge=function(){return Math.min(this.height,this.width)},this.getCoordinates=function(t){var e,i=[],a=this.xoffset,s=this.yoffset,o=r(t)/this.height,n=r(t)/this.width;if(this.width>=this.height)for(e=0;e<t.length;e++)i.push([a,s,a+o,s+t[e]/o]),s+=t[e]/o;else for(e=0;e<t.length;e++)i.push([a,s,a+t[e]/n,s+n]),a+=t[e]/n;return i},this.cutArea=function(e){var i;if(this.width>=this.height){var a=e/this.height,s=this.width-a;i=new t(this.xoffset+a,this.yoffset,s,this.height)}else{var r=e/this.width,o=this.height-r;i=new t(this.xoffset,this.yoffset+r,this.width,o)}return i}}function e(e,a,s,o,n){return o=void 0===o?0:o,n=void 0===n?0:n,function(t){var e,i,a=[];for(e=0;e<t.length;e++)for(i=0;i<t[e].length;i++)a.push(t[e][i]);return a}(i(function(t,e){var i,a=[],s=e/r(t);for(i=0;i<t.length;i++)a[i]=t[i]*s;return a}(e,a*s),[],new t(o,n,a,s),[]))}function i(t,e,s,o){var n,l,h;
61903if(0!==t.length)return n=s.shortestEdge(),function(t,e,i){var s;if(0===t.length)return!0;(s=t.slice()).push(e);var r=a(t,i),o=a(s,i);return r>=o}(e,l=t[0],n)?(e.push(l),i(t.slice(1),e,s,o)):(h=s.cutArea(r(e),o),o.push(s.getCoordinates(e)),i(t,[],h,o)),o;o.push(s.getCoordinates(e))}function a(t,e){var i=Math.min.apply(Math,t),a=Math.max.apply(Math,t),s=r(t);return Math.max(Math.pow(e,2)*a/Math.pow(s,2),Math.pow(s,2)/(Math.pow(e,2)*i))}function s(t){return t&&t.constructor===Array}function r(t){var e,i=0;for(e=0;e<t.length;e++)i+=t[e];return i}function o(t){var e,i=0;if(s(t[0]))for(e=0;e<t.length;e++)i+=o(t[e]);else i=r(t);return i}return function t(i,a,r,n,l){n=void 0===n?0:n,l=void 0===l?0:l;var h,c,d=[],g=[];if(s(i[0])){for(c=0;c<i.length;c++)d[c]=o(i[c]);for(h=e(d,a,r,n,l),c=0;c<i.length;c++)g.push(t(i[c],h[c][2]-h[c][0],h[c][3]-h[c][1],h[c][0],h[c][1]))}else g=e(i,a,r,n,l);return g}}();var Tt,Mt,It=function(){function t(e,i){a(this,t),this.ctx=e,this.w=e.w,this.strokeWidth=this.w.config.stroke.width,this.helpers=new yt(e),this.dynamicAnim=this.w.config.chart.animations.dynamicAnimation,this.labels=[]}return r(t,[{key:"draw",value:function(t){var e=this,i=this.w,a=new b(this.ctx),s=new L(this.ctx),r=a.group({class:"apexcharts-treemap"});if(i.globals.noData)return r;var o=[];return t.forEach((function(t){var e=t.map((function(t){return Math.abs(t)}));o.push(e)})),this.negRange=this.helpers.checkColorRange(),i.config.series.forEach((function(t,i){t.data.forEach((function(t){Array.isArray(e.labels[i])||(e.labels[i]=[]),e.labels[i].push(t.x)}))})),window.TreemapSquared.generate(o,i.globals.gridWidth,i.globals.gridHeight).forEach((function(o,n){var l=a.group({class:"apexcharts-series apexcharts-treemap-series",seriesName:p.escapeString(i.globals.seriesNames[n]),rel:n+1,"data:realIndex":n});if(i.config.chart.dropShadow.enabled){var h=i.config.chart.dropShadow;new x(e.ctx).dropShadow(r,h,n)}var c=a.group({class:"apexcharts-data-labels"});o.forEach((function(r,o){var h=r[0],c=r[1],d=r[2],g=r[3],u=a.drawRect(h,c,d-h,g-c,0,"#fff",1,e.strokeWidth,i.config.plotOptions.treemap.useFillColorAsStroke?f:i.globals.stroke.colors[n]);u.attr({cx:h,cy:c,index:n,i:n,j:o,width:d-h,height:g-c});var p=e.helpers.getShadeColor(i.config.chart.type,n,o,e.negRange),f=p.color;void 0!==i.config.series[n].data[o]&&i.config.series[n].data[o].fillColor&&(f=i.config.series[n].data[o].fillColor);var x=s.fillPath({color:f,seriesNumber:n,dataPointIndex:o});u.node.classList.add("apexcharts-treemap-rect"),u.attr({fill:x}),e.helpers.addListeners(u);var b={x:h+(d-h)/2,y:c+(g-c)/2,width:0,height:0},v={x:h,y:c,width:d-h,height:g-c};if(i.config.chart.animations.enabled&&!i.globals.dataChanged){var m=1;i.globals.resized||(m=i.config.chart.animations.speed),e.animateTreemap(u,b,v,m)}if(i.globals.dataChanged){var y=1;e.dynamicAnim.enabled&&i.globals.shouldAnimate&&(y=e.dynamicAnim.speed,i.globals.previousPaths[n]&&i.globals.previousPaths[n][o]&&i.globals.previousPaths[n][o].rect&&(b=i.globals.previousPaths[n][o].rect),e.animateTreemap(u,b,v,y))}var w=e.getFontSize(r),k=i.config.dataLabels.formatter(e.labels[n][o],{value:i.globals.series[n][o],seriesIndex:n,dataPointIndex:o,w:i}),A=e.helpers.calculateDataLabels({text:k,x:(h+d)/2,y:(c+g)/2+e.strokeWidth/2+w/3,i:n,j:o,colorProps:p,fontSize:w,series:t});i.config.dataLabels.enabled&&A&&e.rotateToFitLabel(A,k,h,c,d,g),l.add(u),null!==A&&l.add(A)})),l.add(c),r.add(l)})),r}},{key:"getFontSize",value:function(t){var e=this.w;var i,a,s,r,o=function t(e){var i,a=0;if(Array.isArray(e[0]))for(i=0;i<e.length;i++)a+=t(e[i]);else for(i=0;i<e.length;i++)a+=e[i].length;return a}(this.labels)/function t(e){var i,a=0;if(Array.isArray(e[0]))for(i=0;i<e.length;i++)a+=t(e[i]);else for(i=0;i<e.length;i++)a+=1;return a}(this.labels);return i=t[2]-t[0],a=t[3]-t[1],s=i*a,r=Math.pow(s,.5),Math.min(r/o,parseInt(e.config.dataLabels.style.fontSize,10))}},{key:"rotateToFitLabel",value:function(t,e,i,a,s,r){var o=new b(this.ctx),n=o.getTextRects(e);if(n.width+5>s-i&&n.width<=r-a){var l=o.rotateAroundCenter(t.node);t.node.setAttribute("transform","rotate(-90 ".concat(l.x," ").concat(l.y,")"))}}}
61903,{key:"animateTreemap",value:function(t,e,i,a){var s=new f(this.ctx);s.animateRect(t,{x:e.x,y:e.y,width:e.width,height:e.height},{x:i.x,y:i.y,width:i.width,height:i.height},a,(function(){s.animationCompleted(t)}))}}]),t}(),zt=86400,Xt=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w,this.timeScaleArray=[],this.utc=this.w.config.xaxis.labels.datetimeUTC}return r(t,[{key:"calculateTimeScaleTicks",value:function(t,i){var a=this,s=this.w;if(s.globals.allSeriesCollapsed)return s.globals.labels=[],s.globals.timescaleLabels=[],[];var r=new Y(this.ctx),o=(i-t)/864e5;this.determineInterval(o),s.globals.disableZoomIn=!1,s.globals.disableZoomOut=!1,o<.00011574074074074075?s.globals.disableZoomIn=!0:o>5e4&&(s.globals.disableZoomOut=!0);var n=r.getTimeUnitsfromTimestamp(t,i,this.utc),l=s.globals.gridWidth/o,h=l/24,c=h/60,d=c/60,g=Math.floor(24*o),u=Math.floor(1440*o),p=Math.floor(o*zt),f=Math.floor(o),x=Math.floor(o/30),b=Math.floor(o/365),v={minMillisecond:n.minMillisecond,minSecond:n.minSecond,minMinute:n.minMinute,minHour:n.minHour,minDate:n.minDate,minMonth:n.minMonth,minYear:n.minYear},m={firstVal:v,currentMillisecond:v.minMillisecond,currentSecond:v.minSecond,currentMinute:v.minMinute,currentHour:v.minHour,currentMonthDate:v.minDate,currentDate:v.minDate,currentMonth:v.minMonth,currentYear:v.minYear,daysWidthOnXAxis:l,hoursWidthOnXAxis:h,minutesWidthOnXAxis:c,secondsWidthOnXAxis:d,numberOfSeconds:p,numberOfMinutes:u,numberOfHours:g,numberOfDays:f,numberOfMonths:x,numberOfYears:b};switch(this.tickInterval){case"years":this.generateYearScale(m);break;case"months":case"half_year":this.generateMonthScale(m);break;case"months_days":case"months_fortnight":case"days":case"week_days":this.generateDayScale(m);break;case"hours":this.generateHourScale(m);break;case"minutes_fives":case"minutes":this.generateMinuteScale(m);break;case"seconds_tens":case"seconds_fives":case"seconds":this.generateSecondScale(m)}var y=this.timeScaleArray.map((function(t){var i={position:t.position,unit:t.unit,year:t.year,day:t.day?t.day:1,hour:t.hour?t.hour:0,month:t.month+1};return"month"===t.unit?e(e({},i),{},{day:1,value:t.value+1}):"day"===t.unit||"hour"===t.unit?e(e({},i),{},{value:t.value}):"minute"===t.unit?e(e({},i),{},{value:t.value,minute:t.value}):"second"===t.unit?e(e({},i),{},{value:t.value,minute:t.minute,second:t.second}):t}));return y.filter((function(t){var e=1,i=Math.ceil(s.globals.gridWidth/120),r=t.value;void 0!==s.config.xaxis.tickAmount&&(i=s.config.xaxis.tickAmount),y.length>i&&(e=Math.floor(y.length/i));var o=!1,n=!1;switch(a.tickInterval){case"years":"year"===t.unit&&(o=!0);break;case"half_year":e=7,"year"===t.unit&&(o=!0);break;case"months":e=1,"year"===t.unit&&(o=!0);break;case"months_fortnight":e=15,"year"!==t.unit&&"month"!==t.unit||(o=!0),30===r&&(n=!0);break;case"months_days":e=10,"month"===t.unit&&(o=!0),30===r&&(n=!0);break;case"week_days":e=8,"month"===t.unit&&(o=!0);break;case"days":e=1,"month"===t.unit&&(o=!0);break;case"hours":"day"===t.unit&&(o=!0);break;case"minutes_fives":r%5!=0&&(n=!0);break;case"seconds_tens":r%10!=0&&(n=!0);break;case"seconds_fives":r%5!=0&&(n=!0)}if("hours"===a.tickInterval||"minutes_fives"===a.tickInterval||"seconds_tens"===a.tickInterval||"seconds_fives"===a.tickInterval){if(!n)return!0}else if((r%e==0||o)&&!n)return!0}))}},{key:"recalcDimensionsBasedOnFormat",value:function(t,e){var i=this.w,a=this.formatDates(t),s=this.removeOverlappingTS(a);i.globals.timescaleLabels=s.slice(),new ot(this.ctx).plotCoords()}},{key:"determineInterval",value:function(t){var e=24*t,i=60*e;switch(!0){case t/365>5:this.tickInterval="years";break;case t>800:this.tickInterval="half_year";break;case t>180:this.tickInterval="months";break;case t>90:this.tickInterval="months_fortnight";break;case t>60:this.tickInterval="months_days";break;case t>30:this.tickInterval="week_days";break;case t>2:this.tickInterval="days";break;case e>2.4:this.tickInterval="hours";break;case i>15:this.tickInterval="minutes_fives";break;case i>5:this.tickInterval="minutes";break;case i>1:this.tickInterval="seconds_tens";break;case 60*i>20:this.tickInterval="seconds_fives";break;default:this.tickInterval="seconds"}}},{key:"generateYearScale",value:function(t){var e=t.firstVal,i=t.currentMonth,a=t.currentYear,s=t.daysWidthOnXAxis,r=t.numberOfYears,o=e.minYear,n=0,l=new Y(this.ctx),h="year";if(e.minDate>1||e.minMonth>0){var c=l.determineRemainingDaysOfYear(e.minYear,e.minMonth,e.minDate);n=(l.determineDaysOfYear(e.minYear)-c+1)*s,o=e.minYear+1,this.timeScaleArray.push({position:n,value:o,unit:h,year:o,month:p.monthMod(i+1)})}else 1===e.minDate&&0===e.minMonth&&this.timeScaleArray.push({position:n,value:o,unit:h,year:a,month:p.monthMod(i+1)});for(var d=o,g=n,u=0;u<r;u++)d++,g=l.determineDaysOfYear(d-1)*s+g,this.timeScaleArray.push({position:g,value:d,unit:h,year:d,month:1})}},{key:"generateMonthScale",value:function(t){var e=t.firstVal,i=t.currentMonthDate,a=t.currentMonth,s=t.currentYear,r=t.daysWidthOnXAxis,o=t.numberOfMonths,n=a,l=0,h=new Y(this.ctx),c="month",d=0;if(e.minDate>1){l=(h.determineDaysOfMonths(a+1,e.minYear)-i+1)*r,n=p.monthMod(a+1);var g=s+d,u=p.monthMod(n),f=n;0===n&&(c="year",f=g,u=1,g+=d+=1),this.timeScaleArray.push({position:l,value:f,unit:c,year:g,month:u})}else this.timeScaleArray.push({position:l,value:n,unit:c,year:s,month:p.monthMod(a)});for(var x=n+1,b=l,v=0,m=1;v<o;v++,m++){0===(x=p.monthMod(x))?(c="year",d+=1):c="month";var y=this._getYear(s,x,d);b=h.determineDaysOfMonths(x,y)*r+b;var w=0===x?y:x;this.timeScaleArray.push({position:b,value:w,unit:c,year:y,month:0===x?1:x}),x++}}},{key:"generateDayScale",value:function(t){var e=t.firstVal,i=t.currentMonth,a=t.currentYear,s=t.hoursWidthOnXAxis,r=t.numberOfDays,o=new Y(this.ctx),n="day",l=e.minDate+1,h=l,c=function(t,e,
61903i){return t>o.determineDaysOfMonths(e+1,i)?(h=1,n="month",g=e+=1,e):e},d=(24-e.minHour)*s,g=l,u=c(h,i,a);0===e.minHour&&1===e.minDate?(d=0,g=p.monthMod(e.minMonth),n="month",h=e.minDate,r++):1!==e.minDate&&0===e.minHour&&0===e.minMinute&&(d=0,l=e.minDate,g=l,u=c(h=l,i,a)),this.timeScaleArray.push({position:d,value:g,unit:n,year:this._getYear(a,u,0),month:p.monthMod(u),day:h});for(var f=d,x=0;x<r;x++){n="day",u=c(h+=1,u,this._getYear(a,u,0));var b=this._getYear(a,u,0);f=24*s+f;var v=1===h?p.monthMod(u):h;this.timeScaleArray.push({position:f,value:v,unit:n,year:b,month:p.monthMod(u),day:v})}}},{key:"generateHourScale",value:function(t){var e=t.firstVal,i=t.currentDate,a=t.currentMonth,s=t.currentYear,r=t.minutesWidthOnXAxis,o=t.numberOfHours,n=new Y(this.ctx),l="hour",h=function(t,e){return t>n.determineDaysOfMonths(e+1,s)&&(x=1,e+=1),{month:e,date:x}},c=function(t,e){return t>n.determineDaysOfMonths(e+1,s)?e+=1:e},d=60-(e.minMinute+e.minSecond/60),g=d*r,u=e.minHour+1,f=u+1;60===d&&(g=0,f=(u=e.minHour)+1);var x=i,b=c(x,a);this.timeScaleArray.push({position:g,value:u,unit:l,day:x,hour:f,year:s,month:p.monthMod(b)});for(var v=g,m=0;m<o;m++){if(l="hour",f>=24)f=0,l="day",b=h(x+=1,b).month,b=c(x,b);var y=this._getYear(s,b,0);v=0===f&&0===m?d*r:60*r+v;var w=0===f?x:f;this.timeScaleArray.push({position:v,value:w,unit:l,hour:f,day:x,year:y,month:p.monthMod(b)}),f++}}},{key:"generateMinuteScale",value:function(t){for(var e=t.currentMillisecond,i=t.currentSecond,a=t.currentMinute,s=t.currentHour,r=t.currentDate,o=t.currentMonth,n=t.currentYear,l=t.minutesWidthOnXAxis,h=t.secondsWidthOnXAxis,c=t.numberOfMinutes,d=a+1,g=r,u=o,f=n,x=s,b=(60-i-e/1e3)*h,v=0;v<c;v++)d>=60&&(d=0,24===(x+=1)&&(x=0)),this.timeScaleArray.push({position:b,value:d,unit:"minute",hour:x,minute:d,day:g,year:this._getYear(f,u,0),month:p.monthMod(u)}),b+=l,d++}},{key:"generateSecondScale",value:function(t){for(var e=t.currentMillisecond,i=t.currentSecond,a=t.currentMinute,s=t.currentHour,r=t.currentDate,o=t.currentMonth,n=t.currentYear,l=t.secondsWidthOnXAxis,h=t.numberOfSeconds,c=i+1,d=a,g=r,u=o,f=n,x=s,b=(1e3-e)/1e3*l,v=0;v<h;v++)c>=60&&(c=0,++d>=60&&(d=0,24===++x&&(x=0))),this.timeScaleArray.push({position:b,value:c,unit:"second",hour:x,minute:d,second:c,day:g,year:this._getYear(f,u,0),month:p.monthMod(u)}),b+=l,c++}},{key:"createRawDateString",value:function(t,e){var i=t.year;return 0===t.month&&(t.month=1),i+="-"+("0"+t.month.toString()).slice(-2),"day"===t.unit?i+="day"===t.unit?"-"+("0"+e).slice(-2):"-01":i+="-"+("0"+(t.day?t.day:"1")).slice(-2),"hour"===t.unit?i+="hour"===t.unit?"T"+("0"+e).slice(-2):"T00":i+="T"+("0"+(t.hour?t.hour:"0")).slice(-2),"minute"===t.unit?i+=":"+("0"+e).slice(-2):i+=":"+(t.minute?("0"+t.minute).slice(-2):"00"),"second"===t.unit?i+=":"+("0"+e).slice(-2):i+=":00",this.utc&&(i+=".000Z"),i}},{key:"formatDates",value:function(t){var e=this,i=this.w;return t.map((function(t){var a=t.value.toString(),s=new Y(e.ctx),r=e.createRawDateString(t,a),o=s.getDate(s.parseDate(r));if(e.utc||(o=s.getDate(s.parseDateWithTimezone(r))),void 0===i.config.xaxis.labels.format){var n="dd MMM",l=i.config.xaxis.labels.datetimeFormatter;"year"===t.unit&&(n=l.year),"month"===t.unit&&(n=l.month),"day"===t.unit&&(n=l.day),"hour"===t.unit&&(n=l.hour),"minute"===t.unit&&(n=l.minute),"second"===t.unit&&(n=l.second),a=s.formatDate(o,n)}else a=s.formatDate(o,i.config.xaxis.labels.format);return{dateString:r,position:t.position,value:a,unit:t.unit,year:t.year,month:t.month}}))}},{key:"removeOverlappingTS",value:function(t){var e,i=this,a=new b(this.ctx),s=!1;t.length>0&&t[0].value&&t.every((function(e){return e.value.length===t[0].value.length}))&&(s=!0,e=a.getTextRects(t[0].value).width);var r=0,o=t.map((function(o,n){if(n>0&&i.w.config.xaxis.labels.hideOverlappingLabels){var l=s?e:a.getTextRects(t[r].value).width,h=t[r].position;return o.position>h+l+10?(r=n,o):null}return o}));return o=o.filter((function(t){return null!==t}))}},{key:"_getYear",value:function(t,e,i){return t+Math.floor(e/12)+i}}]),t}(),Et=function(){function t(e,i){a(this,t),this.ctx=i,this.w=i.w,this.el=e}return r(t,[{key:"setupElements",value:function(){var t=this.w.globals,e=this.w.config,i=e.chart.type;t.axisCharts=["line","area","bar","rangeBar","candlestick","boxPlot","scatter","bubble","radar","heatmap","treemap"].indexOf(i)>-1,t.xyCharts=["line","area","bar","rangeBar","candlestick","boxPlot","scatter","bubble"].indexOf(i)>-1,t.isBarHorizontal=("bar"===e.chart.type||"rangeBar"===e.chart.type||"boxPlot"===e.chart.type)&&e.plotOptions.bar.horizontal,t.chartClass=".apexcharts"+t.chartID,t.dom.baseEl=this.el,t.dom.elWrap=document.createElement("div"),b.setAttrs(t.dom.elWrap,{id:t.chartClass.substring(1),class:"apexcharts-canvas "+t.chartClass.substring(1)}),this.el.appendChild(t.dom.elWrap),t.dom.Paper=new window.SVG.Doc(t.dom.elWrap),t.dom.Paper.attr({class:"apexcharts-svg","xmlns:data":"ApexChartsNS",transform:"translate(".concat(e.chart.offsetX,", ").concat(e.chart.offsetY,")")}),t.dom.Paper.node.style.background=e.chart.background,this.setSVGDimensions(),t.dom.elGraphical=t.dom.Paper.group().attr({class:"apexcharts-inner apexcharts-graphical"}),t.dom.elAnnotations=t.dom.Paper.group().attr({class:"apexcharts-annotations"}
61903),t.dom.elDefs=t.dom.Paper.defs(),t.dom.elLegendWrap=document.createElement("div"),t.dom.elLegendWrap.classList.add("apexcharts-legend"),t.dom.elWrap.appendChild(t.dom.elLegendWrap),t.dom.Paper.add(t.dom.elGraphical),t.dom.elGraphical.add(t.dom.elDefs)}},{key:"plotChartType",value:function(t,e){var i=this.w,a=i.config,s=i.globals,r={series:[],i:[]},o={series:[],i:[]},n={series:[],i:[]},l={series:[],i:[]},h={series:[],i:[]},c={series:[],i:[]},d={series:[],i:[]};s.series.map((function(e,g){var u=0;void 0!==t[g].type?("column"===t[g].type||"bar"===t[g].type?(s.series.length>1&&a.plotOptions.bar.horizontal&&console.warn("Horizontal bars are not supported in a mixed/combo chart. Please turn off `plotOptions.bar.horizontal`"),h.series.push(e),h.i.push(g),u++,i.globals.columnSeries=h.series):"area"===t[g].type?(o.series.push(e),o.i.push(g),u++):"line"===t[g].type?(r.series.push(e),r.i.push(g),u++):"scatter"===t[g].type?(n.series.push(e),n.i.push(g)):"bubble"===t[g].type?(l.series.push(e),l.i.push(g),u++):"candlestick"===t[g].type?(c.series.push(e),c.i.push(g),u++):"boxPlot"===t[g].type?(d.series.push(e),d.i.push(g),u++):console.warn("You have specified an unrecognized chart type. Available types for this property are line/area/column/bar/scatter/bubble"),u>1&&(s.comboCharts=!0)):(r.series.push(e),r.i.push(g))}));var g=new Pt(this.ctx,e),u=new mt(this.ctx,e);this.ctx.pie=new At(this.ctx);var p=new Ct(this.ctx);this.ctx.rangeBar=new F(this.ctx,e);var f=new St(this.ctx),x=[];if(s.comboCharts){if(o.series.length>0&&x.push(g.draw(o.series,"area",o.i)),h.series.length>0)if(i.config.chart.stacked){var b=new vt(this.ctx,e);x.push(b.draw(h.series,h.i))}else this.ctx.bar=new E(this.ctx,e),x.push(this.ctx.bar.draw(h.series,h.i));if(r.series.length>0&&x.push(g.draw(r.series,"line",r.i)),c.series.length>0&&x.push(u.draw(c.series,c.i)),d.series.length>0&&x.push(u.draw(d.series,d.i)),n.series.length>0){var v=new Pt(this.ctx,e,!0);x.push(v.draw(n.series,"scatter",n.i))}if(l.series.length>0){var m=new Pt(this.ctx,e,!0);x.push(m.draw(l.series,"bubble",l.i))}}else switch(a.chart.type){case"line":x=g.draw(s.series,"line");break;case"area":x=g.draw(s.series,"area");break;case"bar":if(a.chart.stacked)x=new vt(this.ctx,e).draw(s.series);else this.ctx.bar=new E(this.ctx,e),x=this.ctx.bar.draw(s.series);break;case"candlestick":x=new mt(this.ctx,e).draw(s.series);break;case"boxPlot":x=new mt(this.ctx,e).draw(s.series);break;case"rangeBar":x=this.ctx.rangeBar.draw(s.series);break;case"heatmap":x=new wt(this.ctx,e).draw(s.series);break;case"treemap":x=new It(this.ctx,e).draw(s.series);break;case"pie":case"donut":case"polarArea":x=this.ctx.pie.draw(s.series);break;case"radialBar":x=p.draw(s.series);break;case"radar":x=f.draw(s.series);break;default:x=g.draw(s.series)}return x}},{key:"setSVGDimensions",value:function(){var t=this.w.globals,e=this.w.config;t.svgWidth=e.chart.width,t.svgHeight=e.chart.height;var i=p.getDimensions(this.el),a=e.chart.width.toString().split(/[0-9]+/g).pop();"%"===a?p.isNumber(i[0])&&(0===i[0].width&&(i=p.getDimensions(this.el.parentNode)),t.svgWidth=i[0]*parseInt(e.chart.width,10)/100):"px"!==a&&""!==a||(t.svgWidth=parseInt(e.chart.width,10));var s=e.chart.height.toString().split(/[0-9]+/g).pop();if("auto"!==t.svgHeight&&""!==t.svgHeight)if("%"===s){var r=p.getDimensions(this.el.parentNode);t.svgHeight=r[1]*parseInt(e.chart.height,10)/100}else t.svgHeight=parseInt(e.chart.height,10);else t.axisCharts?t.svgHeight=t.svgWidth/1.61:t.svgHeight=t.svgWidth/1.2;if(t.svgWidth<0&&(t.svgWidth=0),t.svgHeight<0&&(t.svgHeight=0),b.setAttrs(t.dom.Paper.node,{width:t.svgWidth,height:t.svgHeight}),"%"!==s){var o=e.chart.sparkline.enabled?0:t.axisCharts?e.chart.parentHeightOffset:0;t.dom.Paper.node.parentNode.parentNode.style.minHeight=t.svgHeight+o+"px"}t.dom.elWrap.style.width=t.svgWidth+"px",t.dom.elWrap.style.height=t.svgHeight+"px"}},{key:"shiftGraphPosition",value:function(){var t=this.w.globals,e=t.translateY,i={transform:"translate("+t.translateX+", "+e+")"};b.setAttrs(t.dom.elGraphical.node,i)}},{key:"resizeNonAxisCharts",value:function(){var t=this.w,e=t.globals,i=0,a=t.config.chart.sparkline.enabled?1:15;a+=t.config.grid.padding.bottom,"top"!==t.config.legend.position&&"bottom"!==t.config.legend.position||!t.config.legend.show||t.config.legend.floating||(i=new lt(this.ctx).legendHelpers.getLegendBBox().clwh+10);var s=t.globals.dom.baseEl.querySelector(".apexcharts-radialbar, .apexcharts-pie"),r=2.05*t.globals.radialSize;if(s&&!t.config.chart.sparkline.enabled&&0!==t.config.plotOptions.radialBar.startAngle){var o=p.getBoundingClientRect(s);r=o.bottom;var n=o.bottom-o.top;r=Math.max(2.05*t.globals.radialSize,n)}var l=r+e.translateY+i+a;e.dom.elLegendForeign&&e.dom.elLegendForeign.setAttribute("height",l),e.dom.elWrap.style.height=l+"px",b.setAttrs(e.dom.Paper.node,{height:l}),e.dom.Paper.node.parentNode.parentNode.style.minHeight=l+"px"}},{key:"coreCalculations",value:function(){new U(this.ctx).init()}},{key:"resetGlobals",value:function(){var t=this,e=function(){return t.w.config.series.map((function(t){return[]}))},i=new D,a=this.w.globals;i.initGlobalVars(a),a.seriesXvalues=e(),a.seriesYvalues=e()}},{key:"isMultipleY",value:function(){if(this.w.config.yaxis.constructor===Array&&this.w.config.yaxis.length>1)return this.w.globals.isMultipleYAxis=!0,!0}},{key:"xySettings",value:function(){var t=null,e=this.w;if(e.globals.axisCharts){if("back"===e.config.xaxis.crosshairs.position)new Q(this.ctx).drawXCrosshairs();if("back"===e.config.yaxis[0].crosshairs.position)new Q(this.ctx).drawYCrosshairs();if("datetime"===e.config.xaxis.type&&void 0===e.config.xaxis.labels.formatter){this.ctx.timeScale=new Xt(this.ctx);var i=[];isFinite(e.globals.minX)&&isFinite(e.globals.maxX)&&!e.globals.isBarHorizontal?i=this.ctx.timeScale.calculateTimeScaleTicks(e.globals.minX,e.globals.maxX):e.globals.isBarHorizontal&&(i=this.ctx.timeScale.calculateTimeScaleTicks(e.globals.minY,e.globals.maxY)),this.ctx.timeScale.recalcDimensionsBasedOnFormat(i)}t=new y(this.ctx).getCalculatedRatios()}return t}},{key:"updateSourceChart",value:function(t){this.ctx.w.globals.selection=void 0,this.ctx.updateHelpers._updateOptions({chart:{selection:{xaxis:{min:t.w.globals.minX,max:t.w.globals.maxX}}}},!1,!1)}},{key:"setupBrushHandler",value:function(){var t=this,i=this.w;if(i.config.chart.brush.enabled&&"function"!=typeof i.config.chart.events.selection){var a=i.config.chart.brush.targets||[i.config.chart.brush.target];a.forEach((function(e){var i=ApexCharts.getChartByID(e);i.w.globals.brushSource=t.ctx,"function"!=typeof i.w.config.chart.events.zoomed&&(i.w.c
61903onfig.chart.events.zoomed=function(){t.updateSourceChart(i)}),"function"!=typeof i.w.config.chart.events.scrolled&&(i.w.config.chart.events.scrolled=function(){t.updateSourceChart(i)})})),i.config.chart.events.selection=function(t,s){a.forEach((function(t){var a=ApexCharts.getChartByID(t),r=p.clone(i.config.yaxis);if(i.config.chart.brush.autoScaleYaxis&&1===a.w.globals.series.length){var o=new j(a);r=o.autoScaleY(a,r,s)}var n=a.w.config.yaxis.reduce((function(t,i,s){return[].concat(g(t),[e(e({},a.w.config.yaxis[s]),{},{min:r[0].min,max:r[0].max})])}),[]);a.ctx.updateHelpers._updateOptions({xaxis:{min:s.xaxis.min,max:s.xaxis.max},yaxis:n},!1,!1,!1,!1)}))}}}}]),t}(),Yt=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w}return r(t,[{key:"_updateOptions",value:function(t){var e=this,a=arguments.length>1&&void 0!==arguments[1]&&arguments[1],s=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],r=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],o=arguments.length>4&&void 0!==arguments[4]&&arguments[4];return new Promise((function(n){var l=[e.ctx];r&&(l=e.ctx.getSyncedCharts()),e.ctx.w.globals.isExecCalled&&(l=[e.ctx],e.ctx.w.globals.isExecCalled=!1),l.forEach((function(r,h){var c=r.w;return c.globals.shouldAnimate=s,a||(c.globals.resized=!0,c.globals.dataChanged=!0,s&&r.series.getPreviousPaths()),t&&"object"===i(t)&&(r.config=new H(t),t=y.extendArrayProps(r.config,t,c),r.w.globals.chartID!==e.ctx.w.globals.chartID&&delete t.series,c.config=p.extend(c.config,t),o&&(c.globals.lastXAxis=t.xaxis?p.clone(t.xaxis):[],c.globals.lastYAxis=t.yaxis?p.clone(t.yaxis):[],c.globals.initialConfig=p.extend({},c.config),c.globals.initialSeries=p.clone(c.config.series))),r.update(t).then((function(){h===l.length-1&&n(r)}))}))}))}},{key:"_updateSeries",value:function(t,e){var i=this,a=arguments.length>2&&void 0!==arguments[2]&&arguments[2];return new Promise((function(s){var r,o=i.w;return o.globals.shouldAnimate=e,o.globals.dataChanged=!0,e&&i.ctx.series.getPreviousPaths(),o.globals.axisCharts?(0===(r=t.map((function(t,e){return i._extendSeries(t,e)}))).length&&(r=[{data:[]}]),o.config.series=r):o.config.series=t.slice(),a&&(o.globals.initialSeries=p.clone(o.config.series)),i.ctx.update().then((function(){s(i.ctx)}))}))}},{key:"_extendSeries",value:function(t,i){var a=this.w,s=a.config.series[i];return e(e({},a.config.series[i]),{},{name:t.name?t.name:s&&s.name,color:t.color?t.color:s&&s.color,type:t.type?t.type:s&&s.type,data:t.data?t.data:s&&s.data})}},{key:"toggleDataPointSelection",value:function(t,e){var i=this.w,a=null,s=".apexcharts-series[data\\:realIndex='".concat(t,"']");return i.globals.axisCharts?a=i.globals.dom.Paper.select("".concat(s," path[j='").concat(e,"'], ").concat(s," circle[j='").concat(e,"'], ").concat(s," rect[j='").concat(e,"']")).members[0]:void 0===e&&(a=i.globals.dom.Paper.select("".concat(s," path[j='").concat(t,"']")).members[0],"pie"!==i.config.chart.type&&"polarArea"!==i.config.chart.type&&"donut"!==i.config.chart.type||this.ctx.pie.pieClicked(t)),a?(new b(this.ctx).pathMouseDown(a,null),a.node?a.node:null):(console.warn("toggleDataPointSelection: Element not found"),null)}},{key:"forceXAxisUpdate",value:function(t){var e=this.w;if(["min","max"].forEach((function(i){void 0!==t.xaxis[i]&&(e.config.xaxis[i]=t.xaxis[i],e.globals.lastXAxis[i]=t.xaxis[i])})),t.xaxis.categories&&t.xaxis.categories.length&&(e.config.xaxis.categories=t.xaxis.categories),e.config.xaxis.convertedCatToNumeric){var i=new R(t);t=i.convertCatToNumericXaxis(t,this.ctx)}return t}},{key:"forceYAxisUpdate",value:function(t){var e=this.w;return e.config.chart.stacked&&"100%"===e.config.chart.stackType&&(Array.isArray(t.yaxis)?t.yaxis.forEach((function(e,i){t.yaxis[i].min=0,t.yaxis[i].max=100})):(t.yaxis.min=0,t.yaxis.max=100)),t}},{key:"revertDefaultAxisMinMax",value:function(t){var e=this,i=this.w,a=i.globals.lastXAxis,s=i.globals.lastYAxis;t&&t.xaxis&&(a=t.xaxis),t&&t.yaxis&&(s=t.yaxis),i.config.xaxis.min=a.min,i.config.xaxis.max=a.max;var r=function(t){void 0!==s[t]&&(i.config.yaxis[t].min=s[t].min,i.config.yaxis[t].max=s[t].max)};i.config.yaxis.map((function(t,a){i.globals.zoomed||void 0!==s[a]?r(a):void 0!==e.ctx.opts.yaxis[a]&&(t.min=e.ctx.opts.yaxis[a].min,t.max=e.ctx.opts.yaxis[a].max)}))}}]),t}();Tt="undefined"!=typeof window?window:void 0,Mt=function(t,e){var a=(void 0!==this?this:t).SVG=function(t){if(a.supported)return t=new a.Doc(t),a.parser.draw||a.prepare(),t};if(a.ns="http://www.w3.org/2000/svg",a.xmlns="http://www.w3.org/2000/xmlns/",a.xlink="http://www.w3.org/1999/xlink",a.svgjs="http://svgjs.dev",a.supported=!0,!a.supported)return!1;a.did=1e3,a.eid=function(t){return"Svgjs"+d(t)+a.did++},a.create=function(t){var i=e.createElementNS(this.ns,t);return i.setAttribute("id",this.eid(t)),i},a.extend=function(){var t,e;e=(t=[].slice.call(arguments)).pop();for(var i=t.length-1;i>=0;i--)if(t[i])for(var s in e)t[i].prototype[s]=e[s];a.Set&&a.Set.inherit&&a.Set.inherit()},a.invent=function(t){var e="function"==typeof t.create?t.create:function(){this.constructor.call(this,a.create(t.create))};return t.inherit&&(e.prototype=new t.inherit),t.extend&&a.extend(e,t.extend),t.construct&&a.extend(t.parent||a.Container,t.construct),e},a.adopt=function(e){return e?e.instance?e.instance:((i="svg"==e.nodeName?e.parentNode instanceof t.SVGElement?new a.Nested:new a.Doc:"linearGradient"==e.nodeName?new a.Gradient("linear"):"radialGradient"==e.nodeName?new a.Gradient("radial"):a[d(e.nodeName)]?new(a[d(e.nodeName)]):new a.Element(e)).type=e.nodeName,i.node=e,e.instance=i,i instanceof a.Doc&&i.namespace().defs(),i.setData(JSON.parse(e.getAttribute("svgjs:data"))||{}),i):null;var i},a.prepare=function(){var t=e.getElementsByTagName("body")[0],i=(t?new a.Doc(t):a.adopt(e.documentElement).nested()).size(2,0);a.parser={body:t||e.documentElement,draw:i.style("opacity:0;position:absolute;
61903left:-100%;top:-100%;overflow:hidden").node,poly:i.polyline().node,path:i.path().node,native:a.create("svg")}},a.parser={native:a.create("svg")},e.addEventListener("DOMContentLoaded",(function(){a.parser.draw||a.prepare()}),!1),a.regex={numberAndUnit:/^([+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?)([a-z%]*)$/i,hex:/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i,rgb:/rgb\((\d+),(\d+),(\d+)\)/,reference:/#([a-z0-9\-_]+)/i,transforms:/\)\s*,?\s*/,whitespace:/\s/g,isHex:/^#[a-f0-9]{3,6}$/i,isRgb:/^rgb\(/,isCss:/[^:]+:[^;]+;?/,isBlank:/^(\s+)?$/,isNumber:/^[+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,isPercent:/^-?[\d\.]+%$/,isImage:/\.(jpg|jpeg|png|gif|svg)(\?[^=]+.*)?/i,delimiter:/[\s,]+/,hyphen:/([^e])\-/gi,pathLetters:/[MLHVCSQTAZ]/gi,isPathLetter:/[MLHVCSQTAZ]/i,numbersWithDots:/((\d?\.\d+(?:e[+-]?\d+)?)((?:\.\d+(?:e[+-]?\d+)?)+))+/gi,dots:/\./g},a.utils={map:function(t,e){for(var i=t.length,a=[],s=0;s<i;s++)a.push(e(t[s]));return a},filter:function(t,e){for(var i=t.length,a=[],s=0;s<i;s++)e(t[s])&&a.push(t[s]);return a},filterSVGElements:function(e){return this.filter(e,(function(e){return e instanceof t.SVGElement}))}},a.defaults={attrs:{"fill-opacity":1,"stroke-opacity":1,"stroke-width":0,"stroke-linejoin":"miter","stroke-linecap":"butt",fill:"#000000",stroke:"#000000",opacity:1,x:0,y:0,cx:0,cy:0,width:0,height:0,r:0,rx:0,ry:0,offset:0,"stop-opacity":1,"stop-color":"#000000","font-size":16,"font-family":"Helvetica, Arial, sans-serif","text-anchor":"start"}},a.Color=function(t){var e,s;this.r=0,this.g=0,this.b=0,t&&("string"==typeof t?a.regex.isRgb.test(t)?(e=a.regex.rgb.exec(t.replace(a.regex.whitespace,"")),this.r=parseInt(e[1]),this.g=parseInt(e[2]),this.b=parseInt(e[3])):a.regex.isHex.test(t)&&(e=a.regex.hex.exec(4==(s=t).length?["#",s.substring(1,2),s.substring(1,2),s.substring(2,3),s.substring(2,3),s.substring(3,4),s.substring(3,4)].join(""):s),this.r=parseInt(e[1],16),this.g=parseInt(e[2],16),this.b=parseInt(e[3],16)):"object"===i(t)&&(this.r=t.r,this.g=t.g,this.b=t.b))},a.extend(a.Color,{toString:function(){return this.toHex()},toHex:function(){return"#"+g(this.r)+g(this.g)+g(this.b)},toRgb:function(){return"rgb("+[this.r,this.g,this.b].join()+")"},brightness:function(){return this.r/255*.3+this.g/255*.59+this.b/255*.11},morph:function(t){return this.destination=new a.Color(t),this},at:function(t){return this.destination?(t=t<0?0:t>1?1:t,new a.Color({r:~~(this.r+(this.destination.r-this.r)*t),g:~~(this.g+(this.destination.g-this.g)*t),b:~~(this.b+(this.destination.b-this.b)*t)})):this}}),a.Color.test=function(t){return t+="",a.regex.isHex.test(t)||a.regex.isRgb.test(t)},a.Color.isRgb=function(t){return t&&"number"==typeof t.r&&"number"==typeof t.g&&"number"==typeof t.b},a.Color.isColor=function(t){return a.Color.isRgb(t)||a.Color.test(t)},a.Array=function(t,e){0==(t=(t||[]).valueOf()).length&&e&&(t=e.valueOf()),this.value=this.parse(t)},a.extend(a.Array,{toString:function(){return this.value.join(" ")},valueOf:function(){return this.value},parse:function(t){return t=t.valueOf(),Array.isArray(t)?t:this.split(t)}}),a.PointArray=function(t,e){a.Array.call(this,t,e||[[0,0]])},a.PointArray.prototype=new a.Array,a.PointArray.prototype.constructor=a.PointArray;for(var s={M:function(t,e,i){return e.x=i.x=t[0],e.y=i.y=t[1],["M",e.x,e.y]},L:function(t,e){return e.x=t[0],e.y=t[1],["L",t[0],t[1]]},H:function(t,e){return e.x=t[0],["H",t[0]]},V:function(t,e){return e.y=t[0],["V",t[0]]},C:function(t,e){return e.x=t[4],e.y=t[5],["C",t[0],t[1],t[2],t[3],t[4],t[5]]},Q:function(t,e){return e.x=t[2],e.y=t[3],["Q",t[0],t[1],t[2],t[3]]},Z:function(t,e,i){return e.x=i.x,e.y=i.y,["Z"]}},r="mlhvqtcsaz".split(""),o=0,n=r.length;o<n;++o)s[r[o]]=function(t){return function(e,i,a){if("H"==t)e[0]=e[0]+i.x;else if("V"==t)e[0]=e[0]+i.y;else if("A"==t)e[5]=e[5]+i.x,e[6]=e[6]+i.y;else for(var r=0,o=e.length;r<o;++r)e[r]=e[r]+(r%2?i.y:i.x);if(s&&"function"==typeof s[t])return s[t](e,i,a)}}(r[o].toUpperCase());a.PathArray=function(t,e){a.Array.call(this,t,e||[["M",0,0]])},a.PathArray.prototype=new a.Array,a.PathArray.prototype.constructor=a.PathArray,a.extend(a.PathArray,{toString:function(){return function(t){for(var e=0,i=t.length,a="";e<i;e++)a+=t[e][0],null!=t[e][1]&&(a+=t[e][1],null!=t[e][2]&&(a+=" ",a+=t[e][2],null!=t[e][3]&&(a+=" ",a+=t[e][3],a+=" ",a+=t[e][4],null!=t[e][5]&&(a+=" ",a+=t[e][5],a+=" ",a+=t[e][6],null!=t[e][7]&&
61903(a+=" ",a+=t[e][7])))));return a+" "}(this.value)},move:function(t,e){var i=this.bbox();return i.x,i.y,this},at:function(t){if(!this.destination)return this;for(var e=this.value,i=this.destination.value,s=[],r=new a.PathArray,o=0,n=e.length;o<n;o++){s[o]=[e[o][0]];for(var l=1,h=e[o].length;l<h;l++)s[o][l]=e[o][l]+(i[o][l]-e[o][l])*t;"A"===s[o][0]&&(s[o][4]=+(0!=s[o][4]),s[o][5]=+(0!=s[o][5]))}return r.value=s,r},parse:function(t){if(t instanceof a.PathArray)return t.valueOf();var e,i={M:2,L:2,H:1,V:1,C:6,S:4,Q:4,T:2,A:7,Z:0};t="string"==typeof t?t.replace(a.regex.numbersWithDots,h).replace(a.regex.pathLetters," $& ").replace(a.regex.hyphen,"$1 -").trim().split(a.regex.delimiter):t.reduce((function(t,e){return[].concat.call(t,e)}),[]);var r=[],o=new a.Point,n=new a.Point,l=0,c=t.length;do{a.regex.isPathLetter.test(t[l])?(e=t[l],++l):"M"==e?e="L":"m"==e&&(e="l"),r.push(s[e].call(null,t.slice(l,l+=i[e.toUpperCase()]).map(parseFloat),o,n))}while(c>l);return r},bbox:function(){return a.parser.draw||a.prepare(),a.parser.path.setAttribute("d",this.toString()),a.parser.path.getBBox()}}),a.Number=a.invent({create:function(t,e){this.value=0,this.unit=e||"","number"==typeof t?this.value=isNaN(t)?0:isFinite(t)?t:t<0?-34e37:34e37:"string"==typeof t?(e=t.match(a.regex.numberAndUnit))&&(this.value=parseFloat(e[1]),"%"==e[5]?this.value/=100:"s"==e[5]&&(this.value*=1e3),this.unit=e[5]):t instanceof a.Number&&(this.value=t.valueOf(),this.unit=t.unit)},extend:{toString:function(){return("%"==this.unit?~~(1e8*this.value)/1e6:"s"==this.unit?this.value/1e3:this.value)+this.unit},toJSON:function(){return this.toString()},valueOf:function(){return this.value},plus:function(t){return t=new a.Number(t),new a.Number(this+t,this.unit||t.unit)},minus:function(t){return t=new a.Number(t),new a.Number(this-t,this.unit||t.unit)},times:function(t){return t=new a.Number(t),new a.Number(this*t,this.unit||t.unit)},divide:function(t){return t=new a.Number(t),new a.Number(this/t,this.unit||t.unit)},to:function(t){var e=new a.Number(this);return"string"==typeof t&&(e.unit=t),e},morph:function(t){return this.destination=new a.Number(t),t.relative&&(this.destination.value+=this.value),this},at:function(t){return this.destination?new a.Number(this.destination).minus(this).times(t).plus(this):this}}}),a.Element=a.invent({create:function(t){this._stroke=a.defaults.attrs.stroke,this._event=null,this.dom={},(this.node=t)&&(this.type=t.nodeName,this.node.instance=this,this._stroke=t.getAttribute("stroke")||this._stroke)},extend:{x:function(t){return this.attr("x",t)},y:function(t){return this.attr("y",t)},cx:function(t){return null==t?this.x()+this.width()/2:this.x(t-this.width()/2)},cy:function(t){return null==t?this.y()+this.height()/2:this.y(t-this.height()/2)},move:function(t,e){return this.x(t).y(e)},center:function(t,e){return this.cx(t).cy(e)},width:function(t){return this.attr("width",t)},height:function(t){return this.attr("height",t)},size:function(t,e){var i=u(this,t,e);return this.width(new a.Number(i.width)).height(new a.Number(i.height))},clone:function(t){this.writeDataToDom();var e=x(this.node.cloneNode(!0));return t?t.add(e):this.after(e),e},remove:function(){return this.parent()&&this.parent().removeElement(this),this},replace:function(t){return this.after(t).remove(),t},addTo:function(t){return t.put(this)},putIn:function(t){return t.add(this)},id:function(t){return this.attr("id",t)},show:function(){return this.style("display","")},hide:function(){return this.style("display","none")},visible:function(){return"none"!=this.style("display")},toString:function(){return this.attr("id")},classes:function(){var t=this.attr("class");return null==t?[]:t.trim().split(a.regex.delimiter)},hasClass:function(t){return-1!=this.classes().indexOf(t)},addClass:function(t){if(!this.hasClass(t)){var e=this.classes();e.push(t),this.attr("class",e.join(" "))}return this},removeClass:function(t){return this.hasClass(t)&&this.attr("class",this.classes().filter((function(e){return e!=t})).join(" ")),this},toggleClass:function(t){return this.hasClass(t)?this.removeClass(t):this.addClass(t)},reference:function(t){return a.get(this.attr(t))},parent:function(e){var i=this;if(!i.node.parentNode)return null;if(i=a.adopt(i.node.parentNode),!e)return i;for(;i&&i.node instanceof t.SVGElement;){if("string"==typeof e?i.matches(e):i instanceof e)return i;if(!i.node.parentNode||"#document"==i.node.parentNode.nodeName)return null;i=a.adopt(i.node.parentNode)}},doc:function(){return this instanceof a.Doc?this:this.parent(a.Doc)},parents:function(t){var e=[],i=this;do{if(!(i=i.parent(t))||!i.node)break;e.push(i)}while(i.parent);return e},matches:function(t){return function(t,e){return(t.matches||t.matchesSelector||t.msMatchesSelector||t.mozMatchesSelector||t.webkitMatchesSelector||t.oMatchesSelector).call(t,e)}(this.node,t)},native:function(){return this.node},svg:function(t){var i=e.createElement("svg");if(!(t&&this instanceof a.Parent))return i.appendChild(t=e.createElement("svg")),this.writeDataToDom(),t.appendChild(this.node.cloneNode(!0)),i.innerHTML.replace(/^<svg>/,"").replace(/<\/svg>$/,"");i.innerHTML="<svg>"+t.replace(/\n/,"").replace(/<([\w:-]+)([^<]+?)\/>/g,"<$1$2></$1>")+"</svg>";for(var s=0,r=i.firstChild.childNodes.length;s<r;s++)this.node.appendChild(i.firstChild.firstChild);return this},writeDataToDom:function(){return(this.each||this.lines)&&(this.each?this:this.lines()).each((function(){this.writeDataToDom()})),this.node.removeAttribute("svgjs:data"),Object.keys(this.dom).length&&this.node.setAttribute("svgjs:data",JSON.stringify(this.dom)),this},setData:function(t){return this.dom=t,this},is:function(t){return function(t,e){return t instanceof e}(this,t)}}}),a.easing={"-":function(t){return t},"<>":function(t){return-Math.cos(t*Math.PI)/2+.5},">":function(t){return Math.sin(t*Math.PI/2)},"<":function(t){return 1-Math.cos(t*Math.PI/2)}},a.morph=function(t){return function(e,i){return new a.MorphObj(e,i).at(t)}},a.Situation=a.invent({create:function(t){this.init=!1,this.reversed=!1,this.reversing=!1,this.duration=new a.Number(t.duration).valueOf(),this.delay=new a.Number(t.delay).valueOf(),this.start=+new Date+this.delay,this.finish=this.start+this.duration,this.ease=t.ease,this.loop=0,this.loops=!1,this.animations={},this.attrs={},this.styles={},this.transforms=[],this.once={}}}),a.FX=a.invent({create:function(t){this._target=t,this.situations=[],this.active=!1,this.situation=null,this.paused=!1,this.lastPos=0,this.pos=0,this.absPos=0,this._speed=1},extend:{animate:function(t,e,s){"object"===i(t)&&(e=t.ease,s=t.delay,t=t.duration);var r=new a.Situation({duration:t||1e3,delay:s||0,ease:a.easing[e||"-"]||e});return this.queue(r),this},target:function(t){return t&&t instanceof a.Element?(this._target=t,this):this._target},timeToAbsPos:function(t){return(t-this.situation.start)/(this.situation.duration/this._speed)},absPosToTime:function(t){return this.situation.duration/this._speed*t+this.situation.start}
61903,startAnimFrame:function(){this.stopAnimFrame(),this.animationFrame=t.requestAnimationFrame(function(){this.step()}.bind(this))},stopAnimFrame:function(){t.cancelAnimationFrame(this.animationFrame)},start:function(){return!this.active&&this.situation&&(this.active=!0,this.startCurrent()),this},startCurrent:function(){return this.situation.start=+new Date+this.situation.delay/this._speed,this.situation.finish=this.situation.start+this.situation.duration/this._speed,this.initAnimations().step()},queue:function(t){return("function"==typeof t||t instanceof a.Situation)&&this.situations.push(t),this.situation||(this.situation=this.situations.shift()),this},dequeue:function(){return this.stop(),this.situation=this.situations.shift(),this.situation&&(this.situation instanceof a.Situation?this.start():this.situation.call(this)),this},initAnimations:function(){var t,e=this.situation;if(e.init)return this;for(var i in e.animations){t=this.target()[i](),Array.isArray(t)||(t=[t]),Array.isArray(e.animations[i])||(e.animations[i]=[e.animations[i]]);for(var s=t.length;s--;)e.animations[i][s]instanceof a.Number&&(t[s]=new a.Number(t[s])),e.animations[i][s]=t[s].morph(e.animations[i][s])}for(var i in e.attrs)e.attrs[i]=new a.MorphObj(this.target().attr(i),e.attrs[i]);for(var i in e.styles)e.styles[i]=new a.MorphObj(this.target().style(i),e.styles[i]);return e.initialTransformation=this.target().matrixify(),e.init=!0,this},clearQueue:function(){return this.situations=[],this},clearCurrent:function(){return this.situation=null,this},stop:function(t,e){var i=this.active;return this.active=!1,e&&this.clearQueue(),t&&this.situation&&(!i&&this.startCurrent(),this.atEnd()),this.stopAnimFrame(),this.clearCurrent()},after:function(t){var e=this.last();return this.target().on("finished.fx",(function i(a){a.detail.situation==e&&(t.call(this,e),this.off("finished.fx",i))})),this._callStart()},during:function(t){var e=this.last(),i=function(i){i.detail.situation==e&&t.call(this,i.detail.pos,a.morph(i.detail.pos),i.detail.eased,e)};return this.target().off("during.fx",i).on("during.fx",i),this.after((function(){this.off("during.fx",i)})),this._callStart()},afterAll:function(t){var e=function e(i){t.call(this),this.off("allfinished.fx",e)};return this.target().off("allfinished.fx",e).on("allfinished.fx",e),this._callStart()},last:function(){return this.situations.length?this.situations[this.situations.length-1]:this.situation},add:function(t,e,i){return this.last()[i||"animations"][t]=e,this._callStart()},step:function(t){var e,i,a;t||(this.absPos=this.timeToAbsPos(+new Date)),!1!==this.situation.loops?(e=Math.max(this.absPos,0),i=Math.floor(e),!0===this.situation.loops||i<this.situation.loops?(this.pos=e-i,a=this.situation.loop,this.situation.loop=i):(this.absPos=this.situation.loops,this.pos=1,a=this.situation.loop-1,this.situation.loop=this.situation.loops),this.situation.reversing&&(this.situation.reversed=this.situation.reversed!=Boolean((this.situation.loop-a)%2))):(this.absPos=Math.min(this.absPos,1),this.pos=this.absPos),this.pos<0&&(this.pos=0),this.situation.reversed&&(this.pos=1-this.pos);var s=this.situation.ease(this.pos);for(var r in this.situation.once)r>this.lastPos&&r<=s&&(this.situation.once[r].call(this.target(),this.pos,s),delete this.situation.once[r]);return this.active&&this.target().fire("during",{pos:this.pos,eased:s,fx:this,situation:this.situation}),this.situation?(this.eachAt(),1==this.pos&&!this.situation.reversed||this.situation.reversed&&0==this.pos?(this.stopAnimFrame(),this.target().fire("finished",{fx:this,situation:this.situation}),this.situations.length||(this.target().fire("allfinished"),this.situations.length||(this.target().off(".fx"),this.active=!1)),this.active?this.dequeue():this.clearCurrent()):!this.paused&&this.active&&this.startAnimFrame(),this.lastPos=s,this):this},eachAt:function(){var t,e=this,i=this.target(),s=this.situation;for(var r in s.animations)t=[].concat(s.animations[r]).map((function(t){return"string"!=typeof t&&t.at?t.at(s.ease(e.pos),e.pos):t})),i[r].apply(i,t);for(var r in s.attrs)t=[r].concat(s.attrs[r]).map((function(t){return"string"!=typeof t&&t.at?t.at(s.ease(e.pos),e.pos):t})),i.attr.apply(i,t);for(var r in s.styles)t=[r].concat(s.styles[r]).map((function(t){return"string"!=typeof t&&t.at?t.at(s.ease(e.pos),e.pos):t})),i.style.apply(i,t);if(s.transforms.length){t=s.initialTransformation,r=0;for(var o=s.transforms.length;r<o;r++){var n=s.transforms[r];n instanceof a.Matrix?t=n.relative?t.multiply((new a.Matrix).morph(n).at(s.ease(this.pos))):t.morph(n).at(s.ease(this.pos)):(n.relative||n.und
61903o(t.extract()),t=t.multiply(n.at(s.ease(this.pos))))}i.matrix(t)}return this},once:function(t,e,i){var a=this.last();return i||(t=a.ease(t)),a.once[t]=e,this},_callStart:function(){return setTimeout(function(){this.start()}.bind(this),0),this}},parent:a.Element,construct:{animate:function(t,e,i){return(this.fx||(this.fx=new a.FX(this))).animate(t,e,i)},delay:function(t){return(this.fx||(this.fx=new a.FX(this))).delay(t)},stop:function(t,e){return this.fx&&this.fx.stop(t,e),this},finish:function(){return this.fx&&this.fx.finish(),this}}}),a.MorphObj=a.invent({create:function(t,e){return a.Color.isColor(e)?new a.Color(t).morph(e):a.regex.delimiter.test(t)?a.regex.pathLetters.test(t)?new a.PathArray(t).morph(e):new a.Array(t).morph(e):a.regex.numberAndUnit.test(e)?new a.Number(t).morph(e):(this.value=t,void(this.destination=e))},extend:{at:function(t,e){return e<1?this.value:this.destination},valueOf:function(){return this.value}}}),a.extend(a.FX,{attr:function(t,e,a){if("object"===i(t))for(var s in t)this.attr(s,t[s]);else this.add(t,e,"attrs");return this},plot:function(t,e,i,a){return 4==arguments.length?this.plot([t,e,i,a]):this.add("plot",new(this.target().morphArray)(t))}}),a.Box=a.invent({create:function(t,e,s,r){if(!("object"!==i(t)||t instanceof a.Element))return a.Box.call(this,null!=t.left?t.left:t.x,null!=t.top?t.top:t.y,t.width,t.height);4==arguments.length&&(this.x=t,this.y=e,this.width=s,this.height=r),b(this)}}),a.BBox=a.invent({create:function(t){if(a.Box.apply(this,[].slice.call(arguments)),t instanceof a.Element){var i;try{if(!e.documentElement.contains){for(var s=t.node;s.parentNode;)s=s.parentNode;if(s!=e)throw new Error("Element not in the dom")}i=t.node.getBBox()}catch(e){if(t instanceof a.Shape){a.parser.draw||a.prepare();var r=t.clone(a.parser.draw.instance).show();r&&r.node&&"function"==typeof r.node.getBBox&&(i=r.node.getBBox()),r&&"function"==typeof r.remove&&r.remove()}else i={x:t.node.clientLeft,y:t.node.clientTop,width:t.node.clientWidth,height:t.node.clientHeight}}a.Box.call(this,i)}},inherit:a.Box,parent:a.Element,construct:{bbox:function(){return new a.BBox(this)}}}),a.BBox.prototype.constructor=a.BBox,a.Matrix=a.invent({create:function(t){var e=f([1,0,0,1,0,0]);t=null===t?e:t instanceof a.Element?t.matrixify():"string"==typeof t?f(t.split(a.regex.delimiter).map(parseFloat)):6==arguments.length?f([].slice.call(arguments)):Array.isArray(t)?f(t):t&&"object"===i(t)?t:e;for(var s=m.length-1;s>=0;--s)this[m[s]]=null!=t[m[s]]?t[m[s]]:e[m[s]]},extend:{extract:function(){var t=p(this,0,1);p(this,1,0);var e=180/Math.PI*Math.atan2(t.y,t.x)-90;return{x:this.e,y:this.f,transformedX:(this.e*Math.cos(e*Math.PI/180)+this.f*Math.sin(e*Math.PI/180))/Math.sqrt(this.a*this.a+this.b*this.b),transformedY:(this.f*Math.cos(e*Math.PI/180)+this.e*Math.sin(-e*Math.PI/180))/Math.sqrt(this.c*this.c+this.d*this.d),rotation:e,a:this.a,b:this.b,c:this.c,d:this.d,e:this.e,f:this.f,matrix:new a.Matrix(this)}},clone:function(){return new a.Matrix(this)},morph:function(t){return this.destination=new a.Matrix(t),this},multiply:function(t){return new a.Matrix(this.native().multiply(function(t){return t instanceof a.Matrix||(t=new a.Matrix(t)),t}(t).native()))},inverse:function(){return new a.Matrix(this.native().inverse())},translate:function(t,e){return new a.Matrix(this.native().translate(t||0,e||0))},native:function(){for(var t=a.parser.native.createSVGMatrix(),e=m.length-1;e>=0;e--)t[m[e]]=this[m[e]];return t},toString:function(){return"matrix("+v(this.a)+","+v(this.b)+","+v(this.c)+","+v(this.d)+","+v(this.e)+","+v(this.f)+")"}},parent:a.Element,construct:{ctm:function(){return new a.Matrix(this.node.getCTM())},screenCTM:function(){if(this instanceof a.Nested){var t=this.rect(1,1),e=t.node.getScreenCTM();return t.remove(),new a.Matrix(e)}return new a.Matrix(this.node.getScreenCTM())}}}),a.Point=a.invent({create:function(t,e){var a;a=Array.isArray(t)?{x:t[0],y:t[1]}:"object"===i(t)?{x:t.x,y:t.y}:null!=t?{x:t,y:null!=e?e:t}:{x:0,y:0},this.x=a.x,this.y=a.y},extend:{clone:function(){return new a.Point(this)},morph:function(t,e){return this.destination=new a.Point(t,e),this}}}),a.extend(a.Element,{point:function(t,e){return new a.Point(t,e).transform(this.screenCTM().inverse())}}),a.extend(a.Element,{attr:function(t,e,s){if(null==t){for(t={},s=(e=this.node.attributes).length-1;s>=0;s--)t[e[s].nodeName]=a.regex.isNumber.test(e[s].nodeValue)?parseFloat(e[s].nodeValue):e[s].nodeValue;return t}if("object"===i(t))for(var r in t)this.attr(r,t[r]);else if(null===e)this.node.removeAttribute(t);else{if(null==e)return null==(e=this.node.getAttribute(t))?a.defaults.attrs[t]:a.regex.isNumber.test(e)?parseFloat(e):e;"stroke-width"==t?this.attr("stroke",parseFloat(e)>0?this._stroke:null):"stroke"==t&&(this._stroke=e),"fill"!=t&&"stroke"!=t||(a.regex.isImage.test(e)&&(e=this.doc().defs().image(e,0,0)),e instanceof a.Image&&(e=this.doc().defs().pattern(0,0,(function(){this.add(e)})))),"number"==typeof e?e=new a.Number(e):a.Color.isColor(e)?e=new a.Color(e):Array.isArray(e)&&(e=new a.Array(e)),"leading"==t?this.leading&&this.leading(e):"str
61903ing"==typeof s?this.node.setAttributeNS(s,t,e.toString()):this.node.setAttribute(t,e.toString()),!this.rebuild||"font-size"!=t&&"x"!=t||this.rebuild(t,e)}return this}}),a.extend(a.Element,{transform:function(t,e){var s;return"object"!==i(t)?(s=new a.Matrix(this).extract(),"string"==typeof t?s[t]:s):(s=new a.Matrix(this),e=!!e||!!t.relative,null!=t.a&&(s=e?s.multiply(new a.Matrix(t)):new a.Matrix(t)),this.attr("transform",s))}}),a.extend(a.Element,{untransform:function(){return this.attr("transform",null)},matrixify:function(){return(this.attr("transform")||"").split(a.regex.transforms).slice(0,-1).map((function(t){var e=t.trim().split("(");return[e[0],e[1].split(a.regex.delimiter).map((function(t){return parseFloat(t)}))]})).reduce((function(t,e){return"matrix"==e[0]?t.multiply(f(e[1])):t[e[0]].apply(t,e[1])}),new a.Matrix)},toParent:function(t){if(this==t)return this;var e=this.screenCTM(),i=t.screenCTM().inverse();return this.addTo(t).untransform().transform(i.multiply(e)),this},toDoc:function(){return this.toParent(this.doc())}}),a.Transformation=a.invent({create:function(t,e){if(arguments.length>1&&"boolean"!=typeof e)return this.constructor.call(this,[].slice.call(arguments));if(Array.isArray(t))for(var a=0,s=this.arguments.length;a<s;++a)this[this.arguments[a]]=t[a];else if(t&&"object"===i(t))for(a=0,s=this.arguments.length;a<s;++a)this[this.arguments[a]]=t[this.arguments[a]];this.inversed=!1,!0===e&&(this.inversed=!0)}}),a.Translate=a.invent({parent:a.Matrix,inherit:a.Transformation,create:function(t,e){this.constructor.apply(this,[].slice.call(arguments))},extend:{arguments:["transformedX","transformedY"],method:"translate"}}),a.extend(a.Element,{style:function(t,e){if(0==arguments.length)return this.node.style.cssText||"";if(arguments.length<2)if("object"===i(t))for(var s in t)this.style(s,t[s]);else{if(!a.regex.isCss.test(t))return this.node.style[c(t)];for(t=t.split(/\s*;\s*/).filter((function(t){return!!t})).map((function(t){return t.split(/\s*:\s*/)}));e=t.pop();)this.style(e[0],e[1])}else this.node.style[c(t)]=null===e||a.regex.isBlank.test(e)?"":e;return this}}),a.Parent=a.invent({create:function(t){this.constructor.call(this,t)},inherit:a.Element,extend:{children:function(){return a.utils.map(a.utils.filterSVGElements(this.node.childNodes),(function(t){return a.adopt(t)}))},add:function(t,e){return null==e?this.node.appendChild(t.node):t.node!=this.node.childNodes[e]&&this.node.insertBefore(t.node,this.node.childNodes[e]),this},put:function(t,e){return this.add(t,e),t},has:function(t){return this.index(t)>=0},index:function(t){return[].slice.call(this.node.childNodes).indexOf(t.node)},get:function(t){return a.adopt(this.node.childNodes[t])},first:function(){return this.get(0)},last:function(){return this.get(this.node.childNodes.length-1)},each:function(t,e){for(var i=this.children(),s=0,r=i.length;s<r;s++)i[s]instanceof a.Element&&t.apply(i[s],[s,i]),e&&i[s]instanceof a.Container&&i[s].each(t,e);return this},removeElement:function(t){return this.node.removeChild(t.node),this},clear:function(){for(;this.node.hasChildNodes();)this.node.removeChild(this.node.lastChild);return delete this._defs,this},defs:function(){return this.doc().defs()}}}),a.extend(a.Parent,{ungroup:function(t,e){return 0===e||this instanceof a.Defs||this.node==a.parser.draw||(t=t||(this instanceof a.Doc?this:this.parent(a.Parent)),e=e||1/0,this.each((function(){return this instanceof a.Defs?this:this instanceof a.Parent?this.ungroup(t,e-1):this.toParent(t)})),this.node.firstChild||this.remove()),this},flatten:function(t,e){return this.ungroup(t,e)}}),a.Container=a.invent({create:function(t){this.constructor.call(this,t)},inherit:a.Parent}),a.ViewBox=a.invent({parent:a.Container,construct:{}}),["click","dblclick","mousedown","mouseup","mouseover","mouseout","mousemove","touchstart","touchmove","touchleave","touchend","touchcancel"].forEach((function(t){a.Element.prototype[t]=function(e){return a.on(this.node,t,e),this}})),a.listeners=[],a.handlerMap=[],a.listenerId=0,a.on=function(t,e,i,s,r){var o=i.bind(s||t.instance||t),n=(a.handlerMap.indexOf(t)+1||a.handlerMap.push(t))-1,l=e.split(".")[0],h=e.split(".")[1]||"*";a.listeners[n]=a.listeners[n]||{},a.listeners[n][l]=a.listeners[n][l]||{},a.listeners[n][l][h]=a.listeners[n][l][h]||{},i._svgjsListenerId||(i._svgjsListenerId=++a.listenerId),a.listeners[n][l][h][i._svgjsListenerId]=o,t.addEventListener(l,o,r||{passive:!0})}
61903,a.off=function(t,e,i){var s=a.handlerMap.indexOf(t),r=e&&e.split(".")[0],o=e&&e.split(".")[1],n="";if(-1!=s)if(i){if("function"==typeof i&&(i=i._svgjsListenerId),!i)return;a.listeners[s][r]&&a.listeners[s][r][o||"*"]&&(t.removeEventListener(r,a.listeners[s][r][o||"*"][i],!1),delete a.listeners[s][r][o||"*"][i])}else if(o&&r){if(a.listeners[s][r]&&a.listeners[s][r][o]){for(var l in a.listeners[s][r][o])a.off(t,[r,o].join("."),l);delete a.listeners[s][r][o]}}else if(o)for(var h in a.listeners[s])for(var n in a.listeners[s][h])o===n&&a.off(t,[h,o].join("."));else if(r){if(a.listeners[s][r]){for(var n in a.listeners[s][r])a.off(t,[r,n].join("."));delete a.listeners[s][r]}}else{for(var h in a.listeners[s])a.off(t,h);delete a.listeners[s],delete a.handlerMap[s]}},a.extend(a.Element,{on:function(t,e,i,s){return a.on(this.node,t,e,i,s),this},off:function(t,e){return a.off(this.node,t,e),this},fire:function(e,i){return e instanceof t.Event?this.node.dispatchEvent(e):this.node.dispatchEvent(e=new a.CustomEvent(e,{detail:i,cancelable:!0})),this._event=e,this},event:function(){return this._event}}),a.Defs=a.invent({create:"defs",inherit:a.Container}),a.G=a.invent({create:"g",inherit:a.Container,extend:{x:function(t){return null==t?this.transform("x"):this.transform({x:t-this.x()},!0)}},construct:{group:function(){return this.put(new a.G)}}}),a.Doc=a.invent({create:function(t){t&&("svg"==(t="string"==typeof t?e.getElementById(t):t).nodeName?this.constructor.call(this,t):(this.constructor.call(this,a.create("svg")),t.appendChild(this.node),this.size("100%","100%")),this.namespace().defs())},inherit:a.Container,extend:{namespace:function(){return this.attr({xmlns:a.ns,version:"1.1"}).attr("xmlns:xlink",a.xlink,a.xmlns).attr("xmlns:svgjs",a.svgjs,a.xmlns)},defs:function(){var t;return this._defs||((t=this.node.getElementsByTagName("defs")[0])?this._defs=a.adopt(t):this._defs=new a.Defs,this.node.appendChild(this._defs.node)),this._defs},parent:function(){return this.node.parentNode&&"#document"!=this.node.parentNode.nodeName?this.node.parentNode:null},remove:function(){return this.parent()&&this.parent().removeChild(this.node),this},clear:function(){for(;this.node.hasChildNodes();)this.node.removeChild(this.node.lastChild);return delete this._defs,a.parser.draw&&!a.parser.draw.parentNode&&this.node.appendChild(a.parser.draw),this},clone:function(t){this.writeDataToDom();var e=this.node,i=x(e.cloneNode(!0));return t?(t.node||t).appendChild(i.node):e.parentNode.insertBefore(i.node,e.nextSibling),i}}}),a.extend(a.Element,{}),a.Gradient=a.invent({create:function(t){this.constructor.call(this,a.create(t+"Gradient")),this.type=t},inherit:a.Container,extend:{at:function(t,e,i){return this.put(new a.Stop).update(t,e,i)},update:function(t){return this.clear(),"function"==typeof t&&t.call(this,this),this},fill:function(){return"url(#"+this.id()+")"},toString:function(){return this.fill()},attr:function(t,e,i){return"transform"==t&&(t="gradientTransform"),a.Container.prototype.attr.call(this,t,e,i)}},construct:{gradient:function(t,e){return this.defs().gradient(t,e)}}}),a.extend(a.Gradient,a.FX,{from:function(t,e){return"radial"==(this._target||this).type?this.attr({fx:new a.Number(t),fy:new a.Number(e)}):this.attr({x1:new a.Number(t),y1:new a.Number(e)})},to:function(t,e){return"radial"==(this._target||this).type?this.attr({cx:new a.Number(t),cy:new a.Number(e)}):this.attr({x2:new a.Number(t),y2:new a.Number(e)})}}),a.extend(a.Defs,{gradient:function(t,e){return this.put(new a.Gradient(t)).update(e)}}),a.Stop=a.invent({create:"stop",inherit:a.Element,extend:{update:function(t){return("number"==typeof t||t instanceof a.Number)&&(t={offset:arguments[0],color:arguments[1],opacity:arguments[2]}),null!=t.opacity&&this.attr("stop-opacity",t.opacity),null!=t.color&&this.attr("stop-color",t.color),null!=t.offset&&this.attr("offset",new a.Number(t.offset)),this}}}),a.Pattern=a.invent({create:"pattern",inherit:a.Container,extend:{fill:function(){return"url(#"+this.id()+")"},update:function(t){return this.clear(),"function"==typeof t&&t.call(this,this),this},toString:function(){return this.fill()}
61903,attr:function(t,e,i){return"transform"==t&&(t="patternTransform"),a.Container.prototype.attr.call(this,t,e,i)}},construct:{pattern:function(t,e,i){return this.defs().pattern(t,e,i)}}}),a.extend(a.Defs,{pattern:function(t,e,i){return this.put(new a.Pattern).update(i).attr({x:0,y:0,width:t,height:e,patternUnits:"userSpaceOnUse"})}}),a.Shape=a.invent({create:function(t){this.constructor.call(this,t)},inherit:a.Element}),a.Symbol=a.invent({create:"symbol",inherit:a.Container,construct:{symbol:function(){return this.put(new a.Symbol)}}}),a.Use=a.invent({create:"use",inherit:a.Shape,extend:{element:function(t,e){return this.attr("href",(e||"")+"#"+t,a.xlink)}},construct:{use:function(t,e){return this.put(new a.Use).element(t,e)}}}),a.Rect=a.invent({create:"rect",inherit:a.Shape,construct:{rect:function(t,e){return this.put(new a.Rect).size(t,e)}}}),a.Circle=a.invent({create:"circle",inherit:a.Shape,construct:{circle:function(t){return this.put(new a.Circle).rx(new a.Number(t).divide(2)).move(0,0)}}}),a.extend(a.Circle,a.FX,{rx:function(t){return this.attr("r",t)},ry:function(t){return this.rx(t)}}),a.Ellipse=a.invent({create:"ellipse",inherit:a.Shape,construct:{ellipse:function(t,e){return this.put(new a.Ellipse).size(t,e).move(0,0)}}}),a.extend(a.Ellipse,a.Rect,a.FX,{rx:function(t){return this.attr("rx",t)},ry:function(t){return this.attr("ry",t)}}),a.extend(a.Circle,a.Ellipse,{x:function(t){return null==t?this.cx()-this.rx():this.cx(t+this.rx())},y:function(t){return null==t?this.cy()-this.ry():this.cy(t+this.ry())},cx:function(t){return null==t?this.attr("cx"):this.attr("cx",t)},cy:function(t){return null==t?this.attr("cy"):this.attr("cy",t)},width:function(t){return null==t?2*this.rx():this.rx(new a.Number(t).divide(2))},height:function(t){return null==t?2*this.ry():this.ry(new a.Number(t).divide(2))},size:function(t,e){var i=u(this,t,e);return this.rx(new a.Number(i.width).divide(2)).ry(new a.Number(i.height).divide(2))}}),a.Line=a.invent({create:"line",inherit:a.Shape,extend:{array:function(){return new a.PointArray([[this.attr("x1"),this.attr("y1")],[this.attr("x2"),this.attr("y2")]])},plot:function(t,e,i,s){return null==t?this.array():(t=void 0!==e?{x1:t,y1:e,x2:i,y2:s}:new a.PointArray(t).toLine(),this.attr(t))},move:function(t,e){return this.attr(this.array().move(t,e).toLine())},size:function(t,e){var i=u(this,t,e);return this.attr(this.array().size(i.width,i.height).toLine())}},construct:{line:function(t,e,i,s){return a.Line.prototype.plot.apply(this.put(new a.Line),null!=t?[t,e,i,s]:[0,0,0,0])}}}),a.Polyline=a.invent({create:"polyline",inherit:a.Shape,construct:{polyline:function(t){return this.put(new a.Polyline).plot(t||new a.PointArray)}}}),a.Polygon=a.invent({create:"polygon",inherit:a.Shape,construct:{polygon:function(t){return this.put(new a.Polygon).plot(t||new a.PointArray)}}}),a.extend(a.Polyline,a.Polygon,{array:function(){return this._array||(this._array=new a.PointArray(this.attr("points")))},plot:function(t){return null==t?this.array():this.clear().attr("points","string"==typeof t?t:this._array=new a.PointArray(t))},clear:function(){return delete this._array,this},move:function(t,e){return this.attr("points",this.array().move(t,e))},size:function(t,e){var i=u(this,t,e);return this.attr("points",this.array().size(i.width,i.height))}}),a.extend(a.Line,a.Polyline,a.Polygon,{morphArray:a.PointArray,x:function(t){return null==t?this.bbox().x:this.move(t,this.bbox().y)},y:function(t){return null==t?this.bbox().y:this.move(this.bbox().x,t)},width:function(t){var e=this.bbox();return null==t?e.width:this.size(t,e.height)},height:function(t){var e=this.bbox();return null==t?e.height:this.size(e.width,t)}}),a.Path=a.invent({create:"path",inherit:a.Shape,extend:{morphArray:a.PathArray,array:function(){return this._array||(this._array=new a.PathArray(this.attr("d")))},plot:function(t){return null==t?this.array():this.clear().attr("d","string"==typeof t?t:this._array=new a.PathArray(t))},clear:function(){return delete this._array,this}},construct:{path:function(t){return this.put(new a.Path).plot(t||new a.PathArray)}}}),a.Image=a.invent({create:"image",inherit:a.Shape,extend:{load:function(e){if(!e)return this;var i=this,s=new t.Image;return a.on(s,"load",(function(){a.off(s);var t=i.parent(a.Pattern);null!==t&&(0==i.width()&&0==i.height()&&i.size(s.width,s.height),t&&0==t.width()&&0==t.height()&&t.size(i.width(),i.height()),"function"==typeof i._loaded&&i._loaded.
61903call(i,{width:s.width,height:s.height,ratio:s.width/s.height,url:e}))})),a.on(s,"error",(function(t){a.off(s),"function"==typeof i._error&&i._error.call(i,t)})),this.attr("href",s.src=this.src=e,a.xlink)},loaded:function(t){return this._loaded=t,this},error:function(t){return this._error=t,this}},construct:{image:function(t,e,i){return this.put(new a.Image).load(t).size(e||0,i||e||0)}}}),a.Text=a.invent({create:function(){this.constructor.call(this,a.create("text")),this.dom.leading=new a.Number(1.3),this._rebuild=!0,this._build=!1,this.attr("font-family",a.defaults.attrs["font-family"])},inherit:a.Shape,extend:{x:function(t){return null==t?this.attr("x"):this.attr("x",t)},text:function(t){if(void 0===t){t="";for(var e=this.node.childNodes,i=0,s=e.length;i<s;++i)0!=i&&3!=e[i].nodeType&&1==a.adopt(e[i]).dom.newLined&&(t+="\n"),t+=e[i].textContent;return t}if(this.clear().build(!0),"function"==typeof t)t.call(this,this);else{i=0;for(var r=(t=t.split("\n")).length;i<r;i++)this.tspan(t[i]).newLine()}return this.build(!1).rebuild()},size:function(t){return this.attr("font-size",t).rebuild()},leading:function(t){return null==t?this.dom.leading:(this.dom.leading=new a.Number(t),this.rebuild())},lines:function(){var t=(this.textPath&&this.textPath()||this).node,e=a.utils.map(a.utils.filterSVGElements(t.childNodes),(function(t){return a.adopt(t)}));return new a.Set(e)},rebuild:function(t){if("boolean"==typeof t&&(this._rebuild=t),this._rebuild){var e=this,i=0,s=this.dom.leading*new a.Number(this.attr("font-size"));this.lines().each((function(){this.dom.newLined&&(e.textPath()||this.attr("x",e.attr("x")),"\n"==this.text()?i+=s:(this.attr("dy",s+i),i=0))})),this.fire("rebuild")}return this},build:function(t){return this._build=!!t,this},setData:function(t){return this.dom=t,this.dom.leading=new a.Number(t.leading||1.3),this}},construct:{text:function(t){return this.put(new a.Text).text(t)},plain:function(t){return this.put(new a.Text).plain(t)}}}),a.Tspan=a.invent({create:"tspan",inherit:a.Shape,extend:{text:function(t){return null==t?this.node.textContent+(this.dom.newLined?"\n":""):("function"==typeof t?t.call(this,this):this.plain(t),this)},dx:function(t){return this.attr("dx",t)},dy:function(t){return this.attr("dy",t)},newLine:function(){var t=this.parent(a.Text);return this.dom.newLined=!0,this.dy(t.dom.leading*t.attr("font-size")).attr("x",t.x())}}}),a.extend(a.Text,a.Tspan,{plain:function(t){return!1===this._build&&this.clear(),this.node.appendChild(e.createTextNode(t)),this},tspan:function(t){var e=(this.textPath&&this.textPath()||this).node,i=new a.Tspan;return!1===this._build&&this.clear(),e.appendChild(i.node),i.text(t)},clear:function(){for(var t=(this.textPath&&this.textPath()||this).node;t.hasChildNodes();)t.removeChild(t.lastChild);return this},length:function(){return this.node.getComputedTextLength()}}),a.TextPath=a.invent({create:"textPath",inherit:a.Parent,parent:a.Text,construct:{morphArray:a.PathArray,array:function(){var t=this.track();return t?t.array():null},plot:function(t){var e=this.track(),i=null;return e&&(i=e.plot(t)),null==t?i:this},track:function(){var t=this.textPath();if(t)return t.reference("href")},textPath:function(){if(this.node.firstChild&&"textPath"==this.node.firstChild.nodeName)return a.adopt(this.node.firstChild)}}}),a.Nested=a.invent({create:function(){this.constructor.call(this,a.create("svg")),this.style("overflow","visible")},inherit:a.Container,construct:{nested:function(){return this.put(new a.Nested)}}});var l={stroke:["color","width","opacity","linecap","linejoin","miterlimit","dasharray","dashoffset"],fill:["color","opacity","rule"],prefix:function(t,e){return"color"==e?t:t+"-"+e}};function h(t,e,i,s){return i+s.replace(a.regex.dots," .")}function c(t){return t.toLowerCase().replace(/-(.)/g,(function(t,e){return e.toUpperCase()}))}function d(t){return t.charAt(0).toUpperCase()+t.slice(1)}function g(t){var e=t.toString(16);return 1==e.length?"0"+e:e}function u(t,e,i){if(null==e||null==i){var a=t.bbox();null==e?e=a.width/a.height*i:null==i&&(i=a.height/a.width*e)}return{width:e,height:i}}
61903function p(t,e,i){return{x:e*t.a+i*t.c+0,y:e*t.b+i*t.d+0}}function f(t){return{a:t[0],b:t[1],c:t[2],d:t[3],e:t[4],f:t[5]}}function x(e){for(var i=e.childNodes.length-1;i>=0;i--)e.childNodes[i]instanceof t.SVGElement&&x(e.childNodes[i]);return a.adopt(e).id(a.eid(e.nodeName))}function b(t){return null==t.x&&(t.x=0,t.y=0,t.width=0,t.height=0),t.w=t.width,t.h=t.height,t.x2=t.x+t.width,t.y2=t.y+t.height,t.cx=t.x+t.width/2,t.cy=t.y+t.height/2,t}function v(t){return Math.abs(t)>1e-37?t:0}["fill","stroke"].forEach((function(t){var e={};e[t]=function(e){if(void 0===e)return this;if("string"==typeof e||a.Color.isRgb(e)||e&&"function"==typeof e.fill)this.attr(t,e);else for(var i=l[t].length-1;i>=0;i--)null!=e[l[t][i]]&&this.attr(l.prefix(t,l[t][i]),e[l[t][i]]);return this},a.extend(a.Element,a.FX,e)})),a.extend(a.Element,a.FX,{translate:function(t,e){return this.transform({x:t,y:e})},matrix:function(t){return this.attr("transform",new a.Matrix(6==arguments.length?[].slice.call(arguments):t))},opacity:function(t){return this.attr("opacity",t)},dx:function(t){return this.x(new a.Number(t).plus(this instanceof a.FX?0:this.x()),!0)},dy:function(t){return this.y(new a.Number(t).plus(this instanceof a.FX?0:this.y()),!0)}}),a.extend(a.Path,{length:function(){return this.node.getTotalLength()},pointAt:function(t){return this.node.getPointAtLength(t)}}),a.Set=a.invent({create:function(t){Array.isArray(t)?this.members=t:this.clear()},extend:{add:function(){for(var t=[].slice.call(arguments),e=0,i=t.length;e<i;e++)this.members.push(t[e]);return this},remove:function(t){var e=this.index(t);return e>-1&&this.members.splice(e,1),this},each:function(t){for(var e=0,i=this.members.length;e<i;e++)t.apply(this.members[e],[e,this.members]);return this},clear:function(){return this.members=[],this},length:function(){return this.members.length},has:function(t){return this.index(t)>=0},index:function(t){return this.members.indexOf(t)},get:function(t){return this.members[t]},first:function(){return this.get(0)},last:function(){return this.get(this.members.length-1)},valueOf:function(){return this.members}},construct:{set:function(t){return new a.Set(t)}}}),a.FX.Set=a.invent({create:function(t){this.set=t}}),a.Set.inherit=function(){var t=[];for(var e in a.Shape.prototype)"function"==typeof a.Shape.prototype[e]&&"function"!=typeof a.Set.prototype[e]&&t.push(e);for(var e in t.forEach((function(t){a.Set.prototype[t]=function(){for(var e=0,i=this.members.length;e<i;e++)this.members[e]&&"function"==typeof this.members[e][t]&&this.members[e][t].apply(this.members[e],arguments);return"animate"==t?this.fx||(this.fx=new a.FX.Set(this)):this}})),t=[],a.FX.prototype)"function"==typeof a.FX.prototype[e]&&"function"!=typeof a.FX.Set.prototype[e]&&t.push(e);t.forEach((function(t){a.FX.Set.prototype[t]=function(){for(var e=0,i=this.set.members.length;e<i;e++)this.set.members[e].fx[t].apply(this.set.members[e].fx,arguments);return this}}))},a.extend(a.Element,{}),a.extend(a.Element,{remember:function(t,e){if("object"===i(arguments[0]))for(var a in t)this.remember(a,t[a]);else{if(1==arguments.length)return this.memory()[t];this.memory()[t]=e}return this},forget:function(){if(0==arguments.length)this._memory={};else for(var t=arguments.length-1;t>=0;t--)delete this.memory()[arguments[t]];return this},memory:function(){return this._memory||(this._memory={})}}),a.get=function(t){var i=e.getElementById(function(t){var e=(t||"").toString().match(a.regex.reference);if(e)return e[1]}(t)||t);return a.adopt(i)},a.select=function(t,i){return new a.Set(a.utils.map((i||e).querySelectorAll(t),(function(t){return a.adopt(t)})))},a.extend(a.Parent,{select:function(t){return a.select(t,this.node)}});var m="abcdef".split("");if("function"!=typeof t.CustomEvent){var y=function(t,i){i=i||{bubbles:!1,cancelable:!1,detail:void 0};var a=e.createEvent("CustomEvent");return a.initCustomEvent(t,i.bubbles,i.cancelable,i.detail),a};y.prototype=t.Event.prototype,a.CustomEvent=y}else a.CustomEvent=t.CustomEvent;return a},"function"==typeof define&&define.amd?define((function(){return Mt(Tt,Tt.document)})):"object"===("undefined"==typeof exports?"undefined":i(exports))&&"undefined"!=typeof module?module.exports=Tt.document?Mt(Tt,Tt.document):function(t){return Mt(t,t.document)}:Tt.SVG=Mt(Tt,Tt.document),
61904/*! svg.filter.js - v2.0.2 - 2016-02-24
61905  * https://github.com/wout/svg.filter.js
61906  * Copyright (c) 2016 Wout Fierens; Licensed MIT */
61907function(){SVG.Filter=SVG.invent({create:"filter",inherit:SVG.Parent,extend:{source:"SourceGraphic",sourceAlpha:"SourceAlpha",background:"Backgroun
61907dImage",backgroundAlpha:"BackgroundAlpha",fill:"FillPaint",stroke:"StrokePaint",autoSetIn:!0,put:function(t,e){return this.add(t,e),!t.attr("in")&&this.autoSetIn&&t.attr("in",this.source),t.attr("result")||t.attr("result",t),t},blend:function(t,e,i){return this.put(new SVG.BlendEffect(t,e,i))},colorMatrix:function(t,e){return this.put(new SVG.ColorMatrixEffect(t,e))},convolveMatrix:function(t){return this.put(new SVG.ConvolveMatrixEffect(t))},componentTransfer:function(t){return this.put(new SVG.ComponentTransferEffect(t))},composite:function(t,e,i){return this.put(new SVG.CompositeEffect(t,e,i))},flood:function(t,e){return this.put(new SVG.FloodEffect(t,e))},offset:function(t,e){return this.put(new SVG.OffsetEffect(t,e))},image:function(t){return this.put(new SVG.ImageEffect(t))},merge:function(){var t=[void 0];for(var e in arguments)t.push(arguments[e]);return this.put(new(SVG.MergeEffect.bind.apply(SVG.MergeEffect,t)))},gaussianBlur:function(t,e){return this.put(new SVG.GaussianBlurEffect(t,e))},morphology:function(t,e){return this.put(new SVG.MorphologyEffect(t,e))},diffuseLighting:function(t,e,i){return this.put(new SVG.DiffuseLightingEffect(t,e,i))},displacementMap:function(t,e,i,a,s){return this.put(new SVG.DisplacementMapEffect(t,e,i,a,s))},specularLighting:function(t,e,i,a){return this.put(new SVG.SpecularLightingEffect(t,e,i,a))},tile:function(){return this.put(new SVG.TileEffect)},turbulence:function(t,e,i,a,s){return this.put(new SVG.TurbulenceEffect(t,e,i,a,s))},toString:function(){return"url(#"+this.attr("id")+")"}}}),SVG.extend(SVG.Defs,{filter:function(t){var e=this.put(new SVG.Filter);return"function"==typeof t&&t.call(e,e),e}}),SVG.extend(SVG.Container,{filter:function(t){return this.defs().filter(t)}}),SVG.extend(SVG.Element,SVG.G,SVG.Nested,{filter:function(t){return this.filterer=t instanceof SVG.Element?t:this.doc().filter(t),this.doc()&&this.filterer.doc()!==this.doc()&&this.doc().defs().add(this.filterer),this.attr("filter",this.filterer),this.filterer},unfilter:function(t){return this.filterer&&!0===t&&this.filterer.remove(),delete this.filterer,this.attr("filter",null)}}),SVG.Effect=SVG.invent({create:function(){this.constructor.call(this)},inherit:SVG.Element,extend:{in:function(t){return null==t?this.parent()&&this.parent().select('[result="'+this.attr("in")+'"]').get(0)||this.attr("in"):this.attr("in",t)},result:function(t){return null==t?this.attr("result"):this.attr("result",t)},toString:function(){return this.result()}}}),SVG.ParentEffect=SVG.invent({create:function(){this.constructor.call(this)},inherit:SVG.Parent,extend:{in:function(t){return null==t?this.parent()&&this.parent().select('[result="'+this.attr("in")+'"]').get(0)||this.attr("in"):this.attr("in",t)},result:function(t){return null==t?this.attr("result"):this.attr("result",t)},toString:function(){return this.result()}}});var t={blend:function(t,e){return this.parent()&&this.parent().blend(this,t,e)},colorMatrix:function(t,e){return this.parent()&&this.parent().colorMatrix(t,e).in(this)},convolveMatrix:function(t){return this.parent()&&this.parent().convolveMatrix(t).in(this)},componentTransfer:function(t){return this.parent()&&this.parent().componentTransfer(t).in(this)},composite:function(t,e){return this.parent()&&this.parent().composite(this,t,e)},flood:function(t,e){return this.parent()&&this.parent().flood(t,e)},offset:function(t,e){return this.parent()&&this.parent().offset(t,e).in(this)},image:function(t){return this.parent()&&this.parent().image(t)},merge:function(){return this.parent()&&this.parent().merge.apply(this.parent(),[this].concat(arguments))},gaussianBlur:function(t,e){return this.parent()&&this.parent().gaussianBlur(t,e).in(this)},morphology:function(t,e){return this.parent()&&this.parent().morphology(t,e).in(this)},diffuseLighting:function(t,e,i){return this.parent()&&this.parent().diffuseLighting(t,e,i).in(this)},displacementMap:function(t,e,i,a){return this.parent()&&this.parent().displacementMap(this,t,e,i,a)},specularLighting:function(t,e,i,a){return this.parent()&&this.parent().specularLighting(t,e,i,a).in(this)},tile:function(){return this.parent()&&this.parent().tile().in(this)}
61907,turbulence:function(t,e,i,a,s){return this.parent()&&this.parent().turbulence(t,e,i,a,s).in(this)}};SVG.extend(SVG.Effect,t),SVG.extend(SVG.ParentEffect,t),SVG.ChildEffect=SVG.invent({create:function(){this.constructor.call(this)},inherit:SVG.Element,extend:{in:function(t){this.attr("in",t)}}});var e={blend:function(t,e,i){this.attr({in:t,in2:e,mode:i||"normal"})},colorMatrix:function(t,e){"matrix"==t&&(e=s(e)),this.attr({type:t,values:void 0===e?null:e})},convolveMatrix:function(t){t=s(t),this.attr({order:Math.sqrt(t.split(" ").length),kernelMatrix:t})},composite:function(t,e,i){this.attr({in:t,in2:e,operator:i})},flood:function(t,e){this.attr("flood-color",t),null!=e&&this.attr("flood-opacity",e)},offset:function(t,e){this.attr({dx:t,dy:e})},image:function(t){this.attr("href",t,SVG.xlink)},displacementMap:function(t,e,i,a,s){this.attr({in:t,in2:e,scale:i,xChannelSelector:a,yChannelSelector:s})},gaussianBlur:function(t,e){null!=t||null!=e?this.attr("stdDeviation",r(Array.prototype.slice.call(arguments))):this.attr("stdDeviation","0 0")},morphology:function(t,e){this.attr({operator:t,radius:e})},tile:function(){},turbulence:function(t,e,i,a,s){this.attr({numOctaves:e,seed:i,stitchTiles:a,baseFrequency:t,type:s})}},i={merge:function(){var t;if(arguments[0]instanceof SVG.Set){var e=this;arguments[0].each((function(t){this instanceof SVG.MergeNode?e.put(this):(this instanceof SVG.Effect||this instanceof SVG.ParentEffect)&&e.put(new SVG.MergeNode(this))}))}else{t=Array.isArray(arguments[0])?arguments[0]:arguments;for(var i=0;i<t.length;i++)t[i]instanceof SVG.MergeNode?this.put(t[i]):this.put(new SVG.MergeNode(t[i]))}},componentTransfer:function(t){if(this.rgb=new SVG.Set,["r","g","b","a"].forEach(function(t){this[t]=new(SVG["Func"+t.toUpperCase()])("identity"),this.rgb.add(this[t]),this.node.appendChild(this[t].node)}.bind(this)),t)for(var e in t.rgb&&(["r","g","b"].forEach(function(e){this[e].attr(t.rgb)}.bind(this)),delete t.rgb),t)this[e].attr(t[e])},diffuseLighting:function(t,e,i){this.attr({surfaceScale:t,diffuseConstant:e,kernelUnitLength:i})},specularLighting:function(t,e,i,a){this.attr({surfaceScale:t,diffuseConstant:e,specularExponent:i,kernelUnitLength:a})}},a={distantLight:function(t,e){this.attr({azimuth:t,elevation:e})},pointLight:function(t,e,i){this.attr({x:t,y:e,z:i})},spotLight:function(t,e,i,a,s,r){this.attr({x:t,y:e,z:i,pointsAtX:a,pointsAtY:s,pointsAtZ:r})},mergeNode:function(t){this.attr("in",t)}};function s(t){return Array.isArray(t)&&(t=new SVG.Array(t)),t.toString().replace(/^\s+/,"").replace(/\s+$/,"").replace(/\s+/g," ")}function r(t){if(!Array.isArray(t))return t;for(var e=0,i=t.length,a=[];e<i;e++)a.push(t[e]);return a.join(" ")}function o(){var t=function(){};for(var e in"function"==typeof arguments[arguments.length-1]&&(t=arguments[arguments.length-1],Array.prototype.splice.call(arguments,arguments.length-1,1)),arguments)for(var i in arguments[e])t(arguments[e][i],i,arguments[e])}["r","g","b","a"].forEach((function(t){a["Func"+t.toUpperCase()]=function(t){switch(this.attr("type",t),t){case"table":this.attr("tableValues",arguments[1]);break;case"linear":this.attr("slope",arguments[1]),this.attr("intercept",arguments[2]);break;case"gamma":this.attr("amplitude",arguments[1]),this.attr("exponent",arguments[2]),this.attr("offset",arguments[2])}}})),o(e,(function(t,e){var i=e.charAt(0).toUpperCase()+e.slice(1);SVG[i+"Effect"]=SVG.invent({create:function(){this.constructor.call(this,SVG.create("fe"+i)),t.apply(this,arguments),this.result(this.attr("id")+"Out")},inherit:SVG.Effect,extend:{}})})),o(i,(function(t,e){var i=e.charAt(0).toUpperCase()+e.slice(1);SVG[i+"Effect"]=SVG.invent({create:function(){this.constructor.call(this,SVG.create("fe"+i)),t.apply(this,arguments),this.result(this.attr("id")+"Out")},inherit:SVG.ParentEffect,extend:{}})})),o(a,(function(t,e){var i=e.charAt(0).toUpperCase()+e.slice(1);SVG[i]=SVG.invent({create:function(){this.constructor.call(this,SVG.create("fe"+i)),t.apply(this,arguments)},inherit:SVG.ChildEffect,extend:{}})})),SVG.extend(SVG.MergeEffect,{in:function(t){return t instanceof SVG.MergeNode?this.add(t,0):this.add(new SVG.MergeNode(t),0),this}}),SVG.extend(SVG.CompositeEffect,SVG.BlendEffect,SVG.DisplacementMapEffect,{in2:function(t){return null==t?this.parent()&&this.parent().select('[result="'+this.attr("in2")+'"]').get(0)||this.attr("in2"):this.attr("in2",t)}}),SVG.filter={sepiatone:[.343,.669,.119,0,0,.249,.626,.13,0,0,.172,.334,.111,0,0,0,0,0,1,0]}}.call(void 0),function(){function t(t,s,r,o,n,l,h){for(var c=t.slice(s,r||h),d=o.slice(n,l||h),g=0,u={pos:[0,0],start:[0,0]},p={pos:[0,0],start:[0,0]};;){if(c[g]=e.call(u,c[g]),d[g]=e.call(p,d[g]),c[g][0]!=d[g][0]||"M"==c[g][0]||"A"==c[g][0]&&(c[g][4]!=d[g][4]||c[g][5]!=d[g][5])?(Array.prototype.splice.apply(c,[g,1].concat(a.call(u,c[g]))),Array.prototype.splice.apply(d,[g,1].concat(a.call(p,d[g])))):(c[g]=i.call(u,c[g]),d[g]=i.call(p,d[g])),++g==c.length&&g==d.length)break;g==c.length&&c.push(["C",u.pos[0],u.pos[1],u.pos[0],u.pos[1],u.pos[0],u.pos[1]]),g==d.length&&d.push(["C",p.pos[0],p.pos[1],p.pos[0],p.pos[1],p.pos[0],p.pos[1]])}return{start:c,dest:d}}function e(t){switch(t[0]){case"z":case"Z":t[0]="L",t[1]=this.start[0],t[2]=this.start[1];break;case"H":t[0]="L",t[2]=this.pos[1];break;case"V":t[0]="L",t[2]=t[1],t[1]=this.pos[0];break;case"T":t[0]="Q",t[3]=t[1],t[4]=t[2],t[1]=this.reflection[1],t[2]=this.reflection[0];break;case"S":t[0]="C",t[6]=t[4],t[5]=t[3],t[4]=t[2],t[3]=t[1],t[2]=this.reflection[1],t[1]=this.reflection[0]}return t}function i(t){var e=t.length;return this.pos=[t[e-2],t[e-1]],-1!="SCQT".indexOf(t[0])&&(this.reflection=[2*this.pos[0]-t[e-4],2*this.pos[1]-t[e-3]]),t}function a(t){var e=[t];switch(t[0]){case"M":return this.pos=this.start=[t[1],t[2]],e;
61907case"L":t[5]=t[3]=t[1],t[6]=t[4]=t[2],t[1]=this.pos[0],t[2]=this.pos[1];break;case"Q":t[6]=t[4],t[5]=t[3],t[4]=1*t[4]/3+2*t[2]/3,t[3]=1*t[3]/3+2*t[1]/3,t[2]=1*this.pos[1]/3+2*t[2]/3,t[1]=1*this.pos[0]/3+2*t[1]/3;break;case"A":t=(e=function(t,e){var i,a,s,r,o,n,l,h,c,d,g,u,p,f,x,b,v,m,y,w,k,A,S,C,L,P,T=Math.abs(e[1]),M=Math.abs(e[2]),I=e[3]%360,z=e[4],X=e[5],E=e[6],Y=e[7],F=new SVG.Point(t),R=new SVG.Point(E,Y),H=[];if(0===T||0===M||F.x===R.x&&F.y===R.y)return[["C",F.x,F.y,R.x,R.y,R.x,R.y]];i=new SVG.Point((F.x-R.x)/2,(F.y-R.y)/2).transform((new SVG.Matrix).rotate(I)),(a=i.x*i.x/(T*T)+i.y*i.y/(M*M))>1&&(T*=a=Math.sqrt(a),M*=a);s=(new SVG.Matrix).rotate(I).scale(1/T,1/M).rotate(-I),F=F.transform(s),R=R.transform(s),r=[R.x-F.x,R.y-F.y],n=r[0]*r[0]+r[1]*r[1],o=Math.sqrt(n),r[0]/=o,r[1]/=o,l=n<4?Math.sqrt(1-n/4):0,z===X&&(l*=-1);h=new SVG.Point((R.x+F.x)/2+l*-r[1],(R.y+F.y)/2+l*r[0]),c=new SVG.Point(F.x-h.x,F.y-h.y),d=new SVG.Point(R.x-h.x,R.y-h.y),g=Math.acos(c.x/Math.sqrt(c.x*c.x+c.y*c.y)),c.y<0&&(g*=-1);u=Math.acos(d.x/Math.sqrt(d.x*d.x+d.y*d.y)),d.y<0&&(u*=-1);X&&g>u&&(u+=2*Math.PI);!X&&g<u&&(u-=2*Math.PI);for(f=Math.ceil(2*Math.abs(g-u)/Math.PI),b=[],v=g,p=(u-g)/f,x=4*Math.tan(p/4)/3,k=0;k<=f;k++)y=Math.cos(v),m=Math.sin(v),w=new SVG.Point(h.x+y,h.y+m),b[k]=[new SVG.Point(w.x+x*m,w.y-x*y),w,new SVG.Point(w.x-x*m,w.y+x*y)],v+=p;for(b[0][0]=b[0][1].clone(),b[b.length-1][2]=b[b.length-1][1].clone(),s=(new SVG.Matrix).rotate(I).scale(T,M).rotate(-I),k=0,A=b.length;k<A;k++)b[k][0]=b[k][0].transform(s),b[k][1]=b[k][1].transform(s),b[k][2]=b[k][2].transform(s);for(k=1,A=b.length;k<A;k++)S=(w=b[k-1][2]).x,C=w.y,L=(w=b[k][0]).x,P=w.y,E=(w=b[k][1]).x,Y=w.y,H.push(["C",S,C,L,P,E,Y]);return H}(this.pos,t))[0]}return t[0]="C",this.pos=[t[5],t[6]],this.reflection=[2*t[5]-t[3],2*t[6]-t[4]],e}function s(t,e){if(!1===e)return!1;for(var i=e,a=t.length;i<a;++i)if("M"==t[i][0])return i;return!1}SVG.extend(SVG.PathArray,{morph:function(e){for(var i=this.value,a=this.parse(e),r=0,o=0,n=!1,l=!1;!1!==r||!1!==o;){var h;n=s(i,!1!==r&&r+1),l=s(a,!1!==o&&o+1),!1===r&&(r=0==(h=new SVG.PathArray(c.start).bbox()).height||0==h.width?i.push(i[0])-1:i.push(["M",h.x+h.width/2,h.y+h.height/2])-1),!1===o&&(o=0==(h=new SVG.PathArray(c.dest).bbox()).height||0==h.width?a.push(a[0])-1:a.push(["M",h.x+h.width/2,h.y+h.height/2])-1);var c=t(i,r,n,a,o,l);i=i.slice(0,r).concat(c.start,!1===n?[]:i.slice(n)),a=a.slice(0,o).concat(c.dest,!1===l?[]:a.slice(l)),r=!1!==n&&r+c.start.length,o=!1!==l&&o+c.dest.length}return this.value=i,this.destination=new SVG.PathArray,this.destination.value=a,this}})}(),
61908/*! svg.draggable.js - v2.2.2 - 2019-01-08
61909  * https://github.com/svgdotjs/svg.draggable.js
61910  * Copyright (c) 2019 Wout Fierens; Licensed MIT */
61911function(){function t(t){t.remember("_draggable",this),this.el=t}t.prototype.init=function(t,e){var i=this;this.constraint=t,this.value=e,this.el.on("mousedown.drag",(function(t){i.start(t)})),this.el.on("touchstart.drag",(function(t){i.start(t)}))},t.prototype.transformPoint=function(t,e){var i=(t=t||window.event).changedTouches&&t.changedTouches[0]||t;return this.p.x=i.clientX-(e||0),this.p.y=i.clientY,this.p.matrixTransform(this.m)},t.prototype.getBBox=function(){var t=this.el.bbox();return this.el instanceof SVG.Nested&&(t=this.el.rbox()),(this.el instanceof SVG.G||this.el instanceof SVG.Use||this.el instanceof SVG.Nested)&&(t.x=this.el.x(),t.y=this.el.y()),t},t.prototype.start=function(t){if("click"!=t.type&&"mousedown"!=t.type&&"mousemove"!=t.type||1==(t.which||t.buttons)){var e=this;if(this.el.fire("beforedrag",{event:t,handler:this}),!this.el.event().defaultPrevented){t.preventDefault(),t.stopPropagation(),this.parent=this.parent||this.el.parent(SVG.Nested)||this.el.parent(SVG.Doc),this.p=this.parent.node.createSVGPoint(),this.m=this.el.node.getScreenCTM().inverse();var i,a=this.getBBox();if(this.el instanceof SVG.Text)switch(i=this.el.node.getComputedTextLength(),this.el.attr("text-anchor")){case"middle":i/=2;break;case"start":i=0}this.startPoints={point:this.transformPoint(t,i),box:a,transform:this.el.transform()},SVG.on(window,"mousemove.drag",(function(t){e.drag(t)})),SVG.on(window,"touchmove.drag",(function(t){e.drag(t)})),SVG.on(window,"mouseup.drag",(function(t){e.end(t)})),SVG.on(window,"touchend.drag",(function(t){e.end(t)})),this.el.fire("dragstart",{event:t,p:this.startPoints.point,m:this.m,handler:this})}}},t.prototype.drag=function(t){var e=this.getBBox(),i=this.transformPoint(t),a=this.startPoints.box.x+i.x-this.startPoints.point.x,s=this.startPoints.box.y+i.y-this.startPoints.point.y,r=this.constraint,o=i.x-this.startPoints.point.x,n=i.y-this.startPoints.point.y;if(this.el.fire("dragmove",{event:t,p:i,m:this.m,handler:this}),this.el.event().defaultPrevented)return i;if("function"==typeof r){var l=r.call(this.el,a,s,this.m);"boolean"==typeof l&&(l={x:l,y:l}),!0===l.x?this.el.x(a):!1!==l.x&&this.el.x(l.x),!0===l.y?this.el.y(s):!1!==l.y&&this.el.y(l.y)}else"object"==typeof r&&(null!=r.minX&&a<r.minX?o=(a=r.minX)-this.startPoints.box.x:null!=r.maxX&&a>r.maxX-e.width&&(o=(a=r.maxX-e.width)-this.startPoints.box.x),null!=r.minY&&s<r.minY?n=(s=r.minY)-this.startPoints.box.y:null!=r.maxY&&s>r.maxY-e.height&&(n=(s=r.maxY-e.height)-this.startPoints.box.y),null!=r.snapToGri
61911d&&(a-=a%r.snapToGrid,s-=s%r.snapToGrid,o-=o%r.snapToGrid,n-=n%r.snapToGrid),this.el instanceof SVG.G?this.el.matrix(this.startPoints.transform).transform({x:o,y:n},!0):this.el.move(a,s));return i},t.prototype.end=function(t){var e=this.drag(t);this.el.fire("dragend",{event:t,p:e,m:this.m,handler:this}),SVG.off(window,"mousemove.drag"),SVG.off(window,"touchmove.drag"),SVG.off(window,"mouseup.drag"),SVG.off(window,"touchend.drag")},SVG.extend(SVG.Element,{draggable:function(e,i){"function"!=typeof e&&"object"!=typeof e||(i=e,e=!0);var a=this.remember("_draggable")||new t(this);return(e=void 0===e||e)?a.init(i||{},e):(this.off("mousedown.drag"),this.off("touchstart.drag")),this}})}.call(void 0),function(){function t(t){this.el=t,t.remember("_selectHandler",this),this.pointSelection={isSelected:!1},this.rectSelection={isSelected:!1},this.pointsList={lt:[0,0],rt:["width",0],rb:["width","height"],lb:[0,"height"],t:["width",0],r:["width","height"],b:["width","height"],l:[0,"height"]},this.pointCoord=function(t,e,i){var a="string"!=typeof t?t:e[t];return i?a/2:a},this.pointCoords=function(t,e){var i=this.pointsList[t];return{x:this.pointCoord(i[0],e,"t"===t||"b"===t),y:this.pointCoord(i[1],e,"r"===t||"l"===t)}}}t.prototype.init=function(t,e){var i=this.el.bbox();this.options={};var a=this.el.selectize.defaults.points;for(var s in this.el.selectize.defaults)this.options[s]=this.el.selectize.defaults[s],void 0!==e[s]&&(this.options[s]=e[s]);var r=["points","pointsExclude"];for(var s in r){var o=this.options[r[s]];"string"==typeof o?o=o.length>0?o.split(/\s*,\s*/i):[]:"boolean"==typeof o&&"points"===r[s]&&(o=o?a:[]),this.options[r[s]]=o}this.options.points=[a,this.options.points].reduce((function(t,e){return t.filter((function(t){return e.indexOf(t)>-1}))})),this.options.points=[this.options.points,this.options.pointsExclude].reduce((function(t,e){return t.filter((function(t){return e.indexOf(t)<0}))})),this.parent=this.el.parent(),this.nested=this.nested||this.parent.group(),this.nested.matrix(new SVG.Matrix(this.el).translate(i.x,i.y)),this.options.deepSelect&&-1!==["line","polyline","polygon"].indexOf(this.el.type)?this.selectPoints(t):this.selectRect(t),this.observe(),this.cleanup()},t.prototype.selectPoints=function(t){return this.pointSelection.isSelected=t,this.pointSelection.set||(this.pointSelection.set=this.parent.set(),this.drawPoints()),this},t.prototype.getPointArray=function(){var t=this.el.bbox();return this.el.array().valueOf().map((function(e){return[e[0]-t.x,e[1]-t.y]}))},t.prototype.drawPoints=function(){for(var t=this,e=this.getPointArray(),i=0,a=e.length;i<a;++i){var s=function(e){return function(i){(i=i||window.event).preventDefault?i.preventDefault():i.returnValue=!1,i.stopPropagation();var a=i.pageX||i.touches[0].pageX,s=i.pageY||i.touches[0].pageY;t.el.fire("point",{x:a,y:s,i:e,event:i})}}(i),r=this.drawPoint(e[i][0],e[i][1]).addClass(this.options.classPoints).addClass(this.options.classPoints+"_point").on("touchstart",s).on("mousedown",s);this.pointSelection.set.add(r)}},t.prototype.drawPoint=function(t,e){var i=this.options.pointType;switch(i){case"circle":return this.drawCircle(t,e);case"rect":return this.drawRect(t,e);default:if("function"==typeof i)return i.call(this,t,e);throw new Error("Unknown "+i+" point type!")}},t.prototype.drawCircle=function(t,e){return this.nested.circle(this.options.pointSize).center(t,e)},t.prototype.drawRect=function(t,e){return this.nested.rect(this.options.pointSize,this.options.pointSize).center(t,e)},t.prototype.updatePointSelection=function(){var t=this.getPointArray();this.pointSelection.set.each((function(e){this.cx()===t[e][0]&&this.cy()===t[e][1]||this.center(t[e][0],t[e][1])}))},t.prototype.updateRectSelection=function(){var t=this,e=this.el.bbox();if(this.rectSelection.set.get(0).attr({width:e.width,height:e.height}),this.options.points.length&&this.options.points.map((function(i,a){var s=t.pointCoords(i,e);t.rectSelection.set.get(a+1).center(s.x,s.y)})),this.options.rotationPoint){var i=this.rectSelection.set.length();this.rectSelection.set.get(i-1).center(e.width/2,20)}},t.prototype.selectRect=function(t){var e=this,i=this.el.bbox();function a(t){return function(i){(i=i||window.event).preventDefault?i.preventDefault():i.returnValue=!1,i.stopPropagation();var a=i.pageX||i.touches[0].pageX,s=i.pageY||i.touches[0].pageY;e.el.fire(t,{x:a,y:s,event:i})}}if(this.rectSelection.isSelected=t,this.rectSelection.set=this.rectSelection.set||this.parent.set(),this.rectSelection.set.get(0)||this.rectSelection.set.add(this.nested.rect(i.width,i.height).addClass(this.options.classRect)),this.options.points.length&&this.rectSelection.set.length()<2){this.options.points.map((function(t,s){var r=e.pointCoords(t,i),o=e.drawPoint(r.x,r.y).attr("class",e.options.classPoints+"_"+t).on("mousedown",a(t)).on("touchstart",a(t));
61911e.rectSelection.set.add(o)})),this.rectSelection.set.each((function(){this.addClass(e.options.classPoints)}))}if(this.options.rotationPoint&&(this.options.points&&!this.rectSelection.set.get(9)||!this.options.points&&!this.rectSelection.set.get(1))){var s=function(t){(t=t||window.event).preventDefault?t.preventDefault():t.returnValue=!1,t.stopPropagation();var i=t.pageX||t.touches[0].pageX,a=t.pageY||t.touches[0].pageY;e.el.fire("rot",{x:i,y:a,event:t})},r=this.drawPoint(i.width/2,20).attr("class",this.options.classPoints+"_rot").on("touchstart",s).on("mousedown",s);this.rectSelection.set.add(r)}},t.prototype.handler=function(){var t=this.el.bbox();this.nested.matrix(new SVG.Matrix(this.el).translate(t.x,t.y)),this.rectSelection.isSelected&&this.updateRectSelection(),this.pointSelection.isSelected&&this.updatePointSelection()},t.prototype.observe=function(){var t=this;if(MutationObserver)if(this.rectSelection.isSelected||this.pointSelection.isSelected)this.observerInst=this.observerInst||new MutationObserver((function(){t.handler()})),this.observerInst.observe(this.el.node,{attributes:!0});else try{this.observerInst.disconnect(),delete this.observerInst}catch(t){}else this.el.off("DOMAttrModified.select"),(this.rectSelection.isSelected||this.pointSelection.isSelected)&&this.el.on("DOMAttrModified.select",(function(){t.handler()}))},t.prototype.cleanup=function(){!this.rectSelection.isSelected&&this.rectSelection.set&&(this.rectSelection.set.each((function(){this.remove()})),this.rectSelection.set.clear(),delete this.rectSelection.set),!this.pointSelection.isSelected&&this.pointSelection.set&&(this.pointSelection.set.each((function(){this.remove()})),this.pointSelection.set.clear(),delete this.pointSelection.set),this.pointSelection.isSelected||this.rectSelection.isSelected||(this.nested.remove(),delete this.nested)},SVG.extend(SVG.Element,{selectize:function(e,i){return"object"==typeof e&&(i=e,e=!0),(this.remember("_selectHandler")||new t(this)).init(void 0===e||e,i||{}),this}}),SVG.Element.prototype.selectize.defaults={points:["lt","rt","rb","lb","t","r","b","l"],pointsExclude:[],classRect:"svg_select_boundingRect",classPoints:"svg_select_points",pointSize:7,rotationPoint:!0,deepSelect:!1,pointType:"circle"}}(),function(){(function(){function t(t){t.remember("_resizeHandler",this),this.el=t,this.parameters={},this.lastUpdateCall=null,this.p=t.doc().node.createSVGPoint()}t.prototype.transformPoint=function(t,e,i){return this.p.x=t-(this.offset.x-window.pageXOffset),this.p.y=e-(this.offset.y-window.pageYOffset),this.p.matrixTransform(i||this.m)},t.prototype._extractPosition=function(t){return{x:null!=t.clientX?t.clientX:t.touches[0].clientX,y:null!=t.clientY?t.clientY:t.touches[0].clientY}},t.prototype.init=function(t){var e=this;if(this.stop(),"stop"!==t){for(var i in this.options={},this.el.resize.defaults)this.options[i]=this.el.resize.defaults[i],void 0!==t[i]&&(this.options[i]=t[i]);this.el.on("lt.resize",(function(t){e.resize(t||window.event)})),this.el.on("rt.resize",(function(t){e.resize(t||window.event)})),this.el.on("rb.resize",(function(t){e.resize(t||window.event)})),this.el.on("lb.resize",(function(t){e.resize(t||window.event)})),this.el.on("t.resize",(function(t){e.resize(t||window.event)})),this.el.on("r.resize",(function(t){e.resize(t||window.event)})),this.el.on("b.resize",(function(t){e.resize(t||window.event)})),this.el.on("l.resize",(function(t){e.resize(t||window.event)})),this.el.on("rot.resize",(function(t){e.resize(t||window.event)})),this.el.on("point.resize",(function(t){e.resize(t||window.event)})),this.update()}},t.prototype.stop=function(){return this.el.off("lt.resize"),this.el.off("rt.resize"),this.el.off("rb.resize"),this.el.off("lb.resize"),this.el.off("t.resize"),this.el.off("r.resize"),this.el.off("b.resize"),this.el.off("l.resize"),this.el.off("rot.resize"),this.el.off("point.resize"),this},t.prototype.resize=function(t){var e=this;this.m=this.el.node.getScreenCTM().inverse(),this.offset={x:window.pageXOffset,y:window.pageYOffset};var i=this._extractPosition(t.detail.event);if(this.parameters={type:this.el.type,p:this.transformPoint(i.x,i.y),x:t.detail.x,y:t.detail.y,box:this.el.bbox(),rotation:this.el.transform().rotation},"text"===this.el.type&&(this.parameters.fontSize=this.el.attr()["font-size"]),void 0!==t.detail.i){var a=this.el.array().valueOf();this.parameters.i=t.detail.i,this.parameters.pointCoords=[a[t.detail.i][0],a[t.detail.i][1]]}switch(t.type){case"lt":this.calc=function(t,e){var i=this.snapToGri
61911d(t,e);if(this.parameters.box.width-i[0]>0&&this.parameters.box.height-i[1]>0){if("text"===this.parameters.type)return this.el.move(this.parameters.box.x+i[0],this.parameters.box.y),void this.el.attr("font-size",this.parameters.fontSize-i[0]);i=this.checkAspectRatio(i),this.el.move(this.parameters.box.x+i[0],this.parameters.box.y+i[1]).size(this.parameters.box.width-i[0],this.parameters.box.height-i[1])}};break;case"rt":this.calc=function(t,e){var i=this.snapToGrid(t,e,2);if(this.parameters.box.width+i[0]>0&&this.parameters.box.height-i[1]>0){if("text"===this.parameters.type)return this.el.move(this.parameters.box.x-i[0],this.parameters.box.y),void this.el.attr("font-size",this.parameters.fontSize+i[0]);i=this.checkAspectRatio(i,!0),this.el.move(this.parameters.box.x,this.parameters.box.y+i[1]).size(this.parameters.box.width+i[0],this.parameters.box.height-i[1])}};break;case"rb":this.calc=function(t,e){var i=this.snapToGrid(t,e,0);if(this.parameters.box.width+i[0]>0&&this.parameters.box.height+i[1]>0){if("text"===this.parameters.type)return this.el.move(this.parameters.box.x-i[0],this.parameters.box.y),void this.el.attr("font-size",this.parameters.fontSize+i[0]);i=this.checkAspectRatio(i),this.el.move(this.parameters.box.x,this.parameters.box.y).size(this.parameters.box.width+i[0],this.parameters.box.height+i[1])}};break;case"lb":this.calc=function(t,e){var i=this.snapToGrid(t,e,1);if(this.parameters.box.width-i[0]>0&&this.parameters.box.height+i[1]>0){if("text"===this.parameters.type)return this.el.move(this.parameters.box.x+i[0],this.parameters.box.y),void this.el.attr("font-size",this.parameters.fontSize-i[0]);i=this.checkAspectRatio(i,!0),this.el.move(this.parameters.box.x+i[0],this.parameters.box.y).size(this.parameters.box.width-i[0],this.parameters.box.height+i[1])}};break;case"t":this.calc=function(t,e){var i=this.snapToGrid(t,e,2);if(this.parameters.box.height-i[1]>0){if("text"===this.parameters.type)return;this.el.move(this.parameters.box.x,this.parameters.box.y+i[1]).height(this.parameters.box.height-i[1])}};break;case"r":this.calc=function(t,e){var i=this.snapToGrid(t,e,0);if(this.parameters.box.width+i[0]>0){if("text"===this.parameters.type)return;this.el.move(this.parameters.box.x,this.parameters.box.y).width(this.parameters.box.width+i[0])}};break;case"b":this.calc=function(t,e){var i=this.snapToGrid(t,e,0);if(this.parameters.box.height+i[1]>0){if("text"===this.parameters.type)return;this.el.move(this.parameters.box.x,this.parameters.box.y).height(this.parameters.box.height+i[1])}};break;case"l":this.calc=function(t,e){var i=this.snapToGrid(t,e,1);if(this.parameters.box.width-i[0]>0){if("text"===this.parameters.type)return;this.el.move(this.parameters.box.x+i[0],this.parameters.box.y).width(this.parameters.box.width-i[0])}};break;case"rot":this.calc=function(t,e){var i=t+this.parameters.p.x,a=e+this.parameters.p.y,s=Math.atan2(this.parameters.p.y-this.parameters.box.y-this.parameters.box.height/2,this.parameters.p.x-this.parameters.box.x-this.parameters.box.width/2),r=Math.atan2(a-this.parameters.box.y-this.parameters.box.height/2,i-this.parameters.box.x-this.parameters.box.width/2),o=this.parameters.rotation+180*(r-s)/Math.PI+this.options.snapToAngle/2;this.el.center(this.parameters.box.cx,this.parameters.box.cy).rotate(o-o%this.options.snapToAngle,this.parameters.box.cx,this.parameters.box.cy)};break;case"point":this.calc=function(t,e){var i=this.snapToGrid(t,e,this.parameters.pointCoords[0],this.parameters.pointCoords[1]),a=this.el.array().valueOf();a[this.parameters.i][0]=this.parameters.pointCoords[0]+i[0],a[this.parameters.i][1]=this.parameters.pointCoords[1]+i[1],this.el.plot(a)}}this.el.fire("resizestart",{dx:this.parameters.x,dy:this.parameters.y,event:t}),SVG.on(window,"touchmove.resize",(function(t){e.update(t||window.event)})),SVG.on(window,"touchend.resize",(function(){e.done()})),SVG.on(window,"mousemove.resize",(function(t){e.update(t||window.event)})),SVG.on(window,"mouseup.resize",(function(){e.done()}))},t.prototype.update=function(t){if(t){var e=this._extractPosition(t),i=this.transformPoint(e.x,e.y),a=i.x-this.parameters.p.x,s=i.y-this.parameters.p.y;this.lastUpdateCall=[a,s],this.calc(a,s),this.el.fire("resizing",{dx:a,dy:s,event:t})}else this.lastUpdateCall&&this.calc(this.lastUpdateCall[0],this.lastUpdateCall[1])},t.prototype.done=function(){this.lastUpdateCall=null,SVG.off(window,"mousemove.resize"),SVG.off(window,"mouseup.resize"),SVG.off(window,"touchmove.resize"),SVG.off(window,"touchend.resize"),this.el.fire("resizedone")}
61911,t.prototype.snapToGrid=function(t,e,i,a){var s;return void 0!==a?s=[(i+t)%this.options.snapToGrid,(a+e)%this.options.snapToGrid]:(i=null==i?3:i,s=[(this.parameters.box.x+t+(1&i?0:this.parameters.box.width))%this.options.snapToGrid,(this.parameters.box.y+e+(2&i?0:this.parameters.box.height))%this.options.snapToGrid]),t<0&&(s[0]-=this.options.snapToGrid),e<0&&(s[1]-=this.options.snapToGrid),t-=Math.abs(s[0])<this.options.snapToGrid/2?s[0]:s[0]-(t<0?-this.options.snapToGrid:this.options.snapToGrid),e-=Math.abs(s[1])<this.options.snapToGrid/2?s[1]:s[1]-(e<0?-this.options.snapToGrid:this.options.snapToGrid),this.constraintToBox(t,e,i,a)},t.prototype.constraintToBox=function(t,e,i,a){var s,r,o=this.options.constraint||{};return void 0!==a?(s=i,r=a):(s=this.parameters.box.x+(1&i?0:this.parameters.box.width),r=this.parameters.box.y+(2&i?0:this.parameters.box.height)),void 0!==o.minX&&s+t<o.minX&&(t=o.minX-s),void 0!==o.maxX&&s+t>o.maxX&&(t=o.maxX-s),void 0!==o.minY&&r+e<o.minY&&(e=o.minY-r),void 0!==o.maxY&&r+e>o.maxY&&(e=o.maxY-r),[t,e]},t.prototype.checkAspectRatio=function(t,e){if(!this.options.saveAspectRatio)return t;var i=t.slice(),a=this.parameters.box.width/this.parameters.box.height,s=this.parameters.box.width+t[0],r=this.parameters.box.height-t[1],o=s/r;return o<a?(i[1]=s/a-this.parameters.box.height,e&&(i[1]=-i[1])):o>a&&(i[0]=this.parameters.box.width-r*a,e&&(i[0]=-i[0])),i},SVG.extend(SVG.Element,{resize:function(e){return(this.remember("_resizeHandler")||new t(this)).init(e||{}),this}}),SVG.Element.prototype.resize.defaults={snapToAngle:.1,snapToGrid:1,constraint:{},saveAspectRatio:!1}}).call(this)}(),void 0===window.Apex&&(window.Apex={});var Ft=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w}return r(t,[{key:"initModules",value:function(){this.ctx.publicMethods=["updateOptions","updateSeries","appendData","appendSeries","toggleSeries","showSeries","hideSeries","setLocale","resetSeries","zoomX","toggleDataPointSelection","dataURI","addXaxisAnnotation","addYaxisAnnotation","addPointAnnotation","clearAnnotations","removeAnnotation","paper","destroy"],this.ctx.eventList=["click","mousedown","mousemove","mouseleave","touchstart","touchmove","touchleave","mouseup","touchend"],this.ctx.animations=new f(this.ctx),this.ctx.axes=new J(this.ctx),this.ctx.core=new Et(this.ctx.el,this.ctx),this.ctx.config=new H({}),this.ctx.data=new O(this.ctx),this.ctx.grid=new _(this.ctx),this.ctx.graphics=new b(this.ctx),this.ctx.coreUtils=new y(this.ctx),this.ctx.crosshairs=new Q(this.ctx),this.ctx.events=new Z(this.ctx),this.ctx.exports=new V(this.ctx),this.ctx.localization=new $(this.ctx),this.ctx.options=new S,this.ctx.responsive=new K(this.ctx),this.ctx.series=new z(this.ctx),this.ctx.theme=new tt(this.ctx),this.ctx.formatters=new W(this.ctx),this.ctx.titleSubtitle=new et(this.ctx),this.ctx.legend=new lt(this.ctx),this.ctx.toolbar=new ht(this.ctx),this.ctx.dimensions=new ot(this.ctx),this.ctx.updateHelpers=new Yt(this.ctx),this.ctx.zoomPanSelection=new ct(this.ctx),this.ctx.w.globals.tooltip=new bt(this.ctx)}}]),t}(),Rt=function(){function t(e){a(this,t),this.ctx=e,this.w=e.w}return r(t,[{key:"clear",value:function(t){var e=t.isUpdating;this.ctx.zoomPanSelection&&this.ctx.zoomPanSelection.destroy(),this.ctx.toolbar&&this.ctx.toolbar.destroy(),this.ctx.animations=null,this.ctx.axes=null,this.ctx.annotations=null,this.ctx.core=null,this.ctx.data=null,this.ctx.grid=null,this.ctx.series=null,this.ctx.responsive=null,this.ctx.theme=null,this.ctx.formatters=null,this.ctx.titleSubtitle=null,this.ctx.legend=null,this.ctx.dimensions=null,this.ctx.options=null,this.ctx.crosshairs=null,this.ctx.zoomPanSelection=null,this.ctx.updateHelpers=null,this.ctx.toolbar=null,this.ctx.localization=null,this.ctx.w.globals.tooltip=null,this.clearDomElements({isUpdating:e})}},{key:"killSVG",value:function(t){t.each((function(t,e){this.removeClass("*"),this.off(),this.stop()}),!0),t.ungroup(),t.clear()}},{key:"clearDomElements",value:function(t){var e=this,i=t.isUpdating,a=this.w.globals.dom.Paper.node;a.parentNode&&a.parentNode.parentNode&&!i&&(a.parentNode.parentNode.style.minHeight="unset");var s=this.w.globals.dom.baseEl;s&&this.ctx.eventList.forEach((function(t){s.removeEventListener(t,e.ctx.events.documentEvent)}));var r=this.w.globals.dom;if(null!==this.ctx.el)for(;this.ctx.el.firstChild;)this.ctx.el.removeChild(this.ctx.el.firstChild);this.killSVG(r.Paper),r.Paper.remove(),r.elWrap=null,r.elGraphical=null,r.elAnnotations=null,r.elLegendWrap=null,r.baseEl=null,r.elGridRect=null,r.elGridRectMask=null,r.elGridRectMarkerMask=null,r.elForecastMask=null,r.elNonForecastMask=null,r.elDefs=null}}]),t}(),Ht=new WeakMap;return function(){function t(e,i){a(this,t),this.opts=i,this.ctx=this,this.w=new N(i).init(),this.el=e,this.w.globals.cuid=p.randomId(),this.w.globals.chartID=this.w.config.chart.id?p.escapeString(this.w.config.chart.id):this.w.globals.cuid,new Ft(this).initModules(),this.create=p.bind(this.create,this),this.windowResizeHandler=this._windowResizeHandler.bind(this),this.parentResizeHandler=this._parentResizeCallback.bind(this)}return r(t,[{key:"render",value:function(){var t=this;return new Promise((function(e,i){if(null!==t.el){void 0===Apex._chartInstances&&(Apex._chartInstances=[]),t.w.config.chart.id&&Apex._chartInstances.push({id:t.w.globals.chartID,group:t.w.config.chart.group,chart:t}),t.setLocale(t.w.config.chart.defaultLocale);var a=t.w.config.chart.events.beforeMount;if("function"==typeof a&&a(t,t.w),t.events.fireEvent("beforeMount",[t,t.w]),window.addEventListener("resize",t.windowResizeHandler),h=t.el.parentNode,c=t.parentResizeHandler,d=!1,g=new ResizeObserver((function(t){d&&c.call(h,t),d=!0})),h.nodeType===Node.DOCUMENT_FRAGMENT_NODE?Array.from(h.children).forEac
61911h((function(t){return g.observe(t)})):g.observe(h),Ht.set(c,g),!t.css){var s=t.el.getRootNode&&t.el.getRootNode(),r=p.is("ShadowRoot",s),o=t.el.ownerDocument,n=o.getElementById("apexcharts-css");!r&&n||(t.css=document.createElement("style"),t.css.id="apexcharts-css",t.css.textContent='.apexcharts-canvas {\n  position: relative;\n  user-select: none;\n  /* cannot give overflow: hidden as it will crop tooltips which overflow outside chart area */\n}\n\n\n/* scrollbar is not visible by default for legend, hence forcing the visibility */\n.apexcharts-canvas ::-webkit-scrollbar {\n  -webkit-appearance: none;\n  width: 6px;\n}\n\n.apexcharts-canvas ::-webkit-scrollbar-thumb {\n  border-radius: 4px;\n  background-color: rgba(0, 0, 0, .5);\n  box-shadow: 0 0 1px rgba(255, 255, 255, .5);\n  -webkit-box-shadow: 0 0 1px rgba(255, 255, 255, .5);\n}\n\n\n.apexcharts-inner {\n  position: relative;\n}\n\n.apexcharts-text tspan {\n  font-family: inherit;\n}\n\n.legend-mouseover-inactive {\n  transition: 0.15s ease all;\n  opacity: 0.20;\n}\n\n.apexcharts-series-collapsed {\n  opacity: 0;\n}\n\n.apexcharts-tooltip {\n  border-radius: 5px;\n  box-shadow: 2px 2px 6px -4px #999;\n  cursor: default;\n  font-size: 14px;\n  left: 62px;\n  opacity: 0;\n  pointer-events: none;\n  position: absolute;\n  top: 20px;\n  display: flex;\n  flex-direction: column;\n  overflow: hidden;\n  white-space: nowrap;\n  z-index: 12;\n  transition: 0.15s ease all;\n}\n\n.apexcharts-tooltip.apexcharts-active {\n  opacity: 1;\n  transition: 0.15s ease all;\n}\n\n.apexcharts-tooltip.apexcharts-theme-light {\n  border: 1px solid #e3e3e3;\n  background: rgba(255, 255, 255, 0.96);\n}\n\n.apexcharts-tooltip.apexcharts-theme-dark {\n  color: #fff;\n  background: rgba(30, 30, 30, 0.8);\n}\n\n.apexcharts-tooltip * {\n  font-family: inherit;\n}\n\n\n.apexcharts-tooltip-title {\n  padding: 6px;\n  font-size: 15px;\n  margin-bottom: 4px;\n}\n\n.apexcharts-tooltip.apexcharts-theme-light .apexcharts-tooltip-title {\n  background: #ECEFF1;\n  border-bottom: 1px solid #ddd;\n}\n\n.apexcharts-tooltip.apexcharts-theme-dark .apexcharts-tooltip-title {\n  background: rgba(0, 0, 0, 0.7);\n  border-bottom: 1px solid #333;\n}\n\n.apexcharts-tooltip-text-y-value,\n.apexcharts-tooltip-text-goals-value,\n.apexcharts-tooltip-text-z-value {\n  display: inline-block;\n  font-weight: 600;\n  margin-left: 5px;\n}\n\n.apexcharts-tooltip-title:empty,\n.apexcharts-tooltip-text-y-label:empty,\n.apexcharts-tooltip-text-y-value:empty,\n.apexcharts-tooltip-text-goals-label:empty,\n.apexcharts-tooltip-text-goals-value:empty,\n.apexcharts-tooltip-text-z-value:empty {\n  display: none;\n}\n\n.apexcharts-tooltip-text-y-value,\n.apexcharts-tooltip-text-goals-value,\n.apexcharts-tooltip-text-z-value {\n  font-weight: 600;\n}\n\n.apexcharts-tooltip-text-goals-label, \n.apexcharts-tooltip-text-goals-value {\n  padding: 6px 0 5px;\n}\n\n.apexcharts-tooltip-goals-group, \n.apexcharts-tooltip-text-goals-label, \n.apexcharts-tooltip-text-goals-value {\n  display: flex;\n}\n.apexcharts-tooltip-text-goals-label:not(:empty),\n.apexcharts-tooltip-text-goals-value:not(:empty) {\n  margin-top: -6px;\n}\n\n.apexcharts-tooltip-marker {\n  width: 12px;\n  height: 12px;\n  position: relative;\n  top: 0px;\n  margin-right: 10px;\n  border-radius: 50%;\n}\n\n.apexcharts-tooltip-series-group {\n  padding: 0 10px;\n  display: none;\n  text-align: left;\n  justify-content: left;\n  align-items: center;\n}\n\n.apexcharts-tooltip-series-group.apexcharts-active .apexcharts-tooltip-marker {\n  opacity: 1;\n}\n\n.apexcharts-tooltip-series-group.apexcharts-active,\n.apexcharts-tooltip-series-group:last-child {\n  padding-bottom: 4px;\n}\n\n.apexcharts-tooltip-series-group-hidden {\n  opacity: 0;\n  height: 0;\n  line-height: 0;\n  padding: 0 !important;\n}\n\n.apexcharts-tooltip-y-group {\n  padding: 6px 0 5px;\n}\n\n.apexcharts-tooltip-box, .apexcharts-custom-tooltip {\n  padding: 4px 8px;\n}\n\n.apexcharts-tooltip-boxPlot {\n  display: flex;\n  flex-direction: column-reverse;\n}\n\n.apexcharts-tooltip-box>div {\n  margin: 4px 0;\n}\n\n.apexcharts-tooltip-box span.value {\n  font-weight: bold;\n}\n\n.apexcharts-tooltip-rangebar {\n  padding: 5px 8px;\n}\n\n.apexcharts-tooltip-rangebar .category {\n  font-weight: 600;\n  color: #777;\n}\n\n.apexcharts-tooltip-rangebar .series-name {\n  font-weight: bold;\n  display: block;\n  margin-bottom: 5px;\n}\n\n.apexcharts-xaxistooltip {\n  opacity: 0;\n  padding: 9px 10px;\n  pointer-events: none;\n  color: #373d3f;\n  font-size: 13px;\n  text-align: center;\n  border-radius: 2px;\n  position: absolute;\n  z-index: 10;\n  background: #ECEFF1;\n  border: 1px solid #90A4AE;\n  transition: 0.15s ease all;\n}\n\n.apexcharts-xaxistooltip.apexcharts-theme-dark {\n  background: rgba(0, 0, 0, 0.7);\n  border: 1px solid rgba(0, 0, 0, 0.5);\n  color: #fff;\n}\n\n.apexcharts-xaxistooltip:after,\n.apexcharts-xaxistooltip:before {\n  left: 50%;\n  border: solid transparent;\n  content: " ";\n  height: 0;\n  width: 0;\n  position: absolute;\n  pointer-events: none;\n}\n\n.apexcharts-xaxistooltip:after {\n  border-color: rgba(236, 239, 241, 0);\n  border-width: 6px;\n  margin-left: -6px;\n}\n\n.apexcharts-xaxistooltip:before {\n  border-color: rgba(144, 164, 174, 0);\n  border-width: 7px;\n  margin-left: -7px;\n}\n\n.apexcharts-xaxistooltip-bottom:after,\n.apexcharts-xaxistooltip-bottom:before {\n  bottom: 100%;\n}\n\n.apexcharts-xaxistooltip-top:after,\n.apexcharts-xaxistooltip-top:before {\n  top: 100%;\n}\n\n.apexcharts-xaxistooltip-bottom:after {\n  border-bottom-color: #ECEFF1;\n}\n\n.apexcharts-xaxistooltip-bottom:before {\n  border-bottom-color: #90A4AE;\n}\n\n.apexcharts-xaxistooltip-bottom.apexcharts-theme-dark:after {\n  border-bottom-color: rgba(0, 0, 0, 0.5);\n}\n\n.apexcharts-xaxistooltip-bottom.apexcharts-theme-dark:before {\n  border-bottom-color: rgba(0, 0, 0, 0.5);\n}\n\n.apexcharts-xaxistooltip-top:after {\n  border-top-color: #ECEFF1\n}\n\n.apexcharts-xaxistooltip-top:before {\n  border-top-color: #90A4AE;\n}\n\n.apexcharts-xaxistooltip-top.apexcharts-theme-dark:after {\n  border-top-color: rgba(0, 0, 0, 0.5);\n}\n\n.apexcharts-xaxistooltip-top.apexcharts-theme-dark:before {\n  border-top-color: rgba(0, 0, 0, 0.5);\n}\n\n.apexcharts-xaxistooltip.apexcharts-active {\n  opacity: 1;\n  transition: 0.15s ease all;\n}\n\n.apexcharts-yaxistooltip {\n  opacity: 0;\n  padding: 4px 10px;\n  pointer-events: none;\n  color: #373d3f;\n  font-size: 13px;\n  text-align: center;\n  border-radius: 2px;\n  position: absolute;\n  z-index: 10;\n  background: #ECEFF1;\n  border: 1px solid #90A4AE;\n}\n\n.apexcharts-yaxistooltip.apexcharts-theme-dark {\n  background: rgba(0, 0, 0, 0.7);\n  border: 1px solid rgba(0, 0, 0, 0.5);\n  color: #fff;\n}\n\n.apexcharts-yaxistooltip:after,\n.apexcharts-yaxistooltip:before {\n  top: 50%;\n  border: solid transparent;\n  content: " ";\n  height: 0;\n  width: 0;\n  position: absolute;\n  pointer-events: none;\n}\n\n.apexcharts-yaxistooltip:after {\n  border-color: rgba(236, 239, 241, 0);\n  border-width: 6px;\n  margin-top: -6px;\n}\n\n.apexcharts-yaxistooltip:before {\n  border-color: rgba(144, 164, 174, 0);\n  border-width: 7px;\n  margin-top: -7px;\n}\n\n.apexcharts-yaxistooltip-left:after,\n.apexcharts-yaxistooltip-left:before {\n  left: 100%;\n}\n\n.apexcharts-yaxistooltip-right:after,\n.apexcharts-yaxistooltip-right:before {\n  right: 100%;\n}\n\n.apexcharts-yaxistooltip-left:after {\n  border-left-color: #ECEFF1;\n}\n\n.apexcharts-yaxistooltip-left:before {\n  border-left-color: #90A4AE;\n}\n\n.apexcharts-yaxistooltip-left.apexcharts-theme-dark:after {\n  border-left-color: rgba(0, 0, 0, 0.5);\n}\n\n.apexcharts-yaxistooltip-left.apexcharts-theme-dark:before {\n  border-left-color: rgba(0, 0, 0, 0.5);\n}\n\n.apexcharts-yaxistooltip-right:after {\n  border-right-color: #ECEFF1;\n}\n\n.apexcharts-yaxistooltip-right:before {\n  border-right-color: #90A4AE;\n}\n\n.apexcharts-yaxistooltip-right.apexcharts-theme-dark:after {\n  border-right-color: rgba(0, 0, 0, 0.5);\n}\n\n.apexcharts-yaxistooltip-right.apexcharts-theme-dark:before {\n  border-right-color: rgba(0, 0, 0, 0.5);\n}\n\n.apexcharts-yaxistooltip.apexcharts-active {\n  opacity: 1;\n}\n\n.apexcharts-yaxistooltip-hidden {\n  display: none;\n}
61911\n\n.apexcharts-xcrosshairs,\n.apexcharts-ycrosshairs {\n  pointer-events: none;\n  opacity: 0;\n  transition: 0.15s ease all;\n}\n\n.apexcharts-xcrosshairs.apexcharts-active,\n.apexcharts-ycrosshairs.apexcharts-active {\n  opacity: 1;\n  transition: 0.15s ease all;\n}\n\n.apexcharts-ycrosshairs-hidden {\n  opacity: 0;\n}\n\n.apexcharts-selection-rect {\n  cursor: move;\n}\n\n.svg_select_boundingRect, .svg_select_points_rot {\n  pointer-events: none;\n  opacity: 0;\n  visibility: hidden;\n}\n.apexcharts-selection-rect + g .svg_select_boundingRect,\n.apexcharts-selection-rect + g .svg_select_points_rot {\n  opacity: 0;\n  visibility: hidden;\n}\n\n.apexcharts-selection-rect + g .svg_select_points_l,\n.apexcharts-selection-rect + g .svg_select_points_r {\n  cursor: ew-resize;\n  opacity: 1;\n  visibility: visible;\n}\n\n.svg_select_points {\n  fill: #efefef;\n  stroke: #333;\n  rx: 2;\n}\n\n.apexcharts-svg.apexcharts-zoomable.hovering-zoom {\n  cursor: crosshair\n}\n\n.apexcharts-svg.apexcharts-zoomable.hovering-pan {\n  cursor: move\n}\n\n.apexcharts-zoom-icon,\n.apexcharts-zoomin-icon,\n.apexcharts-zoomout-icon,\n.apexcharts-reset-icon,\n.apexcharts-pan-icon,\n.apexcharts-selection-icon,\n.apexcharts-menu-icon,\n.apexcharts-toolbar-custom-icon {\n  cursor: pointer;\n  width: 20px;\n  height: 20px;\n  line-height: 24px;\n  color: #6E8192;\n  text-align: center;\n}\n\n.apexcharts-zoom-icon svg,\n.apexcharts-zoomin-icon svg,\n.apexcharts-zoomout-icon svg,\n.apexcharts-reset-icon svg,\n.apexcharts-menu-icon svg {\n  fill: #6E8192;\n}\n\n.apexcharts-selection-icon svg {\n  fill: #444;\n  transform: scale(0.76)\n}\n\n.apexcharts-theme-dark .apexcharts-zoom-icon svg,\n.apexcharts-theme-dark .apexcharts-zoomin-icon svg,\n.apexcharts-theme-dark .apexcharts-zoomout-icon svg,\n.apexcharts-theme-dark .apexcharts-reset-icon svg,\n.apexcharts-theme-dark .apexcharts-pan-icon svg,\n.apexcharts-theme-dark .apexcharts-selection-icon svg,\n.apexcharts-theme-dark .apexcharts-menu-icon svg,\n.apexcharts-theme-dark .apexcharts-toolbar-custom-icon svg {\n  fill: #f3f4f5;\n}\n\n.apexcharts-canvas .apexcharts-zoom-icon.apexcharts-selected svg,\n.apexcharts-canvas .apexcharts-selection-icon.apexcharts-selected svg,\n.apexcharts-canvas .apexcharts-reset-zoom-icon.apexcharts-selected svg {\n  fill: #008FFB;\n}\n\n.apexcharts-theme-light .apexcharts-selection-icon:not(.apexcharts-selected):hover svg,\n.apexcharts-theme-light .apexcharts-zoom-icon:not(.apexcharts-selected):hover svg,\n.apexcharts-theme-light .apexcharts-zoomin-icon:hover svg,\n.apexcharts-theme-light .apexcharts-zoomout-icon:hover svg,\n.apexcharts-theme-light .apexcharts-reset-icon:hover svg,\n.apexcharts-theme-light .apexcharts-menu-icon:hover svg {\n  fill: #333;\n}\n\n.apexcharts-selection-icon,\n.apexcharts-menu-icon {\n  position: relative;\n}\n\n.apexcharts-reset-icon {\n  margin-left: 5px;\n}\n\n.apexcharts-zoom-icon,\n.apexcharts-reset-icon,\n.apexcharts-menu-icon {\n  transform: scale(0.85);\n}\n\n.apexcharts-zoomin-icon,\n.apexcharts-zoomout-icon {\n  transform: scale(0.7)\n}\n\n.apexcharts-zoomout-icon {\n  margin-right: 3px;\n}\n\n.apexcharts-pan-icon {\n  transform: scale(0.62);\n  position: relative;\n  left: 1px;\n  top: 0px;\n}\n\n.apexcharts-pan-icon svg {\n  fill: #fff;\n  stroke: #6E8192;\n  stroke-width: 2;\n}\n\n.apexcharts-pan-icon.apexcharts-selected svg {\n  stroke: #008FFB;\n}\n\n.apexcharts-pan-icon:not(.apexcharts-selected):hover svg {\n  stroke: #333;\n}\n\n.apexcharts-toolbar {\n  position: absolute;\n  z-index: 11;\n  max-width: 176px;\n  text-align: right;\n  border-radius: 3px;\n  padding: 0px 6px 2px 6px;\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n}\n\n.apexcharts-menu {\n  background: #fff;\n  position: absolute;\n  top: 100%;\n  border: 1px solid #ddd;\n  border-radius: 3px;\n  padding: 3px;\n  right: 10px;\n  opacity: 0;\n  min-width: 110px;\n  transition: 0.15s ease all;\n  pointer-events: none;\n}\n\n.apexcharts-menu.apexcharts-menu-open {\n  opacity: 1;\n  pointer-events: all;\n  transition: 0.15s ease all;\n}\n\n.apexcharts-menu-item {\n  padding: 6px 7px;\n  font-size: 12px;\n  cursor: pointer;\n}\n\n.apexcharts-theme-light .apexcharts-menu-item:hover {\n  background: #eee;\n}\n\n.apexcharts-theme-dark .apexcharts-menu {\n  background: rgba(0, 0, 0, 0.7);\n  color: #fff;\n}\n\n@media screen and (min-width: 768px) {\n  .apexcharts-canvas:hover .apexcharts-toolbar {\n    opacity: 1;\n  }\n}\n\n.apexcharts-datalabel.apexcharts-element-hidden {\n  opacity: 0;\n}\n\n.apexcharts-pie-label,\n.apexcharts-datalabels,\n.apexcharts-datalabel,\n.apexcharts-datalabel-label,\n.apexcharts-datalabel-value {\n  cursor: default;\n  pointer-events: none;\n}\n\n.apexcharts-pie-label-delay {\n  opacity: 0;\n  animation-name: opaque;\n  animation-duration: 0.3s;\n  animation-fill-mode: forwards;\n  animation-timing-function: ease;\n}\n\n.apexcharts-canvas .apexcharts-element-hidden {\n  opacity: 0;\n}\n\n.apexcharts-hide .apexcharts-series-points {\n  opacity: 0;\n}\n\n.apexcharts-gridline,\n.apexcharts-annotation-rect,\n.apexcharts-tooltip .apexcharts-marker,\n.apexcharts-area-series .apexcharts-area,\n.apexcharts-line,\n.apexcharts-zoom-rect,\n.apexcharts-toolbar svg,\n.apexcharts-area-series .apexcharts-series-markers .apexcharts-marker.no-pointer-events,\n.apexcharts-line-series .apexcharts-series-markers .apexcharts-marker.no-pointer-events,\n.apexcharts-radar-series path,\n.apexcharts-radar-series polygon {\n  pointer-events: none;\n}\n\n\n/* markers */\n\n.apexcharts-marker {\n  transition: 0.15s ease all;\n}\n\n@keyframes opaque {\n  0% {\n    opacity: 0;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n\n\n/* Resize generated styles */\n\n@keyframes resizeanim {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 0;\n  }\n}\n\n.resize-triggers {\n  animation: 1ms resizeanim;\n  visibility: hidden;\n  opacity: 0;\n}\n\n.resize-triggers,\n.resize-triggers>div,\n.contract-trigger:before {\n  content: " ";\n  display: block;\n  position: absolute;\n  top: 0;\n  left: 0;\n  height: 100%;\n  width: 100%;\n  overflow: hidden;\n}\n\n.resize-triggers>div {\n  background: #eee;\n  overflow: auto;\n}\n\n.contract-trigger:before {\n  width: 200%;\n  height: 200%;\n}',r?s.prepend(t.css):o.head.appendChild(t.css))}var l=t.create(t.w.config.series,{});if(!l)return e(t);t.mount(l).then((function(){"function"==typeof t.w.config.chart.events.mou
61911nted&&t.w.config.chart.events.mounted(t,t.w),t.events.fireEvent("mounted",[t,t.w]),e(l)})).catch((function(t){i(t)}))}else i(new Error("Element not found"));var h,c,d,g}))}},{key:"create",value:function(t,e){var i=this.w;new Ft(this).initModules();var a=this.w.globals;(a.noData=!1,a.animationEnded=!1,this.responsive.checkResponsiveConfig(e),i.config.xaxis.convertedCatToNumeric)&&new R(i.config).convertCatToNumericXaxis(i.config,this.ctx);if(null===this.el)return a.animationEnded=!0,null;if(this.core.setupElements(),"treemap"===i.config.chart.type&&(i.config.grid.show=!1,i.config.yaxis[0].show=!1),0===a.svgWidth)return a.animationEnded=!0,null;var s=y.checkComboSeries(t);a.comboCharts=s.comboCharts,a.comboBarCount=s.comboBarCount;var r=t.every((function(t){return t.data&&0===t.data.length}));(0===t.length||r)&&this.series.handleNoData(),this.events.setupEventHandlers(),this.data.parseData(t),this.theme.init(),new P(this).setGlobalMarkerSize(),this.formatters.setLabelFormatters(),this.titleSubtitle.draw(),a.noData&&a.collapsedSeries.length!==a.series.length&&!i.config.legend.showForSingleSeries||this.legend.init(),this.series.hasAllSeriesEqualX(),a.axisCharts&&(this.core.coreCalculations(),"category"!==i.config.xaxis.type&&this.formatters.setLabelFormatters(),this.ctx.toolbar.minX=i.globals.minX,this.ctx.toolbar.maxX=i.globals.maxX),this.formatters.heatmapLabelFormatters(),this.dimensions.plotCoords();var o=this.core.xySettings();this.grid.createGridMask();var n=this.core.plotChartType(t,o),l=new M(this);l.bringForward(),i.config.dataLabels.background.enabled&&l.dataLabelsBackground(),this.core.shiftGraphPosition();var h={plot:{left:i.globals.translateX,top:i.globals.translateY,width:i.globals.gridWidth,height:i.globals.gridHeight}};return{elGraph:n,xyRatios:o,elInner:i.globals.dom.elGraphical,dimensions:h}}},{key:"mount",value:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,i=this,a=i.w;return new Promise((function(s,r){if(null===i.el)return r(new Error("Not enough data to display or target element not found"));(null===e||a.globals.allSeriesCollapsed)&&i.series.handleNoData(),"treemap"!==a.config.chart.type&&i.axes.drawAxis(a.config.chart.type,e.xyRatios),i.grid=new _(i);var o=i.grid.drawGrid();i.annotations=new C(i),i.annotations.drawImageAnnos(),i.annotations.drawTextAnnos(),"back"===a.config.grid.position&&o&&a.globals.dom.elGraphical.add(o.el);var n=new G(t.ctx),l=new q(t.ctx);if(null!==o&&(n.xAxisLabelCorrections(o.xAxisTickWidth),l.setYAxisTextAlignments(),a.config.yaxis.map((function(t,e){-1===a.globals.ignoreYAxisIndexes.indexOf(e)&&l.yAxisTitleRotate(e,t.opposite)}))),"back"===a.config.annotations.position&&(a.globals.dom.Paper.add(a.globals.dom.elAnnotations),i.annotations.drawAxesAnnotations()),Array.isArray(e.elGraph))for(var h=0;h<e.elGraph.length;h++)a.globals.dom.elGraphical.add(e.elGraph[h]);else a.globals.dom.elGraphical.add(e.elGraph);if("front"===a.config.grid.position&&o&&a.globals.dom.elGraphical.add(o.el),"front"===a.config.xaxis.crosshairs.position&&i.crosshairs.drawXCrosshairs(),"front"===a.config.yaxis[0].crosshairs.position&&i.crosshairs.drawYCrosshairs(),"front"===a.config.annotations.position&&(a.globals.dom.Paper.add(a.globals.dom.elAnnotations),i.annotations.drawAxesAnnotations()),!a.globals.noData){if(a.config.tooltip.enabled&&!a.globals.noData&&i.w.globals.tooltip.drawTooltip(e.xyRatios),a.globals.axisCharts&&(a.globals.isXNumeric||a.config.xaxis.convertedCatToNumeric||a.globals.isRangeBar))(a.config.chart.zoom.enabled||a.config.chart.selection&&a.config.chart.selection.enabled||a.config.chart.pan&&a.config.chart.pan.enabled)&&i.zoomPanSelection.init({xyRatios:e.xyRatios});else{var c=a.config.chart.toolbar.tools;["zoom","zoomin","zoomout","selection","pan","reset"].forEach((function(t){c[t]=!1}))}a.config.chart.toolbar.show&&!a.globals.allSeriesCollapsed&&i.toolbar.createToolbar()}a.globals.memory.methodsToExec.length>0&&a.globals.memory.methodsToExec.forEach((function(t){t.method(t.params,!1,t.context)})),a.globals.axisCharts||a.globals.noData||i.core.resizeNonAxisCharts(),s(i)}))}},{key:"destroy",value:function(){var t,e;window.removeEventListener("resize",this.windowResizeHandler),this.el.parentNode,t=this.parentResizeHandler,(e=Ht.get(t))&&(e.disconnect(),Ht.delete(t));var i=this.w.config.chart.id;
vendor: 7,639 bytes, lines 61911-61940
61911i&&Apex._chartInstances.forEach((function(t,e){t.id===p.escapeString(i)&&Apex._chartInstances.splice(e,1)})),new Rt(this.ctx).clear({isUpdating:!1})}},{key:"updateOptions",value:function(t){var e=this,i=arguments.length>1&&void 0!==arguments[1]&&arguments[1],a=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],s=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],r=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],o=this.w;return o.globals.selection=void 0,t.series&&(this.series.resetSeries(!1,!0,!1),t.series.length&&t.series[0].data&&(t.series=t.series.map((function(t,i){return e.updateHelpers._extendSeries(t,i)}))),this.updateHelpers.revertDefaultAxisMinMax()),t.xaxis&&(t=this.updateHelpers.forceXAxisUpdate(t)),t.yaxis&&(t=this.updateHelpers.forceYAxisUpdate(t)),o.globals.collapsedSeriesIndices.length>0&&this.series.clearPreviousPaths(),t.theme&&(t=this.theme.updateThemeOptions(t)),this.updateHelpers._updateOptions(t,i,a,s,r)}},{key:"updateSeries",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],i=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];return this.series.resetSeries(!1),this.updateHelpers.revertDefaultAxisMinMax(),this.updateHelpers._updateSeries(t,e,i)}},{key:"appendSeries",value:function(t){var e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],i=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],a=this.w.config.series.slice();return a.push(t),this.series.resetSeries(!1),this.updateHelpers.revertDefaultAxisMinMax(),this.updateHelpers._updateSeries(a,e,i)}},{key:"appendData",value:function(t){var e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],i=this;i.w.globals.dataChanged=!0,i.series.getPreviousPaths();for(var a=i.w.config.series.slice(),s=0;s<a.length;s++)if(null!==t[s]&&void 0!==t[s])for(var r=0;r<t[s].data.length;r++)a[s].data.push(t[s].data[r]);return i.w.config.series=a,e&&(i.w.globals.initialSeries=p.clone(i.w.config.series)),this.update()}},{key:"update",value:function(t){var e=this;return new Promise((function(i,a){new Rt(e.ctx).clear({isUpdating:!0});var s=e.create(e.w.config.series,t);if(!s)return i(e);e.mount(s).then((function(){"function"==typeof e.w.config.chart.events.updated&&e.w.config.chart.events.updated(e,e.w),e.events.fireEvent("updated",[e,e.w]),e.w.globals.isDirty=!0,i(e)})).catch((function(t){a(t)}))}))}},{key:"getSyncedCharts",value:function(){var t=this.getGroupedCharts(),e=[this];return t.length&&(e=[],t.forEach((function(t){e.push(t)}))),e}},{key:"getGroupedCharts",value:function(){var t=this;return Apex._chartInstances.filter((function(t){if(t.group)return!0})).map((function(e){return t.w.config.chart.group===e.group?e.chart:t}))}},{key:"toggleSeries",value:function(t){return this.series.toggleSeries(t)}},{key:"highlightSeriesOnLegendHover",value:function(t,e){return this.series.toggleSeriesOnHover(t,e)}},{key:"showSeries",value:function(t){this.series.showSeries(t)}},{key:"hideSeries",value:function(t){this.series.hideSeries(t)}},{key:"resetSeries",value:function(){var t=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];this.series.resetSeries(t,e)}},{key:"addEventListener",value:function(t,e){this.events.addEventListener(t,e)}},{key:"removeEventListener",value:function(t,e){this.events.removeEventListener(t,e)}},{key:"addXaxisAnnotation",value:function(t){var e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0,a=this;i&&(a=i),a.annotations.addXaxisAnnotationExternal(t,e,a)}},{key:"addYaxisAnnotation",value:function(t){var e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0,a=this;i&&(a=i),a.annotations.addYaxisAnnotationExternal(t,e,a)}},{key:"addPointAnnotation",value:function(t){var e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0,a=this;i&&(a=i),a.annotations.addPointAnnotationExternal(t,e,a)}},{key:"clearAnnotations",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:void 0,e=this;t&&(e=t),e.annotations.clearAnnotations(e)}},{key:"removeAnnotation",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:void 0,i=this;e&&(i=e),i.annotations.removeAnnotation(i,t)}},{key:"getChartArea",value:function(){return this.w.globals.dom.baseEl.querySelector(".apexcharts-inner")}},{key:"getSeriesTotalXRange",value:function(t,e){return this.coreUtils.getSeriesTotalsXRange(t,e)}},{key:"getHighestValueInSeries",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,e=new U(this.ctx);return e.getMinYMaxY(t).highestY}},{key:"getLowestValueInSeries",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,e=new U(this.ctx);return e.getMinYMaxY(t).lowestY}},{key:"getSeriesTotal",value:function(){return this.w.globals.seriesTotals}},{key:"toggleDataPointSelection",value:function(t,e){return this.updateHelpers.toggleDataPointSelection(t,e)}},{key:"zoomX",value:function(t,e){this.ctx.toolbar.zoomUpdateOptions(t,e)}},{key:"setLocale",value:function(t){this.localization.setCurrentLocaleValues(t)}},{key:"dataURI",value:function(t){return new V(this.ctx).dataURI(t)}},{key:"paper",value:function(){return this.w.globals.dom.Paper}},{key:"_parentResizeCallback",value:function(){this.w.globals.animationEnded&&this.w.config.chart.redrawOnParentResize&&this._windowResize()}},{key:"_windowResize",value:function(){var t=this;clearTimeout(this.w.globals.resizeTimer),this.w.globals.resizeTimer=window.setTimeout((function(){t.w.globals.resized=!0,t.w.globals.dataChanged=!1,t.ctx.update()}),150)}},{key:"_windowResizeHandler",value:function(){var t=this.w.config.chart.redrawOnWindowResize;"function"==typeof t&&(t=t()),t&&this._windowResize()}}],[{key:"getChartByID",value:function(t){var e=p.escapeString(t),i=Apex._chartInstances.filter((function(t){return t.id===e}))[0];return i&&i.chart}},{key:"initOnLoad",value:function(){for(var e=document.querySelectorAll("[data-apexcharts]"),i=0;i<e.length;i++){new t(e[i],JSON.parse(e[i].getAttribute("data-options"))).render()}}},{key:"exec",value:function(t,e){var i=this.getChartByID(t);if(i){i.w.globals.isExecCalled=!0;var a=null;if(-1!==i.publicMethods.indexOf(e)){for(var s=arguments.length,r=new Array(s>2?s-2:0),o=2;o<s;o++)r[o-2]=arguments[o];a=i[e].apply(i,r)}return a}}},{key:"merge",value:function(t,e){return p.extend(t,e)}}]),t}()}));
61912/**
61913 * @preserve jQuery DateTimePicker plugin v2.4.1
61914 * @homepage http://xdsoft.net/jqplugins/datetimepicker/
61915 * (c) 2014, Chupurnov Valeriy.
61916 */
61917/*global document,window,jQuery,setTimeout,clearTimeout*/
61918(function ($) {
61919	'use strict';
61920	var default_options  = {
61921		i18n: {
61922			ar: { // Arabic
61923				months: [
61924					"كانون الثاني", "شباط", "آذار", "نيسان", "مايو", "حزيران", "تموز", "آب", "أيلول", "تشرين الأول", "تشرين الثاني", "كانون الأول"
61925				],
61926				dayOfWeek: [
61927					"ن", "ث", "ع", "خ", "ج", "س", "ح"
61928				]
61929			},
61930			ro: { // Romanian
61931				months: [
61932					"ianuarie", "februarie", "martie", "aprilie", "mai", "iunie", "iulie", "august", "septembrie", "octombrie", "noiembrie", "decembrie"
61933				],
61934				dayOfWeek: [
61935					"l", "ma", "mi", "j", "v", "s", "d"
61936				]
61937			},
61938			id: { // Indonesian
61939				months: [
61940					"Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "
61940November", "Desember"
61941				],
61942				dayOfWeek: [
61943					"Sen", "Sel", "Rab", "Kam", "Jum", "Sab", "Min"
61944				]
61945			},
61946			bg: { // Bulgarian
61947				months: [
61948					"Януари", "Февруари", "Март", "Април", "Май", "Юни", "Юли", "Август", "Септември", "Октомври", "Ноември", "Декември"
61949				],
61950				dayOfWeek: [
61951					"Нд", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб"
61952				]
61953			},
61954			fa: { // Persian/Farsi
61955				months: [
61956					'فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور', 'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند'
61957				],
61958				dayOfWeek: [
61959					'یکشنبه', 'دوشنبه', 'سه شنبه', 'چهارشنبه', 'پنجشنبه', 'جمعه', 'شنبه'
61960				]
61961			},
61962			ru: { // Russian
61963				months: [
61964					'Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'
61965				],
61966				dayOfWeek: [
61967					"Вск", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб"
61968				]
61969			},
61970			uk: { // Ukrainian
61971				months: [
61972					'Січень', 'Лютий', 'Березень', 'Квітень', 'Травень', 'Червень', 'Липень', 'Серпень', 'Вересень', 'Жовтень', 'Листопад', 'Грудень'
61973				],
61974				dayOfWeek: [
61975					"Ндл", "Пнд", "Втр", "Срд", "Чтв", "Птн", "Сбт"
61976				]
61977			},
61978			en: { // English
61979				months: [
61980					"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "
61980November", "December"
61981				],
61982				dayOfWeek: [
61983					"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
61984				]
61985			},
61986			el: { // Ελληνικά
61987				months: [
61988					"Ιανουάριος", "Φεβρουάριος", "Μάρτιος", "Απρίλιος", "Μάιος", "Ιούνιος", "Ιούλιος", "Αύγουστος", "Σεπτέμβριος", "Οκτώβριος", "Νοέμβριος", "Δεκέμβριος"
61989				],
61990				dayOfWeek: [
61991					"Κυρ", "Δευ", "Τρι", "Τετ", "Πεμ", "Παρ", "Σαβ"
61992				]
61993			},
61994			de: { // German
61995				months: [
61996					'Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'
61997				],
61998				dayOfWeek: [
61999					"So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"
62000				]
62001			},
62002			nl: { // Dutch
62003				months: [
62004					"januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december"
62005				],
62006				dayOfWeek: [
62007					"zo", "ma", "di", "wo", "do", "vr", "za"
62008				]
62009			},
62010			tr: { // Turkish
62011				months: [
62012					"Ocak", "Şubat", "Mart", "Nisan", "Mayıs", "Haziran", "Temmuz", "Ağustos", "Eylül", "Ekim", "Kasım", "Aralık"
62013				],
62014				dayOfWeek: [
62015					"Paz", "Pts", "Sal", "Çar", "Per", "Cum", "Cts"
62016				]
62017			},
62018			fr: { //French
62019				months: [
62020					"Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"
62021				],
62022				dayOfWeek: [
62023					"Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam"
62024				]
62025			},
62026			es: { // Spanish
62027				months: [
62028					"Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"
62029				],
62030				dayOfWeek: [
62031					"Dom", "Lun", "Mar", "Mié", "Jue", "Vie", "Sáb"
62032				]
62033			},
62034			th: { // Thai
62035				months: [
62036					'มกราคม', 'กุมภาพันธ์', 'มีนาคม', 'เมษายน', 'พฤษภาคม', 'มิถุนายน', 'กรกฎาคม', 'สิงหาคม', 'กันยายน', 'ตุลาคม', 'พฤศจิกายน', 'ธันวาคม'
62037				],
62038				dayOfWeek: [
62039					'อา.', 'จ.', 'อ.', 'พ.', 'พฤ.', 'ศ.', 'ส.'
62040				]
62041			},
62042			pl: { // Polish
62043				months: [
62044					"styczeń", "luty", "marzec", "kwiecień", "maj", "czerwiec", "lipiec", "sierpień", "wrzesień", "październik", "listopad", "grudzień"
62045				],
62046				dayOfWeek: [
62047					"nd", "pn", "wt", "śr", "cz", "pt", "sb"
62048				]
62049			},
62050			pt: { // Portuguese
62051				months: [
62052					"Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"
62053				],
62054				dayOfWeek: [
62055					"Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sab"
62056				]
62057			},
62058			ch: { // Simplified Chinese
62059				months: [
62060					"一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"
62061				],
62062				dayOfWeek: [
62063					"日", "一", "二", "三", "四", "五", "六"
62064				]
62065			},
62066			se: { // Swedish
62067				months: [
62068					"Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September",  "Oktober", "November", "December"
62069				],
62070				dayOfWeek: [
62071					"Sön", "Mån", "Tis", "Ons", "Tor", "Fre", "Lör"
62072				]
62073			},
62074			kr: { // Korean
62075				months: [
62076					"1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"
62077				],
62078				dayOfWeek: [
62079					"일", "월", "화", "수", "목", "금", "토"
62080				]
62081			},
62082			it: { // Italian
62083				months: [
62084					"Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"
62085				],
62086				dayOfWeek: [
62087					"Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab"
62088				]
62089			},
62090			da: { // Dansk
62091				months: [
62092					"January", "Februar", "Marts", "April", "Maj", "Juni", "July", "August", "September", "Oktober", "November", "December"
62093				],
62094				dayOfWeek: [
62095					"Søn", "Man", "Tir", "Ons", "Tor", "Fre", "Lør"
62096				]
62097			},
62098			no: { // Norwegian
62099				months: [
62100					"Januar", "Februar", "Mars", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Desember"
62101				],
62102				dayOfWeek: [
62103					"Søn", "Man", "Tir", "Ons", "Tor", "Fre", "Lør"
62104				]
62105			},
62106			ja: { // Japanese
62107				months: [
62108					"1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"
62109				],
62110				dayOfWeek: [
62111					"日", "月", "火", "水", "木", "金", "土"
62112				]
62113			},
62114			vi: { // Vietnamese
62115				months: [
62116					"Tháng 1", "Tháng 2", "Tháng 3", "Tháng 4", "Tháng 5", "Tháng 6", "Tháng 7", "Tháng 8", "Tháng 9", "Tháng 10", "Tháng 11", "Tháng 12"
62117				],
62118				dayOfWeek: [
62119					"CN", "T2", "T3", "T4", "T5", "T6", "T7"
62120				]
62121			},
62122			sl: { // Slovenščina
62123				months: [
62124					"Januar", "Februar", "Marec", "April", "Maj", "Junij", "Julij", "Avgust", "September", "Oktober", "
62124November", "December"
62125				],
62126				dayOfWeek: [
62127					"Ned", "Pon", "Tor", "Sre", "Čet", "Pet", "Sob"
62128				]
62129			},
62130			cs: { // Čeština
62131				months: [
62132					"Leden", "Únor", "Březen", "Duben", "Květen", "Červen", "Červenec", "Srpen", "Září", "Říjen", "Listopad", "Prosinec"
62133				],
62134				dayOfWeek: [
62135					"Ne", "Po", "Út", "St", "Čt", "Pá", "So"
62136				]
62137			},
62138			hu: { // Hungarian
62139				months: [
62140					"Január", "Február", "Március", "Április", "Május", "Június", "Július", "Augusztus", "Szeptember", "Október", "November", "December"
62141				],
62142				dayOfWeek: [
62143					"Va", "Hé", "Ke", "Sze", "Cs", "Pé", "Szo"
62144				]
62145			},
62146			az: { //Azerbaijanian (Azeri)
62147				months: [
62148					"Yanvar", "Fevral", "Mart", "Aprel", "May", "Iyun", "Iyul", "Avqust", "Sentyabr", "Oktyabr", "Noyabr", "Dekabr"
62149				],
62150				dayOfWeek: [
62151					"B", "Be", "Ça", "Ç", "Ca", "C", "Ş"
62152				]
62153			},
62154			bs: { //Bosanski
62155				months: [
62156					"Januar", "Februar", "Mart", "April", "Maj", "Jun", "Jul", "Avgust", "Septembar", "Oktobar", "Novembar", "Decembar"
62157				],
62158				dayOfWeek: [
62159					"Ned", "Pon", "Uto", "Sri", "Čet", "Pet", "Sub"
62160				]
62161			},
62162			ca: { //Català
62163				months: [
62164					"Gener", "Febrer", "Març", "Abril", "Maig", "Juny", "Juliol", "Agost", "Setembre", "Octubre", "Novembre", "Desembre"
62165				],
62166				dayOfWeek: [
62167					"Dg", "Dl", "Dt", "Dc", "Dj", "Dv", "Ds"
62168				]
62169			},
62170			'en-GB': { //English (British)
62171				months: [
62172					"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "
62172November", "December"
62173				],
62174				dayOfWeek: [
62175					"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
62176				]
62177			},
62178			et: { //"Eesti"
62179				months: [
62180					"Jaanuar", "Veebruar", "Märts", "Aprill", "Mai", "Juuni", "Juuli", "August", "September", "Oktoober", "November", "Detsember"
62181				],
62182				dayOfWeek: [
62183					"P", "E", "T", "K", "N", "R", "L"
62184				]
62185			},
62186			eu: { //Euskara
62187				months: [
62188					"Urtarrila", "Otsaila", "Martxoa", "Apirila", "Maiatza", "Ekaina", "Uztaila", "Abuztua", "Iraila", "Urria", "Azaroa", "Abendua"
62189				],
62190				dayOfWeek: [
62191					"Ig.", "Al.", "Ar.", "Az.", "Og.", "Or.", "La."
62192				]
62193			},
62194			fi: { //Finnish (Suomi)
62195				months: [
62196					"Tammikuu", "Helmikuu", "Maaliskuu", "Huhtikuu", "Toukokuu", "Kesäkuu", "Heinäkuu", "Elokuu", "Syyskuu", "Lokakuu", "Marraskuu", "Joulukuu"
62197				],
62198				dayOfWeek: [
62199					"Su", "Ma", "Ti", "Ke", "To", "Pe", "La"
62200				]
62201			},
62202			gl: { //Galego
62203				months: [
62204					"Xan", "Feb", "Maz", "Abr", "Mai", "Xun", "Xul", "Ago", "Set", "Out", "Nov", "Dec"
62205				],
62206				dayOfWeek: [
62207					"Dom", "Lun", "Mar", "Mer", "Xov", "Ven", "Sab"
62208				]
62209			},
62210			hr: { //Hrvatski
62211				months: [
62212					"Siječanj", "Veljača", "Ožujak", "Travanj", "Svibanj", "Lipanj", "Srpanj", "Kolovoz", "Rujan", "Listopad", "Studeni", "Prosinac"
62213				],
62214				dayOfWeek: [
62215					"Ned", "Pon", "Uto", "Sri", "Čet", "Pet", "Sub"
62216				]
62217			},
62218			ko: { //Korean (한국어)
62219				months: [
62220					"1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"
62221				],
62222				dayOfWeek: [
62223					"일", "월", "화", "수", "목", "금", "토"
62224				]
62225			},
62226			lt: { //Lithuanian (lietuvių)
62227				months: [
62228					"Sausio", "Vasario", "Kovo", "Balandžio", "Gegužės", "Birželio", "Liepos", "Rugpjūčio", "Rugsėjo", "Spalio", "Lapkričio", "Gruodžio"
62229				],
62230				dayOfWeek: [
62231					"Sek", "Pir", "Ant", "Tre", "Ket", "Pen", "Šeš"
62232				]
62233			},
62234			lv: { //Latvian (Latviešu)
62235				months: [
62236					"Janvāris", "Februāris", "Marts", "Aprīlis ", "Maijs", "Jūnijs", "Jūlijs", "Augusts", "Septembris", "Oktobris", "Novembris", "Decembris"
62237				],
62238				dayOfWeek: [
62239					"Sv", "Pr", "Ot", "Tr", "Ct", "Pk", "St"
62240				]
62241			},
62242			mk: { //Macedonian (Македонски)
62243				months: [
62244					"јануари", "февруари", "март", "април", "мај", "јуни", "јули", "август", "септември", "октомври", "ноември", "декември"
62245				],
62246				dayOfWeek: [
62247					"нед", "пон", "вто", "сре", "чет", "пет", "саб"
62248				]
62249			},
62250			mn: { //Mongolian (Монгол)
62251				months: [
62252					"1-р сар", "2-р сар", "3-р сар", "4-р сар", "5-р сар", "6-р сар", "7-р сар", "8-р сар", "9-р сар", "10-р сар", "11-р сар", "12-р сар"
62253				],
62254				dayOfWeek: [
62255					"Дав", "Мяг", "Лха", "Пүр", "Бсн", "Бям", "Ням"
62256				]
62257			},
62258			'pt-BR': { //Português(Brasil)
62259				months: [
62260					"Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"
62261				],
62262				dayOfWeek: [
62263					"Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb"
62264				]
62265			},
62266			sk: { //Slovenčina
62267				months: [
62268					"Január", "Február", "Marec", "Apríl", "Máj", "Jún", "Júl", "August", "September", "Október", "November", "December"
62269				],
62270				dayOfWeek: [
62271					"Ne", "Po", "Ut", "St", "Å t", "Pi", "So"
62272				]
62273			},
62274			sq: { //Albanian (Shqip)
62275				months: [
62276					"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "
vendor: 9,048 bytes, lines 62276-62569
62276November", "December"
62277				],
62278				dayOfWeek: [
62279					"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
62280				]
62281			},
62282			'sr-YU': { //Serbian (Srpski)
62283				months: [
62284					"Januar", "Februar", "Mart", "April", "Maj", "Jun", "Jul", "Avgust", "Septembar", "Oktobar", "Novembar", "Decembar"
62285				],
62286				dayOfWeek: [
62287					"Ned", "Pon", "Uto", "Sre", "čet", "Pet", "Sub"
62288				]
62289			},
62290			sr: { //Serbian Cyrillic (Српски)
62291				months: [
62292					"јануар", "фебруар", "март", "април", "мај", "јун", "јул", "август", "септембар", "октобар", "новембар", "децембар"
62293				],
62294				dayOfWeek: [
62295					"нед", "пон", "уто", "сре", "чет", "пет", "суб"
62296				]
62297			},
62298			sv: { //Svenska
62299				months: [
62300					"Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September", "Oktober", "November", "December"
62301				],
62302				dayOfWeek: [
62303					"Sön", "Mån", "Tis", "Ons", "Tor", "Fre", "Lör"
62304				]
62305			},
62306			'zh-TW': { //Traditional Chinese (繁體中文)
62307				months: [
62308					"一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"
62309				],
62310				dayOfWeek: [
62311					"日", "一", "二", "三", "四", "五", "六"
62312				]
62313			},
62314			zh: { //Simplified Chinese (简体中文)
62315				months: [
62316					"一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"
62317				],
62318				dayOfWeek: [
62319					"日", "一", "二", "三", "四", "五", "六"
62320				]
62321			},
62322			he: { //Hebrew (עברית)
62323				months: [
62324					'ינואר', 'פברואר', 'מרץ', 'אפריל', 'מאי', 'יוני', 'יולי', 'אוגוסט', 'ספטמבר', 'אוקטובר', 'נובמבר', 'דצמבר'
62325				],
62326				dayOfWeek: [
62327					'א\'', 'ב\'', 'ג\'', 'ד\'', 'ה\'', 'ו\'', 'שבת'
62328				]
62329			}
62330		},
62331		value: '',
62332		lang: 'en',
62333
62334		format:	'Y/m/d H:i',
62335		formatTime:	'H:i',
62336		formatDate:	'Y/m/d',
62337
62338		startDate:	false, // new Date(), '1986/12/08', '-1970/01/05','-1970/01/05',
62339		step: 60,
62340		monthChangeSpinner: true,
62341
62342		closeOnDateSelect: false,
62343		closeOnWithoutClick: true,
62344		closeOnInputClick: true,
62345
62346		timepicker: true,
62347		datepicker: true,
62348		weeks: false,
62349
62350		defaultTime: false,	// use formatTime format (ex. '10:00' for formatTime:	'H:i')
62351		defaultDate: false,	// use formatDate format (ex new Date() or '1986/12/08' or '-1970/01/05' or '-1970/01/05')
62352
62353		minDate: false,
62354		maxDate: false,
62355		minTime: false,
62356		maxTime: false,
62357
62358		allowTimes: [],
62359		opened: false,
62360		initTime: true,
62361		inline: false,
62362		theme: '',
62363
62364		onSelectDate: function () {},
62365		onSelectTime: function () {},
62366		onChangeMonth: function () {},
62367		onChangeYear: function () {},
62368		onChangeDateTime: function () {},
62369		onShow: function () {},
62370		onClose: function () {},
62371		onGenerate: function () {},
62372
62373		withoutCopyright: true,
62374		inverseButton: false,
62375		hours12: false,
62376		next:	'xdsoft_next',
62377		prev : 'xdsoft_prev',
62378		dayOfWeekStart: 0,
62379		parentID: 'body',
62380		timeHeightInTimePicker: 25,
62381		timepickerScrollbar: true,
62382		todayButton: true,
62383		defaultSelect: true,
62384
62385		scrollMonth: true,
62386		scrollTime: true,
62387		scrollInput: true,
62388
62389		lazyInit: false,
62390		mask: false,
62391		validateOnBlur: true,
62392		allowBlank: true,
62393		yearStart: 1950,
62394		yearEnd: 2050,
62395		style: '',
62396		id: '',
62397		fixed: false,
62398		roundTime: 'round', // ceil, floor
62399		className: '',
62400		weekends: [],
62401		disabledDates : [],
62402		yearOffset: 0,
62403		beforeShowDay: null,
62404
62405		enterLikeTab: true
62406	};
62407	// fix for ie8
62408	if (!Array.prototype.indexOf) {
62409		Array.prototype.indexOf = function (obj, start) {
62410			var i, j;
62411			for (i = (start || 0), j = this.length; i < j; i += 1) {
62412				if (this[i] === obj) { return i; }
62413			}
62414			return -1;
62415		};
62416	}
62417	Date.prototype.countDaysInMonth = function () {
62418		return new Date(this.getFullYear(), this.getMonth() + 1, 0).getDate();
62419	};
62420	$.fn.xdsoftScroller = function (percent) {
62421		return this.each(function () {
62422			var timeboxparent = $(this),
62423				pointerEventToXY = function (e) {
62424					var out = {x: 0, y: 0},
62425						touch;
62426					if (e.type === 'touchstart' || e.type === 'touchmove' || e.type === 'touchend' || e.type === 'touchcancel') {
62427						touch  = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
62428						out.x = touch.clientX;
62429						out.y = touch.clientY;
62430					} else if (e.type === 'mousedown' || e.type === 'mouseup' || e.type === 'mousemove' || e.type === 'mouseover' || e.type === 'mouseout' || e.type === 'mouseenter' || e.type === 'mouseleave') {
62431						out.x = e.clientX;
62432						out.y = e.clientY;
62433					}
62434					return out;
62435				},
62436				move = 0,
62437				timebox,
62438				parentHeight,
62439				height,
62440				scrollbar,
62441				scroller,
62442				maximumOffset = 100,
62443				start = false,
62444				startY = 0,
62445				startTop = 0,
62446				h1 = 0,
62447				touchStart = false,
62448				startTopScroll = 0,
62449				calcOffset = function () {};
62450			if (percent === 'hide') {
62451				timeboxparent.find('.xdsoft_scrollbar').hide();
62452				return;
62453			}
62454			if (!$(this).hasClass('xdsoft_scroller_box')) {
62455				timebox = timeboxparent.children().eq(0);
62456				parentHeight = timeboxparent[0].clientHeight;
62457				height = timebox[0].offsetHeight;
62458				scrollbar = $('<div class="xdsoft_scrollbar"></div>');
62459				scroller = $('<div class="xdsoft_scroller"></div>');
62460				scrollbar.append(scroller);
62461
62462				timeboxparent.addClass('xdsoft_scroller_box').append(scrollbar);
62463				calcOffset = function calcOffset(event) {
62464					var offset = pointerEventToXY(event).y - startY + startTopScroll;
62465					if (offset < 0) {
62466						offset = 0;
62467					}
62468					if (offset + scroller[0].offsetHeight > h1) {
62469						offset = h1 - scroller[0].offsetHeight;
62470					}
62471					timeboxparent.trigger('scroll_element.xdsoft_scroller', [maximumOffset ? offset / maximumOffset : 0]);
62472				};
62473
62474				scroller
62475					.on('touchstart.xdsoft_scroller mousedown.xdsoft_scroller', function (event) {
62476						if (!parentHeight) {
62477							timeboxparent.trigger('resize_scroll.xdsoft_scroller', [percent]);
62478						}
62479
62480						startY = pointerEventToXY(event).y;
62481						startTopScroll = parseInt(scroller.css('margin-top'), 10);
62482						h1 = scrollbar[0].offsetHeight;
62483
62484						if (event.type === 'mousedown') {
62485							if (document) {
62486								$(document.body).addClass('xdsoft_noselect');
62487							}
62488							$([document.body, window]).on('mouseup.xdsoft_scroller', function arguments_callee() {
62489								$([document.body, window]).off('mouseup.xdsoft_scroller', arguments_callee)
62490									.off('mousemove.xdsoft_scroller', calcOffset)
62491									.removeClass('xdsoft_noselect');
62492							});
62493							$(document.body).on('mousemove.xdsoft_scroller', calcOffset);
62494						} else {
62495							touchStart = true;
62496							event.stopPropagation();
62497							event.preventDefault();
62498						}
62499					})
62500					.on('touchmove', function (event) {
62501						if (touchStart) {
62502							event.preventDefault();
62503							calcOffset(event);
62504						}
62505					})
62506					.on('touchend touchcancel', function (event) {
62507						touchStart =  false;
62508						startTopScroll = 0;
62509					});
62510
62511				timeboxparent
62512					.on('scroll_element.xdsoft_scroller', function (event, percentage) {
62513						if (!parentHeight) {
62514							timeboxparent.trigger('resize_scroll.xdsoft_scroller', [percentage, true]);
62515						}
62516						percentage = percentage > 1 ? 1 : (percentage < 0 || isNaN(percentage)) ? 0 : percentage;
62517
62518						scroller.css('margin-top', maximumOffset * percentage);
62519
62520						setTimeout(function () {
62521							timebox.css('marginTop', -parseInt((timebox[0].offsetHeight - parentHeight) * percentage, 10));
62522						}, 10);
62523					})
62524					.on('resize_scroll.xdsoft_scroller', function (event, percentage, noTriggerScroll) {
62525						var percent, sh;
62526						parentHeight = timeboxparent[0].clientHeight;
62527						height = timebox[0].offsetHeight;
62528						percent = parentHeight / height;
62529						sh = percent * scrollbar[0].offsetHeight;
62530						if (percent > 1) {
62531							scroller.hide();
62532						} else {
62533							scroller.show();
62534							scroller.css('height', parseInt(sh > 10 ? sh : 10, 10));
62535							maximumOffset = scrollbar[0].offsetHeight - scroller[0].offsetHeight;
62536							if (noTriggerScroll !== true) {
62537								timeboxparent.trigger('scroll_element.xdsoft_scroller', [percentage || Math.abs(parseInt(timebox.css('marginTop'), 10)) / (height - parentHeight)]);
62538							}
62539						}
62540					});
62541
62542				timeboxparent.on('mousewheel', function (event) {
62543					var top = Math.abs(parseInt(timebox.css('marginTop'), 10));
62544
62545					top = top - (event.deltaY * 20);
62546					if (top < 0) {
62547						top = 0;
62548					}
62549
62550					timeboxparent.trigger('scroll_element.xdsoft_scroller', [top / (height - parentHeight)]);
62551					event.stopPropagation();
62552					return false;
62553				});
62554
62555				timeboxparent.on('touchstart', function (event) {
62556					start = pointerEventToXY(event);
62557					startTop = Math.abs(parseInt(timebox.css('marginTop'), 10));
62558				});
62559
62560				timeboxparent.on('touchmove', function (event) {
62561					if (start) {
62562						event.preventDefault();
62563						var coord = pointerEventToXY(event);
62564						timeboxparent.trigger('scroll_element.xdsoft_scroller', [(startTop - (coord.y - start.y)) / (height - parentHeight)]);
62565					}
62566				});
62567
62568				timeboxparent.on('touchend touchcancel', function (event) {
62569					start = false;
62570					startTop = 0;
62571				});
62572			}
62573			timeboxparent.trigger('resize_scroll.xdsoft_scroller', [percent]);
62574		});
62575	};
62576
62577	$.fn.datetimepicker = function (opt) {
62578		var KEY0 = 48,
62579			KEY9 = 57,
62580			_KEY0 = 96,
62581			_KEY9 = 105,
62582			CTRLKEY = 17,
62583			DEL = 46,
62584			ENTER = 13,
62585			ESC = 27,
62586			BACKSPACE = 8,
62587			ARROWLEFT = 37,
62588			ARROWUP = 38,
62589			ARROWRIGHT = 39,
62590			ARROWDOWN = 40,
62591			TAB = 9,
62592			F5 = 116,
62593			AKEY = 65,
62594			CKEY = 67,
62595			VKEY = 86,
62596			ZKEY = 90,
62597			YKEY = 89,
62598			ctrlDown	=	false,
62599			options = ($.isPlainObject(opt) || !opt) ? $.extend(true, {}, default_options, opt) : $.extend(true, {}, default_options),
62600
62601			lazyInitTimer = 0,
62602			createDateTimePicker,
62603			destroyDateTimePicker,
62604			_xdsoft_datetime,
62605
62606			lazyInit = function (input) {
62607				input
62608					.on('open.xdsoft focusin.xdsoft mousedown.xdsoft', function initOnActionCallback(event) {
62609						if (input.is(':disabled') || input.is(':hidden') || !input.is(':visible') || input.data('xdsoft_datetimepicker')) {
62610							return;
62611						}
62612						clearTimeout(lazyInitTimer);
62613						lazyInitTimer = setTimeout(function () {
62614
62615							if (!input.data('xdsoft_datetimepicker')) {
62616								createDateTimePicker(input);
62617							}
62618							input
62619								.off('open.xdsoft focusin.xdsoft mousedown.xdsoft', initOnActionCallback)
62620								.trigger('open.xdsoft');
62621						}, 100);
62622					});
62623			};
62624
62625		createDateTimePicker = function (input) {
62626			var datetimepicker = $('<div ' + (options.id ? 'id="' + options.id + '"' : '') + ' ' + (options.style ? 'style="' + options.style + '"' : '') + ' class="xdsoft_datetimepicker xdsoft_' + options.theme + ' xdsoft_noselect ' + (options.weeks ? ' xdsoft_showweeks' : '') + options.className + '"></div>'),
62627				xdsoft_copyright = $('<div class="xdsoft_copyright"><a target="_blank" href="http://xdsoft.net/jqplugins/datetimepicker/">xdsoft.net</a></div>'),
62628				datepicker = $('<div class="xdsoft_datepicker active"></div>'),
62629				mounth_picker = $('<div class="xdsoft_mounthpicker"><button type="button" class="xdsoft_prev"></button><button type="button" class="xdsoft_today_button"></button>' +
62630					'<div class="xdsoft_label xdsoft_month"><span></span><i></i></div>' +
62631					'<div class="xdsoft_label xdsoft_year"><span></span><i></i></div>' +
62632					'<button type="button" class="xdsoft_next"></button></div>'),
62633				calendar = $('<div class="xdsoft_calendar"></div>'),
62634				timepicker = $('<div class="xdsoft_timepicker active"><button type="button" class="xdsoft_prev"></button><div class="xdsoft_time_box"></div><button type="button" class="xdsoft_next"></button></div>'),
62635				timeboxparent = timepicker.find('.xdsoft_time_box').eq(0),
62636				timebox = $('<div class="xdsoft_time_variant"></div>'),
62637				/*scrollbar = $('<div class="xdsoft_scrollbar"></div>'),
62638				scroller = $('<div class="xdsoft_scroller"></div>'),*/
62639				monthselect = $('<div class="xdsoft_select xdsoft_monthselect"><div></div></div>'),
62640				yearselect = $('<div class="xdsoft_select xdsoft_yearselect"><div></div></div>'),
62641				triggerAfterOpen = false,
62642				XDSoft_datetime,
62643				//scroll_element,
62644				xchangeTimer,
62645				timerclick,
62646				current_time_index,
62647				setPos,
62648				timer = 0,
62649				timer1 = 0;
62650
62651			mounth_picker
62652				.find('.xdsoft_month span')
62653					.after(monthselect);
62654			mounth_picker
62655				.find('.xdsoft_year span')
62656					.after(yearselect);
62657
62658			mounth_picker
62659				.find('.xdsoft_month,.xdsoft_year')
62660					.on('mousedown.xdsoft', function (event) {
62661					var select = $(this).find('.xdsoft_select').eq(0),
62662						val = 0,
62663						top = 0,
62664						visible = select.is(':visible'),
62665						items,
62666						i;
62667
62668					mounth_picker
62669						.find('.xdsoft_select')
62670							.hide();
62671					if (_xdsoft_datetime.currentTime) {
62672						val = _xdsoft_datetime.currentTime[$(this).hasClass('xdsoft_month') ? 'getMonth' : 'getFullYear']();
62673					}
62674
62675					select[visible ? 'hide' : 'show']();
62676					for (items = select.find('div.xdsoft_option'), i = 0; i < items.length; i += 1) {
62677						if (items.eq(i).data('value') === val) {
62678							break;
62679						} else {
62680							top += items[0].offsetHeight;
62681						}
62682					}
62683
vendor: 2,857 bytes, lines 62684-62772
62684					select.xdsoftScroller(top / (select.children()[0].offsetHeight - (select[0].clientHeight)));
62685					event.stopPropagation();
62686					return false;
62687				});
62688
62689			mounth_picker
62690				.find('.xdsoft_select')
62691					.xdsoftScroller()
62692				.on('mousedown.xdsoft', function (event) {
62693					event.stopPropagation();
62694					event.preventDefault();
62695				})
62696				.on('mousedown.xdsoft', '.xdsoft_option', function (event) {
62697					var year = _xdsoft_datetime.currentTime.getFullYear();
62698					if (_xdsoft_datetime && _xdsoft_datetime.currentTime) {
62699						_xdsoft_datetime.currentTime[$(this).parent().parent().hasClass('xdsoft_monthselect') ? 'setMonth' : 'setFullYear']($(this).data('value'));
62700					}
62701
62702					$(this).parent().parent().hide();
62703
62704					datetimepicker.trigger('xchange.xdsoft');
62705					if (options.onChangeMonth && $.isFunction(options.onChangeMonth)) {
62706						options.onChangeMonth.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
62707					}
62708
62709					if (year !== _xdsoft_datetime.currentTime.getFullYear() && $.isFunction(options.onChangeYear)) {
62710						options.onChangeYear.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
62711					}
62712				});
62713
62714			datetimepicker.setOptions = function (_options) {
62715				options = $.extend(true, {}, options, _options);
62716
62717				if (_options.allowTimes && $.isArray(_options.allowTimes) && _options.allowTimes.length) {
62718					options.allowTimes = $.extend(true, [], _options.allowTimes);
62719				}
62720
62721				if (_options.weekends && $.isArray(_options.weekends) && _options.weekends.length) {
62722					options.weekends = $.extend(true, [], _options.weekends);
62723				}
62724
62725				if (_options.disabledDates && $.isArray(_options.disabledDates) && _options.disabledDates.length) {
62726                    options.disabledDates = $.extend(true, [], _options.disabledDates);
62727                }
62728
62729				if ((options.open || options.opened) && (!options.inline)) {
62730					input.trigger('open.xdsoft');
62731				}
62732
62733				if (options.inline) {
62734					triggerAfterOpen = true;
62735					datetimepicker.addClass('xdsoft_inline');
62736					input.after(datetimepicker).hide();
62737				}
62738
62739				if (options.inverseButton) {
62740					options.next = 'xdsoft_prev';
62741					options.prev = 'xdsoft_next';
62742				}
62743
62744				if (options.datepicker) {
62745					datepicker.addClass('active');
62746				} else {
62747					datepicker.removeClass('active');
62748				}
62749
62750				if (options.timepicker) {
62751					timepicker.addClass('active');
62752				} else {
62753					timepicker.removeClass('active');
62754				}
62755
62756				if (options.value) {
62757					if (input && input.val) {
62758						input.val(options.value);
62759					}
62760					_xdsoft_datetime.setCurrentTime(options.value);
62761				}
62762
62763				if (isNaN(options.dayOfWeekStart)) {
62764					options.dayOfWeekStart = 0;
62765				} else {
62766					options.dayOfWeekStart = parseInt(options.dayOfWeekStart, 10) % 7;
62767				}
62768
62769				if (!options.timepickerScrollbar) {
62770					timeboxparent.xdsoftScroller('hide');
62771				}
62772
62773				if (options.minDate && /^-(.*)$/.test(options.minDate)) {
62774					options.minDate = _xdsoft_datetime.strToDateTime(options.minDate).dateFormat(options.formatDate);
62775				}
62776
62777				if (options.maxDate &&  /^\+(.*)$/.test(options.maxDate)) {
62778					options.maxDate = _xdsoft_datetime.strToDateTime(options.maxDate).dateFormat(options.formatDate);
62779				}
62780
62781				mounth_picker
62782					.find('.xdsoft_today_button')
62783						.css('visibility', !options.todayButton ? 'hidden' : 'visible');
62784
62785				if (options.mask) {
62786					var e,
62787						getCaretPos = function (input) {
62788							try {
62789								if (document.selection && document.selection.createRange) {
62790									var range = document.selection.createRange();
62791									return range.getBookmark().charCodeAt(2) - 2;
62792								}
62793								if (input.setSelectionRange) {
62794									return input.selectionStart;
62795								}
62796							} catch (e) {
62797								return 0;
62798							}
62799						},
62800						setCaretPos = function (node, pos) {
62801							node = (typeof node === "string" || node instanceof String) ? document.getElementById(node) : node;
62802							if (!node) {
62803								return false;
62804							}
62805							if (node.createTextRange) {
62806								var textRange = node.createTextRange();
62807								textRange.collapse(true);
62808								textRange.moveEnd('character', pos);
62809								textRange.moveStart('character', pos);
62810								textRange.select();
62811								return true;
62812							}
62813							if (node.setSelectionRange) {
62814								node.setSelectionRange(pos, pos);
62815								return true;
62816							}
62817							return false;
62818						},
62819						isValidValue = function (mask, value) {
62820							var reg = mask
62821								.replace(/([\[\]\/\{\}\(\)\-\.\+]{1})/g, '\\$1')
62822								.replace(/_/g, '{digit+}')
62823								.replace(/([0-9]{1})/g, '{digit$1}')
62824								.replace(/\{digit([0-9]{1})\}/g, '[0-$1_]{1}')
62825								.replace(/\{digit[\+]\}/g, '[0-9_]{1}');
62826							return (new RegExp(reg)).test(value);
62827						};
62828					input.off('keydown.xdsoft');
62829
62830					if (options.mask === true) {
62831						options.mask = options.format
62832							.replace(/Y/g, '9999')
62833							.replace(/F/g, '9999')
62834							.replace(/m/g, '19')
62835							.replace(/d/g, '39')
62836							.replace(/H/g, '29')
62837							.replace(/i/g, '59')
62838							.replace(/s/g, '59');
62839					}
62840
62841					if ($.type(options.mask) === 'string') {
62842						if (!isValidValue(options.mask, input.val())) {
62843							input.val(options.mask.replace(/[0-9]/g, '_'));
62844						}
62845
62846						input.on('keydown.xdsoft', function (event) {
62847							var val = this.value,
62848								key = event.which,
62849								pos,
62850								digit;
62851
62852							if (((key >= KEY0 && key <= KEY9) || (key >= _KEY0 && key <= _KEY9)) || (key === BACKSPACE || key === DEL)) {
62853								pos = getCaretPos(this);
62854								digit = (key !== BACKSPACE && key !== DEL) ? String.fromCharCode((_KEY0 <= key && key <= _KEY9) ? key - KEY0 : key) : '_';
62855
62856								if ((key === BACKSPACE || key === DEL) && pos) {
62857									pos -= 1;
62858									digit = '_';
62859								}
62860
62861								while (/[^0-9_]/.test(options.mask.substr(pos, 1)) && pos < options.mask.length && pos > 0) {
62862									pos += (key === BACKSPACE || key === DEL) ? -1 : 1;
62863								}
62864
62865								val = val.substr(0, pos) + digit + val.substr(pos + 1);
62866								if ($.trim(val) === '') {
62867									val = options.mask.replace(/[0-9]/g, '_');
62868								} else {
62869									if (pos === options.mask.length) {
62870										event.preventDefault();
62871										return false;
62872									}
62873								}
62874
62875								pos += (key === BACKSPACE || key === DEL) ? 0 : 1;
62876								while (/[^0-9_]/.test(options.mask.substr(pos, 1)) && pos < options.mask.length && pos > 0) {
62877									pos += (key === BACKSPACE || key === DEL) ? -1 : 1;
62878								}
62879
62880								if (isValidValue(options.mask, val)) {
62881									this.value = val;
62882									setCaretPos(this, pos);
62883								} else if ($.trim(val) === '') {
62884									this.value = options.mask.replace(/[0-9]/g, '_');
62885								} else {
62886									input.trigger('error_input.xdsoft');
62887								}
62888							} else {
62889								if (([AKEY, CKEY, VKEY, ZKEY, YKEY].indexOf(key) !== -1 && ctrlDown) || [ESC, ARROWUP, ARROWDOWN, ARROWLEFT, ARROWRIGHT, F5, CTRLKEY, TAB, ENTER].indexOf(key) !== -1) {
62890									return true;
62891								}
62892							}
62893
62894							event.preventDefault();
62895							return false;
62896						});
62897					}
62898				}
62899				if (options.validateOnBlur) {
62900					input
62901						.off('blur.xdsoft')
62902						.on('blur.xdsoft', function () {
62903							if (options.allowBlank && !$.trim($(this).val()).length) {
62904								$(this).val(null);
62905								datetimepicker.data('xdsoft_datetime').empty();
62906							} else if (!Date.parseDate($(this).val(), options.format)) {
62907								$(this).val((_xdsoft_datetime.now()).dateFormat(options.format));
62908								datetimepicker.data('xdsoft_datetime').setCurrentTime($(this).val());
62909							} else {
62910								datetimepicker.data('xdsoft_datetime').setCurrentTime($(this).val());
62911							}
62912							datetimepicker.trigger('changedatetime.xdsoft');
62913						});
62914				}
62915				options.dayOfWeekStartPrev = (options.dayOfWeekStart === 0) ? 6 : options.dayOfWeekStart - 1;
62916
62917				datetimepicker
62918					.trigger('xchange.xdsoft')
62919					.trigger('afterOpen.xdsoft');
62920			};
62921
62922			datetimepicker
62923				.data('options', options)
62924				.on('mousedown.xdsoft', function (event) {
62925					event.stopPropagation();
62926					event.preventDefault();
62927					yearselect.hide();
62928					monthselect.hide();
62929					return false;
62930				});
62931
62932			//scroll_element = timepicker.find('.xdsoft_time_box');
62933			timeboxparent.append(timebox);
62934			timeboxparent.xdsoftScroller();
62935
62936			datetimepicker.on('afterOpen.xdsoft', function () {
62937				timeboxparent.xdsoftScroller();
62938			});
62939
62940			datetimepicker
62941				.append(datepicker)
62942				.append(timepicker);
62943
62944			if (options.withoutCopyright !== true) {
62945				datetimepicker
62946					.append(xdsoft_copyright);
62947			}
62948
62949			datepicker
62950				.append(mounth_picker)
62951				.append(calendar);
62952
62953			$(options.parentID)
62954				.append(datetimepicker);
62955
62956			XDSoft_datetime = function () {
62957				var _this = this;
62958				_this.now = function (norecursion) {
62959					var d = new Date(),
62960						date,
62961						time;
62962
62963					if (!norecursion && options.defaultDate) {
62964						date = _this.strToDate(options.defaultDate);
62965						d.setFullYear(date.getFullYear());
62966						d.setMonth(date.getMonth());
62967						d.setDate(date.getDate());
62968					}
62969
62970					if (options.yearOffset) {
62971						d.setFullYear(d.getFullYear() + options.yearOffset);
62972					}
62973
62974					if (!norecursion && options.defaultTime) {
62975						time = _this.strtotime(options.defaultTime);
62976						d.setHours(time.getHours());
62977						d.setMinutes(time.getMinutes());
62978					}
62979
62980					return d;
62981				};
62982
62983				_this.isValidDate = function (d) {
62984					if (Object.prototype.toString.call(d) !== "[object Date]") {
62985						return false;
62986					}
62987					return !isNaN(d.getTime());
62988				};
62989
62990				_this.setCurrentTime = function (dTime) {
62991					_this.currentTime = (typeof dTime === 'string') ? _this.strToDateTime(dTime) : _this.isValidDate(dTime) ? dTime : _this.now();
62992					datetimepicker.trigger('xchange.xdsoft');
62993				};
62994
62995				_this.empty = function () {
62996					_this.currentTime = null;
62997				};
62998
62999				_this.getCurrentTime = function (dTime) {
63000					return _this.currentTime;
63001				};
63002
63003				_this.nextMonth = function () {
63004					var month = _this.currentTime.getMonth() + 1,
63005						year;
63006					if (month === 12) {
63007						_this.currentTime.setFullYear(_this.currentTime.getFullYear() + 1);
63008						month = 0;
63009					}
63010
63011					year = _this.currentTime.getFullYear();
63012
63013					_this.currentTime.setDate(
63014						Math.min(
63015							new Date(_this.currentTime.getFullYear(), month + 1, 0).getDate(),
63016							_this.currentTime.getDate()
63017						)
63018					);
63019					_this.currentTime.setMonth(month);
63020
63021					if (options.onChangeMonth && $.isFunction(options.onChangeMonth)) {
63022						options.onChangeMonth.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
63023					}
63024
63025					if (year !== _this.currentTime.getFullYear() && $.isFunction(options.onChangeYear)) {
63026						options.onChangeYear.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
63027					}
63028
63029					datetimepicker.trigger('xchange.xdsoft');
63030					return month;
63031				};
63032
63033				_this.prevMonth = function () {
63034					var month = _this.currentTime.getMonth() - 1;
63035					if (month === -1) {
63036						_this.currentTime.setFullYear(_this.currentTime.getFullYear() - 1);
63037						month = 11;
63038					}
63039					_this.currentTime.setDate(
63040						Math.min(
63041							new Date(_this.currentTime.getFullYear(), month + 1, 0).getDate(),
63042							_this.currentTime.getDate()
63043						)
63044					);
63045					_this.currentTime.setMonth(month);
63046					if (options.onChangeMonth && $.isFunction(options.onChangeMonth)) {
63047						options.onChangeMonth.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
63048					}
63049					datetimepicker.trigger('xchange.xdsoft');
63050					return month;
63051				};
63052
63053				_this.getWeekOfYear = function (datetime) {
63054					var onejan = new Date(datetime.getFullYear(), 0, 1);
63055					return Math.ceil((((datetime - onejan) / 86400000) + onejan.getDay() + 1) / 7);
63056				};
63057
63058				_this.strToDateTime = function (sDateTime) {
63059					var tmpDate = [], timeOffset, currentTime;
63060
63061					if (sDateTime && sDateTime instanceof Date && _this.isValidDate(sDateTime)) {
63062						return sDateTime;
63063					}
63064
63065					tmpDate = /^(\+|\-)(.*)$/.exec(sDateTime);
63066					if (tmpDate) {
63067						tmpDate[2] = Date.parseDate(tmpDate[2], options.formatDate);
63068					}
63069					if (tmpDate  && tmpDate[2]) {
63070						timeOffset = tmpDate[2].getTime() - (tmpDate[2].getTimezoneOffset()) * 60000;
63071						currentTime = new Date((_xdsoft_datetime.now()).getTime() + parseInt(tmpDate[1] + '1', 10) * timeOffset);
63072					} else {
63073						currentTime = sDateTime ? Date.parseDate(sDateTime, options.format) : _this.now();
63074					}
63075
63076					if (!_this.isValidDate(currentTime)) {
63077						currentTime = _this.now();
63078					}
63079
63080					return currentTime;
63081				};
63082
63083				_this.strToDate = function (sDate) {
63084					if (sDate && sDate instanceof Date && _this.isValidDate(sDate)) {
63085						return sDate;
63086					}
63087
63088					var currentTime = sDate ? Date.parseDate(sDate, options.formatDate) : _this.now(true);
63089					if (!_this.isValidDate(currentTime)) {
63090						currentTime = _this.now(true);
63091					}
63092					return currentTime;
63093				};
63094
63095				_this.strtotime = function (sTime) {
63096					if (sTime && sTime instanceof Date && _this.isValidDate(sTime)) {
63097						return sTime;
63098					}
63099					var currentTime = sTime ? Date.parseDate(sTime, options.formatTime) : _this.now(true);
63100					if (!_this.isValidDate(currentTime)) {
63101						currentTime = _this.now(true);
63102					}
63103					return currentTime;
63104				};
63105
63106				_this.str = function () {
63107					return _this.currentTime.dateFormat(options.format);
63108				};
63109				_this.currentTime = this.now();
63110			};
63111
63112			_xdsoft_datetime = new XDSoft_datetime();
63113
63114			mounth_picker
63115				.find('.xdsoft_today_button')
63116				.on('mousedown.xdsoft', function () {
63117					datetimepicker.data('changed', true);
63118					_xdsoft_datetime.setCurrentTime(0);
63119					datetimepicker.trigger('afterOpen.xdsoft');
63120				}).on('dblclick.xdsoft', function () {
63121					input.val(_xdsoft_datetime.str());
63122					datetimepicker.trigger('close.xdsoft');
63123				});
vendor: 5,489 bytes, lines 63124-63282
63124			mounth_picker
63125				.find('.xdsoft_prev,.xdsoft_next')
63126				.on('mousedown.xdsoft', function () {
63127					var $this = $(this),
63128						timer = 0,
63129						stop = false;
63130
63131					(function arguments_callee1(v) {
63132						var month =  _xdsoft_datetime.currentTime.getMonth();
63133						if ($this.hasClass(options.next)) {
63134							_xdsoft_datetime.nextMonth();
63135						} else if ($this.hasClass(options.prev)) {
63136							_xdsoft_datetime.prevMonth();
63137						}
63138						if (options.monthChangeSpinner) {
63139							if (!stop) {
63140								timer = setTimeout(arguments_callee1, v || 100);
63141							}
63142						}
63143					}(500));
63144
63145					$([document.body, window]).on('mouseup.xdsoft', function arguments_callee2() {
63146						clearTimeout(timer);
63147						stop = true;
63148						$([document.body, window]).off('mouseup.xdsoft', arguments_callee2);
63149					});
63150				});
63151
63152			timepicker
63153				.find('.xdsoft_prev,.xdsoft_next')
63154				.on('mousedown.xdsoft', function () {
63155					var $this = $(this),
63156						timer = 0,
63157						stop = false,
63158						period = 110;
63159					(function arguments_callee4(v) {
63160						var pheight = timeboxparent[0].clientHeight,
63161							height = timebox[0].offsetHeight,
63162							top = Math.abs(parseInt(timebox.css('marginTop'), 10));
63163						if ($this.hasClass(options.next) && (height - pheight) - options.timeHeightInTimePicker >= top) {
63164							timebox.css('marginTop', '-' + (top + options.timeHeightInTimePicker) + 'px');
63165						} else if ($this.hasClass(options.prev) && top - options.timeHeightInTimePicker >= 0) {
63166							timebox.css('marginTop', '-' + (top - options.timeHeightInTimePicker) + 'px');
63167						}
63168						timeboxparent.trigger('scroll_element.xdsoft_scroller', [Math.abs(parseInt(timebox.css('marginTop'), 10) / (height - pheight))]);
63169						period = (period > 10) ? 10 : period - 10;
63170						if (!stop) {
63171							timer = setTimeout(arguments_callee4, v || period);
63172						}
63173					}(500));
63174					$([document.body, window]).on('mouseup.xdsoft', function arguments_callee5() {
63175						clearTimeout(timer);
63176						stop = true;
63177						$([document.body, window])
63178							.off('mouseup.xdsoft', arguments_callee5);
63179					});
63180				});
63181
63182			xchangeTimer = 0;
63183			// base handler - generating a calendar and timepicker
63184			datetimepicker
63185				.on('xchange.xdsoft', function (event) {
63186					clearTimeout(xchangeTimer);
63187					xchangeTimer = setTimeout(function () {
63188						var table =	'',
63189							start = new Date(_xdsoft_datetime.currentTime.getFullYear(), _xdsoft_datetime.currentTime.getMonth(), 1, 12, 0, 0),
63190							i = 0,
63191							j,
63192							today = _xdsoft_datetime.now(),
63193							maxDate = false,
63194							minDate = false,
63195							d,
63196							y,
63197							m,
63198							w,
63199							classes = [],
63200							customDateSettings,
63201							newRow = true,
63202							time = '',
63203							h = '',
63204							line_time;
63205
63206						while (start.getDay() !== options.dayOfWeekStart) {
63207							start.setDate(start.getDate() - 1);
63208						}
63209
63210						table += '<table><thead><tr>';
63211
63212						if (options.weeks) {
63213							table += '<th></th>';
63214						}
63215
63216						for (j = 0; j < 7; j += 1) {
63217							table += '<th>' + options.i18n[options.lang].dayOfWeek[(j + options.dayOfWeekStart) % 7] + '</th>';
63218						}
63219
63220						table += '</tr></thead>';
63221						table += '<tbody>';
63222
63223						if (options.maxDate !== false) {
63224							maxDate = _xdsoft_datetime.strToDate(options.maxDate);
63225							maxDate = new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate(), 23, 59, 59, 999);
63226						}
63227
63228						if (options.minDate !== false) {
63229							minDate = _xdsoft_datetime.strToDate(options.minDate);
63230							minDate = new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate());
63231						}
63232
63233						while (i < _xdsoft_datetime.currentTime.countDaysInMonth() || start.getDay() !== options.dayOfWeekStart || _xdsoft_datetime.currentTime.getMonth() === start.getMonth()) {
63234							classes = [];
63235							i += 1;
63236
63237							d = start.getDate();
63238							y = start.getFullYear();
63239							m = start.getMonth();
63240							w = _xdsoft_datetime.getWeekOfYear(start);
63241
63242							classes.push('xdsoft_date');
63243
63244							if (options.beforeShowDay && $.isFunction(options.beforeShowDay.call)) {
63245								customDateSettings = options.beforeShowDay.call(datetimepicker, start);
63246							} else {
63247								customDateSettings = null;
63248							}
63249
63250							if ((maxDate !== false && start > maxDate) || (minDate !== false && start < minDate) || (customDateSettings && customDateSettings[0] === false)) {
63251								classes.push('xdsoft_disabled');
63252							} else if (options.disabledDates.indexOf(start.dateFormat(options.formatDate)) !== -1) {
63253								classes.push('xdsoft_disabled');
63254							}
63255
63256							if (customDateSettings && customDateSettings[1] !== "") {
63257								classes.push(customDateSettings[1]);
63258							}
63259
63260							if (_xdsoft_datetime.currentTime.getMonth() !== m) {
63261								classes.push('xdsoft_other_month');
63262							}
63263
63264							if ((options.defaultSelect || datetimepicker.data('changed')) && _xdsoft_datetime.currentTime.dateFormat(options.formatDate) === start.dateFormat(options.formatDate)) {
63265								classes.push('xdsoft_current');
63266							}
63267
63268							if (today.dateFormat(options.formatDate) === start.dateFormat(options.formatDate)) {
63269								classes.push('xdsoft_today');
63270							}
63271
63272							if (start.getDay() === 0 || start.getDay() === 6 || options.weekends.indexOf(start.dateFormat(options.formatDate)) === -1) {
63273								classes.push('xdsoft_weekend');
63274							}
63275
63276							if (options.beforeShowDay && $.isFunction(options.beforeShowDay)) {
63277								classes.push(options.beforeShowDay(start));
63278							}
63279
63280							if (newRow) {
63281								table += '<tr>';
63282								newRow = false;
63283								if (options.weeks) {
63284									table += '<th>' + w + '</th>';
63285								}
63286							}
63287
63288							table += '<td data-date="' + d + '" data-month="' + m + '" data-year="' + y + '"' + ' class="xdsoft_date xdsoft_day_of_week' + start.getDay() + ' ' + classes.join(' ') + '">' +
63289										'<div>' + d + '</div>' +
63290									'</td>';
63291
63292							if (start.getDay() === options.dayOfWeekStartPrev) {
63293								table += '</tr>';
63294								newRow = true;
63295							}
63296
63297							start.setDate(d + 1);
63298						}
63299						table += '</tbody></table>';
63300
63301						calendar.html(table);
63302
63303						mounth_picker.find('.xdsoft_label span').eq(0).text(options.i18n[options.lang].months[_xdsoft_datetime.currentTime.getMonth()]);
63304						mounth_picker.find('.xdsoft_label span').eq(1).text(_xdsoft_datetime.currentTime.getFullYear());
63305
63306						// generate timebox
63307						time = '';
63308						h = '';
63309						m = '';
63310						line_time = function line_time(h, m) {
63311							var now = _xdsoft_datetime.now();
63312							now.setHours(h);
63313							h = parseInt(now.getHours(), 10);
63314							now.setMinutes(m);
63315							m = parseInt(now.getMinutes(), 10);
63316
63317							classes = [];
63318							if ((options.maxTime !== false && _xdsoft_datetime.strtotime(options.maxTime).getTime() < now.getTime()) || (options.minTime !== false && _xdsoft_datetime.strtotime(options.minTime).getTime() > now.getTime())) {
63319								classes.push('xdsoft_disabled');
63320							}
63321							if ((options.initTime || options.defaultSelect || datetimepicker.data('changed')) && parseInt(_xdsoft_datetime.currentTime.getHours(), 10) === parseInt(h, 10) && (options.step > 59 || Math[options.roundTime](_xdsoft_datetime.currentTime.getMinutes() / options.step) * options.step === parseInt(m, 10))) {
63322								if (options.defaultSelect || datetimepicker.data('changed')) {
63323									classes.push('xdsoft_current');
63324								} else if (options.initTime) {
63325									classes.push('xdsoft_init_time');
63326								}
63327							}
63328							if (parseInt(today.getHours(), 10) === parseInt(h, 10) && parseInt(today.getMinutes(), 10) === parseInt(m, 10)) {
63329								classes.push('xdsoft_today');
63330							}
63331							time += '<div class="xdsoft_time ' + classes.join(' ') + '" data-hour="' + h + '" data-minute="' + m + '">' + now.dateFormat(options.formatTime) + '</div>';
63332						};
63333
63334						if (!options.allowTimes || !$.isArray(options.allowTimes) || !options.allowTimes.length) {
63335							for (i = 0, j = 0; i < (options.hours12 ? 12 : 24); i += 1) {
63336								for (j = 0; j < 60; j += options.step) {
63337									h = (i < 10 ? '0' : '') + i;
63338									m = (j < 10 ? '0' : '') + j;
63339									line_time(h, m);
63340								}
63341							}
63342						} else {
63343							for (i = 0; i < options.allowTimes.length; i += 1) {
63344								h = _xdsoft_datetime.strtotime(options.allowTimes[i]).getHours();
63345								m = _xdsoft_datetime.strtotime(options.allowTimes[i]).getMinutes();
63346								line_time(h, m);
63347							}
63348						}
63349
63350						timebox.html(time);
63351
63352						opt = '';
63353						i = 0;
63354
63355						for (i = parseInt(options.yearStart, 10) + options.yearOffset; i <= parseInt(options.yearEnd, 10) + options.yearOffset; i += 1) {
63356							opt += '<div class="xdsoft_option ' + (_xdsoft_datetime.currentTime.getFullYear() === i ? 'xdsoft_current' : '') + '" data-value="' + i + '">' + i + '</div>';
63357						}
63358						yearselect.children().eq(0)
63359												.html(opt);
63360
63361						for (i = 0, opt = ''; i <= 11; i += 1) {
63362							opt += '<div class="xdsoft_option ' + (_xdsoft_datetime.currentTime.getMonth() === i ? 'xdsoft_current' : '') + '" data-value="' + i + '">' + options.i18n[options.lang].months[i] + '</div>';
63363						}
63364						monthselect.children().eq(0).html(opt);
63365						$(datetimepicker)
63366							.trigger('generate.xdsoft');
63367					}, 10);
63368					event.stopPropagation();
63369				})
63370				.on('afterOpen.xdsoft', function () {
63371					if (options.timepicker) {
63372						var classType, pheight, height, top;
63373						if (timebox.find('.xdsoft_current').length) {
63374							classType = '.xdsoft_current';
63375						} else if (timebox.find('.xdsoft_init_time').length) {
63376							classType = '.xdsoft_init_time';
63377						}
63378						if (classType) {
63379							pheight = timeboxparent[0].clientHeight;
63380							height = timebox[0].offsetHeight;
63381							top = timebox.find(classType).index() * options.timeHeightInTimePicker + 1;
63382							if ((height - pheight) < top) {
63383								top = height - pheight;
63384							}
63385							timeboxparent.trigger('scroll_element.xdsoft_scroller', [parseInt(top, 10) / (height - pheight)]);
63386						} else {
63387							timeboxparent.trigger('scroll_element.xdsoft_scroller', [0]);
63388						}
63389					}
63390				});
63391
63392			timerclick = 0;
63393			calendar
63394				.on('click.xdsoft', 'td', function (xdevent) {
63395					xdevent.stopPropagation();  // Prevents closing of Pop-ups, Modals and Flyouts in Bootstrap
63396					timerclick += 1;
63397					var $this = $(this),
63398						currentTime = _xdsoft_datetime.currentTime;
63399
63400					if (currentTime === undefined || currentTime === null) {
63401						_xdsoft_datetime.currentTime = _xdsoft_datetime.now();
63402						currentTime = _xdsoft_datetime.currentTime;
63403					}
63404
63405					if ($this.hasClass('xdsoft_disabled')) {
63406						return false;
63407					}
63408
63409					currentTime.setDate(1);
63410					currentTime.setFullYear($this.data('year'));
63411					currentTime.setMonth($this.data('month'));
63412					currentTime.setDate($this.data('date'));
63413
63414					datetimepicker.trigger('select.xdsoft', [currentTime]);
63415
63416					input.val(_xdsoft_datetime.str());
63417					if ((timerclick > 1 || (options.closeOnDateSelect === true || (options.closeOnDateSelect === 0 && !options.timepicker))) && !options.inline) {
63418						datetimepicker.trigger('close.xdsoft');
63419					}
63420
63421					if (options.onSelectDate &&	$.isFunction(options.onSelectDate)) {
63422						options.onSelectDate.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'), xdevent);
63423					}
63424
63425					datetimepicker.data('changed', true);
63426					datetimepicker.trigger('xchange.xdsoft');
63427					datetimepicker.trigger('changedatetime.xdsoft');
63428					setTimeout(function () {
63429						timerclick = 0;
63430					}, 200);
63431				});
63432
63433			timebox
63434				.on('click.xdsoft', 'div', function (xdevent) {
63435					xdevent.stopPropagation();
63436					var $this = $(this),
63437						currentTime = _xdsoft_datetime.currentTime;
63438
63439					if (currentTime === undefined || currentTime === null) {
63440						_xdsoft_datetime.currentTime = _xdsoft_datetime.now();
63441						currentTime = _xdsoft_datetime.currentTime;
63442					}
63443
63444					if ($this.hasClass('xdsoft_disabled')) {
63445						return false;
63446					}
63447					currentTime.setHours($this.data('hour'));
63448					currentTime.setMinutes($this.data('minute'));
63449					datetimepicker.trigger('select.xdsoft', [currentTime]);
63450
63451					datetimepicker.data('input').val(_xdsoft_datetime.str());
63452					if (!options.inline) {
63453						datetimepicker.trigger('close.xdsoft');
63454					}
63455
63456					if (options.onSelectTime && $.isFunction(options.onSelectTime)) {
63457						options.onSelectTime.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'), xdevent);
63458					}
63459					datetimepicker.data('changed', true);
63460					datetimepicker.trigger('xchange.xdsoft');
63461					datetimepicker.trigger('changedatetime.xdsoft');
63462				});
63463
63464
63465			datepicker
63466				.on('mousewheel.xdsoft', function (event) {
63467					if (!options.scrollMonth) {
63468						return true;
63469					}
63470					if (event.deltaY < 0) {
63471						_xdsoft_datetime.nextMonth();
63472					} else {
63473						_xdsoft_datetime.prevMonth();
63474					}
63475					return false;
63476				});
63477
63478			input
63479				.on('mousewheel.xdsoft', function (event) {
63480					if (!options.scrollInput) {
63481						return true;
63482					}
63483					if (!options.datepicker && options.timepicker) {
63484						current_time_index = timebox.find('.xdsoft_current').length ? timebox.find('.xdsoft_current').eq(0).index() : 0;
63485						if (current_time_index + event.deltaY >= 0 && current_time_index + event.deltaY < timebox.children().length) {
63486							current_time_index += event.deltaY;
63487						}
63488						if (timebox.children().eq(current_time_index).length) {
63489							timebox.children().eq(current_time_index).trigger('mousedown');
63490						}
63491						return false;
63492					}
63493					if (options.datepicker && !options.timepicker) {
63494						datepicker.trigger(event, [event.deltaY, event.deltaX, event.deltaY]);
63495						if (input.val) {
63496							input.val(_xdsoft_datetime.str());
63497						}
63498						datetimepicker.trigger('changedatetime.xdsoft');
63499						return false;
63500					}
63501				});
63502
63503			datetimepicker
63504				.on('changedatetime.xdsoft', function (event) {
63505					if (options.onChangeDateTime && $.isFunction(options.onChangeDateTime)) {
63506						var $input = datetimepicker.data('input');
63507						options.onChangeDateTime.call(datetimepicker, _xdsoft_datetime.currentTime, $input, event);
63508						delete options.value;
63509						$input.trigger('change');
63510					}
63511				})
63512				.on('generate.xdsoft', function () {
63513					if (options.onGenerate && $.isFunction(options.onGenerate)) {
63514						options.onGenerate.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'));
63515					}
63516					if (triggerAfterOpen) {
63517						datetimepicker.trigger('afterOpen.xdsoft');
63518						triggerAfterOpen = false;
63519					}
63520				})
63521				.on('click.xdsoft', function (xdevent) {
63522					xdevent.stopPropagation();
63523				});
63524
63525			current_time_index = 0;
63526
63527			setPos = function () {
63528				var offset = datetimepicker.data('input').offset(), top = offset.top + datetimepicker.data('input')[0].offsetHeight - 1, left = offset.left, position = "absolute";
63529				if (options.fixed) {
63530					top -= $(window).scrollTop();
63531					left -= $(window).scrollLeft();
63532					position = "fixed";
63533				} else {
63534					if (top + datetimepicker[0].offsetHeight > $(window).height() + $(window).scrollTop()) {
63535						top = offset.top - datetimepicker[0].offsetHeight + 1;
63536					}
63537					if (top < 0) {
63538						top = 0;
63539					}
63540					if (left + datetimepicker[0].offsetWidth > $(window).width()) {
63541						left = $(window).width() - datetimepicker[0].offsetWidth;
63542					}
63543				}
63544				datetimepicker.css({
63545					left: left,
63546					top: top,
63547					position: position
63548				});
63549			};
63550			datetimepicker
63551				.on('open.xdsoft', function (event) {
63552					var onShow = true;
63553					if (options.onShow && $.isFunction(options.onShow)) {
63554						onShow = options.onShow.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'), event);
63555					}
63556					if (onShow !== false) {
63557						datetimepicker.show();
63558						setPos();
63559						$(window)
63560							.off('resize.xdsoft', setPos)
63561							.on('resize.xdsoft', setPos);
63562
63563						if (options.closeOnWithoutClick) {
63564							$([document.body, window]).on('mousedown.xdsoft', function arguments_callee6() {
63565								datetimepicker.trigger('close.xdsoft');
63566								$([document.body, window]).off('mousedown.xdsoft', arguments_callee6);
63567							});
63568						}
63569					}
63570				})
63571				.on('close.xdsoft', function (event) {
63572					var onClose = true;
63573					mounth_picker
63574						.find('.xdsoft_month,.xdsoft_year')
63575							.find('.xdsoft_select')
63576								.hide();
63577					if (options.onClose && $.isFunction(options.onClose)) {
63578						onClose = options.onClose.call(datetimepicker, _xdsoft_datetime.currentTime, datetimepicker.data('input'), event);
63579					}
63580					if (onClose !== false && !options.opened && !options.inline) {
63581						datetimepicker.hide();
63582					}
63583					event.stopPropagation();
63584				})
63585				.on('toggle.xdsoft', function (event) {
63586					if (datetimepicker.is(':visible')) {
63587						datetimepicker.trigger('close.xdsoft');
63588					} else {
63589						datetimepicker.trigger('open.xdsoft');
63590					}
63591				})
63592				.data('input', input);
63593
63594			timer = 0;
63595			timer1 = 0;
63596
63597			datetimepicker.data('xdsoft_datetime', _xdsoft_datetime);
63598			datetimepicker.setOptions(options);
63599
63600			function getCurrentValue() {
63601
63602				var ct = false, time;
63603
63604				if (options.startDate) {
63605					ct = _xdsoft_datetime.strToDate(options.startDate);
63606				} else {
63607					ct = options.value || ((input && input.val && input.val()) ? input.val() : '');
63608					if (ct) {
63609						ct = _xdsoft_datetime.strToDateTime(ct);
63610					} else if (options.defaultDate) {
63611						ct = _xdsoft_datetime.strToDate(options.defaultDate);
63612						if (options.defaultTime) {
63613							time = _xdsoft_datetime.strtotime(options.defaultTime);
63614							ct.setHours(time.getHours());
63615							ct.setMinutes(time.getMinutes());
63616						}
63617					}
63618				}
63619
63620				if (ct && _xdsoft_datetime.isValidDate(ct)) {
63621					datetimepicker.data('changed', true);
63622				} else {
63623					ct = '';
63624				}
63625
63626				return ct || 0;
63627			}
63628
63629			_xdsoft_datetime.setCurrentTime(getCurrentValue());
63630
63631			input
63632				.data('xdsoft_datetimepicker', datetimepicker)
63633				.on('open.xdsoft focusin.xdsoft mousedown.xdsoft', function (event) {
63634					if (input.is(':disabled') || input.is(':hidden') || !input.is(':visible') || (input.data('xdsoft_datetimepicker').is(':visible') && options.closeOnInputClick)) {
63635						return;
63636					}
63637					clearTimeout(timer);
63638					timer = setTimeout(function () {
63639						if (input.is(':disabled') || input.is(':hidden') || !input.is(':visible')) {
63640							return;
63641						}
63642
63643						triggerAfterOpen = true;
63644						_xdsoft_datetime.setCurrentTime(getCurrentValue());
63645
63646						datetimepicker.trigger('open.xdsoft');
63647					}, 100);
63648				})
63649				.on('keydown.xdsoft', function (event) {
63650					var val = this.value, elementSelector,
63651						key = event.which;
63652					if ([ENTER].indexOf(key) !== -1 && options.enterLikeTab) {
63653						elementSelector = $("input:visible,textarea:visible");
63654						datetimepicker.trigger('close.xdsoft');
63655						elementSelector.eq(elementSelector.index(this) + 1).focus();
63656						return false;
63657					}
63658					if ([TAB].indexOf(key) !== -1) {
63659						datetimepicker.trigger('close.xdsoft');
63660						return true;
63661					}
63662				});
63663		};
63664		destroyDateTimePicker = function (input) {
63665			var datetimepicker = input.data('xdsoft_datetimepicker');
63666			if (datetimepicker) {
63667				datetimepicker.data('xdsoft_datetime', null);
63668				datetimepicker.remove();
63669				input
63670					.data('xdsoft_datetimepicker', null)
63671					.off('.xdsoft');
63672				$(window).off('resize.xdsoft');
63673				$([window, document.body]).off('mousedown.xdsoft');
63674				if (input.unmousewheel) {
63675					input.unmousewheel();
63676				}
63677			}
63678		};
63679		$(document)
63680			.off('keydown.xdsoftctrl keyup.xdsoftctrl')
63681			.on('keydown.xdsoftctrl', function (e) {
63682				if (e.keyCode === CTRLKEY) {
63683					ctrlDown = true;
63684				}
63685			})
63686			.on('keyup.xdsoftctrl', function (e) {
63687				if (e.keyCode === CTRLKEY) {
63688					ctrlDown = false;
63689				}
63690			});
63691		return this.each(function () {
63692			var datetimepicker = $(this).data('xdsoft_datetimepicker');
63693			if (datetimepicker) {
63694				if ($.type(opt) === 'string') {
63695					switch (opt) {
63696					case 'show':
63697						$(this).select().focus();
63698						datetimepicker.trigger('open.xdsoft');
63699						break;
63700					case 'hide':
63701						datetimepicker.trigger('close.xdsoft');
63702						break;
63703					case 'toggle':
63704						datetimepicker.trigger('toggle.xdsoft');
63705						break;
63706					case 'destroy':
63707						destroyDateTimePicker($(this));
63708						break;
63709					case 'reset':
63710						this.value = this.defaultValue;
63711						if (!this.value || !datetimepicker.data('xdsoft_datetime').isValidDate(Date.parseDate(this.value, options.format))) {
63712							datetimepicker.data('changed', false);
63713						}
63714						datetimepicker.data('xdsoft_datetime').setCurrentTime(this.value);
63715						break;
63716					}
63717				} else {
63718					datetimepicker
63719						.setOptions(opt);
63720				}
63721				return 0;
63722			}
63723			if ($.type(opt) !== 'string') {
63724				if (!options.lazyInit || options.open || options.inline) {
63725					createDateTimePicker($(this));
63726				} else {
63727					lazyInit($(this));
63728				}
63729			}
63730		});
63731	};
63732	$.fn.datetimepicker.defaults = default_options;
63733}(jQuery));
63734(function () {
63735
63736/*! Copyright (c) 2013 Brandon Aaron (http://brandon.aaron.sh)
63737 * Licensed under the MIT License (LICENSE.txt).
63738 *
63739 * Version: 3.1.12
63740 *
63741 * Requires: jQuery 1.2.2+
63742 */
63743!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?module.exports=a:a(jQuery)}(function(a){function b(b){var g=b||window.event,h=i.call(arguments,1),j=0,l=0,m=0,n=0,o=0,p=0;if(b=a.event.fix(g),b.type="mousewheel","detail"in g&&(m=-1*g.detail),"wheelDelta"in g&&(m=g.wheelDelta),"wheelDeltaY"in g&&(m=g.wheelDeltaY),"wheelDeltaX"in g&&(l=-1*g.wheelDeltaX),"axis"in g&&g.axis===g.HORIZONTAL_AXIS&&(l=-1*m,m=0),j=0===m?l:m,"deltaY"in g&&(m=-1*g.deltaY,j=m),"deltaX"in g&&(l=g.deltaX,0===m&&(j=-1*l)),0!==m||0!==l){if(1===g.deltaMode){var q=a.data(this,"mousewheel-line-height");j*=q,m*=q,l*=q}else if(2===g.deltaMode){var r=a.data(this,"mousewheel-page-height");j*=r,m*=r,l*=r}if(n=Math.max(Math.abs(m),Math.abs(l)),(!f||f>n)&&(f=n,d(g,n)&&(f/=40)),d(g,n)&&(j/=40,l/=40,m/=40),j=Math[j>=1?"floor":"ceil"](j/f),l=Math[l>=1?"floor":"ceil"](l/f),m=Math[m>=1?"floor":"ceil"](m/f),k.settings.normalizeOffset&&this.getBoundingClientRect){var s=this.getBoundingClientRect();o=b.clientX-s.left,p=b.clientY-s.top}return b.deltaX=l,b.deltaY=m,b.deltaFactor=f,b.offsetX=o,b.offsetY=p,b.deltaMode=0,h.unshift(b,j,l,m),e&&clearTimeout(e),e=setTimeout(c,200),(a.event.dispatch||a.event.handle).apply(this,h)}}function c(){f=null}function d(a,b){return k.settings.adjustOldDeltas&&"mousewheel"===a.type&&b%120===0}var e,f,g=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],h="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],i=Array.prototype.slice;if(a.event.fixHooks)for(var j=g.length;j;)a.event.fixHooks[g[--j]]=a.event.mouseHooks;var k=a.event.special.mousewheel={version:"3.1.12",setup:function(){if(this.addEventListener)for(var c=h.length;c;)this.addEventListener(h[--c],b,!1);else this.onmousewheel=b;a.data(this,"mousewheel-line-height",k.getLineHeight(this)),a.data(this,"mousewheel-page-height",k.getPageHeight(this))},teardown:function(){if(this.removeEventListener)for(var c=h.length;c;)this.removeEventListener(h[--c],b,!1);else this.onmousewheel=null;a.removeData(this,"mousewheel-line-height"),a.removeData(this,"mousewheel-page-height")},getLineHeight:function(b){var c=a(b),d=c["offsetParent"in a.fn?"offsetParent":"parent"]();return d.length||(d=a("body")),parseInt(d.css("fontSize"),10)||parseInt(c.css("fontSize"),10)||16},getPageHeight:function(b){return a(b).height()},settings:{adjustOldDeltas:!0,normalizeOffset:!0}};a.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})});
63744
63745// Parse and Format Library
63746//http://www.xaprb.com/blog/2005/12/12/javascript-closures-for-runtime-efficiency/
63747/*
63748 * Copyright (C) 2004 Baron Schwartz <baron at sequent dot org>
63749 *
63750 * This program is free software; you can redistribute it and/or modify it
63751 * under the terms of the GNU Lesser General Public License as published by the
63752 * Free Software Foundation, version 2.1.
63753 *
63754 * This program is distributed in the hope that it will be useful, but WITHOUT
63755 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
63756 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
63757 * details.
63758 */
63759Date.parseFunctions={count:0};Date.parseRegexes=[];Date.formatFunctions={count:0};Date.prototype.dateFormat=function(b){if(b=="unixtime"){return parseInt(this.getTime()/1000);}if(Date.formatFunctions[b]==null){Date.createNewFormat(b);}var a=Date.formatFunctions[b];return this[a]();};Date.createNewFormat=function(format){var funcName="format"+Date.formatFunctions.count++;Date.formatFunctions[format]=funcName;var code="Date.prototype."+funcName+" = function() {return ";var special=false;var ch="";for(var i=0;i<format.length;++i){ch=format.charAt(i);if(!special&&ch=="\\"){special=true;}else{if(special){special=false;code+="'"+String.escape(ch)+"' + ";}else{code+=Date.getFormatCode(ch);}}}eval(code.substring(0,code.length-3)+";}");};Date.getFormatCode=function(a){switch(a){case"d":return"String.leftPad(this.getDate(), 2, '0') + ";case"D":return"Date.dayNames[this.getDay()].substring(0, 3) + ";case"j":return"this.getDate() + ";case"l":return"Date.dayNames[this.getDay()] + ";case"S":return"this.getSuffix() + ";case"w":return"this.getDay() + ";case"z":return"this.getDayOfYear() + ";case"W":return"this.getWeekOfYear() + ";case"F":return"Date.monthNames[this.getMonth()] + ";case"m":return"String.leftPad(this.getMonth() + 1, 2, '0') + ";case"M":return"Date.monthNames[this.getMonth()].substring(0, 3) + ";case"n":return"(this.getMonth() + 1) + ";case"t":return"this.getDaysInMonth() + ";case"L":return"(this.isLeapYear() ? 1 : 0) + ";case"Y":return"this.getFullYear() + ";case"y":return"('' + this.getFullYear()).substring(2, 4) + ";case"a":return"(this.getHours() < 12 ? 'am' : 'pm') + ";case"A":return"(this.getHours() < 12 ? 'AM' : 'PM') + ";case"g":return"((this.getHours() %12) ? this.getHours() % 12 : 12) + ";case"G":return"this.getHours() + ";case"h":return"String.leftPad((this.getHours() %12) ? this.getHours() % 12 : 12, 2, '0') + ";case"H":return"String.leftPad(this.getHours(), 2, '0') + ";case"i":return"String.leftPad(this.getMinutes(), 2, '0') + ";case"s":return"String.leftPad(this.getSeconds(), 2, '0') + ";case"O":return"this.getGMTOffset() + ";case"T":return"this.getTimezone() + ";case"Z":return"(this.getTimezoneOffset() * -60) + ";default:return"'"+String.escape(a)+"' + ";}};Date.parseDate=function(a,c){if(c=="unixtime"){return new Date(!isNaN(parseInt(a))?parseInt(a)*1000:0);}if(Date.parseFunctions[c]==null){Date.createParser(c);}var b=Date.parseFunctions[c];return Date[b](a);};Date.createParser=function(format){var funcName="parse"+Date.parseFunctions.count++;var regexNum=Date.parseRegexes.length;var currentGroup=1;Date.parseFunctions[format]=funcName;var code="Date."+funcName+" = function(input) {\nvar y = -1, m = -1, d = -1, h = -1, i = -1, s = -1, z = -1;\nvar d = new Date();\ny = d.getFullYear();\nm = d.getMonth();\nd = d.getDate();\nvar results = input.match(Date.parseRegexes["+regexNum+"]);\nif (results && results.length > 0) {";var regex="";var special=false;var ch="";for(var i=0;i<format.length;++i){ch=format.charAt(i);if(!special&&ch=="\\"){special=true;}else{if(special){special=false;regex+=String.escape(ch);}else{obj=Date.formatCodeToRegex(ch,currentGroup);currentGroup+=obj.g;regex+=obj.s;if(obj.g&&obj.c){code+=obj.c;}}}}code+="if (y > 0 && z > 0){\nvar doyDate = new Date(y,0);\ndoyDate.setDate(z);\nm = doyDate.getMonth();\nd = doyDate.getDate();\n}";code+="if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0)\n{return new Date(y, m, d, h, i, s);}\nelse if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0)\n{return new Date(y, m, d, h, i);}\nelse if (y > 0 && m >= 0 && d > 0 && h >= 0)\n{return new Date(y, m, d, h);}\nelse if (y > 0 && m >= 0 && d > 0)\n{return new Date(y, m, d);}\nelse if (y > 0 && m >= 0)\n{return new Date(y, m);}\nelse if (y > 0)\n{return new Date(y);}\n}return null;}";Date.parseRegexes[regexNum]=new RegExp("^"+regex+"$");eval(code);};Date.formatCodeToRegex=function(b,a){switch(b){case"D":return{g:0,c:null,
63759s:"(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)"};case"j":case"d":return{g:1,c:"d = parseInt(results["+a+"], 10);\n",s:"(\\d{1,2})"};case"l":return{g:0,c:null,s:"(?:"+Date.dayNames.join("|")+")"};case"S":return{g:0,c:null,s:"(?:st|nd|rd|th)"};case"w":return{g:0,c:null,s:"\\d"};case"z":return{g:1,c:"z = parseInt(results["+a+"], 10);\n",s:"(\\d{1,3})"};case"W":return{g:0,c:null,s:"(?:\\d{2})"};case"F":return{g:1,c:"m = parseInt(Date.monthNumbers[results["+a+"].substring(0, 3)], 10);\n",s:"("+Date.monthNames.join("|")+")"};case"M":return{g:1,c:"m = parseInt(Date.monthNumbers[results["+a+"]], 10);\n",s:"(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)"};case"n":case"m":return{g:1,c:"m = parseInt(results["+a+"], 10) - 1;\n",s:"(\\d{1,2})"};case"t":return{g:0,c:null,s:"\\d{1,2}"};case"L":return{g:0,c:null,s:"(?:1|0)"};case"Y":return{g:1,c:"y = parseInt(results["+a+"], 10);\n",s:"(\\d{4})"};case"y":return{g:1,c:"var ty = parseInt(results["+a+"], 10);\ny = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n",s:"(\\d{1,2})"};case"a":return{g:1,c:"if (results["+a+"] == 'am') {\nif (h == 12) { h = 0; }\n} else { if (h < 12) { h += 12; }}",s:"(am|pm)"};case"A":return{g:1,c:"if (results["+a+"] == 'AM') {\nif (h == 12) { h = 0; }\n} else { if (h < 12) { h += 12; }}",s:"(AM|PM)"};case"g":case"G":case"h":case"H":return{g:1,c:"h = parseInt(results["+a+"], 10);\n",s:"(\\d{1,2})"};case"i":return{g:1,c:"i = parseInt(results["+a+"], 10);\n",s:"(\\d{2})"};case"s":return{g:1,c:"s = parseInt(results["+a+"], 10);\n",s:"(\\d{2})"};case"O":return{g:0,c:null,s:"[+-]\\d{4}"};case"T":return{g:0,c:null,s:"[A-Z]{3}"};case"Z":return{g:0,c:null,s:"[+-]\\d{1,5}"};default:return{g:0,c:null,s:String.escape(b)};}};Date.prototype.getTimezone=function(){return this.toString().replace(/^.*? ([A-Z]{3}) [0-9]{4}.*$/,"$1").replace(/^.*?\(([A-Z])[a-z]+ ([A-Z])[a-z]+ ([A-Z])[a-z]+\)$/,"$1$2$3");};Date.prototype.getGMTOffset=function(){return(this.getTimezoneOffset()>0?"-":"+")+String.leftPad(Math.floor(Math.abs(this.getTimezoneOffset())/60),2,"0")+String.leftPad(Math.abs(this.getTimezoneOffset())%60,2,"0");};Date.prototype.getDayOfYear=function(){var a=0;Date.daysInMonth[1]=this.isLeapYear()?29:28;for(var b=0;b<this.getMonth();++b){a+=Date.daysInMonth[b];}return a+this.getDate();};Date.prototype.getWeekOfYear=function(){var b=this.getDayOfYear()+(4-this.getDay());var a=new Date(this.getFullYear(),0,1);var c=(7-a.getDay()+4);return String.leftPad(Math.ceil((b-c)/7)+1,2,"0");};Date.prototype.isLeapYear=function(){var a=this.getFullYear();return((a&3)==0&&(a%100||(a%400==0&&a)));};Date.prototype.getFirstDayOfMonth=function(){var a=(this.getDay()-(this.getDate()-1))%7;return(a<0)?(a+7):a;};Date.prototype.getLastDayOfMonth=function(){var a=(this.getDay()+(Date.daysInMonth[this.getMonth()]-this.getDate()))%7;return(a<0)?(a+7):a;};Date.prototype.getDaysInMonth=function(){Date.daysInMonth[1]=this.isLeapYear()?29:28;return Date.daysInMonth[this.getMonth()];};Date.prototype.getSuffix=function(){switch(this.getDate()){case 1:case 21:case 31:return"st";case 2:case 22:return"nd";case 3:case 23:return"rd";default:return"th";}};String.escape=function(a){return a.replace(/('|\\)/g,"\\$1");};String.leftPad=function(d,b,c){var a=new String(d);if(c==null){c=" ";}while(a.length<b){a=c+a;}return a;};Date.daysInMonth=[31,28,31,30,31,30,31,31,30,31,30,31];Date.monthNames=["January","February","March","April","May","June","July","August","September","October","November","December"];Date.dayNames=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];Date.y2kYear=50;Date.monthNumbers={Jan:0,Feb:1,Mar:2,Apr:3,May:4,Jun:5,Jul:6,Aug:7,Sep:8,Oct:9,Nov:10,Dec:11};Date.patterns={ISO8601LongPattern:"Y-m-d H:i:s",ISO8601ShortPattern:"Y-m-d",ShortDatePattern:"n/j/Y",LongDatePattern:"l, F d, Y",FullDateTimePattern:"l, F d, Y g:i:s A",MonthDayPattern:"F d",ShortTimePattern:"g:i A",LongTimePattern:"g:i:s A",SortableDateTimePattern:"Y-m-d\\TH:i:s",UniversalSortableDateTimePattern:"Y-m-d H:i:sO",YearMonthPattern:"F, Y"};
63760}());
63761/*!
63762 * Select2 4.0.13
vendor: 17,402 bytes, lines 63762-64261
63762
63763 * https://select2.github.io
63764 *
63765 * Released under the MIT license
63766 * https://github.com/select2/select2/blob/master/LICENSE.md
63767 */
63768;(function (factory) {
63769  if (typeof define === 'function' && define.amd) {
63770    // AMD. Register as an anonymous module.
63771    define(['jquery'], factory);
63772  } else if (typeof module === 'object' && module.exports) {
63773    // Node/CommonJS
63774    module.exports = function (root, jQuery) {
63775      if (jQuery === undefined) {
63776        // require('jQuery') returns a factory that requires window to
63777        // build a jQuery instance, we normalize how we use modules
63778        // that require this pattern but the window provided is a noop
63779        // if it's defined (how jquery works)
63780        if (typeof window !== 'undefined') {
63781          jQuery = require('jquery');
63782        }
63783        else {
63784          jQuery = require('jquery')(root);
63785        }
63786      }
63787      factory(jQuery);
63788      return jQuery;
63789    };
63790  } else {
63791    // Browser globals
63792    factory(jQuery);
63793  }
63794} (function (jQuery) {
63795  // This is needed so we can catch the AMD loader configuration and use it
63796  // The inner file should be wrapped (by `banner.start.js`) in a function that
63797  // returns the AMD loader references.
63798  var S2 =(function () {
63799  // Restore the Select2 AMD loader so it can be used
63800  // Needed mostly in the language files, where the loader is not inserted
63801  if (jQuery && jQuery.fn && jQuery.fn.select2 && jQuery.fn.select2.amd) {
63802    var S2 = jQuery.fn.select2.amd;
63803  }
63804var S2;(function () { if (!S2 || !S2.requirejs) {
63805if (!S2) { S2 = {}; } else { require = S2; }
63806/**
63807 * @license almond 0.3.3 Copyright jQuery Foundation and other contributors.
63808 * Released under MIT license, http://github.com/requirejs/almond/LICENSE
63809 */
63810//Going sloppy to avoid 'use strict' string cost, but strict practices should
63811//be followed.
63812/*global setTimeout: false */
63813
63814var requirejs, require, define;
63815(function (undef) {
63816    var main, req, makeMap, handlers,
63817        defined = {},
63818        waiting = {},
63819        config = {},
63820        defining = {},
63821        hasOwn = Object.prototype.hasOwnProperty,
63822        aps = [].slice,
63823        jsSuffixRegExp = /\.js$/;
63824
63825    function hasProp(obj, prop) {
63826        return hasOwn.call(obj, prop);
63827    }
63828
63829    /**
63830     * Given a relative module name, like ./something, normalize it to
63831     * a real name that can be mapped to a path.
63832     * @param {String} name the relative name
63833     * @param {String} baseName a real name that the name arg is relative
63834     * to.
63835     * @returns {String} normalized name
63836     */
63837    function normalize(name, baseName) {
63838        var nameParts, nameSegment, mapValue, foundMap, lastIndex,
63839            foundI, foundStarMap, starI, i, j, part, normalizedBaseParts,
63840            baseParts = baseName && baseName.split("/"),
63841            map = config.map,
63842            starMap = (map && map['*']) || {};
63843
63844        //Adjust any relative paths.
63845        if (name) {
63846            name = name.split('/');
63847            lastIndex = name.length - 1;
63848
63849            // If wanting node ID compatibility, strip .js from end
63850            // of IDs. Have to do this here, and not in nameToUrl
63851            // because node allows either .js or non .js to map
63852            // to same file.
63853            if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
63854                name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
63855            }
63856
63857            // Starts with a '.' so need the baseName
63858            if (name[0].charAt(0) === '.' && baseParts) {
63859                //Convert baseName to array, and lop off the last part,
63860                //so that . matches that 'directory' and not name of the baseName's
63861                //module. For instance, baseName of 'one/two/three', maps to
63862                //'one/two/three.js', but we want the directory, 'one/two' for
63863                //this normalization.
63864                normalizedBaseParts = baseParts.slice(0, baseParts.length - 1);
63865                name = normalizedBaseParts.concat(name);
63866            }
63867
63868            //start trimDots
63869            for (i = 0; i < name.length; i++) {
63870                part = name[i];
63871                if (part === '.') {
63872                    name.splice(i, 1);
63873                    i -= 1;
63874                } else if (part === '..') {
63875                    // If at the start, or previous value is still ..,
63876                    // keep them so that when converted to a path it may
63877                    // still work when converted to a path, even though
63878                    // as an ID it is less than ideal. In larger point
63879                    // releases, may be better to just kick out an error.
63880                    if (i === 0 || (i === 1 && name[2] === '..') || name[i - 1] === '..') {
63881                        continue;
63882                    } else if (i > 0) {
63883                        name.splice(i - 1, 2);
63884                        i -= 2;
63885                    }
63886                }
63887            }
63888            //end trimDots
63889
63890            name = name.join('/');
63891        }
63892
63893        //Apply map config if available.
63894        if ((baseParts || starMap) && map) {
63895            nameParts = name.split('/');
63896
63897            for (i = nameParts.length; i > 0; i -= 1) {
63898                nameSegment = nameParts.slice(0, i).join("/");
63899
63900                if (baseParts) {
63901                    //Find the longest baseName segment match in the config.
63902                    //So, do joins on the biggest to smallest lengths of baseParts.
63903                    for (j = baseParts.length; j > 0; j -= 1) {
63904                        mapValue = map[baseParts.slice(0, j).join('/')];
63905
63906                        //baseName segment has  config, find if it has one for
63907                        //this name.
63908                        if (mapValue) {
63909                            mapValue = mapValue[nameSegment];
63910                            if (mapValue) {
63911                                //Match, update name to the new value.
63912                                foundMap = mapValue;
63913                                foundI = i;
63914                                break;
63915                            }
63916                        }
63917                    }
63918                }
63919
63920                if (foundMap) {
63921                    break;
63922                }
63923
63924                //Check for a star map match, but just hold on to it,
63925                //if there is a shorter segment match later in a matching
63926                //config, then favor over this star map.
63927                if (!foundStarMap && starMap && starMap[nameSegment]) {
63928                    foundStarMap = starMap[nameSegment];
63929                    starI = i;
63930                }
63931            }
63932
63933            if (!foundMap && foundStarMap) {
63934                foundMap = foundStarMap;
63935                foundI = starI;
63936            }
63937
63938            if (foundMap) {
63939                nameParts.splice(0, foundI, foundMap);
63940                name = nameParts.join('/');
63941            }
63942        }
63943
63944        return name;
63945    }
63946
63947    function makeRequire(relName, forceSync) {
63948        return function () {
63949            //A version of a require function that passes a moduleName
63950            //value for items that may need to
63951            //look up paths relative to the moduleName
63952            var args = aps.call(arguments, 0);
63953
63954            //If first arg is not require('string'), and there is only
63955            //one arg, it is the array form without a callback. Insert
63956            //a null so that the following concat is correct.
63957            if (typeof args[0] !== 'string' && args.length === 1) {
63958                args.push(null);
63959            }
63960            return req.apply(undef, args.concat([relName, forceSync]));
63961        };
63962    }
63963
63964    function makeNormalize(relName) {
63965        return function (name) {
63966            return normalize(name, relName);
63967        };
63968    }
63969
63970    function makeLoad(depName) {
63971        return function (value) {
63972            defined[depName] = value;
63973        };
63974    }
63975
63976    function callDep(name) {
63977        if (hasProp(waiting, name)) {
63978            var args = waiting[name];
63979            delete waiting[name];
63980            defining[name] = true;
63981            main.apply(undef, args);
63982        }
63983
63984        if (!hasProp(defined, name) && !hasProp(defining, name)) {
63985            throw new Error('No ' + name);
63986        }
63987        return defined[name];
63988    }
63989
63990    //Turns a plugin!resource to [plugin, resource]
63991    //with the plugin being undefined if the name
63992    //did not have a plugin prefix.
63993    function splitPrefix(name) {
63994        var prefix,
63995            index = name ? name.indexOf('!') : -1;
63996        if (index > -1) {
63997            prefix = name.substring(0, index);
63998            name = name.substring(index + 1, name.length);
63999        }
64000        return [prefix, name];
64001    }
64002
64003    //Creates a parts array for a relName where first part is plugin ID,
64004    //second part is resource ID. Assumes relName has already been normalized.
64005    function makeRelParts(relName) {
64006        return relName ? splitPrefix(relName) : [];
64007    }
64008
64009    /**
64010     * Makes a name map, normalizing the name, and using a plugin
64011     * for normalization if necessary. Grabs a ref to plugin
64012     * too, as an optimization.
64013     */
64014    makeMap = function (name, relParts) {
64015        var plugin,
64016            parts = splitPrefix(name),
64017            prefix = parts[0],
64018            relResourceName = relParts[1];
64019
64020        name = parts[1];
64021
64022        if (prefix) {
64023            prefix = normalize(prefix, relResourceName);
64024            plugin = callDep(prefix);
64025        }
64026
64027        //Normalize according
64028        if (prefix) {
64029            if (plugin && plugin.normalize) {
64030                name = plugin.normalize(name, makeNormalize(relResourceName));
64031            } else {
64032                name = normalize(name, relResourceName);
64033            }
64034        } else {
64035            name = normalize(name, relResourceName);
64036            parts = splitPrefix(name);
64037            prefix = parts[0];
64038            name = parts[1];
64039            if (prefix) {
64040                plugin = callDep(prefix);
64041            }
64042        }
64043
64044        //Using ridiculous property names for space reasons
64045        return {
64046            f: prefix ? prefix + '!' + name : name, //fullName
64047            n: name,
64048            pr: prefix,
64049            p: plugin
64050        };
64051    };
64052
64053    function makeConfig(name) {
64054        return function () {
64055            return (config && config.config && config.config[name]) || {};
64056        };
64057    }
64058
64059    handlers = {
64060        require: function (name) {
64061            return makeRequire(name);
64062        },
64063        exports: function (name) {
64064            var e = defined[name];
64065            if (typeof e !== 'undefined') {
64066                return e;
64067            } else {
64068                return (defined[name] = {});
64069            }
64070        },
64071        module: function (name) {
64072            return {
64073                id: name,
64074                uri: '',
64075                exports: defined[name],
64076                config: makeConfig(name)
64077            };
64078        }
64079    };
64080
64081    main = function (name, deps, callback, relName) {
64082        var cjsModule, depName, ret, map, i, relParts,
64083            args = [],
64084            callbackType = typeof callback,
64085            usingExports;
64086
64087        //Use name if no relName
64088        relName = relName || name;
64089        relParts = makeRelParts(relName);
64090
64091        //Call the callback to define the module, if necessary.
64092        if (callbackType === 'undefined' || callbackType === 'function') {
64093            //Pull out the defined dependencies and pass the ordered
64094            //values to the callback.
64095            //Default to [require, exports, module] if no deps
64096            deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;
64097            for (i = 0; i < deps.length; i += 1) {
64098                map = makeMap(deps[i], relParts);
64099                depName = map.f;
64100
64101                //Fast path CommonJS standard dependencies.
64102                if (depName === "require") {
64103                    args[i] = handlers.require(name);
64104                } else if (depName === "exports") {
64105                    //CommonJS module spec 1.1
64106                    args[i] = handlers.exports(name);
64107                    usingExports = true;
64108                } else if (depName === "module") {
64109                    //CommonJS module spec 1.1
64110                    cjsModule = args[i] = handlers.module(name);
64111                } else if (hasProp(defined, depName) ||
64112                           hasProp(waiting, depName) ||
64113                           hasProp(defining, depName)) {
64114                    args[i] = callDep(depName);
64115                } else if (map.p) {
64116                    map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});
64117                    args[i] = defined[depName];
64118                } else {
64119                    throw new Error(name + ' missing ' + depName);
64120                }
64121            }
64122
64123            ret = callback ? callback.apply(defined[name], args) : undefined;
64124
64125            if (name) {
64126                //If setting exports via "module" is in play,
64127                //favor that over return value and exports. After that,
64128                //favor a non-undefined return value over exports use.
64129                if (cjsModule && cjsModule.exports !== undef &&
64130                        cjsModule.exports !== defined[name]) {
64131                    defined[name] = cjsModule.exports;
64132                } else if (ret !== undef || !usingExports) {
64133                    //Use the return value from the function.
64134                    defined[name] = ret;
64135                }
64136            }
64137        } else if (name) {
64138            //May just be an object definition for the module. Only
64139            //worry about defining if have a module name.
64140            defined[name] = callback;
64141        }
64142    };
64143
64144    requirejs = require = req = function (deps, callback, relName, forceSync, alt) {
64145        if (typeof deps === "string") {
64146            if (handlers[deps]) {
64147                //callback in this case is really relName
64148                return handlers[deps](callback);
64149            }
64150            //Just return the module wanted. In this scenario, the
64151            //deps arg is the module name, and second arg (if passed)
64152            //is just the relName.
64153            //Normalize module name, if it contains . or ..
64154            return callDep(makeMap(deps, makeRelParts(callback)).f);
64155        } else if (!deps.splice) {
64156            //deps is a config object, not an array.
64157            config = deps;
64158            if (config.deps) {
64159                req(config.deps, config.callback);
64160            }
64161            if (!callback) {
64162                return;
64163            }
64164
64165            if (callback.splice) {
64166                //callback is an array, which means it is a dependency list.
64167                //Adjust args if there are dependencies
64168                deps = callback;
64169                callback = relName;
64170                relName = null;
64171            } else {
64172                deps = undef;
64173            }
64174        }
64175
64176        //Support require(['a'])
64177        callback = callback || function () {};
64178
64179        //If relName is a function, it is an errback handler,
64180        //so remove it.
64181        if (typeof relName === 'function') {
64182            relName = forceSync;
64183            forceSync = alt;
64184        }
64185
64186        //Simulate async callback;
64187        if (forceSync) {
64188            main(undef, deps, callback, relName);
64189        } else {
64190            //Using a non-zero value because of concern for what old browsers
64191            //do, and latest browsers "upgrade" to 4 if lower value is used:
64192            //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout:
64193            //If want a value immediately, use require('id') instead -- something
64194            //that works in almond on the global level, but not guaranteed and
64195            //unlikely to work in other AMD implementations.
64196            setTimeout(function () {
64197                main(undef, deps, callback, relName);
64198            }, 4);
64199        }
64200
64201        return req;
64202    };
64203
64204    /**
64205     * Just drops the config on the floor, but returns req in case
64206     * the config return value is used.
64207     */
64208    req.config = function (cfg) {
64209        return req(cfg);
64210    };
64211
64212    /**
64213     * Expose module registry for debugging and tooling
64214     */
64215    requirejs._defined = defined;
64216
64217    define = function (name, deps, callback) {
64218        if (typeof name !== 'string') {
64219            throw new Error('See almond README: incorrect module build, no module name');
64220        }
64221
64222        //This module may not have dependencies
64223        if (!deps.splice) {
64224            //deps is not an array, so probably means
64225            //an object literal or factory function for
64226            //the value. Adjust args.
64227            callback = deps;
64228            deps = [];
64229        }
64230
64231        if (!hasProp(defined, name) && !hasProp(waiting, name)) {
64232            waiting[name] = [name, deps, callback];
64233        }
64234    };
64235
64236    define.amd = {
64237        jQuery: true
64238    };
64239}());
64240
64241S2.requirejs = requirejs;S2.require = require;S2.define = define;
64242}
64243}());
64244S2.define("almond", function(){});
64245
64246/* global jQuery:false, $:false */
64247S2.define('jquery',[],function () {
64248  var _$ = jQuery || $;
64249
64250  if (_$ == null && console && console.error) {
64251    console.error(
64252      'Select2: An instance of jQuery or a jQuery-compatible library was not ' +
64253      'found. Make sure that you are including jQuery before Select2 on your ' +
64254      'web page.'
64255    );
64256  }
64257
64258  return _$;
64259});
64260
64261S2.define('select2/utils',[
vendor: 5,112 bytes, lines 64262-64474
64262  'jquery'
64263], function ($) {
64264  var Utils = {};
64265
64266  Utils.Extend = function (ChildClass, SuperClass) {
64267    var __hasProp = {}.hasOwnProperty;
64268
64269    function BaseConstructor () {
64270      this.constructor = ChildClass;
64271    }
64272
64273    for (var key in SuperClass) {
64274      if (__hasProp.call(SuperClass, key)) {
64275        ChildClass[key] = SuperClass[key];
64276      }
64277    }
64278
64279    BaseConstructor.prototype = SuperClass.prototype;
64280    ChildClass.prototype = new BaseConstructor();
64281    ChildClass.__super__ = SuperClass.prototype;
64282
64283    return ChildClass;
64284  };
64285
64286  function getMethods (theClass) {
64287    var proto = theClass.prototype;
64288
64289    var methods = [];
64290
64291    for (var methodName in proto) {
64292      var m = proto[methodName];
64293
64294      if (typeof m !== 'function') {
64295        continue;
64296      }
64297
64298      if (methodName === 'constructor') {
64299        continue;
64300      }
64301
64302      methods.push(methodName);
64303    }
64304
64305    return methods;
64306  }
64307
64308  Utils.Decorate = function (SuperClass, DecoratorClass) {
64309    var decoratedMethods = getMethods(DecoratorClass);
64310    var superMethods = getMethods(SuperClass);
64311
64312    function DecoratedClass () {
64313      var unshift = Array.prototype.unshift;
64314
64315      var argCount = DecoratorClass.prototype.constructor.length;
64316
64317      var calledConstructor = SuperClass.prototype.constructor;
64318
64319      if (argCount > 0) {
64320        unshift.call(arguments, SuperClass.prototype.constructor);
64321
64322        calledConstructor = DecoratorClass.prototype.constructor;
64323      }
64324
64325      calledConstructor.apply(this, arguments);
64326    }
64327
64328    DecoratorClass.displayName = SuperClass.displayName;
64329
64330    function ctr () {
64331      this.constructor = DecoratedClass;
64332    }
64333
64334    DecoratedClass.prototype = new ctr();
64335
64336    for (var m = 0; m < superMethods.length; m++) {
64337      var superMethod = superMethods[m];
64338
64339      DecoratedClass.prototype[superMethod] =
64340        SuperClass.prototype[superMethod];
64341    }
64342
64343    var calledMethod = function (methodName) {
64344      // Stub out the original method if it's not decorating an actual method
64345      var originalMethod = function () {};
64346
64347      if (methodName in DecoratedClass.prototype) {
64348        originalMethod = DecoratedClass.prototype[methodName];
64349      }
64350
64351      var decoratedMethod = DecoratorClass.prototype[methodName];
64352
64353      return function () {
64354        var unshift = Array.prototype.unshift;
64355
64356        unshift.call(arguments, originalMethod);
64357
64358        return decoratedMethod.apply(this, arguments);
64359      };
64360    };
64361
64362    for (var d = 0; d < decoratedMethods.length; d++) {
64363      var decoratedMethod = decoratedMethods[d];
64364
64365      DecoratedClass.prototype[decoratedMethod] = calledMethod(decoratedMethod);
64366    }
64367
64368    return DecoratedClass;
64369  };
64370
64371  var Observable = function () {
64372    this.listeners = {};
64373  };
64374
64375  Observable.prototype.on = function (event, callback) {
64376    this.listeners = this.listeners || {};
64377
64378    if (event in this.listeners) {
64379      this.listeners[event].push(callback);
64380    } else {
64381      this.listeners[event] = [callback];
64382    }
64383  };
64384
64385  Observable.prototype.trigger = function (event) {
64386    var slice = Array.prototype.slice;
64387    var params = slice.call(arguments, 1);
64388
64389    this.listeners = this.listeners || {};
64390
64391    // Params should always come in as an array
64392    if (params == null) {
64393      params = [];
64394    }
64395
64396    // If there are no arguments to the event, use a temporary object
64397    if (params.length === 0) {
64398      params.push({});
64399    }
64400
64401    // Set the `_type` of the first object to the event
64402    params[0]._type = event;
64403
64404    if (event in this.listeners) {
64405      this.invoke(this.listeners[event], slice.call(arguments, 1));
64406    }
64407
64408    if ('*' in this.listeners) {
64409      this.invoke(this.listeners['*'], arguments);
64410    }
64411  };
64412
64413  Observable.prototype.invoke = function (listeners, params) {
64414    for (var i = 0, len = listeners.length; i < len; i++) {
64415      listeners[i].apply(this, params);
64416    }
64417  };
64418
64419  Utils.Observable = Observable;
64420
64421  Utils.generateChars = function (length) {
64422    var chars = '';
64423
64424    for (var i = 0; i < length; i++) {
64425      var randomChar = Math.floor(Math.random() * 36);
64426      chars += randomChar.toString(36);
64427    }
64428
64429    return chars;
64430  };
64431
64432  Utils.bind = function (func, context) {
64433    return function () {
64434      func.apply(context, arguments);
64435    };
64436  };
64437
64438  Utils._convertData = function (data) {
64439    for (var originalKey in data) {
64440      var keys = originalKey.split('-');
64441
64442      var dataLevel = data;
64443
64444      if (keys.length === 1) {
64445        continue;
64446      }
64447
64448      for (var k = 0; k < keys.length; k++) {
64449        var key = keys[k];
64450
64451        // Lowercase the first letter
64452        // By default, dash-separated becomes camelCase
64453        key = key.substring(0, 1).toLowerCase() + key.substring(1);
64454
64455        if (!(key in dataLevel)) {
64456          dataLevel[key] = {};
64457        }
64458
64459        if (k == keys.length - 1) {
64460          dataLevel[key] = data[originalKey];
64461        }
64462
64463        dataLevel = dataLevel[key];
64464      }
64465
64466      delete data[originalKey];
64467    }
64468
64469    return data;
64470  };
64471
64472  Utils.hasScroll = function (index, el) {
64473    // Adapted from the function created by @ShadowScripter
64474    // and adapted by @BillBarry on the Stack Exchange Code Review website.
64475    // The original code can be found at
64476    // http://codereview.stackexchange.com/q/13338
64477    // and was designed to be used with the Sizzle selector engine.
64478
64479    var $el = $(el);
64480    var overflowX = el.style.overflowX;
64481    var overflowY = el.style.overflowY;
64482
64483    //Check both x and y declarations
64484    if (overflowX === overflowY &&
64485        (overflowY === 'hidden' || overflowY === 'visible')) {
64486      return false;
64487    }
64488
64489    if (overflowX === 'scroll' || overflowY === 'scroll') {
64490      return true;
64491    }
64492
64493    return ($el.innerHeight() < el.scrollHeight ||
64494      $el.innerWidth() < el.scrollWidth);
64495  };
64496
64497  Utils.escapeMarkup = function (markup) {
64498    var replaceMap = {
64499      '\\': '&#92;',
64500      '&': '&amp;',
64501      '<': '&lt;',
64502      '>': '&gt;',
64503      '"': '&quot;',
64504      '\'': '&#39;',
64505      '/': '&#47;'
64506    };
64507
64508    // Do not try to escape the markup if it's not a string
64509    if (typeof markup !== 'string') {
64510      return markup;
64511    }
64512
64513    return String(markup).replace(/[&<>"'\/\\]/g, function (match) {
64514      return replaceMap[match];
64515    });
64516  };
64517
64518  // Append an array of jQuery nodes to a given element.
64519  Utils.appendMany = function ($element, $nodes) {
64520    // jQuery 1.7.x does not support $.fn.append() with an array
64521    // Fall back to a jQuery object collection using $.fn.add()
64522    if ($.fn.jquery.substr(0, 3) === '1.7') {
64523      var $jqNodes = $();
64524
64525      $.map($nodes, function (node) {
64526        $jqNodes = $jqNodes.add(node);
64527      });
64528
64529      $nodes = $jqNodes;
64530    }
64531
64532    $element.append($nodes);
64533  };
64534
64535  // Cache objects in Utils.__cache instead of $.data (see #4346)
64536  Utils.__cache = {};
64537
64538  var id = 0;
64539  Utils.GetUniqueElementId = function (element) {
64540    // Get a unique element Id. If element has no id,
64541    // creates a new unique number, stores it in the id
64542    // attribute and returns the new id.
64543    // If an id already exists, it simply returns it.
64544
64545    var select2Id = element.getAttribute('data-select2-id');
64546    if (select2Id == null) {
64547      // If element has id, use it.
64548      if (element.id) {
64549        select2Id = element.id;
64550        element.setAttribute('data-select2-id', select2Id);
64551      } else {
64552        element.setAttribute('data-select2-id', ++id);
64553        select2Id = id.toString();
64554      }
64555    }
64556    return select2Id;
64557  };
64558
64559  Utils.StoreData = function (element, name, value) {
64560    // Stores an item in the cache for a specified element.
64561    // name is the cache key.
64562    var id = Utils.GetUniqueElementId(element);
64563    if (!Utils.__cache[id]) {
64564      Utils.__cache[id] = {};
64565    }
64566
64567    Utils.__cache[id][name] = value;
64568  };
64569
64570  Utils.GetData = function (element, name) {
64571    // Retrieves a value from the cache by its key (name)
64572    // name is optional. If no name specified, return
64573    // all cache items for the specified element.
64574    // and for a specified element.
64575    var id = Utils.GetUniqueElementId(element);
64576    if (name) {
64577      if (Utils.__cache[id]) {
64578        if (Utils.__cache[id][name] != null) {
64579          return Utils.__cache[id][name];
64580        }
64581        return $(element).data(name); // Fallback to HTML5 data attribs.
64582      }
64583      return $(element).data(name); // Fallback to HTML5 data attribs.
64584    } else {
64585      return Utils.__cache[id];
64586    }
64587  };
64588
64589  Utils.RemoveData = function (element) {
64590    // Removes all cached items for a specified element.
64591    var id = Utils.GetUniqueElementId(element);
64592    if (Utils.__cache[id] != null) {
64593      delete Utils.__cache[id];
64594    }
64595
64596    element.removeAttribute('data-select2-id');
64597  };
64598
64599  return Utils;
64600});
64601
64602S2.define('select2/results',[
64603  'jquery',
64604  './utils'
64605], function ($, Utils) {
64606  function Results ($element, options, dataAdapter) {
64607    this.$element = $element;
64608    this.data = dataAdapter;
64609    this.options = options;
64610
64611    Results.__super__.constructor.call(this);
64612  }
64613
64614  Utils.Extend(Results, Utils.Observable);
64615
64616  Results.prototype.render = function () {
64617    var $results = $(
64618      '<ul class="select2-results__options" role="listbox"></ul>'
64619    );
64620
64621    if (this.options.get('multiple')) {
64622      $results.attr('aria-multiselectable', 'true');
64623    }
64624
64625    this.$results = $results;
64626
64627    return $results;
64628  };
64629
64630  Results.prototype.clear = function () {
64631    this.$results.empty();
64632  };
64633
64634  Results.prototype.displayMessage = function (params) {
64635    var escapeMarkup = this.options.get('escapeMarkup');
64636
64637    this.clear();
64638    this.hideLoading();
64639
64640    var $message = $(
64641      '<li role="alert" aria-live="assertive"' +
64642      ' class="select2-results__option"></li>'
64643    );
64644
64645    var message = this.options.get('translations').get(params.message);
64646
64647    $message.append(
64648      escapeMarkup(
64649        message(params.args)
64650      )
64651    );
64652
64653    $message[0].className += ' select2-results__message';
vendor: 47,567 bytes, lines 64654-66671
64654
64655    this.$results.append($message);
64656  };
64657
64658  Results.prototype.hideMessages = function () {
64659    this.$results.find('.select2-results__message').remove();
64660  };
64661
64662  Results.prototype.append = function (data) {
64663    this.hideLoading();
64664
64665    var $options = [];
64666
64667    if (data.results == null || data.results.length === 0) {
64668      if (this.$results.children().length === 0) {
64669        this.trigger('results:message', {
64670          message: 'noResults'
64671        });
64672      }
64673
64674      return;
64675    }
64676
64677    data.results = this.sort(data.results);
64678
64679    for (var d = 0; d < data.results.length; d++) {
64680      var item = data.results[d];
64681
64682      var $option = this.option(item);
64683
64684      $options.push($option);
64685    }
64686
64687    this.$results.append($options);
64688  };
64689
64690  Results.prototype.position = function ($results, $dropdown) {
64691    var $resultsContainer = $dropdown.find('.select2-results');
64692    $resultsContainer.append($results);
64693  };
64694
64695  Results.prototype.sort = function (data) {
64696    var sorter = this.options.get('sorter');
64697
64698    return sorter(data);
64699  };
64700
64701  Results.prototype.highlightFirstItem = function () {
64702    var $options = this.$results
64703      .find('.select2-results__option[aria-selected]');
64704
64705    var $selected = $options.filter('[aria-selected=true]');
64706
64707    // Check if there are any selected options
64708    if ($selected.length > 0) {
64709      // If there are selected options, highlight the first
64710      $selected.first().trigger('mouseenter');
64711    } else {
64712      // If there are no selected options, highlight the first option
64713      // in the dropdown
64714      $options.first().trigger('mouseenter');
64715    }
64716
64717    this.ensureHighlightVisible();
64718  };
64719
64720  Results.prototype.setClasses = function () {
64721    var self = this;
64722
64723    this.data.current(function (selected) {
64724      var selectedIds = $.map(selected, function (s) {
64725        return s.id.toString();
64726      });
64727
64728      var $options = self.$results
64729        .find('.select2-results__option[aria-selected]');
64730
64731      $options.each(function () {
64732        var $option = $(this);
64733
64734        var item = Utils.GetData(this, 'data');
64735
64736        // id needs to be converted to a string when comparing
64737        var id = '' + item.id;
64738
64739        if ((item.element != null && item.element.selected) ||
64740            (item.element == null && $.inArray(id, selectedIds) > -1)) {
64741          $option.attr('aria-selected', 'true');
64742        } else {
64743          $option.attr('aria-selected', 'false');
64744        }
64745      });
64746
64747    });
64748  };
64749
64750  Results.prototype.showLoading = function (params) {
64751    this.hideLoading();
64752
64753    var loadingMore = this.options.get('translations').get('searching');
64754
64755    var loading = {
64756      disabled: true,
64757      loading: true,
64758      text: loadingMore(params)
64759    };
64760    var $loading = this.option(loading);
64761    $loading.className += ' loading-results';
64762
64763    this.$results.prepend($loading);
64764  };
64765
64766  Results.prototype.hideLoading = function () {
64767    this.$results.find('.loading-results').remove();
64768  };
64769
64770  Results.prototype.option = function (data) {
64771    var option = document.createElement('li');
64772    option.className = 'select2-results__option';
64773
64774    var attrs = {
64775      'role': 'option',
64776      'aria-selected': 'false'
64777    };
64778
64779    var matches = window.Element.prototype.matches ||
64780      window.Element.prototype.msMatchesSelector ||
64781      window.Element.prototype.webkitMatchesSelector;
64782
64783    if ((data.element != null && matches.call(data.element, ':disabled')) ||
64784        (data.element == null && data.disabled)) {
64785      delete attrs['aria-selected'];
64786      attrs['aria-disabled'] = 'true';
64787    }
64788
64789    if (data.id == null) {
64790      delete attrs['aria-selected'];
64791    }
64792
64793    if (data._resultId != null) {
64794      option.id = data._resultId;
64795    }
64796
64797    if (data.title) {
64798      option.title = data.title;
64799    }
64800
64801    if (data.children) {
64802      attrs.role = 'group';
64803      attrs['aria-label'] = data.text;
64804      delete attrs['aria-selected'];
64805    }
64806
64807    for (var attr in attrs) {
64808      var val = attrs[attr];
64809
64810      option.setAttribute(attr, val);
64811    }
64812
64813    if (data.children) {
64814      var $option = $(option);
64815
64816      var label = document.createElement('strong');
64817      label.className = 'select2-results__group';
64818
64819      var $label = $(label);
64820      this.template(data, label);
64821
64822      var $children = [];
64823
64824      for (var c = 0; c < data.children.length; c++) {
64825        var child = data.children[c];
64826
64827        var $child = this.option(child);
64828
64829        $children.push($child);
64830      }
64831
64832      var $childrenContainer = $('<ul></ul>', {
64833        'class': 'select2-results__options select2-results__options--nested'
64834      });
64835
64836      $childrenContainer.append($children);
64837
64838      $option.append(label);
64839      $option.append($childrenContainer);
64840    } else {
64841      this.template(data, option);
64842    }
64843
64844    Utils.StoreData(option, 'data', data);
64845
64846    return option;
64847  };
64848
64849  Results.prototype.bind = function (container, $container) {
64850    var self = this;
64851
64852    var id = container.id + '-results';
64853
64854    this.$results.attr('id', id);
64855
64856    container.on('results:all', function (params) {
64857      self.clear();
64858      self.append(params.data);
64859
64860      if (container.isOpen()) {
64861        self.setClasses();
64862        self.highlightFirstItem();
64863      }
64864    });
64865
64866    container.on('results:append', function (params) {
64867      self.append(params.data);
64868
64869      if (container.isOpen()) {
64870        self.setClasses();
64871      }
64872    });
64873
64874    container.on('query', function (params) {
64875      self.hideMessages();
64876      self.showLoading(params);
64877    });
64878
64879    container.on('select', function () {
64880      if (!container.isOpen()) {
64881        return;
64882      }
64883
64884      self.setClasses();
64885
64886      if (self.options.get('scrollAfterSelect')) {
64887        self.highlightFirstItem();
64888      }
64889    });
64890
64891    container.on('unselect', function () {
64892      if (!container.isOpen()) {
64893        return;
64894      }
64895
64896      self.setClasses();
64897
64898      if (self.options.get('scrollAfterSelect')) {
64899        self.highlightFirstItem();
64900      }
64901    });
64902
64903    container.on('open', function () {
64904      // When the dropdown is open, aria-expended="true"
64905      self.$results.attr('aria-expanded', 'true');
64906      self.$results.attr('aria-hidden', 'false');
64907
64908      self.setClasses();
64909      self.ensureHighlightVisible();
64910    });
64911
64912    container.on('close', function () {
64913      // When the dropdown is closed, aria-expended="false"
64914      self.$results.attr('aria-expanded', 'false');
64915      self.$results.attr('aria-hidden', 'true');
64916      self.$results.removeAttr('aria-activedescendant');
64917    });
64918
64919    container.on('results:toggle', function () {
64920      var $highlighted = self.getHighlightedResults();
64921
64922      if ($highlighted.length === 0) {
64923        return;
64924      }
64925
64926      $highlighted.trigger('mouseup');
64927    });
64928
64929    container.on('results:select', function () {
64930      var $highlighted = self.getHighlightedResults();
64931
64932      if ($highlighted.length === 0) {
64933        return;
64934      }
64935
64936      var data = Utils.GetData($highlighted[0], 'data');
64937
64938      if ($highlighted.attr('aria-selected') == 'true') {
64939        self.trigger('close', {});
64940      } else {
64941        self.trigger('select', {
64942          data: data
64943        });
64944      }
64945    });
64946
64947    container.on('results:previous', function () {
64948      var $highlighted = self.getHighlightedResults();
64949
64950      var $options = self.$results.find('[aria-selected]');
64951
64952      var currentIndex = $options.index($highlighted);
64953
64954      // If we are already at the top, don't move further
64955      // If no options, currentIndex will be -1
64956      if (currentIndex <= 0) {
64957        return;
64958      }
64959
64960      var nextIndex = currentIndex - 1;
64961
64962      // If none are highlighted, highlight the first
64963      if ($highlighted.length === 0) {
64964        nextIndex = 0;
64965      }
64966
64967      var $next = $options.eq(nextIndex);
64968
64969      $next.trigger('mouseenter');
64970
64971      var currentOffset = self.$results.offset().top;
64972      var nextTop = $next.offset().top;
64973      var nextOffset = self.$results.scrollTop() + (nextTop - currentOffset);
64974
64975      if (nextIndex === 0) {
64976        self.$results.scrollTop(0);
64977      } else if (nextTop - currentOffset < 0) {
64978        self.$results.scrollTop(nextOffset);
64979      }
64980    });
64981
64982    container.on('results:next', function () {
64983      var $highlighted = self.getHighlightedResults();
64984
64985      var $options = self.$results.find('[aria-selected]');
64986
64987      var currentIndex = $options.index($highlighted);
64988
64989      var nextIndex = currentIndex + 1;
64990
64991      // If we are at the last option, stay there
64992      if (nextIndex >= $options.length) {
64993        return;
64994      }
64995
64996      var $next = $options.eq(nextIndex);
64997
64998      $next.trigger('mouseenter');
64999
65000      var currentOffset = self.$results.offset().top +
65001        self.$results.outerHeight(false);
65002      var nextBottom = $next.offset().top + $next.outerHeight(false);
65003      var nextOffset = self.$results.scrollTop() + nextBottom - currentOffset;
65004
65005      if (nextIndex === 0) {
65006        self.$results.scrollTop(0);
65007      } else if (nextBottom > currentOffset) {
65008        self.$results.scrollTop(nextOffset);
65009      }
65010    });
65011
65012    container.on('results:focus', function (params) {
65013      params.element.addClass('select2-results__option--highlighted');
65014    });
65015
65016    container.on('results:message', function (params) {
65017      self.displayMessage(params);
65018    });
65019
65020    if ($.fn.mousewheel) {
65021      this.$results.on('mousewheel', function (e) {
65022        var top = self.$results.scrollTop();
65023
65024        var bottom = self.$results.get(0).scrollHeight - top + e.deltaY;
65025
65026        var isAtTop = e.deltaY > 0 && top - e.deltaY <= 0;
65027        var isAtBottom = e.deltaY < 0 && bottom <= self.$results.height();
65028
65029        if (isAtTop) {
65030          self.$results.scrollTop(0);
65031
65032          e.preventDefault();
65033          e.stopPropagation();
65034        } else if (isAtBottom) {
65035          self.$results.scrollTop(
65036            self.$results.get(0).scrollHeight - self.$results.height()
65037          );
65038
65039          e.preventDefault();
65040          e.stopPropagation();
65041        }
65042      });
65043    }
65044
65045    this.$results.on('mouseup', '.select2-results__option[aria-selected]',
65046      function (evt) {
65047      var $this = $(this);
65048
65049      var data = Utils.GetData(this, 'data');
65050
65051      if ($this.attr('aria-selected') === 'true') {
65052        if (self.options.get('multiple')) {
65053          self.trigger('unselect', {
65054            originalEvent: evt,
65055            data: data
65056          });
65057        } else {
65058          self.trigger('close', {});
65059        }
65060
65061        return;
65062      }
65063
65064      self.trigger('select', {
65065        originalEvent: evt,
65066        data: data
65067      });
65068    });
65069
65070    this.$results.on('mouseenter', '.select2-results__option[aria-selected]',
65071      function (evt) {
65072      var data = Utils.GetData(this, 'data');
65073
65074      self.getHighlightedResults()
65075          .removeClass('select2-results__option--highlighted');
65076
65077      self.trigger('results:focus', {
65078        data: data,
65079        element: $(this)
65080      });
65081    });
65082  };
65083
65084  Results.prototype.getHighlightedResults = function () {
65085    var $highlighted = this.$results
65086    .find('.select2-results__option--highlighted');
65087
65088    return $highlighted;
65089  };
65090
65091  Results.prototype.destroy = function () {
65092    this.$results.remove();
65093  };
65094
65095  Results.prototype.ensureHighlightVisible = function () {
65096    var $highlighted = this.getHighlightedResults();
65097
65098    if ($highlighted.length === 0) {
65099      return;
65100    }
65101
65102    var $options = this.$results.find('[aria-selected]');
65103
65104    var currentIndex = $options.index($highlighted);
65105
65106    var currentOffset = this.$results.offset().top;
65107    var nextTop = $highlighted.offset().top;
65108    var nextOffset = this.$results.scrollTop() + (nextTop - currentOffset);
65109
65110    var offsetDelta = nextTop - currentOffset;
65111    nextOffset -= $highlighted.outerHeight(false) * 2;
65112
65113    if (currentIndex <= 2) {
65114      this.$results.scrollTop(0);
65115    } else if (offsetDelta > this.$results.outerHeight() || offsetDelta < 0) {
65116      this.$results.scrollTop(nextOffset);
65117    }
65118  };
65119
65120  Results.prototype.template = function (result, container) {
65121    var template = this.options.get('templateResult');
65122    var escapeMarkup = this.options.get('escapeMarkup');
65123
65124    var content = template(result, container);
65125
65126    if (content == null) {
65127      container.style.display = 'none';
65128    } else if (typeof content === 'string') {
65129      container.innerHTML = escapeMarkup(content);
65130    } else {
65131      $(container).append(content);
65132    }
65133  };
65134
65135  return Results;
65136});
65137
65138S2.define('select2/keys',[
65139
65140], function () {
65141  var KEYS = {
65142    BACKSPACE: 8,
65143    TAB: 9,
65144    ENTER: 13,
65145    SHIFT: 16,
65146    CTRL: 17,
65147    ALT: 18,
65148    ESC: 27,
65149    SPACE: 32,
65150    PAGE_UP: 33,
65151    PAGE_DOWN: 34,
65152    END: 35,
65153    HOME: 36,
65154    LEFT: 37,
65155    UP: 38,
65156    RIGHT: 39,
65157    DOWN: 40,
65158    DELETE: 46
65159  };
65160
65161  return KEYS;
65162});
65163
65164S2.define('select2/selection/base',[
65165  'jquery',
65166  '../utils',
65167  '../keys'
65168], function ($, Utils, KEYS) {
65169  function BaseSelection ($element, options) {
65170    this.$element = $element;
65171    this.options = options;
65172
65173    BaseSelection.__super__.constructor.call(this);
65174  }
65175
65176  Utils.Extend(BaseSelection, Utils.Observable);
65177
65178  BaseSelection.prototype.render = function () {
65179    var $selection = $(
65180      '<span class="select2-selection" role="combobox" ' +
65181      ' aria-haspopup="true" aria-expanded="false">' +
65182      '</span>'
65183    );
65184
65185    this._tabindex = 0;
65186
65187    if (Utils.GetData(this.$element[0], 'old-tabindex') != null) {
65188      this._tabindex = Utils.GetData(this.$element[0], 'old-tabindex');
65189    } else if (this.$element.attr('tabindex') != null) {
65190      this._tabindex = this.$element.attr('tabindex');
65191    }
65192
65193    $selection.attr('title', this.$element.attr('title'));
65194    $selection.attr('tabindex', this._tabindex);
65195    $selection.attr('aria-disabled', 'false');
65196
65197    this.$selection = $selection;
65198
65199    return $selection;
65200  };
65201
65202  BaseSelection.prototype.bind = function (container, $container) {
65203    var self = this;
65204
65205    var resultsId = container.id + '-results';
65206
65207    this.container = container;
65208
65209    this.$selection.on('focus', function (evt) {
65210      self.trigger('focus', evt);
65211    });
65212
65213    this.$selection.on('blur', function (evt) {
65214      self._handleBlur(evt);
65215    });
65216
65217    this.$selection.on('keydown', function (evt) {
65218      self.trigger('keypress', evt);
65219
65220      if (evt.which === KEYS.SPACE) {
65221        evt.preventDefault();
65222      }
65223    });
65224
65225    container.on('results:focus', function (params) {
65226      self.$selection.attr('aria-activedescendant', params.data._resultId);
65227    });
65228
65229    container.on('selection:update', function (params) {
65230      self.update(params.data);
65231    });
65232
65233    container.on('open', function () {
65234      // When the dropdown is open, aria-expanded="true"
65235      self.$selection.attr('aria-expanded', 'true');
65236      self.$selection.attr('aria-owns', resultsId);
65237
65238      self._attachCloseHandler(container);
65239    });
65240
65241    container.on('close', function () {
65242      // When the dropdown is closed, aria-expanded="false"
65243      self.$selection.attr('aria-expanded', 'false');
65244      self.$selection.removeAttr('aria-activedescendant');
65245      self.$selection.removeAttr('aria-owns');
65246
65247      self.$selection.trigger('focus');
65248
65249      self._detachCloseHandler(container);
65250    });
65251
65252    container.on('enable', function () {
65253      self.$selection.attr('tabindex', self._tabindex);
65254      self.$selection.attr('aria-disabled', 'false');
65255    });
65256
65257    container.on('disable', function () {
65258      self.$selection.attr('tabindex', '-1');
65259      self.$selection.attr('aria-disabled', 'true');
65260    });
65261  };
65262
65263  BaseSelection.prototype._handleBlur = function (evt) {
65264    var self = this;
65265
65266    // This needs to be delayed as the active element is the body when the tab
65267    // key is pressed, possibly along with others.
65268    window.setTimeout(function () {
65269      // Don't trigger `blur` if the focus is still in the selection
65270      if (
65271        (document.activeElement == self.$selection[0]) ||
65272        ($.contains(self.$selection[0], document.activeElement))
65273      ) {
65274        return;
65275      }
65276
65277      self.trigger('blur', evt);
65278    }, 1);
65279  };
65280
65281  BaseSelection.prototype._attachCloseHandler = function (container) {
65282
65283    $(document.body).on('mousedown.select2.' + container.id, function (e) {
65284      var $target = $(e.target);
65285
65286      var $select = $target.closest('.select2');
65287
65288      var $all = $('.select2.select2-container--open');
65289
65290      $all.each(function () {
65291        if (this == $select[0]) {
65292          return;
65293        }
65294
65295        var $element = Utils.GetData(this, 'element');
65296
65297        $element.select2('close');
65298      });
65299    });
65300  };
65301
65302  BaseSelection.prototype._detachCloseHandler = function (container) {
65303    $(document.body).off('mousedown.select2.' + container.id);
65304  };
65305
65306  BaseSelection.prototype.position = function ($selection, $container) {
65307    var $selectionContainer = $container.find('.selection');
65308    $selectionContainer.append($selection);
65309  };
65310
65311  BaseSelection.prototype.destroy = function () {
65312    this._detachCloseHandler(this.container);
65313  };
65314
65315  BaseSelection.prototype.update = function (data) {
65316    throw new Error('The `update` method must be defined in child classes.');
65317  };
65318
65319  /**
65320   * Helper method to abstract the "enabled" (not "disabled") state of this
65321   * object.
65322   *
65323   * @return {true} if the instance is not disabled.
65324   * @return {false} if the instance is disabled.
65325   */
65326  BaseSelection.prototype.isEnabled = function () {
65327    return !this.isDisabled();
65328  };
65329
65330  /**
65331   * Helper method to abstract the "disabled" state of this object.
65332   *
65333   * @return {true} if the disabled option is true.
65334   * @return {false} if the disabled option is false.
65335   */
65336  BaseSelection.prototype.isDisabled = function () {
65337    return this.options.get('disabled');
65338  };
65339
65340  return BaseSelection;
65341});
65342
65343S2.define('select2/selection/single',[
65344  'jquery',
65345  './base',
65346  '../utils',
65347  '../keys'
65348], function ($, BaseSelection, Utils, KEYS) {
65349  function SingleSelection () {
65350    SingleSelection.__super__.constructor.apply(this, arguments);
65351  }
65352
65353  Utils.Extend(SingleSelection, BaseSelection);
65354
65355  SingleSelection.prototype.render = function () {
65356    var $selection = SingleSelection.__super__.render.call(this);
65357
65358    $selection.addClass('select2-selection--single');
65359
65360    $selection.html(
65361      '<span class="select2-selection__rendered"></span>' +
65362      '<span class="select2-selection__arrow" role="presentation">' +
65363        '<b role="presentation"></b>' +
65364      '</span>'
65365    );
65366
65367    return $selection;
65368  };
65369
65370  SingleSelection.prototype.bind = function (container, $container) {
65371    var self = this;
65372
65373    SingleSelection.__super__.bind.apply(this, arguments);
65374
65375    var id = container.id + '-container';
65376
65377    this.$selection.find('.select2-selection__rendered')
65378      .attr('id', id)
65379      .attr('role', 'textbox')
65380      .attr('aria-readonly', 'true');
65381    this.$selection.attr('aria-labelledby', id);
65382
65383    this.$selection.on('mousedown', function (evt) {
65384      // Only respond to left clicks
65385      if (evt.which !== 1) {
65386        return;
65387      }
65388
65389      self.trigger('toggle', {
65390        originalEvent: evt
65391      });
65392    });
65393
65394    this.$selection.on('focus', function (evt) {
65395      // User focuses on the container
65396    });
65397
65398    this.$selection.on('blur', function (evt) {
65399      // User exits the container
65400    });
65401
65402    container.on('focus', function (evt) {
65403      if (!container.isOpen()) {
65404        self.$selection.trigger('focus');
65405      }
65406    });
65407  };
65408
65409  SingleSelection.prototype.clear = function () {
65410    var $rendered = this.$selection.find('.select2-selection__rendered');
65411    $rendered.empty();
65412    $rendered.removeAttr('title'); // clear tooltip on empty
65413  };
65414
65415  SingleSelection.prototype.display = function (data, container) {
65416    var template = this.options.get('templateSelection');
65417    var escapeMarkup = this.options.get('escapeMarkup');
65418
65419    return escapeMarkup(template(data, container));
65420  };
65421
65422  SingleSelection.prototype.selectionContainer = function () {
65423    return $('<span></span>');
65424  };
65425
65426  SingleSelection.prototype.update = function (data) {
65427    if (data.length === 0) {
65428      this.clear();
65429      return;
65430    }
65431
65432    var selection = data[0];
65433
65434    var $rendered = this.$selection.find('.select2-selection__rendered');
65435    var formatted = this.display(selection, $rendered);
65436
65437    $rendered.empty().append(formatted);
65438
65439    var title = selection.title || selection.text;
65440
65441    if (title) {
65442      $rendered.attr('title', title);
65443    } else {
65444      $rendered.removeAttr('title');
65445    }
65446  };
65447
65448  return SingleSelection;
65449});
65450
65451S2.define('select2/selection/multiple',[
65452  'jquery',
65453  './base',
65454  '../utils'
65455], function ($, BaseSelection, Utils) {
65456  function MultipleSelection ($element, options) {
65457    MultipleSelection.__super__.constructor.apply(this, arguments);
65458  }
65459
65460  Utils.Extend(MultipleSelection, BaseSelection);
65461
65462  MultipleSelection.prototype.render = function () {
65463    var $selection = MultipleSelection.__super__.render.call(this);
65464
65465    $selection.addClass('select2-selection--multiple');
65466
65467    $selection.html(
65468      '<ul class="select2-selection__rendered"></ul>'
65469    );
65470
65471    return $selection;
65472  };
65473
65474  MultipleSelection.prototype.bind = function (container, $container) {
65475    var self = this;
65476
65477    MultipleSelection.__super__.bind.apply(this, arguments);
65478
65479    this.$selection.on('click', function (evt) {
65480      self.trigger('toggle', {
65481        originalEvent: evt
65482      });
65483    });
65484
65485    this.$selection.on(
65486      'click',
65487      '.select2-selection__choice__remove',
65488      function (evt) {
65489        // Ignore the event if it is disabled
65490        if (self.isDisabled()) {
65491          return;
65492        }
65493
65494        var $remove = $(this);
65495        var $selection = $remove.parent();
65496
65497        var data = Utils.GetData($selection[0], 'data');
65498
65499        self.trigger('unselect', {
65500          originalEvent: evt,
65501          data: data
65502        });
65503      }
65504    );
65505  };
65506
65507  MultipleSelection.prototype.clear = function () {
65508    var $rendered = this.$selection.find('.select2-selection__rendered');
65509    $rendered.empty();
65510    $rendered.removeAttr('title');
65511  };
65512
65513  MultipleSelection.prototype.display = function (data, container) {
65514    var template = this.options.get('templateSelection');
65515    var escapeMarkup = this.options.get('escapeMarkup');
65516
65517    return escapeMarkup(template(data, container));
65518  };
65519
65520  MultipleSelection.prototype.selectionContainer = function () {
65521    var $container = $(
65522      '<li class="select2-selection__choice">' +
65523        '<span class="select2-selection__choice__remove" role="presentation">' +
65524          '&times;' +
65525        '</span>' +
65526      '</li>'
65527    );
65528
65529    return $container;
65530  };
65531
65532  MultipleSelection.prototype.update = function (data) {
65533    this.clear();
65534
65535    if (data.length === 0) {
65536      return;
65537    }
65538
65539    var $selections = [];
65540
65541    for (var d = 0; d < data.length; d++) {
65542      var selection = data[d];
65543
65544      var $selection = this.selectionContainer();
65545      var formatted = this.display(selection, $selection);
65546
65547      $selection.append(formatted);
65548
65549      var title = selection.title || selection.text;
65550
65551      if (title) {
65552        $selection.attr('title', title);
65553      }
65554
65555      Utils.StoreData($selection[0], 'data', selection);
65556
65557      $selections.push($selection);
65558    }
65559
65560    var $rendered = this.$selection.find('.select2-selection__rendered');
65561
65562    Utils.appendMany($rendered, $selections);
65563  };
65564
65565  return MultipleSelection;
65566});
65567
65568S2.define('select2/selection/placeholder',[
65569  '../utils'
65570], function (Utils) {
65571  function Placeholder (decorated, $element, options) {
65572    this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
65573
65574    decorated.call(this, $element, options);
65575  }
65576
65577  Placeholder.prototype.normalizePlaceholder = function (_, placeholder) {
65578    if (typeof placeholder === 'string') {
65579      placeholder = {
65580        id: '',
65581        text: placeholder
65582      };
65583    }
65584
65585    return placeholder;
65586  };
65587
65588  Placeholder.prototype.createPlaceholder = function (decorated, placeholder) {
65589    var $placeholder = this.selectionContainer();
65590
65591    $placeholder.html(this.display(placeholder));
65592    $placeholder.addClass('select2-selection__placeholder')
65593                .removeClass('select2-selection__choice');
65594
65595    return $placeholder;
65596  };
65597
65598  Placeholder.prototype.update = function (decorated, data) {
65599    var singlePlaceholder = (
65600      data.length == 1 && data[0].id != this.placeholder.id
65601    );
65602    var multipleSelections = data.length > 1;
65603
65604    if (multipleSelections || singlePlaceholder) {
65605      return decorated.call(this, data);
65606    }
65607
65608    this.clear();
65609
65610    var $placeholder = this.createPlaceholder(this.placeholder);
65611
65612    this.$selection.find('.select2-selection__rendered').append($placeholder);
65613  };
65614
65615  return Placeholder;
65616});
65617
65618S2.define('select2/selection/allowClear',[
65619  'jquery',
65620  '../keys',
65621  '../utils'
65622], function ($, KEYS, Utils) {
65623  function AllowClear () { }
65624
65625  AllowClear.prototype.bind = function (decorated, container, $container) {
65626    var self = this;
65627
65628    decorated.call(this, container, $container);
65629
65630    if (this.placeholder == null) {
65631      if (this.options.get('debug') && window.console && console.error) {
65632        console.error(
65633          'Select2: The `allowClear` option should be used in combination ' +
65634          'with the `placeholder` option.'
65635        );
65636      }
65637    }
65638
65639    this.$selection.on('mousedown', '.select2-selection__clear',
65640      function (evt) {
65641        self._handleClear(evt);
65642    });
65643
65644    container.on('keypress', function (evt) {
65645      self._handleKeyboardClear(evt, container);
65646    });
65647  };
65648
65649  AllowClear.prototype._handleClear = function (_, evt) {
65650    // Ignore the event if it is disabled
65651    if (this.isDisabled()) {
65652      return;
65653    }
65654
65655    var $clear = this.$selection.find('.select2-selection__clear');
65656
65657    // Ignore the event if nothing has been selected
65658    if ($clear.length === 0) {
65659      return;
65660    }
65661
65662    evt.stopPropagation();
65663
65664    var data = Utils.GetData($clear[0], 'data');
65665
65666    var previousVal = this.$element.val();
65667    this.$element.val(this.placeholder.id);
65668
65669    var unselectData = {
65670      data: data
65671    };
65672    this.trigger('clear', unselectData);
65673    if (unselectData.prevented) {
65674      this.$element.val(previousVal);
65675      return;
65676    }
65677
65678    for (var d = 0; d < data.length; d++) {
65679      unselectData = {
65680        data: data[d]
65681      };
65682
65683      // Trigger the `unselect` event, so people can prevent it from being
65684      // cleared.
65685      this.trigger('unselect', unselectData);
65686
65687      // If the event was prevented, don't clear it out.
65688      if (unselectData.prevented) {
65689        this.$element.val(previousVal);
65690        return;
65691      }
65692    }
65693
65694    this.$element.trigger('input').trigger('change');
65695
65696    this.trigger('toggle', {});
65697  };
65698
65699  AllowClear.prototype._handleKeyboardClear = function (_, evt, container) {
65700    if (container.isOpen()) {
65701      return;
65702    }
65703
65704    if (evt.which == KEYS.DELETE || evt.which == KEYS.BACKSPACE) {
65705      this._handleClear(evt);
65706    }
65707  };
65708
65709  AllowClear.prototype.update = function (decorated, data) {
65710    decorated.call(this, data);
65711
65712    if (this.$selection.find('.select2-selection__placeholder').length > 0 ||
65713        data.length === 0) {
65714      return;
65715    }
65716
65717    var removeAll = this.options.get('translations').get('removeAllItems');
65718
65719    var $remove = $(
65720      '<span class="select2-selection__clear" title="' + removeAll() +'">' +
65721        '&times;' +
65722      '</span>'
65723    );
65724    Utils.StoreData($remove[0], 'data', data);
65725
65726    this.$selection.find('.select2-selection__rendered').prepend($remove);
65727  };
65728
65729  return AllowClear;
65730});
65731
65732S2.define('select2/selection/search',[
65733  'jquery',
65734  '../utils',
65735  '../keys'
65736], function ($, Utils, KEYS) {
65737  function Search (decorated, $element, options) {
65738    decorated.call(this, $element, options);
65739  }
65740
65741  Search.prototype.render = function (decorated) {
65742    var $search = $(
65743      '<li class="select2-search select2-search--inline">' +
65744        '<input class="select2-search__field" type="search" tabindex="-1"' +
65745        ' autocomplete="off" autocorrect="off" autocapitalize="none"' +
65746        ' spellcheck="false" role="searchbox" aria-autocomplete="list" />' +
65747      '</li>'
65748    );
65749
65750    this.$searchContainer = $search;
65751    this.$search = $search.find('input');
65752
65753    var $rendered = decorated.call(this);
65754
65755    this._transferTabIndex();
65756
65757    return $rendered;
65758  };
65759
65760  Search.prototype.bind = function (decorated, container, $container) {
65761    var self = this;
65762
65763    var resultsId = container.id + '-results';
65764
65765    decorated.call(this, container, $container);
65766
65767    container.on('open', function () {
65768      self.$search.attr('aria-controls', resultsId);
65769      self.$search.trigger('focus');
65770    });
65771
65772    container.on('close', function () {
65773      self.$search.val('');
65774      self.$search.removeAttr('aria-controls');
65775      self.$search.removeAttr('aria-activedescendant');
65776      self.$search.trigger('focus');
65777    });
65778
65779    container.on('enable', function () {
65780      self.$search.prop('disabled', false);
65781
65782      self._transferTabIndex();
65783    });
65784
65785    container.on('disable', function () {
65786      self.$search.prop('disabled', true);
65787    });
65788
65789    container.on('focus', function (evt) {
65790      self.$search.trigger('focus');
65791    });
65792
65793    container.on('results:focus', function (params) {
65794      if (params.data._resultId) {
65795        self.$search.attr('aria-activedescendant', params.data._resultId);
65796      } else {
65797        self.$search.removeAttr('aria-activedescendant');
65798      }
65799    });
65800
65801    this.$selection.on('focusin', '.select2-search--inline', function (evt) {
65802      self.trigger('focus', evt);
65803    });
65804
65805    this.$selection.on('focusout', '.select2-search--inline', function (evt) {
65806      self._handleBlur(evt);
65807    });
65808
65809    this.$selection.on('keydown', '.select2-search--inline', function (evt) {
65810      evt.stopPropagation();
65811
65812      self.trigger('keypress', evt);
65813
65814      self._keyUpPrevented = evt.isDefaultPrevented();
65815
65816      var key = evt.which;
65817
65818      if (key === KEYS.BACKSPACE && self.$search.val() === '') {
65819        var $previousChoice = self.$searchContainer
65820          .prev('.select2-selection__choice');
65821
65822        if ($previousChoice.length > 0) {
65823          var item = Utils.GetData($previousChoice[0], 'data');
65824
65825          self.searchRemoveChoice(item);
65826
65827          evt.preventDefault();
65828        }
65829      }
65830    });
65831
65832    this.$selection.on('click', '.select2-search--inline', function (evt) {
65833      if (self.$search.val()) {
65834        evt.stopPropagation();
65835      }
65836    });
65837
65838    // Try to detect the IE version should the `documentMode` property that
65839    // is stored on the document. This is only implemented in IE and is
65840    // slightly cleaner than doing a user agent check.
65841    // This property is not available in Edge, but Edge also doesn't have
65842    // this bug.
65843    var msie = document.documentMode;
65844    var disableInputEvents = msie && msie <= 11;
65845
65846    // Workaround for browsers which do not support the `input` event
65847    // This will prevent double-triggering of events for browsers which support
65848    // both the `keyup` and `input` events.
65849    this.$selection.on(
65850      'input.searchcheck',
65851      '.select2-search--inline',
65852      function (evt) {
65853        // IE will trigger the `input` event when a placeholder is used on a
65854        // search box. To get around this issue, we are forced to ignore all
65855        // `input` events in IE and keep using `keyup`.
65856        if (disableInputEvents) {
65857          self.$selection.off('input.search input.searchcheck');
65858          return;
65859        }
65860
65861        // Unbind the duplicated `keyup` event
65862        self.$selection.off('keyup.search');
65863      }
65864    );
65865
65866    this.$selection.on(
65867      'keyup.search input.search',
65868      '.select2-search--inline',
65869      function (evt) {
65870        // IE will trigger the `input` event when a placeholder is used on a
65871        // search box. To get around this issue, we are forced to ignore all
65872        // `input` events in IE and keep using `keyup`.
65873        if (disableInputEvents && evt.type === 'input') {
65874          self.$selection.off('input.search input.searchcheck');
65875          return;
65876        }
65877
65878        var key = evt.which;
65879
65880        // We can freely ignore events from modifier keys
65881        if (key == KEYS.SHIFT || key == KEYS.CTRL || key == KEYS.ALT) {
65882          return;
65883        }
65884
65885        // Tabbing will be handled during the `keydown` phase
65886        if (key == KEYS.TAB) {
65887          return;
65888        }
65889
65890        self.handleSearch(evt);
65891      }
65892    );
65893  };
65894
65895  /**
65896   * This method will transfer the tabindex attribute from the rendered
65897   * selection to the search box. This allows for the search box to be used as
65898   * the primary focus instead of the selection container.
65899   *
65900   * @private
65901   */
65902  Search.prototype._transferTabIndex = function (decorated) {
65903    this.$search.attr('tabindex', this.$selection.attr('tabindex'));
65904    this.$selection.attr('tabindex', '-1');
65905  };
65906
65907  Search.prototype.createPlaceholder = function (decorated, placeholder) {
65908    this.$search.attr('placeholder', placeholder.text);
65909  };
65910
65911  Search.prototype.update = function (decorated, data) {
65912    var searchHadFocus = this.$search[0] == document.activeElement;
65913
65914    this.$search.attr('placeholder', '');
65915
65916    decorated.call(this, data);
65917
65918    this.$selection.find('.select2-selection__rendered')
65919                   .append(this.$searchContainer);
65920
65921    this.resizeSearch();
65922    if (searchHadFocus) {
65923      this.$search.trigger('focus');
65924    }
65925  };
65926
65927  Search.prototype.handleSearch = function () {
65928    this.resizeSearch();
65929
65930    if (!this._keyUpPrevented) {
65931      var input = this.$search.val();
65932
65933      this.trigger('query', {
65934        term: input
65935      });
65936    }
65937
65938    this._keyUpPrevented = false;
65939  };
65940
65941  Search.prototype.searchRemoveChoice = function (decorated, item) {
65942    this.trigger('unselect', {
65943      data: item
65944    });
65945
65946    this.$search.val(item.text);
65947    this.handleSearch();
65948  };
65949
65950  Search.prototype.resizeSearch = function () {
65951    this.$search.css('width', '25px');
65952
65953    var width = '';
65954
65955    if (this.$search.attr('placeholder') !== '') {
65956      width = this.$selection.find('.select2-selection__rendered').width();
65957    } else {
65958      var minimumWidth = this.$search.val().length + 1;
65959
65960      width = (minimumWidth * 0.75) + 'em';
65961    }
65962
65963    this.$search.css('width', width);
65964  };
65965
65966  return Search;
65967});
65968
65969S2.define('select2/selection/eventRelay',[
65970  'jquery'
65971], function ($) {
65972  function EventRelay () { }
65973
65974  EventRelay.prototype.bind = function (decorated, container, $container) {
65975    var self = this;
65976    var relayEvents = [
65977      'open', 'opening',
65978      'close', 'closing',
65979      'select', 'selecting',
65980      'unselect', 'unselecting',
65981      'clear', 'clearing'
65982    ];
65983
65984    var preventableEvents = [
65985      'opening', 'closing', 'selecting', 'unselecting', 'clearing'
65986    ];
65987
65988    decorated.call(this, container, $container);
65989
65990    container.on('*', function (name, params) {
65991      // Ignore events that should not be relayed
65992      if ($.inArray(name, relayEvents) === -1) {
65993        return;
65994      }
65995
65996      // The parameters should always be an object
65997      params = params || {};
65998
65999      // Generate the jQuery event for the Select2 event
66000      var evt = $.Event('select2:' + name, {
66001        params: params
66002      });
66003
66004      self.$element.trigger(evt);
66005
66006      // Only handle preventable events if it was one
66007      if ($.inArray(name, preventableEvents) === -1) {
66008        return;
66009      }
66010
66011      params.prevented = evt.isDefaultPrevented();
66012    });
66013  };
66014
66015  return EventRelay;
66016});
66017
66018S2.define('select2/translation',[
66019  'jquery',
66020  'require'
66021], function ($, require) {
66022  function Translation (dict) {
66023    this.dict = dict || {};
66024  }
66025
66026  Translation.prototype.all = function () {
66027    return this.dict;
66028  };
66029
66030  Translation.prototype.get = function (key) {
66031    return this.dict[key];
66032  };
66033
66034  Translation.prototype.extend = function (translation) {
66035    this.dict = $.extend({}, translation.all(), this.dict);
66036  };
66037
66038  // Static functions
66039
66040  Translation._cache = {};
66041
66042  Translation.loadPath = function (path) {
66043    if (!(path in Translation._cache)) {
66044      var translations = require(path);
66045
66046      Translation._cache[path] = translations;
66047    }
66048
66049    return new Translation(Translation._cache[path]);
66050  };
66051
66052  return Translation;
66053});
66054
66055S2.define('select2/diacritics',[
66056
66057], function () {
66058  var diacritics = {
66059    '\u24B6': 'A',
66060    '\uFF21': 'A',
66061    '\u00C0': 'A',
66062    '\u00C1': 'A',
66063    '\u00C2': 'A',
66064    '\u1EA6': 'A',
66065    '\u1EA4': 'A',
66066    '\u1EAA': 'A',
66067    '\u1EA8': 'A',
66068    '\u00C3': 'A',
66069    '\u0100': 'A',
66070    '\u0102': 'A',
66071    '\u1EB0': 'A',
66072    '\u1EAE': 'A',
66073    '\u1EB4': 'A',
66074    '\u1EB2': 'A',
66075    '\u0226': 'A',
66076    '\u01E0': 'A',
66077    '\u00C4': 'A',
66078    '\u01DE': 'A',
66079    '\u1EA2': 'A',
66080    '\u00C5': 'A',
66081    '\u01FA': 'A',
66082    '\u01CD': 'A',
66083    '\u0200': 'A',
66084    '\u0202': 'A',
66085    '\u1EA0': 'A',
66086    '\u1EAC': 'A',
66087    '\u1EB6': 'A',
66088    '\u1E00': 'A',
66089    '\u0104': 'A',
66090    '\u023A': 'A',
66091    '\u2C6F': 'A',
66092    '\uA732': 'AA',
66093    '\u00C6': 'AE',
66094    '\u01FC': 'AE',
66095    '\u01E2': 'AE',
66096    '\uA734': 'AO',
66097    '\uA736': 'AU',
66098    '\uA738': 'AV',
66099    '\uA73A': 'AV',
66100    '\uA73C': 'AY',
66101    '\u24B7': 'B',
66102    '\uFF22': 'B',
66103    '\u1E02': 'B',
66104    '\u1E04': 'B',
66105    '\u1E06': 'B',
66106    '\u0243': 'B',
66107    '\u0182': 'B',
66108    '\u0181': 'B',
66109    '\u24B8': 'C',
66110    '\uFF23': 'C',
66111    '\u0106': 'C',
66112    '\u0108': 'C',
66113    '\u010A': 'C',
66114    '\u010C': 'C',
66115    '\u00C7': 'C',
66116    '\u1E08': 'C',
66117    '\u0187': 'C',
66118    '\u023B': 'C',
66119    '\uA73E': 'C',
66120    '\u24B9': 'D',
66121    '\uFF24': 'D',
66122    '\u1E0A': 'D',
66123    '\u010E': 'D',
66124    '\u1E0C': 'D',
66125    '\u1E10': 'D',
66126    '\u1E12': 'D',
66127    '\u1E0E': 'D',
66128    '\u0110': 'D',
66129    '\u018B': 'D',
66130    '\u018A': 'D',
66131    '\u0189': 'D',
66132    '\uA779': 'D',
66133    '\u01F1': 'DZ',
66134    '\u01C4': 'DZ',
66135    '\u01F2': 'Dz',
66136    '\u01C5': 'Dz',
66137    '\u24BA': 'E',
66138    '\uFF25': 'E',
66139    '\u00C8': 'E',
66140    '\u00C9': 'E',
66141    '\u00CA': 'E',
66142    '\u1EC0': 'E',
66143    '\u1EBE': 'E',
66144    '\u1EC4': 'E',
66145    '\u1EC2': 'E',
66146    '\u1EBC': 'E',
66147    '\u0112': 'E',
66148    '\u1E14': 'E',
66149    '\u1E16': 'E',
66150    '\u0114': 'E',
66151    '\u0116': 'E',
66152    '\u00CB': 'E',
66153    '\u1EBA': 'E',
66154    '\u011A': 'E',
66155    '\u0204': 'E',
66156    '\u0206': 'E',
66157    '\u1EB8': 'E',
66158    '\u1EC6': 'E',
66159    '\u0228': 'E',
66160    '\u1E1C': 'E',
66161    '\u0118': 'E',
66162    '\u1E18': 'E',
66163    '\u1E1A': 'E',
66164    '\u0190': 'E',
66165    '\u018E': 'E',
66166    '\u24BB': 'F',
66167    '\uFF26': 'F',
66168    '\u1E1E': 'F',
66169    '\u0191': 'F',
66170    '\uA77B': 'F',
66171    '\u24BC': 'G',
66172    '\uFF27': 'G',
66173    '\u01F4': 'G',
66174    '\u011C': 'G',
66175    '\u1E20': 'G',
66176    '\u011E': 'G',
66177    '\u0120': 'G',
66178    '\u01E6': 'G',
66179    '\u0122': 'G',
66180    '\u01E4': 'G',
66181    '\u0193': 'G',
66182    '\uA7A0': 'G',
66183    '\uA77D': 'G',
66184    '\uA77E': 'G',
66185    '\u24BD': 'H',
66186    '\uFF28': 'H',
66187    '\u0124': 'H',
66188    '\u1E22': 'H',
66189    '\u1E26': 'H',
66190    '\u021E': 'H',
66191    '\u1E24': 'H',
66192    '\u1E28': 'H',
66193    '\u1E2A': 'H',
66194    '\u0126': 'H',
66195    '\u2C67': 'H',
66196    '\u2C75': 'H',
66197    '\uA78D': 'H',
66198    '\u24BE': 'I',
66199    '\uFF29': 'I',
66200    '\u00CC': 'I',
66201    '\u00CD': 'I',
66202    '\u00CE': 'I',
66203    '\u0128': 'I',
66204    '\u012A': 'I',
66205    '\u012C': 'I',
66206    '\u0130': 'I',
66207    '\u00CF': 'I',
66208    '\u1E2E': 'I',
66209    '\u1EC8': 'I',
66210    '\u01CF': 'I',
66211    '\u0208': 'I',
66212    '\u020A': 'I',
66213    '\u1ECA': 'I',
66214    '\u012E': 'I',
66215    '\u1E2C': 'I',
66216    '\u0197': 'I',
66217    '\u24BF': 'J',
66218    '\uFF2A': 'J',
66219    '\u0134': 'J',
66220    '\u0248': 'J',
66221    '\u24C0': 'K',
66222    '\uFF2B': 'K',
66223    '\u1E30': 'K',
66224    '\u01E8': 'K',
66225    '\u1E32': 'K',
66226    '\u0136': 'K',
66227    '\u1E34': 'K',
66228    '\u0198': 'K',
66229    '\u2C69': 'K',
66230    '\uA740': 'K',
66231    '\uA742': 'K',
66232    '\uA744': 'K',
66233    '\uA7A2': 'K',
66234    '\u24C1': 'L',
66235    '\uFF2C': 'L',
66236    '\u013F': 'L',
66237    '\u0139': 'L',
66238    '\u013D': 'L',
66239    '\u1E36': 'L',
66240    '\u1E38': 'L',
66241    '\u013B': 'L',
66242    '\u1E3C': 'L',
66243    '\u1E3A': 'L',
66244    '\u0141': 'L',
66245    '\u023D': 'L',
66246    '\u2C62': 'L',
66247    '\u2C60': 'L',
66248    '\uA748': 'L',
66249    '\uA746': 'L',
66250    '\uA780': 'L',
66251    '\u01C7': 'LJ',
66252    '\u01C8': 'Lj',
66253    '\u24C2': 'M',
66254    '\uFF2D': 'M',
66255    '\u1E3E': 'M',
66256    '\u1E40': 'M',
66257    '\u1E42': 'M',
66258    '\u2C6E': 'M',
66259    '\u019C': 'M',
66260    '\u24C3': 'N',
66261    '\uFF2E': 'N',
66262    '\u01F8': 'N',
66263    '\u0143': 'N',
66264    '\u00D1': 'N',
66265    '\u1E44': 'N',
66266    '\u0147': 'N',
66267    '\u1E46': 'N',
66268    '\u0145': 'N',
66269    '\u1E4A': 'N',
66270    '\u1E48': 'N',
66271    '\u0220': 'N',
66272    '\u019D': 'N',
66273    '\uA790': 'N',
66274    '\uA7A4': 'N',
66275    '\u01CA': 'NJ',
66276    '\u01CB': 'Nj',
66277    '\u24C4': 'O',
66278    '\uFF2F': 'O',
66279    '\u00D2': 'O',
66280    '\u00D3': 'O',
66281    '\u00D4': 'O',
66282    '\u1ED2': 'O',
66283    '\u1ED0': 'O',
66284    '\u1ED6': 'O',
66285    '\u1ED4': 'O',
66286    '\u00D5': 'O',
66287    '\u1E4C': 'O',
66288    '\u022C': 'O',
66289    '\u1E4E': 'O',
66290    '\u014C': 'O',
66291    '\u1E50': 'O',
66292    '\u1E52': 'O',
66293    '\u014E': 'O',
66294    '\u022E': 'O',
66295    '\u0230': 'O',
66296    '\u00D6': 'O',
66297    '\u022A': 'O',
66298    '\u1ECE': 'O',
66299    '\u0150': 'O',
66300    '\u01D1': 'O',
66301    '\u020C': 'O',
66302    '\u020E': 'O',
66303    '\u01A0': 'O',
66304    '\u1EDC': 'O',
66305    '\u1EDA': 'O',
66306    '\u1EE0': 'O',
66307    '\u1EDE': 'O',
66308    '\u1EE2': 'O',
66309    '\u1ECC': 'O',
66310    '\u1ED8': 'O',
66311    '\u01EA': 'O',
66312    '\u01EC': 'O',
66313    '\u00D8': 'O',
66314    '\u01FE': 'O',
66315    '\u0186': 'O',
66316    '\u019F': 'O',
66317    '\uA74A': 'O',
66318    '\uA74C': 'O',
66319    '\u0152': 'OE',
66320    '\u01A2': 'OI',
66321    '\uA74E': 'OO',
66322    '\u0222': 'OU',
66323    '\u24C5': 'P',
66324    '\uFF30': 'P',
66325    '\u1E54': 'P',
66326    '\u1E56': 'P',
66327    '\u01A4': 'P',
66328    '\u2C63': 'P',
66329    '\uA750': 'P',
66330    '\uA752': 'P',
66331    '\uA754': 'P',
66332    '\u24C6': 'Q',
66333    '\uFF31': 'Q',
66334    '\uA756': 'Q',
66335    '\uA758': 'Q',
66336    '\u024A': 'Q',
66337    '\u24C7': 'R',
66338    '\uFF32': 'R',
66339    '\u0154': 'R',
66340    '\u1E58': 'R',
66341    '\u0158': 'R',
66342    '\u0210': 'R',
66343    '\u0212': 'R',
66344    '\u1E5A': 'R',
66345    '\u1E5C': 'R',
66346    '\u0156': 'R',
66347    '\u1E5E': 'R',
66348    '\u024C': 'R',
66349    '\u2C64': 'R',
66350    '\uA75A': 'R',
66351    '\uA7A6': 'R',
66352    '\uA782': 'R',
66353    '\u24C8': 'S',
66354    '\uFF33': 'S',
66355    '\u1E9E': 'S',
66356    '\u015A': 'S',
66357    '\u1E64': 'S',
66358    '\u015C': 'S',
66359    '\u1E60': 'S',
66360    '\u0160': 'S',
66361    '\u1E66': 'S',
66362    '\u1E62': 'S',
66363    '\u1E68': 'S',
66364    '\u0218': 'S',
66365    '\u015E': 'S',
66366    '\u2C7E': 'S',
66367    '\uA7A8': 'S',
66368    '\uA784': 'S',
66369    '\u24C9': 'T',
66370    '\uFF34': 'T',
66371    '\u1E6A': 'T',
66372    '\u0164': 'T',
66373    '\u1E6C': 'T',
66374    '\u021A': 'T',
66375    '\u0162': 'T',
66376    '\u1E70': 'T',
66377    '\u1E6E': 'T',
66378    '\u0166': 'T',
66379    '\u01AC': 'T',
66380    '\u01AE': 'T',
66381    '\u023E': 'T',
66382    '\uA786': 'T',
66383    '\uA728': 'TZ',
66384    '\u24CA': 'U',
66385    '\uFF35': 'U',
66386    '\u00D9': 'U',
66387    '\u00DA': 'U',
66388    '\u00DB': 'U',
66389    '\u0168': 'U',
66390    '\u1E78': 'U',
66391    '\u016A': 'U',
66392    '\u1E7A': 'U',
66393    '\u016C': 'U',
66394    '\u00DC': 'U',
66395    '\u01DB': 'U',
66396    '\u01D7': 'U',
66397    '\u01D5': 'U',
66398    '\u01D9': 'U',
66399    '\u1EE6': 'U',
66400    '\u016E': 'U',
66401    '\u0170': 'U',
66402    '\u01D3': 'U',
66403    '\u0214': 'U',
66404    '\u0216': 'U',
66405    '\u01AF': 'U',
66406    '\u1EEA': 'U',
66407    '\u1EE8': 'U',
66408    '\u1EEE': 'U',
66409    '\u1EEC': 'U',
66410    '\u1EF0': 'U',
66411    '\u1EE4': 'U',
66412    '\u1E72': 'U',
66413    '\u0172': 'U',
66414    '\u1E76': 'U',
66415    '\u1E74': 'U',
66416    '\u0244': 'U',
66417    '\u24CB': 'V',
66418    '\uFF36': 'V',
66419    '\u1E7C': 'V',
66420    '\u1E7E': 'V',
66421    '\u01B2': 'V',
66422    '\uA75E': 'V',
66423    '\u0245': 'V',
66424    '\uA760': 'VY',
66425    '\u24CC': 'W',
66426    '\uFF37': 'W',
66427    '\u1E80': 'W',
66428    '\u1E82': 'W',
66429    '\u0174': 'W',
66430    '\u1E86': 'W',
66431    '\u1E84': 'W',
66432    '\u1E88': 'W',
66433    '\u2C72': 'W',
66434    '\u24CD': 'X',
66435    '\uFF38': 'X',
66436    '\u1E8A': 'X',
66437    '\u1E8C': 'X',
66438    '\u24CE': 'Y',
66439    '\uFF39': 'Y',
66440    '\u1EF2': 'Y',
66441    '\u00DD': 'Y',
66442    '\u0176': 'Y',
66443    '\u1EF8': 'Y',
66444    '\u0232': 'Y',
66445    '\u1E8E': 'Y',
66446    '\u0178': 'Y',
66447    '\u1EF6': 'Y',
66448    '\u1EF4': 'Y',
66449    '\u01B3': 'Y',
66450    '\u024E': 'Y',
66451    '\u1EFE': 'Y',
66452    '\u24CF': 'Z',
66453    '\uFF3A': 'Z',
66454    '\u0179': 'Z',
66455    '\u1E90': 'Z',
66456    '\u017B': 'Z',
66457    '\u017D': 'Z',
66458    '\u1E92': 'Z',
66459    '\u1E94': 'Z',
66460    '\u01B5': 'Z',
66461    '\u0224': 'Z',
66462    '\u2C7F': 'Z',
66463    '\u2C6B': 'Z',
66464    '\uA762': 'Z',
66465    '\u24D0': 'a',
66466    '\uFF41': 'a',
66467    '\u1E9A': 'a',
66468    '\u00E0': 'a',
66469    '\u00E1': 'a',
66470    '\u00E2': 'a',
66471    '\u1EA7': 'a',
66472    '\u1EA5': 'a',
66473    '\u1EAB': 'a',
66474    '\u1EA9': 'a',
66475    '\u00E3': 'a',
66476    '\u0101': 'a',
66477    '\u0103': 'a',
66478    '\u1EB1': 'a',
66479    '\u1EAF': 'a',
66480    '\u1EB5': 'a',
66481    '\u1EB3': 'a',
66482    '\u0227': 'a',
66483    '\u01E1': 'a',
66484    '\u00E4': 'a',
66485    '\u01DF': 'a',
66486    '\u1EA3': 'a',
66487    '\u00E5': 'a',
66488    '\u01FB': 'a',
66489    '\u01CE': 'a',
66490    '\u0201': 'a',
66491    '\u0203': 'a',
66492    '\u1EA1': 'a',
66493    '\u1EAD': 'a',
66494    '\u1EB7': 'a',
66495    '\u1E01': 'a',
66496    '\u0105': 'a',
66497    '\u2C65': 'a',
66498    '\u0250': 'a',
66499    '\uA733': 'aa',
66500    '\u00E6': 'ae',
66501    '\u01FD': 'ae',
66502    '\u01E3': 'ae',
66503    '\uA735': 'ao',
66504    '\uA737': 'au',
66505    '\uA739': 'av',
66506    '\uA73B': 'av',
66507    '\uA73D': 'ay',
66508    '\u24D1': 'b',
66509    '\uFF42': 'b',
66510    '\u1E03': 'b',
66511    '\u1E05': 'b',
66512    '\u1E07': 'b',
66513    '\u0180': 'b',
66514    '\u0183': 'b',
66515    '\u0253': 'b',
66516    '\u24D2': 'c',
66517    '\uFF43': 'c',
66518    '\u0107': 'c',
66519    '\u0109': 'c',
66520    '\u010B': 'c',
66521    '\u010D': 'c',
66522    '\u00E7': 'c',
66523    '\u1E09': 'c',
66524    '\u0188': 'c',
66525    '\u023C': 'c',
66526    '\uA73F': 'c',
66527    '\u2184': 'c',
66528    '\u24D3': 'd',
66529    '\uFF44': 'd',
66530    '\u1E0B': 'd',
66531    '\u010F': 'd',
66532    '\u1E0D': 'd',
66533    '\u1E11': 'd',
66534    '\u1E13': 'd',
66535    '\u1E0F': 'd',
66536    '\u0111': 'd',
66537    '\u018C': 'd',
66538    '\u0256': 'd',
66539    '\u0257': 'd',
66540    '\uA77A': 'd',
66541    '\u01F3': 'dz',
66542    '\u01C6': 'dz',
66543    '\u24D4': 'e',
66544    '\uFF45': 'e',
66545    '\u00E8': 'e',
66546    '\u00E9': 'e',
66547    '\u00EA': 'e',
66548    '\u1EC1': 'e',
66549    '\u1EBF': 'e',
66550    '\u1EC5': 'e',
66551    '\u1EC3': 'e',
66552    '\u1EBD': 'e',
66553    '\u0113': 'e',
66554    '\u1E15': 'e',
66555    '\u1E17': 'e',
66556    '\u0115': 'e',
66557    '\u0117': 'e',
66558    '\u00EB': 'e',
66559    '\u1EBB': 'e',
66560    '\u011B': 'e',
66561    '\u0205': 'e',
66562    '\u0207': 'e',
66563    '\u1EB9': 'e',
66564    '\u1EC7': 'e',
66565    '\u0229': 'e',
66566    '\u1E1D': 'e',
66567    '\u0119': 'e',
66568    '\u1E19': 'e',
66569    '\u1E1B': 'e',
66570    '\u0247': 'e',
66571    '\u025B': 'e',
66572    '\u01DD': 'e',
66573    '\u24D5': 'f',
66574    '\uFF46': 'f',
66575    '\u1E1F': 'f',
66576    '\u0192': 'f',
66577    '\uA77C': 'f',
66578    '\u24D6': 'g',
66579    '\uFF47': 'g',
66580    '\u01F5': 'g',
66581    '\u011D': 'g',
66582    '\u1E21': 'g',
66583    '\u011F': 'g',
66584    '\u0121': 'g',
66585    '\u01E7': 'g',
66586    '\u0123': 'g',
66587    '\u01E5': 'g',
66588    '\u0260': 'g',
66589    '\uA7A1': 'g',
66590    '\u1D79': 'g',
66591    '\uA77F': 'g',
66592    '\u24D7': 'h',
66593    '\uFF48': 'h',
66594    '\u0125': 'h',
66595    '\u1E23': 'h',
66596    '\u1E27': 'h',
66597    '\u021F': 'h',
66598    '\u1E25': 'h',
66599    '\u1E29': 'h',
66600    '\u1E2B': 'h',
66601    '\u1E96': 'h',
66602    '\u0127': 'h',
66603    '\u2C68': 'h',
66604    '\u2C76': 'h',
66605    '\u0265': 'h',
66606    '\u0195': 'hv',
66607    '\u24D8': 'i',
66608    '\uFF49': 'i',
66609    '\u00EC': 'i',
66610    '\u00ED': 'i',
66611    '\u00EE': 'i',
66612    '\u0129': 'i',
66613    '\u012B': 'i',
66614    '\u012D': 'i',
66615    '\u00EF': 'i',
66616    '\u1E2F': 'i',
66617    '\u1EC9': 'i',
66618    '\u01D0': 'i',
66619    '\u0209': 'i',
66620    '\u020B': 'i',
66621    '\u1ECB': 'i',
66622    '\u012F': 'i',
66623    '\u1E2D': 'i',
66624    '\u0268': 'i',
66625    '\u0131': 'i',
66626    '\u24D9': 'j',
66627    '\uFF4A': 'j',
66628    '\u0135': 'j',
66629    '\u01F0': 'j',
66630    '\u0249': 'j',
66631    '\u24DA': 'k',
66632    '\uFF4B': 'k',
66633    '\u1E31': 'k',
66634    '\u01E9': 'k',
66635    '\u1E33': 'k',
66636    '\u0137': 'k',
66637    '\u1E35': 'k',
66638    '\u0199': 'k',
66639    '\u2C6A': 'k',
66640    '\uA741': 'k',
66641    '\uA743': 'k',
66642    '\uA745': 'k',
66643    '\uA7A3': 'k',
66644    '\u24DB': 'l',
66645    '\uFF4C': 'l',
66646    '\u0140': 'l',
66647    '\u013A': 'l',
66648    '\u013E': 'l',
66649    '\u1E37': 'l',
66650    '\u1E39': 'l',
66651    '\u013C': 'l',
66652    '\u1E3D': 'l',
66653    '\u1E3B': 'l',
66654    '\u017F': 'l',
66655    '\u0142': 'l',
66656    '\u019A': 'l',
66657    '\u026B': 'l',
66658    '\u2C61': 'l',
66659    '\uA749': 'l',
66660    '\uA781': 'l',
66661    '\uA747': 'l',
66662    '\u01C9': 'lj',
66663    '\u24DC': 'm',
66664    '\uFF4D': 'm',
66665    '\u1E3F': 'm',
66666    '\u1E41': 'm',
66667    '\u1E43': 'm',
66668    '\u0271': 'm',
66669    '\u026F': 'm',
66670    '\u24DD': 'n',
66671    '\uFF4E': 'n',
66672    '\u01F9': 'n',
66673    '\u0144': 'n',
66674    '\u00F1': 'n',
66675    '\u1E45': 'n',
66676    '\u0148': 'n',
66677    '\u1E47': 'n',
66678    '\u0146': 'n',
66679    '\u1E4B': 'n',
66680    '\u1E49': 'n',
66681    '\u019E': 'n',
66682    '\u0272': 'n',
66683    '\u0149': 'n',
66684    '\uA791': 'n',
66685    '\uA7A5': 'n',
66686    '\u01CC': 'nj',
66687    '\u24DE': 'o',
66688    '\uFF4F': 'o',
66689    '\u00F2': 'o',
66690    '\u00F3': 'o',
66691    '\u00F4': 'o',
66692    '\u1ED3': 'o',
66693    '\u1ED1': 'o',
66694    '\u1ED7': 'o',
66695    '\u1ED5': 'o',
66696    '\u00F5': 'o',
66697    '\u1E4D': 'o',
66698    '\u022D': 'o',
66699    '\u1E4F': 'o',
66700    '\u014D': 'o',
66701    '\u1E51': 'o',
66702    '\u1E53': 'o',
66703    '\u014F': 'o',
66704    '\u022F': 'o',
66705    '\u0231': 'o',
66706    '\u00F6': 'o',
66707    '\u022B': 'o',
66708    '\u1ECF': 'o',
66709    '\u0151': 'o',
66710    '\u01D2': 'o',
66711    '\u020D': 'o',
66712    '\u020F': 'o',
66713    '\u01A1': 'o',
66714    '\u1EDD': 'o',
66715    '\u1EDB': 'o',
66716    '\u1EE1': 'o',
66717    '\u1EDF': 'o',
66718    '\u1EE3': 'o',
66719    '\u1ECD': 'o',
66720    '\u1ED9': 'o',
66721    '\u01EB': 'o',
66722    '\u01ED': 'o',
66723    '\u00F8': 'o',
66724    '\u01FF': 'o',
66725    '\u0254': 'o',
66726    '\uA74B': 'o',
66727    '\uA74D': 'o',
66728    '\u0275': 'o',
66729    '\u0153': 'oe',
66730    '\u01A3': 'oi',
66731    '\u0223': 'ou',
66732    '\uA74F': 'oo',
66733    '\u24DF': 'p',
66734    '\uFF50': 'p',
66735    '\u1E55': 'p',
66736    '\u1E57': 'p',
66737    '\u01A5': 'p',
66738    '\u1D7D': 'p',
66739    '\uA751': 'p',
66740    '\uA753': 'p',
66741    '\uA755': 'p',
66742    '\u24E0': 'q',
66743    '\uFF51': 'q',
66744    '\u024B': 'q',
66745    '\uA757': 'q',
66746    '\uA759': 'q',
66747    '\u24E1': 'r',
66748    '\uFF52': 'r',
66749    '\u0155': 'r',
66750    '\u1E59': 'r',
66751    '\u0159': 'r',
66752    '\u0211': 'r',
66753    '\u0213': 'r',
66754    '\u1E5B': 'r',
66755    '\u1E5D': 'r',
66756    '\u0157': 'r',
66757    '\u1E5F': 'r',
66758    '\u024D': 'r',
66759    '\u027D': 'r',
66760    '\uA75B': 'r',
66761    '\uA7A7': 'r',
66762    '\uA783': 'r',
66763    '\u24E2': 's',
66764    '\uFF53': 's',
66765    '\u00DF': 's',
66766    '\u015B': 's',
66767    '\u1E65': 's',
66768    '\u015D': 's',
66769    '\u1E61': 's',
66770    '\u0161': 's',
66771    '\u1E67': 's',
66772    '\u1E63': 's',
66773    '\u1E69': 's',
66774    '\u0219': 's',
66775    '\u015F': 's',
66776    '\u023F': 's',
66777    '\uA7A9': 's',
66778    '\uA785': 's',
66779    '\u1E9B': 's',
66780    '\u24E3': 't',
66781    '\uFF54': 't',
66782    '\u1E6B': 't',
66783    '\u1E97': 't',
66784    '\u0165': 't',
66785    '\u1E6D': 't',
66786    '\u021B': 't',
66787    '\u0163': 't',
66788    '\u1E71': 't',
66789    '\u1E6F': 't',
66790    '\u0167': 't',
66791    '\u01AD': 't',
66792    '\u0288': 't',
66793    '\u2C66': 't',
66794    '\uA787': 't',
66795    '\uA729': 'tz',
66796    '\u24E4': 'u',
66797    '\uFF55': 'u',
66798    '\u00F9': 'u',
66799    '\u00FA': 'u',
66800    '\u00FB': 'u',
66801    '\u0169': 'u',
66802    '\u1E79': 'u',
66803    '\u016B': 'u',
66804    '\u1E7B': 'u',
66805    '\u016D': 'u',
66806    '\u00FC': 'u',
66807    '\u01DC': 'u',
66808    '\u01D8': 'u',
66809    '\u01D6': 'u',
66810    '\u01DA': 'u',
66811    '\u1EE7': 'u',
66812    '\u016F': 'u',
66813    '\u0171': 'u',
66814    '\u01D4': 'u',
66815    '\u0215': 'u',
66816    '\u0217': 'u',
66817    '\u01B0': 'u',
66818    '\u1EEB': 'u',
66819    '\u1EE9': 'u',
66820    '\u1EEF': 'u',
66821    '\u1EED': 'u',
66822    '\u1EF1': 'u',
66823    '\u1EE5': 'u',
66824    '\u1E73': 'u',
66825    '\u0173': 'u',
66826    '\u1E77': 'u',
66827    '\u1E75': 'u',
66828    '\u0289': 'u',
66829    '\u24E5': 'v',
66830    '\uFF56': 'v',
66831    '\u1E7D': 'v',
66832    '\u1E7F': 'v',
66833    '\u028B': 'v',
66834    '\uA75F': 'v',
66835    '\u028C': 'v',
66836    '\uA761': 'vy',
66837    '\u24E6': 'w',
66838    '\uFF57': 'w',
66839    '\u1E81': 'w',
66840    '\u1E83': 'w',
66841    '\u0175': 'w',
66842    '\u1E87': 'w',
66843    '\u1E85': 'w',
66844    '\u1E98': 'w',
66845    '\u1E89': 'w',
66846    '\u2C73': 'w',
66847    '\u24E7': 'x',
66848    '\uFF58': 'x',
66849    '\u1E8B': 'x',
66850    '\u1E8D': 'x',
66851    '\u24E8': 'y',
66852    '\uFF59': 'y',
66853    '\u1EF3': 'y',
66854    '\u00FD': 'y',
66855    '\u0177': 'y',
66856    '\u1EF9': 'y',
66857    '\u0233': 'y',
66858    '\u1E8F': 'y',
66859    '\u00FF': 'y',
66860    '\u1EF7': 'y',
66861    '\u1E99': 'y',
66862    '\u1EF5': 'y',
66863    '\u01B4': 'y',
66864    '\u024F': 'y',
66865    '\u1EFF': 'y',
66866    '\u24E9': 'z',
66867    '\uFF5A': 'z',
66868    '\u017A': 'z',
66869    '\u1E91': 'z',
66870    '\u017C': 'z',
66871    '\u017E': 'z',
66872    '\u1E93': 'z',
66873    '\u1E95': 'z',
66874    '\u01B6': 'z',
66875    '\u0225': 'z',
66876    '\u0240': 'z',
66877    '\u2C6C': 'z',
66878    '\uA763': 'z',
66879    '\u0386': '\u0391',
66880    '\u0388': '\u0395',
66881    '\u0389': '\u0397',
66882    '\u038A': '\u0399',
66883    '\u03AA': '\u0399',
66884    '\u038C': '\u039F',
66885    '\u038E': '\u03A5',
66886    '\u03AB': '\u03A5',
66887    '\u038F': '\u03A9',
66888    '\u03AC': '\u03B1',
66889    '\u03AD': '\u03B5',
66890    '\u03AE': '\u03B7',
66891    '\u03AF': '\u03B9',
66892    '\u03CA': '\u03B9',
66893    '\u0390': '\u03B9',
66894    '\u03CC': '\u03BF',
66895    '\u03CD': '\u03C5',
66896    '\u03CB': '\u03C5',
66897    '\u03B0': '\u03C5',
66898    '\u03CE': '\u03C9',
66899    '\u03C2': '\u03C3',
66900    '\u2019': '\''
66901  };
66902
66903  return diacritics;
66904});
66905
66906S2.define('select2/data/base',[
66907  '../utils'
66908], function (Utils) {
66909  function BaseAdapter ($element, options) {
66910    BaseAdapter.__super__.constructor.call(this);
66911  }
66912
66913  Utils.Extend(BaseAdapter, Utils.Observable);
66914
66915  BaseAdapter.prototype.current = function (callback) {
66916    throw new Error('The `current` method must be defined in child classes.');
66917  };
66918
66919  BaseAdapter.prototype.query = function (params, callback) {
66920    throw new Error('The `query` method must be defined in child classes.');
66921  };
66922
66923  BaseAdapter.prototype.bind = function (container, $container) {
66924    // Can be implemented in subclasses
66925  };
66926
66927  BaseAdapter.prototype.destroy = function () {
66928    // Can be implemented in subclasses
66929  };
66930
66931  BaseAdapter.prototype.generateResultId = function (container, data) {
66932    var id = container.id + '-result-';
66933
66934    id += Utils.generateChars(4);
66935
66936    if (data.id != null) {
66937      id += '-' + data.id.toString();
66938    } else {
66939      id += '-' + Utils.generateChars(4);
66940    }
66941    return id;
66942  };
66943
66944  return BaseAdapter;
66945});
66946
66947S2.define('select2/data/select',[
66948  './base',
66949  '../utils',
66950  'jquery'
66951], function (BaseAdapter, Utils, $) {
66952  function SelectAdapter ($element, options) {
66953    this.$element = $element;
66954    this.options = options;
66955
66956    SelectAdapter.__super__.constructor.call(this);
66957  }
66958
66959  Utils.Extend(SelectAdapter, BaseAdapter);
66960
66961  SelectAdapter.prototype.current = function (callback) {
66962    var data = [];
66963    var self = this;
66964
66965    this.$element.find(':selected').each(function () {
66966      var $option = $(this);
66967
66968      var option = self.item($option);
66969
66970      data.push(option);
66971    });
66972
66973    callback(data);
66974  };
66975
66976  SelectAdapter.prototype.select = function (data) {
66977    var self = this;
66978
66979    data.selected = true;
66980
66981    // If data.element is a DOM node, use it instead
66982    if ($(data.element).is('option')) {
66983      data.element.selected = true;
66984
66985      this.$element.trigger('input').trigger('change');
66986
66987      return;
66988    }
66989
66990    if (this.$element.prop('multiple')) {
66991      this.current(function (currentData) {
66992        var val = [];
66993
66994        data = [data];
66995        data.push.apply(data, currentData);
66996
66997        for (var d = 0; d < data.length; d++) {
66998          var id = data[d].id;
66999
67000          if ($.inArray(id, val) === -1) {
67001            val.push(id);
67002          }
67003        }
67004
67005        self.$element.val(val);
67006        self.$element.trigger('input').trigger('change');
67007      });
67008    } else {
67009      var val = data.id;
67010
67011      this.$element.val(val);
67012      this.$element.trigger('input').trigger('change');
67013    }
67014  };
67015
67016  SelectAdapter.prototype.unselect = function (data) {
67017    var self = this;
67018
67019    if (!this.$element.prop('multiple')) {
67020      return;
67021    }
67022
67023    data.selected = false;
vendor: 59,256 bytes, lines 67024-69388
67024
67025    if ($(data.element).is('option')) {
67026      data.element.selected = false;
67027
67028      this.$element.trigger('input').trigger('change');
67029
67030      return;
67031    }
67032
67033    this.current(function (currentData) {
67034      var val = [];
67035
67036      for (var d = 0; d < currentData.length; d++) {
67037        var id = currentData[d].id;
67038
67039        if (id !== data.id && $.inArray(id, val) === -1) {
67040          val.push(id);
67041        }
67042      }
67043
67044      self.$element.val(val);
67045
67046      self.$element.trigger('input').trigger('change');
67047    });
67048  };
67049
67050  SelectAdapter.prototype.bind = function (container, $container) {
67051    var self = this;
67052
67053    this.container = container;
67054
67055    container.on('select', function (params) {
67056      self.select(params.data);
67057    });
67058
67059    container.on('unselect', function (params) {
67060      self.unselect(params.data);
67061    });
67062  };
67063
67064  SelectAdapter.prototype.destroy = function () {
67065    // Remove anything added to child elements
67066    this.$element.find('*').each(function () {
67067      // Remove any custom data set by Select2
67068      Utils.RemoveData(this);
67069    });
67070  };
67071
67072  SelectAdapter.prototype.query = function (params, callback) {
67073    var data = [];
67074    var self = this;
67075
67076    var $options = this.$element.children();
67077
67078    $options.each(function () {
67079      var $option = $(this);
67080
67081      if (!$option.is('option') && !$option.is('optgroup')) {
67082        return;
67083      }
67084
67085      var option = self.item($option);
67086
67087      var matches = self.matches(params, option);
67088
67089      if (matches !== null) {
67090        data.push(matches);
67091      }
67092    });
67093
67094    callback({
67095      results: data
67096    });
67097  };
67098
67099  SelectAdapter.prototype.addOptions = function ($options) {
67100    Utils.appendMany(this.$element, $options);
67101  };
67102
67103  SelectAdapter.prototype.option = function (data) {
67104    var option;
67105
67106    if (data.children) {
67107      option = document.createElement('optgroup');
67108      option.label = data.text;
67109    } else {
67110      option = document.createElement('option');
67111
67112      if (option.textContent !== undefined) {
67113        option.textContent = data.text;
67114      } else {
67115        option.innerText = data.text;
67116      }
67117    }
67118
67119    if (data.id !== undefined) {
67120      option.value = data.id;
67121    }
67122
67123    if (data.disabled) {
67124      option.disabled = true;
67125    }
67126
67127    if (data.selected) {
67128      option.selected = true;
67129    }
67130
67131    if (data.title) {
67132      option.title = data.title;
67133    }
67134
67135    var $option = $(option);
67136
67137    var normalizedData = this._normalizeItem(data);
67138    normalizedData.element = option;
67139
67140    // Override the option's data with the combined data
67141    Utils.StoreData(option, 'data', normalizedData);
67142
67143    return $option;
67144  };
67145
67146  SelectAdapter.prototype.item = function ($option) {
67147    var data = {};
67148
67149    data = Utils.GetData($option[0], 'data');
67150
67151    if (data != null) {
67152      return data;
67153    }
67154
67155    if ($option.is('option')) {
67156      data = {
67157        id: $option.val(),
67158        text: $option.text(),
67159        disabled: $option.prop('disabled'),
67160        selected: $option.prop('selected'),
67161        title: $option.prop('title')
67162      };
67163    } else if ($option.is('optgroup')) {
67164      data = {
67165        text: $option.prop('label'),
67166        children: [],
67167        title: $option.prop('title')
67168      };
67169
67170      var $children = $option.children('option');
67171      var children = [];
67172
67173      for (var c = 0; c < $children.length; c++) {
67174        var $child = $($children[c]);
67175
67176        var child = this.item($child);
67177
67178        children.push(child);
67179      }
67180
67181      data.children = children;
67182    }
67183
67184    data = this._normalizeItem(data);
67185    data.element = $option[0];
67186
67187    Utils.StoreData($option[0], 'data', data);
67188
67189    return data;
67190  };
67191
67192  SelectAdapter.prototype._normalizeItem = function (item) {
67193    if (item !== Object(item)) {
67194      item = {
67195        id: item,
67196        text: item
67197      };
67198    }
67199
67200    item = $.extend({}, {
67201      text: ''
67202    }, item);
67203
67204    var defaults = {
67205      selected: false,
67206      disabled: false
67207    };
67208
67209    if (item.id != null) {
67210      item.id = item.id.toString();
67211    }
67212
67213    if (item.text != null) {
67214      item.text = item.text.toString();
67215    }
67216
67217    if (item._resultId == null && item.id && this.container != null) {
67218      item._resultId = this.generateResultId(this.container, item);
67219    }
67220
67221    return $.extend({}, defaults, item);
67222  };
67223
67224  SelectAdapter.prototype.matches = function (params, data) {
67225    var matcher = this.options.get('matcher');
67226
67227    return matcher(params, data);
67228  };
67229
67230  return SelectAdapter;
67231});
67232
67233S2.define('select2/data/array',[
67234  './select',
67235  '../utils',
67236  'jquery'
67237], function (SelectAdapter, Utils, $) {
67238  function ArrayAdapter ($element, options) {
67239    this._dataToConvert = options.get('data') || [];
67240
67241    ArrayAdapter.__super__.constructor.call(this, $element, options);
67242  }
67243
67244  Utils.Extend(ArrayAdapter, SelectAdapter);
67245
67246  ArrayAdapter.prototype.bind = function (container, $container) {
67247    ArrayAdapter.__super__.bind.call(this, container, $container);
67248
67249    this.addOptions(this.convertToOptions(this._dataToConvert));
67250  };
67251
67252  ArrayAdapter.prototype.select = function (data) {
67253    var $option = this.$element.find('option').filter(function (i, elm) {
67254      return elm.value == data.id.toString();
67255    });
67256
67257    if ($option.length === 0) {
67258      $option = this.option(data);
67259
67260      this.addOptions($option);
67261    }
67262
67263    ArrayAdapter.__super__.select.call(this, data);
67264  };
67265
67266  ArrayAdapter.prototype.convertToOptions = function (data) {
67267    var self = this;
67268
67269    var $existing = this.$element.find('option');
67270    var existingIds = $existing.map(function () {
67271      return self.item($(this)).id;
67272    }).get();
67273
67274    var $options = [];
67275
67276    // Filter out all items except for the one passed in the argument
67277    function onlyItem (item) {
67278      return function () {
67279        return $(this).val() == item.id;
67280      };
67281    }
67282
67283    for (var d = 0; d < data.length; d++) {
67284      var item = this._normalizeItem(data[d]);
67285
67286      // Skip items which were pre-loaded, only merge the data
67287      if ($.inArray(item.id, existingIds) >= 0) {
67288        var $existingOption = $existing.filter(onlyItem(item));
67289
67290        var existingData = this.item($existingOption);
67291        var newData = $.extend(true, {}, item, existingData);
67292
67293        var $newOption = this.option(newData);
67294
67295        $existingOption.replaceWith($newOption);
67296
67297        continue;
67298      }
67299
67300      var $option = this.option(item);
67301
67302      if (item.children) {
67303        var $children = this.convertToOptions(item.children);
67304
67305        Utils.appendMany($option, $children);
67306      }
67307
67308      $options.push($option);
67309    }
67310
67311    return $options;
67312  };
67313
67314  return ArrayAdapter;
67315});
67316
67317S2.define('select2/data/ajax',[
67318  './array',
67319  '../utils',
67320  'jquery'
67321], function (ArrayAdapter, Utils, $) {
67322  function AjaxAdapter ($element, options) {
67323    this.ajaxOptions = this._applyDefaults(options.get('ajax'));
67324
67325    if (this.ajaxOptions.processResults != null) {
67326      this.processResults = this.ajaxOptions.processResults;
67327    }
67328
67329    AjaxAdapter.__super__.constructor.call(this, $element, options);
67330  }
67331
67332  Utils.Extend(AjaxAdapter, ArrayAdapter);
67333
67334  AjaxAdapter.prototype._applyDefaults = function (options) {
67335    var defaults = {
67336      data: function (params) {
67337        return $.extend({}, params, {
67338          q: params.term
67339        });
67340      },
67341      transport: function (params, success, failure) {
67342        var $request = $.ajax(params);
67343
67344        $request.then(success);
67345        $request.fail(failure);
67346
67347        return $request;
67348      }
67349    };
67350
67351    return $.extend({}, defaults, options, true);
67352  };
67353
67354  AjaxAdapter.prototype.processResults = function (results) {
67355    return results;
67356  };
67357
67358  AjaxAdapter.prototype.query = function (params, callback) {
67359    var matches = [];
67360    var self = this;
67361
67362    if (this._request != null) {
67363      // JSONP requests cannot always be aborted
67364      if ($.isFunction(this._request.abort)) {
67365        this._request.abort();
67366      }
67367
67368      this._request = null;
67369    }
67370
67371    var options = $.extend({
67372      type: 'GET'
67373    }, this.ajaxOptions);
67374
67375    if (typeof options.url === 'function') {
67376      options.url = options.url.call(this.$element, params);
67377    }
67378
67379    if (typeof options.data === 'function') {
67380      options.data = options.data.call(this.$element, params);
67381    }
67382
67383    function request () {
67384      var $request = options.transport(options, function (data) {
67385        var results = self.processResults(data, params);
67386
67387        if (self.options.get('debug') && window.console && console.error) {
67388          // Check to make sure that the response included a `results` key.
67389          if (!results || !results.results || !$.isArray(results.results)) {
67390            console.error(
67391              'Select2: The AJAX results did not return an array in the ' +
67392              '`results` key of the response.'
67393            );
67394          }
67395        }
67396
67397        callback(results);
67398      }, function () {
67399        // Attempt to detect if a request was aborted
67400        // Only works if the transport exposes a status property
67401        if ('status' in $request &&
67402            ($request.status === 0 || $request.status === '0')) {
67403          return;
67404        }
67405
67406        self.trigger('results:message', {
67407          message: 'errorLoading'
67408        });
67409      });
67410
67411      self._request = $request;
67412    }
67413
67414    if (this.ajaxOptions.delay && params.term != null) {
67415      if (this._queryTimeout) {
67416        window.clearTimeout(this._queryTimeout);
67417      }
67418
67419      this._queryTimeout = window.setTimeout(request, this.ajaxOptions.delay);
67420    } else {
67421      request();
67422    }
67423  };
67424
67425  return AjaxAdapter;
67426});
67427
67428S2.define('select2/data/tags',[
67429  'jquery'
67430], function ($) {
67431  function Tags (decorated, $element, options) {
67432    var tags = options.get('tags');
67433
67434    var createTag = options.get('createTag');
67435
67436    if (createTag !== undefined) {
67437      this.createTag = createTag;
67438    }
67439
67440    var insertTag = options.get('insertTag');
67441
67442    if (insertTag !== undefined) {
67443        this.insertTag = insertTag;
67444    }
67445
67446    decorated.call(this, $element, options);
67447
67448    if ($.isArray(tags)) {
67449      for (var t = 0; t < tags.length; t++) {
67450        var tag = tags[t];
67451        var item = this._normalizeItem(tag);
67452
67453        var $option = this.option(item);
67454
67455        this.$element.append($option);
67456      }
67457    }
67458  }
67459
67460  Tags.prototype.query = function (decorated, params, callback) {
67461    var self = this;
67462
67463    this._removeOldTags();
67464
67465    if (params.term == null || params.page != null) {
67466      decorated.call(this, params, callback);
67467      return;
67468    }
67469
67470    function wrapper (obj, child) {
67471      var data = obj.results;
67472
67473      for (var i = 0; i < data.length; i++) {
67474        var option = data[i];
67475
67476        var checkChildren = (
67477          option.children != null &&
67478          !wrapper({
67479            results: option.children
67480          }, true)
67481        );
67482
67483        var optionText = (option.text || '').toUpperCase();
67484        var paramsTerm = (params.term || '').toUpperCase();
67485
67486        var checkText = optionText === paramsTerm;
67487
67488        if (checkText || checkChildren) {
67489          if (child) {
67490            return false;
67491          }
67492
67493          obj.data = data;
67494          callback(obj);
67495
67496          return;
67497        }
67498      }
67499
67500      if (child) {
67501        return true;
67502      }
67503
67504      var tag = self.createTag(params);
67505
67506      if (tag != null) {
67507        var $option = self.option(tag);
67508        $option.attr('data-select2-tag', true);
67509
67510        self.addOptions([$option]);
67511
67512        self.insertTag(data, tag);
67513      }
67514
67515      obj.results = data;
67516
67517      callback(obj);
67518    }
67519
67520    decorated.call(this, params, wrapper);
67521  };
67522
67523  Tags.prototype.createTag = function (decorated, params) {
67524    var term = $.trim(params.term);
67525
67526    if (term === '') {
67527      return null;
67528    }
67529
67530    return {
67531      id: term,
67532      text: term
67533    };
67534  };
67535
67536  Tags.prototype.insertTag = function (_, data, tag) {
67537    data.unshift(tag);
67538  };
67539
67540  Tags.prototype._removeOldTags = function (_) {
67541    var $options = this.$element.find('option[data-select2-tag]');
67542
67543    $options.each(function () {
67544      if (this.selected) {
67545        return;
67546      }
67547
67548      $(this).remove();
67549    });
67550  };
67551
67552  return Tags;
67553});
67554
67555S2.define('select2/data/tokenizer',[
67556  'jquery'
67557], function ($) {
67558  function Tokenizer (decorated, $element, options) {
67559    var tokenizer = options.get('tokenizer');
67560
67561    if (tokenizer !== undefined) {
67562      this.tokenizer = tokenizer;
67563    }
67564
67565    decorated.call(this, $element, options);
67566  }
67567
67568  Tokenizer.prototype.bind = function (decorated, container, $container) {
67569    decorated.call(this, container, $container);
67570
67571    this.$search =  container.dropdown.$search || container.selection.$search ||
67572      $container.find('.select2-search__field');
67573  };
67574
67575  Tokenizer.prototype.query = function (decorated, params, callback) {
67576    var self = this;
67577
67578    function createAndSelect (data) {
67579      // Normalize the data object so we can use it for checks
67580      var item = self._normalizeItem(data);
67581
67582      // Check if the data object already exists as a tag
67583      // Select it if it doesn't
67584      var $existingOptions = self.$element.find('option').filter(function () {
67585        return $(this).val() === item.id;
67586      });
67587
67588      // If an existing option wasn't found for it, create the option
67589      if (!$existingOptions.length) {
67590        var $option = self.option(item);
67591        $option.attr('data-select2-tag', true);
67592
67593        self._removeOldTags();
67594        self.addOptions([$option]);
67595      }
67596
67597      // Select the item, now that we know there is an option for it
67598      select(item);
67599    }
67600
67601    function select (data) {
67602      self.trigger('select', {
67603        data: data
67604      });
67605    }
67606
67607    params.term = params.term || '';
67608
67609    var tokenData = this.tokenizer(params, this.options, createAndSelect);
67610
67611    if (tokenData.term !== params.term) {
67612      // Replace the search term if we have the search box
67613      if (this.$search.length) {
67614        this.$search.val(tokenData.term);
67615        this.$search.trigger('focus');
67616      }
67617
67618      params.term = tokenData.term;
67619    }
67620
67621    decorated.call(this, params, callback);
67622  };
67623
67624  Tokenizer.prototype.tokenizer = function (_, params, options, callback) {
67625    var separators = options.get('tokenSeparators') || [];
67626    var term = params.term;
67627    var i = 0;
67628
67629    var createTag = this.createTag || function (params) {
67630      return {
67631        id: params.term,
67632        text: params.term
67633      };
67634    };
67635
67636    while (i < term.length) {
67637      var termChar = term[i];
67638
67639      if ($.inArray(termChar, separators) === -1) {
67640        i++;
67641
67642        continue;
67643      }
67644
67645      var part = term.substr(0, i);
67646      var partParams = $.extend({}, params, {
67647        term: part
67648      });
67649
67650      var data = createTag(partParams);
67651
67652      if (data == null) {
67653        i++;
67654        continue;
67655      }
67656
67657      callback(data);
67658
67659      // Reset the term to not include the tokenized portion
67660      term = term.substr(i + 1) || '';
67661      i = 0;
67662    }
67663
67664    return {
67665      term: term
67666    };
67667  };
67668
67669  return Tokenizer;
67670});
67671
67672S2.define('select2/data/minimumInputLength',[
67673
67674], function () {
67675  function MinimumInputLength (decorated, $e, options) {
67676    this.minimumInputLength = options.get('minimumInputLength');
67677
67678    decorated.call(this, $e, options);
67679  }
67680
67681  MinimumInputLength.prototype.query = function (decorated, params, callback) {
67682    params.term = params.term || '';
67683
67684    if (params.term.length < this.minimumInputLength) {
67685      this.trigger('results:message', {
67686        message: 'inputTooShort',
67687        args: {
67688          minimum: this.minimumInputLength,
67689          input: params.term,
67690          params: params
67691        }
67692      });
67693
67694      return;
67695    }
67696
67697    decorated.call(this, params, callback);
67698  };
67699
67700  return MinimumInputLength;
67701});
67702
67703S2.define('select2/data/maximumInputLength',[
67704
67705], function () {
67706  function MaximumInputLength (decorated, $e, options) {
67707    this.maximumInputLength = options.get('maximumInputLength');
67708
67709    decorated.call(this, $e, options);
67710  }
67711
67712  MaximumInputLength.prototype.query = function (decorated, params, callback) {
67713    params.term = params.term || '';
67714
67715    if (this.maximumInputLength > 0 &&
67716        params.term.length > this.maximumInputLength) {
67717      this.trigger('results:message', {
67718        message: 'inputTooLong',
67719        args: {
67720          maximum: this.maximumInputLength,
67721          input: params.term,
67722          params: params
67723        }
67724      });
67725
67726      return;
67727    }
67728
67729    decorated.call(this, params, callback);
67730  };
67731
67732  return MaximumInputLength;
67733});
67734
67735S2.define('select2/data/maximumSelectionLength',[
67736
67737], function (){
67738  function MaximumSelectionLength (decorated, $e, options) {
67739    this.maximumSelectionLength = options.get('maximumSelectionLength');
67740
67741    decorated.call(this, $e, options);
67742  }
67743
67744  MaximumSelectionLength.prototype.bind =
67745    function (decorated, container, $container) {
67746      var self = this;
67747
67748      decorated.call(this, container, $container);
67749
67750      container.on('select', function () {
67751        self._checkIfMaximumSelected();
67752      });
67753  };
67754
67755  MaximumSelectionLength.prototype.query =
67756    function (decorated, params, callback) {
67757      var self = this;
67758
67759      this._checkIfMaximumSelected(function () {
67760        decorated.call(self, params, callback);
67761      });
67762  };
67763
67764  MaximumSelectionLength.prototype._checkIfMaximumSelected =
67765    function (_, successCallback) {
67766      var self = this;
67767
67768      this.current(function (currentData) {
67769        var count = currentData != null ? currentData.length : 0;
67770        if (self.maximumSelectionLength > 0 &&
67771          count >= self.maximumSelectionLength) {
67772          self.trigger('results:message', {
67773            message: 'maximumSelected',
67774            args: {
67775              maximum: self.maximumSelectionLength
67776            }
67777          });
67778          return;
67779        }
67780
67781        if (successCallback) {
67782          successCallback();
67783        }
67784      });
67785  };
67786
67787  return MaximumSelectionLength;
67788});
67789
67790S2.define('select2/dropdown',[
67791  'jquery',
67792  './utils'
67793], function ($, Utils) {
67794  function Dropdown ($element, options) {
67795    this.$element = $element;
67796    this.options = options;
67797
67798    Dropdown.__super__.constructor.call(this);
67799  }
67800
67801  Utils.Extend(Dropdown, Utils.Observable);
67802
67803  Dropdown.prototype.render = function () {
67804    var $dropdown = $(
67805      '<span class="select2-dropdown">' +
67806        '<span class="select2-results"></span>' +
67807      '</span>'
67808    );
67809
67810    $dropdown.attr('dir', this.options.get('dir'));
67811
67812    this.$dropdown = $dropdown;
67813
67814    return $dropdown;
67815  };
67816
67817  Dropdown.prototype.bind = function () {
67818    // Should be implemented in subclasses
67819  };
67820
67821  Dropdown.prototype.position = function ($dropdown, $container) {
67822    // Should be implemented in subclasses
67823  };
67824
67825  Dropdown.prototype.destroy = function () {
67826    // Remove the dropdown from the DOM
67827    this.$dropdown.remove();
67828  };
67829
67830  return Dropdown;
67831});
67832
67833S2.define('select2/dropdown/search',[
67834  'jquery',
67835  '../utils'
67836], function ($, Utils) {
67837  function Search () { }
67838
67839  Search.prototype.render = function (decorated) {
67840    var $rendered = decorated.call(this);
67841
67842    var $search = $(
67843      '<span class="select2-search select2-search--dropdown">' +
67844        '<input class="select2-search__field" type="search" tabindex="-1"' +
67845        ' autocomplete="off" autocorrect="off" autocapitalize="none"' +
67846        ' spellcheck="false" role="searchbox" aria-autocomplete="list" />' +
67847      '</span>'
67848    );
67849
67850    this.$searchContainer = $search;
67851    this.$search = $search.find('input');
67852
67853    $rendered.prepend($search);
67854
67855    return $rendered;
67856  };
67857
67858  Search.prototype.bind = function (decorated, container, $container) {
67859    var self = this;
67860
67861    var resultsId = container.id + '-results';
67862
67863    decorated.call(this, container, $container);
67864
67865    this.$search.on('keydown', function (evt) {
67866      self.trigger('keypress', evt);
67867
67868      self._keyUpPrevented = evt.isDefaultPrevented();
67869    });
67870
67871    // Workaround for browsers which do not support the `input` event
67872    // This will prevent double-triggering of events for browsers which support
67873    // both the `keyup` and `input` events.
67874    this.$search.on('input', function (evt) {
67875      // Unbind the duplicated `keyup` event
67876      $(this).off('keyup');
67877    });
67878
67879    this.$search.on('keyup input', function (evt) {
67880      self.handleSearch(evt);
67881    });
67882
67883    container.on('open', function () {
67884      self.$search.attr('tabindex', 0);
67885      self.$search.attr('aria-controls', resultsId);
67886
67887      self.$search.trigger('focus');
67888
67889      window.setTimeout(function () {
67890        self.$search.trigger('focus');
67891      }, 0);
67892    });
67893
67894    container.on('close', function () {
67895      self.$search.attr('tabindex', -1);
67896      self.$search.removeAttr('aria-controls');
67897      self.$search.removeAttr('aria-activedescendant');
67898
67899      self.$search.val('');
67900      self.$search.trigger('blur');
67901    });
67902
67903    container.on('focus', function () {
67904      if (!container.isOpen()) {
67905        self.$search.trigger('focus');
67906      }
67907    });
67908
67909    container.on('results:all', function (params) {
67910      if (params.query.term == null || params.query.term === '') {
67911        var showSearch = self.showSearch(params);
67912
67913        if (showSearch) {
67914          self.$searchContainer.removeClass('select2-search--hide');
67915        } else {
67916          self.$searchContainer.addClass('select2-search--hide');
67917        }
67918      }
67919    });
67920
67921    container.on('results:focus', function (params) {
67922      if (params.data._resultId) {
67923        self.$search.attr('aria-activedescendant', params.data._resultId);
67924      } else {
67925        self.$search.removeAttr('aria-activedescendant');
67926      }
67927    });
67928  };
67929
67930  Search.prototype.handleSearch = function (evt) {
67931    if (!this._keyUpPrevented) {
67932      var input = this.$search.val();
67933
67934      this.trigger('query', {
67935        term: input
67936      });
67937    }
67938
67939    this._keyUpPrevented = false;
67940  };
67941
67942  Search.prototype.showSearch = function (_, params) {
67943    return true;
67944  };
67945
67946  return Search;
67947});
67948
67949S2.define('select2/dropdown/hidePlaceholder',[
67950
67951], function () {
67952  function HidePlaceholder (decorated, $element, options, dataAdapter) {
67953    this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
67954
67955    decorated.call(this, $element, options, dataAdapter);
67956  }
67957
67958  HidePlaceholder.prototype.append = function (decorated, data) {
67959    data.results = this.removePlaceholder(data.results);
67960
67961    decorated.call(this, data);
67962  };
67963
67964  HidePlaceholder.prototype.normalizePlaceholder = function (_, placeholder) {
67965    if (typeof placeholder === 'string') {
67966      placeholder = {
67967        id: '',
67968        text: placeholder
67969      };
67970    }
67971
67972    return placeholder;
67973  };
67974
67975  HidePlaceholder.prototype.removePlaceholder = function (_, data) {
67976    var modifiedData = data.slice(0);
67977
67978    for (var d = data.length - 1; d >= 0; d--) {
67979      var item = data[d];
67980
67981      if (this.placeholder.id === item.id) {
67982        modifiedData.splice(d, 1);
67983      }
67984    }
67985
67986    return modifiedData;
67987  };
67988
67989  return HidePlaceholder;
67990});
67991
67992S2.define('select2/dropdown/infiniteScroll',[
67993  'jquery'
67994], function ($) {
67995  function InfiniteScroll (decorated, $element, options, dataAdapter) {
67996    this.lastParams = {};
67997
67998    decorated.call(this, $element, options, dataAdapter);
67999
68000    this.$loadingMore = this.createLoadingMore();
68001    this.loading = false;
68002  }
68003
68004  InfiniteScroll.prototype.append = function (decorated, data) {
68005    this.$loadingMore.remove();
68006    this.loading = false;
68007
68008    decorated.call(this, data);
68009
68010    if (this.showLoadingMore(data)) {
68011      this.$results.append(this.$loadingMore);
68012      this.loadMoreIfNeeded();
68013    }
68014  };
68015
68016  InfiniteScroll.prototype.bind = function (decorated, container, $container) {
68017    var self = this;
68018
68019    decorated.call(this, container, $container);
68020
68021    container.on('query', function (params) {
68022      self.lastParams = params;
68023      self.loading = true;
68024    });
68025
68026    container.on('query:append', function (params) {
68027      self.lastParams = params;
68028      self.loading = true;
68029    });
68030
68031    this.$results.on('scroll', this.loadMoreIfNeeded.bind(this));
68032  };
68033
68034  InfiniteScroll.prototype.loadMoreIfNeeded = function () {
68035    var isLoadMoreVisible = $.contains(
68036      document.documentElement,
68037      this.$loadingMore[0]
68038    );
68039
68040    if (this.loading || !isLoadMoreVisible) {
68041      return;
68042    }
68043
68044    var currentOffset = this.$results.offset().top +
68045      this.$results.outerHeight(false);
68046    var loadingMoreOffset = this.$loadingMore.offset().top +
68047      this.$loadingMore.outerHeight(false);
68048
68049    if (currentOffset + 50 >= loadingMoreOffset) {
68050      this.loadMore();
68051    }
68052  };
68053
68054  InfiniteScroll.prototype.loadMore = function () {
68055    this.loading = true;
68056
68057    var params = $.extend({}, {page: 1}, this.lastParams);
68058
68059    params.page++;
68060
68061    this.trigger('query:append', params);
68062  };
68063
68064  InfiniteScroll.prototype.showLoadingMore = function (_, data) {
68065    return data.pagination && data.pagination.more;
68066  };
68067
68068  InfiniteScroll.prototype.createLoadingMore = function () {
68069    var $option = $(
68070      '<li ' +
68071      'class="select2-results__option select2-results__option--load-more"' +
68072      'role="option" aria-disabled="true"></li>'
68073    );
68074
68075    var message = this.options.get('translations').get('loadingMore');
68076
68077    $option.html(message(this.lastParams));
68078
68079    return $option;
68080  };
68081
68082  return InfiniteScroll;
68083});
68084
68085S2.define('select2/dropdown/attachBody',[
68086  'jquery',
68087  '../utils'
68088], function ($, Utils) {
68089  function AttachBody (decorated, $element, options) {
68090    this.$dropdownParent = $(options.get('dropdownParent') || document.body);
68091
68092    decorated.call(this, $element, options);
68093  }
68094
68095  AttachBody.prototype.bind = function (decorated, container, $container) {
68096    var self = this;
68097
68098    decorated.call(this, container, $container);
68099
68100    container.on('open', function () {
68101      self._showDropdown();
68102      self._attachPositioningHandler(container);
68103
68104      // Must bind after the results handlers to ensure correct sizing
68105      self._bindContainerResultHandlers(container);
68106    });
68107
68108    container.on('close', function () {
68109      self._hideDropdown();
68110      self._detachPositioningHandler(container);
68111    });
68112
68113    this.$dropdownContainer.on('mousedown', function (evt) {
68114      evt.stopPropagation();
68115    });
68116  };
68117
68118  AttachBody.prototype.destroy = function (decorated) {
68119    decorated.call(this);
68120
68121    this.$dropdownContainer.remove();
68122  };
68123
68124  AttachBody.prototype.position = function (decorated, $dropdown, $container) {
68125    // Clone all of the container classes
68126    $dropdown.attr('class', $container.attr('class'));
68127
68128    $dropdown.removeClass('select2');
68129    $dropdown.addClass('select2-container--open');
68130
68131    $dropdown.css({
68132      position: 'absolute',
68133      top: -999999
68134    });
68135
68136    this.$container = $container;
68137  };
68138
68139  AttachBody.prototype.render = function (decorated) {
68140    var $container = $('<span></span>');
68141
68142    var $dropdown = decorated.call(this);
68143    $container.append($dropdown);
68144
68145    this.$dropdownContainer = $container;
68146
68147    return $container;
68148  };
68149
68150  AttachBody.prototype._hideDropdown = function (decorated) {
68151    this.$dropdownContainer.detach();
68152  };
68153
68154  AttachBody.prototype._bindContainerResultHandlers =
68155      function (decorated, container) {
68156
68157    // These should only be bound once
68158    if (this._containerResultsHandlersBound) {
68159      return;
68160    }
68161
68162    var self = this;
68163
68164    container.on('results:all', function () {
68165      self._positionDropdown();
68166      self._resizeDropdown();
68167    });
68168
68169    container.on('results:append', function () {
68170      self._positionDropdown();
68171      self._resizeDropdown();
68172    });
68173
68174    container.on('results:message', function () {
68175      self._positionDropdown();
68176      self._resizeDropdown();
68177    });
68178
68179    container.on('select', function () {
68180      self._positionDropdown();
68181      self._resizeDropdown();
68182    });
68183
68184    container.on('unselect', function () {
68185      self._positionDropdown();
68186      self._resizeDropdown();
68187    });
68188
68189    this._containerResultsHandlersBound = true;
68190  };
68191
68192  AttachBody.prototype._attachPositioningHandler =
68193      function (decorated, container) {
68194    var self = this;
68195
68196    var scrollEvent = 'scroll.select2.' + container.id;
68197    var resizeEvent = 'resize.select2.' + container.id;
68198    var orientationEvent = 'orientationchange.select2.' + container.id;
68199
68200    var $watchers = this.$container.parents().filter(Utils.hasScroll);
68201    $watchers.each(function () {
68202      Utils.StoreData(this, 'select2-scroll-position', {
68203        x: $(this).scrollLeft(),
68204        y: $(this).scrollTop()
68205      });
68206    });
68207
68208    $watchers.on(scrollEvent, function (ev) {
68209      var position = Utils.GetData(this, 'select2-scroll-position');
68210      $(this).scrollTop(position.y);
68211    });
68212
68213    $(window).on(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent,
68214      function (e) {
68215      self._positionDropdown();
68216      self._resizeDropdown();
68217    });
68218  };
68219
68220  AttachBody.prototype._detachPositioningHandler =
68221      function (decorated, container) {
68222    var scrollEvent = 'scroll.select2.' + container.id;
68223    var resizeEvent = 'resize.select2.' + container.id;
68224    var orientationEvent = 'orientationchange.select2.' + container.id;
68225
68226    var $watchers = this.$container.parents().filter(Utils.hasScroll);
68227    $watchers.off(scrollEvent);
68228
68229    $(window).off(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent);
68230  };
68231
68232  AttachBody.prototype._positionDropdown = function () {
68233    var $window = $(window);
68234
68235    var isCurrentlyAbove = this.$dropdown.hasClass('select2-dropdown--above');
68236    var isCurrentlyBelow = this.$dropdown.hasClass('select2-dropdown--below');
68237
68238    var newDirection = null;
68239
68240    var offset = this.$container.offset();
68241
68242    offset.bottom = offset.top + this.$container.outerHeight(false);
68243
68244    var container = {
68245      height: this.$container.outerHeight(false)
68246    };
68247
68248    container.top = offset.top;
68249    container.bottom = offset.top + container.height;
68250
68251    var dropdown = {
68252      height: this.$dropdown.outerHeight(false)
68253    };
68254
68255    var viewport = {
68256      top: $window.scrollTop(),
68257      bottom: $window.scrollTop() + $window.height()
68258    };
68259
68260    var enoughRoomAbove = viewport.top < (offset.top - dropdown.height);
68261    var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height);
68262
68263    var css = {
68264      left: offset.left,
68265      top: container.bottom
68266    };
68267
68268    // Determine what the parent element is to use for calculating the offset
68269    var $offsetParent = this.$dropdownParent;
68270
68271    // For statically positioned elements, we need to get the element
68272    // that is determining the offset
68273    if ($offsetParent.css('position') === 'static') {
68274      $offsetParent = $offsetParent.offsetParent();
68275    }
68276
68277    var parentOffset = {
68278      top: 0,
68279      left: 0
68280    };
68281
68282    if (
68283      $.contains(document.body, $offsetParent[0]) ||
68284      $offsetParent[0].isConnected
68285      ) {
68286      parentOffset = $offsetParent.offset();
68287    }
68288
68289    css.top -= parentOffset.top;
68290    css.left -= parentOffset.left;
68291
68292    if (!isCurrentlyAbove && !isCurrentlyBelow) {
68293      newDirection = 'below';
68294    }
68295
68296    if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) {
68297      newDirection = 'above';
68298    } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) {
68299      newDirection = 'below';
68300    }
68301
68302    if (newDirection == 'above' ||
68303      (isCurrentlyAbove && newDirection !== 'below')) {
68304      css.top = container.top - parentOffset.top - dropdown.height;
68305    }
68306
68307    if (newDirection != null) {
68308      this.$dropdown
68309        .removeClass('select2-dropdown--below select2-dropdown--above')
68310        .addClass('select2-dropdown--' + newDirection);
68311      this.$container
68312        .removeClass('select2-container--below select2-container--above')
68313        .addClass('select2-container--' + newDirection);
68314    }
68315
68316    this.$dropdownContainer.css(css);
68317  };
68318
68319  AttachBody.prototype._resizeDropdown = function () {
68320    var css = {
68321      width: this.$container.outerWidth(false) + 'px'
68322    };
68323
68324    if (this.options.get('dropdownAutoWidth')) {
68325      css.minWidth = css.width;
68326      css.position = 'relative';
68327      css.width = 'auto';
68328    }
68329
68330    this.$dropdown.css(css);
68331  };
68332
68333  AttachBody.prototype._showDropdown = function (decorated) {
68334    this.$dropdownContainer.appendTo(this.$dropdownParent);
68335
68336    this._positionDropdown();
68337    this._resizeDropdown();
68338  };
68339
68340  return AttachBody;
68341});
68342
68343S2.define('select2/dropdown/minimumResultsForSearch',[
68344
68345], function () {
68346  function countResults (data) {
68347    var count = 0;
68348
68349    for (var d = 0; d < data.length; d++) {
68350      var item = data[d];
68351
68352      if (item.children) {
68353        count += countResults(item.children);
68354      } else {
68355        count++;
68356      }
68357    }
68358
68359    return count;
68360  }
68361
68362  function MinimumResultsForSearch (decorated, $element, options, dataAdapter) {
68363    this.minimumResultsForSearch = options.get('minimumResultsForSearch');
68364
68365    if (this.minimumResultsForSearch < 0) {
68366      this.minimumResultsForSearch = Infinity;
68367    }
68368
68369    decorated.call(this, $element, options, dataAdapter);
68370  }
68371
68372  MinimumResultsForSearch.prototype.showSearch = function (decorated, params) {
68373    if (countResults(params.data.results) < this.minimumResultsForSearch) {
68374      return false;
68375    }
68376
68377    return decorated.call(this, params);
68378  };
68379
68380  return MinimumResultsForSearch;
68381});
68382
68383S2.define('select2/dropdown/selectOnClose',[
68384  '../utils'
68385], function (Utils) {
68386  function SelectOnClose () { }
68387
68388  SelectOnClose.prototype.bind = function (decorated, container, $container) {
68389    var self = this;
68390
68391    decorated.call(this, container, $container);
68392
68393    container.on('close', function (params) {
68394      self._handleSelectOnClose(params);
68395    });
68396  };
68397
68398  SelectOnClose.prototype._handleSelectOnClose = function (_, params) {
68399    if (params && params.originalSelect2Event != null) {
68400      var event = params.originalSelect2Event;
68401
68402      // Don't select an item if the close event was triggered from a select or
68403      // unselect event
68404      if (event._type === 'select' || event._type === 'unselect') {
68405        return;
68406      }
68407    }
68408
68409    var $highlightedResults = this.getHighlightedResults();
68410
68411    // Only select highlighted results
68412    if ($highlightedResults.length < 1) {
68413      return;
68414    }
68415
68416    var data = Utils.GetData($highlightedResults[0], 'data');
68417
68418    // Don't re-select already selected resulte
68419    if (
68420      (data.element != null && data.element.selected) ||
68421      (data.element == null && data.selected)
68422    ) {
68423      return;
68424    }
68425
68426    this.trigger('select', {
68427        data: data
68428    });
68429  };
68430
68431  return SelectOnClose;
68432});
68433
68434S2.define('select2/dropdown/closeOnSelect',[
68435
68436], function () {
68437  function CloseOnSelect () { }
68438
68439  CloseOnSelect.prototype.bind = function (decorated, container, $container) {
68440    var self = this;
68441
68442    decorated.call(this, container, $container);
68443
68444    container.on('select', function (evt) {
68445      self._selectTriggered(evt);
68446    });
68447
68448    container.on('unselect', function (evt) {
68449      self._selectTriggered(evt);
68450    });
68451  };
68452
68453  CloseOnSelect.prototype._selectTriggered = function (_, evt) {
68454    var originalEvent = evt.originalEvent;
68455
68456    // Don't close if the control key is being held
68457    if (originalEvent && (originalEvent.ctrlKey || originalEvent.metaKey)) {
68458      return;
68459    }
68460
68461    this.trigger('close', {
68462      originalEvent: originalEvent,
68463      originalSelect2Event: evt
68464    });
68465  };
68466
68467  return CloseOnSelect;
68468});
68469
68470S2.define('select2/i18n/en',[],function () {
68471  // English
68472  return {
68473    errorLoading: function () {
68474      return 'The results could not be loaded.';
68475    },
68476    inputTooLong: function (args) {
68477      var overChars = args.input.length - args.maximum;
68478
68479      var message = 'Please delete ' + overChars + ' character';
68480
68481      if (overChars != 1) {
68482        message += 's';
68483      }
68484
68485      return message;
68486    },
68487    inputTooShort: function (args) {
68488      var remainingChars = args.minimum - args.input.length;
68489
68490      var message = 'Please enter ' + remainingChars + ' or more characters';
68491
68492      return message;
68493    },
68494    loadingMore: function () {
68495      return 'Loading more results…';
68496    },
68497    maximumSelected: function (args) {
68498      var message = 'You can only select ' + args.maximum + ' item';
68499
68500      if (args.maximum != 1) {
68501        message += 's';
68502      }
68503
68504      return message;
68505    },
68506    noResults: function () {
68507      return 'No results found';
68508    },
68509    searching: function () {
68510      return 'Searching…';
68511    },
68512    removeAllItems: function () {
68513      return 'Remove all items';
68514    }
68515  };
68516});
68517
68518S2.define('select2/defaults',[
68519  'jquery',
68520  'require',
68521
68522  './results',
68523
68524  './selection/single',
68525  './selection/multiple',
68526  './selection/placeholder',
68527  './selection/allowClear',
68528  './selection/search',
68529  './selection/eventRelay',
68530
68531  './utils',
68532  './translation',
68533  './diacritics',
68534
68535  './data/select',
68536  './data/array',
68537  './data/ajax',
68538  './data/tags',
68539  './data/tokenizer',
68540  './data/minimumInputLength',
68541  './data/maximumInputLength',
68542  './data/maximumSelectionLength',
68543
68544  './dropdown',
68545  './dropdown/search',
68546  './dropdown/hidePlaceholder',
68547  './dropdown/infiniteScroll',
68548  './dropdown/attachBody',
68549  './dropdown/minimumResultsForSearch',
68550  './dropdown/selectOnClose',
68551  './dropdown/closeOnSelect',
68552
68553  './i18n/en'
68554], function ($, require,
68555
68556             ResultsList,
68557
68558             SingleSelection, MultipleSelection, Placeholder, AllowClear,
68559             SelectionSearch, EventRelay,
68560
68561             Utils, Translation, DIACRITICS,
68562
68563             SelectData, ArrayData, AjaxData, Tags, Tokenizer,
68564             MinimumInputLength, MaximumInputLength, MaximumSelectionLength,
68565
68566             Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
68567             AttachBody, MinimumResultsForSearch, SelectOnClose, CloseOnSelect,
68568
68569             EnglishTranslation) {
68570  function Defaults () {
68571    this.reset();
68572  }
68573
68574  Defaults.prototype.apply = function (options) {
68575    options = $.extend(true, {}, this.defaults, options);
68576
68577    if (options.dataAdapter == null) {
68578      if (options.ajax != null) {
68579        options.dataAdapter = AjaxData;
68580      } else if (options.data != null) {
68581        options.dataAdapter = ArrayData;
68582      } else {
68583        options.dataAdapter = SelectData;
68584      }
68585
68586      if (options.minimumInputLength > 0) {
68587        options.dataAdapter = Utils.Decorate(
68588          options.dataAdapter,
68589          MinimumInputLength
68590        );
68591      }
68592
68593      if (options.maximumInputLength > 0) {
68594        options.dataAdapter = Utils.Decorate(
68595          options.dataAdapter,
68596          MaximumInputLength
68597        );
68598      }
68599
68600      if (options.maximumSelectionLength > 0) {
68601        options.dataAdapter = Utils.Decorate(
68602          options.dataAdapter,
68603          MaximumSelectionLength
68604        );
68605      }
68606
68607      if (options.tags) {
68608        options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags);
68609      }
68610
68611      if (options.tokenSeparators != null || options.tokenizer != null) {
68612        options.dataAdapter = Utils.Decorate(
68613          options.dataAdapter,
68614          Tokenizer
68615        );
68616      }
68617
68618      if (options.query != null) {
68619        var Query = require(options.amdBase + 'compat/query');
68620
68621        options.dataAdapter = Utils.Decorate(
68622          options.dataAdapter,
68623          Query
68624        );
68625      }
68626
68627      if (options.initSelection != null) {
68628        var InitSelection = require(options.amdBase + 'compat/initSelection');
68629
68630        options.dataAdapter = Utils.Decorate(
68631          options.dataAdapter,
68632          InitSelection
68633        );
68634      }
68635    }
68636
68637    if (options.resultsAdapter == null) {
68638      options.resultsAdapter = ResultsList;
68639
68640      if (options.ajax != null) {
68641        options.resultsAdapter = Utils.Decorate(
68642          options.resultsAdapter,
68643          InfiniteScroll
68644        );
68645      }
68646
68647      if (options.placeholder != null) {
68648        options.resultsAdapter = Utils.Decorate(
68649          options.resultsAdapter,
68650          HidePlaceholder
68651        );
68652      }
68653
68654      if (options.selectOnClose) {
68655        options.resultsAdapter = Utils.Decorate(
68656          options.resultsAdapter,
68657          SelectOnClose
68658        );
68659      }
68660    }
68661
68662    if (options.dropdownAdapter == null) {
68663      if (options.multiple) {
68664        options.dropdownAdapter = Dropdown;
68665      } else {
68666        var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch);
68667
68668        options.dropdownAdapter = SearchableDropdown;
68669      }
68670
68671      if (options.minimumResultsForSearch !== 0) {
68672        options.dropdownAdapter = Utils.Decorate(
68673          options.dropdownAdapter,
68674          MinimumResultsForSearch
68675        );
68676      }
68677
68678      if (options.closeOnSelect) {
68679        options.dropdownAdapter = Utils.Decorate(
68680          options.dropdownAdapter,
68681          CloseOnSelect
68682        );
68683      }
68684
68685      if (
68686        options.dropdownCssClass != null ||
68687        options.dropdownCss != null ||
68688        options.adaptDropdownCssClass != null
68689      ) {
68690        var DropdownCSS = require(options.amdBase + 'compat/dropdownCss');
68691
68692        options.dropdownAdapter = Utils.Decorate(
68693          options.dropdownAdapter,
68694          DropdownCSS
68695        );
68696      }
68697
68698      options.dropdownAdapter = Utils.Decorate(
68699        options.dropdownAdapter,
68700        AttachBody
68701      );
68702    }
68703
68704    if (options.selectionAdapter == null) {
68705      if (options.multiple) {
68706        options.selectionAdapter = MultipleSelection;
68707      } else {
68708        options.selectionAdapter = SingleSelection;
68709      }
68710
68711      // Add the placeholder mixin if a placeholder was specified
68712      if (options.placeholder != null) {
68713        options.selectionAdapter = Utils.Decorate(
68714          options.selectionAdapter,
68715          Placeholder
68716        );
68717      }
68718
68719      if (options.allowClear) {
68720        options.selectionAdapter = Utils.Decorate(
68721          options.selectionAdapter,
68722          AllowClear
68723        );
68724      }
68725
68726      if (options.multiple) {
68727        options.selectionAdapter = Utils.Decorate(
68728          options.selectionAdapter,
68729          SelectionSearch
68730        );
68731      }
68732
68733      if (
68734        options.containerCssClass != null ||
68735        options.containerCss != null ||
68736        options.adaptContainerCssClass != null
68737      ) {
68738        var ContainerCSS = require(options.amdBase + 'compat/containerCss');
68739
68740        options.selectionAdapter = Utils.Decorate(
68741          options.selectionAdapter,
68742          ContainerCSS
68743        );
68744      }
68745
68746      options.selectionAdapter = Utils.Decorate(
68747        options.selectionAdapter,
68748        EventRelay
68749      );
68750    }
68751
68752    // If the defaults were not previously applied from an element, it is
68753    // possible for the language option to have not been resolved
68754    options.language = this._resolveLanguage(options.language);
68755
68756    // Always fall back to English since it will always be complete
68757    options.language.push('en');
68758
68759    var uniqueLanguages = [];
68760
68761    for (var l = 0; l < options.language.length; l++) {
68762      var language = options.language[l];
68763
68764      if (uniqueLanguages.indexOf(language) === -1) {
68765        uniqueLanguages.push(language);
68766      }
68767    }
68768
68769    options.language = uniqueLanguages;
68770
68771    options.translations = this._processTranslations(
68772      options.language,
68773      options.debug
68774    );
68775
68776    return options;
68777  };
68778
68779  Defaults.prototype.reset = function () {
68780    function stripDiacritics (text) {
68781      // Used 'uni range + named function' from http://jsperf.com/diacritics/18
68782      function match(a) {
68783        return DIACRITICS[a] || a;
68784      }
68785
68786      return text.replace(/[^\u0000-\u007E]/g, match);
68787    }
68788
68789    function matcher (params, data) {
68790      // Always return the object if there is nothing to compare
68791      if ($.trim(params.term) === '') {
68792        return data;
68793      }
68794
68795      // Do a recursive check for options with children
68796      if (data.children && data.children.length > 0) {
68797        // Clone the data object if there are children
68798        // This is required as we modify the object to remove any non-matches
68799        var match = $.extend(true, {}, data);
68800
68801        // Check each child of the option
68802        for (var c = data.children.length - 1; c >= 0; c--) {
68803          var child = data.children[c];
68804
68805          var matches = matcher(params, child);
68806
68807          // If there wasn't a match, remove the object in the array
68808          if (matches == null) {
68809            match.children.splice(c, 1);
68810          }
68811        }
68812
68813        // If any children matched, return the new object
68814        if (match.children.length > 0) {
68815          return match;
68816        }
68817
68818        // If there were no matching children, check just the plain object
68819        return matcher(params, match);
68820      }
68821
68822      var original = stripDiacritics(data.text).toUpperCase();
68823      var term = stripDiacritics(params.term).toUpperCase();
68824
68825      // Check if the text contains the term
68826      if (original.indexOf(term) > -1) {
68827        return data;
68828      }
68829
68830      // If it doesn't contain the term, don't return anything
68831      return null;
68832    }
68833
68834    this.defaults = {
68835      amdBase: './',
68836      amdLanguageBase: './i18n/',
68837      closeOnSelect: true,
68838      debug: false,
68839      dropdownAutoWidth: false,
68840      escapeMarkup: Utils.escapeMarkup,
68841      language: {},
68842      matcher: matcher,
68843      minimumInputLength: 0,
68844      maximumInputLength: 0,
68845      maximumSelectionLength: 0,
68846      minimumResultsForSearch: 0,
68847      selectOnClose: false,
68848      scrollAfterSelect: false,
68849      sorter: function (data) {
68850        return data;
68851      },
68852      templateResult: function (result) {
68853        return result.text;
68854      },
68855      templateSelection: function (selection) {
68856        return selection.text;
68857      },
68858      theme: 'default',
68859      width: 'resolve'
68860    };
68861  };
68862
68863  Defaults.prototype.applyFromElement = function (options, $element) {
68864    var optionLanguage = options.language;
68865    var defaultLanguage = this.defaults.language;
68866    var elementLanguage = $element.prop('lang');
68867    var parentLanguage = $element.closest('[lang]').prop('lang');
68868
68869    var languages = Array.prototype.concat.call(
68870      this._resolveLanguage(elementLanguage),
68871      this._resolveLanguage(optionLanguage),
68872      this._resolveLanguage(defaultLanguage),
68873      this._resolveLanguage(parentLanguage)
68874    );
68875
68876    options.language = languages;
68877
68878    return options;
68879  };
68880
68881  Defaults.prototype._resolveLanguage = function (language) {
68882    if (!language) {
68883      return [];
68884    }
68885
68886    if ($.isEmptyObject(language)) {
68887      return [];
68888    }
68889
68890    if ($.isPlainObject(language)) {
68891      return [language];
68892    }
68893
68894    var languages;
68895
68896    if (!$.isArray(language)) {
68897      languages = [language];
68898    } else {
68899      languages = language;
68900    }
68901
68902    var resolvedLanguages = [];
68903
68904    for (var l = 0; l < languages.length; l++) {
68905      resolvedLanguages.push(languages[l]);
68906
68907      if (typeof languages[l] === 'string' && languages[l].indexOf('-') > 0) {
68908        // Extract the region information if it is included
68909        var languageParts = languages[l].split('-');
68910        var baseLanguage = languageParts[0];
68911
68912        resolvedLanguages.push(baseLanguage);
68913      }
68914    }
68915
68916    return resolvedLanguages;
68917  };
68918
68919  Defaults.prototype._processTranslations = function (languages, debug) {
68920    var translations = new Translation();
68921
68922    for (var l = 0; l < languages.length; l++) {
68923      var languageData = new Translation();
68924
68925      var language = languages[l];
68926
68927      if (typeof language === 'string') {
68928        try {
68929          // Try to load it with the original name
68930          languageData = Translation.loadPath(language);
68931        } catch (e) {
68932          try {
68933            // If we couldn't load it, check if it wasn't the full path
68934            language = this.defaults.amdLanguageBase + language;
68935            languageData = Translation.loadPath(language);
68936          } catch (ex) {
68937            // The translation could not be loaded at all. Sometimes this is
68938            // because of a configuration problem, other times this can be
68939            // because of how Select2 helps load all possible translation files
68940            if (debug && window.console && console.warn) {
68941              console.warn(
68942                'Select2: The language file for "' + language + '" could ' +
68943                'not be automatically loaded. A fallback will be used instead.'
68944              );
68945            }
68946          }
68947        }
68948      } else if ($.isPlainObject(language)) {
68949        languageData = new Translation(language);
68950      } else {
68951        languageData = language;
68952      }
68953
68954      translations.extend(languageData);
68955    }
68956
68957    return translations;
68958  };
68959
68960  Defaults.prototype.set = function (key, value) {
68961    var camelKey = $.camelCase(key);
68962
68963    var data = {};
68964    data[camelKey] = value;
68965
68966    var convertedData = Utils._convertData(data);
68967
68968    $.extend(true, this.defaults, convertedData);
68969  };
68970
68971  var defaults = new Defaults();
68972
68973  return defaults;
68974});
68975
68976S2.define('select2/options',[
68977  'require',
68978  'jquery',
68979  './defaults',
68980  './utils'
68981], function (require, $, Defaults, Utils) {
68982  function Options (options, $element) {
68983    this.options = options;
68984
68985    if ($element != null) {
68986      this.fromElement($element);
68987    }
68988
68989    if ($element != null) {
68990      this.options = Defaults.applyFromElement(this.options, $element);
68991    }
68992
68993    this.options = Defaults.apply(this.options);
68994
68995    if ($element && $element.is('input')) {
68996      var InputCompat = require(this.get('amdBase') + 'compat/inputData');
68997
68998      this.options.dataAdapter = Utils.Decorate(
68999        this.options.dataAdapter,
69000        InputCompat
69001      );
69002    }
69003  }
69004
69005  Options.prototype.fromElement = function ($e) {
69006    var excludedData = ['select2'];
69007
69008    if (this.options.multiple == null) {
69009      this.options.multiple = $e.prop('multiple');
69010    }
69011
69012    if (this.options.disabled == null) {
69013      this.options.disabled = $e.prop('disabled');
69014    }
69015
69016    if (this.options.dir == null) {
69017      if ($e.prop('dir')) {
69018        this.options.dir = $e.prop('dir');
69019      } else if ($e.closest('[dir]').prop('dir')) {
69020        this.options.dir = $e.closest('[dir]').prop('dir');
69021      } else {
69022        this.options.dir = 'ltr';
69023      }
69024    }
69025
69026    $e.prop('disabled', this.options.disabled);
69027    $e.prop('multiple', this.options.multiple);
69028
69029    if (Utils.GetData($e[0], 'select2Tags')) {
69030      if (this.options.debug && window.console && console.warn) {
69031        console.warn(
69032          'Select2: The `data-select2-tags` attribute has been changed to ' +
69033          'use the `data-data` and `data-tags="true"` attributes and will be ' +
69034          'removed in future versions of Select2.'
69035        );
69036      }
69037
69038      Utils.StoreData($e[0], 'data', Utils.GetData($e[0], 'select2Tags'));
69039      Utils.StoreData($e[0], 'tags', true);
69040    }
69041
69042    if (Utils.GetData($e[0], 'ajaxUrl')) {
69043      if (this.options.debug && window.console && console.warn) {
69044        console.warn(
69045          'Select2: The `data-ajax-url` attribute has been changed to ' +
69046          '`data-ajax--url` and support for the old attribute will be removed' +
69047          ' in future versions of Select2.'
69048        );
69049      }
69050
69051      $e.attr('ajax--url', Utils.GetData($e[0], 'ajaxUrl'));
69052      Utils.StoreData($e[0], 'ajax-Url', Utils.GetData($e[0], 'ajaxUrl'));
69053    }
69054
69055    var dataset = {};
69056
69057    function upperCaseLetter(_, letter) {
69058      return letter.toUpperCase();
69059    }
69060
69061    // Pre-load all of the attributes which are prefixed with `data-`
69062    for (var attr = 0; attr < $e[0].attributes.length; attr++) {
69063      var attributeName = $e[0].attributes[attr].name;
69064      var prefix = 'data-';
69065
69066      if (attributeName.substr(0, prefix.length) == prefix) {
69067        // Get the contents of the attribute after `data-`
69068        var dataName = attributeName.substring(prefix.length);
69069
69070        // Get the data contents from the consistent source
69071        // This is more than likely the jQuery data helper
69072        var dataValue = Utils.GetData($e[0], dataName);
69073
69074        // camelCase the attribute name to match the spec
69075        var camelDataName = dataName.replace(/-([a-z])/g, upperCaseLetter);
69076
69077        // Store the data attribute contents into the dataset since
69078        dataset[camelDataName] = dataValue;
69079      }
69080    }
69081
69082    // Prefer the element's `dataset` attribute if it exists
69083    // jQuery 1.x does not correctly handle data attributes with multiple dashes
69084    if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) {
69085      dataset = $.extend(true, {}, $e[0].dataset, dataset);
69086    }
69087
69088    // Prefer our internal data cache if it exists
69089    var data = $.extend(true, {}, Utils.GetData($e[0]), dataset);
69090
69091    data = Utils._convertData(data);
69092
69093    for (var key in data) {
69094      if ($.inArray(key, excludedData) > -1) {
69095        continue;
69096      }
69097
69098      if ($.isPlainObject(this.options[key])) {
69099        $.extend(this.options[key], data[key]);
69100      } else {
69101        this.options[key] = data[key];
69102      }
69103    }
69104
69105    return this;
69106  };
69107
69108  Options.prototype.get = function (key) {
69109    return this.options[key];
69110  };
69111
69112  Options.prototype.set = function (key, val) {
69113    this.options[key] = val;
69114  };
69115
69116  return Options;
69117});
69118
69119S2.define('select2/core',[
69120  'jquery',
69121  './options',
69122  './utils',
69123  './keys'
69124], function ($, Options, Utils, KEYS) {
69125  var Select2 = function ($element, options) {
69126    if (Utils.GetData($element[0], 'select2') != null) {
69127      Utils.GetData($element[0], 'select2').destroy();
69128    }
69129
69130    this.$element = $element;
69131
69132    this.id = this._generateId($element);
69133
69134    options = options || {};
69135
69136    this.options = new Options(options, $element);
69137
69138    Select2.__super__.constructor.call(this);
69139
69140    // Set up the tabindex
69141
69142    var tabindex = $element.attr('tabindex') || 0;
69143    Utils.StoreData($element[0], 'old-tabindex', tabindex);
69144    $element.attr('tabindex', '-1');
69145
69146    // Set up containers and adapters
69147
69148    var DataAdapter = this.options.get('dataAdapter');
69149    this.dataAdapter = new DataAdapter($element, this.options);
69150
69151    var $container = this.render();
69152
69153    this._placeContainer($container);
69154
69155    var SelectionAdapter = this.options.get('selectionAdapter');
69156    this.selection = new SelectionAdapter($element, this.options);
69157    this.$selection = this.selection.render();
69158
69159    this.selection.position(this.$selection, $container);
69160
69161    var DropdownAdapter = this.options.get('dropdownAdapter');
69162    this.dropdown = new DropdownAdapter($element, this.options);
69163    this.$dropdown = this.dropdown.render();
69164
69165    this.dropdown.position(this.$dropdown, $container);
69166
69167    var ResultsAdapter = this.options.get('resultsAdapter');
69168    this.results = new ResultsAdapter($element, this.options, this.dataAdapter);
69169    this.$results = this.results.render();
69170
69171    this.results.position(this.$results, this.$dropdown);
69172
69173    // Bind events
69174
69175    var self = this;
69176
69177    // Bind the container to all of the adapters
69178    this._bindAdapters();
69179
69180    // Register any DOM event handlers
69181    this._registerDomEvents();
69182
69183    // Register any internal event handlers
69184    this._registerDataEvents();
69185    this._registerSelectionEvents();
69186    this._registerDropdownEvents();
69187    this._registerResultsEvents();
69188    this._registerEvents();
69189
69190    // Set the initial state
69191    this.dataAdapter.current(function (initialData) {
69192      self.trigger('selection:update', {
69193        data: initialData
69194      });
69195    });
69196
69197    // Hide the original select
69198    $element.addClass('select2-hidden-accessible');
69199    $element.attr('aria-hidden', 'true');
69200
69201    // Synchronize any monitored attributes
69202    this._syncAttributes();
69203
69204    Utils.StoreData($element[0], 'select2', this);
69205
69206    // Ensure backwards compatibility with $element.data('select2').
69207    $element.data('select2', this);
69208  };
69209
69210  Utils.Extend(Select2, Utils.Observable);
69211
69212  Select2.prototype._generateId = function ($element) {
69213    var id = '';
69214
69215    if ($element.attr('id') != null) {
69216      id = $element.attr('id');
69217    } else if ($element.attr('name') != null) {
69218      id = $element.attr('name') + '-' + Utils.generateChars(2);
69219    } else {
69220      id = Utils.generateChars(4);
69221    }
69222
69223    id = id.replace(/(:|\.|\[|\]|,)/g, '');
69224    id = 'select2-' + id;
69225
69226    return id;
69227  };
69228
69229  Select2.prototype._placeContainer = function ($container) {
69230    $container.insertAfter(this.$element);
69231
69232    var width = this._resolveWidth(this.$element, this.options.get('width'));
69233
69234    if (width != null) {
69235      $container.css('width', width);
69236    }
69237  };
69238
69239  Select2.prototype._resolveWidth = function ($element, method) {
69240    var WIDTH = /^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;
69241
69242    if (method == 'resolve') {
69243      var styleWidth = this._resolveWidth($element, 'style');
69244
69245      if (styleWidth != null) {
69246        return styleWidth;
69247      }
69248
69249      return this._resolveWidth($element, 'element');
69250    }
69251
69252    if (method == 'element') {
69253      var elementWidth = $element.outerWidth(false);
69254
69255      if (elementWidth <= 0) {
69256        return 'auto';
69257      }
69258
69259      return elementWidth + 'px';
69260    }
69261
69262    if (method == 'style') {
69263      var style = $element.attr('style');
69264
69265      if (typeof(style) !== 'string') {
69266        return null;
69267      }
69268
69269      var attrs = style.split(';');
69270
69271      for (var i = 0, l = attrs.length; i < l; i = i + 1) {
69272        var attr = attrs[i].replace(/\s/g, '');
69273        var matches = attr.match(WIDTH);
69274
69275        if (matches !== null && matches.length >= 1) {
69276          return matches[1];
69277        }
69278      }
69279
69280      return null;
69281    }
69282
69283    if (method == 'computedstyle') {
69284      var computedStyle = window.getComputedStyle($element[0]);
69285
69286      return computedStyle.width;
69287    }
69288
69289    return method;
69290  };
69291
69292  Select2.prototype._bindAdapters = function () {
69293    this.dataAdapter.bind(this, this.$container);
69294    this.selection.bind(this, this.$container);
69295
69296    this.dropdown.bind(this, this.$container);
69297    this.results.bind(this, this.$container);
69298  };
69299
69300  Select2.prototype._registerDomEvents = function () {
69301    var self = this;
69302
69303    this.$element.on('change.select2', function () {
69304      self.dataAdapter.current(function (data) {
69305        self.trigger('selection:update', {
69306          data: data
69307        });
69308      });
69309    });
69310
69311    this.$element.on('focus.select2', function (evt) {
69312      self.trigger('focus', evt);
69313    });
69314
69315    this._syncA = Utils.bind(this._syncAttributes, this);
69316    this._syncS = Utils.bind(this._syncSubtree, this);
69317
69318    if (this.$element[0].attachEvent) {
69319      this.$element[0].attachEvent('onpropertychange', this._syncA);
69320    }
69321
69322    var observer = window.MutationObserver ||
69323      window.WebKitMutationObserver ||
69324      window.MozMutationObserver
69325    ;
69326
69327    if (observer != null) {
69328      this._observer = new observer(function (mutations) {
69329        self._syncA();
69330        self._syncS(null, mutations);
69331      });
69332      this._observer.observe(this.$element[0], {
69333        attributes: true,
69334        childList: true,
69335        subtree: false
69336      });
69337    } else if (this.$element[0].addEventListener) {
69338      this.$element[0].addEventListener(
69339        'DOMAttrModified',
69340        self._syncA,
69341        false
69342      );
69343      this.$element[0].addEventListener(
69344        'DOMNodeInserted',
69345        self._syncS,
69346        false
69347      );
69348      this.$element[0].addEventListener(
69349        'DOMNodeRemoved',
69350        self._syncS,
69351        false
69352      );
69353    }
69354  };
69355
69356  Select2.prototype._registerDataEvents = function () {
69357    var self = this;
69358
69359    this.dataAdapter.on('*', function (name, params) {
69360      self.trigger(name, params);
69361    });
69362  };
69363
69364  Select2.prototype._registerSelectionEvents = function () {
69365    var self = this;
69366    var nonRelayEvents = ['toggle', 'focus'];
69367
69368    this.selection.on('toggle', function () {
69369      self.toggleDropdown();
69370    });
69371
69372    this.selection.on('focus', function (params) {
69373      self.focus(params);
69374    });
69375
69376    this.selection.on('*', function (name, params) {
69377      if ($.inArray(name, nonRelayEvents) !== -1) {
69378        return;
69379      }
69380
69381      self.trigger(name, params);
69382    });
69383  };
69384
69385  Select2.prototype._registerDropdownEvents = function () {
69386    var self = this;
69387
69388    this.dropdown.on('*', fu
69388nction (name, params) {
69389      self.trigger(name, params);
69390    });
69391  };
69392
69393  Select2.prototype._registerResultsEvents = function () {
69394    var self = this;
69395
69396    this.results.on('*', function (name, params) {
69397      self.trigger(name, params);
69398    });
69399  };
69400
69401  Select2.prototype._registerEvents = function () {
69402    var self = this;
69403
69404    this.on('open', function () {
69405      self.$container.addClass('select2-container--open');
69406    });
69407
69408    this.on('close', function () {
69409      self.$container.removeClass('select2-container--open');
69410    });
69411
69412    this.on('enable', function () {
69413      self.$container.removeClass('select2-container--disabled');
69414    });
69415
69416    this.on('disable', function () {
69417      self.$container.addClass('select2-container--disabled');
69418    });
69419
69420    this.on('blur', function () {
69421      self.$container.removeClass('select2-container--focus');
69422    });
69423
69424    this.on('query', function (params) {
69425      if (!self.isOpen()) {
69426        self.trigger('open', {});
69427      }
69428
69429      this.dataAdapter.query(params, function (data) {
69430        self.trigger('results:all', {
69431          data: data,
69432          query: params
69433        });
69434      });
69435    });
69436
69437    this.on('query:append', function (params) {
69438      this.dataAdapter.query(params, function (data) {
69439        self.trigger('results:append', {
69440          data: data,
69441          query: params
69442        });
69443      });
69444    });
69445
69446    this.on('keypress', function (evt) {
69447      var key = evt.which;
69448
69449      if (self.isOpen()) {
69450        if (key === KEYS.ESC || key === KEYS.TAB ||
69451            (key === KEYS.UP && evt.altKey)) {
69452          self.close(evt);
69453
69454          evt.preventDefault();
69455        } else if (key === KEYS.ENTER) {
69456          self.trigger('results:select', {});
69457
69458          evt.preventDefault();
69459        } else if ((key === KEYS.SPACE && evt.ctrlKey)) {
69460          self.trigger('results:toggle', {});
69461
69462          evt.preventDefault();
69463        } else if (key === KEYS.UP) {
69464          self.trigger('results:previous', {});
69465
69466          evt.preventDefault();
69467        } else if (key === KEYS.DOWN) {
69468          self.trigger('results:next', {});
69469
69470          evt.preventDefault();
69471        }
69472      } else {
69473        if (key === KEYS.ENTER || key === KEYS.SPACE ||
69474            (key === KEYS.DOWN && evt.altKey)) {
69475          self.open();
69476
69477          evt.preventDefault();
69478        }
69479      }
69480    });
69481  };
69482
69483  Select2.prototype._syncAttributes = function () {
69484    this.options.set('disabled', this.$element.prop('disabled'));
69485
69486    if (this.isDisabled()) {
69487      if (this.isOpen()) {
69488        this.close();
69489      }
69490
69491      this.trigger('disable', {});
69492    } else {
69493      this.trigger('enable', {});
69494    }
69495  };
69496
69497  Select2.prototype._isChangeMutation = function (evt, mutations) {
69498    var changed = false;
69499    var self = this;
69500
69501    // Ignore any mutation events raised for elements that aren't options or
69502    // optgroups. This handles the case when the select element is destroyed
69503    if (
69504      evt && evt.target && (
69505        evt.target.nodeName !== 'OPTION' && evt.target.nodeName !== 'OPTGROUP'
69506      )
69507    ) {
69508      return;
69509    }
69510
69511    if (!mutations) {
69512      // If mutation events aren't supported, then we can only assume that the
69513      // change affected the selections
69514      changed = true;
69515    } else if (mutations.addedNodes && mutations.addedNodes.length > 0) {
69516      for (var n = 0; n < mutations.addedNodes.length; n++) {
69517        var node = mutations.addedNodes[n];
69518
69519        if (node.selected) {
69520          changed = true;
69521        }
69522      }
69523    } else if (mutations.removedNodes && mutations.removedNodes.length > 0) {
69524      changed = true;
69525    } else if ($.isArray(mutations)) {
69526      $.each(mutations, function(evt, mutation) {
69527        if (self._isChangeMutation(evt, mutation)) {
69528          // We've found a change mutation.
69529          // Let's escape from the loop and continue
69530          changed = true;
69531          return false;
69532        }
69533      });
69534    }
69535    return changed;
69536  };
69537
69538  Select2.prototype._syncSubtree = function (evt, mutations) {
69539    var changed = this._isChangeMutation(evt, mutations);
69540    var self = this;
69541
69542    // Only re-pull the data if we think there is a change
69543    if (changed) {
69544      this.dataAdapter.current(function (currentData) {
69545        self.trigger('selection:update', {
69546          data: currentData
69547        });
69548      });
69549    }
69550  };
69551
69552  /**
69553   * Override the trigger method to automatically trigger pre-events when
69554   * there are events that can be prevented.
69555   */
69556  Select2.prototype.trigger = function (name, args) {
69557    var actualTrigger = Select2.__super__.trigger;
69558    var preTriggerMap = {
69559      'open': 'opening',
69560      'close': 'closing',
69561      'select': 'selecting',
69562      'unselect': 'unselecting',
69563      'clear': 'clearing'
69564    };
69565
69566    if (args === undefined) {
69567      args = {};
69568    }
69569
69570    if (name in preTriggerMap) {
69571      var preTriggerName = preTriggerMap[name];
69572      var preTriggerArgs = {
69573        prevented: false,
69574        name: name,
69575        args: args
69576      };
69577
69578      actualTrigger.call(this, preTriggerName, preTriggerArgs);
69579
69580      if (preTriggerArgs.prevented) {
69581        args.prevented = true;
69582
69583        return;
69584      }
69585    }
69586
69587    actualTrigger.call(this, name, args);
69588  };
69589
69590  Select2.prototype.toggleDropdown = function () {
69591    if (this.isDisabled()) {
69592      return;
69593    }
69594
69595    if (this.isOpen()) {
69596      this.close();
69597    } else {
69598      this.open();
69599    }
69600  };
69601
69602  Select2.prototype.open = function () {
69603    if (this.isOpen()) {
69604      return;
69605    }
69606
69607    if (this.isDisabled()) {
69608      return;
69609    }
69610
69611    this.trigger('query', {});
69612  };
69613
69614  Select2.prototype.close = function (evt) {
69615    if (!this.isOpen()) {
69616      return;
69617    }
69618
69619    this.trigger('close', { originalEvent : evt });
69620  };
69621
69622  /**
69623   * Helper method to abstract the "enabled" (not "disabled") state of this
69624   * object.
69625   *
69626   * @return {true} if the instance is not disabled.
69627   * @return {false} if the instance is disabled.
69628   */
69629  Select2.prototype.isEnabled = function () {
69630    return !this.isDisabled();
69631  };
69632
69633  /**
69634   * Helper method to abstract the "disabled" state of this object.
69635   *
69636   * @return {true} if the disabled option is true.
69637   * @return {false} if the disabled option is false.
69638   */
69639  Select2.prototype.isDisabled = function () {
69640    return this.options.get('disabled');
69641  };
69642
69643  Select2.prototype.isOpen = function () {
69644    return this.$container.hasClass('select2-container--open');
69645  };
69646
69647  Select2.prototype.hasFocus = function () {
69648    return this.$container.hasClass('select2-container--focus');
69649  };
69650
69651  Select2.prototype.focus = function (data) {
69652    // No need to re-trigger focus events if we are already focused
69653    if (this.hasFocus()) {
69654      return;
69655    }
69656
69657    this.$container.addClass('select2-container--focus');
69658    this.trigger('focus', {});
69659  };
69660
69661  Select2.prototype.enable = function (args) {
69662    if (this.options.get('debug') && window.console && console.warn) {
69663      console.warn(
69664        'Select2: The `select2("enable")` method has been deprecated and will' +
69665        ' be removed in later Select2 versions. Use $element.prop("disabled")' +
69666        ' instead.'
69667      );
69668    }
69669
69670    if (args == null || args.length === 0) {
69671      args = [true];
69672    }
69673
69674    var disabled = !args[0];
69675
69676    this.$element.prop('disabled', disabled);
69677  };
69678
69679  Select2.prototype.data = function () {
69680    if (this.options.get('debug') &&
69681        arguments.length > 0 && window.console && console.warn) {
69682      console.warn(
69683        'Select2: Data can no longer be set using `select2("data")`. You ' +
69684        'should consider setting the value instead using `$element.val()`.'
69685      );
69686    }
69687
69688    var data = [];
69689
69690    this.dataAdapter.current(function (currentData) {
69691      data = currentData;
69692    });
69693
69694    return data;
69695  };
69696
69697  Select2.prototype.val = function (args) {
69698    if (this.options.get('debug') && window.console && console.warn) {
69699      console.warn(
69700        'Select2: The `select2("val")` method has been deprecated and will be' +
69701        ' removed in later Select2 versions. Use $element.val() instead.'
69702      );
69703    }
69704
69705    if (args == null || args.length === 0) {
69706      return this.$element.val();
69707    }
69708
69709    var newVal = args[0];
69710
69711    if ($.isArray(newVal)) {
69712      newVal = $.map(newVal, function (obj) {
69713        return obj.toString();
69714      });
69715    }
69716
69717    this.$element.val(newVal).trigger('input').trigger('change');
69718  };
69719
69720  Select2.prototype.destroy = function () {
69721    this.$container.remove();
69722
69723    if (this.$element[0].detachEvent) {
69724      this.$element[0].detachEvent('onpropertychange', this._syncA);
69725    }
69726
69727    if (this._observer != null) {
69728      this._observer.disconnect();
69729      this._observer = null;
69730    } else if (this.$element[0].removeEventListener) {
69731      this.$element[0]
69732        .removeEventListener('DOMAttrModified', this._syncA, false);
69733      this.$element[0]
69734        .removeEventListener('DOMNodeInserted', this._syncS, false);
69735      this.$element[0]
69736        .removeEventListener('DOMNodeRemoved', this._syncS, false);
69737    }
69738
69739    this._syncA = null;
69740    this._syncS = null;
69741
69742    this.$element.off('.select2');
69743    this.$element.attr('tabindex',
69744    Utils.GetData(this.$element[0], 'old-tabindex'));
69745
69746    this.$element.removeClass('select2-hidden-accessible');
69747    this.$element.attr('aria-hidden', 'false');
69748    Utils.RemoveData(this.$element[0]);
69749    this.$element.removeData('select2');
69750
69751    this.dataAdapter.destroy();
69752    this.selection.destroy();
69753    this.dropdown.destroy();
69754    this.results.destroy();
69755
69756    this.dataAdapter = null;
69757    this.selection = null;
69758    this.dropdown = null;
69759    this.results = null;
69760  };
69761
69762  Select2.prototype.render = function () {
69763    var $container = $(
69764      '<span class="select2 select2-container">' +
69765        '<span class="selection"></span>' +
69766        '<span class="dropdown-wrapper" aria-hidden="true"></span>' +
69767      '</span>'
69768    );
69769
69770    $container.attr('dir', this.options.get('dir'));
69771
69772    this.$container = $container;
69773
69774    this.$container.addClass('select2-container--' + this.options.get('theme'));
69775
69776    Utils.StoreData($container[0], 'element', this.$element);
69777
69778    return $container;
69779  };
69780
69781  return Select2;
69782});
69783
69784S2.define('jquery-mousewheel',[
69785  'jquery'
69786], function ($) {
69787  // Used to shim jQuery.mousewheel for non-full builds.
69788  return $;
69789});
69790
69791S2.define('jquery.select2',[
69792  'jquery',
69793  'jquery-mousewheel',
69794
69795  './select2/core',
69796  './select2/defaults',
69797  './select2/utils'
69798], function ($, _, Select2, Defaults, Utils) {
69799  if ($.fn.select2 == null) {
69800    // All methods that should return the element
69801    var thisMethods = ['open', 'close', 'destroy'];
69802
69803    $.fn.select2 = function (options) {
69804      options = options || {};
69805
69806      if (typeof options === 'object') {
69807        this.each(function () {
69808          var instanceOptions = $.extend(true, {}, options);
69809
69810          var instance = new Select2($(this), instanceOptions);
69811        });
69812
69813        return this;
69814      } else if (typeof options === 'string') {
69815        var ret;
69816        var args = Array.prototype.slice.call(arguments, 1);
69817
69818        this.each(function () {
69819          var instance = Utils.GetData(this, 'select2');
69820
69821          if (instance == null && window.console && console.error) {
69822            console.error(
69823              'The select2(\'' + options + '\') method was called on an ' +
69824              'element that is not using Select2.'
69825            );
69826          }
69827
69828          ret = instance[options].apply(instance, args);
69829        });
69830
69831        // Check if we should be returning `this`
69832        if ($.inArray(options, thisMethods) > -1) {
69833          return this;
69834        }
69835
69836        return ret;
69837      } else {
69838        throw new Error('Invalid arguments for Select2: ' + options);
69839      }
69840    };
69841  }
69842
69843  if ($.fn.select2.defaults == null) {
69844    $.fn.select2.defaults = Defaults;
69845  }
69846
69847  return Select2;
69848});
69849
69850  // Return the AMD loader configuration so it can be used outside of this file
69851  return {
69852    define: S2.define,
69853    require: S2.require
69854  };
69855}());
69856
69857  // Autoload the jQuery bindings
69858  // We know that all of the modules exist above this, so we're safe
69859  var select2 = S2.require('jquery.select2');
69860
69861  // Hold the AMD module references on the jQuery function that was just loaded
69862  // This allows Select2 to use the internal loader outside of this file, such
69863  // as in the language files.
69864  jQuery.fn.select2.amd = S2;
69865
69866  // Return the Select2 instance for anyone who is importing it.
69867  return select2;
69868}));
69869(function() {
69870  var appendData, fetching, installScrollCallback;
69871
69872  installScrollCallback = true;
69873
69874  fetching = false;
69875
69876  appendData = function() {
69877    var url;
69878    url = $("[data-dynamic-load='true']").data("fetch-url");
69879    if (fetching || (url == null) || url === "") {
69880      return;
69881    }
69882    fetching = true;
69883    return $.get(url).always(function() {
69884      return fetching = false;
69885    });
69886  };
69887
69888  $(document).ready(function() {
69889    if (installScrollCallback) {
69890      $(window).scroll(function() {
69891        if ($(window).scrollTop() + 20 >= $(document).height() - $(window).height()) {
69892          return appendData();
69893        }
69894      });
69895      return installScrollCallback = false;
69896    }
69897  });
69898
69899}).call(this);
69900
69901  function setup_ace_editor(elm_id, update_elm_id) {
69902    var block_editor = ace_rails.edit(elm_id, {
69903      mode: "ace/mode/liquid",
69904      tabSize: 2,
69905    });
69906    window.block_editor = block_editor
69907    block_editor.setTheme("ace/theme/merbivore");
69908    block_editor.session.setMode("ace/mode/liquid");
69909    
69910    block_editor.on('change', (e) => {
69911      const body = block_editor.getSession().getValue()
69912      $(update_elm_id).val(body)
69913    })
69914
69915    document.getElementById(elm_id).addEventListener('paste', (e) => {
69916      console.log(e)
69917      upload_image_files(e.clipboardData.files[0])
69918    })
69919  };
69920function update_select(){
69921  if ($(".evaluation input.batch:checked").length > 0) {
69922    $(".not-selected-title").hide()
69923    $(".selected-title").show()
69924    copy_evaluator_ids_field();
69925  } else {
69926    $(".not-selected-title").show()
69927    $(".selected-title").hide()
69928  }
69929}
69930
69931function init_assignees(){
69932  $('input.evaluation-daterange').each(function(index, input){
69933    var evaluation_option = $.extend(true, {}, window.daterangepicker_config);
69934    if ($(this).data("default-duration")) {
69935      var duration = $(this).data("default-duration").split(" - ").map(function(date){return new Date(date)});
69936      evaluation_option.ranges = evaluation_option.ranges || {};
69937      evaluation_option.ranges["デフォルト"] = duration;
69938    }
69939    var evaluation_option = $.extend(true, {}, evaluation_option, window.default_evaluation_duration)
69940    $(this).daterangepicker(evaluation_option);
69941  })
69942
69943  $('input.evaluation-date-filter, input.evaluation-daterange').on("apply.daterangepicker", function(){
69944    $(this.form).trigger("submit.rails");
69945  });
69946  $(".evaluatee-results").html("");
69947  $(".batch-filter").removeClass("open");
69948  copy_evaluator_ids_field();
69949}
69950
69951function get_data_from(form, index){
69952  var data = $(form).serializeArray();
69953  data = data.map(function(form_data){
69954    if (form_data.name.match(/^evaluation\[/)) {
69955      form_data.name = "evaluations["+index+"]" + form_data.name.replace(/^evaluation\[/, "[evaluation][")
69956      return form_data;
69957    } else {
69958      return null;
69959    }
69960  }).filter(function(x){ return x != null})
69961  return data;
69962}
69963
69964function copy_evaluator_ids_field(){
69965  $(".batch-ids").remove();
69966  $(".evaluation input.batch:checked").each(function(index, checked_input){
69967    var evaluator_input = $(checked_input).closest(".row").find(".evaluator-ids").clone().addClass("batch-evaluator-ids").addClass("batch-ids").prop("name", "evaluator_ids[]");
69968    $("form.batch-evaluator").append(evaluator_input);
69969
69970    var reviewer_input = $(checked_input).closest(".row").find(".reviewer-ids").clone().addClass("batch-reviewer-ids").addClass("batch-ids").prop("name", "reviewer_ids[]");
69971    $("form.batch-reviewer").append(reviewer_input);
69972  })
69973}
69974
69975function show_evaluation_loading(target) {
69976  $(target).closest(".evaluation").children(".loading-show").show();
69977}
69978
69979$(document).on("submit.rails", ".update-evaluation-form", function(){
69980  show_evaluation_loading(this);
69981})
69982
69983$(document).on("mouseenter", ".select-item-batch", function() {
69984  $(".select-item-batch.selected").removeClass("selected");
69985  $(this).addClass("selected");
69986});
69987
69988$(document).on("keypress", ".batch-filter-menu, .select-filter-menu", function(event){
69989  if (event.which == 13) {
69990    var selected = $(".select-item-batch.selected:visible");
69991    if (selected.length == 0) return;
69992    selected.trigger("click");
69993    return false;
69994  }
69995});
69996
69997$(document).on("keyup", ".batch-filter-menu, .select-filter-menu", function(event){
69998  if (event.which == 27) {
69999    $("batch-filter").removeClass("open");
70000    return false;
70001  } else if (event.which == 13) {
70002    return false;
70003  } else if (event.which == 40 || event.which == 38 && $(".select-item-batch.selected:visible").length > 0) {
70004    var selected;
70005    if (event.which == 40) {
70006      selected = $(".select-item-batch.selected:visible").next();
70007      if (selected.length == 0) selected = $(".select-item-batch.selected:visible").first();
70008    } else {
70009      selected = $(".select-item-batch.selected:visible").prev();
70010      if (selected.length == 0) selected = $(".select-item-batch.selected:visible").last();
70011    }
70012    $(".select-item-batch.selected").removeClass("selected");
70013    selected.addClass("selected")
70014    return false;
70015  } else {
70016    if ($(this).hasClass("batch-filter-menu")) {
70017      $(this).find("form").trigger("submit.rails");
70018    } else {
70019      var input = $(this).find(".filter-input");
70020      var source = input.data("data-source");
70021      var query = input.val();
70022      $.ajax({url: source, type: "GET", data: {q: query}});
70023    }
70024    return true;
70025  }
70026})
70027
70028$(document).on('shown.bs.dropdown', ".batch-filter", function(event) {
70029  var dropdown = $(event.target);
70030  $(this).find("filter-input").val("");
70031  $(this).find(".filter-input:visible").trigger("keyup");
70032
70033  setTimeout(function() {
70034    dropdown.find('.dropdown-menu .filter-input:first').focus();
70035  }, 10);
70036});
70037
70038$(document).on("click", ".filter-submit", function(event){
70039  $(".filter-input:visible").trigger("keyup");
70040  return false;
70041})
70042
70043$(document).on("click", ".not-saved .delete-button", function(event){
70044  var target = $(this).closest(".evaluation");
70045  var user_id = target.data("user");
70046  if ($(".evaluation[data-user='" + user_id + "']").length > 1) {
70047    target.remove();
70048  } else {
70049    alert("削除できません")
70050  }
70051  return false;
70052})
70053
70054$(document).off("click", ".select-filter-menu .select-evaluator .select-user").on("click", ".select-filter-menu .select-evaluator .select-user", function(){
70055  var form = $(this).closest("form");
70056  var user_id = $(this).data("user-id");
70057  form.find(".evaluator-ids").val(user_id);
70058
70059  form.trigger("submit.rails");
70060})
70061
70062$(document).off("click", ".evaluation input.batch").on("click", ".evaluation input.batch", function(){
70063  if (!$(this).prop("checked")) $(".evaluation_all").prop("checked", false);
70064  update_select();
70065});
70066
70067$(document).off("click", ".batch-filter-menu .select-evaluator .select-user").on("click", ".batch-filter-menu .select-evaluator .select-user", function(){
70068  var user_id = $(this).data("user-id");
70069  var datas = [];
70070  $(".evaluation input.batch:checked").each(function(index, checkbox){
70071    var data = get_data_from($(checkbox).closest("form"), index);
70072    data.push({name: "evaluations["+index+"][evaluation][evaluator_user_id]", value: user_id})
70073    datas = datas.concat(data);
70074    show_evaluation_loading(checkbox);
70075  })
70076
70077  $.ajax({url: $(".assignees-header ").data("batch-url"), type: "PATCH", data: $.param(datas)});
70078})
70079
70080$(document).off("click", ".batch-filter-menu .select-reviewer .not-selected").on("click", ".batch-filter-menu .select-reviewer .not-selected", function(){
70081  var user_id = $(this).data("user-id");
70082  var datas = [];
70083  $(".evaluation input.batch:checked").each(function(index, checkbox){
70084    var data = get_data_from($(checkbox).closest("form"), index);
70085    var add_index = data.find(function(input){return input.name == "evaluations["+index+"][evaluation][_remove_reviewer_ids][]" && input.value == "user_id"});
70086    if (add_index) data.splice(add_index, 1);
70087    data.push({name: "evaluations["+index+"][evaluation][_add_reviewer_ids][]", value: user_id})
70088    datas = datas.concat(data);
70089    show_evaluation_loading(checkbox);
70090  })
70091
70092  $.ajax({url: $(".assignees-header ").data("batch-url"), type: "PATCH", data: $.param(datas)});
70093})
70094
70095$(document).off("click", ".batch-filter-menu .select-reviewer .all-selected, .batch-filter-menu .select-reviewer .some-selected").on("click", ".batch-filter-menu .select-reviewer .all-selected, .batch-filter-menu .select-reviewer .some-selected", function(){
70096  var user_id = $(this).data("user-id");
70097  var datas = [];
70098  $(".evaluation input.batch:checked").each(function(index, checkbox){
70099    var data = get_data_from($(checkbox).closest("form"), index);
70100    var add_index = data.find(function(input){return input.name == "evaluations["+index+"][evaluation][_add_reviewer_ids][]" && input.value == "user_id"});
70101    if (add_index) data.splice(add_index, 1);
70102    data.push({name: "evaluations["+index+"][evaluation][_remove_reviewer_ids][]", value: user_id})
70103    datas = datas.concat(data);
70104    show_evaluation_loading(checkbox);
70105  })
70106
70107  $.ajax({url: $(".assignees-header ").data("batch-url"), type: "PATCH", data: $.param(datas)});
70108})
70109
70110$(document).off("click", ".select-filter-menu .select-reviewer .not-selected").on("click", ".select-filter-menu .select-reviewer .not-selected", function(){
70111  var form = $(this).closest("form");
70112  var user_id = $(this).data("user-id");
70113
70114  form.find(".remove-reviewer-input[value="+user_id+"]").remove();
70115  form.append("<input type='hidden' name='evaluation[_add_reviewer_ids][]' value='"+user_id+"' />");
70116  form.trigger("submit.rails");
70117})
70118
70119$(document).off("click", ".select-filter-menu .select-reviewer .all-selected, .batch-filter-menu .select-reviewer .some-selected")
70120  .on("click", ".select-filter-menu .select-reviewer .all-selected, .batch-filter-menu .select-reviewer .some-selected", function(){
70121    var form = $(this).closest("form");
70122    var user_id = $(this).data("user-id");
70123
70124    form.find(".add-reviewer-input[value="+user_id+"]").remove();
70125    form.append("<input type='hidden' name='evaluation[_remove_reviewer_ids][]' value='"+user_id+"' />");
70126    form.trigger("submit.rails");
70127})
70128
70129$(document).off("click", ".select-evaluation-sheet").on("click", ".select-evaluation-sheet", function(){
70130  var evaluation_sheet_id = $(this).data("evaluation-sheet-id");
70131  var datas = [];
70132  $(".evaluation input.batch:checked").each(function(index, checkbox){
70133    var data = get_data_from($(checkbox).closest("form"), index);
70134    data.push({name: "evaluations["+index+"][evaluation][evaluation_sheet_id]", value: evaluation_sheet_id})
70135    datas = datas.concat(data);
70136    show_evaluation_loading(checkbox);
70137  })
70138
70139  $.ajax({url: $(".assignees-header ").data("batch-url"), type: "PATCH", data: $.param(datas)});
70140});
70141
70142function setupAutoSave(buttonId = '#submit-btn') {
70143  if (!window.school_design_keydown_event_setuped) {
70144    window.school_design_keydown_event_setuped = true
70145    document.addEventListener("keydown", function(e) {
70146      if ((window.navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey)  && e.keyCode == 83) {
70147        e.preventDefault();
70148        $(buttonId).trigger("click");
70149      }
70150    }, false);
70151  }
70152};
70153jQuery(function($) {
70154  $(document).ready(function() {
70155    $.fn.select2.amd.require([
70156      "select2/dropdown",
70157      "select2/dropdown/search",
70158      "select2/dropdown/attachBody",
70159      "select2/utils"
70160    ], function (Dropdown, DropdownSearch, AttachBody, Utils) {
70161      var DropdownAdapter = Utils.Decorate(
70162        Utils.Decorate(
70163          Dropdown,
70164          DropdownSearch
70165        ),
70166        AttachBody
70167      )
70168      var base_element = $(".js-fetch-ajax")
70169      var url = base_element.data("url")
70170      if (url) {
70171        $(base_element).select2({
70172          theme: "bootstrap",
70173          hideInput: true,
70174          closeOnSelect: true,
70175          placeholder: "銀行名を選択してください",
70176          dropdownAdapter: DropdownAdapter,
70177          templateResult: function (data) {
70178            if (!data.id) {
70179              return data.text
70180            }
70181            var res = $("<div></div>")
70182            res.text(data.text)
70183            res.addClass("wrap")
70184            res.attr("data-id", data.bank_id)
70185            return res
70186          },
70187          ajax: {
70188            url: url,
70189            dataType: "json",
70190            processResults: function (data) {
70191              return {
70192                results: data
70193              }
70194            }
70195          }
70196        })
70197      } else {
70198        destroy_select2()
70199      }
70200    })
70201  })
70202
70203  function destroy_select2() {
70204    var base_element = $(".js-fetch-ajax")
70205    if (base_element.data("select2")) {
70206      base_element.select2("destroy")
70207    }
70208  }
70209
70210  window.addEventListener("beforeunload", function() {
70211    destroy_select2()
70212  })
70213
70214  $(document).ready(function() {
70215    destroy_select2()
70216  })
70217
70218  function load_branches() {
70219    $.fn.select2.amd.require([
70220      "select2/dropdown",
70221      "select2/dropdown/search",
70222      "select2/dropdown/attachBody",
70223      "select2/utils"
70224    ], function (Dropdown, DropdownSearch, AttachBody, Utils) {
70225      var DropdownAdapter = Utils.Decorate(
70226        Utils.Decorate(
70227          Dropdown,
70228          DropdownSearch
70229        ),
70230        AttachBody
70231      )
70232      var bank_elm = $(".js-bank-fetch-ajax option:selected")
70233      var bank_id = bank_elm.data("data") && bank_elm.data("data").bank_id || bank_elm.data("bank_id")
70234      var base_element = $(".js-bank-branch-fetch-ajax")
70235
70236      if (bank_id) {
70237        var url = "/admin/banks/" + bank_id + "/branches"
70238        $(base_element).select2({
70239          theme: "bootstrap",
70240          hideInput: true,
70241          closeOnSelect: true,
70242          placeholder: "支店を選択してください",
70243          dropdownAdapter: DropdownAdapter,
70244          templateResult: function (data) {
70245            if (!data.id) {
70246              return data.text
70247            }
70248            var $res = $("<div></div>")
70249            $res.text(data.text)
70250            $res.addClass("wrap")
70251            $res.attr("data-id", data.bank_id)
70252            return $res
70253          },
70254          ajax: {
70255            url: url,
70256            dataType: "json",
70257            processResults: function (data) {
70258              return {
70259                results: data
70260              }
70261            }
70262          }
70263        })
70264        !bank_elm.data("bank_id") && base_element.val(null).trigger("change")
70265      } else {
70266        if (base_element.data("select2")) {
70267          base_element.select2("destroy")
70268        }
70269      }
70270    })
70271  }
70272
70273  $(document).on("change", ".js-bank-fetch-ajax", function() {
70274    var bank_elm = $(".js-bank-fetch-ajax option:selected")
70275    bank_elm.data("bank_id")
70276    destroy_select2()
70277    load_branches()
70278  })
70279
70280  load_branches()
70281});
70282$(document).off("change", ".switch-input.published-btn").on("change", ".published-btn.switch-input", function(){
70283  if($(this).is(':checked')){
70284    $(this).closest(".publish-area").find(".datetime-selector").prop('disabled', false);
70285  }
70286  else{
70287    $(this).closest(".publish-area").find(".datetime-selector").prop('disabled', true);
70288  }
70289});
70290(function() {
70291  $(document).ready(function() {
70292    var user_duration_evaluation_option;
70293    user_duration_evaluation_option = {
70294      autoUpdateInput: false,
70295      opens: "right",
70296      locale: {
70297        format: "YYYY/MM/DD",
70298        cancelLabel: "クリア",
70299        applyLabel: "決定",
70300        "daysOfWeek": ["日", "月", "火", "水", "木", "金", "土"],
70301        "monthNames": ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"]
70302      }
70303    };
70304    $(".duration-selector").daterangepicker(user_duration_evaluation_option);
70305    $('.duration-selector').on('apply.daterangepicker', function(ev, picker) {
70306      return $(this).val(picker.startDate.format('YYYY/MM/DD') + ' - ' + picker.endDate.format('YYYY/MM/DD'));
70307    });
70308    return $('.duration-selector').on('cancel.daterangepicker', function(ev, picker) {
70309      return $(this).val('');
70310    });
70311  });
70312
70313}).call(this);
70314function format_number(value) {
70315  return Number(Math.round(value * 10)/10).toFixed(1);
70316}
70317function get_average_points() {
70318  $(".average-point").each(function() {
70319    var total_point = $(this).closest("tr").find(".point").toArray().reduce(function(sum, point) {
70320      return sum + parseFloat($(point).text());
70321    }, 0.0);
70322    $(this).closest("tr").find(".average-point").text(total_point > 0 ? format_number(total_point/$(this).closest("tr").find(".point").length) : format_number(0.0));
70323  });
70324}
70325function highlight_points() {
70326  $(".highlight-points").each(function() {
70327    var current_index = $(this).index() + 1;
70328    var current_point = $(this).find(".point").text();
70329    if (!current_point) return;
70330    current_point = parseFloat(current_point);
70331    var average_point = parseFloat($(this).closest("table").find("tr.average-points td:nth-child("+current_index+") span").text());
70332    var done_point = parseFloat($(this).closest("table").find("tr.done-points td:nth-child("+current_index+") span").text());
70333    if(average_point == NaN && done_point == NaN) return;
70334    if (current_point > done_point) {
70335      $(this).removeClass("bad-result").addClass("good-result");
70336    } else if(current_point < average_point) {
70337      $(this).removeClass("good-result").addClass("bad-result");
70338    } else {
70339      $(this).removeClass("good-result").removeClass("bad-result");
70340    }
70341  });
70342}
70343
70344$(document).ready(highlight_points);
70345
70346function goBack() {
70347  window.history.back();
70348};
70349
70350$(document).ready(function() {
70351  var progressBarInterval;
70352  progressBar = $("#progress-bar")
70353  if(progressBar.length > 0){
70354    url = $(progressBar).data("url")
70355    progressBarInterval = setInterval(function() {
70356      $.ajax(url)
70357        .done(function(data) {
70358          if(data.status == "working"){
70359            $("#progress-bar").css("width", data.percent+"%")
70360          }
70361          else{
70362            clearInterval(progressBarInterval)
70363            location.reload()
70364          }
70365        })
70366    }, 3000);
70367  }
70368})
70369
70370$(document).on("click", ".import-question-link", function(event){
70371  event.preventDefault();
70372  $("#uploadQuestion").trigger("click")
70373})
70374
70375$(document).on("click", ".hide-reexams-link", function(event){
70376  event.preventDefault();
70377  var examId = $(this).closest("tr").data("exam-id");
70378  $(this).closest("tbody").find("tr[data-root-exam-id='" + examId + "']").remove()
70379  $("tr[data-exam-id='" + examId + "'] .hide-reexams-link").hide();
70380  $("tr[data-exam-id='" + examId + "'] .sub-exam").show();
70381})
70382
70383$(document).ready(function() {
70384  escapeHtml = (input) => {
70385    return String(input).replace(/\[/g, "\\[")
70386                        .replace(/\]/g, "\\]")
70387                        .replace(/\(/g, "\\(")
70388                        .replace(/\)/g, "\\)")
70389                        .replace(/\./g, "\\.")
70390                        .replace(/\*/g, "\\*")
70391                        .replace(/\$/g, "\\$")
70392                        .replace(/\#/g, "\\#")
70393                        .replace(/\%/g, "\\%")
70394                        .replace(/\|/g, "\\|")
70395                        .replace(/\//g, "\\/")
70396                        .replace(/\+/g, "\\+")
70397                        .replace(/\{/g, "\\{")
70398                        .replace(/\}/g, "\\}")
70399                        .replace(/\?/g, "\\?")
70400                        .replace(/\`/g, "\\`")
70401                        .replace(/&/g, "\\&")
70402                        .replace(/\^/g, "\\^")
70403                        .replace(/</g, "\\<")
70404                        .replace(/>/g, "\\>")
70405                        .replace(/"/g, "\\\"")
70406                        .replace(/\!/g, "\\!")
70407                        .replace(/'/g, "\\'");
70408  }
70409
70410  removeAnswerItem = (elm) => {
70411    $(elm).closest("tr").remove()
70412  }
70413  changeStatus = (elm) => {
70414    current_value = Math.max(parseInt($(elm).val()) || 0, 0)
70415    $(elm).val(current_value)
70416    label_question = $(elm).closest(".ai-detail").find(".label-question")
70417    if(current_value > 0){
70418      label_question.find("input").val("true")
70419      $(elm).data("correct", "true")
70420      label_question.addClass("show-correct").removeClass("show-wrong")
70421    }
70422    else{
70423      label_question.find("input").val("false")
70424      $(elm).data("correct", "false")
70425      label_question.addClass("show-wrong").removeClass("show-correct")
70426    }
70427  }
70428  $(document).off("click", "form .add_fields").on('click', 'form .add_fields', function(event) {
70429    var regexp, time;
70430    time = new Date().getTime();
70431    regexp = new RegExp($(this).data('id'), 'g');
70432    $(".btn-group-action").before($(this).data('fields').replace(regexp, time));
70433    $(".btn-group-action").prev().find(".action-btn").html("<a class='btn btn-danger edit-question-btn' onclick='removeAnswerItem(this)'>削除</a>")
70434    return event.preventDefault();
70435  });
70436
70437  $(document).off("submit", ".submit.select-format").one('submit', '.submit.select-format', function(event){
70438    event.preventDefault()
70439    target = $(this)
70440    q_body = $(this).find("input#q_body").val()
70441    $(".ai-detail").toArray().forEach((elm) =>
70442      {
70443        old_value = $(elm).data("format").replace("value", escapeHtml($(elm).data("body").replace(/\\/g, "\\\\")))
70444        allotment_input = $(elm).find(".allotment").val()
70445        body = $(elm).find(".body").val()
70446        new_value = `\$_after${allotment_input == "0" ? "" : allotment_input} [ ${body} ]`
70447        if(target.find("#q_body").val().match(new RegExp(old_value, "i")))
70448          new_value = target.find("#q_body").val().replace(new RegExp(old_value, "i"), new_value)
70449        else{
70450          last_match = escapeHtml(target.find("#q_body").val().match(new RegExp(/\$_after.*/, "g")).pop())
70451          if(last_match.last != "\n")
70452            new_value = "\n"+new_value
70453          new_value = target.find("#q_body").val().replace(new RegExp(`(${last_match})`), `$1${new_value}\n`)
70454        }
70455        target.find("#q_body").val(new_value)
70456      }
70457    )
70458    new_value = target.find("#q_body").val().replace(/\$_after/g , "$")
70459    target.find("#q_body").val(new_value)
70460    target.find("#q_html_body").val(questionParser(new_value, "select", false))
70461    target.submit()
70462  })
70463
70464  $(document).off("submit", ".submit.multi_checkbox-format").one('submit', '.submit.multi_checkbox-format', function(event){
70465    event.preventDefault()
70466    target = $(this)
70467    q_body = $(this).find("input#q_body").val()
70468    $(".ai-detail").toArray().forEach((elm) =>
70469      {
70470        old_value = $(elm).data("format").replace("value",  escapeHtml($(elm).data("body").replace(/\\/g, "\\\\")))
70471        allotment_input = $(elm).find(".correct:checked").length > 0 ? "*" : ""
70472        body = $(elm).find(".body").val()
70473        new_value = `\$_after${allotment_input} [ ] ${body}`
70474        if(target.find("#q_body").val().match(new RegExp(old_value, "i")))
70475          new_value = target.find("#q_body").val().replace(new RegExp(old_value, "i"), new_value)
70476        else{
70477          new_value = target.find("#q_body").val().replace(/(\$\*\d+)/, `${new_value}\n$1`)
70478        }
70479        target.find("#q_body").val(new_value)
70480      }
70481    )
70482    new_value = target.find("#q_body").val().replace(/\$_after/g , "$")
70483    target.find("#q_body").val(new_value)
70484    target.find("#q_html_body").val(questionParser(new_value, "checkbox", false))
70485    target.submit()
70486  })
70487
70488  $(document).off("submit", ".submit.checkbox-format").one('submit', '.submit.checkbox-format', function(event){
70489    event.preventDefault()
70490    target = $(this)
70491    q_body = $(this).find("input#q_body").val()
70492    $(".ai-detail").toArray().forEach((elm) =>
70493      {
70494        old_value = $(elm).data("format").replace("value", escapeHtml($(elm).data("body").replace(/\\/g, "\\\\")))
70495        allotment_input = $(elm).find(".allotment").val()
70496        body = $(elm).find(".body").val()
70497        new_value = `\$_after${allotment_input} [ ] ${body}`
70498        if(target.find("#q_body").val().match(new RegExp(old_value, "i")))
70499          new_value = target.find("#q_body").val().replace(new RegExp(old_value, "i"), new_value)
70500        else{
70501          last_match = escapeHtml(target.find("#q_body").val().match(new RegExp(/\$_after.*/, "g")).pop())
70502          if(last_match.last != "\n")
70503            new_value = "\n"+new_value
70504          new_value = target.find("#q_body").val().replace(new RegExp(`(${last_match})`), `$1${new_value}\n`)
70505        }
70506        target.find("#q_body").val(new_value)
70507      }
70508    )
70509    new_value = target.find("#q_body").val().replace(/\$_after/g , "$")
70510    target.find("#q_body").val(new_value)
70511    target.find("#q_html_body").val(questionParser(new_value, "checkbox", false))
70512    target.submit()
70513  })
70514
70515  $(document).off("submit", ".submit.radio-format").one('submit', '.submit.radio-format', function(event){
70516    event.preventDefault()
70517    target = $(this)
70518    q_body = $(this).find("input#q_body").val()
70519    $(".ai-detail").toArray().forEach((elm) =>
70520      {
70521        old_value = $(elm).data("format").replace("value",  escapeHtml($(elm).data("body").replace(/\\/g, "\\\\")))
70522        allotment_input = $(elm).find(".allotment").val()
70523        body = $(elm).find(".body").val()
70524        new_value = `\$_after${allotment_input} ( ) ${body}`
70525        if(target.find("#q_body").val().match(new RegExp(old_value, "i")))
70526          new_value = target.find("#q_body").val().replace(new RegExp(old_value, "i"), new_value)
70527        else{
70528          last_match = escapeHtml(target.find("#q_body").val().match(new RegExp(/\$_after.*/, "g")).pop())
70529          if(last_match.last != "\n")
70530            new_value = "\n"+new_value
70531          new_value = target.find("#q_body").val().replace(new RegExp(`(${last_match})`), `$1${new_value}\n`.trim())
70532        }
70533        target.find("#q_body").val(new_value)
70534      }
70535    )
70536    new_value = target.find("#q_body").val().replace(/\$_after/g , "$")
70537    target.find("#q_body").val(new_value)
70538    target.find("#q_html_body").val(questionParser(new_value, "radio", false))
70539    target.submit()
70540  })
70541
70542  $(document).off('submit', '.submit.textfield-format').one('submit', '.submit.textfield-format', function(event){
70543    event.preventDefault()
70544    target = $(this)
70545    q_body = $(this).find("input#q_body").val()
70546    $(".ai-detail").toArray().forEach((elm) =>
70547      {
70548        old_value = $(elm).data("format").replace("value",  escapeHtml($(elm).data("body").replace(/\\/g, "\\\\")))
70549        allotment_input = $(elm).find(".allotment").val()
70550        body = $(elm).find(".body").val()
70551        new_value = `\$_after\(${body} \| ${allotment_input} \) _________ `
70552        if(target.find("#q_body").val().match(new RegExp(old_value, "i")))
70553          new_value = target.find("#q_body").val().replace(new RegExp(old_value, "i"), new_value)
70554        else{
70555          last_match = escapeHtml(target.find("#q_body").val().match(new RegExp(/\$_after.*_+/, "g")).pop())
70556          if(last_match.last != "\n")
70557            new_value = "\n"+new_value
70558          new_value = target.find("#q_body").val().replace(new RegExp(`(${last_match})`), `$1${new_value}\n`.trim())
70559        }
70560        target.find("#q_body").val(new_value)
70561      }
70562    )
70563    new_value = target.find("#q_body").val().replace(/\$_after/g , "$")
70564    target.find("#q_body").val(new_value)
70565    target.find("#q_html_body").val(questionParser(new_value, "textfield", false))
70566    target.submit()
70567  })
70568});
70569function setChangeFromEvent(form_id) {
70570  $(document).on("change", form_id, function() {
70571    $(form_id).data("changed",true);
70572  });
70573}
70574
70575function resetFromEvent(form_id) {
70576  $(form_id).data("changed",false);
70577}
70578
70579function checkChangeFromEvent(form_id, message = "変更が保存されていません。本当に移動しますか") {
70580  if ($(form_id).data("changed")) {
70581    return confirm(message);
70582  }
70583  return true;
70584};
70585(function() {
70586  var update_boolean_field, update_field;
70587
70588  update_field = function(input) {
70589    var target;
70590    target = $(input.form).find("input[type='number'][name='" + $(input).prop("name") + "']");
70591    if ($(input).is(":checked")) {
70592      return target.prop("disabled", true);
70593    } else {
70594      return target.prop("disabled", false).val(parseInt(target.val()) < 0 ? 0 : target.val());
70595    }
70596  };
70597
70598  update_boolean_field = function(input) {
70599    var target;
70600    target = $(input.form).find("input[type='text'][name='" + $(input).prop("name") + "']");
70601    return target.val($(input).is(":checked") ? "利用可能" : "利用不可能");
70602  };
70603
70604  $(document).ready(function() {
70605    $(".number-limit").each(function(index, input) {
70606      return update_field(input);
70607    });
70608    return $(".boolean-limit").each(function(index, input) {
70609      return update_boolean_field(input);
70610    });
70611  });
70612
70613  $(document).on("change", ".number-limit", function(event) {
70614    return update_field(event.target);
70615  });
70616
70617  $(document).on("change", ".boolean-limit", function(event) {
70618    return update_boolean_field(event.target);
70619  });
70620
70621}).call(this);
70622$(document).off("change", ".freezerank-all").on("change", ".freezerank-all", function(){
70623    $(this).closest("table").find("input.freezerank").prop("checked", $(this).prop("checked"))
70624  });
vendor: 56,160 bytes, lines 70625-71239
70625/**
70626 * jquery-resizable-columns - Resizable table columns for jQuery
70627 * @date Sat May 16 2015 19:03:57 GMT+0100 (BST)
70628 * @version v0.1.0
70629 * @link http://dobtco.github.io/jquery-resizable-columns/
70630 * @license MIT
70631 */
70632(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
70633'use strict';
70634
70635function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
70636
70637var _class = require('./class');
70638
70639var _class2 = _interopRequireDefault(_class);
70640
70641var _constants = require('./constants');
70642
70643$.fn.resizableColumns = function (optionsOrMethod) {
70644	for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
70645		args[_key - 1] = arguments[_key];
70646	}
70647
70648	return this.each(function () {
70649		var $table = $(this);
70650
70651		var api = $table.data(_constants.DATA_API);
70652		if (!api) {
70653			api = new _class2['default']($table, optionsOrMethod);
70654			$table.data(_constants.DATA_API, api);
70655		} else if (typeof optionsOrMethod === 'string') {
70656			return api[optionsOrMethod].apply(api, args);
70657		}
70658	});
70659};
70660
70661$.resizableColumns = _class2['default'];
70662
70663},{"./class":2,"./constants":3}],2:[function(require,module,exports){
70664'use strict';
70665
70666Object.defineProperty(exports, '__esModule', {
70667	value: true
70668});
70669
70670var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
70671
70672function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
70673
70674var _constants = require('./constants');
70675
70676/**
70677Takes a <table /> element and makes it's columns resizable across both
70678mobile and desktop clients.
70679
70680@class ResizableColumns
70681@param $table {jQuery} jQuery-wrapped <table> element to make resizable
70682@param options {Object} Configuration object
70683**/
70684
70685var ResizableColumns = (function () {
70686	function ResizableColumns($table, options) {
70687		_classCallCheck(this, ResizableColumns);
70688
70689		this.ns = '.rc' + this.count++;
70690
70691		this.options = $.extend({}, ResizableColumns.defaults, options);
70692
70693		this.$window = $(window);
70694		this.$ownerDocument = $($table[0].ownerDocument);
70695		this.$table = $table;
70696
70697		this.refreshHeaders();
70698		this.restoreColumnWidths();
70699		this.syncHandleWidths();
70700
70701		this.bindEvents(this.$window, 'resize', this.syncHandleWidths.bind(this));
70702
70703		if (this.options.start) {
70704			this.bindEvents(this.$table, _constants.EVENT_RESIZE_START, this.options.start);
70705		}
70706		if (this.options.resize) {
70707			this.bindEvents(this.$table, _constants.EVENT_RESIZE, this.options.resize);
70708		}
70709		if (this.options.stop) {
70710			this.bindEvents(this.$table, _constants.EVENT_RESIZE_STOP, this.options.stop);
70711		}
70712	}
70713
70714	_createClass(ResizableColumns, [{
70715		key: 'refreshHeaders',
70716
70717		/**
70718  Refreshes the headers associated with this instances <table/> element and
70719  generates handles for them. Also assigns percentage widths.
70720  	@method refreshHeaders
70721  **/
70722		value: function refreshHeaders() {
70723			// Allow the selector to be both a regular selctor string as well as
70724			// a dynamic callback
70725			var selector = this.options.selector;
70726			if (typeof selector === 'function') {
70727				selector = selector.call(this, this.$table);
70728			}
70729
70730			// Select all table headers
70731			this.$tableHeaders = this.$table.find(selector);
70732
70733			// Assign percentage widths first, then create drag handles
70734			this.assignPercentageWidths();
70735			this.createHandles();
70736		}
70737	}, {
70738		key: 'createHandles',
70739
70740		/**
70741  Creates dummy handle elements for all table header columns
70742  	@method createHandles
70743  **/
70744		value: function createHandles() {
70745			var _this = this;
70746
70747			var ref = this.$handleContainer;
70748			if (ref != null) {
70749				ref.remove();
70750			}
70751
70752			this.$handleContainer = $('<div class=\'' + _constants.CLASS_HANDLE_CONTAINER + '\' />');
70753			this.$table.before(this.$handleContainer);
70754
70755			this.$tableHeaders.each(function (i, el) {
70756				var $current = _this.$tableHeaders.eq(i);
70757				var $next = _this.$tableHeaders.eq(i + 1);
70758
70759				if ($next.length === 0 || $current.is(_constants.SELECTOR_UNRESIZABLE) || $next.is(_constants.SELECTOR_UNRESIZABLE)) {
70760					return;
70761				}
70762
70763				var $handle = $('<div class=\'' + _constants.CLASS_HANDLE + '\' />').data(_constants.DATA_TH, $(el)).appendTo(_this.$handleContainer);
70764			});
70765
70766			this.bindEvents(this.$handleContainer, ['mousedown', 'touchstart'], '.' + _constants.CLASS_HANDLE, this.onPointerDown.bind(this));
70767		}
70768	}, {
70769		key: 'assignPercentageWidths',
70770
70771		/**
70772  Assigns a percentage width to all columns based on their current pixel width(s)
70773  	@method assignPercentageWidths
70774  **/
70775		value: function assignPercentageWidths() {
70776			var _this2 = this;
70777
70778			this.$tableHeaders.each(function (_, el) {
70779				var $el = $(el);
70780				_this2.setWidth($el[0], $el.outerWidth() / _this2.$table.width() * 100);
70781			});
70782		}
70783	}, {
70784		key: 'syncHandleWidths',
70785
70786		/**
70787  
70788  @method syncHandleWidths
70789  **/
70790		value: function syncHandleWidths() {
70791			var _this3 = this;
70792
70793			var $container = this.$handleContainer;
70794
70795			$container.width(this.$table.width());
70796
70797			$container.find('.' + _constants.CLASS_HANDLE).each(function (_, el) {
70798				var $el = $(el);
70799
70800				var height = _this3.options.resizeFromBody ? _this3.$table.height() : _this3.$table.find('thead').height();
70801
70802				var left = $el.data(_constants.DATA_TH).outerWidth() + ($el.data(_constants.DATA_TH).offset().left - _this3.$handleContainer.offset().left);
70803
70804				$el.css({ left: left, height: height });
70805			});
70806		}
70807	}, {
70808		key: 'saveColumnWidths',
70809
70810		/**
70811  Persists the column widths in localStorage
70812  	@method saveColumnWidths
70813  **/
70814		value: function saveColumnWidths() {
70815			var _this4 = this;
70816
70817			this.$tableHeaders.each(function (_, el) {
70818				var $el = $(el);
70819
70820				if (_this4.options.store && !$el.is(_constants.SELECTOR_UNRESIZABLE)) {
70821					_this4.options.store.set(_this4.generateColumnId($el), _this4.parseWidth(el));
70822				}
70823			});
70824		}
70825	}, {
70826		key: 'restoreColumnWidths',
70827
70828		/**
70829  Retrieves and sets the column widths from localStorage
70830  	@method restoreColumnWidths
70831  **/
70832		value: function restoreColumnWidths() {
70833			var _this5 = this;
70834
70835			this.$tableHeaders.each(function (_, el) {
70836				var $el = $(el);
70837
70838				if (_this5.options.store && !$el.is(_constants.SELECTOR_UNRESIZABLE)) {
70839					var width = _this5.options.store.get(_this5.generateColumnId($el));
70840
70841					if (width != null) {
70842						_this5.setWidth(el, width);
70843					}
70844				}
70845			});
70846		}
70847	}, {
70848		key: 'onPointerDown',
70849
70850		/**
70851  Pointer/mouse down handler
70852  	@method onPointerDown
70853  @param event {Object} Event object associated with the interaction
70854  **/
70855		value: function onPointerDown(event) {
70856			// Only applies to left-click dragging
70857			if (event.which !== 1) {
70858				return;
70859			}
70860
70861			// If a previous operation is defined, we missed the last mouseup.
70862			// Probably gobbled up by user mousing out the window then releasing.
70863			// We'll simulate a pointerup here prior to it
70864			if (this.operation) {
70865				this.onPointerUp(event);
70866			}
70867
70868			// Ignore non-resizable columns
70869			var $currentGrip = $(event.currentTarget);
70870			if ($currentGrip.is(_constants.SELECTOR_UNRESIZABLE)) {
70871				return;
70872			}
70873
70874			var gripIndex = $currentGrip.index();
70875			var $leftColumn = this.$tableHeaders.eq(gripIndex).not(_constants.SELECTOR_UNRESIZABLE);
70876			var $rightColumn = this.$tableHeaders.eq(gripIndex + 1).not(_constants.SELECTOR_UNRESIZABLE);
70877
70878			var leftWidth = this.parseWidth($leftColumn[0]);
70879			var rightWidth = this.parseWidth($rightColumn[0]);
70880
70881			this.operation = {
70882				$leftColumn: $leftColumn, $rightColumn: $rightColumn, $currentGrip: $currentGrip,
70883
70884				startX: this.getPointerX(event),
70885
70886				widths: {
70887					left: leftWidth,
70888					right: rightWidth
70889				},
70890				newWidths: {
70891					left: leftWidth,
70892					right: rightWidth
70893				}
70894			};
70895
70896			this.bindEvents(this.$ownerDocument, ['mousemove', 'touchmove'], this.onPointerMove.bind(this));
70897			this.bindEvents(this.$ownerDocument, ['mouseup', 'touchend'], this.onPointerUp.bind(this));
70898
70899			this.$handleContainer.add(this.$table).addClass(_constants.CLASS_TABLE_RESIZING);
70900
70901			$leftColumn.add($rightColumn).add($currentGrip).addClass(_constants.CLASS_COLUMN_RESIZING);
70902
70903			this.triggerEvent(_constants.EVENT_RESIZE_START, [$leftColumn, $rightColumn, leftWidth, rightWidth], event);
70904
70905			event.preventDefault();
70906		}
70907	}, {
70908		key: 'onPointerMove',
70909
70910		/**
70911  Pointer/mouse movement handler
70912  	@method onPointerMove
70913  @param event {Object} Event object associated with the interaction
70914  **/
70915		value: function onPointerMove(event) {
70916			var op = this.operation;
70917			if (!this.operation) {
70918				return;
70919			}
70920
70921			// Determine the delta change between start and new mouse position, as a percentage of the table width
70922			var difference = (this.getPointerX(event) - op.startX) / this.$table.width() * 100;
70923			if (difference === 0) {
70924				return;
70925			}
70926
70927			var leftColumn = op.$leftColumn[0];
70928			var rightColumn = op.$rightColumn[0];
70929			var widthLeft = undefined,
70930			    widthRight = undefined;
70931
70932			if (difference > 0) {
70933				widthLeft = this.constrainWidth(op.widths.left + (op.widths.right - op.newWidths.right));
70934				widthRight = this.constrainWidth(op.widths.right - difference);
70935			} else if (difference < 0) {
70936				widthLeft = this.constrainWidth(op.widths.left + difference);
70937				widthRight = this.constrainWidth(op.widths.right + (op.widths.left - op.newWidths.left));
70938			}
70939
70940			if (leftColumn) {
70941				this.setWidth(leftColumn, widthLeft);
70942			}
70943			if (rightColumn) {
70944				this.setWidth(rightColumn, widthRight);
70945			}
70946
70947			op.newWidths.left = widthLeft;
70948			op.newWidths.right = widthRight;
70949
70950			return this.triggerEvent(_constants.EVENT_RESIZE, [op.$leftColumn, op.$rightColumn, widthLeft, widthRight], event);
70951		}
70952	}, {
70953		key: 'onPointerUp',
70954
70955		/**
70956  Pointer/mouse release handler
70957  	@method onPointerUp
70958  @param event {Object} Event object associated with the interaction
70959  **/
70960		value: function onPointerUp(event) {
70961			var op = this.operation;
70962			if (!this.operation) {
70963				return;
70964			}
70965
70966			this.unbindEvents(this.$ownerDocument, ['mouseup', 'touchend', 'mousemove', 'touchmove']);
70967
70968			this.$handleContainer.add(this.$table).removeClass(_constants.CLASS_TABLE_RESIZING);
70969
70970			op.$leftColumn.add(op.$rightColumn).add(op.$currentGrip).removeClass(_constants.CLASS_COLUMN_RESIZING);
70971
70972			this.syncHandleWidths();
70973			this.saveColumnWidths();
70974
70975			this.operation = null;
70976
70977			return this.triggerEvent(_constants.EVENT_RESIZE_STOP, [op.$leftColumn, op.$rightColumn, op.newWidths.left, op.newWidths.right], event);
70978		}
70979	}, {
70980		key: 'destroy',
70981
70982		/**
70983  Removes all event listeners, data, and added DOM elements. Takes
70984  the <table/> element back to how it was, and returns it
70985  	@method destroy
70986  @return {jQuery} Original jQuery-wrapped <table> element
70987  **/
70988		value: function destroy() {
70989			var $table = this.$table;
70990			var $handles = this.$handleContainer.find('.' + _constants.CLASS_HANDLE);
70991
70992			this.unbindEvents(this.$window.add(this.$ownerDocument).add(this.$table).add($handles));
70993
70994			$handles.removeData(_constants.DATA_TH);
70995			$table.removeData(_constants.DATA_API);
70996
70997			this.$handleContainer.remove();
70998			this.$handleContainer = null;
70999			this.$tableHeaders = null;
71000			this.$table = null;
71001
71002			return $table;
71003		}
71004	}, {
71005		key: 'bindEvents',
71006
71007		/**
71008  Binds given events for this instance to the given target DOMElement
71009  	@private
71010  @method bindEvents
71011  @param target {jQuery} jQuery-wrapped DOMElement to bind events to
71012  @param events {String|Array} Event name (or array of) to bind
71013  @param selectorOrCallback {String|Function} Selector string or callback
71014  @param [callback] {Function} Callback method
71015  **/
71016		value: function bindEvents($target, events, selectorOrCallback, callback) {
71017			if (typeof events === 'string') {
71018				events = events + this.ns;
71019			} else {
71020				events = events.join(this.ns + ' ') + this.ns;
71021			}
71022
71023			if (arguments.length > 3) {
71024				$target.on(events, selectorOrCallback, callback);
71025			} else {
71026				$target.on(events, selectorOrCallback);
71027			}
71028		}
71029	}, {
71030		key: 'unbindEvents',
71031
71032		/**
71033  Unbinds events specific to this instance from the given target DOMElement
71034  	@private
71035  @method unbindEvents
71036  @param target {jQuery} jQuery-wrapped DOMElement to unbind events from
71037  @param events {String|Array} Event name (or array of) to unbind
71038  **/
71039		value: function unbindEvents($target, events) {
71040			if (typeof events === 'string') {
71041				events = events + this.ns;
71042			} else if (events != null) {
71043				events = events.join(this.ns + ' ') + this.ns;
71044			} else {
71045				events = this.ns;
71046			}
71047
71048			$target.off(events);
71049		}
71050	}, {
71051		key: 'triggerEvent',
71052
71053		/**
71054  Triggers an event on the <table/> element for a given type with given
71055  arguments, also setting and allowing access to the originalEvent if
71056  given. Returns the result of the triggered event.
71057  	@private
71058  @method triggerEvent
71059  @param type {String} Event name
71060  @param args {Array} Array of arguments to pass through
71061  @param [originalEvent] If given, is set on the event object
71062  @return {Mixed} Result of the event trigger action
71063  **/
71064		value: function triggerEvent(type, args, originalEvent) {
71065			var event = $.Event(type);
71066			if (event.originalEvent) {
71067				event.originalEvent = $.extend({}, originalEvent);
71068			}
71069
71070			return this.$table.trigger(event, [this].concat(args || []));
71071		}
71072	}, {
71073		key: 'generateColumnId',
71074
71075		/**
71076  Calculates a unique column ID for a given column DOMElement
71077  	@private
71078  @method generateColumnId
71079  @param $el {jQuery} jQuery-wrapped column element
71080  @return {String} Column ID
71081  **/
71082		value: function generateColumnId($el) {
71083			return this.$table.data(_constants.DATA_COLUMNS_ID) + '-' + $el.data(_constants.DATA_COLUMN_ID);
71084		}
71085	}, {
71086		key: 'parseWidth',
71087
71088		/**
71089  Parses a given DOMElement's width into a float
71090  	@private
71091  @method parseWidth
71092  @param element {DOMElement} Element to get width of
71093  @return {Number} Element's width as a float
71094  **/
71095		value: function parseWidth(element) {
71096			return element ? parseFloat(element.style.width.replace('%', '')) : 0;
71097		}
71098	}, {
71099		key: 'setWidth',
71100
71101		/**
71102  Sets the percentage width of a given DOMElement
71103  	@private
71104  @method setWidth
71105  @param element {DOMElement} Element to set width on
71106  @param width {Number} Width, as a percentage, to set
71107  **/
71108		value: function setWidth(element, width) {
71109			width = width.toFixed(2);
71110			width = width > 0 ? width : 0;
71111			element.style.width = width + '%';
71112		}
71113	}, {
71114		key: 'constrainWidth',
71115
71116		/**
71117  Constrains a given width to the minimum and maximum ranges defined in
71118  the `minWidth` and `maxWidth` configuration options, respectively.
71119  	@private
71120  @method constrainWidth
71121  @param width {Number} Width to constrain
71122  @return {Number} Constrained width
71123  **/
71124		value: function constrainWidth(width) {
71125			if (this.options.minWidth != undefined) {
71126				width = Math.max(this.options.minWidth, width);
71127			}
71128
71129			if (this.options.maxWidth != undefined) {
71130				width = Math.min(this.options.maxWidth, width);
71131			}
71132
71133			return width;
71134		}
71135	}, {
71136		key: 'getPointerX',
71137
71138		/**
71139  Given a particular Event object, retrieves the current pointer offset along
71140  the horizontal direction. Accounts for both regular mouse clicks as well as
71141  pointer-like systems (mobiles, tablets etc.)
71142  	@private
71143  @method getPointerX
71144  @param event {Object} Event object associated with the interaction
71145  @return {Number} Horizontal pointer offset
71146  **/
71147		value: function getPointerX(event) {
71148			if (event.type.indexOf('touch') === 0) {
71149				return (event.originalEvent.touches[0] || event.originalEvent.changedTouches[0]).pageX;
71150			}
71151			return event.pageX;
71152		}
71153	}]);
71154
71155	return ResizableColumns;
71156})();
71157
71158exports['default'] = ResizableColumns;
71159
71160ResizableColumns.defaults = {
71161	selector: function selector($table) {
71162		if ($table.find('thead').length) {
71163			return _constants.SELECTOR_TH;
71164		}
71165
71166		return _constants.SELECTOR_TD;
71167	},
71168	store: window.store,
71169	syncHandlers: true,
71170	resizeFromBody: true,
71171	maxWidth: null,
71172	minWidth: 0.01
71173};
71174
71175ResizableColumns.count = 0;
71176module.exports = exports['default'];
71177
71178},{"./constants":3}],3:[function(require,module,exports){
71179'use strict';
71180
71181Object.defineProperty(exports, '__esModule', {
71182  value: true
71183});
71184var DATA_API = 'resizableColumns';
71185exports.DATA_API = DATA_API;
71186var DATA_COLUMNS_ID = 'resizable-columns-id';
71187exports.DATA_COLUMNS_ID = DATA_COLUMNS_ID;
71188var DATA_COLUMN_ID = 'resizable-column-id';
71189exports.DATA_COLUMN_ID = DATA_COLUMN_ID;
71190var DATA_TH = 'th';
71191
71192exports.DATA_TH = DATA_TH;
71193var CLASS_TABLE_RESIZING = 'rc-table-resizing';
71194exports.CLASS_TABLE_RESIZING = CLASS_TABLE_RESIZING;
71195var CLASS_COLUMN_RESIZING = 'rc-column-resizing';
71196exports.CLASS_COLUMN_RESIZING = CLASS_COLUMN_RESIZING;
71197var CLASS_HANDLE = 'rc-handle';
71198exports.CLASS_HANDLE = CLASS_HANDLE;
71199var CLASS_HANDLE_CONTAINER = 'rc-handle-container';
71200
71201exports.CLASS_HANDLE_CONTAINER = CLASS_HANDLE_CONTAINER;
71202var EVENT_RESIZE_START = 'column:resize:start';
71203exports.EVENT_RESIZE_START = EVENT_RESIZE_START;
71204var EVENT_RESIZE = 'column:resize';
71205exports.EVENT_RESIZE = EVENT_RESIZE;
71206var EVENT_RESIZE_STOP = 'column:resize:stop';
71207
71208exports.EVENT_RESIZE_STOP = EVENT_RESIZE_STOP;
71209var SELECTOR_TH = 'tr:first > th:visible';
71210exports.SELECTOR_TH = SELECTOR_TH;
71211var SELECTOR_TD = 'tr:first > td:visible';
71212exports.SELECTOR_TD = SELECTOR_TD;
71213var SELECTOR_UNRESIZABLE = '[data-noresize]';
71214exports.SELECTOR_UNRESIZABLE = SELECTOR_UNRESIZABLE;
71215
71216},{}],4:[function(require,module,exports){
71217'use strict';
71218
71219Object.defineProperty(exports, '__esModule', {
71220  value: true
71221});
71222
71223function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
71224
71225var _class = require('./class');
71226
71227var _class2 = _interopRequireDefault(_class);
71228
71229var _adapter = require('./adapter');
71230
71231var _adapter2 = _interopRequireDefault(_adapter);
71232
71233exports['default'] = _class2['default'];
71234module.exports = exports['default'];
71235
71236},{"./adapter":1,"./class":2}]},{},[4])
71237
71238
71239//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJzcmMvYWRhcHRlci5qcyIsInNyYy9jbGFzcy5qcyIsInNyYy9jb25zdGFudHMuanMiLCJzcmMvaW5kZXguanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7O3FCQ0E2QixTQUFTOzs7O3lCQUNmLGFBQWE7O0FBRXBDLENBQUMsQ0FBQyxFQUFFLENBQUMsZ0JBQWdCLEdBQUcsVUFBUyxlQUFlLEVBQVc7bUNBQU4sSUFBSTtBQUFKLE1BQUk7OztBQUN4RCxRQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBVztBQUMzQixNQUFJLE1BQU0sR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7O0FBRXJCLE1BQUksR0FBRyxHQUFHLE1BQU0sQ0FBQyxJQUFJLFlBTmYsUUFBUSxDQU1pQixDQUFDO0FBQ2hDLE1BQUksQ0FBQyxHQUFHLEVBQUU7QUFDVCxNQUFHLEdBQUcsdUJBQXFCLE1BQU0sRUFBRSxlQUFlLENBQUMsQ0FBQztBQUNwRCxTQUFNLENBQUMsSUFBSSxZQVROLFFBQVEsRUFTUyxHQUFHLENBQUMsQ0FBQztHQUMzQixNQUVJLElBQUksT0FBTyxlQUFlLEtBQUssUUFBUSxFQUFFO0FBQzdDLFVBQU8sR0FBRyxDQUFDLGVBQWUsT0FBQyxDQUFwQixHQUFHLEVBQXFCLElBQUksQ0FBQyxDQUFDO0dBQ3JDO0VBQ0QsQ0FBQyxDQUFDO0NBQ0gsQ0FBQzs7QUFFRixDQUFDLENBQUMsZ0JBQWdCLHFCQUFtQixDQUFDOzs7Ozs7Ozs7Ozs7O3lCQ0hqQyxhQUFhOzs7Ozs7Ozs7OztJQVVHLGdCQUFnQjtBQUN6QixVQURTLGdCQUFnQixDQUN4QixNQUFNLEVBQUUsT0FBTyxFQUFFO3dCQURULGdCQUFnQjs7QUFFbkMsTUFBSSxDQUFDLEVBQUUsR0FBRyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDOztBQUUvQixNQUFJLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLGdCQUFnQixDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsQ0FBQzs7QUFFaEUsTUFBSSxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDekIsTUFBSSxDQUFDLGNBQWMsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxDQUFDO0FBQ2pELE1BQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDOztBQUVyQixNQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7QUFDdEIsTUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7QUFDM0IsTUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7O0FBRXhCLE1BQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDOztBQUUxRSxNQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFO0FBQ3ZCLE9BQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLE1BQU0sYUFsQzdCLGtCQUFrQixFQWtDaUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztHQUNyRTtBQUNELE1BQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUU7QUFDeEIsT0FBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsTUFBTSxhQXBDN0IsWUFBWSxFQW9DaUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztHQUNoRTtBQUNELE1BQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUU7QUFDdEIsT0FBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsTUFBTSxhQXRDN0IsaUJBQWlCLEVBc0NpQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0dBQ25FO0VBQ0Q7O2NBekJtQixnQkFBZ0I7Ozs7Ozs7O1NBaUN0QiwwQkFBRzs7O0FBR2hCLE9BQUksUUFBUSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDO0FBQ3JDLE9BQUcsT0FBTyxRQUFRLEtBQUssVUFBVSxFQUFFO0FBQ2xDLFlBQVEsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDNUM7OztBQUdELE9BQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7OztBQUdoRCxPQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztBQUM5QixPQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7R0FDckI7Ozs7Ozs7O1NBT1kseUJBQUc7OztBQUNmLE9BQUksR0FBRyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztBQUNoQyxPQUFJLEdBQUcsSUFBSSxJQUFJLEVBQUU7QUFDaEIsT0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ2I7O0FBRUQsT0FBSSxDQUFDLGdCQUFnQixHQUFHLENBQUMsOEJBOUUxQixzQkFBc0IsV0E4RWlELENBQUE7QUFDdEUsT0FBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7O0FBRTFDLE9BQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLFVBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBSztBQUNsQyxRQUFJLFFBQVEsR0FBRyxNQUFLLGFBQWEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDeEMsUUFBSSxLQUFLLEdBQUcsTUFBSyxhQUFhLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQzs7QUFFekMsUUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxRQUFRLENBQUMsRUFBRSxZQS9FdkMsb0JBQW9CLENBK0V5QyxJQUFJLEtBQUssQ0FBQyxFQUFFLFlBL0V6RSxvQkFBb0IsQ0ErRTJFLEVBQUU7QUFDOUYsWUFBTztLQUNQOztBQUVELFFBQUksT0FBTyxHQUFHLENBQUMsOEJBMUZqQixZQUFZLFdBMEZ3QyxDQUNoRCxJQUFJLFlBOUZSLE9BQU8sRUE4RlcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQ3BCLFFBQVEsQ0FBQyxNQUFLLGdCQUFnQixDQUFDLENBQUM7SUFDbEMsQ0FBQyxDQUFDOztBQUVILE9BQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUMsV0FBVyxFQUFFLFlBQVksQ0FBQyxFQUFFLEdBQUcsY0EvRnhFLFlBQVksQUErRnlFLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztHQUNySDs7Ozs7Ozs7U0FPcUIsa0NBQUc7OztBQUN4QixPQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxVQUFDLENBQUMsRUFBRSxFQUFFLEVBQUs7QUFDbEMsUUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2hCLFdBQUssUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsVUFBVSxFQUFFLEdBQUcsT0FBSyxNQUFNLENBQUMsS0FBSyxFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUM7SUFDcEUsQ0FBQyxDQUFDO0dBQ0g7Ozs7Ozs7O1NBT2UsNEJBQUc7OztBQUNsQixPQUFJLFVBQVUsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUE7O0FBRXRDLGFBQVUsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDOztBQUV0QyxhQUFVLENBQUMsSUFBSSxDQUFDLEdBQUcsY0F4SHBCLFlBQVksQUF3SHFCLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBQyxDQUFDLEVBQUUsRUFBRSxFQUFLO0FBQ2pELFFBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQzs7QUFFaEIsUUFBSSxNQUFNLEdBQUcsT0FBSyxPQUFPLENBQUMsY0FBYyxHQUN2QyxPQUFLLE1BQU0sQ0FBQyxNQUFNLEVBQUUsR0FDcEIsT0FBSyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDOztBQUVwQyxRQUFJLElBQUksR0FBRyxHQUFHLENBQUMsSUFBSSxZQWxJckIsT0FBTyxDQWtJdUIsQ0FBQyxVQUFVLEVBQUUsSUFDeEMsR0FBRyxDQUFDLElBQUksWUFuSVgsT0FBTyxDQW1JYSxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksR0FBRyxPQUFLLGdCQUFnQixDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksQ0FBQSxBQUNyRSxDQUFDOztBQUVGLE9BQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxJQUFJLEVBQUosSUFBSSxFQUFFLE1BQU0sRUFBTixNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQzFCLENBQUMsQ0FBQztHQUNIOzs7Ozs7OztTQU9lLDRCQUFHOzs7QUFDbEIsT0FBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsVUFBQyxDQUFDLEVBQUUsRUFBRSxFQUFLO0FBQ2xDLFFBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQzs7QUFFaEIsUUFBSSxPQUFLLE9BQU8sQ0FBQyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxZQXpJbkMsb0JBQW9CLENBeUlxQyxFQUFFO0FBQ3hELFlBQUssT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQ3JCLE9BQUssZ0JBQWdCLENBQUMsR0FBRyxDQUFDLEVBQzFCLE9BQUssVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUNuQixDQUFDO0tBQ0Y7SUFDRCxDQUFDLENBQUM7R0FDSDs7Ozs7Ozs7U0FPa0IsK0JBQUc7OztBQUNyQixPQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxVQUFDLENBQUMsRUFBRSxFQUFFLEVBQUs7QUFDbEMsUUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDOztBQUVoQixRQUFHLE9BQUssT0FBTyxDQUFDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLFlBM0psQyxvQkFBb0IsQ0EySm9DLEVBQUU7QUFDdkQsU0FBSSxLQUFLLEdBQUcsT0FBSyxPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FDakMsT0FBSyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsQ0FDMUIsQ0FBQzs7QUFFRixTQUFHLEtBQUssSUFBSSxJQUFJLEVBQUU7QUFDakIsYUFBSyxRQUFRLENBQUMsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO01BQ3pCO0tBQ0Q7SUFDRCxDQUFDLENBQUM7R0FDSDs7Ozs7Ozs7O1NBUVksdUJBQUMsS0FBSyxFQUFFOztBQUVwQixPQUFHLEtBQUssQ0FBQyxLQUFLLEtBQUssQ0FBQyxFQUFFO0FBQUUsV0FBTztJQUFFOzs7OztBQUtqQyxPQUFHLElBQUksQ0FBQyxTQUFTLEVBQUU7QUFDbEIsUUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN4Qjs7O0FBR0QsT0FBSSxZQUFZLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQztBQUMxQyxPQUFHLFlBQVksQ0FBQyxFQUFFLFlBMUxuQixvQkFBb0IsQ0EwTHFCLEVBQUU7QUFDekMsV0FBTztJQUNQOztBQUVELE9BQUksU0FBUyxHQUFHLFlBQVksQ0FBQyxLQUFLLEVBQUUsQ0FBQztBQUNyQyxPQUFJLFdBQVcsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxHQUFHLFlBL0x2RCxvQkFBb0IsQ0ErTHlELENBQUM7QUFDN0UsT0FBSSxZQUFZLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsWUFoTTVELG9CQUFvQixDQWdNOEQsQ0FBQzs7QUFFbEYsT0FBSSxTQUFTLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNoRCxPQUFJLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDOztBQUVsRCxPQUFJLENBQUMsU0FBUyxHQUFHO0FBQ2hCLGVBQVcsRUFBWCxXQUFXLEVBQUUsWUFBWSxFQUFaLFlBQVksRUFBRSxZQUFZLEVBQVosWUFBWTs7QUFFdkMsVUFBTSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDOztBQUUvQixVQUFNLEVBQUU7QUFDUCxTQUFJLEVBQUUsU0FBUztBQUNmLFVBQUssRUFBRSxVQUFVO0tBQ2pCO0FBQ0QsYUFBUyxFQUFFO0FBQ1YsU0FBSSxFQUFFLFNBQVM7QUFDZixVQUFLLEVBQUUsVUFBVTtLQUNqQjtJQUNELENBQUM7O0FBRUYsT0FBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUMsV0FBVyxFQUFFLFdBQVcsQ0FBQyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7QUFDaEcsT0FBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUMsU0FBUyxFQUFFLFVBQVUsQ0FBQyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7O0FBRTNGLE9BQUksQ0FBQyxnQkFBZ0IsQ0FDbkIsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FDaEIsUUFBUSxZQWxPWCxvQkFBb0IsQ0FrT2EsQ0FBQzs7QUFFakMsY0FBVyxDQUNULEdBQUcsQ0FBQyxZQUFZLENBQUMsQ0FDakIsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUNqQixRQUFRLFlBdE9YLHFCQUFxQixDQXNPYSxDQUFDOztBQUVsQyxPQUFJLENBQUMsWUFBWSxZQXJPbEIsa0JBQWtCLEVBcU9xQixDQUNyQyxXQUFXLEVBQUUsWUFBWSxFQUN6QixTQUFTLEVBQUUsVUFBVSxDQUNyQixFQUNELEtBQUssQ0FBQyxDQUFDOztBQUVQLFFBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztHQUN2Qjs7Ozs7Ozs7O1NBUVksdUJBQUMsS0FBSyxFQUFFO0FBQ3BCLE9BQUksRUFBRSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7QUFDeEIsT0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUU7QUFBRSxXQUFPO0lBQUU7OztBQUcvQixPQUFJLFVBQVUsR0FBRyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQSxHQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLEdBQUcsR0FBRyxDQUFDO0FBQ25GLE9BQUcsVUFBVSxLQUFLLENBQUMsRUFBRTtBQUNwQixXQUFPO0lBQ1A7O0FBRUQsT0FBSSxVQUFVLEdBQUcsRUFBRSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNuQyxPQUFJLFdBQVcsR0FBRyxFQUFFLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3JDLE9BQUksU0FBUyxZQUFBO09BQUUsVUFBVSxZQUFBLENBQUM7O0FBRTFCLE9BQUcsVUFBVSxHQUFHLENBQUMsRUFBRTtBQUNsQixhQUFTLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQSxBQUFDLENBQUMsQ0FBQztBQUN6RixjQUFVLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssR0FBRyxVQUFVLENBQUMsQ0FBQztJQUMvRCxNQUNJLElBQUcsVUFBVSxHQUFHLENBQUMsRUFBRTtBQUN2QixhQUFTLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksR0FBRyxVQUFVLENBQUMsQ0FBQztBQUM3RCxjQUFVLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksR0FBRyxFQUFFLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQSxBQUFDLENBQUMsQ0FBQztJQUN6Rjs7QUFFRCxPQUFHLFVBQVUsRUFBRTtBQUNkLFFBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQ3JDO0FBQ0QsT0FBRyxXQUFXLEVBQUU7QUFDZixRQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsRUFBRSxVQUFVLENBQUMsQ0FBQztJQUN2Qzs7QUFFRCxLQUFFLENBQUMsU0FBUyxDQUFDLElBQUksR0FBRyxTQUFTLENBQUM7QUFDOUIsS0FBRSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEdBQUcsVUFBVSxDQUFDOztBQUVoQyxVQUFPLElBQUksQ0FBQyxZQUFZLFlBcFJ6QixZQUFZLEVBb1I0QixDQUN0QyxFQUFFLENBQUMsV0FBVyxFQUFFLEVBQUUsQ0FBQyxZQUFZLEVBQy9CLFNBQVMsRUFBRSxVQUFVLENBQ3JCLEVBQ0QsS0FBSyxDQUFDLENBQUM7R0FDUDs7Ozs7Ozs7O1NBUVUscUJBQUMsS0FBSyxFQUFFO0FBQ2xCLE9BQUksRUFBRSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7QUFDeEIsT0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUU7QUFBRSxXQUFPO0lBQUU7O0FBRS9CLE9BQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDLFNBQVMsRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUM7O0FBRTFGLE9BQUksQ0FBQyxnQkFBZ0IsQ0FDbkIsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FDaEIsV0FBVyxZQTlTZCxvQkFBb0IsQ0E4U2dCLENBQUM7O0FBRXBDLEtBQUUsQ0FBQyxXQUFXLENBQ1osR0FBRyxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsQ0FDcEIsR0FBRyxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsQ0FDcEIsV0FBVyxZQWxUZCxxQkFBcUIsQ0FrVGdCLENBQUM7O0FBRXJDLE9BQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO0FBQ3hCLE9BQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDOztBQUV4QixPQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQzs7QUFFdEIsVUFBTyxJQUFJLENBQUMsWUFBWSxZQXBUekIsaUJBQWlCLEVBb1Q0QixDQUMzQyxFQUFFLENBQUMsV0FBVyxFQUFFLEVBQUUsQ0FBQyxZQUFZLEVBQy9CLEVBQUUsQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUNyQyxFQUNELEtBQUssQ0FBQyxDQUFDO0dBQ1A7Ozs7Ozs7Ozs7U0FTTSxtQkFBRztBQUNULE9BQUksTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7QUFDekIsT0FBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxHQUFHLGNBeFU5QyxZQUFZLEFBd1UrQyxDQUFDLENBQUM7O0FBRTVELE9BQUksQ0FBQyxZQUFZLENBQ2hCLElBQUksQ0FBQyxPQUFPLENBQ1YsR0FBRyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FDeEIsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FDaEIsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUNmLENBQUM7O0FBRUYsV0FBUSxDQUFDLFVBQVUsWUFwVnBCLE9BQU8sQ0FvVnNCLENBQUM7QUFDN0IsU0FBTSxDQUFDLFVBQVUsWUF4VmxCLFFBQVEsQ0F3Vm9CLENBQUM7O0FBRTVCLE9BQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUUsQ0FBQztBQUMvQixPQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO0FBQzdCLE9BQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO0FBQzFCLE9BQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDOztBQUVuQixVQUFPLE1BQU0sQ0FBQztHQUNkOzs7Ozs7Ozs7Ozs7O1NBWVMsb0JBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxrQkFBa0IsRUFBRSxRQUFRLEVBQUU7QUFDekQsT0FBRyxPQUFPLE1BQU0sS0FBSyxRQUFRLEVBQUU7QUFDOUIsVUFBTSxHQUFHLE1BQU0sR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDO0lBQzFCLE1BQ0k7QUFDSixVQUFNLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUM7SUFDOUM7O0FBRUQsT0FBRyxTQUFTLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtBQUN4QixXQUFPLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxrQkFBa0IsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUNqRCxNQUNJO0FBQ0osV0FBTyxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztJQUN2QztHQUNEOzs7Ozs7Ozs7OztTQVVXLHNCQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUU7QUFDN0IsT0FBRyxPQUFPLE1BQU0sS0FBSyxRQUFRLEVBQUU7QUFDOUIsVUFBTSxHQUFHLE1BQU0sR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDO0lBQzFCLE1BQ0ksSUFBRyxNQUFNLElBQUksSUFBSSxFQUFFO0FBQ3ZCLFVBQU0sR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQztJQUM5QyxNQUNJO0FBQ0osVUFBTSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUM7SUFDakI7O0FBRUQsVUFBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztHQUNwQjs7Ozs7Ozs7Ozs7Ozs7O1NBY1csc0JBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxhQUFhLEVBQUU7QUFDdkMsT0FBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUMxQixPQUFHLEtBQUssQ0FBQyxhQUFhLEVBQUU7QUFDdkIsU0FBSyxDQUFDLGFBQWEsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxhQUFhLENBQUMsQ0FBQztJQUNsRDs7QUFFRCxVQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztHQUM3RDs7Ozs7Ozs7Ozs7U0FVZSwwQkFBQyxHQUFHLEVBQUU7QUFDckIsVUFBTyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksWUEvYXhCLGVBQWUsQ0ErYTBCLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxJQUFJLFlBOWExRCxjQUFjLENBOGE0RCxDQUFDO0dBQzFFOzs7Ozs7Ozs7OztTQVVTLG9CQUFDLE9BQU8sRUFBRTtBQUNuQixVQUFPLE9BQU8sR0FBRyxVQUFVLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztHQUN0RTs7Ozs7Ozs7Ozs7U0FVTyxrQkFBQyxPQUFPLEVBQUUsS0FBSyxFQUFFO0FBQ3hCLFFBQUssR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3pCLFFBQUssR0FBRyxLQUFLLEdBQUcsQ0FBQyxHQUFHLEtBQUssR0FBRyxDQUFDLENBQUM7QUFDOUIsVUFBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsS0FBSyxHQUFHLEdBQUcsQ0FBQztHQUNsQzs7Ozs7Ozs7Ozs7O1NBV2Esd0JBQUMsS0FBSyxFQUFFO0FBQ3JCLE9BQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLElBQUksU0FBUyxFQUFFO0FBQ3ZDLFNBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQy9DOztBQUVELE9BQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLElBQUksU0FBUyxFQUFFO0FBQ3ZDLFNBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQy9DOztBQUVELFVBQU8sS0FBSyxDQUFDO0dBQ2I7Ozs7Ozs7Ozs7Ozs7U0FZVSxxQkFBQyxLQUFLLEVBQUU7QUFDbEIsT0FBSSxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUU7QUFDdEMsV0FBTyxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssQ0FBQyxhQUFhLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFBLENBQUUsS0FBSyxDQUFDO0lBQ3ZGO0FBQ0QsVUFBTyxLQUFLLENBQUMsS0FBSyxDQUFDO0dBQ25COzs7UUF4ZG1CLGdCQUFnQjs7O3FCQUFoQixnQkFBZ0I7O0FBMmRyQyxnQkFBZ0IsQ0FBQyxRQUFRLEdBQUc7QUFDM0IsU0FBUSxFQUFFLGtCQUFTLE1BQU0sRUFBRTtBQUMxQixNQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxFQUFFO0FBQy9CLHFCQTVlRixXQUFXLENBNGVVO0dBQ25COztBQUVELG9CQTllRCxXQUFXLENBOGVTO0VBQ25CO0FBQ0QsTUFBSyxFQUFFLE1BQU0sQ0FBQyxLQUFLO0FBQ25CLGFBQVksRUFBRSxJQUFJO0FBQ2xCLGVBQWMsRUFBRSxJQUFJO0FBQ3BCLFNBQVEsRUFBRSxJQUFJO0FBQ2QsU0FBUSxFQUFFLElBQUk7Q0FDZCxDQUFDOztBQUVGLGdCQUFnQixDQUFDLEtBQUssR0FBRyxDQUFDLENBQUM7Ozs7Ozs7OztBQ3BnQnBCLElBQU0sUUFBUSxHQUFHLGtCQUFrQixDQUFDO1FBQTlCLFFBQVEsR0FBUixRQUFRO0FBQ2QsSUFBTSxlQUFlLEdBQUcsc0JBQXNCLENBQUM7UUFBekMsZUFBZSxHQUFmLGVBQWU7QUFDckIsSUFBTSxjQUFjLEdBQUcscUJBQXFCLENBQUM7UUFBdkMsY0FBYyxHQUFkLGNBQWM7QUFDcEIsSUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDOztRQUFmLE9BQU8sR0FBUCxPQUFPO0FBRWIsSUFBTSxvQkFBb0IsR0FBRyxtQkFBbUIsQ0FBQztRQUEzQyxvQkFBb0IsR0FBcEIsb0JBQW9CO0FBQzFCLElBQU0scUJBQXFCLEdBQUcsb0JBQW9CLENBQUM7UUFBN0MscUJBQXFCLEdBQXJCLHFCQUFxQjtBQUMzQixJQUFNLFlBQVksR0FBRyxXQUFXLENBQUM7UUFBM0IsWUFBWSxHQUFaLFlBQVk7QUFDbEIsSUFBTSxzQkFBc0IsR0FBRyxxQkFBcUIsQ0FBQzs7UUFBL0Msc0JBQXNCLEdBQXRCLHNCQUFzQjtBQUU1QixJQUFNLGtCQUFrQixHQUFHLHFCQUFxQixDQUFDO1FBQTNDLGtCQUFrQixHQUFsQixrQkFBa0I7QUFDeEIsSUFBTSxZQUFZLEdBQUcsZUFBZSxDQUFDO1FBQS9CLFlBQVksR0FBWixZQUFZO0FBQ2xCLElBQU0saUJBQWlCLEdBQUcsb0JBQW9CLENBQUM7O1FBQXpDLGlCQUFpQixHQUFqQixpQkFBaUI7QUFFdkIsSUFBTSxXQUFXLEdBQUcsdUJBQXVCLENBQUM7UUFBdEMsV0FBVyxHQUFYLFdBQVc7QUFDakIsSUFBTSxXQUFXLEdBQUcsdUJBQXVCLENBQUM7UUFBdEMsV0FBVyxHQUFYLFdBQVc7QUFDakIsSUFBTSxvQkFBb0Isb0JBQW9CLENBQUM7UUFBekMsb0JBQW9CLEdBQXBCLG9CQUFvQjs7Ozs7Ozs7Ozs7cUJDaEJKLFNBQVM7Ozs7dUJBQ2xCLFdBQVciLCJmaWxlIjoianF1ZXJ5LnJlc2l6YWJsZUNvbHVtbnMuanMiLCJzb3VyY2VSb290IjoiL3NvdXJjZS8iLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsImltcG9ydCBSZXNpemFibGVDb2x1bW5zIGZyb20gJy4vY2xhc3MnO1xuaW1wb3J0IHtEQVRBX0FQSX0gZnJvbSAnLi9jb25zdGFudHMnO1xuXG4kLmZuLnJlc2l6YWJsZUNvbHVtbnMgPSBmdW5jdGlvbihvcHRpb25zT3JNZXRob2QsIC4uLmFyZ3MpIHtcblx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRsZXQgJHRhYmxlID0gJCh0aGlzKTtcblxuXHRcdGxldCBhcGkgPSAkdGFibGUuZGF0YShEQVRBX0FQSSk7XG5cdFx0aWYgKCFhcGkpIHtcblx0XHRcdGFwaSA9IG5ldyBSZXNpemFibGVDb2x1bW5zKCR0YWJsZSwgb3B0aW9uc09yTWV0aG9kKTtcblx0XHRcdCR0YWJsZS5kYXRhKERBVEFfQVBJLCBhcGkpO1xuXHRcdH1cblxuXHRcdGVsc2UgaWYgKHR5cGVvZiBvcHRpb25zT3JNZXRob2QgPT09ICdzdHJpbmcnKSB7XG5cdFx0XHRyZXR1cm4gYXBpW29wdGlvbnNPck1ldGhvZF0oLi4uYXJncyk7XG5cdFx0fVxuXHR9KTtcbn07XG5cbiQucmVzaXphYmxlQ29sdW1ucyA9IFJlc2l6YWJsZUNvbHVtbnM7XG4iLCJpbXBvcnQge1xuXHREQVRBX0FQSSxcblx0REFUQV9DT0xVTU5TX0lELFxuXHREQVRBX0NPTFVNTl9JRCxcblx0REFUQV9USCxcblx0Q0xBU1NfVEFCTEVfUkVTSVpJTkcsXG5cdENMQVNTX0NPTFVNTl9SRVNJWklORyxcblx0Q0xBU1NfSEFORExFLFxuXHRDTEFTU19IQU5ETEVfQ09OVEFJTkVSLFxuXHRFVkVOVF9SRVNJWkVfU1RBUlQsXG5cdEVWRU5UX1JFU0laRSxcblx0RVZFTlRfUkVTSVpFX1NUT1AsXG5cdFNFTEVDVE9SX1RILFxuXHRTRUxFQ1RPUl9URCxcblx0U0VMRUNUT1JfVU5SRVNJWkFCTEVcbn1cbmZyb20gJy4vY29uc3RhbnRzJztcblxuLyoqXG5UYWtlcyBhIDx0YWJsZSAvPiBlbGVtZW50IGFuZCBtYWtlcyBpdCdzIGNvbHVtbnMgcmVzaXphYmxlIGFjcm9zcyBib3RoXG5tb2JpbGUgYW5kIGRlc2t0b3AgY2xpZW50cy5cblxuQGNsYXNzIFJlc2l6YWJsZUNvbHVtbnNcbkBwYXJhbSAkdGFibGUge2pRdWVyeX0galF1ZXJ5LXdyYXBwZWQgPHRhYmxlPiBlbGVtZW50IHRvIG1ha2UgcmVzaXphYmxlXG5AcGFyYW0gb3B0aW9ucyB7T2JqZWN0fSBDb25maWd1cmF0aW9uIG9iamVjdFxuKiovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSZXNpemFibGVDb2x1bW5zIHtcblx0Y29uc3RydWN0b3IoJHRhYmxlLCBvcHRpb25zKSB7XG5cdFx0dGhpcy5ucyA9ICcucmMnICsgdGhpcy5jb3VudCsrO1xuXG5cdFx0dGhpcy5vcHRpb25zID0gJC5leHRlbmQoe30sIFJlc2l6YWJsZUNvbHVtbnMuZGVmYXVsdHMsIG9wdGlvbnMpO1xuXG5cdFx0dGhpcy4kd2luZG93ID0gJCh3aW5kb3cpO1xuXHRcdHRoaXMuJG93bmVyRG9jdW1lbnQgPSAkKCR0YWJsZVswXS5vd25lckRvY3VtZW50KTtcblx0XHR0aGlzLiR0YWJsZSA9ICR0YWJsZTtcblxuXHRcdHRoaXMucmVmcmVzaEhlYWRlcnMoKTtcblx0XHR0aGlzLnJlc3RvcmVDb2x1bW5XaWR0aHMoKTtcblx0XHR0aGlzLnN5bmNIYW5kbGVXaWR0aHMoKTtcblxuXHRcdHRoaXMuYmluZEV2ZW50cyh0aGlzLiR3aW5kb3csICdyZXNpemUnLCB0aGlzLnN5bmNIYW5kbGVXaWR0aHMuYmluZCh0aGlzKSk7XG5cblx0XHRpZiAodGhpcy5vcHRpb25zLnN0YXJ0KSB7XG5cdFx0XHR0aGlzLmJpbmRFdmVudHModGhpcy4kdGFibGUsIEVWRU5UX1JFU0laRV9TVEFSVCwgdGhpcy5vcHRpb25zLnN0YXJ0KTtcblx0XHR9XG5cdFx0aWYgKHRoaXMub3B0aW9ucy5yZXNpemUpIHtcblx0XHRcdHRoaXMuYmluZEV2ZW50cyh0aGlzLiR0YWJsZSwgRVZFTlRfUkVTSVpFLCB0aGlzLm9wdGlvbnMucmVzaXplKTtcblx0XHR9XG5cdFx0aWYgKHRoaXMub3B0aW9ucy5zdG9wKSB7XG5cdFx0XHR0aGlzLmJpbmRFdmVudHModGhpcy4kdGFibGUsIEVWRU5UX1JFU0laRV9TVE9QLCB0aGlzLm9wdGlvbnMuc3RvcCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdFJlZnJlc2hlcyB0aGUgaGVhZGVycyBhc3NvY2lhdGVkIHdpdGggdGhpcyBpbnN0YW5jZXMgPHRhYmxlLz4gZWxlbWVudCBhbmRcblx0Z2VuZXJhdGVzIGhhbmRsZXMgZm9yIHRoZW0uIEFsc28gYXNzaWducyBwZXJjZW50YWdlIHdpZHRocy5cblxuXHRAbWV0aG9kIHJlZnJlc2hIZWFkZXJzXG5cdCoqL1xuXHRyZWZyZXNoSGVhZGVycygpIHtcblx0XHQvLyBBbGxvdyB0aGUgc2VsZWN0b3IgdG8gYmUgYm90aCBhIHJlZ3VsYXIgc2VsY3RvciBzdHJpbmcgYXMgd2VsbCBhc1xuXHRcdC8vIGEgZHluYW1pYyBjYWxsYmFja1xuXHRcdGxldCBzZWxlY3RvciA9IHRoaXMub3B0aW9ucy5zZWxlY3Rvcjtcblx0XHRpZih0eXBlb2Ygc2VsZWN0b3IgPT09ICdmdW5jdGlvbicpIHtcblx0XHRcdHNlbGVjdG9yID0gc2VsZWN0b3IuY2FsbCh0aGlzLCB0aGlzLiR0YWJsZSk7XG5cdFx0fVxuXG5cdFx0Ly8gU2VsZWN0IGFsbCB0YWJsZSBoZWFkZXJzXG5cdFx0dGhpcy4kdGFibGVIZWFkZXJzID0gdGhpcy4kdGFibGUuZmluZChzZWxlY3Rvcik7XG5cblx0XHQvLyBBc3NpZ24gcGVyY2VudGFnZSB3aWR0aHMgZmlyc3QsIHRoZW4gY3JlYXRlIGRyYWcgaGFuZGxlc1xuXHRcdHRoaXMuYXNzaWduUGVyY2VudGFnZVdpZHRocygpO1xuXHRcdHRoaXMuY3JlYXRlSGFuZGxlcygpO1xuXHR9XG5cblx0LyoqXG5cdENyZWF0ZXMgZHVtbXkgaGFuZGxlIGVsZW1lbnRzIGZvciBhbGwgdGFibGUgaGVhZGVyIGNvbHVtbnNcblxuXHRAbWV0aG9kIGNyZWF0ZUhhbmRsZXNcblx0KiovXG5cdGNyZWF0ZUhhbmRsZXMoKSB7XG5cdFx0bGV0IHJlZiA9IHRoaXMuJGhhbmRsZUNvbnRhaW5lcjtcblx0XHRpZiAocmVmICE9IG51bGwpIHtcblx0XHRcdHJlZi5yZW1vdmUoKTtcblx0XHR9XG5cblx0XHR0aGlzLiRoYW5kbGVDb250YWluZXIgPSAkKGA8ZGl2IGNsYXNzPScke0NMQVNTX0hBTkRMRV9DT05UQUlORVJ9JyAvPmApXG5cdFx0dGhpcy4kdGFibGUuYmVmb3JlKHRoaXMuJGhhbmRsZUNvbnRhaW5lcik7XG5cblx0XHR0aGlzLiR0YWJsZUhlYWRlcnMuZWFjaCgoaSwgZWwpID0+IHtcblx0XHRcdGxldCAkY3VycmVudCA9IHRoaXMuJHRhYmxlSGVhZGVycy5lcShpKTtcblx0XHRcdGxldCAkbmV4dCA9IHRoaXMuJHRhYmxlSGVhZGVycy5lcShpICsgMSk7XG5cblx0XHRcdGlmICgkbmV4dC5sZW5ndGggPT09IDAgfHwgJGN1cnJlbnQuaXMoU0VMRUNUT1JfVU5SRVNJWkFCTEUpIHx8ICRuZXh0LmlzKFNFTEVDVE9SX1VOUkVTSVpBQkxFKSkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdGxldCAkaGFuZGxlID0gJChgPGRpdiBjbGFzcz0nJHtDTEFTU19IQU5ETEV9JyAvPmApXG5cdFx0XHRcdC5kYXRhKERBVEFfVEgsICQoZWwpKVxuXHRcdFx0XHQuYXBwZW5kVG8odGhpcy4kaGFuZGxlQ29udGFpbmVyKTtcblx0XHR9KTtcblxuXHRcdHRoaXMuYmluZEV2ZW50cyh0aGlzLiRoYW5kbGVDb250YWluZXIsIFsnbW91c2Vkb3duJywgJ3RvdWNoc3RhcnQnXSwgJy4nK0NMQVNTX0hBTkRMRSwgdGhpcy5vblBvaW50ZXJEb3duLmJpbmQodGhpcykpO1xuXHR9XG5cblx0LyoqXG5cdEFzc2lnbnMgYSBwZXJjZW50YWdlIHdpZHRoIHRvIGFsbCBjb2x1bW5zIGJhc2VkIG9uIHRoZWlyIGN1cnJlbnQgcGl4ZWwgd2lkdGgocylcblxuXHRAbWV0aG9kIGFzc2lnblBlcmNlbnRhZ2VXaWR0aHNcblx0KiovXG5cdGFzc2lnblBlcmNlbnRhZ2VXaWR0aHMoKSB7XG5cdFx0dGhpcy4kdGFibGVIZWFkZXJzLmVhY2goKF8sIGVsKSA9PiB7XG5cdFx0XHRsZXQgJGVsID0gJChlbCk7XG5cdFx0XHR0aGlzLnNldFdpZHRoKCRlbFswXSwgJGVsLm91dGVyV2lkdGgoKSAvIHRoaXMuJHRhYmxlLndpZHRoKCkgKiAxMDApO1xuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cblxuXHRAbWV0aG9kIHN5bmNIYW5kbGVXaWR0aHNcblx0KiovXG5cdHN5bmNIYW5kbGVXaWR0aHMoKSB7XG5cdFx0bGV0ICRjb250YWluZXIgPSB0aGlzLiRoYW5kbGVDb250YWluZXJcblxuXHRcdCRjb250YWluZXIud2lkdGgodGhpcy4kdGFibGUud2lkdGgoKSk7XG5cblx0XHQkY29udGFpbmVyLmZpbmQoJy4nK0NMQVNTX0hBTkRMRSkuZWFjaCgoXywgZWwpID0+IHtcblx0XHRcdGxldCAkZWwgPSAkKGVsKTtcblxuXHRcdFx0bGV0IGhlaWdodCA9IHRoaXMub3B0aW9ucy5yZXNpemVGcm9tQm9keSA/XG5cdFx0XHRcdHRoaXMuJHRhYmxlLmhlaWdodCgpIDpcblx0XHRcdFx0dGhpcy4kdGFibGUuZmluZCgndGhlYWQnKS5oZWlnaHQoKTtcblxuXHRcdFx0bGV0IGxlZnQgPSAkZWwuZGF0YShEQVRBX1RIKS5vdXRlcldpZHRoKCkgKyAoXG5cdFx0XHRcdCRlbC5kYXRhKERBVEFfVEgpLm9mZnNldCgpLmxlZnQgLSB0aGlzLiRoYW5kbGVDb250YWluZXIub2Zmc2V0KCkubGVmdFxuXHRcdFx0KTtcblxuXHRcdFx0JGVsLmNzcyh7IGxlZnQsIGhlaWdodCB9KTtcblx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHRQZXJzaXN0cyB0aGUgY29sdW1uIHdpZHRocyBpbiBsb2NhbFN0b3JhZ2VcblxuXHRAbWV0aG9kIHNhdmVDb2x1bW5XaWR0aHNcblx0KiovXG5cdHNhdmVDb2x1bW5XaWR0aHMoKSB7XG5cdFx0dGhpcy4kdGFibGVIZWFkZXJzLmVhY2goKF8sIGVsKSA9PiB7XG5cdFx0XHRsZXQgJGVsID0gJChlbCk7XG5cblx0XHRcdGlmICh0aGlzLm9wdGlvbnMuc3RvcmUgJiYgISRlbC5pcyhTRUxFQ1RPUl9VTlJFU0laQUJMRSkpIHtcblx0XHRcdFx0dGhpcy5vcHRpb25zLnN0b3JlLnNldChcblx0XHRcdFx0XHR0aGlzLmdlbmVyYXRlQ29sdW1uSWQoJGVsKSxcblx0XHRcdFx0XHR0aGlzLnBhcnNlV2lkdGgoZWwpXG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0UmV0cmlldmVzIGFuZCBzZXRzIHRoZSBjb2x1bW4gd2lkdGhzIGZyb20gbG9jYWxTdG9yYWdlXG5cblx0QG1ldGhvZCByZXN0b3JlQ29sdW1uV2lkdGhzXG5cdCoqL1xuXHRyZXN0b3JlQ29sdW1uV2lkdGhzKCkge1xuXHRcdHRoaXMuJHRhYmxlSGVhZGVycy5lYWNoKChfLCBlbCkgPT4ge1xuXHRcdFx0bGV0ICRlbCA9ICQoZWwpO1xuXG5cdFx0XHRpZih0aGlzLm9wdGlvbnMuc3RvcmUgJiYgISRlbC5pcyhTRUxFQ1RPUl9VTlJFU0laQUJMRSkpIHtcblx0XHRcdFx0bGV0IHdpZHRoID0gdGhpcy5vcHRpb25zLnN0b3JlLmdldChcblx0XHRcdFx0XHR0aGlzLmdlbmVyYXRlQ29sdW1uSWQoJGVsKVxuXHRcdFx0XHQpO1xuXG5cdFx0XHRcdGlmKHdpZHRoICE9IG51bGwpIHtcblx0XHRcdFx0XHR0aGlzLnNldFdpZHRoKGVsLCB3aWR0aCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHRQb2ludGVyL21vdXNlIGRvd24gaGFuZGxlclxuXG5cdEBtZXRob2Qgb25Qb2ludGVyRG93blxuXHRAcGFyYW0gZXZlbnQge09iamVjdH0gRXZlbnQgb2JqZWN0IGFzc29jaWF0ZWQgd2l0aCB0aGUgaW50ZXJhY3Rpb25cblx0KiovXG5cdG9uUG9pbnRlckRvd24oZXZlbnQpIHtcblx0XHQvLyBPbmx5IGFwcGxpZXMgdG8gbGVmdC1jbGljayBkcmFnZ2luZ1xuXHRcdGlmKGV2ZW50LndoaWNoICE9PSAxKSB7IHJldHVybjsgfVxuXG5cdFx0Ly8gSWYgYSBwcmV2aW91cyBvcGVyYXRpb24gaXMgZGVmaW5lZCwgd2UgbWlzc2VkIHRoZSBsYXN0IG1vdXNldXAuXG5cdFx0Ly8gUHJvYmFibHkgZ29iYmxlZCB1cCBieSB1c2VyIG1vdXNpbmcgb3V0IHRoZSB3aW5kb3cgdGhlbiByZWxlYXNpbmcuXG5cdFx0Ly8gV2UnbGwgc2ltdWxhdGUgYSBwb2ludGVydXAgaGVyZSBwcmlvciB0byBpdFxuXHRcdGlmKHRoaXMub3BlcmF0aW9uKSB7XG5cdFx0XHR0aGlzLm9uUG9pbnRlclVwKGV2ZW50KTtcblx0XHR9XG5cblx0XHQvLyBJZ25vcmUgbm9uLXJlc2l6YWJsZSBjb2x1bW5zXG5cdFx0bGV0ICRjdXJyZW50R3JpcCA9ICQoZXZlbnQuY3VycmVudFRhcmdldCk7XG5cdFx0aWYoJGN1cnJlbnRHcmlwLmlzKFNFTEVDVE9SX1VOUkVTSVpBQkxFKSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGxldCBncmlwSW5kZXggPSAkY3VycmVudEdyaXAuaW5kZXgoKTtcblx0XHRsZXQgJGxlZnRDb2x1bW4gPSB0aGlzLiR0YWJsZUhlYWRlcnMuZXEoZ3JpcEluZGV4KS5ub3QoU0VMRUNUT1JfVU5SRVNJWkFCTEUpO1xuXHRcdGxldCAkcmlnaHRDb2x1bW4gPSB0aGlzLiR0YWJsZUhlYWRlcnMuZXEoZ3JpcEluZGV4ICsgMSkubm90KFNFTEVDVE9SX1VOUkVTSVpBQkxFKTtcblxuXHRcdGxldCBsZWZ0V2lkdGggPSB0aGlzLnBhcnNlV2lkdGgoJGxlZnRDb2x1bW5bMF0pO1xuXHRcdGxldCByaWdodFdpZHRoID0gdGhpcy5wYXJzZVdpZHRoKCRyaWdodENvbHVtblswXSk7XG5cblx0XHR0aGlzLm9wZXJhdGlvbiA9IHtcblx0XHRcdCRsZWZ0Q29sdW1uLCAkcmlnaHRDb2x1bW4sICRjdXJyZW50R3JpcCxcblxuXHRcdFx0c3RhcnRYOiB0aGlzLmdldFBvaW50ZXJYKGV2ZW50KSxcblxuXHRcdFx0d2lkdGhzOiB7XG5cdFx0XHRcdGxlZnQ6IGxlZnRXaWR0aCxcblx0XHRcdFx0cmlnaHQ6IHJpZ2h0V2lkdGhcblx0XHRcdH0sXG5cdFx0XHRuZXdXaWR0aHM6IHtcblx0XHRcdFx0bGVmdDogbGVmdFdpZHRoLFxuXHRcdFx0XHRyaWdodDogcmlnaHRXaWR0aFxuXHRcdFx0fVxuXHRcdH07XG5cblx0XHR0aGlzLmJpbmRFdmVudHModGhpcy4kb3duZXJEb2N1bWVudCwgWydtb3VzZW1vdmUnLCAndG91Y2htb3ZlJ10sIHRoaXMub25Qb2ludGVyTW92ZS5iaW5kKHRoaXMpKTtcblx0XHR0aGlzLmJpbmRFdmVudHModGhpcy4kb3duZXJEb2N1bWVudCwgWydtb3VzZXVwJywgJ3RvdWNoZW5kJ10sIHRoaXMub25Qb2ludGVyVXAuYmluZCh0aGlzKSk7XG5cblx0XHR0aGlzLiRoYW5kbGVDb250YWluZXJcblx0XHRcdC5hZGQodGhpcy4kdGFibGUpXG5cdFx0XHQuYWRkQ2xhc3MoQ0xBU1NfVEFCTEVfUkVTSVpJTkcpO1xuXG5cdFx0JGxlZnRDb2x1bW5cblx0XHRcdC5hZGQoJHJpZ2h0Q29sdW1uKVxuXHRcdFx0LmFkZCgkY3VycmVudEdyaXApXG5cdFx0XHQuYWRkQ2xhc3MoQ0xBU1NfQ09MVU1OX1JFU0laSU5HKTtcblxuXHRcdHRoaXMudHJpZ2dlckV2ZW50KEVWRU5UX1JFU0laRV9TVEFSVCwgW1xuXHRcdFx0JGxlZnRDb2x1bW4sICRyaWdodENvbHVtbixcblx0XHRcdGxlZnRXaWR0aCwgcmlnaHRXaWR0aFxuXHRcdF0sXG5cdFx0ZXZlbnQpO1xuXG5cdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0fVxuXG5cdC8qKlxuXHRQb2ludGVyL21vdXNlIG1vdmVtZW50IGhhbmRsZXJcblxuXHRAbWV0aG9kIG9uUG9pbnRlck1vdmVcblx0QHBhcmFtIGV2ZW50IHtPYmplY3R9IEV2ZW50IG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhlIGludGVyYWN0aW9uXG5cdCoqL1xuXHRvblBvaW50ZXJNb3ZlKGV2ZW50KSB7XG5cdFx0bGV0IG9wID0gdGhpcy5vcGVyYXRpb247XG5cdFx0aWYoIXRoaXMub3BlcmF0aW9uKSB7IHJldHVybjsgfVxuXG5cdFx0Ly8gRGV0ZXJtaW5lIHRoZSBkZWx0YSBjaGFuZ2UgYmV0d2VlbiBzdGFydCBhbmQgbmV3IG1vdXNlIHBvc2l0aW9uLCBhcyBhIHBlcmNlbnRhZ2Ugb2YgdGhlIHRhYmxlIHdpZHRoXG5cdFx0bGV0IGRpZmZlcmVuY2UgPSAodGhpcy5nZXRQb2ludGVyWChldmVudCkgLSBvcC5zdGFydFgpIC8gdGhpcy4kdGFibGUud2lkdGgoKSAqIDEwMDtcblx0XHRpZihkaWZmZXJlbmNlID09PSAwKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0bGV0IGxlZnRDb2x1bW4gPSBvcC4kbGVmdENvbHVtblswXTtcblx0XHRsZXQgcmlnaHRDb2x1bW4gPSBvcC4kcmlnaHRDb2x1bW5bMF07XG5cdFx0bGV0IHdpZHRoTGVmdCwgd2lkdGhSaWdodDtcblxuXHRcdGlmKGRpZmZlcmVuY2UgPiAwKSB7XG5cdFx0XHR3aWR0aExlZnQgPSB0aGlzLmNvbnN0cmFpbldpZHRoKG9wLndpZHRocy5sZWZ0ICsgKG9wLndpZHRocy5yaWdodCAtIG9wLm5ld1dpZHRocy5yaWdodCkpO1xuXHRcdFx0d2lkdGhSaWdodCA9IHRoaXMuY29uc3RyYWluV2lkdGgob3Aud2lkdGhzLnJpZ2h0IC0gZGlmZmVyZW5jZSk7XG5cdFx0fVxuXHRcdGVsc2UgaWYoZGlmZmVyZW5jZSA8IDApIHtcblx0XHRcdHdpZHRoTGVmdCA9IHRoaXMuY29uc3RyYWluV2lkdGgob3Aud2lkdGhzLmxlZnQgKyBkaWZmZXJlbmNlKTtcblx0XHRcdHdpZHRoUmlnaHQgPSB0aGlzLmNvbnN0cmFpbldpZHRoKG9wLndpZHRocy5yaWdodCArIChvcC53aWR0aHMubGVmdCAtIG9wLm5ld1dpZHRocy5sZWZ0KSk7XG5cdFx0fVxuXG5cdFx0aWYobGVmdENvbHVtbikge1xuXHRcdFx0dGhpcy5zZXRXaWR0aChsZWZ0Q29sdW1uLCB3aWR0aExlZnQpO1xuXHRcdH1cblx0XHRpZihyaWdodENvbHVtbikge1xuXHRcdFx0dGhpcy5zZXRXaWR0aChyaWdodENvbHVtbiwgd2lkdGhSaWdodCk7XG5cdFx0fVxuXG5cdFx0b3AubmV3V2lkdGhzLmxlZnQgPSB3aWR0aExlZnQ7XG5cdFx0b3AubmV3V2lkdGhzLnJpZ2h0ID0gd2lkdGhSaWdodDtcblxuXHRcdHJldHVybiB0aGlzLnRyaWdnZXJFdmVudChFVkVOVF9SRVNJWkUsIFtcblx0XHRcdG9wLiRsZWZ0Q29sdW1uLCBvcC4kcmlnaHRDb2x1bW4sXG5cdFx0XHR3aWR0aExlZnQsIHdpZHRoUmlnaHRcblx0XHRdLFxuXHRcdGV2ZW50KTtcblx0fVxuXG5cdC8qKlxuXHRQb2ludGVyL21vdXNlIHJlbGVhc2UgaGFuZGxlclxuXG5cdEBtZXRob2Qgb25Qb2ludGVyVXBcblx0QHBhcmFtIGV2ZW50IHtPYmplY3R9IEV2ZW50IG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhlIGludGVyYWN0aW9uXG5cdCoqL1xuXHRvblBvaW50ZXJVcChldmVudCkge1xuXHRcdGxldCBvcCA9IHRoaXMub3BlcmF0aW9uO1xuXHRcdGlmKCF0aGlzLm9wZXJhdGlvbikgeyByZXR1cm47IH1cblxuXHRcdHRoaXMudW5iaW5kRXZlbnRzKHRoaXMuJG93bmVyRG9jdW1lbnQsIFsnbW91c2V1cCcsICd0b3VjaGVuZCcsICdtb3VzZW1vdmUnLCAndG91Y2htb3ZlJ10pO1xuXG5cdFx0dGhpcy4kaGFuZGxlQ29udGFpbmVyXG5cdFx0XHQuYWRkKHRoaXMuJHRhYmxlKVxuXHRcdFx0LnJlbW92ZUNsYXNzKENMQVNTX1RBQkxFX1JFU0laSU5HKTtcblxuXHRcdG9wLiRsZWZ0Q29sdW1uXG5cdFx0XHQuYWRkKG9wLiRyaWdodENvbHVtbilcblx0XHRcdC5hZGQob3AuJGN1cnJlbnRHcmlwKVxuXHRcdFx0LnJlbW92ZUNsYXNzKENMQVNTX0NPTFVNTl9SRVNJWklORyk7XG5cblx0XHR0aGlzLnN5bmNIYW5kbGVXaWR0aHMoKTtcblx0XHR0aGlzLnNhdmVDb2x1bW5XaWR0aHMoKTtcblxuXHRcdHRoaXMub3BlcmF0aW9uID0gbnVsbDtcblxuXHRcdHJldHVybiB0aGlzLnRyaWdnZXJFdmVudChFVkVOVF9SRVNJWkVfU1RPUCwgW1xuXHRcdFx0b3AuJGxlZnRDb2x1bW4sIG9wLiRyaWdodENvbHVtbixcblx0XHRcdG9wLm5ld1dpZHRocy5sZWZ0LCBvcC5uZXdXaWR0aHMucmlnaHRcblx0XHRdLFxuXHRcdGV2ZW50KTtcblx0fVxuXG5cdC8qKlxuXHRSZW1vdmVzIGFsbCBldmVudCBsaXN0ZW5lcnMsIGRhdGEsIGFuZCBhZGRlZCBET00gZWxlbWVudHMuIFRha2VzXG5cdHRoZSA8dGFibGUvPiBlbGVtZW50IGJhY2sgdG8gaG93IGl0IHdhcywgYW5kIHJldHVybnMgaXRcblxuXHRAbWV0aG9kIGRlc3Ryb3lcblx0QHJldHVybiB7alF1ZXJ5fSBPcmlnaW5hbCBqUXVlcnktd3JhcHBlZCA8dGFibGU+IGVsZW1lbnRcblx0KiovXG5cdGRlc3Ryb3koKSB7XG5cdFx0bGV0ICR0YWJsZSA9IHRoaXMuJHRhYmxlO1xuXHRcdGxldCAkaGFuZGxlcyA9IHRoaXMuJGhhbmRsZUNvbnRhaW5lci5maW5kKCcuJytDTEFTU19IQU5ETEUpO1xuXG5cdFx0dGhpcy51bmJpbmRFdmVudHMoXG5cdFx0XHR0aGlzLiR3aW5kb3dcblx0XHRcdFx0LmFkZCh0aGlzLiRvd25lckRvY3VtZW50KVxuXHRcdFx0XHQuYWRkKHRoaXMuJHRhYmxlKVxuXHRcdFx0XHQuYWRkKCRoYW5kbGVzKVxuXHRcdCk7XG5cblx0XHQkaGFuZGxlcy5yZW1vdmVEYXRhKERBVEFfVEgpO1xuXHRcdCR0YWJsZS5yZW1vdmVEYXRhKERBVEFfQVBJKTtcblxuXHRcdHRoaXMuJGhhbmRsZUNvbnRhaW5lci5yZW1vdmUoKTtcblx0XHR0aGlzLiRoYW5kbGVDb250YWluZXIgPSBudWxsO1xuXHRcdHRoaXMuJHRhYmxlSGVhZGVycyA9IG51bGw7XG5cdFx0dGhpcy4kdGFibGUgPSBudWxsO1xuXG5cdFx0cmV0dXJuICR0YWJsZTtcblx0fVxuXG5cdC8qKlxuXHRCaW5kcyBnaXZlbiBldmVudHMgZm9yIHRoaXMgaW5zdGFuY2UgdG8gdGhlIGdpdmVuIHRhcmdldCBET01FbGVtZW50XG5cblx0QHByaXZhdGVcblx0QG1ldGhvZCBiaW5kRXZlbnRzXG5cdEBwYXJhbSB0YXJnZXQge2pRdWVyeX0galF1ZXJ5LXdyYXBwZWQgRE9NRWxlbWVudCB0byBiaW5kIGV2ZW50cyB0b1xuXHRAcGFyYW0gZXZlbnRzIHtTdHJpbmd8QXJyYXl9IEV2ZW50IG5hbWUgKG9yIGFycmF5IG9mKSB0byBiaW5kXG5cdEBwYXJhbSBzZWxlY3Rvck9yQ2FsbGJhY2sge1N0cmluZ3xGdW5jdGlvbn0gU2VsZWN0b3Igc3RyaW5nIG9yIGNhbGxiYWNrXG5cdEBwYXJhbSBbY2FsbGJhY2tdIHtGdW5jdGlvbn0gQ2FsbGJhY2sgbWV0aG9kXG5cdCoqL1xuXHRiaW5kRXZlbnRzKCR0YXJnZXQsIGV2ZW50cywgc2VsZWN0b3JPckNhbGxiYWNrLCBjYWxsYmFjaykge1xuXHRcdGlmKHR5cGVvZiBldmVudHMgPT09ICdzdHJpbmcnKSB7XG5cdFx0XHRldmVudHMgPSBldmVudHMgKyB0aGlzLm5zO1xuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdGV2ZW50cyA9IGV2ZW50cy5qb2luKHRoaXMubnMgKyAnICcpICsgdGhpcy5ucztcblx0XHR9XG5cblx0XHRpZihhcmd1bWVudHMubGVuZ3RoID4gMykge1xuXHRcdFx0JHRhcmdldC5vbihldmVudHMsIHNlbGVjdG9yT3JDYWxsYmFjaywgY2FsbGJhY2spO1xuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdCR0YXJnZXQub24oZXZlbnRzLCBzZWxlY3Rvck9yQ2FsbGJhY2spO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHRVbmJpbmRzIGV2ZW50cyBzcGVjaWZpYyB0byB0aGlzIGluc3RhbmNlIGZyb20gdGhlIGdpdmVuIHRhcmdldCBET01FbGVtZW50XG5cblx0QHByaXZhdGVcblx0QG1ldGhvZCB1bmJpbmRFdmVudHNcblx0QHBhcmFtIHRhcmdldCB7alF1ZXJ5fSBqUXVlcnktd3JhcHBlZCBET01FbGVtZW50IHRvIHVuYmluZCBldmVudHMgZnJvbVxuXHRAcGFyYW0gZXZlbnRzIHtTdHJpbmd8QXJyYXl9IEV2ZW50IG5hbWUgKG9yIGFycmF5IG9mKSB0byB1bmJpbmRcblx0KiovXG5cdHVuYmluZEV2ZW50cygkdGFyZ2V0LCBldmVudHMpIHtcblx0XHRpZih0eXBlb2YgZXZlbnRzID09PSAnc3RyaW5nJykge1xuXHRcdFx0ZXZlbnRzID0gZXZlbnRzICsgdGhpcy5ucztcblx0XHR9XG5cdFx0ZWxzZSBpZihldmVudHMgIT0gbnVsbCkge1xuXHRcdFx0ZXZlbnRzID0gZXZlbnRzLmpvaW4odGhpcy5ucyArICcgJykgKyB0aGlzLm5zO1xuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdGV2ZW50cyA9IHRoaXMubnM7XG5cdFx0fVxuXG5cdFx0JHRhcmdldC5vZmYoZXZlbnRzKTtcblx0fVxuXG5cdC8qKlxuXHRUcmlnZ2VycyBhbiBldmVudCBvbiB0aGUgPHRhYmxlLz4gZWxlbWVudCBmb3IgYSBnaXZlbiB0eXBlIHdpdGggZ2l2ZW5cblx0YXJndW1lbnRzLCBhbHNvIHNldHRpbmcgYW5kIGFsbG93aW5nIGFjY2VzcyB0byB0aGUgb3JpZ2luYWxFdmVudCBpZlxuXHRnaXZlbi4gUmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSB0cmlnZ2VyZWQgZXZlbnQuXG5cblx0QHByaXZhdGVcblx0QG1ldGhvZCB0cmlnZ2VyRXZlbnRcblx0QHBhcmFtIHR5cGUge1N0cmluZ30gRXZlbnQgbmFtZVxuXHRAcGFyYW0gYXJncyB7QXJyYXl9IEFycmF5IG9mIGFyZ3VtZW50cyB0byBwYXNzIHRocm91Z2hcblx0QHBhcmFtIFtvcmlnaW5hbEV2ZW50XSBJZiBnaXZlbiwgaXMgc2V0IG9uIHRoZSBldmVudCBvYmplY3Rcblx0QHJldHVybiB7TWl4ZWR9IFJlc3VsdCBvZiB0aGUgZXZlbnQgdHJpZ2dlciBhY3Rpb25cblx0KiovXG5cdHRyaWdnZXJFdmVudCh0eXBlLCBhcmdzLCBvcmlnaW5hbEV2ZW50KSB7XG5cdFx0bGV0IGV2ZW50ID0gJC5FdmVudCh0eXBlKTtcblx0XHRpZihldmVudC5vcmlnaW5hbEV2ZW50KSB7XG5cdFx0XHRldmVudC5vcmlnaW5hbEV2ZW50ID0gJC5leHRlbmQoe30sIG9yaWdpbmFsRXZlbnQpO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLiR0YWJsZS50cmlnZ2VyKGV2ZW50LCBbdGhpc10uY29uY2F0KGFyZ3MgfHwgW10pKTtcblx0fVxuXG5cdC8qKlxuXHRDYWxjdWxhdGVzIGEgdW5pcXVlIGNvbHVtbiBJRCBmb3IgYSBnaXZlbiBjb2x1bW4gRE9NRWxlbWVudFxuXG5cdEBwcml2YXRlXG5cdEBtZXRob2QgZ2VuZXJhdGVDb2x1bW5JZFxuXHRAcGFyYW0gJGVsIHtqUXVlcnl9IGpRdWVyeS13cmFwcGVkIGNvbHVtbiBlbGVtZW50XG5cdEByZXR1cm4ge1N0cmluZ30gQ29sdW1uIElEXG5cdCoqL1xuXHRnZW5lcmF0ZUNvbHVtbklkKCRlbCkge1xuXHRcdHJldHVybiB0aGlzLiR0YWJsZS5kYXRhKERBVEFfQ09MVU1OU19JRCkgKyAnLScgKyAkZWwuZGF0YShEQVRBX0NPTFVNTl9JRCk7XG5cdH1cblxuXHQvKipcblx0UGFyc2VzIGEgZ2l2ZW4gRE9NRWxlbWVudCdzIHdpZHRoIGludG8gYSBmbG9hdFxuXG5cdEBwcml2YXRlXG5cdEBtZXRob2QgcGFyc2VXaWR0aFxuXHRAcGFyYW0gZWxlbWVudCB7RE9NRWxlbWVudH0gRWxlbWVudCB0byBnZXQgd2lkdGggb2Zcblx0QHJldHVybiB7TnVtYmVyfSBFbGVtZW50J3Mgd2lkdGggYXMgYSBmbG9hdFxuXHQqKi9cblx0cGFyc2VXaWR0aChlbGVtZW50KSB7XG5cdFx0cmV0dXJuIGVsZW1lbnQgPyBwYXJzZUZsb2F0KGVsZW1lbnQuc3R5bGUud2lkdGgucmVwbGFjZSgnJScsICcnKSkgOiAwO1xuXHR9XG5cblx0LyoqXG5cdFNldHMgdGhlIHBlcmNlbnRhZ2Ugd2lkdGggb2YgYSBnaXZlbiBET01FbGVtZW50XG5cblx0QHByaXZhdGVcblx0QG1ldGhvZCBzZXRXaWR0aFxuXHRAcGFyYW0gZWxlbWVudCB7RE9NRWxlbWVudH0gRWxlbWVudCB0byBzZXQgd2lkdGggb25cblx0QHBhcmFtIHdpZHRoIHtOdW1iZXJ9IFdpZHRoLCBhcyBhIHBlcmNlbnRhZ2UsIHRvIHNldFxuXHQqKi9cblx0c2V0V2lkdGgoZWxlbWVudCwgd2lkdGgpIHtcblx0XHR3aWR0aCA9IHdpZHRoLnRvRml4ZWQoMik7XG5cdFx0d2lkdGggPSB3aWR0aCA+IDAgPyB3aWR0aCA6IDA7XG5cdFx0ZWxlbWVudC5zdHlsZS53aWR0aCA9IHdpZHRoICsgJyUnO1xuXHR9XG5cblx0LyoqXG5cdENvbnN0cmFpbnMgYSBnaXZlbiB3aWR0aCB0byB0aGUgbWluaW11bSBhbmQgbWF4aW11bSByYW5nZXMgZGVmaW5lZCBpblxuXHR0aGUgYG1pbldpZHRoYCBhbmQgYG1heFdpZHRoYCBjb25maWd1cmF0aW9uIG9wdGlvbnMsIHJlc3BlY3RpdmVseS5cblxuXHRAcHJpdmF0ZVxuXHRAbWV0aG9kIGNvbnN0cmFpbldpZHRoXG5cdEBwYXJhbSB3aWR0aCB7TnVtYmVyfSBXaWR0aCB0byBjb25zdHJhaW5cblx0QHJldHVybiB7TnVtYmVyfSBDb25zdHJhaW5lZCB3aWR0aFxuXHQqKi9cblx0Y29uc3RyYWluV2lkdGgod2lkdGgpIHtcblx0XHRpZiAodGhpcy5vcHRpb25zLm1pbldpZHRoICE9IHVuZGVmaW5lZCkge1xuXHRcdFx0d2lkdGggPSBNYXRoLm1heCh0aGlzLm9wdGlvbnMubWluV2lkdGgsIHdpZHRoKTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5vcHRpb25zLm1heFdpZHRoICE9IHVuZGVmaW5lZCkge1xuXHRcdFx0d2lkdGggPSBNYXRoLm1pbih0aGlzLm9wdGlvbnMubWF4V2lkdGgsIHdpZHRoKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gd2lkdGg7XG5cdH1cblxuXHQvKipcblx0R2l2ZW4gYSBwYXJ0aWN1bGFyIEV2ZW50IG9iamVjdCwgcmV0cmlldmVzIHRoZSBjdXJyZW50IHBvaW50ZXIgb2Zmc2V0IGFsb25nXG5cdHRoZSBob3Jpem9udGFsIGRpcmVjdGlvbi4gQWNjb3VudHMgZm9yIGJvdGggcmVndWxhciBtb3VzZSBjbGlja3MgYXMgd2VsbCBhc1xuXHRwb2ludGVyLWxpa2Ugc3lzdGVtcyAobW9iaWxlcywgdGFibGV0cyBldGMuKVxuXG5cdEBwcml2YXRlXG5cdEBtZXRob2QgZ2V0UG9pbnRlclhcblx0QHBhcmFtIGV2ZW50IHtPYmplY3R9IEV2ZW50IG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhlIGludGVyYWN0aW9uXG5cdEByZXR1cm4ge051bWJlcn0gSG9yaXpvbnRhbCBwb2ludGVyIG9mZnNldFxuXHQqKi9cblx0Z2V0UG9pbnRlclgoZXZlbnQpIHtcblx0XHRpZiAoZXZlbnQudHlwZS5pbmRleE9mKCd0b3VjaCcpID09PSAwKSB7XG5cdFx0XHRyZXR1cm4gKGV2ZW50Lm9yaWdpbmFsRXZlbnQudG91Y2hlc1swXSB8fCBldmVudC5vcmlnaW5hbEV2ZW50LmNoYW5nZWRUb3VjaGVzWzBdKS5wYWdlWDtcblx0XHR9XG5cdFx0cmV0dXJuIGV2ZW50LnBhZ2VYO1xuXHR9XG59XG5cblJlc2l6YWJsZUNvbHVtbnMuZGVmYXVsdHMgPSB7XG5cdHNlbGVjdG9yOiBmdW5jdGlvbigkdGFibGUpIHtcblx0XHRpZigkdGFibGUuZmluZCgndGhlYWQnKS5sZW5ndGgpIHtcblx0XHRcdHJldHVybiBTRUxFQ1RPUl9USDtcblx0XHR9XG5cblx0XHRyZXR1cm4gU0VMRUNUT1JfVEQ7XG5cdH0sXG5cdHN0b3JlOiB3aW5kb3cuc3RvcmUsXG5cdHN5bmNIYW5kbGVyczogdHJ1ZSxcblx0cmVzaXplRnJvbUJvZHk6IHRydWUsXG5cdG1heFdpZHRoOiBudWxsLFxuXHRtaW5XaWR0aDogMC4wMVxufTtcblxuUmVzaXphYmxlQ29sdW1ucy5jb3VudCA9IDA7XG4iLCJleHBvcnQgY29uc3QgREFUQV9BUEkgPSAncmVzaXphYmxlQ29sdW1ucyc7XG5leHBvcnQgY29uc3QgREFUQV9DT0xVTU5TX0lEID0gJ3Jlc2l6YWJsZS1jb2x1bW5zLWlkJztcbmV4cG9ydCBjb25zdCBEQVRBX0NPTFVNTl9JRCA9ICdyZXNpemFibGUtY29sdW1uLWlkJztcbmV4cG9ydCBjb25zdCBEQVRBX1RIID0gJ3RoJztcblxuZXhwb3J0IGNvbnN0IENMQVNTX1RBQkxFX1JFU0laSU5HID0gJ3JjLXRhYmxlLXJlc2l6aW5nJztcbmV4cG9ydCBjb25zdCBDTEFTU19DT0xVTU5fUkVTSVpJTkcgPSAncmMtY29sdW1uLXJlc2l6aW5nJztcbmV4cG9ydCBjb25zdCBDTEFTU19IQU5ETEUgPSAncmMtaGFuZGxlJztcbmV4cG9ydCBjb25zdCBDTEFTU19IQU5ETEVfQ09OVEFJTkVSID0gJ3JjLWhhbmRsZS1jb250YWluZXInO1xuXG5leHBvcnQgY29uc3QgRVZFTlRfUkVTSVpFX1NUQVJUID0gJ2NvbHVtbjpyZXNpemU6c3RhcnQnO1xuZXhwb3J0IGNvbnN0IEVWRU5UX1JFU0laRSA9ICdjb2x1bW46cmVzaXplJztcbmV4cG9ydCBjb25zdCBFVkVOVF9SRVNJWkVfU1RPUCA9ICdjb2x1bW46cmVzaXplOnN0b3AnO1xuXG5leHBvcnQgY29uc3QgU0VMRUNUT1JfVEggPSAndHI6Zmlyc3QgPiB0aDp2aXNpYmxlJztcbmV4cG9ydCBjb25zdCBTRUxFQ1RPUl9URCA9ICd0cjpmaXJzdCA+IHRkOnZpc2libGUnO1xuZXhwb3J0IGNvbnN0IFNFTEVDVE9SX1VOUkVTSVpBQkxFID0gYFtkYXRhLW5vcmVzaXplXWA7XG4iLCJpbXBvcnQgUmVzaXphYmxlQ29sdW1ucyBmcm9tICcuL2NsYXNzJztcbmltcG9ydCBhZGFwdGVyIGZyb20gJy4vYWRhcHRlcic7XG5cbmV4cG9ydCBkZWZhdWx0IFJlc2l6YWJsZUNvbHVtbnM7Il19
71239;
71240$(document).ready(function() {
71241  $("input.search-query").each(function(index, input) {
71242    if (!input.id) {
71243      $(input).prop("id", Math.random().toString(36).substr(2, 10))
71244    }
71245    $(input).attr("autocomplete", "off")
71246    $(input).popover({
71247      animation: false,
71248      content: function() {
71249        return $("#autocomlpete-list").html()
71250      },
71251      html: true,
71252      placement: "bottom",
71253      trigger: "manual",
71254      sanitize: false
71255    })
71256  })
71257})
71258
71259$(document)
71260  .off("click", ".autocomplete-item")
71261  .on("click", ".autocomplete-item", function() {
71262    select_suggest($(this))
71263  })
71264
71265$(document).on("mouseenter", ".autocomplete-item", function() {
71266  $(".autocomplete-item.selected").removeClass("selected")
71267  $(this).addClass("selected")
71268})
71269
71270$(document).on("keypress", ".search-query", function(event) {
71271  if (event.which == 13) {
71272    var selected = $(".autocomplete-item.selected")
71273    if (selected.length == 0) return
71274    select_suggest(selected)
71275    return false
71276  }
71277})
71278
71279$(document).on("focus", ".search-query", function(event) {
71280  if ($(this).data("selected")) {
71281    $(this).data("selected", false)
71282    return
71283  }
71284  if ($(this).val()) {
71285    var option = ""
71286    var option_types = ["excepts", "scope-type", "scope-id", "scope-ids", "except-scope-type", "except-scope-id", "except-scope-ids"]
71287    option_types.forEach(function(option_type) {
71288      if ($(event.target).data(option_type)) {
71289        option += "&" + option_type.replace(/-/g, "_") + "=" + $(event.target).data(option_type)
71290      }
71291    })
71292
71293    var school_id = $(this).data("scope-id")
71294    var search_target = $(this).data("search-target")
71295    if (school_id) {
71296      $.get(`/admin/schools/${school_id}/${search_target}/search.js?q=${encodeURIComponent($(this).val())}${option}`)
71297    } else {
71298      $.get(`/admin/${search_target}/search.js?q=${encodeURIComponent($(this).val())}${option}`)
71299    }
71300  }
71301})
71302
71303$(document).on("keyup", ".search-query", function(event) {
71304  if (event.which == 27) {
71305    $(this).popover("hide")
71306  } else if (event.which == 13) {
71307    return false
71308  } else if (event.which == 40 || event.which == 38 && $(".autocomplete-item:visible").length > 0) {
71309    var selected
71310    if (event.which == 40) {
71311      selected = $(".autocomplete-item.selected").next()
71312      if (selected.length == 0) {
71313        selected = $(".autocomplete-item:visible:first")
71314      }
71315    } else {
71316      selected = $(".autocomplete-item.selected").prev()
71317      if (selected.length == 0) {
71318        selected = $(".autocomplete-item:visible:last")
71319      }
71320    }
71321    $(".autocomplete-item.selected").removeClass("selected")
71322    selected.addClass("selected")
71323  } else {
71324    if ($(this).data("submit-target")) {
71325      $(this).closest("form").find($(this).data("submit-target")).attr("disabled", true)
71326    }
71327    $(this).trigger("focus")
71328  }
71329})
71330
71331function select_suggest(target) {
71332  var input = $("input.search-query")
71333  input.data("selected", true)
71334    .focus()
71335    .val(target.data("title"))
71336    .popover("hide")
71337
71338  if (target.data("url")) {
71339    window.location.href = target.data("url")
71340  }
71341};
71342function select_exam(target) {
71343  var input = $("input.exam-search");
71344  var form_id = input[0].id;
71345  input.data("selected", true);
71346  $("input#" + form_id)
71347    .focus()
71348    .val(target.find("div.exam-name").text())
71349    .popover("hide");
71350  $("input.exam-search-value")
71351    .val(target.find("div.exam-id").text())
71352    .trigger("change");
71353  if (input.data("submit-target")) {
71354    $($(input).data("submit-target")).removeAttr("disabled");
71355  }
71356  var exam_id = target.find("div.exam-id").text();
71357  var school_id = $(".exam-search").data("scope-id");
71358
71359  location.href = "/admin/schools/" + school_id + "/exams/" + exam_id;
71360}
71361
71362$(document).ready(function() {
71363  $("input.exam-search").each(function(index, input) {
71364    $(input).attr("autocomplete", "off");
71365    $(input).popover({
71366      animation: false,
71367      content: function() {
71368        return $("#select-exam").html();
71369      },
71370      html: true,
71371      placement: "bottom",
71372      trigger: "manual"
71373    });
71374  });
71375});
71376
71377$(document)
71378  .off("click", ".select-exam-button")
71379  .on("click", ".select-exam-button", function() {
71380    select_exam($(this));
71381  });
71382
71383$(document).on("mouseenter", ".select-exam-button", function() {
71384  $(".select-exam-button.selected").removeClass("selected");
71385  $(this).addClass("selected");
71386});
71387
71388$(document).on("keypress", ".exam-search", function(event) {
71389  if (event.which == 13) {
71390    var selected = $(".select-exam-button.selected");
71391    if (selected.length == 0) return;
71392    select_exam(selected);
71393    return false;
71394  }
71395});
71396
71397$(document).on("focus", ".exam-search", function(event) {
71398  if ($(this).data("selected")) {
71399    $(this).data("selected", false);
71400    return;
71401  }
71402  if ($(this).val()) {
71403    $(".exam-search-input").val($(this).val());
71404    $("input.exam-email").val($(this).val());
71405    var option = "";
71406    [
71407      "excepts",
71408      "scope-type",
71409      "scope-id",
71410      "scope-ids",
71411      "except-scope-type",
71412      "except-scope-id",
71413      "type",
71414      "except-scope-ids"
71415    ].forEach(function(option_type) {
71416      if ($(event.target).data(option_type))
71417        option +=
71418          "&" +
71419          option_type.replace(/-/g, "_") +
71420          "=" +
71421          $(event.target).data(option_type);
71422    });
71423    var school_id = $(event.target).data("scope-id");
71424    $.get(
71425      "/admin/schools/" +
71426        school_id +
71427        "/exams.js?search=" +
71428        encodeURIComponent($(this).val()) +
71429        "&form_id=" +
71430        $(this)[0].id +
71431        option
71432    );
71433  }
71434});
71435
71436$(document).on("keyup", ".exam-search", function(event) {
71437  if (event.which == 27) {
71438    $(this).popover("hide");
71439  } else if (event.which == 13) {
71440    return false;
71441  } else if (
71442    event.which == 40 ||
71443    (event.which == 38 && $(".select-exam-button:visible").length > 0)
71444  ) {
71445    var selected;
71446    if (event.which == 40) {
71447      selected = $(".select-exam-button.selected").next();
71448      if (selected.length == 0)
71449        selected = $(".select-exam-button:visible:first");
71450    } else {
71451      selected = $(".select-exam-button.selected").prev();
71452      if (selected.length == 0)
71453        selected = $(".select-exam-button:visible:last");
71454    }
71455    $(".select-exam-button.selected").removeClass("selected");
71456    selected.addClass("selected");
71457  } else {
71458    if ($(this).data("submit-target"))
71459      $(this)
71460        .closest("form")
71461        .find($(this).data("submit-target"))
71462        .attr("disabled", true);
71463    $(this).trigger("focus");
71464  }
71465});
71466/*!
71467 * select2 4.0.5
71468 * https://select2.github.io
71469 *
71470 * Released under the MIT license
71471 * https://github.com/select2/select2/blob/master/LICENSE.md
71472 */
71473(function (factory) {
71474  if (typeof define === 'function' && define.amd) {
71475    // AMD. Register as an anonymous module.
71476    define(['jquery'], factory);
71477  } else if (typeof module === 'object' && module.exports) {
71478    // Node/CommonJS
71479    module.exports = function (root, jQuery) {
71480      if (jQuery === undefined) {
71481        // require('jQuery') returns a factory that requires window to
71482        // build a jQuery instance, we normalize how we use modules
71483        // that require this pattern but the window provided is a noop
71484        // if it's defined (how jquery works)
71485        if (typeof window !== 'undefined') {
71486          jQuery = require('jquery');
71487        }
71488        else {
71489          jQuery = require('jquery')(root);
71490        }
71491      }
71492      factory(jQuery);
71493      return jQuery;
71494    };
71495  } else {
71496    // Browser globals
71497    factory(jQuery);
71498  }
71499} (function (jQuery) {
71500  // This is needed so we can catch the AMD loader configuration and use it
71501  // The inner file should be wrapped (by `banner.start.js`) in a function that
71502  // returns the AMD loader references.
71503  var S2 =(function () {
71504    // Restore the select2 AMD loader so it can be used
71505    // Needed mostly in the language files, where the loader is not inserted
71506    if (jQuery && jQuery.fn && jQuery.fn.select2 && jQuery.fn.select2.amd) {
71507      var S2 = jQuery.fn.select2.amd;
71508    }
71509    var S2;(function () { if (!S2 || !S2.requirejs) {
71510      if (!S2) { S2 = {}; } else { require = S2; }
71511      /**
71512       * @license almond 0.3.3 Copyright jQuery Foundation and other contributors.
71513       * Released under MIT license, http://github.com/requirejs/almond/LICENSE
71514       */
71515//Going sloppy to avoid 'use strict' string cost, but strict practices should
71516//be followed.
71517      /*global setTimeout: false */
71518
71519      var requirejs, require, define;
71520      (function (undef) {
71521        var main, req, makeMap, handlers,
71522          defined = {},
71523          waiting = {},
71524          config = {},
71525          defining = {},
71526          hasOwn = Object.prototype.hasOwnProperty,
71527          aps = [].slice,
71528          jsSuffixRegExp = /\.js$/;
71529
71530        function hasProp(obj, prop) {
71531          return hasOwn.call(obj, prop);
71532        }
71533
71534        /**
71535         * Given a relative module name, like ./something, normalize it to
71536         * a real name that can be mapped to a path.
71537         * @param {String} name the relative name
71538         * @param {String} baseName a real name that the name arg is relative
71539         * to.
71540         * @returns {String} normalized name
71541         */
71542        function normalize(name, baseName) {
71543          var nameParts, nameSegment, mapValue, foundMap, lastIndex,
71544            foundI, foundStarMap, starI, i, j, part, normalizedBaseParts,
71545            baseParts = baseName && baseName.split("/"),
71546            map = config.map,
71547            starMap = (map && map['*']) || {};
71548
71549          //Adjust any relative paths.
71550          if (name) {
71551            name = name.split('/');
71552            lastIndex = name.length - 1;
71553
71554            // If wanting node ID compatibility, strip .js from end
71555            // of IDs. Have to do this here, and not in nameToUrl
71556            // because node allows either .js or non .js to map
71557            // to same file.
71558            if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
71559              name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
71560            }
71561
71562            // Starts with a '.' so need the baseName
71563            if (name[0].charAt(0) === '.' && baseParts) {
71564              //Convert baseName to array, and lop off the last part,
71565              //so that . matches that 'directory' and not name of the baseName's
71566              //module. For instance, baseName of 'one/two/three', maps to
71567              //'one/two/three.js', but we want the directory, 'one/two' for
71568              //this normalization.
71569              normalizedBaseParts = baseParts.slice(0, baseParts.length - 1);
71570              name = normalizedBaseParts.concat(name);
71571            }
71572
71573            //start trimDots
71574            for (i = 0; i < name.length; i++) {
71575              part = name[i];
71576              if (part === '.') {
71577                name.splice(i, 1);
71578                i -= 1;
71579              } else if (part === '..') {
71580                // If at the start, or previous value is still ..,
71581                // keep them so that when converted to a path it may
71582                // still work when converted to a path, even though
71583                // as an ID it is less than ideal. In larger point
71584                // releases, may be better to just kick out an error.
71585                if (i === 0 || (i === 1 && name[2] === '..') || name[i - 1] === '..') {
71586                  continue;
71587                } else if (i > 0) {
71588                  name.splice(i - 1, 2);
71589                  i -= 2;
71590                }
71591              }
71592            }
71593            //end trimDots
71594
71595            name = name.join('/');
71596          }
71597
71598          //Apply map config if available.
71599          if ((baseParts || starMap) && map) {
vendor: 18,153 bytes, lines 71600-72179
71600            nameParts = name.split('/');
71601
71602            for (i = nameParts.length; i > 0; i -= 1) {
71603              nameSegment = nameParts.slice(0, i).join("/");
71604
71605              if (baseParts) {
71606                //Find the longest baseName segment match in the config.
71607                //So, do joins on the biggest to smallest lengths of baseParts.
71608                for (j = baseParts.length; j > 0; j -= 1) {
71609                  mapValue = map[baseParts.slice(0, j).join('/')];
71610
71611                  //baseName segment has  config, find if it has one for
71612                  //this name.
71613                  if (mapValue) {
71614                    mapValue = mapValue[nameSegment];
71615                    if (mapValue) {
71616                      //Match, update name to the new value.
71617                      foundMap = mapValue;
71618                      foundI = i;
71619                      break;
71620                    }
71621                  }
71622                }
71623              }
71624
71625              if (foundMap) {
71626                break;
71627              }
71628
71629              //Check for a star map match, but just hold on to it,
71630              //if there is a shorter segment match later in a matching
71631              //config, then favor over this star map.
71632              if (!foundStarMap && starMap && starMap[nameSegment]) {
71633                foundStarMap = starMap[nameSegment];
71634                starI = i;
71635              }
71636            }
71637
71638            if (!foundMap && foundStarMap) {
71639              foundMap = foundStarMap;
71640              foundI = starI;
71641            }
71642
71643            if (foundMap) {
71644              nameParts.splice(0, foundI, foundMap);
71645              name = nameParts.join('/');
71646            }
71647          }
71648
71649          return name;
71650        }
71651
71652        function makeRequire(relName, forceSync) {
71653          return function () {
71654            //A version of a require function that passes a moduleName
71655            //value for items that may need to
71656            //look up paths relative to the moduleName
71657            var args = aps.call(arguments, 0);
71658
71659            //If first arg is not require('string'), and there is only
71660            //one arg, it is the array form without a callback. Insert
71661            //a null so that the following concat is correct.
71662            if (typeof args[0] !== 'string' && args.length === 1) {
71663              args.push(null);
71664            }
71665            return req.apply(undef, args.concat([relName, forceSync]));
71666          };
71667        }
71668
71669        function makeNormalize(relName) {
71670          return function (name) {
71671            return normalize(name, relName);
71672          };
71673        }
71674
71675        function makeLoad(depName) {
71676          return function (value) {
71677            defined[depName] = value;
71678          };
71679        }
71680
71681        function callDep(name) {
71682          if (hasProp(waiting, name)) {
71683            var args = waiting[name];
71684            delete waiting[name];
71685            defining[name] = true;
71686            main.apply(undef, args);
71687          }
71688
71689          if (!hasProp(defined, name) && !hasProp(defining, name)) {
71690            throw new Error('No ' + name);
71691          }
71692          return defined[name];
71693        }
71694
71695        //Turns a plugin!resource to [plugin, resource]
71696        //with the plugin being undefined if the name
71697        //did not have a plugin prefix.
71698        function splitPrefix(name) {
71699          var prefix,
71700            index = name ? name.indexOf('!') : -1;
71701          if (index > -1) {
71702            prefix = name.substring(0, index);
71703            name = name.substring(index + 1, name.length);
71704          }
71705          return [prefix, name];
71706        }
71707
71708        //Creates a parts array for a relName where first part is plugin ID,
71709        //second part is resource ID. Assumes relName has already been normalized.
71710        function makeRelParts(relName) {
71711          return relName ? splitPrefix(relName) : [];
71712        }
71713
71714        /**
71715         * Makes a name map, normalizing the name, and using a plugin
71716         * for normalization if necessary. Grabs a ref to plugin
71717         * too, as an optimization.
71718         */
71719        makeMap = function (name, relParts) {
71720          var plugin,
71721            parts = splitPrefix(name),
71722            prefix = parts[0],
71723            relResourceName = relParts[1];
71724
71725          name = parts[1];
71726
71727          if (prefix) {
71728            prefix = normalize(prefix, relResourceName);
71729            plugin = callDep(prefix);
71730          }
71731
71732          //Normalize according
71733          if (prefix) {
71734            if (plugin && plugin.normalize) {
71735              name = plugin.normalize(name, makeNormalize(relResourceName));
71736            } else {
71737              name = normalize(name, relResourceName);
71738            }
71739          } else {
71740            name = normalize(name, relResourceName);
71741            parts = splitPrefix(name);
71742            prefix = parts[0];
71743            name = parts[1];
71744            if (prefix) {
71745              plugin = callDep(prefix);
71746            }
71747          }
71748
71749          //Using ridiculous property names for space reasons
71750          return {
71751            f: prefix ? prefix + '!' + name : name, //fullName
71752            n: name,
71753            pr: prefix,
71754            p: plugin
71755          };
71756        };
71757
71758        function makeConfig(name) {
71759          return function () {
71760            return (config && config.config && config.config[name]) || {};
71761          };
71762        }
71763
71764        handlers = {
71765          require: function (name) {
71766            return makeRequire(name);
71767          },
71768          exports: function (name) {
71769            var e = defined[name];
71770            if (typeof e !== 'undefined') {
71771              return e;
71772            } else {
71773              return (defined[name] = {});
71774            }
71775          },
71776          module: function (name) {
71777            return {
71778              id: name,
71779              uri: '',
71780              exports: defined[name],
71781              config: makeConfig(name)
71782            };
71783          }
71784        };
71785
71786        main = function (name, deps, callback, relName) {
71787          var cjsModule, depName, ret, map, i, relParts,
71788            args = [],
71789            callbackType = typeof callback,
71790            usingExports;
71791
71792          //Use name if no relName
71793          relName = relName || name;
71794          relParts = makeRelParts(relName);
71795
71796          //Call the callback to define the module, if necessary.
71797          if (callbackType === 'undefined' || callbackType === 'function') {
71798            //Pull out the defined dependencies and pass the ordered
71799            //values to the callback.
71800            //Default to [require, exports, module] if no deps
71801            deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;
71802            for (i = 0; i < deps.length; i += 1) {
71803              map = makeMap(deps[i], relParts);
71804              depName = map.f;
71805
71806              //Fast path CommonJS standard dependencies.
71807              if (depName === "require") {
71808                args[i] = handlers.require(name);
71809              } else if (depName === "exports") {
71810                //CommonJS module spec 1.1
71811                args[i] = handlers.exports(name);
71812                usingExports = true;
71813              } else if (depName === "module") {
71814                //CommonJS module spec 1.1
71815                cjsModule = args[i] = handlers.module(name);
71816              } else if (hasProp(defined, depName) ||
71817                hasProp(waiting, depName) ||
71818                hasProp(defining, depName)) {
71819                args[i] = callDep(depName);
71820              } else if (map.p) {
71821                map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});
71822                args[i] = defined[depName];
71823              } else {
71824                throw new Error(name + ' missing ' + depName);
71825              }
71826            }
71827
71828            ret = callback ? callback.apply(defined[name], args) : undefined;
71829
71830            if (name) {
71831              //If setting exports via "module" is in play,
71832              //favor that over return value and exports. After that,
71833              //favor a non-undefined return value over exports use.
71834              if (cjsModule && cjsModule.exports !== undef &&
71835                cjsModule.exports !== defined[name]) {
71836                defined[name] = cjsModule.exports;
71837              } else if (ret !== undef || !usingExports) {
71838                //Use the return value from the function.
71839                defined[name] = ret;
71840              }
71841            }
71842          } else if (name) {
71843            //May just be an object definition for the module. Only
71844            //worry about defining if have a module name.
71845            defined[name] = callback;
71846          }
71847        };
71848
71849        requirejs = require = req = function (deps, callback, relName, forceSync, alt) {
71850          if (typeof deps === "string") {
71851            if (handlers[deps]) {
71852              //callback in this case is really relName
71853              return handlers[deps](callback);
71854            }
71855            //Just return the module wanted. In this scenario, the
71856            //deps arg is the module name, and second arg (if passed)
71857            //is just the relName.
71858            //Normalize module name, if it contains . or ..
71859            return callDep(makeMap(deps, makeRelParts(callback)).f);
71860          } else if (!deps.splice) {
71861            //deps is a config object, not an array.
71862            config = deps;
71863            if (config.deps) {
71864              req(config.deps, config.callback);
71865            }
71866            if (!callback) {
71867              return;
71868            }
71869
71870            if (callback.splice) {
71871              //callback is an array, which means it is a dependency list.
71872              //Adjust args if there are dependencies
71873              deps = callback;
71874              callback = relName;
71875              relName = null;
71876            } else {
71877              deps = undef;
71878            }
71879          }
71880
71881          //Support require(['a'])
71882          callback = callback || function () {};
71883
71884          //If relName is a function, it is an errback handler,
71885          //so remove it.
71886          if (typeof relName === 'function') {
71887            relName = forceSync;
71888            forceSync = alt;
71889          }
71890
71891          //Simulate async callback;
71892          if (forceSync) {
71893            main(undef, deps, callback, relName);
71894          } else {
71895            //Using a non-zero value because of concern for what old browsers
71896            //do, and latest browsers "upgrade" to 4 if lower value is used:
71897            //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout:
71898            //If want a value immediately, use require('id') instead -- something
71899            //that works in almond on the global level, but not guaranteed and
71900            //unlikely to work in other AMD implementations.
71901            setTimeout(function () {
71902              main(undef, deps, callback, relName);
71903            }, 4);
71904          }
71905
71906          return req;
71907        };
71908
71909        /**
71910         * Just drops the config on the floor, but returns req in case
71911         * the config return value is used.
71912         */
71913        req.config = function (cfg) {
71914          return req(cfg);
71915        };
71916
71917        /**
71918         * Expose module registry for debugging and tooling
71919         */
71920        requirejs._defined = defined;
71921
71922        define = function (name, deps, callback) {
71923          if (typeof name !== 'string') {
71924            throw new Error('See almond README: incorrect module build, no module name');
71925          }
71926
71927          //This module may not have dependencies
71928          if (!deps.splice) {
71929            //deps is not an array, so probably means
71930            //an object literal or factory function for
71931            //the value. Adjust args.
71932            callback = deps;
71933            deps = [];
71934          }
71935
71936          if (!hasProp(defined, name) && !hasProp(waiting, name)) {
71937            waiting[name] = [name, deps, callback];
71938          }
71939        };
71940
71941        define.amd = {
71942          jQuery: true
71943        };
71944      }());
71945
71946      S2.requirejs = requirejs;S2.require = require;S2.define = define;
71947    }
71948    }());
71949    S2.define("almond", function(){});
71950
71951    /* global jQuery:false, $:false */
71952    S2.define('jquery',[],function () {
71953      var _$ = jQuery || $;
71954
71955      if (_$ == null && console && console.error) {
71956        console.error(
71957          'select2: An instance of jQuery or a jQuery-compatible library was not ' +
71958          'found. Make sure that you are including jQuery before select2 on your ' +
71959          'web page.'
71960        );
71961      }
71962
71963      return _$;
71964    });
71965
71966    S2.define('select2/utils',[
71967      'jquery'
71968    ], function ($) {
71969      var Utils = {};
71970
71971      Utils.Extend = function (ChildClass, SuperClass) {
71972        var __hasProp = {}.hasOwnProperty;
71973
71974        function BaseConstructor () {
71975          this.constructor = ChildClass;
71976        }
71977
71978        for (var key in SuperClass) {
71979          if (__hasProp.call(SuperClass, key)) {
71980            ChildClass[key] = SuperClass[key];
71981          }
71982        }
71983
71984        BaseConstructor.prototype = SuperClass.prototype;
71985        ChildClass.prototype = new BaseConstructor();
71986        ChildClass.__super__ = SuperClass.prototype;
71987
71988        return ChildClass;
71989      };
71990
71991      function getMethods (theClass) {
71992        var proto = theClass.prototype;
71993
71994        var methods = [];
71995
71996        for (var methodName in proto) {
71997          var m = proto[methodName];
71998
71999          if (typeof m !== 'function') {
72000            continue;
72001          }
72002
72003          if (methodName === 'constructor') {
72004            continue;
72005          }
72006
72007          methods.push(methodName);
72008        }
72009
72010        return methods;
72011      }
72012
72013      Utils.Decorate = function (SuperClass, DecoratorClass) {
72014        var decoratedMethods = getMethods(DecoratorClass);
72015        var superMethods = getMethods(SuperClass);
72016
72017        function DecoratedClass () {
72018          var unshift = Array.prototype.unshift;
72019
72020          var argCount = DecoratorClass.prototype.constructor.length;
72021
72022          var calledConstructor = SuperClass.prototype.constructor;
72023
72024          if (argCount > 0) {
72025            unshift.call(arguments, SuperClass.prototype.constructor);
72026
72027            calledConstructor = DecoratorClass.prototype.constructor;
72028          }
72029
72030          calledConstructor.apply(this, arguments);
72031        }
72032
72033        DecoratorClass.displayName = SuperClass.displayName;
72034
72035        function ctr () {
72036          this.constructor = DecoratedClass;
72037        }
72038
72039        DecoratedClass.prototype = new ctr();
72040
72041        for (var m = 0; m < superMethods.length; m++) {
72042          var superMethod = superMethods[m];
72043
72044          DecoratedClass.prototype[superMethod] =
72045            SuperClass.prototype[superMethod];
72046        }
72047
72048        var calledMethod = function (methodName) {
72049          // Stub out the original method if it's not decorating an actual method
72050          var originalMethod = function () {};
72051
72052          if (methodName in DecoratedClass.prototype) {
72053            originalMethod = DecoratedClass.prototype[methodName];
72054          }
72055
72056          var decoratedMethod = DecoratorClass.prototype[methodName];
72057
72058          return function () {
72059            var unshift = Array.prototype.unshift;
72060
72061            unshift.call(arguments, originalMethod);
72062
72063            return decoratedMethod.apply(this, arguments);
72064          };
72065        };
72066
72067        for (var d = 0; d < decoratedMethods.length; d++) {
72068          var decoratedMethod = decoratedMethods[d];
72069
72070          DecoratedClass.prototype[decoratedMethod] = calledMethod(decoratedMethod);
72071        }
72072
72073        return DecoratedClass;
72074      };
72075
72076      var Observable = function () {
72077        this.listeners = {};
72078      };
72079
72080      Observable.prototype.on = function (event, callback) {
72081        this.listeners = this.listeners || {};
72082
72083        if (event in this.listeners) {
72084          this.listeners[event].push(callback);
72085        } else {
72086          this.listeners[event] = [callback];
72087        }
72088      };
72089
72090      Observable.prototype.trigger = function (event) {
72091        var slice = Array.prototype.slice;
72092        var params = slice.call(arguments, 1);
72093
72094        this.listeners = this.listeners || {};
72095
72096        // Params should always come in as an array
72097        if (params == null) {
72098          params = [];
72099        }
72100
72101        // If there are no arguments to the event, use a temporary object
72102        if (params.length === 0) {
72103          params.push({});
72104        }
72105
72106        // Set the `_type` of the first object to the event
72107        params[0]._type = event;
72108
72109        if (event in this.listeners) {
72110          this.invoke(this.listeners[event], slice.call(arguments, 1));
72111        }
72112
72113        if ('*' in this.listeners) {
72114          this.invoke(this.listeners['*'], arguments);
72115        }
72116      };
72117
72118      Observable.prototype.invoke = function (listeners, params) {
72119        for (var i = 0, len = listeners.length; i < len; i++) {
72120          listeners[i].apply(this, params);
72121        }
72122      };
72123
72124      Utils.Observable = Observable;
72125
72126      Utils.generateChars = function (length) {
72127        var chars = '';
72128
72129        for (var i = 0; i < length; i++) {
72130          var randomChar = Math.floor(Math.random() * 36);
72131          chars += randomChar.toString(36);
72132        }
72133
72134        return chars;
72135      };
72136
72137      Utils.bind = function (func, context) {
72138        return function () {
72139          func.apply(context, arguments);
72140        };
72141      };
72142
72143      Utils._convertData = function (data) {
72144        for (var originalKey in data) {
72145          var keys = originalKey.split('-');
72146
72147          var dataLevel = data;
72148
72149          if (keys.length === 1) {
72150            continue;
72151          }
72152
72153          for (var k = 0; k < keys.length; k++) {
72154            var key = keys[k];
72155
72156            // Lowercase the first letter
72157            // By default, dash-separated becomes camelCase
72158            key = key.substring(0, 1).toLowerCase() + key.substring(1);
72159
72160            if (!(key in dataLevel)) {
72161              dataLevel[key] = {};
72162            }
72163
72164            if (k == keys.length - 1) {
72165              dataLevel[key] = data[originalKey];
72166            }
72167
72168            dataLevel = dataLevel[key];
72169          }
72170
72171          delete data[originalKey];
72172        }
72173
72174        return data;
72175      };
72176
72177      Utils.hasScroll = function (index, el) {
72178        // Adapted from the function created by @ShadowScripter
72179        // and adapted by @BillBarry on the Stack Exchange Code Review website.
72180        // The original code can be found at
72181        // http://codereview.stackexchange.com/q/13338
72182        // and was designed to be used with the Sizzle selector engine.
72183
72184        var $el = $(el);
72185        var overflowX = el.style.overflowX;
72186        var overflowY = el.style.overflowY;
72187
72188        //Check both x and y declarations
72189        if (overflowX === overflowY &&
72190          (overflowY === 'hidden' || overflowY === 'visible')) {
72191          return false;
72192        }
72193
72194        if (overflowX === 'scroll' || overflowY === 'scroll') {
72195          return true;
72196        }
72197
72198        return ($el.innerHeight() < el.scrollHeight ||
72199          $el.innerWidth() < el.scrollWidth);
72200      };
72201
72202      Utils.escapeMarkup = function (markup) {
72203        var replaceMap = {
72204          '\\': '&#92;',
72205          '&': '&amp;',
72206          '<': '&lt;',
72207          '>': '&gt;',
72208          '"': '&quot;',
72209          '\'': '&#39;',
72210          '/': '&#47;'
72211        };
72212
72213        // Do not try to escape the markup if it's not a string
72214        if (typeof markup !== 'string') {
72215          return markup;
72216        }
72217
72218        return String(markup).replace(/[&<>"'\/\\]/g, function (match) {
72219          return replaceMap[match];
72220        });
72221      };
72222
72223      // Append an array of jQuery nodes to a given element.
72224      Utils.appendMany = function ($element, $nodes) {
72225        // jQuery 1.7.x does not support $.fn.append() with an array
72226        // Fall back to a jQuery object collection using $.fn.add()
72227        if ($.fn.jquery.substr(0, 3) === '1.7') {
72228          var $jqNodes = $();
72229
72230          $.map($nodes, function (node) {
72231            $jqNodes = $jqNodes.add(node);
72232          });
72233
72234          $nodes = $jqNodes;
72235        }
72236
72237        $element.append($nodes);
72238      };
72239
72240      return Utils;
72241    });
72242
72243    S2.define('select2/results',[
72244      'jquery',
72245      './utils'
72246    ], function ($, Utils) {
72247      function Results ($element, options, dataAdapter) {
72248        this.$element = $element;
72249        this.data = dataAdapter;
72250        this.options = options;
72251
72252        Results.__super__.constructor.call(this);
72253      }
72254
72255      Utils.Extend(Results, Utils.Observable);
72256
72257      Results.prototype.render = function () {
72258        var $results = $(
72259          '<ul class="select2-results__options" role="tree"></ul>'
72260        );
72261
72262        if (this.options.get('multiple')) {
72263          $results.attr('aria-multiselectable', 'true');
72264        }
72265
72266        this.$results = $results;
72267
72268        return $results;
72269      };
72270
72271      Results.prototype.clear = function () {
72272        this.$results.empty();
72273      };
72274
72275      Results.prototype.displayMessage = function (params) {
72276        var escapeMarkup = this.options.get('escapeMarkup');
72277
72278        this.clear();
72279        this.hideLoading();
72280
72281        var $message = $(
72282          '<li role="treeitem" aria-live="assertive"' +
72283          ' class="select2-results__option"></li>'
72284        );
72285
72286        var message = this.options.get('translations').get(params.message);
72287
72288        $message.append(
72289          escapeMarkup(
72290            message(params.args)
72291          )
72292        );
72293
72294        $message[0].className += ' select2-results__message';
72295
72296        this.$results.append($message);
72297      };
72298
72299      Results.prototype.hideMessages = function () {
72300        this.$results.find('.select2-results__message').remove();
72301      };
72302
72303      Results.prototype.append = function (data) {
72304        this.hideLoading();
72305
72306        var $options = [];
72307
72308        if (data.results == null || data.results.length === 0) {
72309          if (this.$results.children().length === 0) {
72310            this.trigger('results:message', {
72311              message: 'noResults'
72312            });
72313          }
72314
72315          return;
72316        }
72317
72318        data.results = this.sort(data.results);
72319
72320        for (var d = 0; d < data.results.length; d++) {
72321          var item = data.results[d];
72322
72323          var $option = this.option(item);
72324
72325          $options.push($option);
72326        }
72327
72328        this.$results.append($options);
72329      };
72330
72331      Results.prototype.position = function ($results, $dropdown) {
72332        var $resultsContainer = $dropdown.find('.select2-results');
72333        $resultsContainer.append($results);
72334      };
72335
72336      Results.prototype.sort = function (data) {
72337        var sorter = this.options.get('sorter');
72338
72339        return sorter(data);
72340      };
72341
72342      Results.prototype.highlightFirstItem = function () {
72343        var $options = this.$results
72344          .find('.select2-results__option[aria-selected]');
72345
72346        var $selected = $options.filter('[aria-selected=true]');
72347
72348        // Check if there are any selected options
72349        if ($selected.length > 0) {
72350          // If there are selected options, highlight the first
72351          $selected.first().trigger('mouseenter');
72352        } else {
72353          // If there are no selected options, highlight the first option
72354          // in the dropdown
72355          $options.first().trigger('mouseenter');
72356        }
72357
72358        this.ensureHighlightVisible();
72359      };
72360
72361      Results.prototype.setClasses = function () {
72362        var self = this;
72363
72364        this.data.current(function (selected) {
72365          var selectedIds = $.map(selected, function (s) {
72366            return s.id.toString();
72367          });
72368
72369          var $options = self.$results
72370            .find('.select2-results__option[aria-selected]');
72371
72372          $options.each(function () {
72373            var $option = $(this);
72374
72375            var item = $.data(this, 'data');
72376
72377            // id needs to be converted to a string when comparing
72378            var id = '' + item.id;
72379
72380            if ((item.element != null && item.element.selected) ||
72381              (item.element == null && $.inArray(id, selectedIds) > -1)) {
72382              $option.attr('aria-selected', 'true');
72383            } else {
72384              $option.attr('aria-selected', 'false');
72385            }
72386          });
72387
72388        });
72389      };
72390
72391      Results.prototype.showLoading = function (params) {
72392        this.hideLoading();
72393
72394        var loadingMore = this.options.get('translations').get('searching');
72395
72396        var loading = {
72397          disabled: true,
72398          loading: true,
72399          text: loadingMore(params)
72400        };
72401        var $loading = this.option(loading);
72402        $loading.className += ' loading-results';
72403
72404        this.$results.prepend($loading);
72405      };
72406
72407      Results.prototype.hideLoading = function () {
72408        this.$results.find('.loading-results').remove();
72409      };
72410
72411      Results.prototype.option = function (data) {
72412        var option = document.createElement('li');
72413        option.className = 'select2-results__option';
72414
72415        var attrs = {
72416          'role': 'treeitem',
72417          'aria-selected': 'false'
72418        };
72419
72420        if (data.disabled) {
72421          delete attrs['aria-selected'];
72422          attrs['aria-disabled'] = 'true';
72423        }
72424
72425        if (data.id == null) {
72426          delete attrs['aria-selected'];
72427        }
72428
72429        if (data._resultId != null) {
72430          option.id = data._resultId;
72431        }
72432
72433        if (data.title) {
72434          option.title = data.title;
72435        }
72436
72437        if (data.children) {
72438          attrs.role = 'group';
72439          attrs['aria-label'] = data.text;
72440          delete attrs['aria-selected'];
72441        }
72442
72443        for (var attr in attrs) {
72444          var val = attrs[attr];
72445
72446          option.setAttribute(attr, val);
72447        }
72448
72449        if (data.children) {
72450          var $option = $(option);
72451
72452          var label = document.createElement('strong');
72453          label.className = 'select2-results__group';
72454
72455          var $label = $(label);
72456          this.template(data, label);
72457
72458          var $children = [];
72459
72460          for (var c = 0; c < data.children.length; c++) {
72461            var child = data.children[c];
72462
72463            var $child = this.option(child);
72464
72465            $children.push($child);
72466          }
72467
72468          var $childrenContainer = $('<ul></ul>', {
72469            'class': 'select2-results__options select2-results__options--nested'
72470          });
72471
72472          $childrenContainer.append($children);
72473
72474          $option.append(label);
72475          $option.append($childrenContainer);
72476        } else {
72477          this.template(data, option);
72478        }
72479
72480        $.data(option, 'data', data);
72481
72482        return option;
72483      };
72484
72485      Results.prototype.bind = function (container, $container) {
72486        var self = this;
72487
72488        var id = container.id + '-results';
72489
72490        this.$results.attr('id', id);
72491
72492        container.on('results:all', function (params) {
72493          self.clear();
72494          self.append(params.data);
72495
72496          if (container.isOpen()) {
72497            self.setClasses();
72498            self.highlightFirstItem();
72499          }
72500        });
72501
72502        container.on('results:append', function (params) {
72503          self.append(params.data);
72504
72505          if (container.isOpen()) {
72506            self.setClasses();
72507          }
72508        });
72509
72510        container.on('query', function (params) {
72511          self.hideMessages();
72512          // self.showLoading(params);
72513        });
72514
72515        container.on('select', function () {
72516          if (!container.isOpen()) {
72517            return;
72518          }
72519
72520          self.setClasses();
72521          // self.highlightFirstItem();
72522        });
72523
72524        container.on('unselect', function () {
72525          if (!container.isOpen()) {
72526            return;
72527          }
72528
72529          self.setClasses();
72530          // self.highlightFirstItem();
72531        });
72532
72533        container.on('open', function () {
72534          // When the dropdown is open, aria-expended="true"
72535          self.$results.attr('aria-expanded', 'true');
72536          self.$results.attr('aria-hidden', 'false');
72537
72538          self.setClasses();
72539          self.ensureHighlightVisible();
72540        });
72541
72542        container.on('close', function () {
72543          // When the dropdown is closed, aria-expended="false"
72544          self.$results.attr('aria-expanded', 'false');
72545          self.$results.attr('aria-hidden', 'true');
72546          self.$results.removeAttr('aria-activedescendant');
72547        });
72548
72549        container.on('results:toggle', function () {
72550          var $highlighted = self.getHighlightedResults();
72551
72552          if ($highlighted.length === 0) {
72553            return;
72554          }
72555
72556          $highlighted.trigger('mouseup');
72557        });
72558
72559        container.on('results:select', function () {
72560          var $highlighted = self.getHighlightedResults();
72561
72562          if ($highlighted.length === 0) {
72563            return;
72564          }
72565
72566          var data = $highlighted.data('data');
72567
72568          if ($highlighted.attr('aria-selected') == 'true') {
72569            self.trigger('close', {});
72570          } else {
72571            self.trigger('select', {
72572              data: data
72573            });
72574          }
72575        });
72576
72577        container.on('results:previous', function () {
72578          var $highlighted = self.getHighlightedResults();
72579
72580          var $options = self.$results.find('[aria-selected]');
72581
72582          var currentIndex = $options.index($highlighted);
72583
72584          // If we are already at te top, don't move further
72585          if (currentIndex === 0) {
72586            return;
72587          }
72588
72589          var nextIndex = currentIndex - 1;
72590
72591          // If none are highlighted, highlight the first
72592          if ($highlighted.length === 0) {
72593            nextIndex = 0;
72594          }
72595
72596          var $next = $options.eq(nextIndex);
72597
72598          $next.trigger('mouseenter');
72599
72600          var currentOffset = self.$results.offset().top;
72601          var nextTop = $next.offset().top;
72602          var nextOffset = self.$results.scrollTop() + (nextTop - currentOffset);
72603
72604          if (nextIndex === 0) {
72605            self.$results.scrollTop(0);
72606          } else if (nextTop - currentOffset < 0) {
72607            self.$results.scrollTop(nextOffset);
72608          }
72609        });
72610
72611        container.on('results:next', function () {
72612          var $highlighted = self.getHighlightedResults();
72613
72614          var $options = self.$results.find('[aria-selected]');
72615
72616          var currentIndex = $options.index($highlighted);
72617
72618          var nextIndex = currentIndex + 1;
72619
72620          // If we are at the last option, stay there
72621          if (nextIndex >= $options.length) {
72622            return;
72623          }
72624
72625          var $next = $options.eq(nextIndex);
72626
72627          $next.trigger('mouseenter');
72628
72629          var currentOffset = self.$results.offset().top +
72630            self.$results.outerHeight(false);
72631          var nextBottom = $next.offset().top + $next.outerHeight(false);
72632          var nextOffset = self.$results.scrollTop() + nextBottom - currentOffset;
72633
72634          if (nextIndex === 0) {
72635            self.$results.scrollTop(0);
72636          } else if (nextBottom > currentOffset) {
72637            self.$results.scrollTop(nextOffset);
72638          }
72639        });
72640
72641        container.on('results:focus', function (params) {
72642          params.element.addClass('select2-results__option--highlighted');
72643        });
72644
72645        container.on('results:message', function (params) {
vendor: 16,384 bytes, lines 72646-73225
72646          self.displayMessage(params);
72647        });
72648
72649        if ($.fn.mousewheel) {
72650          this.$results.on('mousewheel', function (e) {
72651            var top = self.$results.scrollTop();
72652
72653            var bottom = self.$results.get(0).scrollHeight - top + e.deltaY;
72654
72655            var isAtTop = e.deltaY > 0 && top - e.deltaY <= 0;
72656            var isAtBottom = e.deltaY < 0 && bottom <= self.$results.height();
72657
72658            if (isAtTop) {
72659              self.$results.scrollTop(0);
72660
72661              e.preventDefault();
72662              e.stopPropagation();
72663            } else if (isAtBottom) {
72664              self.$results.scrollTop(
72665                self.$results.get(0).scrollHeight - self.$results.height()
72666              );
72667
72668              e.preventDefault();
72669              e.stopPropagation();
72670            }
72671          });
72672        }
72673
72674        this.$results.on('mouseup', '.select2-results__option[aria-selected]',
72675          function (evt) {
72676            var $this = $(this);
72677
72678            var data = $this.data('data');
72679
72680            if ($this.attr('aria-selected') === 'true') {
72681              if (self.options.get('multiple')) {
72682                self.trigger('unselect', {
72683                  originalEvent: evt,
72684                  data: data
72685                });
72686              } else {
72687                self.trigger('close', {});
72688              }
72689
72690              return;
72691            }
72692
72693            self.trigger('select', {
72694              originalEvent: evt,
72695              data: data
72696            });
72697          });
72698
72699        this.$results.on('mouseenter', '.select2-results__option[aria-selected]',
72700          function (evt) {
72701            var data = $(this).data('data');
72702
72703            self.getHighlightedResults()
72704              .removeClass('select2-results__option--highlighted');
72705
72706            self.trigger('results:focus', {
72707              data: data,
72708              element: $(this)
72709            });
72710          });
72711      };
72712
72713      Results.prototype.getHighlightedResults = function () {
72714        var $highlighted = this.$results
72715          .find('.select2-results__option--highlighted');
72716
72717        return $highlighted;
72718      };
72719
72720      Results.prototype.destroy = function () {
72721        this.$results.remove();
72722      };
72723
72724      Results.prototype.ensureHighlightVisible = function () {
72725        var $highlighted = this.getHighlightedResults();
72726
72727        if ($highlighted.length === 0) {
72728          return;
72729        }
72730
72731        var $options = this.$results.find('[aria-selected]');
72732
72733        var currentIndex = $options.index($highlighted);
72734
72735        var currentOffset = this.$results.offset().top;
72736        var nextTop = $highlighted.offset().top;
72737        var nextOffset = this.$results.scrollTop() + (nextTop - currentOffset);
72738
72739        var offsetDelta = nextTop - currentOffset;
72740        nextOffset -= $highlighted.outerHeight(false) * 2;
72741
72742        if (currentIndex <= 2) {
72743          this.$results.scrollTop(0);
72744        } else if (offsetDelta > this.$results.outerHeight() || offsetDelta < 0) {
72745          this.$results.scrollTop(nextOffset);
72746        }
72747      };
72748
72749      Results.prototype.template = function (result, container) {
72750        var template = this.options.get('templateResult');
72751        var escapeMarkup = this.options.get('escapeMarkup');
72752
72753        var content = template(result, container);
72754
72755        if (content == null) {
72756          container.style.display = 'none';
72757        } else if (typeof content === 'string') {
72758          container.innerHTML = escapeMarkup(content);
72759        } else {
72760          $(container).append(content);
72761        }
72762      };
72763
72764      return Results;
72765    });
72766
72767    S2.define('select2/keys',[
72768
72769    ], function () {
72770      var KEYS = {
72771        BACKSPACE: 8,
72772        TAB: 9,
72773        ENTER: 13,
72774        SHIFT: 16,
72775        CTRL: 17,
72776        ALT: 18,
72777        ESC: 27,
72778        SPACE: 32,
72779        PAGE_UP: 33,
72780        PAGE_DOWN: 34,
72781        END: 35,
72782        HOME: 36,
72783        LEFT: 37,
72784        UP: 38,
72785        RIGHT: 39,
72786        DOWN: 40,
72787        DELETE: 46
72788      };
72789
72790      return KEYS;
72791    });
72792
72793    S2.define('select2/selection/base',[
72794      'jquery',
72795      '../utils',
72796      '../keys'
72797    ], function ($, Utils, KEYS) {
72798      function BaseSelection ($element, options) {
72799        this.$element = $element;
72800        this.options = options;
72801
72802        BaseSelection.__super__.constructor.call(this);
72803      }
72804
72805      Utils.Extend(BaseSelection, Utils.Observable);
72806
72807      BaseSelection.prototype.render = function () {
72808        var $selection = $(
72809          '<span class="select2-selection" role="combobox" ' +
72810          ' aria-haspopup="true" aria-expanded="false">' +
72811          '</span>'
72812        );
72813
72814        this._tabindex = 0;
72815
72816        if (this.$element.data('old-tabindex') != null) {
72817          this._tabindex = this.$element.data('old-tabindex');
72818        } else if (this.$element.attr('tabindex') != null) {
72819          this._tabindex = this.$element.attr('tabindex');
72820        }
72821
72822        $selection.attr('title', this.$element.attr('title'));
72823        $selection.attr('tabindex', this._tabindex);
72824
72825        this.$selection = $selection;
72826
72827        return $selection;
72828      };
72829
72830      BaseSelection.prototype.bind = function (container, $container) {
72831        var self = this;
72832
72833        var id = container.id + '-container';
72834        var resultsId = container.id + '-results';
72835
72836        this.container = container;
72837
72838        this.$selection.on('focus', function (evt) {
72839          self.trigger('focus', evt);
72840        });
72841
72842        this.$selection.on('blur', function (evt) {
72843          self._handleBlur(evt);
72844        });
72845
72846        this.$selection.on('keydown', function (evt) {
72847          self.trigger('keypress', evt);
72848
72849          if (evt.which === KEYS.SPACE) {
72850            evt.preventDefault();
72851          }
72852        });
72853
72854        container.on('results:focus', function (params) {
72855          self.$selection.attr('aria-activedescendant', params.data._resultId);
72856        });
72857
72858        container.on('selection:update', function (params) {
72859          self.update(params.data);
72860        });
72861
72862        container.on('open', function () {
72863          // When the dropdown is open, aria-expanded="true"
72864          self.$selection.attr('aria-expanded', 'true');
72865          self.$selection.attr('aria-owns', resultsId);
72866
72867          self._attachCloseHandler(container);
72868        });
72869
72870        container.on('close', function () {
72871          // When the dropdown is closed, aria-expanded="false"
72872          self.$selection.attr('aria-expanded', 'false');
72873          self.$selection.removeAttr('aria-activedescendant');
72874          self.$selection.removeAttr('aria-owns');
72875
72876          self.$selection.focus();
72877
72878          self._detachCloseHandler(container);
72879        });
72880
72881        container.on('enable', function () {
72882          self.$selection.attr('tabindex', self._tabindex);
72883        });
72884
72885        container.on('disable', function () {
72886          self.$selection.attr('tabindex', '-1');
72887        });
72888      };
72889
72890      BaseSelection.prototype._handleBlur = function (evt) {
72891        var self = this;
72892
72893        // This needs to be delayed as the active element is the body when the tab
72894        // key is pressed, possibly along with others.
72895        window.setTimeout(function () {
72896          // Don't trigger `blur` if the focus is still in the selection
72897          if (
72898            (document.activeElement == self.$selection[0]) ||
72899            ($.contains(self.$selection[0], document.activeElement))
72900          ) {
72901            return;
72902          }
72903
72904          self.trigger('blur', evt);
72905        }, 1);
72906      };
72907
72908      BaseSelection.prototype._attachCloseHandler = function (container) {
72909        var self = this;
72910
72911        $(document.body).on('mousedown.select2.' + container.id, function (e) {
72912          var $target = $(e.target);
72913
72914          var $select = $target.closest('.select2');
72915
72916          var $all = $('.select2.select2-container--open');
72917
72918          $all.each(function () {
72919            var $this = $(this);
72920
72921            if (this == $select[0]) {
72922              return;
72923            }
72924
72925            var $element = $this.data('element');
72926
72927            $element.select2('close');
72928          });
72929        });
72930      };
72931
72932      BaseSelection.prototype._detachCloseHandler = function (container) {
72933        $(document.body).off('mousedown.select2.' + container.id);
72934      };
72935
72936      BaseSelection.prototype.position = function ($selection, $container) {
72937        var $selectionContainer = $container.find('.selection');
72938        $selectionContainer.append($selection);
72939      };
72940
72941      BaseSelection.prototype.destroy = function () {
72942        this._detachCloseHandler(this.container);
72943      };
72944
72945      BaseSelection.prototype.update = function (data) {
72946        throw new Error('The `update` method must be defined in child classes.');
72947      };
72948
72949      return BaseSelection;
72950    });
72951
72952    S2.define('select2/selection/single',[
72953      'jquery',
72954      './base',
72955      '../utils',
72956      '../keys'
72957    ], function ($, BaseSelection, Utils, KEYS) {
72958      function SingleSelection () {
72959        SingleSelection.__super__.constructor.apply(this, arguments);
72960      }
72961
72962      Utils.Extend(SingleSelection, BaseSelection);
72963
72964      SingleSelection.prototype.render = function () {
72965
72966        var $selection = SingleSelection.__super__.render.call(this);
72967
72968        $selection.addClass('select2-selection--single');
72969
72970        $selection.html(
72971          '<span class="select2-selection__rendered"></span>' +
72972          '<span class="select2-selection__arrow" role="presentation">' +
72973          '<b role="presentation"></b>' +
72974          '</span>'
72975        );
72976
72977        return $selection;
72978      };
72979
72980      SingleSelection.prototype.bind = function (container, $container) {
72981        var self = this;
72982
72983        SingleSelection.__super__.bind.apply(this, arguments);
72984
72985        var id = container.id + '-container';
72986
72987        this.$selection.find('.select2-selection__rendered').attr('id', id);
72988        this.$selection.attr('aria-labelledby', id);
72989
72990        this.$selection.on('mousedown', function (evt) {
72991          // Only respond to left clicks
72992          if (evt.which !== 1) {
72993            return;
72994          }
72995
72996          self.trigger('toggle', {
72997            originalEvent: evt
72998          });
72999        });
73000
73001        this.$selection.on('focus', function (evt) {
73002          // User focuses on the container
73003        });
73004
73005        this.$selection.on('blur', function (evt) {
73006          // User exits the container
73007        });
73008
73009        container.on('focus', function (evt) {
73010          if (!container.isOpen()) {
73011            self.$selection.focus();
73012          }
73013        });
73014
73015        container.on('selection:update', function (params) {
73016          self.update(params.data);
73017        });
73018      };
73019
73020      SingleSelection.prototype.clear = function () {
73021        this.$selection.find('.select2-selection__rendered').empty();
73022      };
73023
73024      SingleSelection.prototype.display = function (data, container) {
73025        var template = this.options.get('templateSelection');
73026        var escapeMarkup = this.options.get('escapeMarkup');
73027
73028        return escapeMarkup(template(data, container));
73029      };
73030
73031      SingleSelection.prototype.selectionContainer = function () {
73032        return $('<span></span>');
73033      };
73034
73035      SingleSelection.prototype.update = function (data) {
73036        if (data.length === 0) {
73037          this.clear();
73038          return;
73039        }
73040
73041        var selection = data[0];
73042
73043        var $rendered = this.$selection.find('.select2-selection__rendered');
73044        var formatted = this.display(selection, $rendered);
73045
73046        $rendered.empty().append(formatted);
73047        $rendered.prop('title', selection.title || selection.text);
73048      };
73049
73050      return SingleSelection;
73051    });
73052
73053    S2.define('select2/selection/multiple',[
73054      'jquery',
73055      './base',
73056      '../utils'
73057    ], function ($, BaseSelection, Utils) {
73058      function MultipleSelection ($element, options) {
73059        MultipleSelection.__super__.constructor.apply(this, arguments);
73060      }
73061
73062      Utils.Extend(MultipleSelection, BaseSelection);
73063
73064      MultipleSelection.prototype.render = function () {
73065        var $selection = MultipleSelection.__super__.render.call(this);
73066
73067        $selection.addClass('select2-selection--multiple');
73068
73069        $selection.html(
73070          '<ul class="select2-selection__rendered"></ul>'
73071        );
73072
73073        return $selection;
73074      };
73075
73076      MultipleSelection.prototype.bind = function (container, $container) {
73077        var self = this;
73078
73079        MultipleSelection.__super__.bind.apply(this, arguments);
73080
73081        this.$selection.on('click', function (evt) {
73082          self.trigger('toggle', {
73083            originalEvent: evt
73084          });
73085        });
73086
73087        this.$selection.on(
73088          'click',
73089          '.select2-selection__choice__remove',
73090          function (evt) {
73091            // Ignore the event if it is disabled
73092            if (self.options.get('disabled')) {
73093              return;
73094            }
73095
73096            var $remove = $(this);
73097            var $selection = $remove.parent();
73098
73099            var data = $selection.data('data');
73100
73101            self.trigger('unselect', {
73102              originalEvent: evt,
73103              data: data
73104            });
73105          }
73106        );
73107      };
73108
73109      MultipleSelection.prototype.clear = function () {
73110        this.$selection.find('.select2-selection__rendered').empty();
73111      };
73112
73113      MultipleSelection.prototype.display = function (data, container) {
73114        var template = this.options.get('templateSelection');
73115        var escapeMarkup = this.options.get('escapeMarkup');
73116
73117        return escapeMarkup(template(data, container));
73118      };
73119
73120      MultipleSelection.prototype.selectionContainer = function () {
73121        var $container = $(
73122          '<li class="select2-selection__choice">' +
73123          '<span class="select2-selection__choice__remove" role="presentation">' +
73124          '&times;' +
73125          '</span>' +
73126          '</li>'
73127        );
73128
73129        return $container;
73130      };
73131
73132      MultipleSelection.prototype.update = function (data) {
73133        this.clear();
73134
73135        if (data.length === 0) {
73136          return;
73137        }
73138
73139        var $selections = [];
73140
73141        for (var d = 0; d < data.length; d++) {
73142          var selection = data[d];
73143
73144          var $selection = this.selectionContainer();
73145          var formatted = this.display(selection, $selection);
73146
73147          $selection.append(formatted);
73148          $selection.prop('title', selection.title || selection.text);
73149
73150          $selection.data('data', selection);
73151
73152          $selections.push($selection);
73153        }
73154
73155        var $rendered = this.$selection.find('.select2-selection__rendered');
73156
73157        Utils.appendMany($rendered, $selections);
73158      };
73159
73160      return MultipleSelection;
73161    });
73162
73163    S2.define('select2/selection/placeholder',[
73164      '../utils'
73165    ], function (Utils) {
73166      function Placeholder (decorated, $element, options) {
73167        this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
73168
73169        decorated.call(this, $element, options);
73170      }
73171
73172      Placeholder.prototype.normalizePlaceholder = function (_, placeholder) {
73173        if (typeof placeholder === 'string') {
73174          placeholder = {
73175            id: '',
73176            text: placeholder
73177          };
73178        }
73179
73180        return placeholder;
73181      };
73182
73183      Placeholder.prototype.createPlaceholder = function (decorated, placeholder) {
73184        var $placeholder = this.selectionContainer();
73185
73186        $placeholder.html(this.display(placeholder));
73187        $placeholder.addClass('select2-selection__placeholder')
73188          .removeClass('select2-selection__choice');
73189
73190        return $placeholder;
73191      };
73192
73193      Placeholder.prototype.update = function (decorated, data) {
73194        var singlePlaceholder = (
73195          data.length == 1 && data[0].id != this.placeholder.id
73196        );
73197        var multipleSelections = data.length > 1;
73198
73199        if (multipleSelections || singlePlaceholder) {
73200          return decorated.call(this, data);
73201        }
73202
73203        this.clear();
73204
73205        var $placeholder = this.createPlaceholder(this.placeholder);
73206
73207        this.$selection.find('.select2-selection__rendered').append($placeholder);
73208      };
73209
73210      return Placeholder;
73211    });
73212
73213    S2.define('select2/selection/allowClear',[
73214      'jquery',
73215      '../keys'
73216    ], function ($, KEYS) {
73217      function AllowClear () { }
73218
73219      AllowClear.prototype.bind = function (decorated, container, $container) {
73220        var self = this;
73221
73222        decorated.call(this, container, $container);
73223
73224        if (this.placeholder == null) {
73225          if (this.options.get('deb
73225ug') && window.console && console.error) {
73226            console.error(
73227              'select2: The `allowClear` option should be used in combination ' +
73228              'with the `placeholder` option.'
73229            );
73230          }
73231        }
73232
73233        this.$selection.on('mousedown', '.select2-selection__clear',
73234          function (evt) {
73235            self._handleClear(evt);
73236          });
73237
73238        container.on('keypress', function (evt) {
73239          self._handleKeyboardClear(evt, container);
73240        });
73241      };
73242
73243      AllowClear.prototype._handleClear = function (_, evt) {
73244        // Ignore the event if it is disabled
73245        if (this.options.get('disabled')) {
73246          return;
73247        }
73248
73249        var $clear = this.$selection.find('.select2-selection__clear');
73250
73251        // Ignore the event if nothing has been selected
73252        if ($clear.length === 0) {
73253          return;
73254        }
73255
73256        evt.stopPropagation();
73257
73258        var data = $clear.data('data');
73259
73260        for (var d = 0; d < data.length; d++) {
73261          var unselectData = {
73262            data: data[d]
73263          };
73264
73265          // Trigger the `unselect` event, so people can prevent it from being
73266          // cleared.
73267          this.trigger('unselect', unselectData);
73268
73269          // If the event was prevented, don't clear it out.
73270          if (unselectData.prevented) {
73271            return;
73272          }
73273        }
73274
73275        this.$element.val(this.placeholder.id).trigger('change');
73276
73277        this.trigger('toggle', {});
73278      };
73279
73280      AllowClear.prototype._handleKeyboardClear = function (_, evt, container) {
73281        if (container.isOpen()) {
73282          return;
73283        }
73284
73285        if (evt.which == KEYS.DELETE || evt.which == KEYS.BACKSPACE) {
73286          this._handleClear(evt);
73287        }
73288      };
73289
73290      AllowClear.prototype.update = function (decorated, data) {
73291        decorated.call(this, data);
73292
73293        if (this.$selection.find('.select2-selection__placeholder').length > 0 ||
73294          data.length === 0) {
73295          return;
73296        }
73297
73298        var $remove = $(
73299          '<span class="select2-selection__clear">' +
73300          '&times;' +
73301          '</span>'
73302        );
73303        $remove.data('data', data);
73304
73305        this.$selection.find('.select2-selection__rendered').prepend($remove);
73306      };
73307
73308      return AllowClear;
73309    });
73310
73311    S2.define('select2/selection/search',[
73312      'jquery',
73313      '../utils',
73314      '../keys'
73315    ], function ($, Utils, KEYS) {
73316      function Search (decorated, $element, options) {
73317        decorated.call(this, $element, options);
73318      }
73319
73320      Search.prototype.render = function (decorated) {
73321        var $search = $(
73322          '<li class="select2-search select2-search--inline">' +
73323          '<input class="select2-search__field" type="search" tabindex="-1"' +
73324          ' autocomplete="off" autocorrect="off" autocapitalize="none"' +
73325          ' spellcheck="false" role="textbox" aria-autocomplete="list" />' +
73326          '</li>'
73327        );
73328
73329        this.$searchContainer = $search;
73330        this.$search = $search.find('input');
73331
73332        var $rendered = decorated.call(this);
73333
73334        this._transferTabIndex();
73335
73336        return $rendered;
73337      };
73338
73339      Search.prototype.bind = function (decorated, container, $container) {
73340        var self = this;
73341
73342        decorated.call(this, container, $container);
73343
73344        container.on('open', function () {
73345          self.$search.trigger('focus');
73346        });
73347
73348        container.on('close', function () {
73349          self.$search.val('');
73350          self.$search.removeAttr('aria-activedescendant');
73351          self.$search.trigger('focus');
73352        });
73353
73354        container.on('enable', function () {
73355          self.$search.prop('disabled', false);
73356
73357          self._transferTabIndex();
73358        });
73359
73360        container.on('disable', function () {
73361          self.$search.prop('disabled', true);
73362        });
73363
73364        container.on('focus', function (evt) {
73365          self.$search.trigger('focus');
73366        });
73367
73368        container.on('results:focus', function (params) {
73369          self.$search.attr('aria-activedescendant', params.id);
73370        });
73371
73372        this.$selection.on('focusin', '.select2-search--inline', function (evt) {
73373          self.trigger('focus', evt);
73374        });
73375
73376        this.$selection.on('focusout', '.select2-search--inline', function (evt) {
73377          self._handleBlur(evt);
73378        });
73379
73380        this.$selection.on('keydown', '.select2-search--inline', function (evt) {
73381          evt.stopPropagation();
73382
73383          self.trigger('keypress', evt);
73384
73385          self._keyUpPrevented = evt.isDefaultPrevented();
73386
73387          var key = evt.which;
73388
73389          if (key === KEYS.BACKSPACE && self.$search.val() === '') {
73390            var $previousChoice = self.$searchContainer
73391              .prev('.select2-selection__choice');
73392
73393            if ($previousChoice.length > 0) {
73394              var item = $previousChoice.data('data');
73395
73396              self.searchRemoveChoice(item);
73397
73398              evt.preventDefault();
73399            }
73400          }
73401        });
73402
73403        // Try to detect the IE version should the `documentMode` property that
73404        // is stored on the document. This is only implemented in IE and is
73405        // slightly cleaner than doing a user agent check.
73406        // This property is not available in Edge, but Edge also doesn't have
73407        // this bug.
73408        var msie = document.documentMode;
73409        var disableInputEvents = msie && msie <= 11;
73410
73411        // Workaround for browsers which do not support the `input` event
73412        // This will prevent double-triggering of events for browsers which support
73413        // both the `keyup` and `input` events.
73414        this.$selection.on(
73415          'input.searchcheck',
73416          '.select2-search--inline',
73417          function (evt) {
73418            // IE will trigger the `input` event when a placeholder is used on a
73419            // search box. To get around this issue, we are forced to ignore all
73420            // `input` events in IE and keep using `keyup`.
73421            if (disableInputEvents) {
73422              self.$selection.off('input.search input.searchcheck');
73423              return;
73424            }
73425
73426            // Unbind the duplicated `keyup` event
73427            self.$selection.off('keyup.search');
73428          }
73429        );
73430
73431        this.$selection.on(
73432          'keyup.search input.search',
73433          '.select2-search--inline',
73434          function (evt) {
73435            // IE will trigger the `input` event when a placeholder is used on a
73436            // search box. To get around this issue, we are forced to ignore all
73437            // `input` events in IE and keep using `keyup`.
73438            if (disableInputEvents && evt.type === 'input') {
73439              self.$selection.off('input.search input.searchcheck');
73440              return;
73441            }
73442
73443            var key = evt.which;
73444
73445            // We can freely ignore events from modifier keys
73446            if (key == KEYS.SHIFT || key == KEYS.CTRL || key == KEYS.ALT) {
73447              return;
73448            }
73449
73450            // Tabbing will be handled during the `keydown` phase
73451            if (key == KEYS.TAB) {
73452              return;
73453            }
73454
73455            self.handleSearch(evt);
73456          }
73457        );
73458      };
73459
73460      /**
73461       * This method will transfer the tabindex attribute from the rendered
73462       * selection to the search box. This allows for the search box to be used as
73463       * the primary focus instead of the selection container.
73464       *
73465       * @private
73466       */
73467      Search.prototype._transferTabIndex = function (decorated) {
73468        this.$search.attr('tabindex', this.$selection.attr('tabindex'));
73469        this.$selection.attr('tabindex', '-1');
73470      };
73471
73472      Search.prototype.createPlaceholder = function (decorated, placeholder) {
73473        this.$search.attr('placeholder', placeholder.text);
73474      };
73475
73476      Search.prototype.update = function (decorated, data) {
73477        var searchHadFocus = this.$search[0] == document.activeElement;
73478
73479        this.$search.attr('placeholder', '');
73480
73481        decorated.call(this, data);
73482
73483        if(this.options.get("hideInput") && !this.$search.attr('placeholder')){
73484          this.$searchContainer.css("display", "none")
73485        }
73486        else{
73487          this.$searchContainer.css("display", "block")
73488        }
73489
73490        this.$selection.find('.select2-selection__rendered')
73491          .append(this.$searchContainer);
73492
73493        this.resizeSearch();
73494        if (searchHadFocus) {
73495          this.$search.focus();
73496        }
73497      };
73498
73499      Search.prototype.handleSearch = function () {
73500        this.resizeSearch();
73501
73502        if (!this._keyUpPrevented) {
73503          var input = this.$search.val();
73504
73505          this.trigger('query', {
73506            term: input
73507          });
73508        }
73509
73510        this._keyUpPrevented = false;
vendor: 16,384 bytes, lines 73511-74212
73511      };
73512
73513      Search.prototype.searchRemoveChoice = function (decorated, item) {
73514        this.trigger('unselect', {
73515          data: item
73516        });
73517
73518        this.$search.val(item.text);
73519        this.handleSearch();
73520      };
73521
73522      Search.prototype.resizeSearch = function () {
73523        this.$search.css('width', '25px');
73524
73525        var width = '';
73526
73527        if (this.$search.attr('placeholder') !== '') {
73528          width = this.$selection.find('.select2-selection__rendered').innerWidth();
73529        } else {
73530          var minimumWidth = this.$search.val().length + 1;
73531
73532          width = (minimumWidth * 0.75) + 'em';
73533        }
73534
73535        this.$search.css('width', width);
73536      };
73537
73538      return Search;
73539    });
73540
73541    S2.define('select2/selection/eventRelay',[
73542      'jquery'
73543    ], function ($) {
73544      function EventRelay () { }
73545
73546      EventRelay.prototype.bind = function (decorated, container, $container) {
73547        var self = this;
73548        var relayEvents = [
73549          'open', 'opening',
73550          'close', 'closing',
73551          'select', 'selecting',
73552          'unselect', 'unselecting'
73553        ];
73554
73555        var preventableEvents = ['opening', 'closing', 'selecting', 'unselecting'];
73556
73557        decorated.call(this, container, $container);
73558
73559        container.on('*', function (name, params) {
73560          // Ignore events that should not be relayed
73561          if ($.inArray(name, relayEvents) === -1) {
73562            return;
73563          }
73564
73565          // The parameters should always be an object
73566          params = params || {};
73567
73568          // Generate the jQuery event for the select2 event
73569          var evt = $.Event('select2:' + name, {
73570            params: params
73571          });
73572
73573          self.$element.trigger(evt);
73574
73575          // Only handle preventable events if it was one
73576          if ($.inArray(name, preventableEvents) === -1) {
73577            return;
73578          }
73579
73580          params.prevented = evt.isDefaultPrevented();
73581        });
73582      };
73583
73584      return EventRelay;
73585    });
73586
73587    S2.define('select2/translation',[
73588      'jquery',
73589      'require'
73590    ], function ($, require) {
73591      function Translation (dict) {
73592        this.dict = dict || {};
73593      }
73594
73595      Translation.prototype.all = function () {
73596        return this.dict;
73597      };
73598
73599      Translation.prototype.get = function (key) {
73600        return this.dict[key];
73601      };
73602
73603      Translation.prototype.extend = function (translation) {
73604        this.dict = $.extend({}, translation.all(), this.dict);
73605      };
73606
73607      // Static functions
73608
73609      Translation._cache = {};
73610
73611      Translation.loadPath = function (path) {
73612        if (!(path in Translation._cache)) {
73613          var translations = require(path);
73614
73615          Translation._cache[path] = translations;
73616        }
73617
73618        return new Translation(Translation._cache[path]);
73619      };
73620
73621      return Translation;
73622    });
73623
73624    S2.define('select2/diacritics',[
73625
73626    ], function () {
73627      var diacritics = {
73628        '\u24B6': 'A',
73629        '\uFF21': 'A',
73630        '\u00C0': 'A',
73631        '\u00C1': 'A',
73632        '\u00C2': 'A',
73633        '\u1EA6': 'A',
73634        '\u1EA4': 'A',
73635        '\u1EAA': 'A',
73636        '\u1EA8': 'A',
73637        '\u00C3': 'A',
73638        '\u0100': 'A',
73639        '\u0102': 'A',
73640        '\u1EB0': 'A',
73641        '\u1EAE': 'A',
73642        '\u1EB4': 'A',
73643        '\u1EB2': 'A',
73644        '\u0226': 'A',
73645        '\u01E0': 'A',
73646        '\u00C4': 'A',
73647        '\u01DE': 'A',
73648        '\u1EA2': 'A',
73649        '\u00C5': 'A',
73650        '\u01FA': 'A',
73651        '\u01CD': 'A',
73652        '\u0200': 'A',
73653        '\u0202': 'A',
73654        '\u1EA0': 'A',
73655        '\u1EAC': 'A',
73656        '\u1EB6': 'A',
73657        '\u1E00': 'A',
73658        '\u0104': 'A',
73659        '\u023A': 'A',
73660        '\u2C6F': 'A',
73661        '\uA732': 'AA',
73662        '\u00C6': 'AE',
73663        '\u01FC': 'AE',
73664        '\u01E2': 'AE',
73665        '\uA734': 'AO',
73666        '\uA736': 'AU',
73667        '\uA738': 'AV',
73668        '\uA73A': 'AV',
73669        '\uA73C': 'AY',
73670        '\u24B7': 'B',
73671        '\uFF22': 'B',
73672        '\u1E02': 'B',
73673        '\u1E04': 'B',
73674        '\u1E06': 'B',
73675        '\u0243': 'B',
73676        '\u0182': 'B',
73677        '\u0181': 'B',
73678        '\u24B8': 'C',
73679        '\uFF23': 'C',
73680        '\u0106': 'C',
73681        '\u0108': 'C',
73682        '\u010A': 'C',
73683        '\u010C': 'C',
73684        '\u00C7': 'C',
73685        '\u1E08': 'C',
73686        '\u0187': 'C',
73687        '\u023B': 'C',
73688        '\uA73E': 'C',
73689        '\u24B9': 'D',
73690        '\uFF24': 'D',
73691        '\u1E0A': 'D',
73692        '\u010E': 'D',
73693        '\u1E0C': 'D',
73694        '\u1E10': 'D',
73695        '\u1E12': 'D',
73696        '\u1E0E': 'D',
73697        '\u0110': 'D',
73698        '\u018B': 'D',
73699        '\u018A': 'D',
73700        '\u0189': 'D',
73701        '\uA779': 'D',
73702        '\u01F1': 'DZ',
73703        '\u01C4': 'DZ',
73704        '\u01F2': 'Dz',
73705        '\u01C5': 'Dz',
73706        '\u24BA': 'E',
73707        '\uFF25': 'E',
73708        '\u00C8': 'E',
73709        '\u00C9': 'E',
73710        '\u00CA': 'E',
73711        '\u1EC0': 'E',
73712        '\u1EBE': 'E',
73713        '\u1EC4': 'E',
73714        '\u1EC2': 'E',
73715        '\u1EBC': 'E',
73716        '\u0112': 'E',
73717        '\u1E14': 'E',
73718        '\u1E16': 'E',
73719        '\u0114': 'E',
73720        '\u0116': 'E',
73721        '\u00CB': 'E',
73722        '\u1EBA': 'E',
73723        '\u011A': 'E',
73724        '\u0204': 'E',
73725        '\u0206': 'E',
73726        '\u1EB8': 'E',
73727        '\u1EC6': 'E',
73728        '\u0228': 'E',
73729        '\u1E1C': 'E',
73730        '\u0118': 'E',
73731        '\u1E18': 'E',
73732        '\u1E1A': 'E',
73733        '\u0190': 'E',
73734        '\u018E': 'E',
73735        '\u24BB': 'F',
73736        '\uFF26': 'F',
73737        '\u1E1E': 'F',
73738        '\u0191': 'F',
73739        '\uA77B': 'F',
73740        '\u24BC': 'G',
73741        '\uFF27': 'G',
73742        '\u01F4': 'G',
73743        '\u011C': 'G',
73744        '\u1E20': 'G',
73745        '\u011E': 'G',
73746        '\u0120': 'G',
73747        '\u01E6': 'G',
73748        '\u0122': 'G',
73749        '\u01E4': 'G',
73750        '\u0193': 'G',
73751        '\uA7A0': 'G',
73752        '\uA77D': 'G',
73753        '\uA77E': 'G',
73754        '\u24BD': 'H',
73755        '\uFF28': 'H',
73756        '\u0124': 'H',
73757        '\u1E22': 'H',
73758        '\u1E26': 'H',
73759        '\u021E': 'H',
73760        '\u1E24': 'H',
73761        '\u1E28': 'H',
73762        '\u1E2A': 'H',
73763        '\u0126': 'H',
73764        '\u2C67': 'H',
73765        '\u2C75': 'H',
73766        '\uA78D': 'H',
73767        '\u24BE': 'I',
73768        '\uFF29': 'I',
73769        '\u00CC': 'I',
73770        '\u00CD': 'I',
73771        '\u00CE': 'I',
73772        '\u0128': 'I',
73773        '\u012A': 'I',
73774        '\u012C': 'I',
73775        '\u0130': 'I',
73776        '\u00CF': 'I',
73777        '\u1E2E': 'I',
73778        '\u1EC8': 'I',
73779        '\u01CF': 'I',
73780        '\u0208': 'I',
73781        '\u020A': 'I',
73782        '\u1ECA': 'I',
73783        '\u012E': 'I',
73784        '\u1E2C': 'I',
73785        '\u0197': 'I',
73786        '\u24BF': 'J',
73787        '\uFF2A': 'J',
73788        '\u0134': 'J',
73789        '\u0248': 'J',
73790        '\u24C0': 'K',
73791        '\uFF2B': 'K',
73792        '\u1E30': 'K',
73793        '\u01E8': 'K',
73794        '\u1E32': 'K',
73795        '\u0136': 'K',
73796        '\u1E34': 'K',
73797        '\u0198': 'K',
73798        '\u2C69': 'K',
73799        '\uA740': 'K',
73800        '\uA742': 'K',
73801        '\uA744': 'K',
73802        '\uA7A2': 'K',
73803        '\u24C1': 'L',
73804        '\uFF2C': 'L',
73805        '\u013F': 'L',
73806        '\u0139': 'L',
73807        '\u013D': 'L',
73808        '\u1E36': 'L',
73809        '\u1E38': 'L',
73810        '\u013B': 'L',
73811        '\u1E3C': 'L',
73812        '\u1E3A': 'L',
73813        '\u0141': 'L',
73814        '\u023D': 'L',
73815        '\u2C62': 'L',
73816        '\u2C60': 'L',
73817        '\uA748': 'L',
73818        '\uA746': 'L',
73819        '\uA780': 'L',
73820        '\u01C7': 'LJ',
73821        '\u01C8': 'Lj',
73822        '\u24C2': 'M',
73823        '\uFF2D': 'M',
73824        '\u1E3E': 'M',
73825        '\u1E40': 'M',
73826        '\u1E42': 'M',
73827        '\u2C6E': 'M',
73828        '\u019C': 'M',
73829        '\u24C3': 'N',
73830        '\uFF2E': 'N',
73831        '\u01F8': 'N',
73832        '\u0143': 'N',
73833        '\u00D1': 'N',
73834        '\u1E44': 'N',
73835        '\u0147': 'N',
73836        '\u1E46': 'N',
73837        '\u0145': 'N',
73838        '\u1E4A': 'N',
73839        '\u1E48': 'N',
73840        '\u0220': 'N',
73841        '\u019D': 'N',
73842        '\uA790': 'N',
73843        '\uA7A4': 'N',
73844        '\u01CA': 'NJ',
73845        '\u01CB': 'Nj',
73846        '\u24C4': 'O',
73847        '\uFF2F': 'O',
73848        '\u00D2': 'O',
73849        '\u00D3': 'O',
73850        '\u00D4': 'O',
73851        '\u1ED2': 'O',
73852        '\u1ED0': 'O',
73853        '\u1ED6': 'O',
73854        '\u1ED4': 'O',
73855        '\u00D5': 'O',
73856        '\u1E4C': 'O',
73857        '\u022C': 'O',
73858        '\u1E4E': 'O',
73859        '\u014C': 'O',
73860        '\u1E50': 'O',
73861        '\u1E52': 'O',
73862        '\u014E': 'O',
73863        '\u022E': 'O',
73864        '\u0230': 'O',
73865        '\u00D6': 'O',
73866        '\u022A': 'O',
73867        '\u1ECE': 'O',
73868        '\u0150': 'O',
73869        '\u01D1': 'O',
73870        '\u020C': 'O',
73871        '\u020E': 'O',
73872        '\u01A0': 'O',
73873        '\u1EDC': 'O',
73874        '\u1EDA': 'O',
73875        '\u1EE0': 'O',
73876        '\u1EDE': 'O',
73877        '\u1EE2': 'O',
73878        '\u1ECC': 'O',
73879        '\u1ED8': 'O',
73880        '\u01EA': 'O',
73881        '\u01EC': 'O',
73882        '\u00D8': 'O',
73883        '\u01FE': 'O',
73884        '\u0186': 'O',
73885        '\u019F': 'O',
73886        '\uA74A': 'O',
73887        '\uA74C': 'O',
73888        '\u01A2': 'OI',
73889        '\uA74E': 'OO',
73890        '\u0222': 'OU',
73891        '\u24C5': 'P',
73892        '\uFF30': 'P',
73893        '\u1E54': 'P',
73894        '\u1E56': 'P',
73895        '\u01A4': 'P',
73896        '\u2C63': 'P',
73897        '\uA750': 'P',
73898        '\uA752': 'P',
73899        '\uA754': 'P',
73900        '\u24C6': 'Q',
73901        '\uFF31': 'Q',
73902        '\uA756': 'Q',
73903        '\uA758': 'Q',
73904        '\u024A': 'Q',
73905        '\u24C7': 'R',
73906        '\uFF32': 'R',
73907        '\u0154': 'R',
73908        '\u1E58': 'R',
73909        '\u0158': 'R',
73910        '\u0210': 'R',
73911        '\u0212': 'R',
73912        '\u1E5A': 'R',
73913        '\u1E5C': 'R',
73914        '\u0156': 'R',
73915        '\u1E5E': 'R',
73916        '\u024C': 'R',
73917        '\u2C64': 'R',
73918        '\uA75A': 'R',
73919        '\uA7A6': 'R',
73920        '\uA782': 'R',
73921        '\u24C8': 'S',
73922        '\uFF33': 'S',
73923        '\u1E9E': 'S',
73924        '\u015A': 'S',
73925        '\u1E64': 'S',
73926        '\u015C': 'S',
73927        '\u1E60': 'S',
73928        '\u0160': 'S',
73929        '\u1E66': 'S',
73930        '\u1E62': 'S',
73931        '\u1E68': 'S',
73932        '\u0218': 'S',
73933        '\u015E': 'S',
73934        '\u2C7E': 'S',
73935        '\uA7A8': 'S',
73936        '\uA784': 'S',
73937        '\u24C9': 'T',
73938        '\uFF34': 'T',
73939        '\u1E6A': 'T',
73940        '\u0164': 'T',
73941        '\u1E6C': 'T',
73942        '\u021A': 'T',
73943        '\u0162': 'T',
73944        '\u1E70': 'T',
73945        '\u1E6E': 'T',
73946        '\u0166': 'T',
73947        '\u01AC': 'T',
73948        '\u01AE': 'T',
73949        '\u023E': 'T',
73950        '\uA786': 'T',
73951        '\uA728': 'TZ',
73952        '\u24CA': 'U',
73953        '\uFF35': 'U',
73954        '\u00D9': 'U',
73955        '\u00DA': 'U',
73956        '\u00DB': 'U',
73957        '\u0168': 'U',
73958        '\u1E78': 'U',
73959        '\u016A': 'U',
73960        '\u1E7A': 'U',
73961        '\u016C': 'U',
73962        '\u00DC': 'U',
73963        '\u01DB': 'U',
73964        '\u01D7': 'U',
73965        '\u01D5': 'U',
73966        '\u01D9': 'U',
73967        '\u1EE6': 'U',
73968        '\u016E': 'U',
73969        '\u0170': 'U',
73970        '\u01D3': 'U',
73971        '\u0214': 'U',
73972        '\u0216': 'U',
73973        '\u01AF': 'U',
73974        '\u1EEA': 'U',
73975        '\u1EE8': 'U',
73976        '\u1EEE': 'U',
73977        '\u1EEC': 'U',
73978        '\u1EF0': 'U',
73979        '\u1EE4': 'U',
73980        '\u1E72': 'U',
73981        '\u0172': 'U',
73982        '\u1E76': 'U',
73983        '\u1E74': 'U',
73984        '\u0244': 'U',
73985        '\u24CB': 'V',
73986        '\uFF36': 'V',
73987        '\u1E7C': 'V',
73988        '\u1E7E': 'V',
73989        '\u01B2': 'V',
73990        '\uA75E': 'V',
73991        '\u0245': 'V',
73992        '\uA760': 'VY',
73993        '\u24CC': 'W',
73994        '\uFF37': 'W',
73995        '\u1E80': 'W',
73996        '\u1E82': 'W',
73997        '\u0174': 'W',
73998        '\u1E86': 'W',
73999        '\u1E84': 'W',
74000        '\u1E88': 'W',
74001        '\u2C72': 'W',
74002        '\u24CD': 'X',
74003        '\uFF38': 'X',
74004        '\u1E8A': 'X',
74005        '\u1E8C': 'X',
74006        '\u24CE': 'Y',
74007        '\uFF39': 'Y',
74008        '\u1EF2': 'Y',
74009        '\u00DD': 'Y',
74010        '\u0176': 'Y',
74011        '\u1EF8': 'Y',
74012        '\u0232': 'Y',
74013        '\u1E8E': 'Y',
74014        '\u0178': 'Y',
74015        '\u1EF6': 'Y',
74016        '\u1EF4': 'Y',
74017        '\u01B3': 'Y',
74018        '\u024E': 'Y',
74019        '\u1EFE': 'Y',
74020        '\u24CF': 'Z',
74021        '\uFF3A': 'Z',
74022        '\u0179': 'Z',
74023        '\u1E90': 'Z',
74024        '\u017B': 'Z',
74025        '\u017D': 'Z',
74026        '\u1E92': 'Z',
74027        '\u1E94': 'Z',
74028        '\u01B5': 'Z',
74029        '\u0224': 'Z',
74030        '\u2C7F': 'Z',
74031        '\u2C6B': 'Z',
74032        '\uA762': 'Z',
74033        '\u24D0': 'a',
74034        '\uFF41': 'a',
74035        '\u1E9A': 'a',
74036        '\u00E0': 'a',
74037        '\u00E1': 'a',
74038        '\u00E2': 'a',
74039        '\u1EA7': 'a',
74040        '\u1EA5': 'a',
74041        '\u1EAB': 'a',
74042        '\u1EA9': 'a',
74043        '\u00E3': 'a',
74044        '\u0101': 'a',
74045        '\u0103': 'a',
74046        '\u1EB1': 'a',
74047        '\u1EAF': 'a',
74048        '\u1EB5': 'a',
74049        '\u1EB3': 'a',
74050        '\u0227': 'a',
74051        '\u01E1': 'a',
74052        '\u00E4': 'a',
74053        '\u01DF': 'a',
74054        '\u1EA3': 'a',
74055        '\u00E5': 'a',
74056        '\u01FB': 'a',
74057        '\u01CE': 'a',
74058        '\u0201': 'a',
74059        '\u0203': 'a',
74060        '\u1EA1': 'a',
74061        '\u1EAD': 'a',
74062        '\u1EB7': 'a',
74063        '\u1E01': 'a',
74064        '\u0105': 'a',
74065        '\u2C65': 'a',
74066        '\u0250': 'a',
74067        '\uA733': 'aa',
74068        '\u00E6': 'ae',
74069        '\u01FD': 'ae',
74070        '\u01E3': 'ae',
74071        '\uA735': 'ao',
74072        '\uA737': 'au',
74073        '\uA739': 'av',
74074        '\uA73B': 'av',
74075        '\uA73D': 'ay',
74076        '\u24D1': 'b',
74077        '\uFF42': 'b',
74078        '\u1E03': 'b',
74079        '\u1E05': 'b',
74080        '\u1E07': 'b',
74081        '\u0180': 'b',
74082        '\u0183': 'b',
74083        '\u0253': 'b',
74084        '\u24D2': 'c',
74085        '\uFF43': 'c',
74086        '\u0107': 'c',
74087        '\u0109': 'c',
74088        '\u010B': 'c',
74089        '\u010D': 'c',
74090        '\u00E7': 'c',
74091        '\u1E09': 'c',
74092        '\u0188': 'c',
74093        '\u023C': 'c',
74094        '\uA73F': 'c',
74095        '\u2184': 'c',
74096        '\u24D3': 'd',
74097        '\uFF44': 'd',
74098        '\u1E0B': 'd',
74099        '\u010F': 'd',
74100        '\u1E0D': 'd',
74101        '\u1E11': 'd',
74102        '\u1E13': 'd',
74103        '\u1E0F': 'd',
74104        '\u0111': 'd',
74105        '\u018C': 'd',
74106        '\u0256': 'd',
74107        '\u0257': 'd',
74108        '\uA77A': 'd',
74109        '\u01F3': 'dz',
74110        '\u01C6': 'dz',
74111        '\u24D4': 'e',
74112        '\uFF45': 'e',
74113        '\u00E8': 'e',
74114        '\u00E9': 'e',
74115        '\u00EA': 'e',
74116        '\u1EC1': 'e',
74117        '\u1EBF': 'e',
74118        '\u1EC5': 'e',
74119        '\u1EC3': 'e',
74120        '\u1EBD': 'e',
74121        '\u0113': 'e',
74122        '\u1E15': 'e',
74123        '\u1E17': 'e',
74124        '\u0115': 'e',
74125        '\u0117': 'e',
74126        '\u00EB': 'e',
74127        '\u1EBB': 'e',
74128        '\u011B': 'e',
74129        '\u0205': 'e',
74130        '\u0207': 'e',
74131        '\u1EB9': 'e',
74132        '\u1EC7': 'e',
74133        '\u0229': 'e',
74134        '\u1E1D': 'e',
74135        '\u0119': 'e',
74136        '\u1E19': 'e',
74137        '\u1E1B': 'e',
74138        '\u0247': 'e',
74139        '\u025B': 'e',
74140        '\u01DD': 'e',
74141        '\u24D5': 'f',
74142        '\uFF46': 'f',
74143        '\u1E1F': 'f',
74144        '\u0192': 'f',
74145        '\uA77C': 'f',
74146        '\u24D6': 'g',
74147        '\uFF47': 'g',
74148        '\u01F5': 'g',
74149        '\u011D': 'g',
74150        '\u1E21': 'g',
74151        '\u011F': 'g',
74152        '\u0121': 'g',
74153        '\u01E7': 'g',
74154        '\u0123': 'g',
74155        '\u01E5': 'g',
74156        '\u0260': 'g',
74157        '\uA7A1': 'g',
74158        '\u1D79': 'g',
74159        '\uA77F': 'g',
74160        '\u24D7': 'h',
74161        '\uFF48': 'h',
74162        '\u0125': 'h',
74163        '\u1E23': 'h',
74164        '\u1E27': 'h',
74165        '\u021F': 'h',
74166        '\u1E25': 'h',
74167        '\u1E29': 'h',
74168        '\u1E2B': 'h',
74169        '\u1E96': 'h',
74170        '\u0127': 'h',
74171        '\u2C68': 'h',
74172        '\u2C76': 'h',
74173        '\u0265': 'h',
74174        '\u0195': 'hv',
74175        '\u24D8': 'i',
74176        '\uFF49': 'i',
74177        '\u00EC': 'i',
74178        '\u00ED': 'i',
74179        '\u00EE': 'i',
74180        '\u0129': 'i',
74181        '\u012B': 'i',
74182        '\u012D': 'i',
74183        '\u00EF': 'i',
74184        '\u1E2F': 'i',
74185        '\u1EC9': 'i',
74186        '\u01D0': 'i',
74187        '\u0209': 'i',
74188        '\u020B': 'i',
74189        '\u1ECB': 'i',
74190        '\u012F': 'i',
74191        '\u1E2D': 'i',
74192        '\u0268': 'i',
74193        '\u0131': 'i',
74194        '\u24D9': 'j',
74195        '\uFF4A': 'j',
74196        '\u0135': 'j',
74197        '\u01F0': 'j',
74198        '\u0249': 'j',
74199        '\u24DA': 'k',
74200        '\uFF4B': 'k',
74201        '\u1E31': 'k',
74202        '\u01E9': 'k',
74203        '\u1E33': 'k',
74204        '\u0137': 'k',
74205        '\u1E35': 'k',
74206        '\u0199': 'k',
74207        '\u2C6A': 'k',
74208        '\uA741': 'k',
74209        '\uA743': 'k',
74210        '\uA745': 'k',
74211        '\uA7A3': 'k',
74212        '\u2
742124DB': 'l',
74213        '\uFF4C': 'l',
74214        '\u0140': 'l',
74215        '\u013A': 'l',
74216        '\u013E': 'l',
74217        '\u1E37': 'l',
74218        '\u1E39': 'l',
74219        '\u013C': 'l',
74220        '\u1E3D': 'l',
74221        '\u1E3B': 'l',
74222        '\u017F': 'l',
74223        '\u0142': 'l',
74224        '\u019A': 'l',
74225        '\u026B': 'l',
74226        '\u2C61': 'l',
74227        '\uA749': 'l',
74228        '\uA781': 'l',
74229        '\uA747': 'l',
74230        '\u01C9': 'lj',
74231        '\u24DC': 'm',
74232        '\uFF4D': 'm',
74233        '\u1E3F': 'm',
74234        '\u1E41': 'm',
74235        '\u1E43': 'm',
74236        '\u0271': 'm',
74237        '\u026F': 'm',
74238        '\u24DD': 'n',
74239        '\uFF4E': 'n',
74240        '\u01F9': 'n',
74241        '\u0144': 'n',
74242        '\u00F1': 'n',
74243        '\u1E45': 'n',
74244        '\u0148': 'n',
74245        '\u1E47': 'n',
74246        '\u0146': 'n',
74247        '\u1E4B': 'n',
74248        '\u1E49': 'n',
74249        '\u019E': 'n',
74250        '\u0272': 'n',
74251        '\u0149': 'n',
74252        '\uA791': 'n',
74253        '\uA7A5': 'n',
74254        '\u01CC': 'nj',
74255        '\u24DE': 'o',
74256        '\uFF4F': 'o',
74257        '\u00F2': 'o',
74258        '\u00F3': 'o',
74259        '\u00F4': 'o',
74260        '\u1ED3': 'o',
74261        '\u1ED1': 'o',
74262        '\u1ED7': 'o',
74263        '\u1ED5': 'o',
74264        '\u00F5': 'o',
74265        '\u1E4D': 'o',
74266        '\u022D': 'o',
74267        '\u1E4F': 'o',
74268        '\u014D': 'o',
74269        '\u1E51': 'o',
74270        '\u1E53': 'o',
74271        '\u014F': 'o',
74272        '\u022F': 'o',
74273        '\u0231': 'o',
74274        '\u00F6': 'o',
74275        '\u022B': 'o',
74276        '\u1ECF': 'o',
74277        '\u0151': 'o',
74278        '\u01D2': 'o',
74279        '\u020D': 'o',
74280        '\u020F': 'o',
74281        '\u01A1': 'o',
74282        '\u1EDD': 'o',
74283        '\u1EDB': 'o',
74284        '\u1EE1': 'o',
74285        '\u1EDF': 'o',
74286        '\u1EE3': 'o',
74287        '\u1ECD': 'o',
74288        '\u1ED9': 'o',
74289        '\u01EB': 'o',
74290        '\u01ED': 'o',
74291        '\u00F8': 'o',
74292        '\u01FF': 'o',
74293        '\u0254': 'o',
74294        '\uA74B': 'o',
74295        '\uA74D': 'o',
74296        '\u0275': 'o',
74297        '\u01A3': 'oi',
74298        '\u0223': 'ou',
74299        '\uA74F': 'oo',
74300        '\u24DF': 'p',
74301        '\uFF50': 'p',
74302        '\u1E55': 'p',
74303        '\u1E57': 'p',
74304        '\u01A5': 'p',
74305        '\u1D7D': 'p',
74306        '\uA751': 'p',
74307        '\uA753': 'p',
74308        '\uA755': 'p',
74309        '\u24E0': 'q',
74310        '\uFF51': 'q',
74311        '\u024B': 'q',
74312        '\uA757': 'q',
74313        '\uA759': 'q',
74314        '\u24E1': 'r',
74315        '\uFF52': 'r',
74316        '\u0155': 'r',
74317        '\u1E59': 'r',
74318        '\u0159': 'r',
74319        '\u0211': 'r',
74320        '\u0213': 'r',
74321        '\u1E5B': 'r',
74322        '\u1E5D': 'r',
74323        '\u0157': 'r',
74324        '\u1E5F': 'r',
74325        '\u024D': 'r',
74326        '\u027D': 'r',
74327        '\uA75B': 'r',
74328        '\uA7A7': 'r',
74329        '\uA783': 'r',
74330        '\u24E2': 's',
74331        '\uFF53': 's',
74332        '\u00DF': 's',
74333        '\u015B': 's',
74334        '\u1E65': 's',
74335        '\u015D': 's',
74336        '\u1E61': 's',
74337        '\u0161': 's',
74338        '\u1E67': 's',
74339        '\u1E63': 's',
74340        '\u1E69': 's',
74341        '\u0219': 's',
74342        '\u015F': 's',
74343        '\u023F': 's',
74344        '\uA7A9': 's',
74345        '\uA785': 's',
74346        '\u1E9B': 's',
74347        '\u24E3': 't',
74348        '\uFF54': 't',
74349        '\u1E6B': 't',
74350        '\u1E97': 't',
74351        '\u0165': 't',
74352        '\u1E6D': 't',
74353        '\u021B': 't',
74354        '\u0163': 't',
74355        '\u1E71': 't',
74356        '\u1E6F': 't',
74357        '\u0167': 't',
74358        '\u01AD': 't',
74359        '\u0288': 't',
74360        '\u2C66': 't',
74361        '\uA787': 't',
74362        '\uA729': 'tz',
74363        '\u24E4': 'u',
74364        '\uFF55': 'u',
74365        '\u00F9': 'u',
74366        '\u00FA': 'u',
74367        '\u00FB': 'u',
74368        '\u0169': 'u',
74369        '\u1E79': 'u',
74370        '\u016B': 'u',
74371        '\u1E7B': 'u',
74372        '\u016D': 'u',
74373        '\u00FC': 'u',
74374        '\u01DC': 'u',
74375        '\u01D8': 'u',
74376        '\u01D6': 'u',
74377        '\u01DA': 'u',
74378        '\u1EE7': 'u',
74379        '\u016F': 'u',
74380        '\u0171': 'u',
74381        '\u01D4': 'u',
74382        '\u0215': 'u',
74383        '\u0217': 'u',
74384        '\u01B0': 'u',
74385        '\u1EEB': 'u',
74386        '\u1EE9': 'u',
74387        '\u1EEF': 'u',
74388        '\u1EED': 'u',
74389        '\u1EF1': 'u',
74390        '\u1EE5': 'u',
74391        '\u1E73': 'u',
74392        '\u0173': 'u',
74393        '\u1E77': 'u',
74394        '\u1E75': 'u',
74395        '\u0289': 'u',
74396        '\u24E5': 'v',
74397        '\uFF56': 'v',
74398        '\u1E7D': 'v',
74399        '\u1E7F': 'v',
74400        '\u028B': 'v',
74401        '\uA75F': 'v',
74402        '\u028C': 'v',
74403        '\uA761': 'vy',
74404        '\u24E6': 'w',
74405        '\uFF57': 'w',
74406        '\u1E81': 'w',
74407        '\u1E83': 'w',
74408        '\u0175': 'w',
74409        '\u1E87': 'w',
74410        '\u1E85': 'w',
74411        '\u1E98': 'w',
74412        '\u1E89': 'w',
74413        '\u2C73': 'w',
74414        '\u24E7': 'x',
74415        '\uFF58': 'x',
74416        '\u1E8B': 'x',
74417        '\u1E8D': 'x',
74418        '\u24E8': 'y',
74419        '\uFF59': 'y',
74420        '\u1EF3': 'y',
74421        '\u00FD': 'y',
74422        '\u0177': 'y',
74423        '\u1EF9': 'y',
74424        '\u0233': 'y',
74425        '\u1E8F': 'y',
74426        '\u00FF': 'y',
74427        '\u1EF7': 'y',
74428        '\u1E99': 'y',
74429        '\u1EF5': 'y',
74430        '\u01B4': 'y',
74431        '\u024F': 'y',
74432        '\u1EFF': 'y',
74433        '\u24E9': 'z',
74434        '\uFF5A': 'z',
74435        '\u017A': 'z',
74436        '\u1E91': 'z',
74437        '\u017C': 'z',
74438        '\u017E': 'z',
74439        '\u1E93': 'z',
74440        '\u1E95': 'z',
74441        '\u01B6': 'z',
74442        '\u0225': 'z',
74443        '\u0240': 'z',
74444        '\u2C6C': 'z',
74445        '\uA763': 'z',
74446        '\u0386': '\u0391',
74447        '\u0388': '\u0395',
74448        '\u0389': '\u0397',
74449        '\u038A': '\u0399',
74450        '\u03AA': '\u0399',
74451        '\u038C': '\u039F',
74452        '\u038E': '\u03A5',
74453        '\u03AB': '\u03A5',
74454        '\u038F': '\u03A9',
74455        '\u03AC': '\u03B1',
74456        '\u03AD': '\u03B5',
74457        '\u03AE': '\u03B7',
74458        '\u03AF': '\u03B9',
74459        '\u03CA': '\u03B9',
74460        '\u0390': '\u03B9',
74461        '\u03CC': '\u03BF',
74462        '\u03CD': '\u03C5',
74463        '\u03CB': '\u03C5',
74464        '\u03B0': '\u03C5',
74465        '\u03C9': '\u03C9',
74466        '\u03C2': '\u03C3'
74467      };
74468
74469      return diacritics;
74470    });
74471
74472    S2.define('select2/data/base',[
74473      '../utils'
74474    ], function (Utils) {
74475      function BaseAdapter ($element, options) {
74476        BaseAdapter.__super__.constructor.call(this);
74477      }
74478
74479      Utils.Extend(BaseAdapter, Utils.Observable);
74480
74481      BaseAdapter.prototype.current = function (callback) {
74482        throw new Error('The `current` method must be defined in child classes.');
74483      };
74484
74485      BaseAdapter.prototype.query = function (params, callback) {
74486        throw new Error('The `query` method must be defined in child classes.');
74487      };
74488
74489      BaseAdapter.prototype.bind = function (container, $container) {
74490        // Can be implemented in subclasses
74491      };
74492
74493      BaseAdapter.prototype.destroy = function () {
74494        // Can be implemented in subclasses
74495      };
74496
74497      BaseAdapter.prototype.generateResultId = function (container, data) {
74498        var id = container.id + '-result-';
74499
74500        id += Utils.generateChars(4);
74501
74502        if (data.id != null) {
74503          id += '-' + data.id.toString();
74504        } else {
74505          id += '-' + Utils.generateChars(4);
74506        }
74507        return id;
74508      };
74509
74510      return BaseAdapter;
74511    });
74512
74513    S2.define('select2/data/select',[
74514      './base',
74515      '../utils',
74516      'jquery'
74517    ], function (BaseAdapter, Utils, $) {
74518      function SelectAdapter ($element, options) {
74519        this.$element = $element;
74520        this.options = options;
74521
74522        SelectAdapter.__super__.constructor.call(this);
74523      }
74524
74525      Utils.Extend(SelectAdapter, BaseAdapter);
74526
74527      SelectAdapter.prototype.current = function (callback) {
74528        var data = [];
74529        var self = this;
74530
74531        this.$element.find(':selected').each(function () {
74532          var $option = $(this);
74533
74534          var option = self.item($option);
74535
74536          data.push(option);
74537        });
74538
74539        callback(data);
74540      };
74541
74542      SelectAdapter.prototype.select = function (data) {
74543        var self = this;
74544
74545        data.selected = true;
74546
74547        // If data.element is a DOM node, use it instead
74548        if ($(data.element).is('option')) {
74549          data.element.selected = true;
74550
74551          this.$element.trigger('change');
74552
74553          return;
74554        }
74555
74556        if (this.$element.prop('multiple')) {
74557          this.current(function (currentData) {
74558            var val = [];
74559
74560            data = [data];
74561            data.push.apply(data, currentData);
74562
74563            for (var d = 0; d < data.length; d++) {
74564              var id = data[d].id;
74565
74566              if ($.inArray(id, val) === -1) {
74567                val.push(id);
74568              }
74569            }
74570
74571            self.$element.val(val);
74572            self.$element.trigger('change');
74573          });
74574        } else {
74575          var val = data.id;
74576
74577          this.$element.val(val);
74578          this.$element.trigger('change');
74579        }
74580      };
74581
74582      SelectAdapter.prototype.unselect = function (data) {
74583        var self = this;
74584
74585        if (!this.$element.prop('multiple')) {
74586          return;
74587        }
74588
74589        data.selected = false;
74590
74591        if ($(data.element).is('option')) {
74592          data.element.selected = false;
74593
74594          this.$element.trigger('change');
74595
74596          return;
74597        }
74598
74599        this.current(function (currentData) {
74600          var val = [];
74601
74602          for (var d = 0; d < currentData.length; d++) {
74603            var id = currentData[d].id;
74604            if (id !== data.id.toString() && $.inArray(id, val) === -1) {
74605              val.push(id);
74606            }
74607          }
74608
74609          self.$element.val(val);
74610
74611          self.$element.trigger('change');
74612        });
74613      };
74614
74615      SelectAdapter.prototype.bind = function (container, $container) {
74616        var self = this;
74617
74618        this.container = container;
74619
74620        container.on('select', function (params) {
74621          self.select(params.data);
74622        });
74623
74624        container.on('unselect', function (params) {
74625          self.unselect(params.data);
74626        });
74627      };
74628
74629      SelectAdapter.prototype.destroy = function () {
74630        // Remove anything added to child elements
74631        this.$element.find('*').each(function () {
74632          // Remove any custom data set by select2
74633          $.removeData(this, 'data');
74634        });
74635      };
74636
74637      SelectAdapter.prototype.query = function (params, callback) {
74638        var data = [];
74639        var self = this;
74640
74641        var $options = this.$element.children();
74642
74643        $options.each(function () {
74644          var $option = $(this);
74645
74646          if (!$option.is('option') && !$option.is('optgroup')) {
74647            return;
74648          }
74649
74650          var option = self.item($option);
74651
74652          var matches = self.matches(params, option);
74653
74654          if (matches !== null) {
74655            data.push(matches);
74656          }
74657        });
74658
74659        callback({
74660          results: data
74661        });
74662      };
74663
74664      SelectAdapter.prototype.addOptions = function ($options) {
74665        Utils.appendMany(this.$element, $options);
74666      };
74667
74668      SelectAdapter.prototype.option = function (data) {
74669        var option;
74670
74671        if (data.children) {
74672          option = document.createElement('optgroup');
74673          option.label = data.text;
74674        } else {
74675          option = document.createElement('option');
74676
74677          if (option.textContent !== undefined) {
74678            option.textContent = data.text;
74679          } else {
74680            option.innerText = data.text;
74681          }
74682        }
74683
74684        if (data.id !== undefined) {
74685          option.value = data.id;
74686        }
74687
74688        if (data.disabled) {
74689          option.disabled = true;
74690        }
74691
74692        if (data.selected) {
74693          option.selected = true;
74694        }
74695
74696        if (data.title) {
74697          option.title = data.title;
74698        }
74699
74700        var $option = $(option);
74701
74702        var normalizedData = this._normalizeItem(data);
74703        normalizedData.element = option;
74704
74705        // Override the option's data with the combined data
74706        $.data(option, 'data', normalizedData);
74707
74708        return $option;
74709      };
74710
74711      SelectAdapter.prototype.item = function ($option) {
74712        var data = {};
74713
74714        data = $.data($option[0], 'data');
74715
74716        if (data != null) {
74717          return data;
74718        }
74719
74720        if ($option.is('option')) {
74721          data = {
74722            id: $option.val(),
74723            text: $option.text(),
74724            disabled: $option.prop('disabled'),
74725            selected: $option.prop('selected'),
74726            title: $option.prop('title')
74727          };
74728        } else if ($option.is('optgroup')) {
74729          data = {
74730            text: $option.prop('label'),
74731            children: [],
74732            title: $option.prop('title')
74733          };
74734
74735          var $children = $option.children('option');
74736          var children = [];
74737
74738          for (var c = 0; c < $children.length; c++) {
74739            var $child = $($children[c]);
74740
74741            var child = this.item($child);
74742
74743            children.push(child);
74744          }
74745
74746          data.children = children;
74747        }
74748
74749        data = this._normalizeItem(data);
74750        data.element = $option[0];
74751
74752        $.data($option[0], 'data', data);
74753
74754        return data;
74755      };
74756
74757      SelectAdapter.prototype._normalizeItem = function (item) {
74758        if (!$.isPlainObject(item)) {
74759          item = {
74760            id: item,
74761            text: item
74762          };
74763        }
74764
74765        item = $.extend({}, {
74766          text: ''
74767        }, item);
74768
74769        var defaults = {
74770          selected: false,
74771          disabled: false
74772        };
74773
74774        if (item.id != null) {
74775          item.id = item.id.toString();
74776        }
74777
74778        if (item.text != null) {
74779          item.text = item.text.toString();
74780        }
74781
74782        if (item._resultId == null && item.id && this.container != null) {
74783          item._resultId = this.generateResultId(this.container, item);
74784        }
74785
74786        return $.extend({}, defaults, item);
74787      };
74788
74789      SelectAdapter.prototype.matches = function (params, data) {
74790        var matcher = this.options.get('matcher');
74791
74792        return matcher(params, data);
74793      };
74794
74795      return SelectAdapter;
74796    });
74797
74798    S2.define('select2/data/array',[
74799      './select',
74800      '../utils',
74801      'jquery'
74802    ], function (SelectAdapter, Utils, $) {
74803      function ArrayAdapter ($element, options) {
74804        var data = options.get('data') || [];
74805
74806        ArrayAdapter.__super__.constructor.call(this, $element, options);
74807
74808        this.addOptions(this.convertToOptions(data));
74809      }
74810
74811      Utils.Extend(ArrayAdapter, SelectAdapter);
74812
74813      ArrayAdapter.prototype.select = function (data) {
74814        var $option = this.$element.find('option').filter(function (i, elm) {
74815          return elm.value == data.id.toString();
74816        });
74817
74818        if ($option.length === 0) {
74819          $option = this.option(data);
74820
74821          this.addOptions($option);
74822        }
74823
74824        ArrayAdapter.__super__.select.call(this, data);
74825      };
74826
74827      ArrayAdapter.prototype.convertToOptions = function (data) {
74828        var self = this;
74829
74830        var $existing = this.$element.find('option');
74831        var existingIds = $existing.map(function () {
74832          return self.item($(this)).id;
74833        }).get();
74834
74835        var $options = [];
74836
74837        // Filter out all items except for the one passed in the argument
74838        function onlyItem (item) {
74839          return function () {
74840            return $(this).val() == item.id;
74841          };
74842        }
74843
74844        for (var d = 0; d < data.length; d++) {
74845          var item = this._normalizeItem(data[d]);
74846
74847          // Skip items which were pre-loaded, only merge the data
74848          if ($.inArray(item.id, existingIds) >= 0) {
74849            var $existingOption = $existing.filter(onlyItem(item));
74850
74851            var existingData = this.item($existingOption);
74852            var newData = $.extend(true, {}, item, existingData);
74853
74854            var $newOption = this.option(newData);
74855
74856            $existingOption.replaceWith($newOption);
74857
74858            continue;
74859          }
74860
74861          var $option = this.option(item);
74862
74863          if (item.children) {
74864            var $children = this.convertToOptions(item.children);
74865
74866            Utils.appendMany($option, $children);
74867          }
74868
74869          $options.push($option);
74870        }
74871
74872        return $options;
74873      };
74874
74875      return ArrayAdapter;
74876    });
74877
74878    S2.define('select2/data/ajax',[
74879      './array',
74880      '../utils',
74881      'jquery'
74882    ], function (ArrayAdapter, Utils, $) {
74883      function AjaxAdapter ($element, options) {
74884        this.ajaxOptions = this._applyDefaults(options.get('ajax'));
74885
74886        if (this.ajaxOptions.processResults != null) {
74887          this.processResults = this.ajaxOptions.processResults;
74888        }
74889
74890        AjaxAdapter.__super__.constructor.call(this, $element, options);
74891      }
74892
74893      Utils.Extend(AjaxAdapter, ArrayAdapter);
74894
74895      AjaxAdapter.prototype._applyDefaults = function (options) {
74896        var defaults = {
74897          data: function (params) {
74898            return $.extend({}, params, {
74899              q: params.term
74900            });
74901          },
74902          transport: function (params, success, failure) {
vendor: 34,324 bytes, lines 74903-76149
74903            var $request = $.ajax(params);
74904
74905            $request.then(success);
74906            $request.fail(failure);
74907
74908            return $request;
74909          }
74910        };
74911
74912        return $.extend({}, defaults, options, true);
74913      };
74914
74915      AjaxAdapter.prototype.processResults = function (results) {
74916        return results;
74917      };
74918
74919      AjaxAdapter.prototype.query = function (params, callback) {
74920        var matches = [];
74921        var self = this;
74922
74923        if (this._request != null) {
74924          // JSONP requests cannot always be aborted
74925          if ($.isFunction(this._request.abort)) {
74926            this._request.abort();
74927          }
74928
74929          this._request = null;
74930        }
74931
74932        var options = $.extend({
74933          type: 'GET'
74934        }, this.ajaxOptions);
74935
74936        if (typeof options.url === 'function') {
74937          options.url = options.url.call(this.$element, params);
74938        }
74939
74940        if (typeof options.data === 'function') {
74941          options.data = options.data.call(this.$element, params);
74942        }
74943
74944        function request () {
74945          var $request = options.transport(options, function (data) {
74946            var results = self.processResults(data, params);
74947
74948            if (self.options.get('debug') && window.console && console.error) {
74949              // Check to make sure that the response included a `results` key.
74950              if (!results || !results.results || !$.isArray(results.results)) {
74951                console.error(
74952                  'select2: The AJAX results did not return an array in the ' +
74953                  '`results` key of the response.'
74954                );
74955              }
74956            }
74957
74958            callback(results);
74959          }, function () {
74960            // Attempt to detect if a request was aborted
74961            // Only works if the transport exposes a status property
74962            if ($request.status && $request.status === '0') {
74963              return;
74964            }
74965
74966            self.trigger('results:message', {
74967              message: 'errorLoading'
74968            });
74969          });
74970
74971          self._request = $request;
74972        }
74973
74974        if (this.ajaxOptions.delay && params.term != null) {
74975          if (this._queryTimeout) {
74976            window.clearTimeout(this._queryTimeout);
74977          }
74978
74979          this._queryTimeout = window.setTimeout(request, this.ajaxOptions.delay);
74980        } else {
74981          request();
74982        }
74983      };
74984
74985      return AjaxAdapter;
74986    });
74987
74988    S2.define('select2/data/tags',[
74989      'jquery'
74990    ], function ($) {
74991      function Tags (decorated, $element, options) {
74992        var tags = options.get('tags');
74993
74994        var createTag = options.get('createTag');
74995
74996        if (createTag !== undefined) {
74997          this.createTag = createTag;
74998        }
74999
75000        var insertTag = options.get('insertTag');
75001
75002        if (insertTag !== undefined) {
75003          this.insertTag = insertTag;
75004        }
75005
75006        decorated.call(this, $element, options);
75007
75008        if ($.isArray(tags)) {
75009          for (var t = 0; t < tags.length; t++) {
75010            var tag = tags[t];
75011            var item = this._normalizeItem(tag);
75012
75013            var $option = this.option(item);
75014
75015            this.$element.append($option);
75016          }
75017        }
75018      }
75019
75020      Tags.prototype.query = function (decorated, params, callback) {
75021        var self = this;
75022
75023        this._removeOldTags();
75024
75025        if (params.term == null || params.page != null) {
75026          decorated.call(this, params, callback);
75027          return;
75028        }
75029
75030        function wrapper (obj, child) {
75031          var data = obj.results;
75032
75033          for (var i = 0; i < data.length; i++) {
75034            var option = data[i];
75035
75036            var checkChildren = (
75037              option.children != null &&
75038              !wrapper({
75039                results: option.children
75040              }, true)
75041            );
75042
75043            var optionText = (option.text || '').toUpperCase();
75044            var paramsTerm = (params.term || '').toUpperCase();
75045
75046            var checkText = optionText === paramsTerm;
75047
75048            if (checkText || checkChildren) {
75049              if (child) {
75050                return false;
75051              }
75052
75053              obj.data = data;
75054              callback(obj);
75055
75056              return;
75057            }
75058          }
75059
75060          if (child) {
75061            return true;
75062          }
75063
75064          var tag = self.createTag(params);
75065
75066          if (tag != null) {
75067            var $option = self.option(tag);
75068            $option.attr('data-select2-tag', true);
75069
75070            self.addOptions([$option]);
75071
75072            self.insertTag(data, tag);
75073          }
75074
75075          obj.results = data;
75076
75077          callback(obj);
75078        }
75079
75080        decorated.call(this, params, wrapper);
75081      };
75082
75083      Tags.prototype.createTag = function (decorated, params) {
75084        var term = $.trim(params.term);
75085
75086        if (term === '') {
75087          return null;
75088        }
75089
75090        return {
75091          id: term,
75092          text: term
75093        };
75094      };
75095
75096      Tags.prototype.insertTag = function (_, data, tag) {
75097        data.unshift(tag);
75098      };
75099
75100      Tags.prototype._removeOldTags = function (_) {
75101        var tag = this._lastTag;
75102
75103        var $options = this.$element.find('option[data-select2-tag]');
75104
75105        $options.each(function () {
75106          if (this.selected) {
75107            return;
75108          }
75109
75110          $(this).remove();
75111        });
75112      };
75113
75114      return Tags;
75115    });
75116
75117    S2.define('select2/data/tokenizer',[
75118      'jquery'
75119    ], function ($) {
75120      function Tokenizer (decorated, $element, options) {
75121        var tokenizer = options.get('tokenizer');
75122
75123        if (tokenizer !== undefined) {
75124          this.tokenizer = tokenizer;
75125        }
75126
75127        decorated.call(this, $element, options);
75128      }
75129
75130      Tokenizer.prototype.bind = function (decorated, container, $container) {
75131        decorated.call(this, container, $container);
75132
75133        this.$search =  container.dropdown.$search || container.selection.$search ||
75134          $container.find('.select2-search__field');
75135      };
75136
75137      Tokenizer.prototype.query = function (decorated, params, callback) {
75138        var self = this;
75139
75140        function createAndSelect (data) {
75141          // Normalize the data object so we can use it for checks
75142          var item = self._normalizeItem(data);
75143
75144          // Check if the data object already exists as a tag
75145          // Select it if it doesn't
75146          var $existingOptions = self.$element.find('option').filter(function () {
75147            return $(this).val() === item.id;
75148          });
75149
75150          // If an existing option wasn't found for it, create the option
75151          if (!$existingOptions.length) {
75152            var $option = self.option(item);
75153            $option.attr('data-select2-tag', true);
75154
75155            self._removeOldTags();
75156            self.addOptions([$option]);
75157          }
75158
75159          // Select the item, now that we know there is an option for it
75160          select(item);
75161        }
75162
75163        function select (data) {
75164          self.trigger('select', {
75165            data: data
75166          });
75167        }
75168
75169        params.term = params.term || '';
75170
75171        var tokenData = this.tokenizer(params, this.options, createAndSelect);
75172
75173        if (tokenData.term !== params.term) {
75174          // Replace the search term if we have the search box
75175          if (this.$search.length) {
75176            this.$search.val(tokenData.term);
75177            this.$search.focus();
75178          }
75179
75180          params.term = tokenData.term;
75181        }
75182
75183        decorated.call(this, params, callback);
75184      };
75185
75186      Tokenizer.prototype.tokenizer = function (_, params, options, callback) {
75187        var separators = options.get('tokenSeparators') || [];
75188        var term = params.term;
75189        var i = 0;
75190
75191        var createTag = this.createTag || function (params) {
75192          return {
75193            id: params.term,
75194            text: params.term
75195          };
75196        };
75197
75198        while (i < term.length) {
75199          var termChar = term[i];
75200
75201          if ($.inArray(termChar, separators) === -1) {
75202            i++;
75203
75204            continue;
75205          }
75206
75207          var part = term.substr(0, i);
75208          var partParams = $.extend({}, params, {
75209            term: part
75210          });
75211
75212          var data = createTag(partParams);
75213
75214          if (data == null) {
75215            i++;
75216            continue;
75217          }
75218
75219          callback(data);
75220
75221          // Reset the term to not include the tokenized portion
75222          term = term.substr(i + 1) || '';
75223          i = 0;
75224        }
75225
75226        return {
75227          term: term
75228        };
75229      };
75230
75231      return Tokenizer;
75232    });
75233
75234    S2.define('select2/data/minimumInputLength',[
75235
75236    ], function () {
75237      function MinimumInputLength (decorated, $e, options) {
75238        this.minimumInputLength = options.get('minimumInputLength');
75239
75240        decorated.call(this, $e, options);
75241      }
75242
75243      MinimumInputLength.prototype.query = function (decorated, params, callback) {
75244        params.term = params.term || '';
75245
75246        if (params.term.length < this.minimumInputLength) {
75247          this.trigger('results:message', {
75248            message: 'inputTooShort',
75249            args: {
75250              minimum: this.minimumInputLength,
75251              input: params.term,
75252              params: params
75253            }
75254          });
75255
75256          return;
75257        }
75258
75259        decorated.call(this, params, callback);
75260      };
75261
75262      return MinimumInputLength;
75263    });
75264
75265    S2.define('select2/data/maximumInputLength',[
75266
75267    ], function () {
75268      function MaximumInputLength (decorated, $e, options) {
75269        this.maximumInputLength = options.get('maximumInputLength');
75270
75271        decorated.call(this, $e, options);
75272      }
75273
75274      MaximumInputLength.prototype.query = function (decorated, params, callback) {
75275        params.term = params.term || '';
75276
75277        if (this.maximumInputLength > 0 &&
75278          params.term.length > this.maximumInputLength) {
75279          this.trigger('results:message', {
75280            message: 'inputTooLong',
75281            args: {
75282              maximum: this.maximumInputLength,
75283              input: params.term,
75284              params: params
75285            }
75286          });
75287
75288          return;
75289        }
75290
75291        decorated.call(this, params, callback);
75292      };
75293
75294      return MaximumInputLength;
75295    });
75296
75297    S2.define('select2/data/maximumSelectionLength',[
75298
75299    ], function (){
75300      function MaximumSelectionLength (decorated, $e, options) {
75301        this.maximumSelectionLength = options.get('maximumSelectionLength');
75302
75303        decorated.call(this, $e, options);
75304      }
75305
75306      MaximumSelectionLength.prototype.query =
75307        function (decorated, params, callback) {
75308          var self = this;
75309
75310          this.current(function (currentData) {
75311            var count = currentData != null ? currentData.length : 0;
75312            if (self.maximumSelectionLength > 0 &&
75313              count >= self.maximumSelectionLength) {
75314              self.trigger('results:message', {
75315                message: 'maximumSelected',
75316                args: {
75317                  maximum: self.maximumSelectionLength
75318                }
75319              });
75320              return;
75321            }
75322            decorated.call(self, params, callback);
75323          });
75324        };
75325
75326      return MaximumSelectionLength;
75327    });
75328
75329    S2.define('select2/dropdown',[
75330      'jquery',
75331      './utils'
75332    ], function ($, Utils) {
75333      function Dropdown ($element, options) {
75334        this.$element = $element;
75335        this.options = options;
75336
75337        Dropdown.__super__.constructor.call(this);
75338      }
75339
75340      Utils.Extend(Dropdown, Utils.Observable);
75341
75342      Dropdown.prototype.render = function () {
75343        var $dropdown = $(
75344          '<span class="select2-dropdown">' +
75345          '<span class="select2-results"></span>' +
75346          '</span>'
75347        );
75348
75349        $dropdown.attr('dir', this.options.get('dir'));
75350
75351        this.$dropdown = $dropdown;
75352
75353        return $dropdown;
75354      };
75355
75356      Dropdown.prototype.bind = function () {
75357        // Should be implemented in subclasses
75358      };
75359
75360      Dropdown.prototype.position = function ($dropdown, $container) {
75361        // Should be implmented in subclasses
75362      };
75363
75364      Dropdown.prototype.destroy = function () {
75365        // Remove the dropdown from the DOM
75366        this.$dropdown.remove();
75367      };
75368
75369      return Dropdown;
75370    });
75371
75372    S2.define('select2/dropdown/search',[
75373      'jquery',
75374      '../utils'
75375    ], function ($, Utils) {
75376      function Search () { }
75377
75378      Search.prototype.render = function (decorated) {
75379        var $rendered = decorated.call(this);
75380
75381        var $search = $(
75382          '<span class="select2-search select2-search--dropdown">' +
75383          '<input class="select2-search__field" type="search" tabindex="-1"' +
75384          ' autocomplete="off" autocorrect="off" autocapitalize="none"' +
75385          ' spellcheck="false" role="textbox" />' +
75386          '</span>'
75387        );
75388
75389        this.$searchContainer = $search;
75390        this.$search = $search.find('input');
75391        this.$search.attr('placeholder', this.options.get('searchInputPlaceholder'));
75392        $rendered.prepend($search);
75393
75394        return $rendered;
75395      };
75396
75397      Search.prototype.bind = function (decorated, container, $container) {
75398        var self = this;
75399
75400        decorated.call(this, container, $container);
75401
75402        this.$search.on('keydown', function (evt) {
75403          self.trigger('keypress', evt);
75404
75405          self._keyUpPrevented = evt.isDefaultPrevented();
75406        });
75407
75408        // Workaround for browsers which do not support the `input` event
75409        // This will prevent double-triggering of events for browsers which support
75410        // both the `keyup` and `input` events.
75411        this.$search.on('input', function (evt) {
75412          // Unbind the duplicated `keyup` event
75413          $(this).off('keyup');
75414        });
75415
75416        this.$search.on('keyup input', function (evt) {
75417          self.handleSearch(evt);
75418        });
75419
75420        container.on('open', function () {
75421          self.$search.attr('tabindex', 0);
75422
75423          self.$search.focus();
75424
75425          window.setTimeout(function () {
75426            self.$search.focus();
75427          }, 0);
75428        });
75429
75430        container.on('close', function () {
75431          self.$search.attr('tabindex', -1);
75432
75433          self.$search.val('');
75434        });
75435
75436        container.on('focus', function () {
75437          if (!container.isOpen()) {
75438            self.$search.focus();
75439          }
75440        });
75441
75442        container.on('results:all', function (params) {
75443          if (params.query.term == null || params.query.term === '') {
75444            var showSearch = self.showSearch(params);
75445
75446            if (showSearch) {
75447              self.$searchContainer.removeClass('select2-search--hide');
75448            } else {
75449              self.$searchContainer.addClass('select2-search--hide');
75450            }
75451          }
75452        });
75453      };
75454
75455      Search.prototype.handleSearch = function (evt) {
75456        if (!this._keyUpPrevented) {
75457          var input = this.$search.val();
75458
75459          this.trigger('query', {
75460            term: input
75461          });
75462        }
75463
75464        this._keyUpPrevented = false;
75465      };
75466
75467      Search.prototype.showSearch = function (_, params) {
75468        return true;
75469      };
75470
75471      return Search;
75472    });
75473
75474    S2.define('select2/dropdown/hidePlaceholder',[
75475
75476    ], function () {
75477      function HidePlaceholder (decorated, $element, options, dataAdapter) {
75478        this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
75479
75480        decorated.call(this, $element, options, dataAdapter);
75481      }
75482
75483      HidePlaceholder.prototype.append = function (decorated, data) {
75484        data.results = this.removePlaceholder(data.results);
75485
75486        decorated.call(this, data);
75487      };
75488
75489      HidePlaceholder.prototype.normalizePlaceholder = function (_, placeholder) {
75490        if (typeof placeholder === 'string') {
75491          placeholder = {
75492            id: '',
75493            text: placeholder
75494          };
75495        }
75496
75497        return placeholder;
75498      };
75499
75500      HidePlaceholder.prototype.removePlaceholder = function (_, data) {
75501        var modifiedData = data.slice(0);
75502
75503        for (var d = data.length - 1; d >= 0; d--) {
75504          var item = data[d];
75505
75506          if (this.placeholder.id === item.id) {
75507            modifiedData.splice(d, 1);
75508          }
75509        }
75510
75511        return modifiedData;
75512      };
75513
75514      return HidePlaceholder;
75515    });
75516
75517    S2.define('select2/dropdown/infiniteScroll',[
75518      'jquery'
75519    ], function ($) {
75520      function InfiniteScroll (decorated, $element, options, dataAdapter) {
75521        this.lastParams = {};
75522
75523        decorated.call(this, $element, options, dataAdapter);
75524
75525        this.$loadingMore = this.createLoadingMore();
75526        this.loading = false;
75527      }
75528
75529      InfiniteScroll.prototype.append = function (decorated, data) {
75530        this.$loadingMore.remove();
75531        this.loading = false;
75532
75533        decorated.call(this, data);
75534
75535        if (this.showLoadingMore(data)) {
75536          this.$results.append(this.$loadingMore);
75537        }
75538      };
75539
75540      InfiniteScroll.prototype.bind = function (decorated, container, $container) {
75541        var self = this;
75542
75543        decorated.call(this, container, $container);
75544
75545        container.on('query', function (params) {
75546          self.lastParams = params;
75547          self.loading = true;
75548        });
75549
75550        container.on('query:append', function (params) {
75551          self.lastParams = params;
75552          self.loading = true;
75553        });
75554
75555        this.$results.on('scroll', function () {
75556          var isLoadMoreVisible = $.contains(
75557            document.documentElement,
75558            self.$loadingMore[0]
75559          );
75560
75561          if (self.loading || !isLoadMoreVisible) {
75562            return;
75563          }
75564
75565          var currentOffset = self.$results.offset().top +
75566            self.$results.outerHeight(false);
75567          var loadingMoreOffset = self.$loadingMore.offset().top +
75568            self.$loadingMore.outerHeight(false);
75569
75570          if (currentOffset + 50 >= loadingMoreOffset) {
75571            self.loadMore();
75572          }
75573        });
75574      };
75575
75576      InfiniteScroll.prototype.loadMore = function () {
75577        this.loading = true;
75578
75579        var params = $.extend({}, {page: 1}, this.lastParams);
75580
75581        params.page++;
75582
75583        this.trigger('query:append', params);
75584      };
75585
75586      InfiniteScroll.prototype.showLoadingMore = function (_, data) {
75587        return data.pagination && data.pagination.more;
75588      };
75589
75590      InfiniteScroll.prototype.createLoadingMore = function () {
75591        var $option = $(
75592          '<li ' +
75593          'class="select2-results__option select2-results__option--load-more"' +
75594          'role="treeitem" aria-disabled="true"></li>'
75595        );
75596
75597        var message = this.options.get('translations').get('loadingMore');
75598
75599        $option.html(message(this.lastParams));
75600
75601        return $option;
75602      };
75603
75604      return InfiniteScroll;
75605    });
75606
75607    S2.define('select2/dropdown/attachBody',[
75608      'jquery',
75609      '../utils'
75610    ], function ($, Utils) {
75611      function AttachBody (decorated, $element, options) {
75612        this.$dropdownParent = options.get('dropdownParent') || $(document.body);
75613
75614        decorated.call(this, $element, options);
75615      }
75616
75617      AttachBody.prototype.bind = function (decorated, container, $container) {
75618        var self = this;
75619
75620        var setupResultsEvents = false;
75621
75622        decorated.call(this, container, $container);
75623
75624        container.on('open', function () {
75625          self._showDropdown();
75626          self._attachPositioningHandler(container);
75627
75628          if (!setupResultsEvents) {
75629            setupResultsEvents = true;
75630
75631            container.on('results:all', function () {
75632              self._positionDropdown();
75633              self._resizeDropdown();
75634            });
75635
75636            container.on('results:append', function () {
75637              self._positionDropdown();
75638              self._resizeDropdown();
75639            });
75640          }
75641        });
75642
75643        container.on('close', function () {
75644          self._hideDropdown();
75645          self._detachPositioningHandler(container);
75646        });
75647
75648        this.$dropdownContainer.on('mousedown', function (evt) {
75649          evt.stopPropagation();
75650        });
75651      };
75652
75653      AttachBody.prototype.destroy = function (decorated) {
75654        decorated.call(this);
75655
75656        this.$dropdownContainer.remove();
75657      };
75658
75659      AttachBody.prototype.position = function (decorated, $dropdown, $container) {
75660        // Clone all of the container classes
75661        $dropdown.attr('class', $container.attr('class'));
75662
75663        $dropdown.removeClass('select2');
75664        $dropdown.addClass('select2-container--open');
75665
75666        $dropdown.css({
75667          position: 'absolute',
75668          top: -999999
75669        });
75670
75671        this.$container = $container;
75672      };
75673
75674      AttachBody.prototype.render = function (decorated) {
75675        var $container = $('<span></span>');
75676
75677        var $dropdown = decorated.call(this);
75678        $container.append($dropdown);
75679
75680        this.$dropdownContainer = $container;
75681
75682        return $container;
75683      };
75684
75685      AttachBody.prototype._hideDropdown = function (decorated) {
75686        this.$dropdownContainer.detach();
75687      };
75688
75689      AttachBody.prototype._attachPositioningHandler =
75690        function (decorated, container) {
75691          var self = this;
75692
75693          var scrollEvent = 'scroll.select2.' + container.id;
75694          var resizeEvent = 'resize.select2.' + container.id;
75695          var orientationEvent = 'orientationchange.select2.' + container.id;
75696
75697          var $watchers = this.$container.parents().filter(Utils.hasScroll);
75698          $watchers.each(function () {
75699            $(this).data('select2-scroll-position', {
75700              x: $(this).scrollLeft(),
75701              y: $(this).scrollTop()
75702            });
75703          });
75704
75705          $watchers.on(scrollEvent, function (ev) {
75706            var position = $(this).data('select2-scroll-position');
75707            $(this).scrollTop(position.y);
75708          });
75709
75710          $(window).on(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent,
75711            function (e) {
75712              self._positionDropdown();
75713              self._resizeDropdown();
75714            });
75715        };
75716
75717      AttachBody.prototype._detachPositioningHandler =
75718        function (decorated, container) {
75719          var scrollEvent = 'scroll.select2.' + container.id;
75720          var resizeEvent = 'resize.select2.' + container.id;
75721          var orientationEvent = 'orientationchange.select2.' + container.id;
75722
75723          var $watchers = this.$container.parents().filter(Utils.hasScroll);
75724          $watchers.off(scrollEvent);
75725
75726          $(window).off(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent);
75727        };
75728
75729      AttachBody.prototype._positionDropdown = function () {
75730        var $window = $(window);
75731
75732        var isCurrentlyAbove = this.$dropdown.hasClass('select2-dropdown--above');
75733        var isCurrentlyBelow = this.$dropdown.hasClass('select2-dropdown--below');
75734
75735        var newDirection = null;
75736
75737        var offset = this.$container.offset();
75738
75739        offset.bottom = offset.top + this.$container.outerHeight(false);
75740
75741        var container = {
75742          height: this.$container.outerHeight(false)
75743        };
75744
75745        container.top = offset.top;
75746        container.bottom = offset.top + container.height;
75747
75748        var dropdown = {
75749          height: this.$dropdown.outerHeight(false)
75750        };
75751
75752        var viewport = {
75753          top: $window.scrollTop(),
75754          bottom: $window.scrollTop() + $window.height()
75755        };
75756
75757        var enoughRoomAbove = viewport.top < (offset.top - dropdown.height);
75758        var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height);
75759
75760        var css = {
75761          left: offset.left,
75762          top: container.bottom
75763        };
75764
75765        // Determine what the parent element is to use for calciulating the offset
75766        var $offsetParent = this.$dropdownParent;
75767
75768        // For statically positoned elements, we need to get the element
75769        // that is determining the offset
75770        if ($offsetParent.css('position') === 'static') {
75771          $offsetParent = $offsetParent.offsetParent();
75772        }
75773
75774        var parentOffset = $offsetParent.offset();
75775
75776        css.top -= parentOffset.top;
75777        css.left -= parentOffset.left;
75778
75779        if (!isCurrentlyAbove && !isCurrentlyBelow) {
75780          newDirection = 'below';
75781        }
75782
75783        if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) {
75784          newDirection = 'above';
75785        } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) {
75786          newDirection = 'below';
75787        }
75788
75789        if (newDirection == 'above' ||
75790          (isCurrentlyAbove && newDirection !== 'below')) {
75791          css.top = container.top - parentOffset.top - dropdown.height;
75792        }
75793
75794        if (newDirection != null) {
75795          this.$dropdown
75796            .removeClass('select2-dropdown--below select2-dropdown--above')
75797            .addClass('select2-dropdown--' + newDirection);
75798          this.$container
75799            .removeClass('select2-container--below select2-container--above')
75800            .addClass('select2-container--' + newDirection);
75801        }
75802
75803        this.$dropdownContainer.css(css);
75804      };
75805
75806      AttachBody.prototype._resizeDropdown = function () {
75807        var css = {
75808          width: this.$container.outerWidth(false) + 'px'
75809        };
75810
75811        if (this.options.get('dropdownAutoWidth')) {
75812          css.minWidth = css.width;
75813          css.position = 'relative';
75814          css.width = 'auto';
75815        }
75816
75817        this.$dropdown.css(css);
75818      };
75819
75820      AttachBody.prototype._showDropdown = function (decorated) {
75821        this.$dropdownContainer.appendTo(this.$dropdownParent);
75822
75823        this._positionDropdown();
75824        this._resizeDropdown();
75825      };
75826
75827      return AttachBody;
75828    });
75829
75830    S2.define('select2/dropdown/minimumResultsForSearch',[
75831
75832    ], function () {
75833      function countResults (data) {
75834        var count = 0;
75835
75836        for (var d = 0; d < data.length; d++) {
75837          var item = data[d];
75838
75839          if (item.children) {
75840            count += countResults(item.children);
75841          } else {
75842            count++;
75843          }
75844        }
75845
75846        return count;
75847      }
75848
75849      function MinimumResultsForSearch (decorated, $element, options, dataAdapter) {
75850        this.minimumResultsForSearch = options.get('minimumResultsForSearch');
75851
75852        if (this.minimumResultsForSearch < 0) {
75853          this.minimumResultsForSearch = Infinity;
75854        }
75855
75856        decorated.call(this, $element, options, dataAdapter);
75857      }
75858
75859      MinimumResultsForSearch.prototype.showSearch = function (decorated, params) {
75860        if (countResults(params.data.results) < this.minimumResultsForSearch) {
75861          return false;
75862        }
75863
75864        return decorated.call(this, params);
75865      };
75866
75867      return MinimumResultsForSearch;
75868    });
75869
75870    S2.define('select2/dropdown/selectOnClose',[
75871
75872    ], function () {
75873      function SelectOnClose () { }
75874
75875      SelectOnClose.prototype.bind = function (decorated, container, $container) {
75876        var self = this;
75877
75878        decorated.call(this, container, $container);
75879
75880        container.on('close', function (params) {
75881          self._handleSelectOnClose(params);
75882        });
75883      };
75884
75885      SelectOnClose.prototype._handleSelectOnClose = function (_, params) {
75886        if (params && params.originalselect2Event != null) {
75887          var event = params.originalselect2Event;
75888
75889          // Don't select an item if the close event was triggered from a select or
75890          // unselect event
75891          if (event._type === 'select' || event._type === 'unselect') {
75892            return;
75893          }
75894        }
75895
75896        var $highlightedResults = this.getHighlightedResults();
75897
75898        // Only select highlighted results
75899        if ($highlightedResults.length < 1) {
75900          return;
75901        }
75902
75903        var data = $highlightedResults.data('data');
75904
75905        // Don't re-select already selected resulte
75906        if (
75907          (data.element != null && data.element.selected) ||
75908          (data.element == null && data.selected)
75909        ) {
75910          return;
75911        }
75912
75913        this.trigger('select', {
75914          data: data
75915        });
75916      };
75917
75918      return SelectOnClose;
75919    });
75920
75921    S2.define('select2/dropdown/closeOnSelect',[
75922
75923    ], function () {
75924      function CloseOnSelect () { }
75925
75926      CloseOnSelect.prototype.bind = function (decorated, container, $container) {
75927        var self = this;
75928
75929        decorated.call(this, container, $container);
75930
75931        container.on('select', function (evt) {
75932          self._selectTriggered(evt);
75933        });
75934
75935        container.on('unselect', function (evt) {
75936          self._selectTriggered(evt);
75937        });
75938      };
75939
75940      CloseOnSelect.prototype._selectTriggered = function (_, evt) {
75941        var originalEvent = evt.originalEvent;
75942
75943        // Don't close if the control key is being held
75944        if (originalEvent && originalEvent.ctrlKey) {
75945          return;
75946        }
75947
75948        this.trigger('close', {
75949          originalEvent: originalEvent,
75950          originalselect2Event: evt
75951        });
75952      };
75953
75954      return CloseOnSelect;
75955    });
75956
75957    S2.define('select2/i18n/en',[],function () {
75958      // English
75959      return {
75960        errorLoading: function () {
75961          return 'The results could not be loaded.';
75962        },
75963        inputTooLong: function (args) {
75964          var overChars = args.input.length - args.maximum;
75965
75966          var message = 'Please delete ' + overChars + ' character';
75967
75968          if (overChars != 1) {
75969            message += 's';
75970          }
75971
75972          return message;
75973        },
75974        inputTooShort: function (args) {
75975          var remainingChars = args.minimum - args.input.length;
75976
75977          var message = 'Please enter ' + remainingChars + ' or more characters';
75978
75979          return message;
75980        },
75981        loadingMore: function () {
75982          return 'Loading more results…';
75983        },
75984        maximumSelected: function (args) {
75985          var message = 'You can only select ' + args.maximum + ' item';
75986
75987          if (args.maximum != 1) {
75988            message += 's';
75989          }
75990
75991          return message;
75992        },
75993        noResults: function () {
75994          return 'No results found';
75995        },
75996        searching: function () {
75997          return 'Searching…';
75998        }
75999      };
76000    });
76001
76002    S2.define('select2/defaults',[
76003      'jquery',
76004      'require',
76005
76006      './results',
76007
76008      './selection/single',
76009      './selection/multiple',
76010      './selection/placeholder',
76011      './selection/allowClear',
76012      './selection/search',
76013      './selection/eventRelay',
76014
76015      './utils',
76016      './translation',
76017      './diacritics',
76018
76019      './data/select',
76020      './data/array',
76021      './data/ajax',
76022      './data/tags',
76023      './data/tokenizer',
76024      './data/minimumInputLength',
76025      './data/maximumInputLength',
76026      './data/maximumSelectionLength',
76027
76028      './dropdown',
76029      './dropdown/search',
76030      './dropdown/hidePlaceholder',
76031      './dropdown/infiniteScroll',
76032      './dropdown/attachBody',
76033      './dropdown/minimumResultsForSearch',
76034      './dropdown/selectOnClose',
76035      './dropdown/closeOnSelect',
76036
76037      './i18n/en'
76038    ], function ($, require,
76039
76040                 ResultsList,
76041
76042                 SingleSelection, MultipleSelection, Placeholder, AllowClear,
76043                 SelectionSearch, EventRelay,
76044
76045                 Utils, Translation, DIACRITICS,
76046
76047                 SelectData, ArrayData, AjaxData, Tags, Tokenizer,
76048                 MinimumInputLength, MaximumInputLength, MaximumSelectionLength,
76049
76050                 Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll, searchInputPlaceholder, hideInput,
76051                 AttachBody, MinimumResultsForSearch, SelectOnClose, CloseOnSelect,
76052
76053                 EnglishTranslation) {
76054      function Defaults () {
76055        this.reset();
76056      }
76057
76058      Defaults.prototype.apply = function (options) {
76059        options = $.extend(true, {}, this.defaults, options);
76060
76061        if (options.dataAdapter == null) {
76062          if (options.ajax != null) {
76063            options.dataAdapter = AjaxData;
76064          } else if (options.data != null) {
76065            options.dataAdapter = ArrayData;
76066          } else {
76067            options.dataAdapter = SelectData;
76068          }
76069
76070          if (options.minimumInputLength > 0) {
76071            options.dataAdapter = Utils.Decorate(
76072              options.dataAdapter,
76073              MinimumInputLength
76074            );
76075          }
76076
76077          if (options.maximumInputLength > 0) {
76078            options.dataAdapter = Utils.Decorate(
76079              options.dataAdapter,
76080              MaximumInputLength
76081            );
76082          }
76083
76084          if (options.maximumSelectionLength > 0) {
76085            options.dataAdapter = Utils.Decorate(
76086              options.dataAdapter,
76087              MaximumSelectionLength
76088            );
76089          }
76090
76091          if (options.tags) {
76092            options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags);
76093          }
76094
76095          if (options.tokenSeparators != null || options.tokenizer != null) {
76096            options.dataAdapter = Utils.Decorate(
76097              options.dataAdapter,
76098              Tokenizer
76099            );
76100          }
76101
76102          if (options.query != null) {
76103            var Query = require(options.amdBase + 'compat/query');
76104
76105            options.dataAdapter = Utils.Decorate(
76106              options.dataAdapter,
76107              Query
76108            );
76109          }
76110
76111          if (options.initSelection != null) {
76112            var InitSelection = require(options.amdBase + 'compat/initSelection');
76113
76114            options.dataAdapter = Utils.Decorate(
76115              options.dataAdapter,
76116              InitSelection
76117            );
76118          }
76119        }
76120
76121        if (options.resultsAdapter == null) {
76122          options.resultsAdapter = ResultsList;
76123
76124          if (options.ajax != null) {
76125            options.resultsAdapter = Utils.Decorate(
76126              options.resultsAdapter,
76127              InfiniteScroll
76128            );
76129          }
76130
76131          if (options.placeholder != null) {
76132            options.resultsAdapter = Utils.Decorate(
76133              options.resultsAdapter,
76134              HidePlaceholder
76135            );
76136          }
76137
76138          if (options.selectOnClose) {
76139            options.resultsAdapter = Utils.Decorate(
76140              options.resultsAdapter,
76141              SelectOnClose
76142            );
76143          }
76144        }
76145
76146        if (options.dropdownAdapter == null) {
76147          if (options.multiple) {
76148            options.dropdownAdapter = Dropdown;
76149          } else {
76150            var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch, searchInputPlaceholder);
76151
76152            options.dropdownAdapter = SearchableDropdown;
76153          }
76154
76155          if (options.minimumResultsForSearch !== 0) {
76156            options.dropdownAdapter = Utils.Decorate(
76157              options.dropdownAdapter,
76158              MinimumResultsForSearch
76159            );
76160          }
76161
76162          if (options.closeOnSelect) {
76163            options.dropdownAdapter = Utils.Decorate(
76164              options.dropdownAdapter,
76165              CloseOnSelect
76166            );
76167          }
76168
76169          if (
76170            options.dropdownCssClass != null ||
76171            options.dropdownCss != null ||
76172            options.adaptDropdownCssClass != null
76173          ) {
76174            var DropdownCSS = require(options.amdBase + 'compat/dropdownCss');
76175
76176            options.dropdownAdapter = Utils.Decorate(
76177              options.dropdownAdapter,
76178              DropdownCSS
76179            );
76180          }
76181
76182          options.dropdownAdapter = Utils.Decorate(
76183            options.dropdownAdapter,
76184            AttachBody
76185          );
76186        }
76187
76188        if (options.selectionAdapter == null) {
76189          if (options.multiple) {
76190            options.selectionAdapter = MultipleSelection;
76191          } else {
76192            options.selectionAdapter = SingleSelection;
76193          }
76194
76195          // Add the placeholder mixin if a placeholder was specified
76196          if (options.placeholder != null) {
76197            options.selectionAdapter = Utils.Decorate(
76198              options.selectionAdapter,
76199              Placeholder
76200            );
76201          }
76202
76203          if (options.allowClear) {
76204            options.selectionAdapter = Utils.Decorate(
76205              options.selectionAdapter,
76206              AllowClear
76207            );
76208          }
76209
76210          if (options.multiple) {
76211            options.selectionAdapter = Utils.Decorate(
76212              options.selectionAdapter,
76213              SelectionSearch
76214            );
76215          }
76216
76217          if (
76218            options.containerCssClass != null ||
76219            options.containerCss != null ||
76220            options.adaptContainerCssClass != null
76221          ) {
76222            var ContainerCSS = require(options.amdBase + 'compat/containerCss');
76223
76224            options.selectionAdapter = Utils.Decorate(
76225              options.selectionAdapter,
76226              ContainerCSS
76227            );
76228          }
76229
76230          options.selectionAdapter = Utils.Decorate(
76231            options.selectionAdapter,
76232            EventRelay
76233          );
76234        }
76235
76236        if (typeof options.language === 'string') {
76237          // Check if the language is specified with a region
76238          if (options.language.indexOf('-') > 0) {
76239            // Extract the region information if it is included
76240            var languageParts = options.language.split('-');
76241            var baseLanguage = languageParts[0];
76242
76243            options.language = [options.language, baseLanguage];
76244          } else {
76245            options.language = [options.language];
76246          }
76247        }
76248
76249        if ($.isArray(options.language)) {
76250          var languages = new Translation();
76251          options.language.push('en');
76252
76253          var languageNames = options.language;
76254
76255          for (var l = 0; l < languageNames.length; l++) {
76256            var name = languageNames[l];
76257            var language = {};
76258
76259            try {
76260              // Try to load it with the original name
76261              language = Translation.loadPath(name);
76262            } catch (e) {
76263              try {
76264                // If we couldn't load it, check if it wasn't the full path
76265                name = this.defaults.amdLanguageBase + name;
76266                language = Translation.loadPath(name);
76267              } catch (ex) {
76268                // The translation could not be loaded at all. Sometimes this is
76269                // because of a configuration problem, other times this can be
76270                // because of how select2 helps load all possible translation files.
76271                if (options.debug && window.console && console.warn) {
76272                  console.warn(
76273                    'select2: The language file for "' + name + '" could not be ' +
76274                    'automatically loaded. A fallback will be used instead.'
76275                  );
76276                }
76277
76278                continue;
76279              }
76280            }
76281
76282            languages.extend(language);
76283          }
76284
76285          options.translations = languages;
76286        } else {
76287          var baseTranslation = Translation.loadPath(
76288            this.defaults.amdLanguageBase + 'en'
76289          );
76290          var customTranslation = new Translation(options.language);
76291
76292          customTranslation.extend(baseTranslation);
76293
76294          options.translations = customTranslation;
76295        }
76296
76297        return options;
76298      };
76299
76300      Defaults.prototype.reset = function () {
76301        function stripDiacritics (text) {
76302          // Used 'uni range + named function' from http://jsperf.com/diacritics/18
76303          function match(a) {
76304            return DIACRITICS[a] || a;
76305          }
76306
vendor: 16,384 bytes, lines 76307-76872
76307          return text.replace(/[^\u0000-\u007E]/g, match);
76308        }
76309
76310        function matcher (params, data) {
76311          // Always return the object if there is nothing to compare
76312          if ($.trim(params.term) === '') {
76313            return data;
76314          }
76315
76316          // Do a recursive check for options with children
76317          if (data.children && data.children.length > 0) {
76318            // Clone the data object if there are children
76319            // This is required as we modify the object to remove any non-matches
76320            var match = $.extend(true, {}, data);
76321
76322            // Check each child of the option
76323            for (var c = data.children.length - 1; c >= 0; c--) {
76324              var child = data.children[c];
76325
76326              var matches = matcher(params, child);
76327
76328              // If there wasn't a match, remove the object in the array
76329              if (matches == null) {
76330                match.children.splice(c, 1);
76331              }
76332            }
76333
76334            // If any children matched, return the new object
76335            if (match.children.length > 0) {
76336              return match;
76337            }
76338
76339            // If there were no matching children, check just the plain object
76340            return matcher(params, match);
76341          }
76342
76343          var original = stripDiacritics(data.text).toUpperCase();
76344          var term = stripDiacritics(params.term).toUpperCase();
76345
76346          // Check if the text contains the term
76347          if (original.indexOf(term) > -1) {
76348            return data;
76349          }
76350
76351          // If it doesn't contain the term, don't return anything
76352          return null;
76353        }
76354
76355        this.defaults = {
76356          amdBase: './',
76357          amdLanguageBase: './i18n/',
76358          closeOnSelect: true,
76359          debug: false,
76360          dropdownAutoWidth: false,
76361          escapeMarkup: Utils.escapeMarkup,
76362          language: EnglishTranslation,
76363          matcher: matcher,
76364          minimumInputLength: 0,
76365          maximumInputLength: 0,
76366          maximumSelectionLength: 0,
76367          minimumResultsForSearch: 0,
76368          selectOnClose: false,
76369          sorter: function (data) {
76370            return data;
76371          },
76372          templateResult: function (result) {
76373            return result.text;
76374          },
76375          templateSelection: function (selection) {
76376            return selection.text;
76377          },
76378          theme: 'default',
76379          width: 'resolve'
76380        };
76381      };
76382
76383      Defaults.prototype.set = function (key, value) {
76384        var camelKey = $.camelCase(key);
76385
76386        var data = {};
76387        data[camelKey] = value;
76388
76389        var convertedData = Utils._convertData(data);
76390
76391        $.extend(this.defaults, convertedData);
76392      };
76393
76394      var defaults = new Defaults();
76395
76396      return defaults;
76397    });
76398
76399    S2.define('select2/options',[
76400      'require',
76401      'jquery',
76402      './defaults',
76403      './utils'
76404    ], function (require, $, Defaults, Utils) {
76405      function Options (options, $element) {
76406        this.options = options;
76407
76408        if ($element != null) {
76409          this.fromElement($element);
76410        }
76411
76412        this.options = Defaults.apply(this.options);
76413
76414        if ($element && $element.is('input')) {
76415          var InputCompat = require(this.get('amdBase') + 'compat/inputData');
76416
76417          this.options.dataAdapter = Utils.Decorate(
76418            this.options.dataAdapter,
76419            InputCompat
76420          );
76421        }
76422      }
76423
76424      Options.prototype.fromElement = function ($e) {
76425        var excludedData = ['select2'];
76426
76427        if (this.options.multiple == null) {
76428          this.options.multiple = $e.prop('multiple');
76429        }
76430
76431        if (this.options.disabled == null) {
76432          this.options.disabled = $e.prop('disabled');
76433        }
76434
76435        if (this.options.language == null) {
76436          if ($e.prop('lang')) {
76437            this.options.language = $e.prop('lang').toLowerCase();
76438          } else if ($e.closest('[lang]').prop('lang')) {
76439            this.options.language = $e.closest('[lang]').prop('lang');
76440          }
76441        }
76442
76443        if (this.options.dir == null) {
76444          if ($e.prop('dir')) {
76445            this.options.dir = $e.prop('dir');
76446          } else if ($e.closest('[dir]').prop('dir')) {
76447            this.options.dir = $e.closest('[dir]').prop('dir');
76448          } else {
76449            this.options.dir = 'ltr';
76450          }
76451        }
76452
76453        $e.prop('disabled', this.options.disabled);
76454        $e.prop('multiple', this.options.multiple);
76455
76456        if ($e.data('select2Tags')) {
76457          if (this.options.debug && window.console && console.warn) {
76458            console.warn(
76459              'select2: The `data-select2-tags` attribute has been changed to ' +
76460              'use the `data-data` and `data-tags="true"` attributes and will be ' +
76461              'removed in future versions of select2.'
76462            );
76463          }
76464
76465          $e.data('data', $e.data('select2Tags'));
76466          $e.data('tags', true);
76467        }
76468
76469        if ($e.data('ajaxUrl')) {
76470          if (this.options.debug && window.console && console.warn) {
76471            console.warn(
76472              'select2: The `data-ajax-url` attribute has been changed to ' +
76473              '`data-ajax--url` and support for the old attribute will be removed' +
76474              ' in future versions of select2.'
76475            );
76476          }
76477
76478          $e.attr('ajax--url', $e.data('ajaxUrl'));
76479          $e.data('ajax--url', $e.data('ajaxUrl'));
76480        }
76481
76482        var dataset = {};
76483
76484        // Prefer the element's `dataset` attribute if it exists
76485        // jQuery 1.x does not correctly handle data attributes with multiple dashes
76486        if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) {
76487          dataset = $.extend(true, {}, $e[0].dataset, $e.data());
76488        } else {
76489          dataset = $e.data();
76490        }
76491
76492        var data = $.extend(true, {}, dataset);
76493
76494        data = Utils._convertData(data);
76495
76496        for (var key in data) {
76497          if ($.inArray(key, excludedData) > -1) {
76498            continue;
76499          }
76500
76501          if ($.isPlainObject(this.options[key])) {
76502            $.extend(this.options[key], data[key]);
76503          } else {
76504            this.options[key] = data[key];
76505          }
76506        }
76507
76508        return this;
76509      };
76510
76511      Options.prototype.get = function (key) {
76512        return this.options[key];
76513      };
76514
76515      Options.prototype.set = function (key, val) {
76516        this.options[key] = val;
76517      };
76518
76519      return Options;
76520    });
76521
76522    S2.define('select2/core',[
76523      'jquery',
76524      './options',
76525      './utils',
76526      './keys'
76527    ], function ($, Options, Utils, KEYS) {
76528      var select2 = function ($element, options) {
76529        if ($element.data('select2') != null) {
76530          $element.data('select2').destroy();
76531        }
76532
76533        this.$element = $element;
76534
76535        this.id = this._generateId($element);
76536
76537        options = options || {};
76538
76539        this.options = new Options(options, $element);
76540
76541        select2.__super__.constructor.call(this);
76542
76543        // Set up the tabindex
76544
76545        var tabindex = $element.attr('tabindex') || 0;
76546        $element.data('old-tabindex', tabindex);
76547        $element.attr('tabindex', '-1');
76548
76549        // Set up containers and adapters
76550
76551        var DataAdapter = this.options.get('dataAdapter');
76552        this.dataAdapter = new DataAdapter($element, this.options);
76553
76554        var $container = this.render();
76555
76556        this._placeContainer($container);
76557
76558        var SelectionAdapter = this.options.get('selectionAdapter');
76559        this.selection = new SelectionAdapter($element, this.options);
76560        this.$selection = this.selection.render();
76561
76562        this.selection.position(this.$selection, $container);
76563
76564        var DropdownAdapter = this.options.get('dropdownAdapter');
76565        this.dropdown = new DropdownAdapter($element, this.options);
76566        this.$dropdown = this.dropdown.render();
76567
76568        this.dropdown.position(this.$dropdown, $container);
76569
76570        var ResultsAdapter = this.options.get('resultsAdapter');
76571        this.results = new ResultsAdapter($element, this.options, this.dataAdapter);
76572        this.$results = this.results.render();
76573
76574        this.results.position(this.$results, this.$dropdown);
76575
76576        // Bind events
76577
76578        var self = this;
76579
76580        // Bind the container to all of the adapters
76581        this._bindAdapters();
76582
76583        // Register any DOM event handlers
76584        this._registerDomEvents();
76585
76586        // Register any internal event handlers
76587        this._registerDataEvents();
76588        this._registerSelectionEvents();
76589        this._registerDropdownEvents();
76590        this._registerResultsEvents();
76591        this._registerEvents();
76592
76593        // Set the initial state
76594        this.dataAdapter.current(function (initialData) {
76595          self.trigger('selection:update', {
76596            data: initialData
76597          });
76598        });
76599
76600        // Hide the original select
76601        $element.addClass('select2-hidden-accessible');
76602        $element.attr('aria-hidden', 'true');
76603
76604        // Synchronize any monitored attributes
76605        this._syncAttributes();
76606
76607        $element.data('select2', this);
76608      };
76609
76610      Utils.Extend(select2, Utils.Observable);
76611
76612      select2.prototype._generateId = function ($element) {
76613        var id = '';
76614
76615        if ($element.attr('id') != null) {
76616          id = $element.attr('id');
76617        } else if ($element.attr('name') != null) {
76618          id = $element.attr('name') + '-' + Utils.generateChars(2);
76619        } else {
76620          id = Utils.generateChars(4);
76621        }
76622
76623        id = id.replace(/(:|\.|\[|\]|,)/g, '');
76624        id = 'select2-' + id;
76625
76626        return id;
76627      };
76628
76629      select2.prototype._placeContainer = function ($container) {
76630        $container.insertAfter(this.$element);
76631
76632        var width = this._resolveWidth(this.$element, this.options.get('width'));
76633
76634        if (width != null) {
76635          $container.css('width', width);
76636        }
76637      };
76638
76639      select2.prototype._resolveWidth = function ($element, method) {
76640        var WIDTH = /^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;
76641
76642        if (method == 'resolve') {
76643          var styleWidth = this._resolveWidth($element, 'style');
76644
76645          if (styleWidth != null) {
76646            return styleWidth;
76647          }
76648
76649          return this._resolveWidth($element, 'element');
76650        }
76651
76652        if (method == 'element') {
76653          var elementWidth = $element.outerWidth(false);
76654
76655          if (elementWidth <= 0) {
76656            return 'auto';
76657          }
76658
76659          return elementWidth + 'px';
76660        }
76661
76662        if (method == 'style') {
76663          var style = $element.attr('style');
76664
76665          if (typeof(style) !== 'string') {
76666            return null;
76667          }
76668
76669          var attrs = style.split(';');
76670
76671          for (var i = 0, l = attrs.length; i < l; i = i + 1) {
76672            var attr = attrs[i].replace(/\s/g, '');
76673            var matches = attr.match(WIDTH);
76674
76675            if (matches !== null && matches.length >= 1) {
76676              return matches[1];
76677            }
76678          }
76679
76680          return null;
76681        }
76682
76683        return method;
76684      };
76685
76686      select2.prototype._bindAdapters = function () {
76687        this.dataAdapter.bind(this, this.$container);
76688        this.selection.bind(this, this.$container);
76689
76690        this.dropdown.bind(this, this.$container);
76691        this.results.bind(this, this.$container);
76692      };
76693
76694      select2.prototype._registerDomEvents = function () {
76695        var self = this;
76696
76697        this.$element.on('change.select2', function () {
76698          self.dataAdapter.current(function (data) {
76699            self.trigger('selection:update', {
76700              data: data
76701            });
76702          });
76703        });
76704
76705        this.$element.on('focus.select2', function (evt) {
76706          self.trigger('focus', evt);
76707        });
76708
76709        this._syncA = Utils.bind(this._syncAttributes, this);
76710        this._syncS = Utils.bind(this._syncSubtree, this);
76711
76712        if (this.$element[0].attachEvent) {
76713          this.$element[0].attachEvent('onpropertychange', this._syncA);
76714        }
76715
76716        var observer = window.MutationObserver ||
76717          window.WebKitMutationObserver ||
76718          window.MozMutationObserver
76719        ;
76720
76721        if (observer != null) {
76722          this._observer = new observer(function (mutations) {
76723            $.each(mutations, self._syncA);
76724            $.each(mutations, self._syncS);
76725          });
76726          this._observer.observe(this.$element[0], {
76727            attributes: true,
76728            childList: true,
76729            subtree: false
76730          });
76731        } else if (this.$element[0].addEventListener) {
76732          this.$element[0].addEventListener(
76733            'DOMAttrModified',
76734            self._syncA,
76735            false
76736          );
76737          this.$element[0].addEventListener(
76738            'DOMNodeInserted',
76739            self._syncS,
76740            false
76741          );
76742          this.$element[0].addEventListener(
76743            'DOMNodeRemoved',
76744            self._syncS,
76745            false
76746          );
76747        }
76748      };
76749
76750      select2.prototype._registerDataEvents = function () {
76751        var self = this;
76752
76753        this.dataAdapter.on('*', function (name, params) {
76754          self.trigger(name, params);
76755        });
76756      };
76757
76758      select2.prototype._registerSelectionEvents = function () {
76759        var self = this;
76760        var nonRelayEvents = ['toggle', 'focus'];
76761
76762        this.selection.on('toggle', function () {
76763          self.toggleDropdown();
76764        });
76765
76766        this.selection.on('focus', function (params) {
76767          self.focus(params);
76768        });
76769
76770        this.selection.on('*', function (name, params) {
76771          if ($.inArray(name, nonRelayEvents) !== -1) {
76772            return;
76773          }
76774
76775          self.trigger(name, params);
76776        });
76777      };
76778
76779      select2.prototype._registerDropdownEvents = function () {
76780        var self = this;
76781
76782        this.dropdown.on('*', function (name, params) {
76783          self.trigger(name, params);
76784        });
76785      };
76786
76787      select2.prototype._registerResultsEvents = function () {
76788        var self = this;
76789
76790        this.results.on('*', function (name, params) {
76791          self.trigger(name, params);
76792        });
76793      };
76794
76795      select2.prototype._registerEvents = function () {
76796        var self = this;
76797
76798        this.on('open', function () {
76799          self.$container.addClass('select2-container--open');
76800        });
76801
76802        this.on('close', function () {
76803          self.$container.removeClass('select2-container--open');
76804        });
76805
76806        this.on('enable', function () {
76807          self.$container.removeClass('select2-container--disabled');
76808        });
76809
76810        this.on('disable', function () {
76811          self.$container.addClass('select2-container--disabled');
76812        });
76813
76814        this.on('blur', function () {
76815          self.$container.removeClass('select2-container--focus');
76816        });
76817
76818        this.on('query', function (params) {
76819          if (!self.isOpen()) {
76820            self.trigger('open', {});
76821          }
76822
76823          this.dataAdapter.query(params, function (data) {
76824            self.trigger('results:all', {
76825              data: data,
76826              query: params
76827            });
76828          });
76829        });
76830
76831        this.on('query:append', function (params) {
76832          this.dataAdapter.query(params, function (data) {
76833            self.trigger('results:append', {
76834              data: data,
76835              query: params
76836            });
76837          });
76838        });
76839
76840        this.on('keypress', function (evt) {
76841          var key = evt.which;
76842
76843          if (self.isOpen()) {
76844            if (key === KEYS.ESC || key === KEYS.TAB ||
76845              (key === KEYS.UP && evt.altKey)) {
76846              self.close();
76847
76848              evt.preventDefault();
76849            } else if (key === KEYS.ENTER) {
76850              self.trigger('results:select', {});
76851
76852              evt.preventDefault();
76853            } else if ((key === KEYS.SPACE && evt.ctrlKey)) {
76854              self.trigger('results:toggle', {});
76855
76856              evt.preventDefault();
76857            } else if (key === KEYS.UP) {
76858              self.trigger('results:previous', {});
76859
76860              evt.preventDefault();
76861            } else if (key === KEYS.DOWN) {
76862              self.trigger('results:next', {});
76863
76864              evt.preventDefault();
76865            }
76866          } else {
76867            if (key === KEYS.ENTER || key === KEYS.SPACE ||
76868              (key === KEYS.DOWN && evt.altKey)) {
76869              self.open();
76870
76871              evt.preventDefault();
76872            }
76872
76873          }
76874        });
76875      };
76876
76877      select2.prototype._syncAttributes = function () {
76878        this.options.set('disabled', this.$element.prop('disabled'));
76879
76880        if (this.options.get('disabled')) {
76881          if (this.isOpen()) {
76882            this.close();
76883          }
76884
76885          this.trigger('disable', {});
76886        } else {
76887          this.trigger('enable', {});
76888        }
76889      };
76890
76891      select2.prototype._syncSubtree = function (evt, mutations) {
76892        var changed = false;
76893        var self = this;
76894
76895        // Ignore any mutation events raised for elements that aren't options or
76896        // optgroups. This handles the case when the select element is destroyed
76897        if (
76898          evt && evt.target && (
76899            evt.target.nodeName !== 'OPTION' && evt.target.nodeName !== 'OPTGROUP'
76900          )
76901        ) {
76902          return;
76903        }
76904
76905        if (!mutations) {
76906          // If mutation events aren't supported, then we can only assume that the
76907          // change affected the selections
76908          changed = true;
76909        } else if (mutations.addedNodes && mutations.addedNodes.length > 0) {
76910          for (var n = 0; n < mutations.addedNodes.length; n++) {
76911            var node = mutations.addedNodes[n];
76912
76913            if (node.selected) {
76914              changed = true;
76915            }
76916          }
76917        } else if (mutations.removedNodes && mutations.removedNodes.length > 0) {
76918          changed = true;
76919        }
76920
76921        // Only re-pull the data if we think there is a change
76922        if (changed) {
76923          this.dataAdapter.current(function (currentData) {
76924            self.trigger('selection:update', {
76925              data: currentData
76926            });
76927          });
76928        }
76929      };
76930
76931      /**
76932       * Override the trigger method to automatically trigger pre-events when
76933       * there are events that can be prevented.
76934       */
76935      select2.prototype.trigger = function (name, args) {
76936        var actualTrigger = select2.__super__.trigger;
76937        var preTriggerMap = {
76938          'open': 'opening',
76939          'close': 'closing',
76940          'select': 'selecting',
76941          'unselect': 'unselecting'
76942        };
76943
76944        if (args === undefined) {
76945          args = {};
76946        }
76947
76948        if (name in preTriggerMap) {
76949          var preTriggerName = preTriggerMap[name];
76950          var preTriggerArgs = {
76951            prevented: false,
76952            name: name,
76953            args: args
76954          };
76955
76956          actualTrigger.call(this, preTriggerName, preTriggerArgs);
76957
76958          if (preTriggerArgs.prevented) {
76959            args.prevented = true;
76960
76961            return;
76962          }
76963        }
76964
76965        actualTrigger.call(this, name, args);
76966      };
76967
76968      select2.prototype.toggleDropdown = function () {
76969        if (this.options.get('disabled')) {
76970          return;
76971        }
76972
76973        if (this.isOpen()) {
76974          this.close();
76975        } else {
76976          this.open();
76977        }
76978      };
76979
76980      select2.prototype.open = function () {
76981        if (this.isOpen()) {
76982          return;
76983        }
76984
76985        this.trigger('query', {});
76986      };
76987
76988      select2.prototype.close = function () {
76989        if (!this.isOpen()) {
76990          return;
76991        }
76992
76993        this.trigger('close', {});
76994      };
76995
76996      select2.prototype.isOpen = function () {
76997        return this.$container.hasClass('select2-container--open');
76998      };
76999
77000      select2.prototype.hasFocus = function () {
77001        return this.$container.hasClass('select2-container--focus');
77002      };
77003
77004      select2.prototype.focus = function (data) {
77005        // No need to re-trigger focus events if we are already focused
77006        if (this.hasFocus()) {
77007          return;
77008        }
77009
77010        this.$container.addClass('select2-container--focus');
77011        this.trigger('focus', {});
77012      };
77013
77014      select2.prototype.enable = function (args) {
77015        if (this.options.get('debug') && window.console && console.warn) {
77016          console.warn(
77017            'select2: The `select2("enable")` method has been deprecated and will' +
77018            ' be removed in later select2 versions. Use $element.prop("disabled")' +
77019            ' instead.'
77020          );
77021        }
77022
77023        if (args == null || args.length === 0) {
77024          args = [true];
77025        }
77026
77027        var disabled = !args[0];
77028
77029        this.$element.prop('disabled', disabled);
77030      };
77031
77032      select2.prototype.data = function () {
77033        if (this.options.get('debug') &&
77034          arguments.length > 0 && window.console && console.warn) {
77035          console.warn(
77036            'select2: Data can no longer be set using `select2("data")`. You ' +
77037            'should consider setting the value instead using `$element.val()`.'
77038          );
77039        }
77040
77041        var data = [];
77042
77043        this.dataAdapter.current(function (currentData) {
77044          data = currentData;
77045        });
77046
77047        return data;
77048      };
77049
77050      select2.prototype.val = function (args) {
77051        if (this.options.get('debug') && window.console && console.warn) {
77052          console.warn(
77053            'select2: The `select2("val")` method has been deprecated and will be' +
77054            ' removed in later select2 versions. Use $element.val() instead.'
77055          );
77056        }
77057
77058        if (args == null || args.length === 0) {
77059          return this.$element.val();
77060        }
77061
77062        var newVal = args[0];
77063
77064        if ($.isArray(newVal)) {
77065          newVal = $.map(newVal, function (obj) {
77066            return obj.toString();
77067          });
77068        }
77069
77070        this.$element.val(newVal).trigger('change');
77071      };
77072
77073      select2.prototype.destroy = function () {
77074        this.$container.remove();
77075
77076        if (this.$element[0].detachEvent) {
77077          this.$element[0].detachEvent('onpropertychange', this._syncA);
77078        }
77079
77080        if (this._observer != null) {
77081          this._observer.disconnect();
77082          this._observer = null;
77083        } else if (this.$element[0].removeEventListener) {
77084          this.$element[0]
77085            .removeEventListener('DOMAttrModified', this._syncA, false);
77086          this.$element[0]
77087            .removeEventListener('DOMNodeInserted', this._syncS, false);
77088          this.$element[0]
77089            .removeEventListener('DOMNodeRemoved', this._syncS, false);
77090        }
77091
77092        this._syncA = null;
77093        this._syncS = null;
77094
77095        this.$element.off('.select2');
77096        this.$element.attr('tabindex', this.$element.data('old-tabindex'));
77097
77098        this.$element.removeClass('select2-hidden-accessible');
77099        this.$element.attr('aria-hidden', 'false');
77100        this.$element.removeData('select2');
77101
77102        this.dataAdapter.destroy();
77103        this.selection.destroy();
77104        this.dropdown.destroy();
77105        this.results.destroy();
77106
77107        this.dataAdapter = null;
77108        this.selection = null;
77109        this.dropdown = null;
77110        this.results = null;
77111      };
77112
77113      select2.prototype.render = function () {
77114        var $container = $(
77115          '<span class="select2 select2-container">' +
77116          '<span class="selection"></span>' +
77117          '<span class="dropdown-wrapper" aria-hidden="true"></span>' +
77118          '</span>'
77119        );
77120
77121        $container.attr('dir', this.options.get('dir'));
77122
77123        this.$container = $container;
77124
77125        this.$container.addClass('select2-container--' + this.options.get('theme'));
77126
77127        $container.data('element', this.$element);
77128
77129        return $container;
77130      };
77131
77132      return select2;
77133    });
77134
77135    S2.define('select2/compat/utils',[
77136      'jquery'
77137    ], function ($) {
77138      function syncCssClasses ($dest, $src, adapter) {
77139        var classes, replacements = [], adapted;
77140
77141        classes = $.trim($dest.attr('class'));
77142
77143        if (classes) {
77144          classes = '' + classes; // for IE which returns object
77145
77146          $(classes.split(/\s+/)).each(function () {
77147            // Save all select2 classes
77148            if (this.indexOf('select2-') === 0) {
77149              replacements.push(this);
77150            }
77151          });
77152        }
77153
77154        classes = $.trim($src.attr('class'));
77155
77156        if (classes) {
77157          classes = '' + classes; // for IE which returns object
77158
77159          $(classes.split(/\s+/)).each(function () {
77160            // Only adapt non-select2 classes
77161            if (this.indexOf('select2-') !== 0) {
77162              adapted = adapter(this);
77163
77164              if (adapted != null) {
77165                replacements.push(adapted);
77166              }
77167            }
77168          });
77169        }
77170
77171        $dest.attr('class', replacements.join(' '));
77172      }
77173
77174      return {
77175        syncCssClasses: syncCssClasses
77176      };
77177    });
77178
77179    S2.define('select2/compat/containerCss',[
77180      'jquery',
77181      './utils'
77182    ], function ($, CompatUtils) {
77183      // No-op CSS adapter that discards all classes by default
77184      function _containerAdapter (clazz) {
77185        return null;
77186      }
77187
77188      function ContainerCSS () { }
77189
77190      ContainerCSS.prototype.render = function (decorated) {
77191        var $container = decorated.call(this);
77192
77193        var containerCssClass = this.options.get('containerCssClass') || '';
77194
77195        if ($.isFunction(containerCssClass)) {
77196          containerCssClass = containerCssClass(this.$element);
77197        }
77198
77199        var containerCssAdapter = this.options.get('adaptContainerCssClass');
77200        containerCssAdapter = containerCssAdapter || _containerAdapter;
77201
77202        if (containerCssClass.indexOf(':all:') !== -1) {
77203          containerCssClass = containerCssClass.replace(':all:', '');
77204
77205          var _cssAdapter = containerCssAdapter;
77206
77207          containerCssAdapter = function (clazz) {
77208            var adapted = _cssAdapter(clazz);
77209
77210            if (adapted != null) {
77211              // Append the old one along with the adapted one
77212              return adapted + ' ' + clazz;
77213            }
77214
77215            return clazz;
77216          };
77217        }
77218
77219        var containerCss = this.options.get('containerCss') || {};
77220
77221        if ($.isFunction(containerCss)) {
77222          containerCss = containerCss(this.$element);
77223        }
77224
77225        CompatUtils.syncCssClasses($container, this.$element, containerCssAdapter);
77226
77227        $container.css(containerCss);
77228        $container.addClass(containerCssClass);
77229
77230        return $container;
77231      };
77232
77233      return ContainerCSS;
77234    });
77235
77236    S2.define('select2/compat/dropdownCss',[
77237      'jquery',
77238      './utils'
77239    ], function ($, CompatUtils) {
77240      // No-op CSS adapter that discards all classes by default
77241      function _dropdownAdapter (clazz) {
77242        return null;
77243      }
77244
77245      function DropdownCSS () { }
77246
77247      DropdownCSS.prototype.render = function (decorated) {
77248        var $dropdown = decorated.call(this);
77249
77250        var dropdownCssClass = this.options.get('dropdownCssClass') || '';
77251
77252        if ($.isFunction(dropdownCssClass)) {
77253          dropdownCssClass = dropdownCssClass(this.$element);
77254        }
77255
77256        var dropdownCssAdapter = this.options.get('adaptDropdownCssClass');
77257        dropdownCssAdapter = dropdownCssAdapter || _dropdownAdapter;
77258
77259        if (dropdownCssClass.indexOf(':all:') !== -1) {
77260          dropdownCssClass = dropdownCssClass.replace(':all:', '');
77261
77262          var _cssAdapter = dropdownCssAdapter;
77263
77264          dropdownCssAdapter = function (clazz) {
77265            var adapted = _cssAdapter(clazz);
77266
77267            if (adapted != null) {
77268              // Append the old one along with the adapted one
77269              return adapted + ' ' + clazz;
77270            }
77271
77272            return clazz;
77273          };
77274        }
77275
77276        var dropdownCss = this.options.get('dropdownCss') || {};
77277
77278        if ($.isFunction(dropdownCss)) {
77279          dropdownCss = dropdownCss(this.$element);
77280        }
77281
77282        CompatUtils.syncCssClasses($dropdown, this.$element, dropdownCssAdapter);
77283
77284        $dropdown.css(dropdownCss);
77285        $dropdown.addClass(dropdownCssClass);
77286
77287        return $dropdown;
77288      };
77289
77290      return DropdownCSS;
77291    });
77292
77293    S2.define('select2/compat/initSelection',[
77294      'jquery'
77295    ], function ($) {
77296      function InitSelection (decorated, $element, options) {
77297        if (options.get('debug') && window.console && console.warn) {
77298          console.warn(
77299            'select2: The `initSelection` option has been deprecated in favor' +
77300            ' of a custom data adapter that overrides the `current` method. ' +
77301            'This method is now called multiple times instead of a single ' +
77302            'time when the instance is initialized. Support will be removed ' +
77303            'for the `initSelection` option in future versions of select2'
77304          );
77305        }
77306
77307        this.initSelection = options.get('initSelection');
77308        this._isInitialized = false;
77309
77310        decorated.call(this, $element, options);
77311      }
77312
77313      InitSelection.prototype.current = function (decorated, callback) {
77314        var self = this;
77315
77316        if (this._isInitialized) {
77317          decorated.call(this, callback);
77318
77319          return;
77320        }
77321
77322        this.initSelection.call(null, this.$element, function (data) {
77323          self._isInitialized = true;
77324
77325          if (!$.isArray(data)) {
77326            data = [data];
77327          }
77328
77329          callback(data);
77330        });
77331      };
77332
77333      return InitSelection;
77334    });
77335
77336    S2.define('select2/compat/inputData',[
77337      'jquery'
77338    ], function ($) {
77339      function InputData (decorated, $element, options) {
77340        this._currentData = [];
77341        this._valueSeparator = options.get('valueSeparator') || ',';
77342
77343        if ($element.prop('type') === 'hidden') {
77344          if (options.get('debug') && console && console.warn) {
77345            console.warn(
77346              'select2: Using a hidden input with select2 is no longer ' +
77347              'supported and may stop working in the future. It is recommended ' +
77348              'to use a `<select>` element instead.'
77349            );
77350          }
77351        }
77352
77353        decorated.call(this, $element, options);
77354      }
77355
77356      InputData.prototype.current = function (_, callback) {
77357        function getSelected (data, selectedIds) {
77358          var selected = [];
77359
77360          if (data.selected || $.inArray(data.id, selectedIds) !== -1) {
77361            data.selected = true;
77362            selected.push(data);
77363          } else {
77364            data.selected = false;
77365          }
77366
77367          if (data.children) {
77368            selected.push.apply(selected, getSelected(data.children, selectedIds));
77369          }
77370
77371          return selected;
77372        }
77373
77374        var selected = [];
77375
77376        for (var d = 0; d < this._currentData.length; d++) {
77377          var data = this._currentData[d];
77378
77379          selected.push.apply(
77380            selected,
77381            getSelected(
77382              data,
77383              this.$element.val().split(
77384                this._valueSeparator
77385              )
77386            )
77387          );
77388        }
77389
77390        callback(selected);
77391      };
77392
77393      InputData.prototype.select = function (_, data) {
77394        if (!this.options.get('multiple')) {
77395          this.current(function (allData) {
77396            $.map(allData, function (data) {
77397              data.selected = false;
77398            });
77399          });
77400
77401          this.$element.val(data.id);
77402          this.$element.trigger('change');
77403        } else {
77404          var value = this.$element.val();
77405          value += this._valueSeparator + data.id;
77406
77407          this.$element.val(value);
77408          this.$element.trigger('change');
77409        }
77410      };
77411
77412      InputData.prototype.unselect = function (_, data) {
77413        var self = this;
77414
77415        data.selected = false;
77416
77417        this.current(function (allData) {
77418          var values = [];
77419
77420          for (var d = 0; d < allData.length; d++) {
77421            var item = allData[d];
77422
77423            if (data.id == item.id) {
77424              continue;
77425            }
77426
77427            values.push(item.id);
77428          }
77429
77430          self.$element.val(values.join(self._valueSeparator));
77431          self.$element.trigger('change');
77432        });
77433      };
77434
77435      InputData.prototype.query = function (_, params, callback) {
77436        var results = [];
77437
77438        for (var d = 0; d < this._currentData.length; d++) {
77439          var data = this._currentData[d];
77440
77441          var matches = this.matches(params, data);
77442
77443          if (matches !== null) {
77444            results.push(matches);
77445          }
77446        }
77447
77448        callback({
77449          results: results
77450        });
77451      };
77452
77453      InputData.prototype.addOptions = function (_, $options) {
77454        var options = $.map($options, function ($option) {
77455          return $.data($option[0], 'data');
77456        });
77457
77458        this._currentData.push.apply(this._currentData, options);
77459      };
77460
77461      return InputData;
77462    });
77463
77464    S2.define('select2/compat/matcher',[
77465      'jquery'
77466    ], function ($) {
77467      function oldMatcher (matcher) {
77468        function wrappedMatcher (params, data) {
77469          var match = $.extend(true, {}, data);
77470
77471          if (params.term == null || $.trim(params.term) === '') {
77472            return match;
77473          }
77474
77475          if (data.children) {
77476            for (var c = data.children.length - 1; c >= 0; c--) {
77477              var child = data.children[c];
77478
77479              // Check if the child object matches
77480              // The old matcher returned a boolean true or false
77481              var doesMatch = matcher(params.term, child.text, child);
77482
77483              // If the child didn't match, pop it off
77484              if (!doesMatch) {
77485                match.children.splice(c, 1);
77486              }
77487            }
77488
77489            if (match.children.length > 0) {
77490              return match;
77491            }
77492          }
77493
77494          if (matcher(params.term, data.text, data)) {
77495            return match;
77496          }
77497
77498          return null;
77499        }
77500
77501        return wrappedMatcher;
77502      }
77503
77504      return oldMatcher;
77505    });
77506
77507    S2.define('select2/compat/query',[
77508
77509    ], function () {
77510      function Query (decorated, $element, options) {
77511        if (options.get('debug') && window.console && console.warn) {
77512          console.warn(
vendor: 10,079 bytes, lines 77513-77829
77513            'select2: The `query` option has been deprecated in favor of a ' +
77514            'custom data adapter that overrides the `query` method. Support ' +
77515            'will be removed for the `query` option in future versions of ' +
77516            'select2.'
77517          );
77518        }
77519
77520        decorated.call(this, $element, options);
77521      }
77522
77523      Query.prototype.query = function (_, params, callback) {
77524        params.callback = callback;
77525
77526        var query = this.options.get('query');
77527
77528        query.call(null, params);
77529      };
77530
77531      return Query;
77532    });
77533
77534    S2.define('select2/dropdown/attachContainer',[
77535
77536    ], function () {
77537      function AttachContainer (decorated, $element, options) {
77538        decorated.call(this, $element, options);
77539      }
77540
77541      AttachContainer.prototype.position =
77542        function (decorated, $dropdown, $container) {
77543          var $dropdownContainer = $container.find('.dropdown-wrapper');
77544          $dropdownContainer.append($dropdown);
77545
77546          $dropdown.addClass('select2-dropdown--below');
77547          $container.addClass('select2-container--below');
77548        };
77549
77550      return AttachContainer;
77551    });
77552
77553    S2.define('select2/dropdown/stopPropagation',[
77554
77555    ], function () {
77556      function StopPropagation () { }
77557
77558      StopPropagation.prototype.bind = function (decorated, container, $container) {
77559        decorated.call(this, container, $container);
77560
77561        var stoppedEvents = [
77562          'blur',
77563          'change',
77564          'click',
77565          'dblclick',
77566          'focus',
77567          'focusin',
77568          'focusout',
77569          'input',
77570          'keydown',
77571          'keyup',
77572          'keypress',
77573          'mousedown',
77574          'mouseenter',
77575          'mouseleave',
77576          'mousemove',
77577          'mouseover',
77578          'mouseup',
77579          'search',
77580          'touchend',
77581          'touchstart'
77582        ];
77583
77584        this.$dropdown.on(stoppedEvents.join(' '), function (evt) {
77585          evt.stopPropagation();
77586        });
77587      };
77588
77589      return StopPropagation;
77590    });
77591
77592    S2.define('select2/selection/stopPropagation',[
77593
77594    ], function () {
77595      function StopPropagation () { }
77596
77597      StopPropagation.prototype.bind = function (decorated, container, $container) {
77598        decorated.call(this, container, $container);
77599
77600        var stoppedEvents = [
77601          'blur',
77602          'change',
77603          'click',
77604          'dblclick',
77605          'focus',
77606          'focusin',
77607          'focusout',
77608          'input',
77609          'keydown',
77610          'keyup',
77611          'keypress',
77612          'mousedown',
77613          'mouseenter',
77614          'mouseleave',
77615          'mousemove',
77616          'mouseover',
77617          'mouseup',
77618          'search',
77619          'touchend',
77620          'touchstart'
77621        ];
77622
77623        this.$selection.on(stoppedEvents.join(' '), function (evt) {
77624          evt.stopPropagation();
77625        });
77626      };
77627
77628      return StopPropagation;
77629    });
77630
77631    /*!
77632 * jQuery Mousewheel 3.1.13
77633 *
77634 * Copyright jQuery Foundation and other contributors
77635 * Released under the MIT license
77636 * http://jquery.org/license
77637 */
77638
77639    (function (factory) {
77640      if ( typeof S2.define === 'function' && S2.define.amd ) {
77641        // AMD. Register as an anonymous module.
77642        S2.define('jquery-mousewheel',['jquery'], factory);
77643      } else if (typeof exports === 'object') {
77644        // Node/CommonJS style for Browserify
77645        module.exports = factory;
77646      } else {
77647        // Browser globals
77648        factory(jQuery);
77649      }
77650    }(function ($) {
77651
77652      var toFix  = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'],
77653        toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ?
77654          ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],
77655        slice  = Array.prototype.slice,
77656        nullLowestDeltaTimeout, lowestDelta;
77657
77658      if ( $.event.fixHooks ) {
77659        for ( var i = toFix.length; i; ) {
77660          $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks;
77661        }
77662      }
77663
77664      var special = $.event.special.mousewheel = {
77665        version: '3.1.12',
77666
77667        setup: function() {
77668          if ( this.addEventListener ) {
77669            for ( var i = toBind.length; i; ) {
77670              this.addEventListener( toBind[--i], handler, false );
77671            }
77672          } else {
77673            this.onmousewheel = handler;
77674          }
77675          // Store the line height and page height for this particular element
77676          $.data(this, 'mousewheel-line-height', special.getLineHeight(this));
77677          $.data(this, 'mousewheel-page-height', special.getPageHeight(this));
77678        },
77679
77680        teardown: function() {
77681          if ( this.removeEventListener ) {
77682            for ( var i = toBind.length; i; ) {
77683              this.removeEventListener( toBind[--i], handler, false );
77684            }
77685          } else {
77686            this.onmousewheel = null;
77687          }
77688          // Clean up the data we added to the element
77689          $.removeData(this, 'mousewheel-line-height');
77690          $.removeData(this, 'mousewheel-page-height');
77691        },
77692
77693        getLineHeight: function(elem) {
77694          var $elem = $(elem),
77695            $parent = $elem['offsetParent' in $.fn ? 'offsetParent' : 'parent']();
77696          if (!$parent.length) {
77697            $parent = $('body');
77698          }
77699          return parseInt($parent.css('fontSize'), 10) || parseInt($elem.css('fontSize'), 10) || 16;
77700        },
77701
77702        getPageHeight: function(elem) {
77703          return $(elem).height();
77704        },
77705
77706        settings: {
77707          adjustOldDeltas: true, // see shouldAdjustOldDeltas() below
77708          normalizeOffset: true  // calls getBoundingClientRect for each event
77709        }
77710      };
77711
77712      $.fn.extend({
77713        mousewheel: function(fn) {
77714          return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel');
77715        },
77716
77717        unmousewheel: function(fn) {
77718          return this.unbind('mousewheel', fn);
77719        }
77720      });
77721
77722
77723      function handler(event) {
77724        var orgEvent   = event || window.event,
77725          args       = slice.call(arguments, 1),
77726          delta      = 0,
77727          deltaX     = 0,
77728          deltaY     = 0,
77729          absDelta   = 0,
77730          offsetX    = 0,
77731          offsetY    = 0;
77732        event = $.event.fix(orgEvent);
77733        event.type = 'mousewheel';
77734
77735        // Old school scrollwheel delta
77736        if ( 'detail'      in orgEvent ) { deltaY = orgEvent.detail * -1;      }
77737        if ( 'wheelDelta'  in orgEvent ) { deltaY = orgEvent.wheelDelta;       }
77738        if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY;      }
77739        if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; }
77740
77741        // Firefox < 17 horizontal scrolling related to DOMMouseScroll event
77742        if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
77743          deltaX = deltaY * -1;
77744          deltaY = 0;
77745        }
77746
77747        // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy
77748        delta = deltaY === 0 ? deltaX : deltaY;
77749
77750        // New school wheel delta (wheel event)
77751        if ( 'deltaY' in orgEvent ) {
77752          deltaY = orgEvent.deltaY * -1;
77753          delta  = deltaY;
77754        }
77755        if ( 'deltaX' in orgEvent ) {
77756          deltaX = orgEvent.deltaX;
77757          if ( deltaY === 0 ) { delta  = deltaX * -1; }
77758        }
77759
77760        // No change actually happened, no reason to go any further
77761        if ( deltaY === 0 && deltaX === 0 ) { return; }
77762
77763        // Need to convert lines and pages to pixels if we aren't already in pixels
77764        // There are three delta modes:
77765        //   * deltaMode 0 is by pixels, nothing to do
77766        //   * deltaMode 1 is by lines
77767        //   * deltaMode 2 is by pages
77768        if ( orgEvent.deltaMode === 1 ) {
77769          var lineHeight = $.data(this, 'mousewheel-line-height');
77770          delta  *= lineHeight;
77771          deltaY *= lineHeight;
77772          deltaX *= lineHeight;
77773        } else if ( orgEvent.deltaMode === 2 ) {
77774          var pageHeight = $.data(this, 'mousewheel-page-height');
77775          delta  *= pageHeight;
77776          deltaY *= pageHeight;
77777          deltaX *= pageHeight;
77778        }
77779
77780        // Store lowest absolute delta to normalize the delta values
77781        absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) );
77782
77783        if ( !lowestDelta || absDelta < lowestDelta ) {
77784          lowestDelta = absDelta;
77785
77786          // Adjust older deltas if necessary
77787          if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
77788            lowestDelta /= 40;
77789          }
77790        }
77791
77792        // Adjust older deltas if necessary
77793        if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
77794          // Divide all the things by 40!
77795          delta  /= 40;
77796          deltaX /= 40;
77797          deltaY /= 40;
77798        }
77799
77800        // Get a whole, normalized value for the deltas
77801        delta  = Math[ delta  >= 1 ? 'floor' : 'ceil' ](delta  / lowestDelta);
77802        deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta);
77803        deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta);
77804
77805        // Normalise offsetX and offsetY properties
77806        if ( special.settings.normalizeOffset && this.getBoundingClientRect ) {
77807          var boundingRect = this.getBoundingClientRect();
77808          offsetX = event.clientX - boundingRect.left;
77809          offsetY = event.clientY - boundingRect.top;
77810        }
77811
77812        // Add information to the event object
77813        event.deltaX = deltaX;
77814        event.deltaY = deltaY;
77815        event.deltaFactor = lowestDelta;
77816        event.offsetX = offsetX;
77817        event.offsetY = offsetY;
77818        // Go ahead and set deltaMode to 0 since we converted to pixels
77819        // Although this is a little odd since we overwrite the deltaX/Y
77820        // properties with normalized deltas.
77821        event.deltaMode = 0;
77822
77823        // Add event and delta to the front of the arguments
77824        args.unshift(event, delta, deltaX, deltaY);
77825
77826        // Clearout lowestDelta after sometime to better
77827        // handle multiple device types that give different
77828        // a different lowestDelta
77829        // Ex: trackpad = 3 and mouse wheel = 120
77830        if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); }
77831        nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200);
77832
77833        return ($.event.dispatch || $.event.handle).apply(this, args);
77834      }
77835
77836      function nullLowestDelta() {
77837        lowestDelta = null;
77838      }
77839
77840      function shouldAdjustOldDeltas(orgEvent, absDelta) {
77841        // If this is an older event and the delta is divisable by 120,
77842        // then we are assuming that the browser is treating this as an
77843        // older mouse wheel event and that we should divide the deltas
77844        // by 40 to try and get a more usable deltaFactor.
77845        // Side note, this actually impacts the reported scroll distance
77846        // in older browsers and can cause scrolling to be slower than native.
77847        // Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false.
77848        return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0;
77849      }
77850
77851    }));
77852
77853    S2.define('jquery.select2',[
77854      'jquery',
77855      'jquery-mousewheel',
77856
77857      './select2/core',
77858      './select2/defaults'
77859    ], function ($, _, select2, Defaults) {
77860      if ($.fn.select2 == null) {
77861        // All methods that should return the element
77862        var thisMethods = ['open', 'close', 'destroy'];
77863
77864        $.fn.select2 = function (options) {
77865          options = options || {};
77866
77867          if (typeof options === 'object') {
77868            this.each(function () {
77869              var instanceOptions = $.extend(true, {}, options);
77870
77871              var instance = new select2($(this), instanceOptions);
77872            });
77873
77874            return this;
77875          } else if (typeof options === 'string') {
77876            var ret;
77877            var args = Array.prototype.slice.call(arguments, 1);
77878
77879            this.each(function () {
77880              var instance = $(this).data('select2');
77881
77882              if (instance == null && window.console && console.error) {
77883                console.error(
77884                  'The select2(\'' + options + '\') method was called on an ' +
77885                  'element that is not using select2.'
77886                );
77887              }
77888
77889              ret = instance[options].apply(instance, args);
77890            });
77891
77892            // Check if we should be returning `this`
77893            if ($.inArray(options, thisMethods) > -1) {
77894              return this;
77895            }
77896
77897            return ret;
77898          } else {
77899            throw new Error('Invalid arguments for select2: ' + options);
77900          }
77901        };
77902      }
77903
77904      if ($.fn.select2.defaults == null) {
77905        $.fn.select2.defaults = Defaults;
77906      }
77907
77908      return select2;
77909    });
77910
77911    // Return the AMD loader configuration so it can be used outside of this file
77912    return {
77913      define: S2.define,
77914      require: S2.require
77915    };
77916  }());
77917
77918  // Autoload the jQuery bindings
77919  // We know that all of the modules exist above this, so we're safe
77920  var select2 = S2.require('jquery.select2');
77921
77922  // Hold the AMD module references on the jQuery function that was just loaded
77923  // This allows select2 to use the internal loader outside of this file, such
77924  // as in the language files.
77925  jQuery.fn.select2.amd = S2;
77926
77927  // Return the select2 instance for anyone who is importing it.
77928  return select2;
77929}));
77930function showQuestionModal(elm){
77931  $("#showModal").modal("show")
77932  modal_detail = $(elm).data("content")
77933  $("#modal-content").html(modal_detail)
77934  $('.custom-ckeditor').each(function(index, editor) {
77935    return CKEDITOR.replace($(editor).attr("id"));
77936  });
77937};
77938(function() {
77939  var fix_sortable_helper, init_table_sortable, ref;
77940
77941  $.ajaxSetup({
77942    beforeSend: function(xhr, settings) {
77943      var token;
77944      if (!(settings.crossDomain || /^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type))) {
77945        token = $('meta[name="csrf-token"]').attr('content');
77946        if (token) {
77947          return xhr.setRequestHeader('X-CSRF-Token', token);
77948        }
77949      }
77950    }
77951  });
77952
77953  fix_sortable_helper = function(e, ui) {
77954    if (ui.is('tr')) {
77955      ui.children().each(function() {
77956        return $(this).width($(this).width());
77957      });
77958    }
77959    return ui;
77960  };
77961
77962  if ((ref = $.ui) != null ? ref.sortable : void 0) {
77963    $.extend($.ui.sortable.prototype.options, {
77964      helper: fix_sortable_helper,
77965      placeholder: 'sortable-placeholder',
77966      forcePlaceholderSize: true,
77967      opacity: 0.9,
77968      tolerance: 'pointer',
77969      cursor: 'grabbing'
77970    });
77971  }
77972
77973  init_table_sortable = function() {
77974    return $('.table-sortable').sortable({
77975      axis: 'y',
77976      items: '.item',
77977      handle: '.drag-cell',
77978      update: function(e, ui) {
77979        var item, item_data, params;
77980        item = ui.item;
77981        item_data = item.data();
77982        params = {
77983          _method: 'put'
77984        };
77985        params[item_data.modelName] = {
77986          row_order_position: item.index()
77987        };
77988        return $.ajax({
77989          type: 'POST',
77990          url: item_data.updateUrl,
77991          dataType: 'json',
77992          data: params
77993        });
77994      }
77995    });
77996  };
77997
77998  $(document).ready(function() {
77999    return init_table_sortable();
78000  });
78001
78002  window.init_table_sortable = init_table_sortable;
78003
78004}).call(this);
78005(function() {
78006  this.fillZero = function(series_data, data_range) {
78007    data_range = data_range.map((function(_this) {
78008      return function(date) {
78009        date = new Date(date);
78010        return date.getTime();
78011      };
78012    })(this));
78013    return series_data.forEach((function(_this) {
78014      return function(series) {
78015        var date, date_data, new_data;
78016        if (series["range_data"]) {
78017          data_range = series["range_data"].map(function(date) {
78018            date = new Date(date);
78019            return date.getTime();
78020          });
78021        }
78022        date = data_range[0];
78023        new_data = [];
78024        while (date <= data_range[1]) {
78025          date_data = series.data.find(function(data) {
78026            return data[0] <= date && data[0] + (3600 * 24 * 1000) > date;
78027          });
78028          if (date_data != null) {
78029            new_data.push(date_data);
78030          } else {
78031            new_data.push([date, 0]);
78032          }
78033          date += 3600 * 24 * 1000;
78034        }
78035        return series.data = new_data;
78036      };
78037    })(this));
78038  };
78039
78040  this.convertDate = function(series_data) {
78041    return series_data.forEach((function(_this) {
78042      return function(series) {
78043        return series.data = series.data.map(function(data) {
78044          var date;
78045          date = new Date(data[0]);
78046          return [date.getTime(), data[1]];
78047        });
78048      };
78049    })(this));
78050  };
78051
78052  this.showUserActionGraph = function(series_data, data_range, id, type, yAxis_setting, xAxis_setting) {
78053    var target, type_target, xAxis_data, yAxis_data;
78054    convertDate(series_data);
78055    fillZero(series_data, data_range);
78056    target = 'usage-time-graph';
78057    if (id) {
78058      target = id;
78059    }
78060    type_target = 'line';
78061    if (type) {
78062      type_target = type;
78063    }
78064    yAxis_data = {
78065      title: {
78066        text: null
78067      },
78068      labels: {
78069        align: 'left',
78070        x: 3,
78071        y: 16,
78072        format: '{value:.,0f}'
78073      },
78074      showFirstLabel: false
78075    };
78076    xAxis_data = {
78077      type: 'datetime'
78078    };
78079    if (yAxis_setting) {
78080      yAxis_data = yAxis_setting;
78081    }
78082    if (xAxis_setting) {
78083      xAxis_data = xAxis_setting;
78084    }
78085    return Highcharts.chart(target, {
78086      time: {
78087        timezone: 'Asia/Tokyo'
78088      },
78089      chart: {
78090        type: type_target
78091      },
78092      title: {
78093        text: null
78094      },
78095      xAxis: xAxis_data,
78096      yAxis: yAxis_data,
78097      plotOptions: {
78098        series: {
78099          cursor: 'pointer',
78100          marker: {
78101            lineWidth: 1
78102          }
78103        }
78104      },
78105      series: series_data
78106    });
78107  };
78108
78109}).call(this);
78110$(document).ready(function() {
78111    $(document).on("click","#test-email-user-group",function(event) {
78112        event.preventDefault()
78113        $.ajax({
78114            url: "/admin/test_announcement_mails.js",
78115            type: "POST",
78116            cache: false,
78117            data: {
78118                "announcement_mail": {
78119                    "title": $(this.form).find(".user-group-mail-title").val(),
78120                    "mail_sender_setting_id": $(this.form).find("#user_group_mail_sender_setting_id").val(),
78121                    "body": $("#"+this.value).val()
78122                }
78123            }})
78124        $(this).prop("disabled", true)
78125    });
78126});
78127var t=[],YubinBango;!function(YubinBango){var n=function(){function n(t,n){if(void 0===t&&(t=""),this.URL="https://yubinbango.github.io/yubinbango-data/data",this.g=[null,"北海道","青森県","岩手県","宮城県","秋田県","山形県","福島県","茨城県","栃木県","群馬県","埼玉県","千葉県","東京都","神奈川県","新潟県","富山県","石川県","福井県","山梨県","長野県","岐阜県","静岡県","愛知県","三重県","滋賀県","京都府","大阪府","兵庫県","奈良県","和歌山県","鳥取県","島根県","岡山県","広島県","山口県","徳島県","香川県","愛媛県","高知県","福岡県","佐賀県","長崎県","熊本県","大分県","宮崎県","鹿児島県","沖縄県"],t){var e=t.replace(/[0-9]/g,function(t){return String.fromCharCode(t.charCodeAt(0)-65248)}),r=e.match(/\d/g),o=r.join(""),i=this.h(o);i?this.i(i,n):n(this.j())}}return n.prototype.h=function(t){if(7===t.length)return t},n.prototype.j=function(t,n,e,r,o){return void 0===t&&(t=""),void 0===n&&(n=""),void 0===e&&(e=""),void 0===r&&(r=""),void 0===o&&(o=""),{k:t,region:n,l:e,m:r,o:o}},n.prototype.p=function(t){return t&&t[0]&&t[1]?this.j(t[0],this.g[t[0]],t[1],t[2],t[3]):this.j()},n.prototype.q=function(t,n){window.$yubin=function(t){return n(t)};var e=document.createElement("script");e.setAttribute("type","text/javascript"),e.setAttribute("charset","UTF-8"),e.setAttribute("src",t),document.head.appendChild(e)},n.prototype.i=function(n,e){var r=this,o=n.substr(0,3);return o in t&&n in t[o]?e(this.p(t[o][n])):void this.q(this.URL+"/"+o+".js",function(i){return t[o]=i,e(r.p(i[n]))})},n}();YubinBango.Core=n}(YubinBango||(YubinBango={}));var n=["Japan","JP","JPN","JAPAN"],e=["p-region-id","p-region","p-locality","p-street-address","p-extended-address"],YubinBango;!function(YubinBango){var t=function(){function t(){this.s()}return t.prototype.s=function(){var n=this,e=document.querySelectorAll(".h-adr");[].map.call(e,function(e){if(n.t(e)){var r=e.querySelectorAll(".p-postal-code");r[r.length-1].addEventListener("keyup",function(e){t.prototype.u(n.v(e.target.parentNode))},!1)}})},t.prototype.v=function(t){return"FORM"===t.tagName||t.classList.contains("h-adr")?t:this.v(t.parentNode)},t.prototype.t=function(t){var e=t.querySelector(".p-country-name"),r=[e.innerHTML,e.value];return r.some(function(t){return n.indexOf(t)>=0})},t.prototype.u=function(t){var n=this,e=t.querySelectorAll(".p-postal-code");new YubinBango.Core(this.A(e),function(e){return n.B(t,e)})},t.prototype.A=function(t){return[].map.call(t,function(t){return t.value}).reduce(function(t,n){return t+n})},t.prototype.B=function(t,n){var r=[this.C,this.D];r.map(function(r){return e.map(function(e){return r(e,t,n)})})},t.prototype.C=function(t,n,e){if(e){var r=n.querySelectorAll("."+t);[].map.call(r,function(t){return t.value=""})}},t.prototype.D=function(t,n,e){var r={"p-region-id":e.k,"p-region":e.region,"p-locality":e.l,"p-street
78127-address":e.m,"p-extended-address":e.o},o=n.querySelectorAll("."+t);[].map.call(o,function(n){return n.value+=r[t]?r[t]:""})},t}();YubinBango.MicroformatDom=t}(YubinBango||(YubinBango={})),document.addEventListener("DOMContentLoaded",function(){new YubinBango.MicroformatDom},!1);
78128(function() {
78129  $(document).on("click", "#test-email", function(event) {
78130    var formData;
78131    event.preventDefault();
78132    formData = $(this.form).serialize();
78133    $.ajax({
78134      url: "/admin/test_announcement_mails.js",
78135      type: "POST",
78136      cache: false,
78137      data: formData
78138    });
78139    return $(this).prop("disabled", true);
78140  });
78141
78142}).call(this);
78143(function() {
78144  var submit;
78145
78146  submit = function(input) {
78147    $(input).data("old-value", $(input).val());
78148    return $(input.form).trigger("submit.rails");
78149  };
78150
78151  $(document).on('focusin', '.auto-submit, .autosubmit', function() {
78152    return $(this).data('old-value', $(this).val());
78153  }).on("change", ".auto-submit, .autosubmit", function() {
78154    if ($(this).data("confirm")) {
78155      if ($.rails.confirm(this.dataset.confirm)) {
78156        return submit(this);
78157      } else {
78158        return $(this).val($(this).data("old-value"));
78159      }
78160    } else {
78161      return submit(this);
78162    }
78163  });
78164
78165  $(document).ready(function() {
78166    return $('.auto-submit-datetime').on('apply.daterangepicker', function() {
78167      return $(this.form).trigger("submit.rails");
78168    });
78169  });
78170
78171}).call(this);
78172(function() {
78173  var update_height;
78174
78175  update_height = function(element) {
78176    return $(element).css({
78177      'height': 'auto',
78178      'overflow-y': 'hidden'
78179    }).height(element.scrollHeight);
78180  };
78181
78182  $(document).ready(function() {
78183    return $(".table-autogrow textarea").each(function(input, element) {
78184      return update_height(element);
78185    });
78186  });
78187
78188  $(document).on("input", ".table-autogrow textarea", function(event) {
78189    return update_height(event.target);
78190  });
78191
78192}).call(this);
78193(function(global, factory) {
78194  typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define([ "exports" ], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, 
78195  factory(global.ActionCable = {}));
78196})(this, (function(exports) {
78197  "use strict";
78198  var adapters = {
78199    logger: self.console,
78200    WebSocket: self.WebSocket
78201  };
78202  var logger = {
78203    log(...messages) {
78204      if (this.enabled) {
78205        messages.push(Date.now());
78206        adapters.logger.log("[ActionCable]", ...messages);
78207      }
78208    }
78209  };
78210  const now = () => (new Date).getTime();
78211  const secondsSince = time => (now() - time) / 1e3;
78212  class ConnectionMonitor {
78213    constructor(connection) {
78214      this.visibilityDidChange = this.visibilityDidChange.bind(this);
78215      this.connection = connection;
78216      this.reconnectAttempts = 0;
78217    }
78218    start() {
78219      if (!this.isRunning()) {
78220        this.startedAt = now();
78221        delete this.stoppedAt;
78222        this.startPolling();
78223        addEventListener("visibilitychange", this.visibilityDidChange);
78224        logger.log(`ConnectionMonitor started. stale threshold = ${this.constructor.staleThreshold} s`);
78225      }
78226    }
78227    stop() {
78228      if (this.isRunning()) {
78229        this.stoppedAt = now();
78230        this.stopPolling();
78231        removeEventListener("visibilitychange", this.visibilityDidChange);
78232        logger.log("ConnectionMonitor stopped");
78233      }
78234    }
78235    isRunning() {
78236      return this.startedAt && !this.stoppedAt;
78237    }
78238    recordPing() {
78239      this.pingedAt = now();
78240    }
78241    recordConnect() {
78242      this.reconnectAttempts = 0;
78243      this.recordPing();
78244      delete this.disconnectedAt;
78245      logger.log("ConnectionMonitor recorded connect");
78246    }
78247    recordDisconnect() {
78248      this.disconnectedAt = now();
78249      logger.log("ConnectionMonitor recorded disconnect");
78250    }
78251    startPolling() {
78252      this.stopPolling();
78253      this.poll();
78254    }
78255    stopPolling() {
78256      clearTimeout(this.pollTimeout);
78257    }
78258    poll() {
78259      this.pollTimeout = setTimeout((() => {
78260        this.reconnectIfStale();
78261        this.poll();
78262      }), this.getPollInterval());
78263    }
78264    getPollInterval() {
78265      const {staleThreshold: staleThreshold, reconnectionBackoffRate: reconnectionBackoffRate} = this.constructor;
78266      const backoff = Math.pow(1 + reconnectionBackoffRate, Math.min(this.reconnectAttempts, 10));
78267      const jitterMax = this.reconnectAttempts === 0 ? 1 : reconnectionBackoffRate;
78268      const jitter = jitterMax * Math.random();
78269      return staleThreshold * 1e3 * backoff * (1 + jitter);
78270    }
78271    reconnectIfStale() {
78272      if (this.connectionIsStale()) {
78273        logger.log(`ConnectionMonitor detected stale connection. reconnectAttempts = ${this.reconnectAttempts}, time stale = ${secondsSince(this.refreshedAt)} s, stale threshold = ${this.constructor.staleThreshold} s`);
78274        this.reconnectAttempts++;
78275        if (this.disconnectedRecently()) {
78276          logger.log(`ConnectionMonitor skipping reopening recent disconnect. time disconnected = ${secondsSince(this.disconnectedAt)} s`);
78277        } else {
78278          logger.log("ConnectionMonitor reopening");
78279          this.connection.reopen();
78280        }
78281      }
78282    }
78283    get refreshedAt() {
78284      return this.pingedAt ? this.pingedAt : this.startedAt;
78285    }
78286    connectionIsStale() {
78287      return secondsSince(this.refreshedAt) > this.constructor.staleThreshold;
78288    }
78289    disconnectedRecently() {
78290      return this.disconnectedAt && secondsSince(this.disconnectedAt) < this.constructor.staleThreshold;
78291    }
78292    visibilityDidChange() {
78293      if (document.visibilityState === "visible") {
78294        setTimeout((() => {
78295          if (this.connectionIsStale() || !this.connection.isOpen()) {
78296            logger.log(`ConnectionMonitor reopening stale connection on visibilitychange. visibilityState = ${document.visibilityState}`);
78297            this.connection.reopen();
78298          }
78299        }), 200);
78300      }
78301    }
78302  }
78303  ConnectionMonitor.staleThreshold = 6;
78304  ConnectionMonitor.reconnectionBackoffRate = .15;
78305  var INTERNAL = {
78306    message_types: {
78307      welcome: "welcome",
78308      disconnect: "disconnect",
78309      ping: "ping",
78310      confirmation: "confirm_subscription",
78311      rejection: "reject_subscription"
78312    },
78313    disconnect_reasons: {
78314      unauthorized: "unauthorized",
78315      invalid_request: "invalid_request",
78316      server_restart: "server_restart"
78317    },
78318    default_mount_path: "/cable",
78319    protocols: [ "actioncable-v1-json", "actioncable-unsupported" ]
78320  };
78321  const {message_types: message_types, protocols: protocols} = INTERNAL;
78322  const supportedProtocols = protocols.slice(0, protocols.length - 1);
78323  const indexOf = [].indexOf;
78324  class Connection {
78325    constructor(consumer) {
78326      this.open = this.open.bind(this);
78327      this.consumer = consumer;
78328      this.subscriptions = this.consumer.subscriptions;
78329      this.monitor = new ConnectionMonitor(this);
78330      this.disconnected = true;
78331    }
78332    send(data) {
78333      if (this.isOpen()) {
78334        this.webSocket.send(JSON.stringify(data));
78335        return true;
78336      } else {
78337        return false;
78338      }
78339    }
78340    open() {
78341      if (this.isActive()) {
78342        logger.log(`Attempted to open WebSocket, but existing socket is ${this.getState()}`);
78343        return false;
78344      } else {
78345        logger.log(`Opening WebSocket, current state is ${this.getState()}, subprotocols: ${protocols}`);
78346        if (this.webSocket) {
78347          this.uninstallEventHandlers();
78348        }
78349        this.webSocket = new adapters.WebSocket(this.consumer.url, protocols);
78350        this.installEventHandlers();
78351        this.monitor.start();
78352        return true;
78353      }
78354    }
78355    close({allowReconnect: allowReconnect} = {
78356      allowReconnect: true
78357    }) {
78358      if (!allowReconnect) {
78359        this.monitor.stop();
78360      }
78361      if (this.isOpen()) {
78362        return this.webSocket.close();
78363      }
78364    }
78365    reopen() {
78366      logger.log(`Reopening WebSocket, current state is ${this.getState()}`);
78367      if (this.isActive()) {
78368        try {
78369          return this.close();
78370        } catch (error) {
78371          logger.log("Failed to reopen WebSocket", error);
78372        } finally {
78373          logger.log(`Reopening WebSocket in ${this.constructor.reopenDelay}ms`);
78374          setTimeout(this.open, this.constructor.reopenDelay);
78375        }
78376      } else {
78377        return this.open();
78378      }
78379    }
78380    getProtocol() {
78381      if (this.webSocket) {
78382        return this.webSocket.protocol;
78383      }
78384    }
78385    isOpen() {
78386      return this.isState("open");
78387    }
78388    isActive() {
78389      return this.isState("open", "connecting");
78390    }
78391    isProtocolSupported() {
78392      return indexOf.call(supportedProtocols, this.getProtocol()) >= 0;
78393    }
78394    isState(...states) {
78395      return indexOf.call(states, this.getState()) >= 0;
78396    }
78397    getState() {
78398      if (this.webSocket) {
78399        for (let state in adapters.WebSocket) {
78400          if (adapters.WebSocket[state] === this.webSocket.readyState) {
78401            return state.toLowerCase();
78402          }
78403        }
78404      }
78405      return null;
78406    }
78407    installEventHandlers() {
78408      for (let eventName in this.events) {
78409        const handler = this.events[eventName].bind(this);
78410        this.webSocket[`on${eventName}`] = handler;
78411      }
78412    }
78413    uninstallEventHandlers() {
78414      for (let eventName in this.events) {
78415        this.webSocket[`on${eventName}`] = function() {};
78416      }
78417    }
78418  }
78419  Connection.reopenDelay = 500;
78420  Connection.prototype.events = {
78421    message(event) {
78422      if (!this.isProtocolSupported()) {
78423        return;
78424      }
78425      const {identifier: identifier, message: message, reason: reason, reconnect: reconnect, type: type} = JSON.parse(event.data);
78426      switch (type) {
78427       case message_types.welcome:
78428        this.monitor.recordConnect();
78429        return this.subscriptions.reload();
78430
78431       case message_types.disconnect:
78432        logger.log(`Disconnecting. Reason: ${reason}`);
78433        return this.close({
78434          allowReconnect: reconnect
78435        });
78436
78437       case message_types.ping:
78438        return this.monitor.recordPing();
78439
78440       case message_types.confirmation:
78441        this.subscriptions.confirmSubscription(identifier);
78442        return this.subscriptions.notify(identifier, "connected");
78443
78444       case message_types.rejection:
78445        return this.subscriptions.reject(identifier);
78446
78447       default:
78448        return this.subscriptions.notify(identifier, "received", message);
78449      }
78450    },
78451    open() {
78452      logger.log(`WebSocket onopen event, using '${this.getProtocol()}' subprotocol`);
78453      this.disconnected = false;
78454      if (!this.isProtocolSupported()) {
78455        logger.log("Protocol is unsupported. Stopping monitor and disconnecting.");
78456        return this.close({
78457          allowReconnect: false
78458        });
78459      }
78460    },
78461    close(event) {
78462      logger.log("WebSocket onclose event");
78463      if (this.disconnected) {
78464        return;
78465      }
78466      this.disconnected = true;
78467      this.monitor.recordDisconnect();
78468      return this.subscriptions.notifyAll("disconnected", {
78469        willAttemptReconnect: this.monitor.isRunning()
78470      });
78471    },
78472    error() {
78473      logger.log("WebSocket onerror event");
78474    }
78475  };
78476  const extend = function(object, properties) {
78477    if (properties != null) {
78478      for (let key in properties) {
78479        const value = properties[key];
78480        object[key] = value;
78481      }
78482    }
78483    return object;
78484  };
78485  class Subscription {
78486    constructor(consumer, params = {}, mixin) {
78487      this.consumer = consumer;
78488      this.identifier = JSON.stringify(params);
78489      extend(this, mixin);
78490    }
78491    perform(action, data = {}) {
78492      data.action = action;
78493      return this.send(data);
78494    }
78495    send(data) {
78496      return this.consumer.send({
78497        command: "message",
78498        identifier: this.identifier,
78499        data: JSON.stringify(data)
78500      });
78501    }
78502    unsubscribe() {
78503      return this.consumer.subscriptions.remove(this);
78504    }
78505  }
78506  class SubscriptionGuarantor {
78507    constructor(subscriptions) {
78508      this.subscriptions = subscriptions;
78509      this.pendingSubscriptions = [];
78510    }
78511    guarantee(subscription) {
78512      if (this.pendingSubscriptions.indexOf(subscription) == -1) {
78513        logger.log(`SubscriptionGuarantor guaranteeing ${subscription.identifier}`);
78514        this.pendingSubscriptions.push(subscription);
78515      } else {
78516        logger.log(`SubscriptionGuarantor already guaranteeing ${subscription.identifier}`);
78517      }
78518      this.startGuaranteeing();
78519    }
78520    forget(subscription) {
78521      logger.log(`SubscriptionGuarantor forgetting ${subscription.identifier}`);
78522      this.pendingSubscriptions = this.pendingSubscriptions.filter((s => s !== subscription));
78523    }
78524    startGuaranteeing() {
78525      this.stopGuaranteeing();
78526      this.retrySubscribing();
78527    }
78528    stopGuaranteeing() {
78529      clearTimeout(this.retryTimeout);
78530    }
78531    retrySubscribing() {
78532      this.retryTimeout = setTimeout((() => {
78533        if (this.subscriptions && typeof this.subscriptions.subscribe === "function") {
78534          this.pendingSubscriptions.map((subscription => {
78535            logger.log(`SubscriptionGuarantor resubscribing ${subscription.identifier}`);
78536            this.subscriptions.subscribe(subscription);
78537          }));
78538        }
78539      }), 500);
78540    }
78541  }
78542  class Subscriptions {
78543    constructor(consumer) {
78544      this.consumer = consumer;
78545      this.guarantor = new SubscriptionGuarantor(this);
78546      this.subscriptions = [];
78547    }
78548    create(channelName, mixin) {
78549      const channel = channelName;
78550      const params = typeof channel === "object" ? channel : {
78551        channel: channel
78552      };
78553      const subscription = new Subscription(this.consumer, params, mixin);
78554      return this.add(subscription);
78555    }
78556    add(subscription) {
78557      this.subscriptions.push(subscription);
78558      this.consumer.ensureActiveConnection();
78559      this.notify(subscription, "initialized");
78560      this.subscribe(subscription);
78561      return subscription;
78562    }
78563    remove(subscription) {
78564      this.forget(subscription);
78565      if (!this.findAll(subscription.identifier).length) {
78566        this.sendCommand(subscription, "unsubscribe");
78567      }
78568      return subscription;
78569    }
78570    reject(identifier) {
78571      return this.findAll(identifier).map((subscription => {
78572        this.forget(subscription);
78573        this.notify(subscription, "rejected");
78574        return subscription;
78575      }));
78576    }
78577    forget(subscription) {
78578      this.guarantor.forget(subscription);
78579      this.subscriptions = this.subscriptions.filter((s => s !== subscription));
78580      return subscription;
78581    }
78582    findAll(identifier) {
78583      return this.subscriptions.filter((s => s.identifier === identifier));
78584    }
78585    reload() {
78586      return this.subscriptions.map((subscription => this.subscribe(subscription)));
78587    }
78588    notifyAll(callbackName, ...args) {
78589      return this.subscriptions.map((subscription => this.notify(subscription, callbackName, ...args)));
78590    }
78591    notify(subscription, callbackName, ...args) {
78592      let subscriptions;
78593      if (typeof subscription === "string") {
78594        subscriptions = this.findAll(subscription);
78595      } else {
78596        subscriptions = [ subscription ];
78597      }
78598      return subscriptions.map((subscription => typeof subscription[callbackName] === "function" ? subscription[callbackName](...args) : undefined));
78599    }
78600    subscribe(subscription) {
78601      if (this.sendCommand(subscription, "subscribe")) {
78602        this.guarantor.guarantee(subscription);
78603      }
78604    }
78605    confirmSubscription(identifier) {
78606      logger.log(`Subscription confirmed ${identifier}`);
78607      this.findAll(identifier).map((subscription => this.guarantor.forget(subscription)));
78608    }
78609    sendCommand(subscription, command) {
78610      const {identifier: identifier} = subscription;
78611      return this.consumer.send({
78612        command: command,
78613        identifier: identifier
78614      });
78615    }
78616  }
78617  class Consumer {
78618    constructor(url) {
78619      this._url = url;
78620      this.subscriptions = new Subscriptions(this);
78621      this.connection = new Connection(this);
78622    }
78623    get url() {
78624      return createWebSocketURL(this._url);
78625    }
78626    send(data) {
78627      return this.connection.send(data);
78628    }
78629    connect() {
78630      return this.connection.open();
78631    }
78632    disconnect() {
78633      return this.connection.close({
78634        allowReconnect: false
78635      });
78636    }
78637    ensureActiveConnection() {
78638      if (!this.connection.isActive()) {
78639        return this.connection.open();
78640      }
78641    }
78642  }
78643  function createWebSocketURL(url) {
78644    if (typeof url === "function") {
78645      url = url();
78646    }
78647    if (url && !/^wss?:/i.test(url)) {
78648      const a = document.createElement("a");
78649      a.href = url;
78650      a.href = a.href;
78651      a.protocol = a.protocol.replace("http", "ws");
78652      return a.href;
78653    } else {
78654      return url;
78655    }
78656  }
78657  function createConsumer(url = getConfig("url") || INTERNAL.default_mount_path) {
78658    return new Consumer(url);
78659  }
78660  function getConfig(name) {
78661    const element = document.head.querySelector(`meta[name='action-cable-${name}']`);
78662    if (element) {
78663      return element.getAttribute("content");
78664    }
78665  }
78666  console.log("DEPRECATION: action_cable.js has been renamed to actioncable.js – please update your reference before Rails 8");
78667  exports.Connection = Connection;
78668  exports.ConnectionMonitor = ConnectionMonitor;
78669  exports.Consumer = Consumer;
78670  exports.INTERNAL = INTERNAL;
78671  exports.Subscription = Subscription;
78672  exports.SubscriptionGuarantor = SubscriptionGuarantor;
78673  exports.Subscriptions = Subscriptions;
78674  exports.adapters = adapters;
78675  exports.createConsumer = createConsumer;
78676  exports.createWebSocketURL = createWebSocketURL;
78677  exports.getConfig = getConfig;
78678  exports.logger = logger;
78679  Object.defineProperty(exports, "__esModule", {
78680    value: true
78681  });
78682}));
78683// Action Cable provides the framework to deal with WebSockets in Rails.
78684// You can generate new channels where WebSocket features live using the `rails generate channel` command.
78685//
78686
78687
78688
78689
78690(function() {
78691  this.App || (this.App = {});
78692  const httpProtocol = location.protocol
78693  const websocketProtocol = httpProtocol === 'https:' ? 'wss:' : 'ws:'
78694  const domainName = window.location.host
78695
78696  App.cable = ActionCable.createConsumer(`${websocketProtocol}//${domainName}/cable/`);
78697
78698}).call(this);
78699(function() {
78700  App.activities = App.cable.subscriptions.create("ActivitiesChannel", {
78701    collection: function() {
78702      return $("[data-channel='activities']");
78703    },
78704    connected: function() {
78705      return setTimeout((function(_this) {
78706        return function() {
78707          _this.follow();
78708          return _this.installPageChangeCallback();
78709        };
78710      })(this), 1000);
78711    },
78712    disconnected: function() {},
78713    received: function(data) {
78714      this.collection().prepend($(data["output"]).hide().fadeIn('slow'));
78715      if (this.collection().children().length > 20) {
78716        return this.collection().children().last().remove();
78717      }
78718    },
78719    installPageChangeCallback: function() {
78720      if (!this.installPageChangeCallback) {
78721        this.installPageChangeCallback = true;
78722        return $(document).ready(function() {
78723          return App.room.follow();
78724        });
78725      }
78726    },
78727    follow: function() {
78728      if (this.collection()) {
78729        return this.perform('follow', {
78730          school_id: this.collection().data("school-id"),
78731          goal_id: this.collection().data("goal-id")
78732        });
78733      } else {
78734        return this.perform('unfollow', {
78735          school_id: this.collection().data("school-id"),
78736          goal_id: this.collection().data("goal-id")
78737        });
78738      }
78739    }
78740  });
78741
78742}).call(this);
78743(function() {
78744  App.chat_notification = App.cable.subscriptions.create("ChatNotificationChannel", {
78745    collection: function() {
78746      return $("[data-channel='chat_notification']");
78747    },
78748    connected: function() {
78749      return setTimeout((function(_this) {
78750        return function() {
78751          _this.followCurrentRoom();
78752          return _this.installPageChangeCallback();
78753        };
78754      })(this), 1000);
78755    },
78756    disconnected: function() {},
78757    mark_as_read: function(chat_room_id) {
78758      return this.perform("mark_as_read", {
78759        chat_room_id: chat_room_id
78760      });
78761    },
78762    received: function(notis) {
78763      var data;
78764      data = notis["data"].reverse();
78765      this.collection().each((function(_this) {
78766        return function(index, collection) {
78767          if ($(collection).data('message-notification-popup')) {
78768            $(collection).html(data.filter(function(notification) {
78769              return notification["unread_count"] > 0;
78770            }).length);
78771          }
78772          return data.forEach(function(notification) {
78773            $(collection).find("[data-chat-room-id='" + notification["chat_room_id"] + "']").html(notification["unread_count"]);
78774            if ($(collection).data("chat-sortable") != null) {
78775              return $(collection).find("[data-chat-room-id='" + notification["chat_room_id"] + "']").closest("li").prependTo($(collection).closest("ul"));
78776            }
78777          });
78778        };
78779      })(this));
78780      return $("#chat-notification-popover").children().appendTo("#chat-notification");
78781    },
78782    installPageChangeCallback: function() {
78783      if (!this.installPageChangeCallback) {
78784        this.installPageChangeCallback = true;
78785        return $(document).ready(function() {
78786          return App.room.followCurrentRoom();
78787        });
78788      }
78789    },
78790    followCurrentRoom: function() {
78791      if (this.collection()) {
78792        return this.perform('follow');
78793      } else {
78794        return this.perform('unfollow');
78795      }
78796    }
78797  });
78798
78799  $(document).on('focus', '[data-behavior~=room_speaker]', function(event) {
78800    return App.chat_notification.mark_as_read($(this).data("chat-room-id"));
78801  });
78802
78803}).call(this);
78804(function() {
78805  var stop_typing;
78806
78807  App.chat_room = App.cable.subscriptions.create("ChatRoomChannel", {
78808    collection: function() {
78809      return $("[data-channel='messages']");
78810    },
78811    connected: function() {
78812      return setTimeout((function(_this) {
78813        return function() {
78814          _this.followCurrentRoom();
78815          return _this.installPageChangeCallback();
78816        };
78817      })(this), 1000);
78818    },
78819    disconnected: function() {},
78820    received: function(data) {
78821      var user_id;
78822      if (data.message != null) {
78823        user_id = $(data.message).attr('data-user-id');
78824        this.collection().find(".typing[data-user-id='" + user_id + "']").remove();
78825        return this.collection().prepend(data.message);
78826      } else if (data.typing != null) {
78827        this.collection().find(".typing[data-user-id='" + data.typing.user_id + "']").remove();
78828        if (data.typing.message != null) {
78829          this.collection().find(".typing").slice(-3).remove();
78830          if (!this.userIsCurrentUser(data.typing.message)) {
78831            return this.collection().prepend(data.typing.message);
78832          }
78833        }
78834      }
78835    },
78836    userIsCurrentUser: function(message) {
78837      return $(message).attr('data-user-id') === $('meta[name=current-user]').attr('id');
78838    },
78839    typing: function(chat_room_id) {
78840      return this.perform('typing', {
78841        chat_room_id: chat_room_id
78842      });
78843    },
78844    stop_typing: function(chat_room_id) {
78845      return this.perform('stop_typing', {
78846        chat_room_id: chat_room_id
78847      });
78848    },
78849    speak: function(message, chat_room_id) {
78850      return this.perform('speak', {
78851        body: message,
78852        chat_room_id: chat_room_id
78853      });
78854    },
78855    installPageChangeCallback: function() {
78856      if (!this.installedPageChangeCallback) {
78857        this.installedPageChangeCallback = true;
78858        $(document).ready(function() {
78859          return function() {
78860            return App.chat_room.followCurrentRoom();
78861          };
78862        });
78863        return setInterval((function(_this) {
78864          return function() {
78865            return $(".typing").each(function(index, element) {
78866              var hide_after;
78867              hide_after = ($(element).data("hide-after") || 30) - 1;
78868              $(element).data(hide_after);
78869              if (hide_after <= 0) {
78870                return $(element).remove();
78871              }
78872            });
78873          };
78874        })(this), 1000);
78875      }
78876    },
78877    followCurrentRoom: function() {
78878      var id;
78879      if (id = this.collection().data('chat-room-id')) {
78880        return this.perform('follow', {
78881          chat_room_id: id
78882        });
78883      } else {
78884        return this.perform('unfollow');
78885      }
78886    }
78887  });
78888
78889  stop_typing = null;
78890
78891  $(document).on('keyup', '[data-behavior~=room_speaker]', function(event) {
78892    if (event.shiftKey && event.keyCode === 13) {
78893      App.chat_room.speak(event.target.value, $(this).data("chat-room-id"));
78894      $("[data-channel='chat_notification'][data-chat-sortable='true']").find("[data-chat-room-id='" + ($(this).data("chat-room-id")) + "']").closest("li").prependTo($("[data-channel='chat_notification'][data-chat-sortable='true']").closest("ul"));
78895      $(this).scrollTop(0);
78896      event.target.value = '';
78897      return event.preventDefault();
78898    } else if (event.keyCode >= 32 && event.keyCode <= 127) {
78899      if (stop_typing != null) {
78900        clearTimeout(stop_typing);
78901        stop_typing = null;
78902      } else {
78903        App.chat_room.typing($(this).data("chat-room-id"));
78904      }
78905      return stop_typing = setTimeout((function(_this) {
78906        return function() {
78907          App.chat_room.stop_typing($(_this).data("chat-room-id"));
78908          return stop_typing = null;
78909        };
78910      })(this), 1000);
78911    }
78912  });
78913
78914}).call(this);
78915(function() {
78916  $(document).ready(function() {
78917    var container, eventId;
78918    container = $("[data-chat-event-id]");
78919    if (container.length > 0) {
78920      eventId = container.data('chat-event-id');
78921      console.log("Found event ID:", eventId);
78922      return App.meetingChat = App.cable.subscriptions.create({
78923        channel: "MeetingChatChannel",
78924        event_id: eventId
78925      }, {
78926        chatContainer: function() {
78927          return $("[data-chat-event-id]");
78928        },
78929        messagesContainer: function() {
78930          return $(".jicoo-message-container");
78931        },
78932        chatForm: function() {
78933          return $("#chat-form");
78934        },
78935        chatInput: function() {
78936          return $("#chat-input");
78937        },
78938        emailNotification: function() {
78939          return $("#detail-email-notification");
78940        },
78941        connected: function() {
78942          console.log("✅ WebSocket connected with event ID: " + eventId + "!");
78943          return setTimeout((function(_this) {
78944            return function() {
78945              _this.installScrollToBottom();
78946              return _this.installFormHandler();
78947            };
78948          })(this), 1000);
78949        },
78950        disconnected: function() {
78951          return console.log("WebSocket disconnected!");
78952        },
78953        received: function(data) {
78954          var isMine, messageClass, messageHtml;
78955          console.log("✅ WebSocket received message!");
78956          console.log(data);
78957          if (data.html) {
78958            this.messagesContainer().append(data.html);
78959          } else {
78960            isMine = data.sender_id === window.currentUserId;
78961            messageClass = isMine ? "jicoo-message my-message" : "jicoo-message";
78962            messageHtml = "<div class=\"d-flex " + messageClass + "\" data-message-id=\"" + data.id + "\">\n  <div class=\"message-avatar\">\n    <img src=\"/assets/default_avatar.png\" alt=\"" + data.sender_name + " avatar\" width=\"36\" height=\"36\" class=\"rounded-circle\">\n  </div>\n  <div class=\"flex-grow-1\">\n    <div class=\"d-flex " + (isMine ? 'justify-content-end' : 'justify-content-between') + " align-items-center mb-1\">\n      <div>" + data.sender_name + "</div>\n      <small class=\"text-muted ms-2\">" + data.created_at + "</small>\n    </div>\n    <div class=\"message-content " + (isMine ? 'sent' : 'received') + "\">\n      <p class=\"mb-0\">" + (data.content.replace(/\n/g, '<br>')) + "</p>\n    </div>\n  </div>\n</div>";
78963            this.messagesContainer().append(messageHtml);
78964          }
78965          return this.scrollToBottom();
78966        },
78967        installScrollToBottom: function() {
78968          return this.scrollToBottom();
78969        },
78970        scrollToBottom: function() {
78971          container = this.messagesContainer();
78972          if (container.length > 0) {
78973            return container.scrollTop(container[0].scrollHeight);
78974          }
78975        },
78976        installFormHandler: function() {
78977          var form, self;
78978          console.log("Installing form handler");
78979          form = this.chatForm();
78980          if (form.length > 0) {
78981            self = this;
78982            return form.off('submit').on('submit', function(e) {
78983              var content, notifyEmail;
78984              e.preventDefault();
78985              content = self.chatInput().val().trim();
78986              if (content) {
78987                eventId = self.chatContainer().data('chat-event-id');
78988                notifyEmail = self.emailNotification().prop('checked') || false;
78989                self.perform('receive', {
78990                  event_id: eventId,
78991                  content: content,
78992                  notify_by_email: notifyEmail
78993                });
78994                self.chatInput().val('');
78995                self.emailNotification().prop('checked', false);
78996              }
78997              return false;
78998            });
78999          }
79000        }
79001      });
79002    }
79003  });
79004
79005}).call(this);
79006(function() {
79007  App.notification = App.cable.subscriptions.create("NotificationChannel", {
79008    collection: function() {
79009      return $("[data-channel='notification']");
79010    },
79011    connected: function() {
79012      return setTimeout((function(_this) {
79013        return function() {
79014          _this.followCurrentRoom();
79015          return _this.installPageChangeCallback();
79016        };
79017      })(this), 1000);
79018    },
79019    disconnected: function() {},
79020    received: function(notis) {
79021      return this.collection().each((function(_this) {
79022        return function(index, collection) {
79023          return $(collection).html(notis["unread_count"] ? notis["unread_count"] : "");
79024        };
79025      })(this));
79026    },
79027    installPageChangeCallback: function() {
79028      if (!this.installPageChangeCallback) {
79029        this.installPageChangeCallback = true;
79030        return $(document).ready(function() {
79031          return App.room.followCurrentRoom();
79032        });
79033      }
79034    },
79035    followCurrentRoom: function() {
79036      if (this.collection()) {
79037        return this.perform('follow');
79038      } else {
79039        return this.perform('unfollow');
79040      }
79041    }
79042  });
79043
79044}).call(this);
79045(function() {
79046  App.tracking = App.cable.subscriptions.create("TrackingChannel", {
79047    connected: function() {},
79048    disconnected: function() {},
79049    auto_start_stop_exam: function(school_id, exam_id) {
79050      return $(document).ready(function() {
79051        setTimeout((function(_this) {
79052          return function() {
79053            return _this.start_exam(school_id, exam_id);
79054          };
79055        })(this), 1000);
79056        return $(document).ready(function() {
79057          return this.stop_exam(school_id, exam_id);
79058        });
79059      });
79060    },
79061    auto_start_stop_lesson: function(school_id, lesson_id) {
79062      return $(document).ready(function() {
79063        setTimeout((function(_this) {
79064          return function() {
79065            return _this.start_lesson(school_id, lesson_id);
79066          };
79067        })(this), 1000);
79068        return $(document).ready(function() {
79069          return this.stop_lesson(school_id, lesson_id);
79070        });
79071      });
79072    },
79073    start_exam: function(school_id, exam_id) {
79074      this.perform('start_exam', {
79075        school_id: school_id,
79076        exam_id: exam_id
79077      });
79078      return this.start_count_down_example(school_id, exam_id);
79079    },
79080    stop_exam: function(school_id, exam_id) {
79081      return this.perform('stop_exam', {
79082        school_id: school_id,
79083        exam_id: exam_id
79084      });
79085    },
79086    start_video_lesson: function(school_id, lesson_id) {
79087      this.perform('start_video_lesson', {
79088        school_id: school_id,
79089        lesson_id: lesson_id
79090      });
79091      return this.start_count_down_lesson_video(school_id, lesson_id);
79092    },
79093    stop_video_lesson: function(school_id, lesson_id) {
79094      return this.perform('stop_video_lesson', {
79095        school_id: school_id,
79096        lesson_id: lesson_id
79097      });
79098    },
79099    start_lesson: function(school_id, lesson_id) {
79100      this.perform('start_lesson', {
79101        school_id: school_id,
79102        lesson_id: lesson_id
79103      });
79104      return this.start_count_down_lesson(school_id, lesson_id);
79105    },
79106    stop_lesson: function(school_id, lesson_id) {
79107      return this.perform('stop_lesson', {
79108        school_id: school_id,
79109        lesson_id: lesson_id
79110      });
79111    },
79112    okClicked: false,
79113    count_down_time: (30 * 60) * 1000,
79114    handle_time: 30 * 1000,
79115    start_count_down_lesson: function(school_id, lesson_id) {
79116      this.okClicked = true;
79117      return setTimeout((function(_this) {
79118        return function() {
79119          return App.tracking.stop_lesson(school_id, lesson_id);
79120        };
79121      })(this), App.tracking.count_down_time);
79122    },
79123    start_count_down_example: function(school_id, exam_id) {
79124      this.okClicked = true;
79125      return setTimeout((function(_this) {
79126        return function() {
79127          return App.tracking.stop_exam(school_id, exam_id);
79128        };
79129      })(this), App.tracking.count_down_time);
79130    },
79131    start_count_down_lesson_video: function(school_id, lesson_id) {
79132      this.okClicked = true;
79133      return setTimeout((function(_this) {
79134        return function() {
79135          return App.tracking.stop_video_lesson(school_id, lesson_id);
79136        };
79137      })(this), App.tracking.count_down_time);
79138    }
79139  });
79140
79141}).call(this);
79142(function() {
79143  this.scrollHandler = function() {
79144    var fetching, loaded_all, page;
79145    page = $(this).data("page") || 1;
79146    loaded_all = $(this).data("loaded-all");
79147    fetching = $(this).data("fetching");
79148    if ($(this).scrollTop() + $(this).height() >= this.scrollHeight - 10 && !fetching && !loaded_all) {
79149      $(this).data("fetching", true);
79150      $(this).data("page", page + 1);
79151      return $.get({
79152        url: $(this).data("fetch-url"),
79153        data: {
79154          page: page + 1
79155        },
79156        complete: (function(_this) {
79157          return function() {
79158            return $(_this).data("fetching", false);
79159          };
79160        })(this)
79161      });
79162    }
79163  };
79164
79165  $(document).ready(function() {
79166    return $("[data-channel='messages']").off('scroll', scrollHandler).on('scroll', scrollHandler);
79167  });
79168
79169}).call(this);
79170(function() {
79171  var cheating_confirm, cheating_detected, cheating_detector, checkTestWindow, checking, confirming, detect_cheating, noPrompt;
79172
79173  confirming = false;
79174
79175  cheating_detected = false;
79176
79177  detect_cheating = function() {
79178    var checking;
79179    $.ajax({
79180      type: "PUT",
79181      url: $("#cheating-detector").data("cheating-url")
79182    });
79183    console.log("CHEATING DETECTED!");
79184    cheating_detected = true;
79185    clearInterval(checking);
79186    return checking = null;
79187  };
79188
79189  checkTestWindow = function() {
79190    if (cheating_detected) {
79191      return;
79192    }
79193    if (!parent.window.opener || parent.window.opener.closed) {
79194      cheating_detected = true;
79195      return window.location = $("#cheating-detector").data("start-url");
79196    } else {
79197      return setTimeout(checkTestWindow, 200);
79198    }
79199  };
79200
79201  cheating_confirm = function() {
79202    if (confirming) {
79203      return;
79204    }
79205    confirming = true;
79206    return setTimeout((function(_this) {
79207      return function() {
79208        if (!document.hasFocus() && document.readyState === "complete" && $("#cheating-detector").length > 0) {
79209          return detect_cheating();
79210        } else {
79211          return confirming = false;
79212        }
79213      };
79214    })(this), 500);
79215  };
79216
79217  cheating_detector = function() {
79218    if (!document.hasFocus() && document.readyState === "complete" && $("#cheating-detector").length > 0) {
79219      return cheating_confirm();
79220    }
79221  };
79222
79223  checking = null;
79224
79225  noPrompt = false;
79226
79227  $(document).ready(function() {
79228    if (checking) {
79229      clearInterval(checking);
79230      checking = null;
79231    }
79232    if ($("#cheating-detector").length > 0) {
79233      $(".submit-exam").data("origin-confirm", $(".submit-exam").data("confirm"));
79234      $(".submit-exam").data("confirm", "");
79235      checking = setInterval(cheating_detector, 200);
79236      setTimeout(checkTestWindow, 200);
79237      return $(".submit-exam").on("click", function(event) {
79238        if ($.rails.confirm($(this).data("origin-confirm"))) {
79239          noPrompt = true;
79240          return window.close();
79241        } else {
79242          event.preventDefault();
79243          return false;
79244        }
79245      });
79246    }
79247  });
79248
79249  window.onbeforeunload = function() {
79250    if (!noPrompt && $("#cheating-detector").length > 0 && !cheating_detected) {
79251      return "クローズしたらテストを提出します。それでもよろしいですか?";
79252    }
79253  };
79254
79255}).call(this);
79256var $,methods;$=window.jQuery||window.Zepto,window.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(a){return window.setTimeout(a,1e3/60)}}(),methods={init:function(a){var b,c,d,e,f;return this.empty(),d={timeout:5e3,onComplete:function(){},onUpdate:function(){},clockwise:!0},c={},c.options=$.extend(d,a),this.data("ct-meta",c),b=document.createElementNS("http://www.w3.org/2000/svg","circle"),b.setAttributeNS(null,"r","25%"),b.setAttributeNS(null,"cx","50%"),b.setAttributeNS(null,"cy","50%"),b.setAttributeNS(null,"stroke-dasharray",50*Math.PI+"%"),f=document.createElementNS("http://www.w3.org/2000/svg","svg"),f.appendChild(b),e=$("<div></div>"),e.attr("id","ct-circle-container"),e.append(f),this.append(e)},start:function(){var a,b,c,d;return b=this.data("ct-meta"),(null==b.timeElapsed||b.timeElapsed===b.options.timeout)&&(c=null,b.timeElapsed=0),null!=b.reqId&&window.cancelAnimationFrame(b.reqId),a=$(this).find("circle"),d=function(e){var f;return null!=c&&(b.timeElapsed+=e-c),c=e,f=b.options.clockwise?-1:1,a.css("stroke-dashoffset",50*f*Math.PI*b.timeElapsed/b.options.timeout+"%"),b.timeElapsed<b.options.timeout?(b.reqId=window.requestAnimationFrame(d),b.options.onUpdate(b.timeElapsed)):(b.timeElapsed=b.options.timeout,b.options.onUpdate(b.timeElapsed),b.options.onComplete())},b.reqId=window.requestAnimationFrame(d),this.data("ct-meta",b)},stop:function(){var a;return a=this.data("ct-meta"),window.cancelAnimationFrame(a.reqId),a.timeElapsed=0,a.options.onUpdate(a.timeElapsed),this.data("ct-meta",a)},pause:function(){var a;return a=this.data("ct-meta"),window.cancelAnimationFrame(a.reqId),this.data("ct-meta",a)},add:function(a){var b;return b=this.data("ct-meta"),a<b.timeElapsed?b.timeElapsed-=a:b.timeElapsed=0,this.data("ct-meta",b)}},$.fn.circletimer=function(a){return methods[a]?methods[a].apply(this,Array.prototype.slice.call(arguments,1
79256)):"object"!=typeof a&&a?$.error("Method "+a+" does not exist in circletimer!"):methods.init.apply(this,arguments)};
79257(function() {
79258  var showQuestion;
79259
79260  showQuestion = function(qId) {
79261    $(".question-form").hide();
79262    $(".question-form[data-q-id='" + qId + "']").show();
79263    $(".open-question").removeClass("active");
79264    $(".open-question[data-q-id='" + qId + "']").addClass("active");
79265    if ($(".answer-status.done-icon").length > 0) {
79266      return $(".submit-exam").show();
79267    }
79268  };
79269
79270  $(document).ready(function() {
79271    var qId;
79272    if ($(".question-detail").length > 0) {
79273      qId = window.location.hash.substring(window.location.hash.indexOf('#') + 1);
79274      if (qId) {
79275        return showQuestion(qId);
79276      } else {
79277        return showQuestion($(".question-form:first").data("q-id"));
79278      }
79279    }
79280  });
79281
79282  $(document).on("click", ".open-question", function(event) {
79283    var qId;
79284    qId = $(this).data("q-id");
79285    showQuestion(qId);
79286    return true;
79287  });
79288
79289  $(document).on("click", ".next-answer", function(event) {
79290    var ckeditorId, currentQId, nextQId;
79291    event.preventDefault();
79292    currentQId = $(this).closest(".question-form").data("q-id");
79293    nextQId = $(this).closest(".question-form").nextAll(".not-answered:first").data("q-id");
79294    if (nextQId == null) {
79295      nextQId = $(this).closest(".question-form").siblings(".not-answered:first").data("q-id");
79296    }
79297    if (nextQId == null) {
79298      nextQId = $(this).closest(".question-form").nextAll(".submit-form").data("q-id");
79299    }
79300    if (nextQId) {
79301      showQuestion(nextQId);
79302    } else {
79303      $(".submit-exam").trigger("click");
79304    }
79305    if ((ckeditorId = $(".question-form[data-q-id='" + currentQId + "'] .custom-ckeditor").attr("id")) && (CKEDITOR.instances[ckeditorId] != null)) {
79306      $(".question-form[data-q-id='" + currentQId + "'] .custom-ckeditor").val(CKEDITOR.instances[ckeditorId].getData());
79307    }
79308    $(this.form).trigger("submit.rails");
79309    return false;
79310  });
79311
79312}).call(this);
79313(function() {
79314  var toogle_export_button;
79315
79316  toogle_export_button = function() {
79317    return setTimeout(function() {
79318      if ($(".export-item:checked").length > 0) {
79319        return $(".export-button").removeClass("disabled").tooltip('destroy');
79320      } else {
79321        return $(".export-button").addClass("disabled").tooltip();
79322      }
79323    });
79324  };
79325
79326  $(document).on("change", ".export-item, .select-all", toogle_export_button);
79327
79328  $(document).ready(function() {
79329    return toogle_export_button;
79330  });
79331
79332}).call(this);
79333(function() {
79334  $(document).on("click", ".cancel-form", function() {
79335    var old_html, wrapper;
79336    wrapper = $(this).closest("form").parent();
79337    old_html = wrapper.data("old-html") || "";
79338    wrapper.html(old_html);
79339    return false;
79340  });
79341
79342}).call(this);
79343(function() {
79344  var checkTestWindow, fixSideBar, fixedSidebar, isPC, noScrollLeft;
79345
79346  checkTestWindow = function(test_window) {
79347    if (test_window.closed) {
79348      return $(".submit-exam").trigger("click");
79349    } else {
79350      return setTimeout((function() {
79351        return checkTestWindow(test_window);
79352      }), 200);
79353    }
79354  };
79355
79356  $(document).on("click", ".start-test", function(event) {
79357    var test_window;
79358    event.preventDefault();
79359    test_window = window.open($(this).prop("href"), '_blank', 'width=800 ,height=600');
79360    $(this).attr({
79361      disabled: true
79362    }).html("提出中。。。");
79363    setTimeout((function() {
79364      return checkTestWindow(test_window);
79365    }), 200);
79366    return false;
79367  });
79368
79369  $(document).ready(function() {
79370    fixSideBar();
79371    return $(window).on('resize', fixSideBar);
79372  });
79373
79374  $(window).on('load', function() {
79375    fixSideBar();
79376    return $(window).on('resize', fixSideBar);
79377  });
79378
79379  isPC = function() {
79380    if ($(window).width() > 960) {
79381      return true;
79382    } else {
79383      return false;
79384    }
79385  };
79386
79387  fixSideBar = function() {
79388    var $unit, $wrapper;
79389    $unit = $('#js-question-list');
79390    $wrapper = $('#js-question-list');
79391    if (isPC()) {
79392      if ($unit.length > 0) {
79393        return fixedSidebar.run();
79394      }
79395    } else {
79396      $(window).off('scroll', fixedSidebar._onScroll);
79397      return $wrapper.css({
79398        position: 'relative',
79399        top: '0px',
79400        padding: '0px'
79401      });
79402    }
79403  };
79404
79405  noScrollLeft = function() {
79406    var wrapper_width;
79407    wrapper_width = $('#js-question-list').outerWidth();
79408    if ($(window).width() >= wrapper_width) {
79409      return true;
79410    } else {
79411      return false;
79412    }
79413  };
79414
79415  fixedSidebar = (function() {
79416    var $question_positions, $unit, $wrapper, _onScroll, fixed_start, fixpx_end_top, header_height, item_default_height;
79417    $wrapper = $('#js-question-list');
79418    $unit = $('#js-question-list-content');
79419    fixed_start = 0;
79420    fixpx_end_top = 0;
79421    header_height = 55;
79422    item_default_height = $(window).height() - header_height - ($wrapper.outerHeight(true) - $unit.outerHeight());
79423    $question_positions = $('.question-score').map(function(index, elm) {
79424      return $(elm).offset().top;
79425    });
79426    _onScroll = function() {
79427      var current_question, prevElement, question_class, screen_height, start_top, width, win_scrol_top;
79428      win_scrol_top = $(window).scrollTop();
79429      screen_height = win_scrol_top + header_height;
79430      prevElement = $($wrapper[0].previousElementSibling);
79431      start_top = prevElement.offset().top + prevElement.height() + 1;
79432      width = $unit.width();
79433      if (screen_height > start_top) {
79434        $wrapper.css({
79435          position: 'fixed',
79436          top: header_height + 'px',
79437          padding: '0px 35px 20px 0px'
79438        });
79439        $unit.css({
79440          width: width
79441        });
79442      } else {
79443        $wrapper.css({
79444          position: 'relative',
79445          top: '0px',
79446          padding: '0px'
79447        });
79448      }
79449      current_question = $question_positions.toArray().findIndex(function(elm) {
79450        return $(window).scrollTop() < elm;
79451      });
79452      if (current_question > 0) {
79453        $(".question-link").css("color", "#337ab7");
79454        question_class = $($(".question-score")[current_question - 1]).attr("id");
79455        return $(".question-link." + question_class).css("color", "gray");
79456      }
79457    };
79458    return {
79459      run: function() {
79460        $wrapper = $('#js-question-list');
79461        $unit = $('#js-question-list-content');
79462        $question_positions = $('.question-score').map(function(index, elm) {
79463          return $(elm).offset().top;
79464        });
79465        this.setScroll();
79466        return this.refresh();
79467      },
79468      setScroll: function() {
79469        $wrapper = $('#js-question-list');
79470        $unit = $('#js-question-list-content');
79471        this.reset();
79472        if ($wrapper.outerHeight(true) >= $(window).height()) {
79473          item_default_height = $(window).height() - header_height - ($wrapper.outerHeight(true) - $unit.outerHeight()) - 60;
79474          $unit.css({
79475            height: item_default_height,
79476            overflow: "scroll"
79477          });
79478          return $wrapper.css({
79479            height: "",
79480            overflow: ""
79481          });
79482        }
79483      },
79484      refresh: function() {
79485        $(window).off('scroll', _onScroll).on('scroll', _onScroll);
79486        return $(window).trigger('scroll');
79487      },
79488      reset: function() {
79489        $wrapper = $('#js-question-list');
79490        $unit = $('#js-question-list-content');
79491        $wrapper.css({
79492          height: "100%",
79493          overflow: "auto",
79494          position: "",
79495          padding: ""
79496        });
79497        return $unit.css({
79498          height: "100%",
79499          overflow: "auto",
79500          width: "100%"
79501        });
79502      }
79503    };
79504  })();
79505
79506}).call(this);
79507$(document).on('click', function (e) {
79508  $('[data-toggle="popover"],[data-original-title]').each(function () {
79509    if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
79510      (($(this).popover('hide').data('bs.popover')||{}).inState||{}).click = false  // fix for BS 3.3.6
79511    }
79512  });
79513});
79514function disableContactFormSubmitButton() {
79515  var btn = document.querySelector('.qbase_contact_form_submit')
79516  if (!btn || btn.disabled) return
79517  btn.dataset.originalText = btn.textContent
79518  setTimeout(function () {
79519    btn.textContent = '送信中...'
79520    btn.disabled = true
79521    btn.style.setProperty('cursor', 'not-allowed', 'important')
79522  }, 0)
79523}
79524
79525function enableContactFormSubmitButton() {
79526  var btn = document.querySelector('.qbase_contact_form_submit')
79527  if (!btn || !btn.disabled) return
79528  if (btn.dataset.originalText) {
79529    btn.textContent = btn.dataset.originalText
79530  }
79531  btn.disabled = false
79532  btn.style.removeProperty('cursor')
79533}
79534
79535function contactFormCheckInput() {
79536  num = document.getElementById('current_contact_form')?.attributes['data-value'].value
79537  if (!num) {
79538    alert('Can not detect form')
79539  }
79540
79541  if ($('#captcha_element').length != 0) {
79542    if (grecaptcha.getResponse() == '') {
79543      document.getElementById('captcha-require').style.display = 'block'
79544      return false
79545    }
79546  }
79547
79548  if ($(':checkbox[name^=qbase_contact_form]').length != 0 && $(':checkbox:checked').length == 0) {
79549    if ($(`.qbase_contact_form_require_${num}:checkbox`).length > 0) {
79550      let name = $(`.qbase_contact_form_require_${num}:checkbox`)[0].name.split('_0')[0]
79551      document.getElementById(`${name}-require`).style.display = 'block'
79552      return false
79553    }
79554  }
79555
79556  require_eles = document.querySelectorAll(`.qbase_contact_form_require_${num}`)
79557  if (require_eles.length > 0) {
79558    let error_count = 0
79559    for (let i = 0; i < require_eles.length; i++) {
79560      if (require_eles[i].value == '') {
79561        error_count += 1
79562        require_eles[i].style.backgroundColor = '#ff7b7b'
79563        if (require_eles[i].nextElementSibling) require_eles[i].nextElementSibling.style.display = 'block'
79564      }
79565    }
79566    if (error_count > 0) {
79567      return false
79568    } else {
79569      disableContactFormSubmitButton()
79570      return true
79571    }
79572  } else {
79573    disableContactFormSubmitButton()
79574    return true
79575  }
79576}
79577
79578function onloadCallback() {
79579  var formSpan = document.getElementById('current_contact_form')
79580  var captchaEl = document.getElementById('captcha_element')
79581  if (!formSpan || !captchaEl) return
79582
79583  var sitekey = formSpan.getAttribute('data-capchart')
79584  if (!sitekey) return
79585
79586  grecaptcha.render('captcha_element', { sitekey: sitekey })
79587}
79588
79589$(document).ajaxComplete(function (event, xhr, settings) {
79590  if (!settings.url.includes('/submit_contact_form/')) return
79591  if (xhr.responseJSON && xhr.responseJSON.redirect) {
79592    window.location.href = xhr.responseJSON.redirect
79593  } else if (xhr.status >= 200 && xhr.status < 300) {
79594    if (window.onContactFormCheckInputSuccess) {
79595      window.onContactFormCheckInputSuccess()
79596    }
79597  } else {
79598    enableContactFormSubmitButton()
79599  }
79600});
79601(function() {
79602  this.daterangepicker_config = {
79603    opens: "left",
79604    locale: {
79605      format: "YYYY/MM/DD",
79606      cancelLabel: "キャンセル",
79607      applyLabel: "更新する",
79608      customRangeLabel: "カスタム",
79609      "daysOfWeek": ["日", "月", "火", "水", "木", "金", "土"],
79610      "monthNames": ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"]
79611    }
79612  };
79613
79614  this.default_evaluation_duration = {
79615    ranges: {
79616      "今クォーター": [moment().startOf('quarter'), moment().endOf('quarter')],
79617      "来クォーター": [moment().add(1, 'quarter').startOf('quarter'), moment().add(1, 'quarter').endOf('quarter')]
79618    }
79619  };
79620
79621}).call(this);
79622(function() {
79623  $(document).keypress(function(event) {
79624    if (event.ctrlKey && event.which === 112) {
79625      return $("#footnotes_debug").toggle();
79626    }
79627  });
79628
79629}).call(this);
79630(function() {
79631  $(document).off("click", ".destroy-checkbox").on("click", ".destroy-checkbox", function() {
79632    var destroy_input, ref;
79633    destroy_input = $(this).next();
79634    return destroy_input.val((ref = destroy_input.val() === "false") != null ? ref : {
79635      "true": "false"
79636    });
79637  });
79638
79639}).call(this);
79640(function() {
79641  $(document).on("click", "button.disabled", function(e) {
79642    return e.preventDefault();
79643  });
79644
79645}).call(this);
79646$(document).on("click", ".public-exam-link", function(event){
79647  event.preventDefault();
79648  $("#exam_link_modal .copied-note").hide();
79649  if ($(this).data("public-link")) {
79650    $("#exam_link_modal .public-test").show();
79651    $("#exam_link_modal .public-test .public-exam-url").val($(this).data("public-link"));
79652  } else {
79653    $("#exam_link_modal .public-test").hide();
79654  }
79655  $("#exam_link_modal").modal("show");
79656})
79657
79658$(document).on("click", "#exam_link_modal .copy-button", function(){
79659  $("#exam_link_modal .public-test .public-exam-url").focus();
79660  document.execCommand("copy");
79661  $("#exam_link_modal .copied-note").html("クリボードにコピーしました").show();
79662});
79663// Reveal Material Icons only after the icon font is actually loaded.
79664// Icons are visibility:hidden by default (see material_icon.scss) to avoid
79665// flashing raw ligature text ("home", "search"...) before the font arrives.
79666// Using a fixed timeout caused an intermittent bug: on slow networks the font
79667// was not ready at the deadline, so the ligature text leaked through.
79668(function () {
79669  function showFonts() {
79670    document.documentElement.classList.add('fonts-loaded');
79671  }
79672
79673  // Safety net: never keep icons hidden forever (slow/failed CDN, old browser).
79674  var fallbackTimer = setTimeout(showFonts, 3000);
79675
79676  if (document.fonts && document.fonts.load) {
79677    Promise.all([
79678      document.fonts.load('400 24px "Material Icons"'),
79679      document.fonts.load('400 24px "Material Icons Outlined"')
79680    ]).then(function () {
79681      clearTimeout(fallbackTimer);
79682      showFonts();
79683    }).catch(function () {
79684      clearTimeout(fallbackTimer);
79685      showFonts();
79686    });
79687  } else {
79688    // Browsers without the Font Loading API: fall back to the old behaviour.
79689    clearTimeout(fallbackTimer);
79690    document.addEventListener('DOMContentLoaded', function () {
79691      setTimeout(showFonts, 100);
79692    });
79693  }
79694})();
79695(function() {
79696  $(document).on("change", ".select-all", function() {
79697    return $(this.form).find($(this).data("select-target")).prop("checked", $(this).prop("checked"));
79698  });
79699
79700}).call(this);
79701!function(e){"undefined"!=typeof exports?e(exports):(window.hljs=e({}),"function"==typeof define&&define.amd&&define("hljs",[],function(){return window.hljs}))}(function(e){function t(e){return e.replace(/&/gm,"&amp;").replace(/</gm,"&lt;").replace(/>/gm,"&gt;")}function r(e){return e.nodeName.toLowerCase()}function a(e,t){var r=e&&e.exec(t);return r&&0==r.index}function n(e){return/no-?highlight|plain|text/.test(e)}function i(e){var t,r,a,i=e.className+" ";if(i+=e.parentNode?e.parentNode.className:"",r=/\blang(?:uage)?-([\w-]+)\b/.exec(i))return y(r[1])?r[1]:"no-highlight";for(i=i.split(/\s+/),t=0,a=i.length;a>t;t++)if(y(i[t])||n(i[t]))return i[t]}function s(e,t){var r,a={};for(r in e)a[r]=e[r];if(t)for(r in t)a[r]=t[r];return a}function c(e){var t=[];return function a(e,n){for(var i=e.firstChild;i;i=i.nextSibling)3==i.nodeType?n+=i.nodeValue.length:1==i.nodeType&&(t.push({event:"start",offset:n,node:i}),n=a(i,n),r(i).match(/br|hr|img|input/)||t.push({event:"stop",offset:n,node:i}));return n}(e,0),t}function o(e,a,n){function i(){return e.length&&a.length?e[0].offset!=a[0].offset?e[0].offset<a[0].offset?e:a:"start"==a[0].event?e:a:e.length?e:a}function s(e){function a(e){return" "+e.nodeName+'="'+t(e.value)+'"'}u+="<"+r(e)+Array.prototype.map.call(e.attributes,a).join("")+">"}function c(e){u+="</"+r(e)+">"}function o(e){("start"==e.event?s:c)(e.node)}for(var l=0,u="",d=[];e.length||a.length;){var b=i();if(u+=t(n.substr(l,b[0].offset-l)),l=b[0].offset,b==e){d.reverse().forEach(c);do o(b.splice(0,1)[0]),b=i();while(b==e&&b.length&&b[0].offset==l);d.reverse().forEach(s)}else"start"==b[0].event?d.push(b[0].node):d.pop(),o(b.splice(0,1)[0])}return u+t(n.substr(l))}function l(e){function t(e){return e&&e.source||e}function r(r,a){return new RegExp(t(r),"m"+(e.cI?"i":"")+(a?"g":""))}
vendor: 1,116 bytes, line 79701
79701function a(n,i){if(!n.compiled){if(n.compiled=!0,n.k=n.k||n.bK,n.k){var c={},o=function(t,r){e.cI&&(r=r.toLowerCase()),r.split(" ").forEach(function(e){var r=e.split("|");c[r[0]]=[t,r[1]?Number(r[1]):1]})};"string"==typeof n.k?o("keyword",n.k):Object.keys(n.k).forEach(function(e){o(e,n.k[e])}),n.k=c}n.lR=r(n.l||/\b\w+\b/,!0),i&&(n.bK&&(n.b="\\b("+n.bK.split(" ").join("|")+")\\b"),n.b||(n.b=/\B|\b/),n.bR=r(n.b),n.e||n.eW||(n.e=/\B|\b/),n.e&&(n.eR=r(n.e)),n.tE=t(n.e)||"",n.eW&&i.tE&&(n.tE+=(n.e?"|":"")+i.tE)),n.i&&(n.iR=r(n.i)),void 0===n.r&&(n.r=1),n.c||(n.c=[]);var l=[];n.c.forEach(function(e){e.v?e.v.forEach(function(t){l.push(s(e,t))}):l.push("self"==e?n:e)}),n.c=l,n.c.forEach(function(e){a(e,n)}),n.starts&&a(n.starts,i);var u=n.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([n.tE,n.i]).map(t).filter(Boolean);n.t=u.length?r(u.join("|"),!0):{exec:function(){return null}}}}a(e)}function u(e,r,n,i){function s(e,t){for(var r=0;r<t.c.length;r++)if(a(t.c[r].bR,e))return t.c[r]}function c(e,t){if(a(e.eR,t)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?c(e.parent,t):void 0}
79701function o(e,t){return!n&&a(t.iR,e)}function b(e,t){var r=v.cI?t[0].toLowerCase():t[0];return e.k.hasOwnProperty(r)&&e.k[r]}function p(e,t,r,a){var n=a?"":w.classPrefix,i='<span class="'+n,s=r?"":"</span>";return i+=e+'">',i+t+s}function m(){if(!x.k)return t(E);var e="",r=0;x.lR.lastIndex=0;for(var a=x.lR.exec(E);a;){e+=t(E.substr(r,a.index-r));var n=b(x,a);n?(B+=n[1],e+=p(n[0],t(a[0]))):e+=t(a[0]),r=x.lR.lastIndex,a=x.lR.exec(E)}return e+t(E.substr(r))}function f(){var e="string"==typeof x.sL;if(e&&!N[x.sL])return t(E);var r=e?u(x.sL,E,!0,C[x.sL]):d(E,x.sL.length?x.sL:void 0);return x.r>0&&(B+=r.r),e&&(C[x.sL]=r.top),p(r.language,r.value,!1,!0)}function g(){return void 0!==x.sL?f():m()}function h(e,r){var a=e.cN?p(e.cN,"",!0):"";e.rB?(M+=a,E=""):e.eB?(M+=t(r)+a,E=""):(M+=a,E=r),x=Object.create(e,{parent:{value:x}})}function _(e,r){if(E+=e,void 0===r)return M+=g(),0;var a=s(r,x);if(a)return M+=g(),h(a,r),a.rB?0:r.length;var n=c(x,r);if(n){var i=x;i.rE||i.eE||(E+=r),M+=g();do x.cN&&(M+="</span>"),B+=x.r,x=x.parent;while(x!=n.parent);return i.eE&&(M+=t(r)),E="",n.starts&&h(n.starts,""),i.rE?0:r.length}if(o(r,x))throw new Error('Illegal lexeme "'+r+'" for mode "'+(x.cN||"<unnamed>")+'"');return E+=r,r.length||1}var v=y(e);if(!v)throw new Error('Unknown language: "'+e+'"');l(v);var k,x=i||v,C={},M="";for(k=x;k!=v;k=k.parent)k.cN&&(M=p(k.cN,"",!0)+M);var E="",B=0;try{for(var z,$,L=0;;){if(x.t.lastIndex=L,z=x.t.exec(r),!z)break;$=_(r.substr(L,z.index-L),z[0]),L=z.index+$}for(_(r.substr(L)),k=x;k.parent;k=k.parent)k.cN&&(M+="</span>");return{r:B,value:M,language:e,top:x}}catch(q){if(-1!=q.message.indexOf("Illegal"))return{r:0,value:t(r)};throw q}}function d(e,r){r=r||w.languages||Object.keys(N);var a={r:0,value:t(e)},n=a;return r.forEach(function(t){if(y(t)){var r=u(t,e,!1);r.language=t,r.r>n.r&&(n=r),r.r>a.r&&(n=a,a=r)}}),n.language&&(a.second_best=n),a}function b(e){return w.tabReplace&&(e=e.replace(/^((<[^>]+>|\t)+)/gm,function(e,t){return t.replace(/\t/g,w.tabReplace)})),w.useBR&&(e=e.replace(/\n/g,"<br>")),e}function p(e,t,r){var a=t?k[t]:r,n=[e.trim()];return e.match(/\bhljs\b/)||n.push("hljs"),-1===e.indexOf(a)&&n.push(a),n.join(" ").trim()}function m(e){var t=i(e);if(!n(t)){var r;w.useBR?(r=document.createElementNS("http://www.w3.org/1999/xhtml","div"),r.innerHTML=e.innerHTML.replace(/\n/g,"").replace(/<br[ \/]*>/g,"\n")):r=e;var a=r.textContent,s=t?u(t,a,!0):d(a),l=c(r);if(l.length){var m=document.createElementNS("http://www.w3.org/1999/xhtml","div");m.innerHTML=s.value,s.value=o(l,c(m),a)}s.value=b(s.value),e.innerHTML=s.value,e.className=p(e.className,t,s.language),e.result={language:s.language,re:s.r},s.second_best&&(e.second_best={language:s.second_best.language,re:s.second_best.r})}}function f(e){w=s(w,e)}function g(){if(!g.called){g.called=!0;var e=document.querySelectorAll("pre code");Array.prototype.forEach.call(e,m)}}function h(){addEventListener("DOMContentLoaded",g,!1),addEventListener("load",g,!1)}function _(t,r){var a=N[t]=r(e);a.aliases&&a.aliases.forEach(function(e){k[e]=t})}function v(){return Object.keys(N)}function y(e){return N[e]||N[k[e]]}var w={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},N={},k={};return e.highlight=u,e.highlightAuto=d,e.fixMarkup=b,e.highlightBlock=m,e.configure=f,e.initHighlighting=g,e.initHighlightingOnLoad=h,e.registerLanguage=_,e.listLanguages=v,e.getLanguage=y,e.inherit=s,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such)\b/},e.C=function(t,r,a){var n=e.inherit({cN:"comment",b:t,e:r,c:[]},a||{});return n.c.push(e.PWM),n.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),n},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0}
vendor: 8,128 bytes, line 79701
79701,e.UTM={cN:"title",b:e.UIR,r:0},e.registerLanguage("apache",function(e){var t={cN:"number",b:"[\\$%]\\d+"};return{aliases:["apacheconf"],cI:!0,c:[e.HCM,{cN:"tag",b:"</?",e:">"},{cN:"keyword",b:/\w+/,r:0,k:{common:"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername"},starts:{e:/$/,r:0,k:{literal:"on off all"},c:[{cN:"sqbracket",b:"\\s\\[",e:"\\]$"},{cN:"cbracket",b:"[\\$%]\\{",e:"\\}",c:["self",t]},t,e.QSM]}}],i:/\S/}}),e.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)}/}]},r={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["sh","zsh"],l:/-?[a-z\.]+/,k:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",operator:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"shebang",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,e.NM,r,a,t]}}),e.registerLanguage("coffeescript",function(e){var t={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super then unless until loop of by when and or is isnt not",literal:"true false null undefined yes no on off",built_in:"npm require console print module global window document"},r="[A-Za-z$_][0-9A-Za-z$_]*",a={cN:"subst",b:/#\{/,e:/}/,k:t},n=[e.BNM,e.inherit(e.CNM,{starts:{e:"(\\s*/)?",r:0}}),{cN:"string",v:[{b:/'''/,e:/'''/,c:[e.BE]},{b:/'/,e:/'/,c:[e.BE]},{b:/"""/,e:/"""/,c:[e.BE,a]},{b:/"/,e:/"/,c:[e.BE,a]}]},{cN:"regexp",v:[{b:"///",e:"///",c:[a,e.HCM]},{b:"//[gim]*",r:0},{b:/\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/}]},{cN:"property",b:"@"+r},{b:"`",e:"`",eB:!0,eE:!0,sL:"javascript"}];a.c=n;var i=e.inherit(e.TM,{b:r}),s="(\\(.*\\))?\\s*\\B[-=]>",c={cN:"params",b:"\\([^\\(]",rB:!0,c:[{b:/\(/,e:/\)/,k:t,c:["self"].concat(n)}]};return{aliases:["coffee","cson","iced"],k:t,i:/\/\*/,c:n.concat([e.C("###","###"),e.HCM,{cN:"function",b:"^\\s*"+r+"\\s*=\\s*"+s,e:"[-=]>",rB:!0,c:[i,c]},{b:/[:\(,=]\s*/,r:0,c:[{cN:"function",b:s,e:"[-=]>",rB:!0,c:[c]}]},{cN:"class",bK:"class",e:"$",i:/[:="\[\]]/,c:[{bK:"extends",eW:!0,i:/[:="\[\]]/,c:[i]},i]},{cN:"attribute",b:r+":",e:":",rB:!0,rE:!0,r:0}])}}),e.registerLanguage("cpp",function(e){var t={cN:"keyword",b:"\\b[a-z\\d_]*_t\\b"},r={cN:"string",v:[e.inherit(e.QSM,{b:'((u8?|U)|L)?"'}),{b:'(u8?|U)?R"',e:'"',c:[e.BE]},{b:"'\\\\?.",e:"'",i:"."}]},a={cN:"number",v:[{b:"\\b(\\d+(\\.\\d*)?|\\.\\d+)(u|U|l|L|ul|UL|f|F)"},{b:e.CNR}]},n=e.IR+"\\s*\\(",i={keyword:"int float while private char catch export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const struct for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using class asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignof constexpr decltype noexcept static_assert thread_local restrict _Bool complex _Complex _Imaginary atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong",built_in:"std string cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf",literal:"true false nullptr NULL"};return{aliases:["c","cc","h","c++","h++","hpp"],k:i,i:"</",c:[t,e.CLCM,e.CBCM,a,r,{cN:"preprocessor",b:"#",e:"$",k:"if else elif endif define undef warning error line pragma ifdef ifndef",c:[{b:/\\\n/,r:0},{bK:"include",e:"$",c:[r,{cN:"string",b:"<",e:">",i:"\\n"}]},r,a,e.CLCM,e.CBCM]},{b:"\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<",e:">",k:i,c:["self",t]},{b:e.IR+"::",k:i},{bK:"new throw return else",r:0},{cN:"function",b:"("+e.IR+"[\\*&\\s]+)+"+n,rB:!0,e:/[{;=]/,eE:!0,k:i,c:[{b:n,rB:!0,c:[e.TM],r:0},{cN:"params",b:/\(/,e:/\)/,k:i,r:0,c:[e.CLCM,e.CBCM,r,a]},e.CLCM,e.CBCM]}]}}),e.registerLanguage("cs",function(e){var t="abstract as base bool break byte case catch char checked const continue decimal dynamic default delegate do double else enum event explicit extern false finally fixed float for foreach goto if implicit in int interface internal is lock long null when object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this true try typeof uint ulong unchecked unsafe ushort using virtual volatile void while async protected public private internal ascending descending from get group into join let orderby partial select set value var where yield",r=e.IR+"(<"+e.IR+">)?";return{aliases:["csharp"],k:t,i:/::/,c:[e.C("///","$",{rB:!0,c:[{cN:"xmlDocTag",v:[{b:"///",r:0},{b:"<!--|-->"},{b:"</?",e:">"}]}]}),e.CLCM,e.CBCM,{cN:"preprocessor",b:"#",e:"$",k:"if else elif endif define undef warning error line region endregion pragma checksum"},{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},e.ASM,e.QSM,e.CNM,{bK:"class interface",e:/[{;=]/,i:/[^\s:]/,c:[e.TM,e.CLCM,e.CBCM]},{bK:"namespace",e:/[{;=]/,i:/[^\s:]/,c:[{cN:"title",b:"[a-zA-Z](\\.?\\w)*",r:0},e.CLCM,e.CBCM]},{bK:"new return throw await",r:0},{cN:"function",b:"("+r+"\\s+)+"+e.IR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:t,c:[{b:e.IR+"\\s*\\(",rB:!0,c:[e.TM],r:0},{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:t,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]}]}}),e.registerLanguage("css",function(e){var t="[a-zA-Z-][a-zA-Z0-9_-]*",r={cN:"function",b:t+"\\(",rB:!0,eE:!0,e:"\\("},a={cN:"rule",b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{cN:"value",eW:!0,eE:!0,c:[r,e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"hexcolor",b:"#[0-9A-Fa-f]+"},{cN:"important",b:"!important"}]}}]};return{cI:!0,i:/[=\/|'\$]/,c:[e.CBCM,a,{cN:"id",b:/\#[A-Za-z0-9_-]+/},{cN:"class",b:/\.[A-Za-z0-9_-]+/},{cN:"attr_selector",b:/\[/,e:/\]/,i:"$"},{cN:"pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"']+/},{cN:"at_rule",b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{cN:"at_rule",b:"@",e:"[{;]",c:[{cN:"keyword",b:/\S+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[r,e.ASM,e.QSM,e.CSSNM]}]},{cN:"tag",b:t,r:0},{cN:"rules",b:"{",e:"}",i:/\S/,c:[e.CBCM,a]}]}}),e.registerLanguage("diff",function(e){return{aliases:["patch"],c:[{cN:"chunk",r:10,v:[{b:/^@@ +\-\d+,\d+ +\+\d+,\d+ +@@$/},{b:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{b:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{cN:"header",v:[{b:/Index: /,e:/$/},{b:/=====/,e:/=====$/},{b:/^\-\-\-/,e:/$/},{b:/^\*{3} /,e:/$/},{b:/^\+\+\+/,e:/$/},{b:/\*{5}/,e:/\*{5}$/}]},{cN:"addition",b:"^\\+",e:"$"}
79701,{cN:"deletion",b:"^\\-",e:"$"},{cN:"change",b:"^\\!",e:"$"}]}}),e.registerLanguage("http",function(e){return{aliases:["https"],i:"\\S",c:[{cN:"status",b:"^HTTP/[0-9\\.]+",e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{cN:"request",b:"^[A-Z]+ (.*?) HTTP/[0-9\\.]+$",rB:!0,e:"$",c:[{cN:"string",b:" ",e:" ",eB:!0,eE:!0}]},{cN:"attribute",b:"^\\w",e:": ",eE:!0,i:"\\n|\\s|=",starts:{cN:"string",e:"$"}},{b:"\\n\\n",starts:{sL:[],eW:!0}}]}}),e.registerLanguage("ini",function(e){var t={cN:"string",c:[e.BE],v:[{b:"'''",e:"'''",r:10},{b:'"""',e:'"""',r:10},{b:'"',e:'"'},{b:"'",e:"'"}]};return{aliases:["toml"],cI:!0,i:/\S/,c:[e.C(";","$"),e.HCM,{cN:"title",b:/^\s*\[+/,e:/\]+/},{cN:"setting",b:/^[a-z0-9\[\]_-]+\s*=\s*/,e:"$",c:[{cN:"value",eW:!0,k:"on off true false yes no",c:[{cN:"variable",v:[{b:/\$[\w\d"][\w\d_]*/},{b:/\$\{(.*?)}/}]},t,{cN:"number",b:/([\+\-]+)?[\d]+_[\d_]+/},e.NM],r:0}]}]}}),e.registerLanguage("java",function(e){var t=e.UIR+"(<"+e.UIR+">)?",r="false synchronized int abstract float private char boolean static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private",a="\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?",n={cN:"number",b:a,r:0};return{aliases:["jsp"],k:r,i:/<\/|#/,c:[e.C("/\\*\\*","\\*/",{r:0,c:[{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"new throw return else",r:0},{cN:"function",b:"("+t+"\\s+)+"+e.UIR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:r,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,k:r,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},n,{cN:"annotation",b:"@[A-Za-z]+"}]}}),e.registerLanguage("javascript",function(e){return{aliases:["js"],k:{keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},c:[{cN:"pi",r:10,b:/^\s*['"]use (strict|asm)['"]/},e.ASM,e.QSM,{cN:"string",b:"`",e:"`",c:[e.BE,{cN:"subst",b:"\\$\\{",e:"\\}"}]},e.CLCM,e.CBCM,{cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{b:/</,e:/>\s*[);\]]/,r:0,sL:"xml"}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:[e.CLCM,e.CBCM],i:/["'\(]/}],i:/\[|%/},{b:/\$[(.]/},{b:"\\."+e.IR,r:0},{bK:"import",e:"[;$]",k:"import from as",c:[e.ASM,e.QSM]},{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]}],i:/#/}}),e.registerLanguage("json",function(e){var t={literal:"true false null"},r=[e.QSM,e.CNM],a={cN:"value",e:",",eW:!0,eE:!0,c:r,k:t},n={b:"{",e:"}",c:[{cN:"attribute",b:'\\s*"',e:'"\\s*:\\s*',eB:!0,eE:!0,c:[e.BE],i:"\\n",starts:a}],i:"\\S"},i={b:"\\[",e:"\\]",c:[e.inherit(a,{cN:null})],i:"\\S"};return r.splice(r.length,0,n,i),{c:r,k:t,i:"\\S"}}),e.registerLanguage("makefile",function(e){var t={cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]};return{aliases:["mk","mak"],c:[e.HCM,{b:/^\w+\s*\W*=/,rB:!0,r:0,starts:{cN:"constant",e:/\s*\W*=/,eE:!0,starts:{e:/$/,r:0,c:[t]}}},{cN:"title",b:/^[\w]+:\s*$/},{cN:"phony",b:/^\.PHONY:/,e:/$/,k:".PHONY",l:/[\.\w]+/},{b:/^\t+/,e:/$/,r:0,c:[e.QSM,t]}]}}),e.registerLanguage("xml",function(e){var t="[A-Za-z0-9\\._:-]+",r={b:/<\?(php)?(?!\w)/,e:/\?>/,sL:"php"},a={eW:!0,i:/</,r:0,c:[r,{cN:"attribute",b:t,r:0},{b:"=",r:0,c:[{cN:"value",c:[r],v:[{b:/"/,e:/"/},{b:/'/,e:/'/},{b:/[^\s\/>]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xsl","plist"],cI:!0,c:[{cN:"doctype",b:"<!DOCTYPE",e:">",r:10,c:[{b:"\\[",e:"\\]"}]},e.C("<!--","-->",{r:10}),{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"<style(?=\\s|>|$)",e:">",k:{title:"style"},c:[a],starts:{e:"</style>",rE:!0,sL:"css"}}
vendor: 2,578 bytes, line 79701
79701,{cN:"tag",b:"<script(?=\\s|>|$)",e:">",k:{title:"script"},c:[a],starts:{e:"</script>",rE:!0,sL:["actionscript","javascript","handlebars"]}},r,{cN:"pi",b:/<\?\w+/,e:/\?>/,r:10},{cN:"tag",b:"</?",e:"/?>",c:[{cN:"title",b:/[^ \/><\n\t]+/,r:0},a]}]}}),e.registerLanguage("markdown",function(e){return{aliases:["md","mkdown","mkd"],c:[{cN:"header",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"blockquote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"`.+?`"},{b:"^( {4}|	)",e:"$",r:0}]},{cN:"horizontal_rule",b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:!0,c:[{cN:"link_label",b:"\\[",e:"\\]",eB:!0,rE:!0,r:0},{cN:"link_url",b:"\\]\\(",e:"\\)",eB:!0,eE:!0},{cN:"link_reference",b:"\\]\\[",e:"\\]",eB:!0,eE:!0}],r:10},{b:"^\\[.+\\]:",rB:!0,c:[{cN:"link_reference",b:"\\[",e:"\\]:",eB:!0,eE:!0,starts:{cN:"link_url",e:"$"}}]}]}}),e.registerLanguage("nginx",function(e){var t={cN:"variable",v:[{b:/\$\d+/},{b:/\$\{/,e:/}/},{b:"[\\$\\@]"+e.UIR}]},r={eW:!0,l:"[a-z/_]+",k:{built_in:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},r:0,i:"=>",c:[e.HCM,{cN:"string",c:[e.BE,t],v:[{b:/"/,e:/"/},{b:/'/,e:/'/}]},{cN:"url",b:"([a-z]+):/",e:"\\s",eW:!0,eE:!0,c:[t]},{cN:"regexp",c:[e.BE,t],v:[{b:"\\s\\^",e:"\\s|{|;",rE:!0},{b:"~\\*?\\s+",e:"\\s|{|;",rE:!0},{b:"\\*(\\.[a-z\\-]+)+"},{b:"([a-z\\-]+\\.)+\\*"}]},{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+[kKmMgGdshdwy]*\\b",r:0},t]};return{aliases:["nginxconf"],c:[e.HCM,{b:e.UIR+"\\s",e:";|{",rB:!0,c:[{cN:"title",b:e.UIR,starts:r}],r:0}],i:"[^\\s\\}]"}}),e.registerLanguage("objectivec",function(e){var t={cN:"built_in",b:"(AV|CA|CF|CG|CI|MK|MP|NS|UI)\\w+"},r={keyword:"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"BOOL dis
vendor: 5,275 bytes, line 79701
79701patch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"},a=/[a-zA-Z@][a-zA-Z0-9_]*/,n="@interface @class @protocol @implementation";return{aliases:["mm","objc","obj-c"],k:r,l:a,i:"</",c:[t,e.CLCM,e.CBCM,e.CNM,e.QSM,{cN:"string",v:[{b:'@"',e:'"',i:"\\n",c:[e.BE]},{b:"'",e:"[^\\\\]'",i:"[^\\\\][^']"}]},{cN:"preprocessor",b:"#",e:"$",c:[{cN:"title",v:[{b:'"',e:'"'},{b:"<",e:">"}]}]},{cN:"class",b:"("+n.split(" ").join("|")+")\\b",e:"({|$)",eE:!0,k:n,l:a,c:[e.UTM]},{cN:"variable",b:"\\."+e.UIR,r:0}]}}),e.registerLanguage("perl",function(e){var t="getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when",r={cN:"subst",b:"[$@]\\{",e:"\\}",k:t},a={b:"->{",e:"}"},n={cN:"variable",v:[{b:/\$\d/},{b:/[\$%@](\^\w\b|#\w+(::\w+)*|{\w+}|\w+(::\w*)*)/},{b:/[\$%@][^\s\w{]/,r:0}]},i=[e.BE,r,n],s=[n,e.HCM,e.C("^\\=\\w","\\=cut",{eW:!0}),a,{cN:"string",c:i,v:[{b:"q[qwxr]?\\s*\\(",e:"\\)",r:5},{b:"q[qwxr]?\\s*\\[",e:"\\]",r:5},{b:"q[qwxr]?\\s*\\{",e:"\\}",r:5},{b:"q[qwxr]?\\s*\\|",e:"\\|",r:5},{b:"q[qwxr]?\\s*\\<",e:"\\>",r:5},{b:"qw\\s+q",e:"q",r:5},{b:"'",e:"'",c:[e.BE]},{b:'"',e:'"'},{b:"`",e:"`",c:[e.BE]},{b:"{\\w+}",c:[],r:0},{b:"-?\\w+\\s*\\=\\>",c:[],r:0}]},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\/\\/|"+e.RSR+"|\\b(split|return|print|reverse|grep)\\b)\\s*",k:"split return print reverse grep",r:0,c:[e.HCM,{cN:"regexp",b:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",r:10},{cN:"regexp",b:"(m|qr)?/",e:"/[a-z]*",c:[e.BE],r:0}]},{cN:"sub",bK:"sub",e:"(\\s*\\(.*?\\))?[;{]",r:5},{cN:"operator",b:"-\\w\\b",r:0},{b:"^__DATA__$",e:"^__END__$",sL:"mojolicious",c:[{b:"^@@.*",e:"$",cN:"comment"}]}];return r.c=s,a.c=s,{aliases:["pl"],k:t,c:s}}),e.registerLanguage("php",function(e){var t={cN:"variable",b:"\\$+[a-zA-Z_�-ÿ][a-zA-Z0-9_�-ÿ]*"},r={cN:"preprocessor",b:/<\?(php)?|\?>/},a={cN:"string",c:[e.BE,r],v:[{b:'b"',e:'"'},{b:"b'",e:"'"},e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},n={v:[e.BNM,e.CNM]};return{aliases:["php3","php4","php5","php6"],cI:!0,k:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally",c:[e.CLCM,e.HCM,e.C("/\\*","\\*/",{c:[{cN:"doctag",b:"@[A-Za-z]+"},r]}),e.C("__halt_compiler.+?;",!1,{eW:!0,k:"__halt_compiler",l:e.UIR}),{cN:"string",b:"<<<['\"]?\\w+['\"]?$",e:"^\\w+;",c:[e.BE]},r,t,{b:/(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{cN:"function",bK:"function",e:/[;{]/,eE:!0,i:"\\$|\\[|%",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)",c:["self",t,e.CBCM,a,n]}]},{cN:"class",bK:"class interface",e:"{",eE:!0,i:/[:\(\$"]/,c:[{bK:"extends implements"},e.UTM]},{bK:"namespace",e:";",i:/[\.']/,c:[e.UTM]},{bK:"use",e:";",c:[e.UTM]},{b:"=>"},a,n]}}),e.registerLanguage("python",function(e){var t={cN:"prompt",b:/^(>>>|\.\.\.) /},r={cN:"string",c:[e.BE],v:[{b:/(u|b)?r?'''/,e:/'''/,c:[t],r:10},{b:/(u|b)?r?"""/,e:/"""/,c:[t],r:10},{b:/(u|r|ur)'/,e:/'/,r:10},{b:/(u|r|ur)"/,e:/"/,r:10},{b:/(b|br)'/,e:/'/},{b:/(b|br)"/,e:/"/},e.ASM,e.QSM]},a={cN:"number",r:0,v:[{b:e.BNR+"[lLjJ]?"},{b:"\\b(0o[0-7]+)[lLjJ]?"},{b:e.CNR+"[lLjJ]?"}]},n={cN:"params",b:/\(/,e:/\)/,c:["self",t,a,r]};return{aliases:["py","gyp"],k:{keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda n
79701onlocal|10 None True False",built_in:"Ellipsis NotImplemented"},i:/(<\/|->|\?)/,c:[t,a,r,e.HCM,{v:[{cN:"function",bK:"def",r:10},{cN:"class",bK:"class"}],e:/:/,i:/[${=;\n,]/,c:[e.UTM,n]},{cN:"decorator",b:/^[\t ]*@/,e:/$/},{b:/\b(print|exec)\(/}]}}),e.registerLanguage("ruby",function(e){var t="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",r="and false then defined module in return redo if BEGIN retry end for true self when next until do begin unless END rescue nil else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",a={cN:"doctag",b:"@[A-Za-z]+"},n={cN:"value",b:"#<",e:">"},i=[e.C("#","$",{c:[a]}),e.C("^\\=begin","^\\=end",{c:[a],r:10}),e.C("^__END__","\\n$")],s={cN:"subst",b:"#\\{",e:"}",k:r},c={cN:"string",c:[e.BE,s],v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/`/,e:/`/},{b:"%[qQwWx]?\\(",e:"\\)"},{b:"%[qQwWx]?\\[",e:"\\]"},{b:"%[qQwWx]?{",e:"}"},{b:"%[qQwWx]?<",e:">"},{b:"%[qQwWx]?/",e:"/"},{b:"%[qQwWx]?%",e:"%"},{b:"%[qQwWx]?-",e:"-"},{b:"%[qQwWx]?\\|",e:"\\|"},{b:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/}]},o={cN:"params",b:"\\(",e:"\\)",k:r},l=[c,n,{cN:"class",bK:"class module",e:"$|;",i:/=/,c:[e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{cN:"inheritance",b:"<\\s*",c:[{cN:"parent",b:"("+e.IR+"::)?"+e.IR}]}].concat(i)},{cN:"function",bK:"def",e:"$|;",r:0,c:[e.inherit(e.TM,{b:t}),o].concat(i)},{cN:"constant",b:"(::)?(\\b[A-Z]\\w*(::)?)+",r:0},{cN:"symbol",b:e.UIR+"(\\!|\\?)?:",r:0},{cN:"symbol",b:":",c:[c,{b:t}],r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"("+e.RSR+")\\s*",c:[n,{cN:"regexp",c:[e.BE,s],i:/\n/,v:[{b:"/",e:"/[a-z]*"},{b:"%r{",e:"}[a-z]*"},{b:"%r\\(",e:"\\)[a-z]*"},{b:"%r!",e:"![a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}].concat(i),r:0}].concat(i);s.c=l,o.c=l;var u="[>?]>",d="[\\w#]+\\(\\w+\\):\\d+:\\d+>
79701",b="(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>",p=[{b:/^\s*=>/,cN:"status",starts:{e:"$",c:l}},{cN:"prompt",b:"^("+u+"|"+d+"|"+b+")",starts:{e:"$",c:l}}];return{aliases:["rb","gemspec","podspec","thor","irb"],k:r,c:i.concat(p).concat(l)}}),e.registerLanguage("sql",function(e){var t=e.C("--","$");return{cI:!0,i:/[<>]/,c:[{cN:"operator",bK:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate savepoint release|0 unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke",e:/;/,eW:!0,k:{keyword:"abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias allocate allow alter always analyze ancillary and any anydata anydataset anyschema anytype apply archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound buffer_cache buffer_pool build bulk by byte byteordermark bytes c cache caching call calling cancel capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base char_length character_length characters characterset charindex charset charsetform charsetid check checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation collect colu colum column column_value columns columns_updated comment commit compact compatibility compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection consider consistent constant constraint constraints constructor container content contents context contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime customdatum cycle d data database databases datafile datafiles datalength date_add date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor deterministic diagnostics difference dimension direct_load directory disable disable_all disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div do document domain dotnet double downgrade drop dumpfile duplicate duration e each edition editionable editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding execu execut execute exempt exists exit exp expire explain export export_set extended extent external external_1 external_2 externally extract f failed failed_login_attempts failover failure far fast feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final finish first first_value fixed flash_cac
79701he flashback floor flush following follows for forall force form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ftp full function g general generated get get_format get_lock getdate getutcdate global global_name globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex hierarchy high high_priority hosts hour http i id ident_current ident_incr ident_seed identified identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile initial initialized initially initrans inmemory inner innodb input insert install instance instantiable instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists k keep keep_duplicates key keys kill l language large last|0 last_day last_insert_id last_value lax lcase lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit lines link|0 list|0 listagg little ln load load_file lob lobs local localtime localtimestamp locate locator lock|0 locked log log10 log2 logfile logfiles logging logical logical_reads_per_call logoff logon logs long loop|0 low low_priority lower lpad lrtrim ltrim m main make_set makedate maketime managed management manual map mapping mask master master_pos_wait match matched materialized max maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans md5 measures median medium member memcompress memory merge microsecond mid migration min minextents minimum mining minus minute minvalue missing mod mode model modification modify module monitoring month months mount move movement multiset mutex n name name_const names nan national native natural nav nchar nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck noswitch not nothing notice notrim novalidate now nowait nth_value nullif nulls num numb numbe nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary out outer outfile outline output over overflow overriding p package pad parallel parallel_enable parameters parent parse partial partition partitions pascal passing password password_grace_time password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction prediction_cost prediction_details prediction_probability prediction_set prepare present preserve prior priority private private_sga privileges procedural procedure procedure_analyze processlist profiles project prompt protection public publishingservername purge quarter query quick quiesce quota quotename radians raise|0 rand range rank raw read reads readsize rebuild record records recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy reject rekey relational relative relaylog release|0 release_lock relies_on relocate rely rem remainder repair repeat replace replicate replication required reset resetlogs resize resource respect restore restricted result result_cache resumable resume retention return returning returns reuse reverse revoke right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll sdo_georaster sdo_topo_geometry search sec_to_time second section securefile security seed segment self sequence sequential serializable server servererror session session_user sessions_per_user set sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone standby start starting startup statement static statistics stats_binomial_test stats_crosstab stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime t table tables tablespace tan tdo template temporary terminated tertiary_weights test than then thread through tier ties time time_format time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse t
79701ype ub1 ub2 ub4 ucase unarchived unbounded uncompress under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unpivot unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear wellformed when whene whenev wheneve whenever where while whitespace with within without work wrapped xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek",
79702literal:"true false null",built_in:"array bigint binary bit blob boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text varchar varying void"},c:[{cN:"string",b:"'",e:"'",c:[e.BE,{b:"''"}]},{cN:"string",b:'"',e:'"',c:[e.BE,{b:'""'}]},{cN:"string",b:"`",e:"`",c:[e.BE]},e.CNM,e.CBCM,t]},e.CBCM,t]}}),e});
79703function reloadHljs(params) {
79704    $('pre code').each(function(i, block) {
79705        hljs.highlightBlock(block);
79706      });
79707};
79708function update_select(){
79709  if ($(".evaluation input.batch:checked").length > 0) {
79710    $(".not-selected-title").hide()
79711    $(".selected-title").show()
79712    copy_evaluator_ids_field();
79713  } else {
79714    $(".not-selected-title").show()
79715    $(".selected-title").hide()
79716  }
79717}
79718
79719function init_assignees(){
79720  var evaluation_option = $.extend(true, {}, daterangepicker_config, {ranges: {
79721    "今月": [moment().startOf('month'), moment().endOf('month')],
79722    "来月": [moment().add(1, 'month').startOf('month'), moment().add(1, 'month').endOf('month')],
79723    "今クォーター": [moment().startOf('quarter'), moment().endOf('quarter')],
79724    "来クォーター": [moment().add(1, 'quarter').startOf('quarter'), moment().add(1, 'quarter').endOf('quarter')],
79725  }})
79726  $('input.evaluation-daterange').daterangepicker(evaluation_option);
79727
79728  $('input.evaluation-date-filter, input.evaluation-daterange').on("apply.daterangepicker", function(){
79729    $(this.form).trigger("submit.rails");
79730  });
79731  $(".evaluatee-results").html("");
79732  $(".batch-filter").removeClass("open");
79733  copy_evaluator_ids_field();
79734}
79735
79736function get_data_from(form, index){
79737  var data = $(form).serializeArray();
79738  data = data.map(function(form_data){
79739    if (form_data.name.match(/^evaluation\[/)) {
79740      form_data.name = "evaluations["+index+"]" + form_data.name.replace(/^evaluation\[/, "[evaluation][")
79741      return form_data;
79742    } else {
79743      return null;
79744    }
79745  }).filter(function(x){ return x != null})
79746  return data;
79747}
79748
79749function copy_evaluator_ids_field(){
79750  $(".batch-ids").remove();
79751  $(".evaluation input.batch:checked").each(function(index, checked_input){
79752    var evaluator_input = $(checked_input).closest(".row").find(".evaluator-ids").clone().addClass("batch-evaluator-ids").addClass("batch-ids").prop("name", "evaluator_ids[]");
79753    $("form.batch-evaluator").append(evaluator_input);
79754
79755    var reviewer_input = $(checked_input).closest(".row").find(".reviewer-ids").clone().addClass("batch-reviewer-ids").addClass("batch-ids").prop("name", "reviewer_ids[]");
79756    $("form.batch-reviewer").append(reviewer_input);
79757  })
79758}
79759
79760function show_evaluation_loading(target) {
79761  $(target).closest(".evaluation").children(".loading-show").show();
79762}
79763
79764$(document).on("submit.rails", ".update-evaluation-form", function(){
79765  show_evaluation_loading(this);
79766})
79767
79768$(document).on("mouseenter", ".select-item-batch", function() {
79769  $(".select-item-batch.selected").removeClass("selected");
79770  $(this).addClass("selected");
79771});
79772
79773$(document).on("keypress", ".batch-filter-menu", function(event){
79774  if (event.which == 13) {
79775    var selected = $(".select-item-batch.selected:visible");
79776    if (selected.length == 0) return;
79777    selected.trigger("click");
79778    return false;
79779  }
79780});
79781
79782$(document).on("keyup", ".batch-filter-menu", function(event){
79783  if (event.which == 27) {
79784    $("batch-filter").removeClass("open");
79785    return false;
79786  } else if (event.which == 13) {
79787    return false;
79788  } else if (event.which == 40 || event.which == 38 && $(".select-item-batch.selected:visible").length > 0) {
79789    var selected;
79790    if (event.which == 40) {
79791      selected = $(".select-item-batch.selected:visible").next();
79792      if (selected.length == 0) selected = $(".select-item-batch.selected:visible").first();
79793    } else {
79794      selected = $(".select-item-batch.selected:visible").prev();
79795      if (selected.length == 0) selected = $(".select-item-batch.selected:visible").last();
79796    }
79797    $(".select-item-batch.selected").removeClass("selected");
79798    selected.addClass("selected")
79799    return false;
79800  } else {
79801    $(this).find("form").trigger("submit.rails");
79802    return true;
79803  }
79804})
79805
79806$(document).on('shown.bs.dropdown', ".batch-filter", function(event) {
79807  var dropdown = $(event.target);
79808
79809  setTimeout(function() {
79810    dropdown.find('.dropdown-menu .filter-input:first').focus();
79811  }, 10);
79812});
79813
79814(function() {
79815  var DelayExcuse, auto_save;
79816
79817  DelayExcuse = (function() {
79818    function DelayExcuse(delay) {
79819      this.delay = delay;
79820    }
79821
79822    DelayExcuse.prototype.run = function(callback) {
79823      this.callback = callback;
79824      if (this.counter != null) {
79825        clearTimeout(this.counter);
79826      }
79827      return this.counter = setTimeout(this.callback, this.delay);
79828    };
79829
79830    DelayExcuse.prototype.stop = function() {
79831      if (this.counter != null) {
79832        clearTimeout(this.counter);
79833      }
79834      return this.counter = null;
79835    };
79836
79837    return DelayExcuse;
79838
79839  })();
79840
79841  auto_save = new DelayExcuse(1000);
79842
79843  $(document).ready(function() {
79844    return this.reloadCKEditor = function() {
79845      if (typeof hljs !== "undefined" && hljs !== null) {
79846        hljs.initHighlightingOnLoad();
79847      }
79848      return $('.custom-ckeditor').each(function(index, editor) {
79849        var options;
79850        options = $(editor).data("ckeditor-options") ? $(editor).data("ckeditor-options") : {};
79851        CKEDITOR.replace($(editor).attr("id"), options);
79852        if ($(editor).data("autosave")) {
79853          return setTimeout((function(_this) {
79854            return function() {
79855              return CKEDITOR.instances[$(editor).attr("id")].on("change", function() {
79856                return auto_save.run(function() {
79857                  $(editor).val(CKEDITOR.instances[$(editor).attr("id")].getData());
79858                  return $(editor).closest("form").trigger("submit");
79859                });
79860              });
79861            };
79862          })(this), 1000);
79863        }
79864      });
79865    };
79866  });
79867
79868}).call(this);
79869$(document).on("change", ".auto-submit-upload", function() {
79870  if($("#js-file-upload")) {
79871    $("#js-file-upload").val(true)
79872  }
79873
79874  // hotfix duplicate request
79875  $(this.form).submit()
79876})
79877
79878$(document).on("direct-upload:initialize", ".material-upload", function(event) {
79879  var { detail } = event
79880  var { id, file } = detail
79881  $(".upload-progress").append(`
79882    <div id="direct-upload-${id}" class="direct-upload direct-upload--inprogress direct-upload--pending">
79883      <div id="direct-upload-progress-${id}" class="direct-upload__progress" style="width: 0%"></div>
79884      <span class="direct-upload__filename">${file.name}</span>
79885    </div>
79886  `)
79887})
79888
79889$(document).on("direct-upload:start", ".material-upload", function(event) {
79890  var { id } = event.detail
79891  var element = document.getElementById(`direct-upload-${id}`)
79892  if (!element) return
79893  element.classList.remove("direct-upload--pending")
79894})
79895
79896$(document).on("direct-upload:progress", ".material-upload", function(event) {
79897  var { id, progress } = event.detail
79898  var progressElement = document.getElementById(`direct-upload-progress-${id}`)
79899  if (!progressElement) return
79900  progressElement.style.width = `${progress}%`
79901})
79902
79903$(document).on("direct-upload:error", ".material-upload", function(event) {
79904  event.preventDefault()
79905  var { id, error } = event.detail
79906  var element = document.getElementById(`direct-upload-${id}`)
79907  if (!element) return
79908  element.classList.add("direct-upload--error")
79909  element.classList.remove("direct-upload--inprogress")
79910  element.setAttribute("title", error)
79911})
79912
79913$(document).on("direct-upload:end", ".material-upload", function(event) {
79914  var { id } = event.detail
79915  var element = document.getElementById(`direct-upload-${id}`)
79916  if (!element) return
79917  element.classList.add("direct-upload--complete")
79918  element.classList.remove("direct-upload--inprogress")
79919  $(this.form).submit()
79920})
79921
79922function confirmChangePage() {
79923  if ($(".direct-upload--inprogress").length == 0) return
79924  return confirm("アップロード中ですが、本当に止めますか?")
79925}
79926$(document).ready(function(){
79927  return confirmChangePage()
79928})
79929
79930$(window).on("beforeunload", function() {
79931  return confirmChangePage()
79932});
79933$(document).ready(function() {
79934  $(document).off("click", "#menu-toggle, #exam-toogle").on("click", "#menu-toggle, #exam-toogle", function(e) {
79935    e.preventDefault();
79936    $("#wrapper").toggleClass("toggled");
79937  });
79938});
79939function setMilestoneEvent() {
79940  milestoneIds.forEach(function(milestoneId, index) {
79941    // 日付変更の時に移行の日付をアップデートする
79942    setDatetimeChange("milestone_target_dates_" + milestoneId, function() {
79943      updateForNextMilestone(milestoneId);
79944    });
79945
79946    // 最初のMilestoneはチェックボックスが要らない
79947    if (index == 0) {
79948      return;
79949    }
79950
79951    // チェックボックスのイベント:
79952    $("#milestone_target_edit_flags_" + milestoneId).change(function() {
79953      disableDatetime("milestone_target_dates_" + milestoneId, this.checked);
79954      if (this.checked) {
79955        if (index > 0) {
79956          updateForNextMilestone(milestoneIds[index - 1]);
79957        }
79958      }
79959    });
79960
79961    // Set default checked
79962    setTimeout(function() {
79963      $("#milestone_target_edit_flags_" + milestoneId).prop("checked", true);
79964      disableDatetime("milestone_target_dates_" + milestoneId);
79965    }, 100);
79966  });
79967}
79968
79969function getNextMilestoneId(currentId) {
79970  var index = milestoneIds.indexOf(currentId);
79971  if (index < 0 || index >= milestoneIds.length - 1) {
79972    return null;
79973  }
79974
79975  return milestoneIds[index + 1];
79976}
79977
79978function updateForNextMilestone(currentId) {
79979  var nextId = getNextMilestoneId(currentId);
79980  if (!nextId) {
79981    return;
79982  }
79983
79984  if (!$("#milestone_target_edit_flags_" + nextId).is(":checked")) {
79985    updateForNextMilestone(nextId);
79986    return;
79987  }
79988
79989  var oldDatetime = new Date($("#milestone_old_target_date_" + currentId).val());
79990  var newDatetime = datetimeSelectToObj("milestone_target_dates_" + currentId);
79991
79992  var timeChanged = newDatetime - oldDatetime;
79993  $("#milestone_target_date_compare_" + nextId).text(Math.round(timeChanged / 1000 / 60 / 60 / 24));
79994
79995  var oldDatetimeOnNextMilestone = new Date($("#milestone_old_target_date_" + nextId).val());
79996  var time = oldDatetimeOnNextMilestone.getTime() + timeChanged;
79997
79998  var newDatetimeOnNextMilestone = new Date(time);
79999  objToDateTime("milestone_target_dates_" + nextId, newDatetimeOnNextMilestone);
80000  setTimeout(function() {
80001    updateForNextMilestone(nextId);
80002  }, 100);
80003}
80004
80005function setDatetimeChange(idPrefix, onChangeCallBack) {
80006  $("#" + idPrefix + "_target_date_1i").on("change", function() {
80007    onChangeCallBack();
80008  });
80009  $("#" + idPrefix + "_target_date_2i").on("change", function() {
80010    onChangeCallBack();
80011  });
80012  $("#" + idPrefix + "_target_date_3i").on("change", function() {
80013    onChangeCallBack();
80014  });
80015  $("#" + idPrefix + "_target_date_4i").on("change", function() {
80016    onChangeCallBack();
80017  });
80018  $("#" + idPrefix + "_target_date_5i").on("change", function() {
80019    onChangeCallBack();
80020  });
80021}
80022
80023function disableDatetime(idPrefix, disabled = true) {
80024  if (disabled) {
80025    $("#" + idPrefix + "_target_date_1i").addClass("readonly");
80026    $("#" + idPrefix + "_target_date_2i").addClass("readonly");
80027    $("#" + idPrefix + "_target_date_3i").addClass("readonly");
80028    $("#" + idPrefix + "_target_date_4i").addClass("readonly");
80029    $("#" + idPrefix + "_target_date_5i").addClass("readonly");
80030  } else {
80031    $("#" + idPrefix + "_target_date_1i").removeClass("readonly");
80032    $("#" + idPrefix + "_target_date_2i").removeClass("readonly");
80033    $("#" + idPrefix + "_target_date_3i").removeClass("readonly");
80034    $("#" + idPrefix + "_target_date_4i").removeClass("readonly");
80035    $("#" + idPrefix + "_target_date_5i").removeClass("readonly");
80036  }
80037}
80038
80039function datetimeSelectToObj(idPrefix) {
80040  var year = $("#" + idPrefix + "_target_date_1i").val();
80041  var month = $("#" + idPrefix + "_target_date_2i").val();
80042  var day = $("#" + idPrefix + "_target_date_3i").val();
80043  var hours = $("#" + idPrefix + "_target_date_4i").val();
80044  var minutes = $("#" + idPrefix + "_target_date_5i").val();
80045
80046  return new Date(year, month - 1, day, hours, minutes, 0, 0);
80047}
80048
80049function objToDateTime(idPrefix, date) {
80050  $("#" + idPrefix + "_target_date_1i").val(date.getFullYear());
80051  $("#" + idPrefix + "_target_date_2i").val(date.getMonth() + 1);
80052  $("#" + idPrefix + "_target_date_3i").val(date.getDate());
80053
80054  var hour = date.getHours();
80055  $("#" + idPrefix + "_target_date_4i").val(hour < 10 ? `0${hour}` : hour);
80056
80057  var minute = date.getMinutes();
80058  $("#" + idPrefix + "_target_date_5i").val(
80059    minute < 10 ? `0${minute}` : minute
80060  );
80061};
80062function reload_min_max_validate(){
80063  $( ".min-max-validate" ).change(function() {
80064    defaultValue = isNaN(parseInt(this.min)) ? 0 : parseInt(this.min)
80065
80066    if (!isNaN(parseInt(this.min)) && parseInt(this.value) < parseInt(this.min)) {
80067      this.value = parseInt(this.min)
80068    }
80069
80070    if (!isNaN(parseInt(this.max)) && parseInt(this.value) > parseInt(this.max)) {
80071      this.value = parseInt(this.max)
80072    }
80073
80074    this.value = isNaN(parseInt(this.value)) ? defaultValue : parseInt(this.value)
80075  });
80076}
80077
80078$(document).ready(function(){
80079  reload_min_max_validate()
80080});
80081init_modal = (title, message, okCalback) => {
80082    $("#myModal").modal({backdrop: "static"});
80083    $('#myModal .modal-title').text(title);
80084    $('#myModal .modal-body').text(message);
80085
80086    $( "#myModal .ok-btn").unbind( "click" );
80087    $("#myModal .ok-btn" ).click(okCalback);
80088}
80089
80090close_modal = () => {
80091    $('#myModal').modal('toggle');
80092};
80093(function() {
80094  $(document).on("click", ".popup-back", function() {
80095    $(".popup-messages").html($(this).data("back-html"));
80096    return $(this).hide();
80097  });
80098
80099  $(document).on("click", ".popup-show, .popup-hide", function() {
80100    return $(".popup-messages, .popup-hide, .popup-show").toggle();
80101  });
80102
80103}).call(this);
80104// Make cart a global variable that can be accessed from anywhere
80105let globalCart;
80106let globalUpdateServerCart;
80107let globalAddToCart;
80108let globalTransformToGoCart;
80109
80110document.addEventListener('DOMContentLoaded', function() {
80111  // ===== Cart Management =====
80112  const cart = {
80113    items: [],
80114    count: 0,
80115    total: 0,
80116    maxItems: 20, // Define maximum cart size
80117
80118    // Add item to cart
80119    addItem(id, title, price, imageUrl = '', productType = 'Course') {
80120      // Check if this item is already in cart
80121      if (this.isInCart(id, productType)) {
80122        return false;
80123      }
80124
80125      // Check if cart has reached max capacity
80126      if (this.count >= this.maxItems) {
80127        showMaxItemsAlert();
80128        return false;
80129      }
80130
80131      // Add new item
80132      this.items.push({
80133        id,
80134        title,
80135        price,
80136        type: productType,
80137        imageUrl,
80138        quantity: 1
80139      });
80140
80141      this.count++;
80142      this.total += parseInt(price);
80143      this.save();
80144      return true;
80145    },
80146
80147    // Check if item is in cart
80148    isInCart(id, productType = 'Course') {
80149      return this.items.some(item => item.id === id && item.type === productType);
80150    },
80151
80152    // Save cart to session storage
80153    save() {
80154      sessionStorage.setItem('cart', JSON.stringify({
80155        items: this.items,
80156        count: this.count,
80157        total: this.total
80158      }));
80159
80160      // Update navbar cart counter whenever cart is saved
80161      this.updateNavCounter();
80162    },
80163
80164    // Add a method to update the navbar counter specifically
80165    updateNavCounter() {
80166      const cartBadge = document.getElementById('cart-counter');
80167      const productNumber = document.getElementById('product-number');
80168      const value = parseInt(productNumber.dataset.value, 10);
80169
80170      if (cartBadge) {
80171        // cartBadge.textContent = this.count.toString();
80172        cartBadge.textContent = (value + cart.count).toString();
80173
80174        // Show/hide based on items in cart
80175        if (this.count > 0) {
80176          cartBadge.classList.remove('d-none');
80177        } else {
80178          cartBadge.classList.add('d-none');
80179        }
80180      }
80181    },
80182
80183    // Load cart from session storage
80184    load() {
80185      const savedCart = sessionStorage.getItem('cart');
80186      if (savedCart) {
80187        const parsedCart = JSON.parse(savedCart);
80188        this.items = parsedCart.items || [];
80189        this.count = parsedCart.count || 0;
80190        this.total = parsedCart.total || 0;
80191
80192        // Update UI with loaded cart data
80193        updateCartCounter();
80194        updateTotalPrice();
80195      }
80196    }
80197  };
80198
80199  // Assign the cart to the global variable
80200  globalCart = cart;
80201  globalUpdateServerCart = updateServerCart;
80202  globalAddToCart = addToCart;
80203
80204  // Format numbers with commas
80205  function numberWithCommas(x) {
80206    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
80207  }
80208
80209  // Show alert for maximum cart items reached
80210  function showMaxItemsAlert() {
80211    let alertContainer = document.getElementById('max-items-alert-container');
80212
80213    // Create alert container if it doesn't exist
80214    if (!alertContainer) {
80215      alertContainer = document.createElement('div');
80216      alertContainer.id = 'max-items-alert-container';
80217      alertContainer.style.position = 'fixed';
80218      alertContainer.style.top = '20px';
80219      alertContainer.style.right = '20px';
80220      alertContainer.style.zIndex = '9999';
80221      document.body.appendChild(alertContainer);
80222    }
80223
80224    // Create the alert element
80225    const alertElement = document.createElement('div');
80226    alertElement.className = 'alert alert-warning alert-dismissible fade show';
80227    alertElement.role = 'alert';
80228    alertElement.innerHTML = `
80229      <strong>カートがいっぱいです!</strong> カートには最大20個までの商品が追加できます。
80230      <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
80231    `;
80232
80233    // Add the alert to the container
80234    alertContainer.appendChild(alertElement);
80235
80236    // Auto-remove after 5 seconds
80237    setTimeout(() => {
80238      if (alertElement.parentNode) {
80239        alertElement.classList.remove('show');
80240        setTimeout(() => alertElement.remove(), 150);
80241      }
80242    }, 5000);
80243
80244    // Initialize Bootstrap's alert dismiss functionality
80245    alertElement.querySelector('.btn-close').addEventListener('click', function() {
80246      alertElement.classList.remove('show');
80247      setTimeout(() => alertElement.remove(), 150);
80248    });
80249  }
80250
80251  // Update cart counter UI including the navbar icon badge
80252  function updateCartCounter() {
80253    // Update all cart count elements
80254    document.querySelectorAll('.cart-count').forEach(counter => {
80255      counter.textContent = cart.count.toString();
80256    });
80257
80258    // Update the cart icon badge
80259    const cartBadge = document.getElementById('cart-counter');
80260    const productNumber = document.getElementById('product-number');
80261    const value = parseInt(productNumber.dataset.value, 10);
80262
80263    if (cartBadge) {
80264      cartBadge.textContent = cart.count.toString();
80265
80266      // Show/hide badge based on items in cart
80267      if (cart.count > 0) {
80268        cartBadge.classList.remove('d-none');
80269        // cartBadge.textContent = (value + cart.count).toString();
80270      // } else if (value > 0) {
80271      //   cartBadge.classList.remove('d-none');
80272      //   cartBadge.textContent = (value + cart.count).toString();
80273      } else {
80274        cartBadge.classList.add('d-none');
80275      }
80276    }
80277  }
80278
80279  // Update total price display
80280  function updateTotalPrice() {
80281    document.querySelectorAll('.cart-total').forEach(el => {
80282      el.textContent = 'Â¥' + numberWithCommas(cart.total);
80283    });
80284  }
80285
80286  // CONSOLIDATED: Transform button to "カートへ進む"
80287  function transformToGoCart(element) {
80288    if (element && (element.tagName === 'BUTTON' || element.classList.contains('add-to-cart-btn'))) {
80289      element.textContent = 'カートへ進む';
80290      element.classList.remove('btn-primary');
80291      element.classList.add('btn-success');
80292
80293      // Change button behavior
80294      element.setAttribute('href', '/purchase/cart');
80295    }
80296  }
80297
80298  globalTransformToGoCart = transformToGoCart;
80299
80300  // Update the cart modal with product info
80301  function updateCartModal(id, title, price, imageUrl) {
80302    const modal = document.getElementById('cartModal');
80303    if (!modal) return;
80304
80305    // Update product information
80306    const productTitle = modal.querySelector('.product-title');
80307    if (productTitle) productTitle.textContent = title;
80308
80309    const productPrice = modal.querySelector('.product-price');
80310    if (productPrice) productPrice.textContent = 'Â¥' + numberWithCommas(price);
80311
80312    // Update image if exists
80313    const productImage = modal.querySelector('.product-image');
80314    if (productImage && imageUrl) {
80315      productImage.src = imageUrl;
80316      productImage.alt = title;
80317    }
80318
80319    // Update cart summary
80320    const cartCount = modal.querySelector('.cart-count');
80321    if (cartCount) cartCount.textContent = cart.count.toString();
80322
80323    const cartTotal = modal.querySelector('.cart-total');
80324    if (cartTotal) cartTotal.textContent = 'Â¥' + numberWithCommas(cart.total);
80325  }
80326
80327  // Send cart update to server
80328  function updateServerCart(id, title, price, productType) {
80329    const token = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
80330    if (!token) return;
80331
80332    fetch('/purchase/cart/add_item', {
80333      method: 'POST',
80334      headers: {
80335        'Content-Type': 'application/json',
80336        'X-CSRF-Token': token
80337      },
80338      body: JSON.stringify({
80339        product_id: id,
80340        product_type: productType,
80341        quantity: 1
80342      })
80343    })
80344    .then(response => response.json())
80345    .then(data => console.log('Product added to cart:', data))
80346    .catch(error => console.error('Error adding product to cart:', error));
80347  }
80348
80349  // Update all buttons for a specific product
80350  function updateButtonsForProduct(id, productType) {
80351    // Find and update all add-to-cart buttons with this product ID
80352    document.querySelectorAll(`.add-to-cart-btn[data-product-id="${id}"]`)
80353      .forEach(transformToGoCart);
80354  }
80355
80356  // ===== Add to Cart Logic =====
80357
80358  // Add to cart function
80359  function addToCart(id, title, price, imageUrl = '', productType = 'Course') {
80360    if (cart.isInCart(id, productType)) {
80361      // If already in cart, just go to cart
80362      window.location.href = '/purchase/cart';
80363      return;
80364    }
80365
80366    // Check if cart has reached max capacity
80367    if (cart.count >= cart.maxItems) {
80368      showMaxItemsAlert();
80369      return;
80370    }
80371
80372    // Add item to cart
80373    if (cart.addItem(id, title, price, imageUrl, productType)) {
80374      // Update UI
80375      updateCartCounter();
80376      updateTotalPrice();
80377
80378      // Update buttons for this product
80379      updateButtonsForProduct(id, productType);
80380
80381      // Send to server
80382      updateServerCart(id, title, price, productType);
80383
80384      // Hide popover if visible
80385      const popover = document.querySelector('.udemy-popover');
80386      if (popover) {
80387        popover.style.display = 'none';
80388      }
80389
80390      // Update and show modal
80391      updateCartModal(id, title, price, imageUrl);
80392      const cartModal = document.getElementById('cartModal');
80393      if (cartModal) {
80394        const bsModal = new bootstrap.Modal(cartModal);
80395        bsModal.show();
80396      }
80397    }
80398  }
80399
80400  // ===== Popover Logic =====
80401
80402  // Get the popover element
80403  const popover = document.querySelector('.udemy-popover');
80404  if (!popover) return;
80405
80406  // Get all product cards
80407  const allCards = document.querySelectorAll('.card-with-popover');
80408
80409  // Load cart data and initialize UI
80410  cart.load();
80411  updateCartCounter();
80412  updateTotalPrice();
80413
80414  // Update buttons for items already in the cart
80415  cart.items.forEach(item => {
80416    updateButtonsForProduct(item.id, item.type);
80417  });
80418
80419  // Set up hover events for cards
80420  allCards.forEach((card, index) => {
80421    if (index === allCards.length - 1) card.classList.add('card-last');
80422
80423    // Add hover event to each card
80424    card.addEventListener('mouseenter', function(e) {
80425      // Get data for this specific product
80426      const productId = this.getAttribute('data-product-id');
80427      const productTitle = this.getAttribute('data-product-title');
80428      const productDescription = this.getAttribute('data-product-description') || '';
80429      const productPrice = parseInt(this.getAttribute('data-product-price'), 10) || 0;
80430      const productDuration = this.getAttribute('data-product-duration') || '12';
80431      const productLevel = this.getAttribute('data-product-level') || '初級';
80432      const productUpdated = this.getAttribute('data-product-updated') || '';
80433      const productType = this.getAttribute('data-product-type') || 'Course';
80434
80435      // Fetch recommendations via AJAX
80436      fetchRecommendations(productId);
80437
80438      const productImg = this.querySelector('img.card-img-top');
80439      const productImgSrc = productImg ? productImg.getAttribute('src') : '';
80440
80441      // Update popover content with this product's data
80442      popover.querySelector('h5').textContent = productTitle;
80443      popover.querySelector('.product-image').setAttribute('src', productImgSrc);
80444      popover.querySelector('.product-image').setAttribute('alt', productTitle);
80445
80446      // Update product metadata in popover
80447      popover.querySelector('.product-updated-date').textContent = productUpdated;
80448      popover.querySelector('.product-duration').textContent = productDuration;
80449      popover.querySelector('.product-level').textContent = productLevel;
80450      popover.querySelector('.product-description').textContent = productDescription;
80451
80452      // Position the popover near the card
80453      const cardRect = card.getBoundingClientRect();
80454      const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
80455
80456      popover.style.position = 'absolute';
80457      popover.style.top = (cardRect.top + scrollTop) + 'px';
80458
80459      // Position horizontally - for right side of screen, show on left side of card
80460      const windowWidth = window.innerWidth;
80461      if (cardRect.right > windowWidth - 350) {
80462        // Show on left side if card is on right side of screen
80463        popover.style.left = cardRect.left - 320 - 10 - 10 + 'px';
80464        popover.style.right = 'auto';
80465        popover.classList.add('right-side');
80466      } else {
80467        // Show on right side of the card
80468        popover.style.left = cardRect.right + 'px';
80469        popover.style.right = 'auto';
80470        popover.classList.remove('right-side');
80471      }
80472
80473      // Show the popover
80474      popover.style.display = 'block';
80475
80476      // Update "Add to Cart" button with product data
80477      const addToCartBtn = popover.querySelector('.add-to-cart-btn');
80478      if (addToCartBtn) {
80479        addToCartBtn.setAttribute('data-product-id', productId);
80480        addToCartBtn.setAttribute('data-product-title', productTitle);
80481        addToCartBtn.setAttribute('data-product-price', productPrice);
80482        addToCartBtn.setAttribute('data-product-image', productImgSrc);
80483        addToCartBtn.setAttribute('data-product-type', productType);
80484
80485        // Check if item is already in cart and update button appearance
80486        if (cart.isInCart(productId, productType)) {
80487          addToCartBtn.textContent = 'カートへ進む';
80488          addToCartBtn.classList.add('btn-success');
80489          addToCartBtn.classList.remove('btn-primary');
80490        } else {
80491          addToCartBtn.textContent = 'カートに入れる';
80492          addToCartBtn.classList.add('btn-primary');
80493          addToCartBtn.classList.remove('btn-success');
80494        }
80495      }
80496    });
80497
80498    // Hide popover when leaving card
80499    card.addEventListener('mouseleave', function() {
80500      if (!popover.matches(':hover')) {
80501        popover.style.display = 'none';
80502      }
80503    });
80504  });
80505
80506  // Handle mouse events on the popover itself
80507  popover.addEventListener('mouseenter', () => {
80508    popover.style.display = 'block';
80509  });
80510
80511  popover.addEventListener('mouseleave', () => {
80512    popover.style.display = 'none';
80513  });
80514
80515  // Add click handler for the "Add to Cart" button in popover
80516  popover.querySelector('.add-to-cart-btn')?.addEventListener('click', function(e) {
80517    e.preventDefault();
80518    const id = this.getAttribute('data-product-id');
80519    const title = this.getAttribute('data-product-title');
80520    const price = parseInt(this.getAttribute('data-product-price'), 10) || 0;
80521    const image = this.getAttribute('data-product-image') || '';
80522    const type = this.getAttribute('data-product-type') || 'Course';
80523
80524    addToCart(id, title, price, image, type);
80525  });
80526
80527  // Event handler for continue shopping button in modal
80528  document.addEventListener('click', function(e) {
80529    if (e.target && e.target.classList.contains('continue-shopping-btn')) {
80530      const modal = bootstrap.Modal.getInstance(document.getElementById('cartModal'));
80531      if (modal) modal.hide();
80532    }
80533  });
80534
80535  // Initialize the cart badge on page load
80536  // Load cart data
80537  cart.load();
80538  
80539  // Setup cart badge
80540  const cartBadge = document.getElementById('cart-counter');
80541  const productNumber = document.getElementById('product-number');
80542  const value = parseInt(productNumber.dataset.value, 10);
80543
80544  if (cartBadge) {
80545    cartBadge.textContent = cart.count.toString();
80546    if (cart.count === 0) {
80547      cartBadge.classList.add('d-none');
80548    } else {
80549      cartBadge.classList.remove('d-none');
80550    }
80551  }
80552});
80553
80554// Initialize cart on page load
80555document.addEventListener('DOMContentLoaded', function() {
80556  // First load saved cart data
80557  if (typeof cart !== 'undefined') {
80558    cart.load();
80559    updateCartCounter();
80560    updateTotalPrice();
80561    cart.updateNavCounter();
80562  }
80563});
80564
80565// ---------- LOGIC PRODUCT RECOMMENDATIONS ---------------
80566document.addEventListener('DOMContentLoaded', function() {
80567  // Function to populate product recommendations in the cart modal
80568  function populateProductRecommendations(productRecommendData) {
80569    if (!productRecommendData) return;
80570
80571    try {
80572      // Parse the product recommend data if it's a string
80573      let recommendedProducts;
80574      if (typeof productRecommendData === 'string') {
80575        // Replace HTML entities with actual characters
80576        recommendedProducts = JSON.parse(productRecommendData);
80577      } else {
80578        recommendedProducts = productRecommendData;
80579      }
80580
80581      if (!Array.isArray(recommendedProducts) || recommendedProducts.length === 0) {
80582        // Hide recommendations section if there are no recommendations
80583        const recommendSection = document.querySelector('#cartModal h6.mb-3');
80584        if (recommendSection) recommendSection.style.display = 'none';
80585
80586        // Hide product recommendation container
80587        const recommendContainer = document.querySelector('.data-recommendation');
80588        if (recommendContainer) recommendContainer.style.display = 'none';
80589        return;
80590      } else {
80591        // Show product recommendation container if there are recommendations
80592        const recommendContainer = document.querySelector('.data-recommendation');
80593        if (recommendContainer) recommendContainer.style.display = 'block';
80594      }
80595      // Get the container and template element
80596      const recommendContainer = document.querySelector('.data-recommendation');
80597      if (!recommendContainer) return;
80598
80599      // Clear existing recommendations
80600      recommendContainer.innerHTML = '';
80601
80602      // Create recommendation cards
80603      recommendedProducts.forEach(product => {
80604        // Format price
80605        const price = parseInt(product.price, 10);
80606        const formattedPrice = price === 0 ? '無料' : `¥${numberWithCommas(price)}`;
80607
80608        // Create the card
80609        const productCard = document.createElement('div');
80610        productCard.className = 'col-12 product-recommend-data';
80611        productCard.innerHTML = `
80612          <div class="card mb-3">
80613            <div class="row g-0">
80614              <div class="col-md-2">
80615                <img src="${product.image || '#'}" class="img-fluid rounded-start product-recommend-image" alt="${product.name || 'コースサムネイル'}">
80616              </div>
80617              <div class="col-md-10">
80618                <div class="card-body">
80619                  <div class="d-flex justify-content-between">
80620                    <div>
80621                      <h6 class="product-recommend-image-title card-title">${product.name || ''}</h6>
80622                      <p class="small mb-1 product-recommend-teacher">${product.teacher || ''}</p>
80623                      <div class="d-flex align-items-center mb-2">
80624                        <span class="fw-bold me-1">4.7</span>
80625                        <div class="rating-stars me-1">
80626                          <i class="bi bi-star-fill"></i>
80627                          <i class="bi bi-star-fill"></i>
80628                          <i class="bi bi-star-fill"></i>
80629                          <i class="bi bi-star-fill"></i>
80630                          <i class="bi bi-star-half"></i>
80631                        </div>
80632                        <span class="text-muted small">(8)</span>
80633                      </div>
80634                      ${product.bestseller ? '<span class="bestseller-badge">ベストセラー</span>' : ''}
80635                    </div>
80636                    <div class="text-end">
80637                      <p class="fw-bold mb-1 product-recommend-price">${formattedPrice}</p>
80638                      <button class="btn btn-outline-primary btn-sm add-recommended-btn" 
80639                        data-course-id="${product.id || ''}" 
80640                        data-course-title="${product.name || ''}" 
80641                        data-course-price="${price}" 
80642                        data-course-image="${product.image || ''}"
80643                        data-course-type="${product.type || 'Course'}">
80644                        <i class="bi bi-plus"></i>
80645                      </button>
80646                    </div>
80647                  </div>
80648                </div>
80649              </div>
80650            </div>
80651          </div>
80652        `;
80653        recommendContainer.appendChild(productCard);
80654      });
80655      
80656      // Add event listeners to add-recommended buttons
80657      document.querySelectorAll('.add-recommended-btn').forEach(button => {
80658        button.addEventListener('click', function() {
80659
80660          const courseId = this.getAttribute('data-course-id');
80661          const courseTitle = this.getAttribute('data-course-title');
80662          const coursePrice = parseInt(this.getAttribute('data-course-price'), 10);
80663          const courseImage = this.getAttribute('data-course-image');
80664          const courseType = this.getAttribute('data-course-type') || 'Course';
80665
80666          // Add to cart using the existing addToCart function
80667          addToCartRecommend(courseId, courseTitle, coursePrice, courseImage, courseType);
80668
80669          // Disable the button after adding
80670          this.disabled = true;
80671          this.innerHTML = '<i class="bi bi-check"></i>';
80672          this.classList.remove('btn-outline-primary');
80673          this.classList.add('btn-success');
80674        });
80675      });
80676      
80677      // Show recommendations section
80678      const recommendSection = document.querySelector('#cartModal h6.mb-3');
80679      if (recommendSection) recommendSection.style.display = 'block';
80680      
80681    } catch (error) {
80682      console.error('Error populating product recommendations:', error);
80683      
80684      // Hide recommendations section on error
80685      const recommendSection = document.querySelector('#cartModal h6.mb-3');
80686      if (recommendSection) recommendSection.style.display = 'none';
80687    }
80688  }
80689  
80690  // Format numbers with commas
80691  function numberWithCommas(x) {
80692    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
80693  }
80694  
80695  // Add the populateProductRecommendations function to the window object
80696  // so it can be called from other scripts
80697  window.populateProductRecommendations = populateProductRecommendations;
80698  
80699  // Find all add-to-cart buttons and add event handlers to populate recommendations
80700  document.querySelectorAll('.add-to-cart-btn').forEach(button => {
80701    const originalClickHandler = button.onclick;
80702
80703    button.onclick = function(event) {
80704      // Show cart icons for both mobile and desktop views
80705      document.querySelectorAll('.icon-cart.d-lg-none, .icon-cart.d-none.d-lg-block')
80706        .forEach(icon => icon.classList.remove('hidden'));
80707
80708      // Execute original handler if exists
80709      if (originalClickHandler) {
80710        originalClickHandler.call(this, event);
80711      }
80712
80713      // After adding to cart, populate recommendations
80714      const productRecommend = this.getAttribute('data-product-recommend') || '';
80715      populateProductRecommendations(productRecommend);
80716    };
80717  });
80718
80719  // Listen for the cartModal being shown
80720  const cartModal = document.getElementById('cartModal');
80721  if (cartModal) {
80722    cartModal.addEventListener('show.bs.modal', function(event) {
80723      // Get the button that triggered the modal
80724      const button = event.relatedTarget;
80725
80726      if (button) {
80727        // Get product recommend data from the button
80728        const productRecommend = button.getAttribute('data-product-recommend') || '';
80729        populateProductRecommendations(productRecommend);
80730      }
80731    });
80732  }
80733  
80734  // Handle continue shopping button click
80735  const continueShoppingBtn = document.querySelector('.continue-shopping-btn');
80736  if (continueShoppingBtn) {
80737    continueShoppingBtn.addEventListener('click', function() {
80738      // Close the modal
80739      const cartModal = bootstrap.Modal.getInstance(document.getElementById('cartModal'));
80740      if (cartModal) {
80741        cartModal.hide();
80742      }
80743    });
80744  }
80745});
80746
80747// Add this function before the populateProductRecommendations function
80748function addToCartRecommend(id, title, price, imageUrl = '', productType = 'Course') {
80749  // First, make sure the globalCart object is available
80750  if (typeof globalCart === 'undefined') {
80751    console.error('Cart object is not defined');
80752    return;
80753  }
80754
80755  // Check if item is already in cart
80756  if (globalCart.isInCart(id, productType)) {
80757    // If already in cart, just show a message and do nothing
80758    console.log('Item is already in cart');
80759    return;
80760  }
80761
80762  // Check if cart has reached max capacity
80763  if (globalCart.count >
80763= globalCart.maxItems) {
80764    showMaxItemsAlert();
80765    return;
80766  }
80767
80768  // Add item to cart
80769  if (globalCart.addItem(id, title, price, imageUrl, productType)) {
80770    // Update UI
80771    if (typeof updateCartCounter === 'function') {
80772      updateCartCounter();
80773    }
80774
80775    if (typeof updateTotalPrice === 'function') {
80776      updateTotalPrice();
80777    }
80778
80779    document.querySelectorAll(`.add-to-cart-btn[data-product-id="${id}"]`).forEach(button => {
80780      if (typeof globalTransformToGoCart === 'function') {
80781        globalTransformToGoCart(button);
80782      }
80783    });
80784
80785    // Send to server
80786    globalUpdateServerCart(id, title, price, productType);
80787
80788    // Show a success message in the cart modal
80789    const recommendContainer = document.querySelector('.product-recommend-data');
80790    if (recommendContainer) {
80791      // Create success alert if it doesn't exist
80792      if (!document.getElementById('recommend-success-alert')) {
80793        const alertElement = document.createElement('div');
80794        alertElement.id = 'recommend-success-alert';
80795        alertElement.className = 'alert alert-success mt-3';
80796        alertElement.innerHTML = `
80797          <i class="bi bi-check-circle-fill me-2"></i>
80798          <strong>${title}</strong> をカートに追加しました
80799        `;
80800
80801        // Insert at the top of recommendations
80802        recommendContainer.insertBefore(alertElement, recommendContainer.firstChild);
80803
80804        // Auto-remove after 3 seconds
80805        setTimeout(() => {
80806          if (alertElement && alertElement.parentNode) {
80807            alertElement.remove();
80808          }
80809        }, 3000);
80810      }
80811    }
80812  }
80813}
80814
80815// Make sure this function is available globally
80816window.addToCartRecommend = addToCartRecommend;
80817
80818document.addEventListener('DOMContentLoaded', function() {
80819  // Rest of your existing code remains the same...
80820
80821  // When you bind event listeners to .add-recommended-btn buttons:
80822  document.querySelectorAll('.add-recommended-btn').forEach(button => {
80823    button.addEventListener('click', function() {
80824      const courseId = this.getAttribute('data-course-id');
80825      const courseTitle = this.getAttribute('data-course-title');
80826      const coursePrice = parseInt(this.getAttribute('data-course-price'), 10);
80827      const courseImage = this.getAttribute('data-course-image');
80828      const courseType = this.getAttribute('data-course-type') || 'Course';
80829
80830      // Use the dedicated function for recommendations
80831      addToCartRecommend(courseId, courseTitle, coursePrice, courseImage, courseType);
80832
80833      // Update this button's state
80834      this.disabled = true;
80835      this.innerHTML = '<i class="bi bi-check"></i>';
80836      this.classList.remove('btn-outline-primary');
80837      this.classList.add('btn-success');
80838    });
80839  });
80840});
80841
80842// Add the fetchRecommendations function
80843function fetchRecommendations(courseId) {
80844  if (!courseId) return;
80845
80846  // Get CSRF token for AJAX request
80847  const token = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
80848  if (!token) return;
80849
80850  // Create fetch request to get recommendations
80851  fetch(`/courses/${courseId}/get_recommendations`, {
80852    method: 'GET',
80853    headers: {
80854      'X-CSRF-Token': token,
80855      'Accept': 'application/json'
80856    }
80857  })
80858  .then(response => {
80859    if (!response.ok) {
80860      throw new Error('Network response was not ok');
80861    }
80862    return response.json();
80863  })
80864  .then(data => {
80865    // Update the data-product-recommend attribute
80866    updateRecommendationAttributes(courseId, data);
80867  })
80868  .catch(error => {
80869    console.error('Error fetching recommendations:', error);
80870  });
80871}
80872
80873// Function to update recommendation attributes on buttons
80874function updateRecommendationAttributes(courseId, recommendationsData) {
80875  // Find all buttons for this course and update their data-product-recommend attribute
80876  document.querySelectorAll(`.add-to-cart-btn[data-product-id="${courseId}"]`).forEach(button => {
80877    button.setAttribute('data-product-recommend', JSON.stringify(recommendationsData));
80878  });
80879
80880  // Also update the current popover if it's visible
80881  const popover = document.querySelector('.udemy-popover');
80882  if (popover && popover.style.display === 'block') {
80883    const popoverButton = popover.querySelector('.add-to-cart-btn');
80884    if (popoverButton && popoverButton.getAttribute('data-product-id') === courseId) {
80885      popoverButton.setAttribute('data-product-recommend', JSON.stringify(rec
80885ommendationsData));
80886    }
80887  }
80888}
80889
80890// Add event listeners to all add-to-cart-btn in screen index and show buttons
80891document.addEventListener('DOMContentLoaded', function() {
80892  const detailPageButton = document.querySelector('.add-to-cart-btn-in-show');
80893  if (detailPageButton) {
80894    const courseId = detailPageButton.getAttribute('data-product-id');
80895
80896    if (courseId) {
80897      fetchRecommendations(courseId);
80898    }
80899
80900    const savedCart = sessionStorage.getItem('cart');
80901    if (savedCart) {
80902      try {
80903        const cartData = JSON.parse(savedCart);
80904
80905        // Check if the course exists in the cart items
80906        if (cartData.items && Array.isArray(cartData.items)) {
80907          const courseInCart = cartData.items.some(item =>
80908            item.id.toString() === courseId.toString() && item.type === 'Course'
80909          );
80910
80911          if (courseInCart) {
80912            document.querySelectorAll(`.add-to-cart-btn[data-product-id="${courseId}"]`).forEach(btn => {
80913              if (typeof globalTransformToGoCart === 'function') {
80914                globalTransformToGoCart(btn);
80915              }
80916            });
80917          }
80918        }
80919      } catch (error) {
80920        console.error('Error parsing cart data:', error);
80921      }
80922    }
80923  }
80924
80925  document.querySelectorAll('.add-to-cart-btn-index, .add-to-cart-btn-in-show').forEach(button => {
80926    button.addEventListener('click', function(e) {
80927      console.log('Add to cart button clicked');
80928      e.preventDefault();
80929
80930      // Get product data from data attributes
80931      const id = this.getAttribute('data-product-id');
80932      const title = this.getAttribute('data-product-title');
80933      const price = parseInt(this.getAttribute('data-product-price'), 10) || 0;
80934      const imageUrl = this.getAttribute('data-product-image') || '';
80935      const type = this.getAttribute('data-product-type') || 'Course';
80936
80937      if (typeof globalAddToCart === 'function') {
80938        globalAddToCart(id, title, price, imageUrl, type);
80939      } else {
80940        console.error('addToCart function is not available');
80941      }
80942    });
80943  });
80944});
80945// jquery-ujs only evals a remote response on a 2xx, so a `render :update_error,
80946// status: :unprocessable_entity` is dropped and the user sees nothing. Run the
80947// error view here so validation messages reach the screen.
80948$(document).on("ajax:error", function(event, xhr) {
80949  var contentType = xhr.getResponseHeader("Content-Type") || "";
80950  if (xhr.status === 422 && contentType.indexOf("javascript") !== -1) {
80951    $.globalEval(xhr.responseText);
80952  }
80953});
80954$(document).on("keyup", "#search-input-global", function(event){
80955  if (event.which == 27) {
80956    var el = document.getElementById("search-input-global");
80957    if (el && typeof bootstrap !== "undefined") {
80958      var popover = bootstrap.Popover.getInstance(el);
80959      if (popover) popover.hide();
80960    }
80961  } else if (event.which == 13) {
80962    return false;
80963  } else {
80964    if ($(this).data("submit-target")) $(this).closest("form").find($(this).data("submit-target")).attr("disabled", true);
80965    $(this).trigger("focus")
80966  }
80967})
80968
80969$(document).off("click", ".select-item-button").on("click", ".select-item-button", function(){
80970  select_item($(this));
80971});
80972
80973function select_item(target) {
80974  // TODO
80975}
80976
80977$(document).on("focus", "#search-input-global", function(event){
80978  if ($(this).val()) {
80979    data = $(this).closest("form").serializeArray().map(function(form_data){
80980      return form_data.name+"="+form_data.value;
80981    }).join("&")
80982    $.ajax({
80983      url: "/search.js",
80984      data: data
80985    })
80986  }
80987})
80988
80989$(document).ready(function() {
80990  var el = document.getElementById("search-input-global");
80991  if (el && typeof bootstrap !== "undefined") {
80992    new bootstrap.Popover(el, {
80993      animation: false,
80994      content: function(){ return $("#select-item").html() },
80995      html: true,
80996      placement: "bottom",
80997      trigger: "manual"
80998    });
80999  }
81000});
81001function select_course(target) {
81002  var input = $("input.course-search");
81003  input.data("selected", true);
81004  input.val(target.find("a").text().trim()).popover("hide").focus().trigger("focus");
81005  $("input.course-search-value").val(target.data("course-id")).trigger("change");
81006}
81007
81008$(document).ready(function() {
81009  $("input.course-search").each(function(index, input){
81010    var fake_input = $(input).clone();
81011    if (!input.id) $(input).prop("id", Math.random().toString(36).substr(2, 10));
81012    fake_input.attr("type", "hidden").attr("name", $(input).attr("name")).removeClass("course-search")
81013      .addClass("course-search-value").insertAfter($(input))
81014    $(input).removeAttr("name").attr("autocomplete", "off")
81015    $(input).popover({
81016      animation: false,
81017      content: function(){return $("#select-course").html()},
81018      html: true,
81019      placement: "bottom",
81020      trigger: "manual"
81021    })
81022  })
81023})
81024
81025$(document).off("click", ".select-course-button").on("click", ".select-course-button", function(){
81026  select_course($(this));
81027});
81028
81029$(document).on("mouseenter", ".select-course-button", function() {
81030  $(".select-course-button.selected").removeClass("selected");
81031  $(this).addClass("selected");
81032});
81033
81034$(document).on("keypress", ".course-search", function(event){
81035  if (event.which == 13) {
81036    var selected = $(".select-course-button.selected");
81037    if (selected.length == 0) {
81038      var hiddenInput = $(this).siblings(".course-search-value");
81039      if (hiddenInput.length > 0) {
81040        hiddenInput.val($(this).val());
81041      }
81042      $(this).popover("hide");
81043      $(this).closest("form").submit();
81044      return false;
81045    }
81046    select_course(selected);
81047    return false;
81048  }
81049});
81050
81051$(document).on("focus", ".course-search", function(event){
81052  if ($(this).data("selected")) {
81053    $(this).data("selected", false);
81054    return;
81055  }
81056  if ($(this).val()) {
81057    $(".course-search-input").val($(this).val())
81058    $("input.course-email").val($(this).val())
81059    var option = "";
81060    ["excepts", "scope-type", "scope-id", "scope-ids", "except-scope-type", "except-scope-id", "except-scope-ids"].forEach(function(option_type){
81061      if ($(event.target).data(option_type)) option += "&" + option_type.replace(/-/g, '_') + "="+$(event.target).data(option_type);
81062    })
81063    $.get("/course_filters.js?q="+encodeURIComponent($(this).val())+"&form_id="+$(this)[0].id+option)
81064  } else {
81065    // Hide popover if input is empty
81066    $(this).popover("hide");
81067  }
81068})
81069
81070$(document).on("keyup", ".course-search", function(event){
81071  var $popoverBody = $(".popover-body")
81072  if (event.which == 27) {
81073    $(this).popover("hide");
81074  } else if (event.which == 13) {
81075    return false;
81076  } else if ((event.which == 40 || event.which == 38) && $popoverBody.find(".select-course-button").length > 0) {
81077    var $selected;
81078    var $current = $popoverBody.find(".select-course-button.selected")
81079    if (event.which == 40) {
81080      const $next = $current.next()
81081      $selected = $current.length === 0 || $next.length === 0 ? $popoverBody.find(".select-course-button:first") : $next;
81082    } else {
81083      const $prev = $current.prev()
81084      $selected = $current.length === 0 || $prev.length === 0 ? $popoverBody.find(".select-course-button:last") : $prev;
81085    }
81086    $selected.addClass("selected")
81087    $current.removeClass("selected");
81088  } else {
81089    // Hide popover if input becomes empty
81090    if (!$(this).val().trim()) {
81091      $(this).popover("hide");
81092    }
81093    if ($(this).data("submit-target")) $(this).closest("form").find($(this).data("submit-target")).attr("disabled", true);
81094    $(this).trigger("focus")
81095  }
81096});
81097// $(document).ready(function() {
81098//   $("input.course-search").each(function(index, input){
81099//     var fake_input = $(input).clone();
81100//     if (!input.id) $(input).prop("id", Math.random().toString(36).substr(2, 10));
81101//     fake_input.attr("type", "hidden").attr("name", $(input).attr("name")).removeClass("course-search")
81102//       .addClass("course-search-value").insertAfter($(input))
81103//     $(input).removeAttr("name").attr("autocomplete", "off")
81104//     $(input).popover({
81105//       animation: false,
81106//       content: function(){return $("#select-course").html()},
81107//       html: true,
81108//       placement: "bottom",
81109//       trigger: "manual"
81110//     })
81111//   })
81112// })
81113//
81114// $(document).off("click", ".select-course-button").on("click", ".select-course-button", function(){
81115//   select_course($(this));
81116// });
81117//
81118// $(document).on("mouseenter", ".select-course-button", function() {
81119//   $(".select-course-button.selected").removeClass("selected");
81120//   $(this).addClass("selected");
81121// });
81122//
81123// $(document).on("keypress", ".course-search", function(event){
81124//   if (event.which == 13) {
81125//     var selected = $(".select-course-button.selected");
81126//     if (selected.length == 0) return;
81127//     select_course(selected);
81128//     return false;
81129//   }
81130// });
81131//
81132// $(document).on("focus", ".course-search", function(event){
81133//   if ($(this).data("selected")) {
81134//     $(this).data("selected", false);
81135//     return;
81136//   }
81137//   if ($(this).val()) {
81138//     $(".course-search-input").val($(this).val())
81139//     $("input.course-email").val($(this).val())
81140//     var option = "";
81141//     ["excepts", "scope-type", "scope-id", "scope-ids", "except-scope-type", "except-scope-id", "except-scope-ids"].forEach(function(option_type){
81142//       if ($(event.target).data(option_type)) option += "&" + option_type.replace(/-/g, '_') + "="+$(event.target).data(option_type);
81143//     })
81144//     $.get("/course_filters.js?q="+encodeURIComponent($(this).val())+"&form_id="+$(this)[0].id+option)
81145//   }
81146// })
81147//
81148// $(document).on("keyup", ".course-search", function(event){
81149//   if (event.which == 27) {
81150//     $(this).popover("hide");
81151//   } else if (event.which == 13) {
81152//     return false;
81153//   } else if (event.which == 40 || event.which == 38 && $(".select-course-button:visible").length > 0) {
81154//     var selected;
81155//     if (event.which == 40) {
81156//       selected = $(".select-course-button.selected").next();
81157//       if (selected.length == 0) selected = $(".select-course-button:visible:first");
81158//     } else {
81159//       selected = $(".select-course-button.selected").prev();
81160//       if (selected.length == 0) selected = $(".select-course-button:visible:last");
81161//     }
81162//     $(".select-course-button.selected").removeClass("selected");
81163//     selected.addClass("selected")
81164//   } else {
81165//     if ($(this).data("submit-target")) $(this).closest("form").find($(this).data("submit-target")).attr("disabled", true);
81166//     $(this).trigger("focus")
81167//   }
81168// });
81169function select_user(target) {
81170  var input = $('input.user-search')
81171  input.data('selected', true)
81172  var inputEl = document.getElementById(form_id)
81173  $(inputEl).focus().val(target.find('div.user-name').text())
81174  if (inputEl && typeof bootstrap !== "undefined") {
81175    var popover = bootstrap.Popover.getInstance(inputEl)
81176    if (popover) popover.hide()
81177  }
81178  $('input.user-search-value')
81179    .val(target.find('div.user-id').text())
81180    .trigger('change')
81181  if (input.data('submit-target')) {
81182    $($(input).data('submit-target')).removeAttr('disabled')
81183  }
81184}
81185
81186$(document).ready(function() {
81187  $('input.user-search').each(function(index, input) {
81188    // ユーザー検索の場合、fakeが不要です。代わりにユーザー登録の場合、ユーザーIDが必要ですので、fakeでuser IDを追加する
81189    if ($(input).data().formType != 'search_user') {
81190      var fake_input = $(input).clone()
81191      if (!input.id)
81192        $(input).prop(
81193          'id',
81194          Math.random()
81195            .toString(36)
81196            .substr(2, 10)
81197        )
81198      fake_input
81199        .attr('type', 'hidden')
81200        .attr('name', $(input).attr('name'))
81201        .removeClass('user-search')
81202        .addClass('user-search-value')
81203        .insertAfter($(input))
81204      $(input).removeAttr('name')
81205    }
81206    $(input).attr('autocomplete', 'off')
81207
81208    if (typeof bootstrap !== "undefined") {
81209      new bootstrap.Popover(input, {
81210        animation: false,
81211        content: function() {
81212          var selectUser = document.getElementById('select-user')
81213          return selectUser ? selectUser.innerHTML : ''
81214        },
81215        html: true,
81216        placement: 'bottom',
81217        trigger: 'manual'
81218      })
81219    }
81220  })
81221})
81222
81223$(document)
81224  .off('click', '.select-user-button')
81225  .on('click', '.select-user-button', function() {
81226    select_user($(this))
81227  })
81228
81229$(document).on('mouseenter', '.select-user-button', function() {
81230  $('.select-user-button.selected').removeClass('selected')
81231  $(this).addClass('selected')
81232})
81233
81234$(document).on('keypress', '.user-search', function(event) {
81235  if (event.which == 13) {
81236    var selected = $('.select-user-button.selected')
81237    if (selected.length == 0) return
81238    select_user(selected)
81239    return false
81240  }
81241})
81242
81243var searchUserTimer = null
81244var searchUserXhr = null
81245
81246function hideUserPopover(input) {
81247  if (typeof bootstrap === "undefined") return
81248  var popover = bootstrap.Popover.getInstance(input)
81249  if (popover) popover.hide()
81250}
81251
81252function fetchUserSuggestions(input) {
81253  var $input = $(input)
81254  if (!$input.val()) {
81255    // Empty input: drop any in-flight request and hide the suggestions popover
81256    if (searchUserXhr) searchUserXhr.abort()
81257    hideUserPopover(input)
81258    return
81259  }
81260
81261  $('.user-search-input').val($input.val())
81262  $('input.user-email').val($input.val())
81263  var option = ''
81264  ;[
81265    'excepts',
81266    'scope-type',
81267    'scope-id',
81268    'scope-ids',
81269    'except-scope-type',
81270    'except-scope-id',
81271    'except-scope-ids'
81272  ].forEach(function(option_type) {
81273    if ($input.data(option_type))
81274      option += '&' + option_type.replace(/-/g, '_') + '=' + $input.data(option_type)
81275  })
81276
81277  // Cancel any in-flight request so stale responses can't overwrite the popover
81278  if (searchUserXhr) searchUserXhr.abort()
81279
81280  var url = window.location.href.toString().includes('teachers')
81281    ? '/admin/teachers.js'
81282    : '/users.js'
81283  searchUserXhr = $.get(url + '?q=' + encodeURIComponent($input.val()) + '&form_id=' + input.id + option)
81284}
81285
81286$(document).on('focus', '.user-search', function(event) {
81287  if ($(this).data('selected')) {
81288    $(this).data('selected', false)
81289    return
81290  }
81291  fetchUserSuggestions(this)
81292})
81293
81294$(document).on('keyup', '.user-search', function(event) {
81295  if (event.which == 27) {
81296    if (typeof bootstrap !== "undefined") {
81297      var popover = bootstrap.Popover.getInstance(this)
81298      if (popover) popover.hide()
81299    }
81300  } else if (event.which == 13) {
81301    return false
81302  } else if (event.which == 40 || (event.which == 38 && $('.select-user-button:visible').length > 0)) {
81303    var selected
81304    if (event.which == 40) {
81305      selected = $('.select-user-button.selected').next()
81306      if (selected.length == 0) selected = $('.select-user-button:visible:first')
81307    } else {
81308      selected = $('.select-user-button.selected').prev()
81309      if (selected.length == 0) selected = $('.select-user-button:visible:last')
81310    }
81311    $('.select-user-button.selected').removeClass('selected')
81312    selected.addClass('selected')
81313  } else {
81314    if ($(this).data('submit-target'))
81315      $(this)
81316        .closest('form')
81317        .find($(this).data('submit-target'))
81318        .attr('disabled', true)
81319    var input = this
81320    if (searchUserTimer) clearTimeout(searchUserTimer)
81321    if (!$(this).val()) {
81322      // Hide immediately when the field is cleared instead of waiting for the debounce
81323      if (searchUserXhr) searchUserXhr.abort()
81324      hideUserPopover(this)
81325      return
81326    }
81327    searchUserTimer = setTimeout(function() {
81328      fetchUserSuggestions(input)
81329    }, 300)
81330  }
81331});
81332/*jslint newcap: true */
81333/*global XMLHttpRequest: false, FormData: false */
81334/*
81335 * Inline Text Attachment
81336 *
81337 * Author: Roy van Kaathoven
81338 * Contact: [email protected]
81339 */
81340(function(document, window) {
81341  'use strict';
81342
81343  var inlineAttachment = function(options, instance) {
81344    this.settings = inlineAttachment.util.merge(options, inlineAttachment.defaults);
81345    this.editor = instance;
81346    this.filenameTag = '{filename}';
81347    this.lastValue = null;
81348  };
81349
81350  /**
81351   * Will holds the available editors
81352   *
81353   * @type {Object}
81354   */
81355  inlineAttachment.editors = {};
81356
81357  /**
81358   * Utility functions
81359   */
81360  inlineAttachment.util = {
81361
81362    /**
81363     * Simple function to merge the given objects
81364     *
81365     * @param {Object[]} object Multiple object parameters
81366     * @returns {Object}
81367     */
81368    merge: function() {
81369      var result = {};
81370      for (var i = arguments.length - 1; i >= 0; i--) {
81371        var obj = arguments[i];
81372        for (var k in obj) {
81373          if (obj.hasOwnProperty(k)) {
81374            result[k] = obj[k];
81375          }
81376        }
81377      }
81378      return result;
81379    },
81380
81381    /**
81382     * Append a line of text at the bottom, ensuring there aren't unnecessary newlines
81383     *
81384     * @param {String} appended Current content
81385     * @param {String} previous Value which should be appended after the current content
81386     */
81387    appendInItsOwnLine: function(previous, appended) {
81388      return (previous + "\n\n[[D]]" + appended)
81389        .replace(/(\n{2,})\[\[D\]\]/, "\n\n")
81390        .replace(/^(\n*)/, "");
81391    },
81392
81393    /**
81394     * Inserts the given value at the current cursor position of the textarea element
81395     *
81396     * @param  {HtmlElement} el
81397     * @param  {String} value Text which will be inserted at the cursor position
81398     */
81399    insertTextAtCursor: function(el, text) {
81400      var scrollPos = el.scrollTop,
81401        strPos = 0,
81402        browser = false,
81403        range;
81404
81405      if ((el.selectionStart || el.selectionStart === '0')) {
81406        browser = "ff";
81407      } else if (document.selection) {
81408        browser = "ie";
81409      }
81410
81411      if (browser === "ie") {
81412        el.focus();
81413        range = document.selection.createRange();
81414        range.moveStart('character', -el.value.length);
81415        strPos = range.text.length;
81416      } else if (browser === "ff") {
81417        strPos = el.selectionStart;
81418      }
81419
81420      var front = (el.value).substring(0, strPos);
81421      var back = (el.value).substring(strPos, el.value.length);
81422      el.value = front + text + back;
81423      strPos = strPos + text.length;
81424      if (browser === "ie") {
81425        el.focus();
81426        range = document.selection.createRange();
81427        range.moveStart('character', -el.value.length);
81428        range.moveStart('character', strPos);
81429        range.moveEnd('character', 0);
81430        range.select();
81431      } else if (browser === "ff") {
81432        el.selectionStart = strPos;
81433        el.selectionEnd = strPos;
81434        el.focus();
81435      }
81436      el.scrollTop = scrollPos;
81437    }
81438  };
81439
81440  /**
81441   * Default configuration options
81442   *
81443   * @type {Object}
81444   */
81445  inlineAttachment.defaults = {
81446    /**
81447     * URL where the file will be send
81448     */
81449    uploadUrl: 'upload_attachment.php',
81450
81451    /**
81452     * Which method will be used to send the file to the upload URL
81453     */
81454    uploadMethod: 'POST',
81455
81456    /**
81457     * Name in which the file will be placed
81458     */
81459    uploadFieldName: 'file',
81460
81461    /**
81462     * Extension which will be used when a file extension could not
81463     * be detected
81464     */
81465    defaultExtension: 'png',
81466
81467    /**
81468     * JSON field which refers to the uploaded file URL
81469     */
81470    jsonFieldName: 'filename',
81471
81472    /**
81473     * Allowed MIME types
81474     */
81475    allowedTypes: [
81476      'image/jpeg',
81477      'image/png',
81478      'image/jpg',
81479      'image/gif'
81480    ],
81481
81482    /**
81483     * Text which will be inserted when dropping or pasting a file.
81484     * Acts as a placeholder which will be replaced when the file is done with uploading
81485     */
81486    progressText: '![Uploading file...]()',
81487
81488    /**
81489     * When a file has successfully been uploaded the progressText
81490     * will be replaced by the urlText, the {filename} tag will be replaced
81491     * by the filename that has been returned by the server
81492     */
81493    urlText: "![file]({filename})",
81494
81495    /**
81496     * Text which will be used when uploading has failed
81497     */
81498    errorText: "Error uploading file",
81499
81500    /**
81501     * Extra parameters which will be send when uploading a file
81502     */
81503    extraParams: {},
81504
81505    /**
81506     * Extra headers which will be send when uploading a file
81507     */
81508    extraHeaders: {},
81509
81510    /**
81511     * Before the file is send
81512     */
81513    beforeFileUpload: function() {
81514      return true;
81515    },
81516
81517    /**
81518     * Triggers when a file is dropped or pasted
81519     */
81520    onFileReceived: function() {},
81521
81522    /**
81523     * Custom upload handler
81524     *
81525     * @return {Boolean} when false is returned it will prevent default upload behavior
81526     */
81527    onFileUploadResponse: function() {
81528      return true;
81529    },
81530
81531    /**
81532     * Custom error handler. Runs after removing the placeholder text and before the alert().
81533     * Return false from this function to prevent the alert dialog.
81534     *
81535     * @return {Boolean} when false is returned it will prevent default error behavior
81536     */
81537    onFileUploadError: function() {
81538      return true;
81539    },
81540
81541    /**
81542     * When a file has succesfully been uploaded
81543     */
81544    onFileUploaded: function() {}
81545  };
81546
81547  /**
81548   * Uploads the blob
81549   *
81550   * @param  {Blob} file blob data received from event.dataTransfer object
81551   * @return {XMLHttpRequest} request object which sends the file
81552   */
81553  inlineAttachment.prototype.uploadFile = function(file) {
81554    var me = this,
81555      formData = new FormData(),
81556      xhr = new XMLHttpRequest(),
81557      settings = this.settings,
81558      extension = settings.defaultExtension || settings.defualtExtension;
81559
81560    if (typeof settings.setupFormData === 'function') {
81561      settings.setupFormData(formData, file);
81562    }
81563
81564    // Attach the file. If coming from clipboard, add a default filename (only works in Chrome for now)
81565    // http://stackoverflow.com/questions/6664967/how-to-give-a-blob-uploaded-as-formdata-a-file-name
81566    if (file.name) {
81567      var fileNameMatches = file.name.match(/\.(.+)$/);
81568      if (fileNameMatches) {
81569        extension = fileNameMatches[1];
81570      }
81571    }
81572
81573    var remoteFilename = "image-" + Date.now() + "." + extension;
81574    if (typeof settings.remoteFilename === 'function') {
81575      remoteFilename = settings.remoteFilename(file);
81576    }
81577
81578    formData.append(settings.uploadFieldName, file, remoteFilename);
81579
81580    // Append the extra parameters to the formdata
81581    if (typeof settings.extraParams === "object") {
81582      for (var key in settings.extraParams) {
81583        if (settings.extraParams.hasOwnProperty(key)) {
81584          formData.append(key, settings.extraParams[key]);
81585        }
81586      }
81587    }
81588
81589    xhr.open('POST', settings.uploadUrl);
81590
81591    // Add any available extra headers
81592    if (typeof settings.extraHeaders === "object") {
81593        for (var header in settings.extraHeaders) {
81594            if (settings.extraHeaders.hasOwnProperty(header)) {
81595                xhr.setRequestHeader(header, settings.extraHeaders[header]);
81596            }
81597        }
81598    }
81599
81600    xhr.onload = function() {
81601      // If HTTP status is OK or Created
81602      if (xhr.status === 200 || xhr.status === 201) {
81603        me.onFileUploadResponse(xhr);
81604      } else {
81605        me.onFileUploadError(xhr);
81606      }
81607    };
81608    if (settings.beforeFileUpload(xhr) !== false) {
81609      xhr.send(formData);
81610    }
81611    return xhr;
81612  };
81613
81614  /**
81615   * Returns if the given file is allowed to handle
81616   *
81617   * @param {File} clipboard data file
81618   */
81619  inlineAttachment.prototype.isFileAllowed = function(file) {
81620    if (file.kind === 'string') { return false; }
81621    if (this.settings.allowedTypes.indexOf('*') === 0){
81622      return true;
81623    } else {
81624      return this.settings.allowedTypes.indexOf(file.type) >= 0;
81625    }
81626  };
81627
81628  /**
81629   * Handles upload response
81630   *
81631   * @param  {XMLHttpRequest} xhr
81632   * @return {Void}
81633   */
81634  inlineAttachment.prototype.onFileUploadResponse = function(xhr) {
81635    if (this.settings.onFileUploadResponse.call(this, xhr) !== false) {
81636      var result = JSON.parse(xhr.responseText),
81637        filename = result[this.settings.jsonFieldName];
81638
81639      if (result && filename) {
81640        var newValue;
81641        if (typeof this.settings.urlText === 'function') {
81642          newValue = this.settings.urlText.call(this, filename, result);
81643        } else {
81644          newValue = this.settings.urlText.replace(this.filenameTag, filename);
81645        }
81646        var text = this.editor.getValue().replace(this.lastValue, newValue);
81647        this.editor.setValue(text);
81648        this.settings.onFileUploaded.call(this, filename);
81649      }
81650    }
81651  };
81652
81653
81654  /**
81655   * Called when a file has failed to upload
81656   *
81657   * @param  {XMLHttpRequest} xhr
81658   * @return {Void}
81659   */
81660  inlineAttachment.prototype.onFileUploadError = function(xhr) {
81661    if (this.settings.onFileUploadError.call(this, xhr) !== false) {
81662      var text = this.editor.getValue().replace(this.lastValue, this.settings.errorText);
81663      this.editor.setValue(text);
81664    }
81665  };
81666
81667  /**
81668   * Called when a file has been inserted, either by drop or paste
81669   *
81670   * @param  {File} file
81671   * @return {Void}
81672   */
81673  inlineAttachment.prototype.onFileInserted = function(file) {
81674    if (this.settings.onFileReceived.call(this, file) !== false) {
81675      this.lastValue = this.settings.progressText;
81676      this.editor.insertValue(this.lastValue);
81677    }
81678  };
81679
81680
81681  /**
81682   * Called when a paste event occured
81683   * @param  {Event} e
81684   * @return {Boolean} if the event was handled
81685   */
81686  inlineAttachment.prototype.onPaste = function(e) {
81687    var result = false,
81688      clipboardData = e.clipboardData,
81689      items;
81690
81691    if (typeof clipboardData === "object") {
81692      items = clipboardData.items || clipboardData.files || [];
81693
81694      for (var i = 0; i < items.length; i++) {
81695        var item = items[i];
81696        if (this.isFileAllowed(item)) {
81697          result = true;
81698          this.onFileInserted(item.getAsFile());
81699          this.uploadFile(item.getAsFile());
81700        }
81701      }
81702    }
81703
81704    if (result) { e.preventDefault(); }
81705
81706    return result;
81707  };
81708
81709  /**
81710   * Called when a drop event occures
81711   * @param  {Event} e
81712   * @return {Boolean} if the event was handled
81713   */
81714  inlineAttachment.prototype.onDrop = function(e) {
81715    var result = false;
81716    for (var i = 0; i < e.dataTransfer.files.length; i++) {
81717      var file = e.dataTransfer.files[i];
81718      if (this.isFileAllowed(file)) {
81719        result = true;
81720        this.onFileInserted(file);
81721        this.uploadFile(file);
81722      }
81723    }
81724
81725    return result;
81726  };
81727
81728  window.inlineAttachment = inlineAttachment;
81729
81730})(document, window);
81731/*jslint newcap: true */
81732/*global inlineAttachment: false */
81733/**
81734 * CodeMirror version for inlineAttachment
81735 *
81736 * Call inlineAttachment.attach(editor) to attach to a codemirror instance
81737 */
81738(function() {
81739  'use strict';
81740
81741  var codeMirrorEditor = function(instance) {
81742
81743    if (!instance.getWrapperElement) {
81744      throw "Invalid CodeMirror object given";
81745    }
81746
81747    this.codeMirror = instance;
81748  };
81749
81750  codeMirrorEditor.prototype.getValue = function() {
81751    return this.codeMirror.getValue();
81752  };
81753
81754  codeMirrorEditor.prototype.insertValue = function(val) {
81755    this.codeMirror.replaceSelection(val);
81756  };
81757
81758  codeMirrorEditor.prototype.setValue = function(val) {
81759    var cursor = this.codeMirror.getCursor();
81760    this.codeMirror.setValue(val);
81761    this.codeMirror.setCursor(cursor);
81762  };
81763
81764  /**
81765   * Attach InlineAttachment to CodeMirror
81766   *
81767   * @param {CodeMirror} codeMirror
81768   */
81769  codeMirrorEditor.attach = function(codeMirror, options) {
81770
81771    options = options || {};
81772
81773    var editor = new codeMirrorEditor(codeMirror),
81774      inlineattach = new inlineAttachment(options, editor),
81775      el = codeMirror.getWrapperElement();
81776
81777    el.addEventListener('paste', function(e) {
81778      inlineattach.onPaste(e);
81779    }, false);
81780
81781    codeMirror.setOption('onDragEvent', function(data, e) {
81782      if (e.type === "drop") {
81783        e.stopPropagation();
81784        e.preventDefault();
81785        return inlineattach.onDrop(e);
81786      }
81787    });
81788  };
81789
81790  inlineAttachment.editors.codemirror3 = codeMirrorEditor;
81791})();
81792/*jslint newcap: true */
81793/*global inlineAttachment: false */
81794/**
81795 * CodeMirror version for inlineAttachment
81796 *
81797 * Call inlineAttachment.attach(editor) to attach to a codemirror instance
81798 */
81799(function() {
81800  'use strict';
81801
81802  var codeMirrorEditor = function(instance) {
81803
81804    if (!instance.getWrapperElement) {
81805      throw "Invalid CodeMirror object given";
81806    }
81807
81808    this.codeMirror = instance;
81809  };
81810
81811  codeMirrorEditor.prototype.getValue = function() {
81812    return this.codeMirror.getValue();
81813  };
81814
81815  codeMirrorEditor.prototype.insertValue = function(val) {
81816    this.codeMirror.replaceSelection(val);
81817  };
81818
81819  codeMirrorEditor.prototype.setValue = function(val) {
81820    var cursor = this.codeMirror.getCursor();
81821    this.codeMirror.setValue(val);
81822    this.codeMirror.setCursor(cursor);
81823  };
81824
81825  /**
81826   * Attach InlineAttachment to CodeMirror
81827   *
81828   * @param {CodeMirror} codeMirror
81829   */
81830  codeMirrorEditor.attach = function(codeMirror, options) {
81831
81832    options = options || {};
81833
81834    var editor = new codeMirrorEditor(codeMirror),
81835      inlineattach = new inlineAttachment(options, editor),
81836      el = codeMirror.getWrapperElement();
81837
81838    el.addEventListener('paste', function(e) {
81839      inlineattach.onPaste(e);
81840    }, false);
81841
81842    codeMirror.setOption('onDragEvent', function(data, e) {
81843      if (e.type === "drop") {
81844        e.stopPropagation();
81845        e.preventDefault();
81846        return inlineattach.onDrop(e);
81847      }
81848    });
81849  };
81850
81851  var codeMirrorEditor4 = function(instance) {
81852    codeMirrorEditor.call(this, instance);
81853  };
81854
81855  codeMirrorEditor4.attach = function(codeMirror, options) {
81856
81857    options = options || {};
81858
81859    var editor = new codeMirrorEditor(codeMirror),
81860      inlineattach = new inlineAttachment(options, editor),
81861      el = codeMirror.getWrapperElement();
81862
81863    el.addEventListener('paste', function(e) {
81864      inlineattach.onPaste(e);
81865    }, false);
81866
81867    codeMirror.on('drop', function(data, e) {
81868      if (inlineattach.onDrop(e)) {
81869        e.stopPropagation();
81870        e.preventDefault();
81871        return true;
81872      } else {
81873        return false;
81874      }
81875    });
81876  };
81877
81878  inlineAttachment.editors.codemirror4 = codeMirrorEditor4;
81879
81880})();
81881function getInlineAttachmentConfig() {
81882  var inlineAttachmentConfig = {
81883    uploadUrl: "/pictures_simplemde",
81884    extraHeaders: {
81885      "X-CSRF-Token": $.rails.csrfToken ? $.rails.csrfToken() : undefined
81886    },
81887    allowedTypes: ['*'],
81888    onFileUploadResponse: function(xhr) {
81889      var result = JSON.parse(xhr.responseText);
81890      const acceptedImageTypes = ['image/gif', 'image/jpeg', 'image/png', 'image/gif'];
81891
81892      if (!result["uploaded"]) {
81893        alert("File invalid");
81894        return false;
81895      }
81896
81897      const url = result["url"];
81898      const fileType = result["content_type"];
81899
81900      if (acceptedImageTypes.includes(fileType)) {
81901        this.settings.urlText = "![file]({filename})";
81902      } else {
81903        this.settings.urlText = "[ダウンロード]({filename})";
81904      }
81905
81906      if (result && url) {
81907        var newValue;
81908        if (typeof this.settings.urlText === "function") {
81909          newValue = this.settings.urlText.call(this, url, result);
81910        } else {
81911          newValue = this.settings.urlText.replace(this.filenameTag, url);
81912        }
81913        var text = this.editor.getValue().replace(this.lastValue, newValue);
81914        this.editor.setValue(text);
81915        this.settings.onFileUploaded.call(this, url);
81916      }
81917      return false;
81918    }
81919  };
81920
81921  return inlineAttachmentConfig;
81922}
81923
81924function initSimpleMdeWithEl(element, onSave, onChange = undefined) {
81925  const toolbar = [
81926    "bold",
81927    // "italic",
81928    // "heading",
81929    // "|",
81930    "code",
81931    "quote",
81932    "unordered-list",
81933    "ordered-list",
81934    // "|",
81935    "link",
81936    "image",
81937    // "table",
81938    // "|",
81939    "preview",
81940    // "guide",
81941    // "|" // Separator
81942  ];
81943
81944  var simplemde = new SimpleMDE({
81945    element: element,
81946    spellChecker: false,
81947    toolbar: toolbar
81948  });
81949  window.simplemde = simplemde;
81950
81951  // Store SimpleMDE instance in element data
81952  $(element).data('simplemde', simplemde);
81953
81954  inlineAttachment.editors.codemirror4.attach(
81955    simplemde.codemirror,
81956    getInlineAttachmentConfig()
81957  );
81958
81959  const codemirror = simplemde.codemirror;
81960  // https://github.com/sparksuite/simplemde-markdown-editor/issues/710
81961  if (onSave != undefined) {
81962    // get shortcuts list
81963    const keys = codemirror.getOption("extraKeys");
81964    // add own's ...
81965    keys["Ctrl-S"] = onSave;
81966    keys["Cmd-S"] = onSave;
81967    // update shortcuts list
81968    codemirror.setOption("extraKeys", keys);
81969  }
81970
81971  if (onChange != undefined) {
81972    codemirror.on('change', function() {
81973      var rawText = simplemde.value();
81974      var renderedHTML = simplemde.options.previewRender(rawText);
81975      onChange(renderedHTML, rawText);
81976    })
81977  }
81978
81979  // Add emoji picker button to toolbar
81980  if (typeof window.addEmojiPickerToSimpleMDE === "function") {
81981    window.addEmojiPickerToSimpleMDE(simplemde);
81982  }
81983
81984  // Add in-editor text search button to toolbar
81985  if (typeof window.addSearchToSimpleMDE === "function") {
81986    window.addSearchToSimpleMDE(simplemde);
81987  }
81988}
81989
81990function initSimpleMde() {
81991  $(".simple-mde-editor").each(function(index, element) {
81992    initSimpleMdeWithEl(element);
81993  });
81994}
81995
81996function addSimpleMdebyClass(className, onSave, onChange = undefined) {
81997  $(className).each(function(index, element) {
81998    if (element.className.includes("simplemde-completed")) {
81999      return
82000    }
82001    initSimpleMdeWithEl(element, onSave, function(renderedHTML, rawText) {
82002      if (onChange) {
82003        onChange(renderedHTML, rawText, element)
82004      }
82005    });
82006    $(element).addClass("simplemde-completed");
82007  });
82008}
82009
82010function initSimpleMdePreview() {
82011  $(".simple-mde-editor-preview").each(function(index, element) {
82012    var simplemde = new SimpleMDE({
82013      element: element,
82014      toolbar: false,
82015      status: false,
82016      spellChecker: false
82017    });
82018
82019    simplemde.togglePreview();
82020  });
82021}
82022
82023$(document).ready(function() {
82024  initSimpleMde();
82025});
82026// Emoji Picker for SimpleMDE - Slack-style emoji picker
82027// This module adds an emoji picker button to the SimpleMDE toolbar
82028
82029(function() {
82030  "use strict";
82031
82032  // Emoji data organized by category
82033  var EMOJI_CATEGORIES = {
82034    "😀 Smileys": [
82035      "😀", "😃", "😄", "😁", "😆", "😅", "🤣", "😂", "🙂", "🙃",
82036      "😉", "😊", "😇", "🥰", "😍", "🤩", "😘", "😗", "😚", "😙",
82037      "🥲", "😋", "😛", "😜", "🤪", "😝", "🤑", "🤗", "🤭", "🤫",
82038      "🤔", "🤐", "🤨", "😐", "😑", "😶", "😏", "😒", "🙄", "😬",
82039      "🤥", "😌", "😔", "😪", "🤤", "😴", "😷", "🤒", "🤕", "🤢",
82040      "🤮", "🤧", "🥵", "🥶", "🥴", "😵", "🤯", "🤠", "🥳", "🥸",
82041      "😎", "🤓", "🧐", "😕", "😟", "🙁", "☹️", "😮", "😯", "😲",
82042      "😳", "🥺", "🥹", "😦", "😧", "😨", "😰", "😥", "😢", "😭",
82043      "😱", "😖", "😣", "😞", "😓", "😩", "😫", "🥱", "😤", "😡",
82044      "😠", "🤬", "😈", "👿", "💀", "☠️", "💩", "🤡", "👹", "👺",
82045      "👻", "👽", "👾", "🤖", "😺", "😸", "😹", "😻", "😼", "😽",
82046      "🙀", "😿", "😾"
82047    ],
82048    "✋ Hands": [
82049      "👋", "🤚", "🖐", "✋", "🖖", "🫱", "🫲", "🫳", "🫴", "👌",
82050      "🤌", "🤏", "✌️", "🤞", "🫰", "🤟", "🤘", "🤙", "👈", "👉",
82051      "👆", "🖕", "👇", "☝️", "🫵", "👍", "👎", "✊", "👊", "🤛",
82052      "🤜", "👏", "🙌", "🫶", "👐", "🤲", "🤝", "🙏", "✍️", "💅",
82053      "🤳", "💪", "🦾", "🦿", "🦵", "🦶", "👂", "🦻", "👃", "👀",
82054      "👁️", "👅", "👄", "💋", "🧠", "🦷", "🦴"
82055    ],
82056    "🙇 People": [
82057      "👶", "🧒", "👦", "👧", "🧑", "👱", "👨", "🧔", "👩", "🧓",
82058      "👴", "👵", "👲", "👳", "👳‍♂️", "👳‍♀️", "🧕", "👮", "👮‍♂️", "👮‍♀️",
82059      "👷", "👷‍♂️", "👷‍♀️", "💂", "💂‍♂️", "💂‍♀️", "🕵️", "🕵️‍♂️", "🕵️‍♀️",
82060      "👩‍⚕️", "👨‍⚕️", "👩‍🌾", "👨‍🌾", "👩‍🍳", "👨‍🍳", "👩‍🎓", "👨‍🎓",
82061      "👩‍🎤", "👨‍🎤", "👩‍🏫", "👨‍🏫", "👩‍🏭", "👨‍🏭", "👩‍💻", "👨‍💻",
82062      "👩‍💼", "👨‍💼", "👩‍🔧", "👨‍🔧", "👩‍🔬", "👨‍🔬", "👩‍🎨", "👨‍🎨",
82063      "👩‍🚒", "👨‍🚒", "👩‍✈️", "👨‍✈️", "👩‍🚀", "👨‍🚀", "👩‍⚖️", "👨‍⚖️",
82064      "🤴", "👸", "🦸", "🦸‍♂️", "🦸‍♀️", "🦹", "🦹‍♂️", "🦹‍♀️",
82065      "🧙", "🧙‍♂️", "🧙‍♀️", "🧚", "🧛", "🧜", "🧝", "🧞", "🧟",
82066      "🙇", "🙇‍♂️", "🙇‍♀️", "💁", "💁‍♂️", "💁‍♀️", "🙆", "🙆‍♂️", "🙆‍♀️",
82067      "🙅", "🙅‍♂️", "🙅‍♀️", "🤷", "🤷‍♂️", "🤷‍♀️", "🙋", "🙋‍♂️", "🙋‍♀️",
82068      "🤦", "🤦‍♂️", "🤦‍♀️", "🙎", "🙎‍♂️", "🙎‍♀️", "🙍", "🙍‍♂️", "🙍‍♀️",
82069      "💇", "💇‍♂️", "💇‍♀️", "💆", "💆‍♂️", "💆‍♀️", "🧖", "🧖‍♂️", "🧖‍♀️",
82070      "🏃", "🏃‍♂️", "🏃‍♀️", "🚶", "🚶‍♂️", "🚶‍♀️", "🧍", "🧍‍♂️", "🧍‍♀️",
82071      "🧎", "🧎‍♂️", "🧎‍♀️", "💃", "🕺", "🕴️", "👯", "👯‍♂️", "👯‍♀️",
82072      "👫", "👬", "👭", "💏", "💑", "👪", "👨‍👩‍👦", "👨‍👩‍👧",
82073      "👨‍👩‍👧‍👦", "👨‍👩‍👦‍👦", "👨‍👩‍👧‍👧"
82074    ],
82075    "💼 Office": [
82076      "📈", "📉", "📊", "💻", "🖥️", "🖨️", "⌨️", "🖱️", "🖲️", "💽",
82077      "💾", "💿", "📀", "📁", "📂", "🗂️", "📌", "📍", "📎", "🖇️",
82078      "📏", "📐", "✂️", "🗃️", "🗄️", "📆", "📅", "🗒️", "🗓️", "📇",
82079      "📋", "📒", "📓", "📔", "📕", "📖", "📗", "📘", "📙", "📚",
82080      "📝", "✏️", "🖊️", "🖋️", "✒️", "📧", "📨", "📩", "📤", "📥",
82081      "📦", "📫", "📪", "📬", "📭", "🏷️", "💰", "💴", "💵", "💶",
82082      "💷", "💳", "🧾", "💹", "🔖"
82083    ],
82084    "🏢 Places": [
82085      "🏠", "🏡", "🏢", "🏣", "🏤", "🏥", "🏦", "🏨", "🏩", "🏪",
82086      "🏫", "🏬", "🏭", "🏯", "🏰", "💒", "🗼", "🗽", "⛪", "🕌",
82087      "🛕", "🕍", "⛩️", "🕋", "⛲", "⛺", "🌁", "🌃", "🏙️", "🌄",
82088      "🌅", "🌆", "🌇", "🌉", "🗻", "🏔️", "⛰️", "🌋", "🗾", "🏕️",
82089      "🏖️", "🏜️", "🏝️", "🏞️", "🗿", "🎠", "🛝", "🎡", "🎢", "💈"
82090    ],
82091    "🚗 Transport": [
82092      "🚗", "🚕", "🚙", "🚌", "🚎", "🏎️", "🚓", "🚑", "🚒", "🚐",
82093      "🛻", "🚚", "🚛", "🚜", "🏍️", "🛵", "🚲", "🛴", "🛺", "🚔",
82094      "🚍", "🚘", "🚖", "🛞", "🚡", "🚠", "🚟", "🚃", "🚋", "🚞",
82095      "🚝", "🚄", "🚅", "🚈", "🚂", "🚆", "🚇", "🚊", "🚉", "🛸",
82096      "✈️", "🛫", "🛬", "🛩️", "💺", "🚀", "🚁", "🛶", "⛵", "🚤",
82097      "🛥️", "🛳️", "⛴️", "🚢", "⚓", "🛟", "🚏", "🚦", "🚥", "⛽"
82098    ],
82099    "🐶 Animals": [
82100      "🐶", "🐕", "🦮", "🐕‍🦺", "🐩", "🐺", "🦊", "🦝", "🐱", "🐈",
82101      "🐈‍⬛", "🦁", "🐯", "🐅", "🐆", "🐴", "🐎", "🦄", "🦓", "🐮",
82102      "🐂", "🐃", "🐄", "🐷", "🐖", "🐗", "🐽", "🐏", "🐑", "🐐",
82103      "🐪", "🐫", "🦙", "🦒", "🐘", "🦣", "🦏", "🦛", "🐭", "🐁",
82104      "🐀", "🐹", "🐰", "🐇", "🐿️", "🦫", "🦔", "🦇", "🐻", "🐻‍❄️",
82105      "🐨", "🐼", "🦥", "🦦", "🦨", "🦘", "🦡", "🐾", "🦃", "🐔",
82106      "🐓", "🐣", "🐤", "🐥", "🐦", "🐧", "🕊️", "🦅", "🦆", "🦢",
82107      "🦉", "🦤", "🪶", "🦩", "🦜", "🐸", "🐊", "🐢", "🦎", "🐍",
82108      "🐉", "🦕", "🦖", "🐳", "🐋", "🐬", "🦭", "🐟", "🐠", "🐡",
82109      "🦈", "🐙", "🐚", "🪸", "🐌", "🦋", "🐛", "🐜", "🐝", "🪲",
82110      "🐞", "🦗", "🪳", "🕷️", "🕸️", "🦂", "🦟", "🪰", "🪱", "🦠"
82111    ],
82112    "🍔 Food": [
82113      "🍔", "🍟", "🍕", "🌭", "🥪", "🌮", "🌯", "🫔", "🥙", "🧆",
82114      "🥚", "🍳", "🥘", "🍲", "🫕", "🥣", "🥗", "🍿", "🧈", "🧂",
82115      "🥫", "🍜", "🍝", "🍣", "🍱", "🥟", "🦪", "🍤", "🍙", "🍚",
82116      "🍘", "🍥", "🥠", "🥮", "🍢", "🍡", "🍧", "🍨", "🍦", "🥧",
82117      "🧁", "🍰", "🎂", "🍮", "🍭", "🍬", "🍫", "🍿", "🍩", "🍪",
82118      "🍞", "🥐", "🥖", "🫓", "🥨", "🥯", "🧇", "🥞", "🫛", "☕",
82119      "🍵", "🧃", "🥤", "🧋", "🍶", "🍺", "🍻", "🥂", "🍷", "🥃",
82120      "🍸", "🍹", "🧉", "🍾", "🫗", "🥛", "🍼"
82121    ],
82122    "🌿 Plants": [
82123      "🌴", "🌲", "🌳", "🌵", "🎋", "🎍", "🌾", "🌿", "☘️", "🍀",
82124      "🍁", "🍂", "🍃", "🌸", "💮", "🏵️", "🌹", "🥀", "🌺", "🌻",
82125      "🌼", "🌷", "🌱", "🪴", "🪹", "🪺", "🍄", "🪨", "🪵", "🎄"
82126    ],
82127    "🍎 Fruits": [
82128      "🍇", "🍈", "🍉", "🍊", "🍋", "🍌", "🍍", "🥭", "🍎", "🍏",
82129      "🍐", "🍑", "🍒", "🍓", "🫐", "🥝", "🥥", "🍅", "🫒", "🥑",
82130      "🍆", "🥔", "🥕", "🌽", "🌶️", "🫑", "🥒", "🥬", "🥦", "🧄",
82131      "🧅", "🍠", "🫘", "🥜", "🌰", "🫚", "🫛"
82132    ],
82133    "⚽ Sports": [
82134      "⚽", "🏀", "🏈", "⚾", "🥎", "🎾", "🏐", "🏉", "🥏", "🎱",
82135      "🏓", "🏸", "🏒", "🏑", "🥍", "🏏", "🪃", "🥅", "⛳", "🪁",
82136      "🏹", "🎣", "🤿", "🥊", "🥋", "🎽", "🛹", "🛼", "🛷", "⛸️",
82137      "🥇", "🥈", "🥉", "🏅", "🎖️", "🏆",
82138      "🧗", "🧗‍♂️", "🧗‍♀️", "🤸", "🤸‍♂️", "🤸‍♀️",
82139      "🏌️", "🏌️‍♂️", "🏌️‍♀️", "🏄", "🏄‍♂️", "🏄‍♀️",
82140      "🏊", "🏊‍♂️", "🏊‍♀️", "🏋️", "🏋️‍♂️", "🏋️‍♀️",
82141      "🚴", "🚴‍♂️", "🚴‍♀️", "🚵", "🚵‍♂️", "🚵‍♀️",
82142      "🤼", "🤽", "🤾", "🤺", "🧘", "🤹"
82143    ],
82144    "🌍 Earth & Sky": [
82145      "🌍", "🌎", "🌏", "🌐", "🗺️", "🧭", "🌑", "🌒", "🌓", "🌔",
82146      "🌕", "🌖", "🌗", "🌘", "🌙", "🌚", "🌛", "🌜", "🌝", "🌞",
82147      "⭐", "🌟", "✨", "💫", "☀️", "🌤️", "⛅", "🌥️", "🌦️", "☁️"
82148    ],
82149    "🌈 Weather": [
82150      "🌈", "🌧️", "⛈️", "🌩️", "🌨️", "☔", "☂️", "🌂", "⛄", "☃️",
82151      "❄️", "🌬️", "💨", "🌪️", "🌫️", "🔥", "💧", "🌊", "⚡", "🌡️"
82152    ],
82153    "👕 Clothing": [
82154      "👚", "👕", "👖", "🧣", "🧤", "🧥", "🧦", "👗", "👘", "🥻",
82155      "🩱", "🩲", "🩳", "👙", "👔", "🎩", "🧢", "👒", "🎓", "⛑️",
82156      "👑", "💍", "👜", "👛", "👝", "🎒", "🧳", "👞", "👟", "🥾",
82157      "🥿", "👠", "👡", "🩰", "👢", "👓", "🕶️", "🥽", "💄", "💎"
82158    ],
82159    "🎵 Audio/Video": [
82160      "🎥", "📽️", "🎞️", "📹", "📺", "📷", "📸", "📻", "🎙️", "🎚️",
82161      "🎛️", "🎵", "🎶", "🎤", "🎧", "🎹", "🪗", "🥁", "🪘", "🎷",
82162      "🎺", "🎸", "🪕", "🎻", "🔔", "🔕", "📢", "📣", "🔊", "🔉",
82163      "🔈", "🔇"
82164    ],
82165    "🎉 Celebration": [
82166      "🎁", "🎀", "🎗️", "🎃", "🎄", "🎆", "🎇", "🧨", "🎈", "🎉",
82167      "🎊", "🎋", "🎍", "🎎", "🎏", "🎐", "🎑", "🎓", "🎂", "🍰",
82168      "🧧", "🪅", "🪆", "🪩", "🎯", "🎮", "🎰", "🎲", "🧩", "🪀"
82169    ],
82170    "🎭 Entertainment": [
82171      "🎨", "🖼️", "🎪", "🎭", "🎡", "🎢", "🎠", "🛝", "🎬", "🎤",
82172      "🎧", "🎼", "🎹", "🥁", "🎷", "🎺", "🎸", "🪕", "🎻", "🎲",
82173      "♟️", "🎯", "🎳", "🎮", "🕹️", "🧸", "🪄", "🎴", "🀄", "🃏"
82174    ],
82175    "❤️ Symbols": [
82176      "❤️", "🧡", "💛", "💚", "💙", "💜", "🖤", "🤍", "🤎", "💔",
82177      "❣️", "💕", "💞", "💓", "💗", "💖", "💘", "💝", "💟", "☮️",
82178      "✅", "❌", "❓", "❗", "‼️", "⁉️", "💯", "🔴", "🟠", "🟡",
82179      "🟢", "🔵", "🟣", "⚫", "⚪", "🟤", "🔶", "🔷", "🔸", "🔹",
82180      "▪️", "▫️", "◾", "◽", "◼️", "◻️", "⬛", "⬜", "🔲", "🔳",
82181      "⬆️", "➡️", "⬇️", "⬅️", "↩️", "↪️", "🔄", "🔃", "🔀", "🔁",
82182      "🔂", "▶️", "⏩", "⏭️", "⏯️", "◀️", "⏪", "⏮️", "⏸️", "⏹️",
82183      "⏺️", "⏏️", "♈", "♉", "♊", "♋", "♌", "♍", "♎", "♏",
82184      "♐", "♑", "♒", "♓", "⛎", "🔀", "🔁", "🔂", "🆔", "⚛️",
82185      "☢️", "☣️", "📴", "📳", "🈶", "🈚", "🈸", "🈺", "🈷️", "🆚"
82186    ]
82187  };
82188
82189  // Build a flat searchable list with keywords
82190  var EMOJI_SEARCH_DATA = [];
82191  (function buildSearchData() {
82192    var categoryKeywords = {
82193      "😀 Smileys": ["smile", "face", "laugh", "cry", "angry", "sad", "happy", "wink", "cool", "sick", "顔", "笑", "泣", "怒"],
82194      "✋ Hands": ["hand", "gesture", "thumbs", "clap", "wave", "point", "fist", "pray", "muscle", "手", "拍手"],
82195      "🙇 People": ["person", "man", "woman", "boy", "girl", "baby", "family", "bow", "ok", "no", "shrug", "raise", "facepalm", "run", "walk", "dance", "worker", "doctor", "teacher", "人", "家族", "お辞儀"],
82196      "💼 Office": ["office", "computer", "document", "chart", "pen", "book", "mail", "money", "calendar", "ä
82196»•事", "オフィス", "書類"],
82197      "🏢 Places": ["place", "building", "house", "church", "castle", "mountain", "tent", "city", "場所", "建物", "家"],
82198      "� Transport": ["car", "bus", "train", "plane", "ship", "rocket", "bike", "taxi", "車", "電車", "飛行機"],
82199      "🐶 Animals": ["animal", "dog", "cat", "bird", "fish", "bug", "dinosaur", "monkey", "bear", "動物", "犬", "猫"],
82200      "🍔 Food": ["food", "burger", "pizza", "sushi", "rice", "cake", "cookie", "drink", "coffee", "beer", "食べ物", "飲み物"],
82201      "🌿 Plants": ["plant", "tree", "flower", "leaf", "grass", "cactus", "mushroom", "植物", "花", "木"],
82202      "🍎 Fruits": ["fruit", "apple", "banana", "grape", "orange", "strawberry", "vegetable", "果物", "野菜"],
82203      "⚽ Sports": ["sport", "ball", "game", "medal", "trophy", "swim", "climb", "bike", "yoga", "スポーツ"],
82204      "🌍 Earth & Sky": ["earth", "globe", "moon", "star", "sun", "sky", "planet", "地球", "月", "星"],
82205      "� Weather": ["weather", "rain", "snow", "wind", "fire", "water", "rainbow", "thunder", "天気", "雨", "雪"],
82206      "👕 Clothing": ["clothes", "shirt", "dress", "hat", "shoe", "bag", "glasses", "ring", "crown", "服", "靴", "帽子"],
82207      "🎵 Audio/Video": ["music", "video", "camera", "speaker", "guitar", "drum", "piano", "音楽", "動画"],
82208      "🎉 Celebration": ["party", "gift", "balloon", "cake", "christmas", "halloween", "firework", "パーティー", "プレゼント"],
82209      "🎭 Entertainment": ["art", "circus", "game", "toy", "magic", "chess", "dice", "エンタメ", "ゲーム"],
82210      "❤️ Symbols": ["heart", "love", "check", "cross", "arrow", "circle", "square", "symbol", "ハート", "記号"]
82211    };
82212
82213    Object.keys(EMOJI_CATEGORIES).forEach(function(catName) {
82214      var keywords = categoryKeywords[catName] || [];
82215      EMOJI_CATEGORIES[catName].forEach(function(emoji) {
82216        EMOJI_SEARCH_DATA.push({
82217          emoji: emoji,
82218          category: catName,
82219          keywords: keywords
82220        });
82221      });
82222    });
82223  })();
82224
82225  // Detect if current page is admin
82226  function isAdminPage() {
82227    return window.location.pathname.indexOf("/admin") === 0;
82228  }
82229
82230  // Create emoji picker popup element
82231  function createEmojiPickerElement() {
82232    var maxHeight = isAdminPage() ? "240px" : "420px";
82233    var picker = document.createElement("div");
82234    picker.className = "emoji-picker-popup";
82235    var pickerWidth = isAdminPage() ? "50%" : (window.innerWidth > 768 ? "50%" : "100%");
82236    picker.style.cssText = "display:none; position:absolute; bottom:calc(100% + 8px); right:0; width:" + pickerWidth + "; max-height:" + maxHeight + "; background:#fff; border:1px solid #e1e4e8; border-radius:8px; box-shadow:0 8px 30px rgba(0,0,0,0.12),0 2px 8px rgba(0,0,0,0.06); z-index:10000; overflow:hidden; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;";
82237
82238    // Header with search
82239    var header = document.createElement("div");
82240    header.className = "emoji-picker-header";
82241    header.style.cssText = "padding:10px 12px 8px; border-bottom:1px solid #f0f0f0; background:#fff;";
82242
82243    var searchInput = document.createElement("input");
82244    searchInput.type = "text";
82245    searchInput.className = "emoji-picker-search";
82246    searchInput.placeholder = "絵文字を検索...";
82247    header.appendChild(searchInput);
82248    picker.appendChild(header);
82249
82250    // Category tabs
82251    var tabsContainer = document.createElement("div");
82252    tabsContainer.className = "emoji-picker-tabs";
82253    tabsContainer.style.cssText = "display:flex; padding:4px 8px; border-bottom:1px solid #f0f0f0; gap:2px; overflow-x:auto; background:#fff;";
82254
82255    var categoryNames = Object.keys(EMOJI_CATEGORIES);
82256    categoryNames.forEach(function(catName, index) {
82257      var tab = document.createElement("button");
82258      tab.type = "button";
82259      tab.className = "emoji-picker-tab" + (index === 0 ? " active" : "");
82260      tab.textContent = catName.split(" ")[0]; // Just the emoji icon
82261      tab.title = catName;
82262      tab.setAttribute("data-category", catName);
82263      tab.addEventListener("click", function(e) {
82264        e.preventDefault();
82265        e.stopPropagation();
82266        switchCategory(picker, catName);
82267      });
82268      tabsContainer.appendChild(tab);
82269    });
82270    picker.appendChild(tabsContainer);
82271
82272    // Emoji grid container
82273    var gridMaxHeight = isAdminPage() ? "120px" : "280px";
82274    var gridContainer = document.createElement("div");
82275    gridContainer.className = "emoji-picker-grid-container";
82276    gridContainer.style.cssText = "flex:1; overflow-y:auto; padding:8px; max-height:" + gridMaxHeight + "; background:#fff;";
82277
82278    // Search results section (hidden by default)
82279    var searchSection = document.createElement("div");
82280    searchSection.className = "emoji-picker-section emoji-picker-search-results";
82281    searchSection.style.display = "none";
82282    var searchGrid = document.createElement("div");
82283    searchGrid.className = "emoji-picker-grid";
82284    searchSection.appendChild(searchGrid);
82285
82286    var noResults = document.createElement("div");
82287    noResults.className = "emoji-picker-no-results";
82288    noResults.textContent = "見つかりませんでした";
82289    noResults.style.display = "none";
82290    searchSection.appendChild(noResults);
82291
82292    gridContainer.appendChild(searchSection);
82293
82294    // Category sections
82295    categoryNames.forEach(function(catName, index) {
82296      var section = document.createElement("div");
82297      section.className = "emoji-picker-section emoji-picker-category-section" + (index === 0 ? " active" : "");
82298      section.setAttribute("data-category", catName);
82299
82300      var grid = document.createElement("div");
82301      grid.className = "emoji-picker-grid";
82302
82303      EMOJI_CATEGORIES[catName].forEach(function(emoji) {
82304        var btn = document.createElement("button");
82305        btn.type = "button";
82306        btn.className = "emoji-picker-emoji";
82307        btn.textContent = emoji;
82308        btn.title = emoji;
82309        btn.addEventListener("click", function(e) {
82310          e.preventDefault();
82311          e.stopPropagation();
82312          if (picker._onSelect) {
82313            picker._onSelect(emoji);
82314          }
82315        });
82316        grid.appendChild(btn);
82317      });
82318
82319      section.appendChild(grid);
82320      gridContainer.appendChild(section);
82321    });
82322    picker.appendChild(gridContainer);
82323
82324    // Search functionality
82325    searchInput.addEventListener("input", function() {
82326      var query = this.value.toLowerCase().trim();
82327
82328      if (query === "") {
82329        // Hide search results, show category sections
82330        searchSection.style.display = "none";
82331        picker.querySelectorAll(".emoji-picker-category-section").forEach(function(section) {
82332          section.classList.remove("active");
82333        });
82334        switchCategory(picker, categoryNames[0]);
82335        return;
82336      }
82337
82338      // Show search results, hide category sections
82339      picker.querySelectorAll(".emoji-picker-category-section").forEach(function(section) {
82340        section.classList.remove("active");
82341      });
82342      searchSection.style.display = "block";
82343
82344      // Clear previous search results
82345      searchGrid.innerHTML = "";
82346
82347      // Filter emojis by query
82348      var matches = EMOJI_SEARCH_DATA.filter(function(item) {
82349        // Match against emoji character itself
82350        if (item.emoji.indexOf(query) !== -1) return true;
82351        // Match against category name
82352        if (item.category.toLowerCase().indexOf(query) !== -1) return true;
82353        // Match against keywords
82354        return item.keywords.some(function(kw) {
82355          return kw.toLowerCase().indexOf(query) !== -1;
82356        });
82357      });
82358
82359      if (matches.length === 0) {
82360        noResults.style.display = "block";
82361      } else {
82362        noResults.style.display = "none";
82363        matches.forEach(function(item) {
82364          var btn = document.createElement("button");
82365          btn.type = "button";
82366          btn.className = "emoji-picker-emoji";
82367          btn.textContent = item.emoji;
82368          btn.title = item.emoji;
82369          btn.addEventListener("click", function(e) {
82370            e.preventDefault();
82371            e.stopPropagation();
82372            if (picker._onSelect) {
82373              picker._onSelect(item.emoji);
82374            }
82375          });
82376          searchGrid.appendChild(btn);
82377        });
82378      }
82379
82380      // Deactivate all category tabs
82381      picker.querySelectorAll(".emoji-picker-tab").forEach(function(tab) {
82382        tab.classList.remove("active");
82383      });
82384    });
82385
82386    // Prevent clicks inside picker from closing it
82387    picker.addEventListener("click", function(e) {
82388      e.stopPropagation();
82389    });
82390
82391    return picker;
82392  }
82393
82394  function switchCategory(picker, categoryName) {
82395    // Hide search results
82396    var searchSection = picker.querySelector(".emoji-picker-search-results");
82397    if (searchSection) searchSection.style.display = "none";
82398
82399    // Update tabs
82400    picker.querySelectorAll(".emoji-picker-tab").forEach(function(tab) {
82401      tab.classList.toggle("active", tab.getAttribute("data-category") === categoryName);
82402    });
82403
82404    // Update sections
82405    picker.querySelectorAll(".emoji-picker-category-section").forEach(function(section) {
82406      section.classList.toggle("active", section.getAttribute("data-category") === categoryName);
82407    });
82408  }
82409
82410  // Add emoji button to SimpleMDE toolbar
82411  window.addEmojiPickerToSimpleMDE = function(simplemde) {
82412    if (!simplemde || !simplemde.codemirror) return;
82413
82414    var toolbarEl = simplemde.gui.toolbar;
82415    if (!toolbarEl) return;
82416
82417    // Check if already added
82418    if (toolbarEl.querySelector(".emoji-toolbar-btn")) return;
82419
82420    // Find the editor container (parent of toolbar)
82421    var editorContainer = toolbarEl.parentNode;
82422    if (!editorContainer) return;
82423    editorContainer.style.position = "relative";
82424
82425    // Create emoji toolbar button
82426    var emojiBtn = document.createElement("button");
82427    emojiBtn.type = "button";
82428    emojiBtn.className = "emoji-toolbar-btn";
82429    emojiBtn.title = "絵文字を挿入";
82430    emojiBtn.innerHTML = "😀";
82431    emojiBtn.tabIndex = -1;
82432    emojiBtn.style.cssText = "background:none; border:none; cursor:pointer; font-size:18px; padding:4px 8px; border-radius:4px; line-height:1; vertical-align:middle;";
82433
82434    // Create a simple wrapper for the button in toolbar
82435    var btnWrapper = document.createElement("div");
82436    btnWrapper.style.cssText = "display:inline-block; vertical-align:middle;";
82437    btnWrapper.appendChild(emojiBtn);
82438
82439    // Create picker - append to editor container so it aligns with the editor
82440    var picker = createEmojiPickerElement();
82441    picker._onSelect = function(emoji) {
82442      var cm = simplemde.codemirror;
82443      var cursor = cm.getCursor();
82444      cm.replaceRange(emoji, cursor);
82445      cm.focus();
82446      picker.style.display = "none";
82447    };
82448
82449    // Position picker: absolute, aligned to editor, width matches editor
82450    var pickerMaxHeight = isAdminPage() ? "240px" : "420px";
82451    var editorPickerWidth = isAdminPage() ? "50%" : (window.innerWidth > 768 ? "50%" : "100%");
82452    picker.style.cssText = "display:none; position:absolute; top:auto; bottom:auto; left:0; width:" + editorPickerWidth + "; max-width:100%; max-height:" + pickerMaxHeight + "; background:#ffffff; border:1px solid #ddd; border-radius:8px; box-shadow:0 8px 24px rgba(0,0,0,0.15); z-index:10000; overflow:hidden; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif; box-sizing:border-box;";
82453
82454    editorContainer.appendChild(picker);
82455
82456    // Add separator and button to toolbar
82457    var separator = document.createElement("i");
82458    separator.className = "separator";
82459    separator.style.cssText = "border-left:1px solid #d9d9d9; display:inline-block; width:0; font-size:0; margin:0 6px; vertical-align:middle; height:24px;";
82460
82461    toolbarEl.appendChild(separator);
82462    toolbarEl.appendChild(btnWrapper);
82463
82464    // Position picker above toolbar when opened
82465    function positionPicker() {
82466      var toolbarRect = toolbarEl.getBoundingClientRect();
82467      var containerRect = editorContainer.getBoundingClientRect();
82468      // Place picker right above the toolbar
82469      var topOffset = toolbarRect.top - containerRect.top - picker.offsetHeight - 4;
82470      picker.style.top = topOffset + "px";
82471    }
82472
82473    // Toggle picker on click
82474    emojiBtn.addEventListener("click", function(e) {
82475      e.preventDefault();
82476      e.stopPropagation();
82477      var isHidden = picker.style.display === "none" || picker.style.display === "";
82478      // Close all other pickers first
82479      document.querySelectorAll(".emoji-picker-popup").forEach(function(p) {
82480        p.style.display = "none";
82481      });
82482      if (isHidden) {
82483        picker.style.display = "flex";
82484        picker.style.flexDirection = "column";
82485        positionPicker();
82486      } else {
82487        picker.style.display = "none";
82488      }
82489    });
82490
82491    // Close picker when clicking outside
82492    document.addEventListener("click", function(e) {
82493      if (!btnWrapper.contains(e.target) && !picker.contains(e.target)) {
82494        picker.style.display = "none";
82495      }
82496    });
82497  };
82498})();
82499
82500// Emoji Picker for plain textarea elements
82501// Adds emoji picker button next to textarea fields that have the 'emoji-enabled' class
82502
82503(function() {
82504  "use strict";
82505
82506  // Reuse the same emoji data from the main emoji picker
82507  // This script depends on emoji_picker.js being loaded first
82508
82509  window.addEmojiPickerToTextarea = function(textareaEl) {
82510    if (!textareaEl) return;
82511
82512    // Check if already added
82513    if (textareaEl.parentNode.querySelector(".emoji-textarea-btn")) return;
82514
82515    // Create a wrapper if the textarea parent is not positioned
82516    var wrapper = textareaEl.parentNode;
82517
82518    // Create emoji button
82519    var emojiBtn = document.createElement("button");
82520    emojiBtn.type = "button";
82521    emojiBtn.className = "emoji-textarea-btn emoji-toolbar-btn";
82522    emojiBtn.title = "絵文字を挿入";
82523    emojiBtn.innerHTML = "😀";
82524
82525    // Create picker wrapper
82526    var pickerWrapper = document.createElement("div");
82527    pickerWrapper.className = "emoji-picker-wrapper emoji-textarea-wrapper";
82528
82529    pickerWrapper.appendChild(emojiBtn);
82530    wrapper.appendChild(pickerWrapper);
82531  };
82532
82533  // Auto-initialize for textareas with emoji-enabled class
82534  $(document).ready(function() {
82535    $("textarea.emoji-enabled").each(function() {
82536      window.addEmojiPickerToTextarea(this);
82537    });
82538  });
82539})();
82540/*jslint newcap: true */
82541/*global inlineAttachment: false */
82542(function() {
82543  'use strict';
82544
82545  inlineAttachment.editors.input = {
82546    Editor: function(instance) {
82547
82548      var input = instance;
82549
82550      return {
82551        getValue: function() {
82552          return input.value;
82553        },
82554        insertValue: function(val) {
82555          inlineAttachment.util.insertTextAtCursor(input, val);
82556        },
82557        setValue: function(val) {
82558          input.value = val;
82559        }
82560      };
82561    },
82562    attachToInput: function(input, options) {
82563      options = options || {};
82564
82565      var editor = new inlineAttachment.editors.input.Editor(input),
82566        inlineattach = new inlineAttachment(options, editor);
82567
82568      input.addEventListener('paste', function(e) {
82569        inlineattach.onPaste(e);
82570      }, false);
82571      input.addEventListener('drop', function(e) {
82572        e.stopPropagation();
82573        e.preventDefault();
82574        inlineattach.onDrop(e);
82575      }, false);
82576      input.addEventListener('dragenter', function(e) {
82577        e.stopPropagation();
82578        e.preventDefault();
82579      }, false);
82580      input.addEventListener('dragover', function(e) {
82581        e.stopPropagation();
82582        e.preventDefault();
82583      }, false);
82584    }
82585  };
82586
82587})();
82588/*jslint newcap: true */
82589/*global inlineAttachment: false, jQuery: false */
82590/**
82591 * jQuery plugin for inline attach
82592 *
82593 * @param {document} document
82594 * @param {window} window
82595 * @param {jQuery} $
82596 */
82597(function(document, window, $) {
82598  'use strict';
82599
82600  inlineAttachment.editors.jquery = {};
82601
82602  /**
82603   * Creates a new editor using jQuery
82604   */
82605  var editor = function(instance) {
82606
82607    var $this = $(instance);
82608
82609    return {
82610      getValue: function() {
82611        return $this.val();
82612      },
82613      insertValue: function(val) {
82614        inlineAttachment.util.insertTextAtCursor($this[0], val);
82615      },
82616      setValue: function(val) {
82617        $this.val(val);
82618      }
82619    };
82620  };
82621
82622  $.fn.inlineattachment = function(options) {
82623
82624    var set = $(this);
82625
82626    set.each(function() {
82627
82628      var $this = $(this),
82629        ed = new editor($this),
82630        inlineattach = new inlineAttachment(options, ed);
82631
82632      $this.bind({
82633        'paste': function(e) {
82634          inlineattach.onPaste(e.originalEvent);
82635        },
82636        'drop': function(e) {
82637          e.stopPropagation();
82638          e.preventDefault();
82639          inlineattach.onDrop(e.originalEvent);
82640        },
82641        'dragenter dragover': function(e) {
82642          e.stopPropagation();
82643          e.preventDefault();
82644        }
82645      });
82646    });
82647
82648    return this;
82649  };
82650
82651  inlineAttachment.editors.jquery.Editor = editor;
82652
82653})(document, window, jQuery);
82654// Text search for SimpleMDE editors.
82655//
82656// CodeMirror only renders the lines currently in the viewport, so the browser's
82657// own find (Ctrl+F / Cmd+F) cannot match text further down the document. This
82658// adds an in-editor search bar instead. See issue #6215.
82659//
82660// The CodeMirror build bundled inside simplemde.min.js (5.15.2) ships without
82661// the search/searchcursor/dialog addons, so this uses core APIs only.
82662(function() {
82663  var MAX_MATCHES = 2000;
82664  var DEBOUNCE_MS = 150;
82665
82666  function escapeRegExp(value) {
82667    return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
82668  }
82669
82670  function findMatches(cm, query) {
82671    var matches = [];
82672    if (!query) return matches;
82673
82674    var text = cm.getValue();
82675    var regexp = new RegExp(escapeRegExp(query), "gi");
82676    var match;
82677
82678    while ((match = regexp.exec(text)) !== null && matches.length < MAX_MATCHES) {
82679      matches.push({
82680        from: cm.posFromIndex(match.index),
82681        to: cm.posFromIndex(match.index + match[0].length)
82682      });
82683    }
82684
82685    return matches;
82686  }
82687
82688  function buildBar() {
82689    var bar = document.createElement("div");
82690    bar.className = "simplemde-search-bar";
82691    bar.innerHTML =
82692      '<input type="text" class="simplemde-search-input" placeholder="エディタ内を検索">' +
82693      '<span class="simplemde-search-count"></span>' +
82694      '<button type="button" class="simplemde-search-prev" title="前の結果 (Shift+Enter)">&#9650;</button>' +
82695      '<button type="button" class="simplemde-search-next" title="次の結果 (Enter)">&#9660;</button>' +
82696      '<button type="button" class="simplemde-search-close" title="閉じる (Esc)">&#10005;</button>';
82697    return bar;
82698  }
82699
82700  window.addSearchToSimpleMDE = function(simplemde) {
82701    if (!simplemde || !simplemde.codemirror) return;
82702
82703    var toolbarEl = simplemde.gui.toolbar;
82704    if (!toolbarEl || toolbarEl.querySelector(".simplemde-search-btn")) return;
82705
82706    var cm = simplemde.codemirror;
82707    var wrapper = cm.getWrapperElement();
82708    if (!wrapper || !wrapper.parentNode) return;
82709
82710    var bar = buildBar();
82711    wrapper.parentNode.insertBefore(bar, wrapper);
82712
82713    var input = bar.querySelector(".simplemde-search-input");
82714    var counter = bar.querySelector(".simplemde-search-count");
82715    var marks = [];
82716    var currentMark = null;
82717    var matches = [];
82718    var currentIndex = -1;
82719    var debounceId = null;
82720
82721    function clearMarks() {
82722      marks.forEach(function(mark) { mark.clear(); });
82723      marks = [];
82724      if (currentMark) {
82725        currentMark.clear();
82726        currentMark = null;
82727      }
82728    }
82729
82730    function renderCounter() {
82731      if (!input.value) {
82732        counter.textContent = "";
82733      } else if (matches.length === 0) {
82734        counter.textContent = "0 / 0";
82735      } else {
82736        counter.textContent = (currentIndex + 1) + " / " + matches.length;
82737      }
82738    }
82739
82740    function highlightCurrent() {
82741      if (currentMark) {
82742        currentMark.clear();
82743        currentMark = null;
82744      }
82745      if (currentIndex < 0 || !matches[currentIndex]) return;
82746
82747      var match = matches[currentIndex];
82748      currentMark = cm.markText(match.from, match.to, {
82749        className: "simplemde-search-match-current"
82750      });
82751      cm.setSelection(match.from, match.to);
82752      cm.scrollIntoView({ from: match.from, to: match.to }, 80);
82753    }
82754
82755    function runSearch(keepPosition) {
82756      var previous = currentIndex;
82757      clearMarks();
82758      matches = findMatches(cm, input.value);
82759
82760      matches.forEach(function(match) {
82761        marks.push(cm.markText(match.from, match.to, {
82762          className: "simplemde-search-match"
82763        }));
82764      });
82765
82766      if (matches.length === 0) {
82767        currentIndex = -1;
82768      } else if (keepPosition && previous >= 0) {
82769        currentIndex = Math.min(previous, matches.length - 1);
82770      } else {
82771        currentIndex = 0;
82772      }
82773
82774      highlightCurrent();
82775      renderCounter();
82776    }
82777
82778    function step(offset) {
82779      if (matches.length === 0) return;
82780      currentIndex = (currentIndex + offset + matches.length) % matches.length;
82781      highlightCurrent();
82782      renderCounter();
82783    }
82784
82785    function open() {
82786      bar.classList.add("is-open");
82787      var selected = cm.getSelection();
82788      if (selected && selected.indexOf("\n") === -1) {
82789        input.value = selected;
82790        runSearch(false);
82791      }
82792      input.focus();
82793      input.select();
82794    }
82795
82796    function close() {
82797      bar.classList.remove("is-open");
82798      clearMarks();
82799      matches = [];
82800      currentIndex = -1;
82801      renderCounter();
82802      cm.focus();
82803    }
82804
82805    function scheduleSearch() {
82806      if (debounceId) clearTimeout(debounceId);
82807      debounceId = setTimeout(function() {
82808        debounceId = null;
82809        runSearch(false);
82810      }, DEBOUNCE_MS);
82811    }
82812
82813    input.addEventListener("input", scheduleSearch);
82814
82815    input.addEventListener("keydown", function(event) {
82816      if (event.key === "Enter") {
82817        event.preventDefault();
82818        if (debounceId) {
82819          clearTimeout(debounceId);
82820          debounceId = null;
82821          runSearch(false);
82822        } else {
82823          step(event.shiftKey ? -1 : 1);
82824        }
82825      } else if (event.key === "Escape") {
82826        event.preventDefault();
82827        close();
82828      }
82829    });
82830
82831    bar.querySelector(".simplemde-search-prev").addEventListener("click", function() { step(-1); });
82832    bar.querySelector(".simplemde-search-next").addEventListener("click", function() { step(1); });
82833    bar.querySelector(".simplemde-search-close").addEventListener("click", close);
82834
82835    // Marks drift once the document changes, so refresh them while the bar is open.
82836    cm.on("change", function() {
82837      if (bar.classList.contains("is-open") && input.value) {
82838        if (debounceId) clearTimeout(debounceId);
82839        debounceId = setTimeout(function() {
82840          debounceId = null;
82841          runSearch(true);
82842        }, DEBOUNCE_MS);
82843      }
82844    });
82845
82846    // Only swallow the browser shortcut while the cursor is inside the editor.
82847    var keys = cm.getOption("extraKeys") || {};
82848    keys["Ctrl-F"] = open;
82849    keys["Cmd-F"] = open;
82850    cm.setOption("extraKeys", keys);
82851
82852    var button = document.createElement("button");
82853    button.type = "button";
82854    button.className = "simplemde-search-btn";
82855    button.title = "エディタ内を検索 (Ctrl+F / Cmd+F)";
82856    button.innerHTML = "&#128269;";
82857    button.tabIndex = -1;
82858    button.addEventListener("click", function() {
82859      if (bar.classList.contains("is-open")) {
82860        close();
82861      } else {
82862        open();
82863      }
82864    });
82865
82866    var buttonWrapper = document.createElement("div");
82867    buttonWrapper.className = "simplemde-search-btn-wrapper";
82868    buttonWrapper.appendChild(button);
82869    toolbarEl.appendChild(buttonWrapper);
82870  };
82871})();
82872(function() {
82873  $(document).ready(function() {
82874    return $(".sortable-table:not(.processed)").each(function(index, table) {
82875      var current_sort, current_sort_direction, sort_url;
82876      $(table).addClass("processed");
82877      sort_url = $(table).data("sortable-url");
82878      current_sort = $(table).data("current-sort").replace("_", "-");
82879      current_sort_direction = $(table).data("current-sort-direction");
82880      return $(this).find("th.sortable").each(function(_, column) {
82881        var column_direction, column_html, column_name, column_sort_url, match;
82882        if (match = $(column).attr("class").match(/sortable-([^\s]+)/)) {
82883          column_name = match[1];
82884          column_direction = $(column).hasClass("asc") ? "asc" : "desc";
82885          if (current_sort === column_name) {
82886            $("<div class = \"caret\">").appendTo(column);
82887            if (current_sort_direction === "asc") {
82888              $(column).addClass("dropup");
82889              column_direction = "desc";
82890            } else {
82891              column_direction = "asc";
82892            }
82893          }
82894          column_html = $(column).html();
82895          column_sort_url = sort_url.match(/\?/) ? sort_url + "&" : sort_url + "?";
82896          column_sort_url += "order=" + (column_name.replace("-", "_")) + "&direction=" + column_direction;
82897          return $(column).html("<a href='" + column_sort_url + "'>" + column_html + "</a>");
82898        }
82899      });
82900    });
82901  });
82902
82903}).call(this);
82904(function() {
82905  var config, observer, update_title;
82906
82907  update_title = function() {
82908    var notify, title;
82909    if ($("title").length === 0) {
82910      return;
82911    }
82912    title = $("title").html().replace(/^(\([0-9]+\))+\s+/, "");
82913    notify = $("span[data-notify-title]").toArray().reduce((function(current, target) {
82914      return current + parseInt($(target).text());
82915    }), 0);
82916    return $("title").html((notify > 0 ? "(" + notify + ") " : "") + title);
82917  };
82918
82919  observer = new MutationObserver(function(mutations) {
82920    return mutations.forEach(function(mutation) {
82921      return update_title();
82922    });
82923  });
82924
82925  config = {
82926    attributes: false,
82927    childList: true,
82928    characterData: true
82929  };
82930
82931  $(document).on('turbolinks:load', function() {
82932    observer.disconnect();
82933    update_title();
82934    return $("span[data-notify-title]").each(function(index, target) {
82935      return observer.observe(target, config);
82936    });
82937  });
82938
82939  window.addEventListener('load', function() {
82940    observer.disconnect();
82941    update_title();
82942    return $("span[data-notify-title]").each(function(index, target) {
82943      return observer.observe(target, config);
82944    });
82945  });
82946
82947}).call(this);
82948
82949$(document).ready(function() {
82950  $('[data-toggle="tooltip"]').tooltip()
82951  $('[data-toggle="tooltip"]').on('click', function() {
82952    if($(this).attr("href")){
82953      $(this).tooltip('hide')
82954    }
82955  })
82956});
82957(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.tus = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
82958"use strict";
82959
82960Object.defineProperty(exports, "__esModule", {
82961  value: true
82962});
82963exports.encode = encode;
82964/* global: window */
82965
82966var _window = window;
82967var btoa = _window.btoa;
82968function encode(data) {
82969  return btoa(unescape(encodeURIComponent(data)));
82970}
82971
82972var isSupported = exports.isSupported = "btoa" in window;
82973
82974},{}],2:[function(_dereq_,module,exports){
82975"use strict";
82976
82977Object.defineProperty(exports, "__esModule", {
82978  value: true
82979});
82980exports.newRequest = newRequest;
82981exports.resolveUrl = resolveUrl;
82982
82983var _resolveUrl = _dereq_("resolve-url");
82984
82985var _resolveUrl2 = _interopRequireDefault(_resolveUrl);
82986
82987function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
82988
82989function newRequest() {
82990  return new window.XMLHttpRequest();
82991} /* global window */
82992
82993
82994function resolveUrl(origin, link) {
82995  return (0, _resolveUrl2.default)(origin, link);
82996}
82997
82998},{"resolve-url":10}],3:[function(_dereq_,module,exports){
82999"use strict";
83000
83001var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
83002
83003Object.defineProperty(exports, "__esModule", {
83004  value: true
83005});
83006exports.getSource = getSource;
83007
83008function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
83009
83010var FileSource = function () {
83011  function FileSource(file) {
83012    _classCallCheck(this, FileSource);
83013
83014    this._file = file;
83015    this.size = file.size;
83016  }
83017
83018  _createClass(FileSource, [{
83019    key: "slice",
83020    value: function slice(start, end) {
83021      return this._file.slice(start, end);
83022    }
83023  }, {
83024    key: "close",
83025    value: function close() {}
83026  }]);
83027
83028  return FileSource;
83029}();
83030
83031function getSource(input) {
83032  // Since we emulate the Blob type in our tests (not all target browsers
83033  // support it), we cannot use `instanceof` for testing whether the input value
83034  // can be handled. Instead, we simply check is the slice() function and the
83035  // size property are available.
83036  if (typeof input.slice === "function" && typeof input.size !== "undefined") {
83037    return new FileSource(input);
83038  }
83039
83040  throw new Error("source object may only be an instance of File or Blob in this environment");
83041}
83042
83043},{}],4:[function(_dereq_,module,exports){
83044"use strict";
83045
83046Object.defineProperty(exports, "__esModule", {
83047  value: true
83048});
83049exports.setItem = setItem;
83050exports.getItem = getItem;
83051exports.removeItem = removeItem;
83052/* global window, localStorage */
83053
83054var hasStorage = false;
83055try {
83056  hasStorage = "localStorage" in window;
83057
83058  // Attempt to store and read entries from the local storage to detect Private
83059  // Mode on Safari on iOS (see #49)
83060  var key = "tusSupport";
83061  localStorage.setItem(key, localStorage.getItem(key));
83062} catch (e) {
83063  // If we try to access localStorage inside a sandboxed iframe, a SecurityError
83064  // is thrown. When in private mode on iOS Safari, a QuotaExceededError is
83065  // thrown (see #49)
83066  if (e.code === e.SECURITY_ERR || e.code === e.QUOTA_EXCEEDED_ERR) {
83067    hasStorage = false;
83068  } else {
83069    throw e;
83070  }
83071}
83072
83073var canStoreURLs = exports.canStoreURLs = hasStorage;
83074
83075function setItem(key, value) {
83076  if (!hasStorage) return;
83077  return localStorage.setItem(key, value);
83078}
83079
83080function getItem(key) {
83081  if (!hasStorage) return;
83082  return localStorage.getItem(key);
83083}
83084
83085function removeItem(key) {
83086  if (!hasStorage) return;
83087  return localStorage.removeItem(key);
83088}
83089
83090},{}],5:[function(_dereq_,module,exports){
83091"use strict";
83092
83093Object.defineProperty(exports, "__esModule", {
83094  value: true
83095});
83096
83097function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
83098
83099function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
83100
83101function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { c
83101onstructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
83102
83103var DetailedError = function (_Error) {
83104  _inherits(DetailedError, _Error);
83105
83106  function DetailedError(error) {
83107    var causingErr = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1];
83108    var xhr = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2];
83109
83110    _classCallCheck(this, DetailedError);
83111
83112    var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(DetailedError).call(this, error.message));
83113
83114    _this.originalRequest = xhr;
83115    _this.causingError = causingErr;
83116
83117    var message = error.message;
83118    if (causingErr != null) {
83119      message += ", caused by " + causingErr.toString();
83120    }
83121    if (xhr != null) {
83122      message += ", originated from request (response code: " + xhr.status + ", response text: " + xhr.responseText + ")";
83123    }
83124    _this.message = message;
83125    return _this;
83126  }
83127
83128  return DetailedError;
83129}(Error);
83130
83131exports.default = DetailedError;
83132
83133},{}],6:[function(_dereq_,module,exports){
83134"use strict";
83135
83136Object.defineProperty(exports, "__esModule", {
83137  value: true
83138});
83139exports.default = fingerprint;
83140/**
83141 * Generate a fingerprint for a file which will be used the store the endpoint
83142 *
83143 * @param {File} file
83144 * @return {String}
83145 */
83146function fingerprint(file, options) {
83147  return ["tus", file.name, file.type, file.size, file.lastModified, options.endpoint].join("-");
83148}
83149
83150},{}],7:[function(_dereq_,module,exports){
83151"use strict";
83152
83153var _upload = _dereq_("./upload");
83154
83155var _upload2 = _interopRequireDefault(_upload);
83156
83157var _storage = _dereq_("./node/storage");
83158
83159function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
83160
83161/* global window */
83162var defaultOptions = _upload2.default.defaultOptions;
83163
83164var isSupported = void 0;
83165
83166if (typeof window !== "undefined") {
83167  // Browser environment using XMLHttpRequest
83168  var _window = window;
83169  var XMLHttpRequest = _window.XMLHttpRequest;
83170  var Blob = _window.Blob;
83171
83172
83173  isSupported = XMLHttpRequest && Blob && typeof Blob.prototype.slice === "function";
83174} else {
83175  // Node.js environment using http module
83176  isSupported = true;
83177}
83178
83179// The usage of the commonjs exporting syntax instead of the new ECMAScript
83180// one is actually inteded and prevents weird behaviour if we are trying to
83181// import this module in another module using Babel.
83182module.exports = {
83183  Upload: _upload2.default,
83184  isSupported: isSupported,
83185  canStoreURLs: _storage.canStoreURLs,
83186  defaultOptions: defaultOptions
83187};
83188
83189},{"./node/storage":4,"./upload":8}],8:[function(_dereq_,module,exports){
83190"use strict";
83191
83192var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /* global window */
83193
83194
83195// We import the files used inside the Node environment which are rewritten
83196// for browsers using the rules defined in the package.json
83197
83198
83199Object.defineProperty(exports, "__esModule", {
83200  value: true
83201});
83202
83203var _fingerprint = _dereq_("./fingerprint");
83204
83205var _fingerprint2 = _interopRequireDefault(_fingerprint);
83206
83207var _error = _dereq_("./error");
83208
83209var _error2 = _interopRequireDefault(_error);
83210
83211var _extend = _dereq_("extend");
83212
83213var _extend2 = _interopRequireDefault(_extend);
83214
83215var _request = _dereq_("./node/request");
83216
83217var _source = _dereq_("./node/source");
83218
83219var _base = _dereq_("./node/base64");
83220
83221var Base64 = _interopRequireWildcard(_base);
83222
83223var _storage = _dereq_("./node/storage");
83224
83225var Storage = _interopRequireWildcard(_storage);
83226
83227function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
83228
83229function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
83230
83231function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
83232
83233var defaultOptions = {
83234  endpoint: null,
83235  fingerprint: _fingerprint2.default,
83236  resume: true,
83237  onProgress: null,
83238  onChunkComplete: null,
83239  onSuccess: null,
83240  onError: null,
83241  headers: {},
83242  chunkSize: Infinity,
83243  withCredentials: false,
83244  uploadUrl: null,
83245  uploadSize: null,
83246  overridePatchMethod: false,
83247  retryDelays: null,
83248  removeFingerprintOnSuccess: false
83249};
83250
83251var Upload = function () {
83252  function Upload(file, options) {
83253    _classCallCheck(this, Upload);
83254
83255    this.options = (0, _extend2.default)(true, {}, defaultOptions, options);
83256
83257    // The underlying File/Blob object
83258    this.file = file;
83259
83260    // The URL against which the file will be uploaded
83261    this.url = null;
83262
83263    // The underlying XHR object for the current PATCH request
83264    this._xhr = null;
83265
83266    // The fingerpinrt for the current file (set after start())
83267    this._fingerprint = null;
83268
83269    // The offset used in the current PATCH request
83270    this._offset = null;
83271
83272    // True if the current PATCH request has been aborted
83273    this._aborted = false;
83274
83275    // The file's size in bytes
83276    this._size = null;
83277
83278    // The Source object which will wrap around the given file and provides us
83279    // with a unified interface for getting its size and slice chunks from its
83280    // content allowing us to easily handle Files, Blobs, Buffers and Streams.
83281    this._source = null;
83282
83283    // The current count of attempts which have been made. Null indicates none.
83284    this._retryAttempt = 0;
83285
83286    // The timeout's ID which is used to delay the next retry
83287    this._retryTimeout = null;
83288
83289    // The offset of the remote upload before the latest attempt was started.
83290    this._offsetBeforeRetry = 0;
83291  }
83292
83293  _createClass(Upload, [{
83294    key: "start",
83295    value: function start() {
83296      var _this = this;
83297
83298      var file = this.file;
83299
83300      if (!file) {
83301        this._emitError(new Error("tus: no file or stream to upload provided"));
83302        return;
83303      }
83304
83305      if (!this.options.endpoint && !this.options.uploadUrl) {
83306        this._emitError(new Error("tus: neither an endpoint or an upload URL is provided"));
83307        return;
83308      }
83309
83310      var source = this._source = (0, _source.getSource)(file, this.options.chunkSize);
83311
83312      // Firstly, check if the caller has supplied a manual upload size or else
83313      // we will use the calculated size by the source object.
83314      if (this.options.uploadSize != null) {
83315        var size = +this.options.uploadSize;
83316        if (isNaN(size)) {
83317          throw new Error("tus: cannot convert `uploadSize` option into a number");
83318        }
83319
83320        this._size = size;
83321      } else {
83322        var size = source.size;
83323
83324        // The size property will be null if we cannot calculate the file's size,
83325        // for example if you handle a stream.
83326        if (size == null) {
83327          throw new Error("tus: cannot automatically derive upload's size from input and must be specified manually using the `uploadSize` option");
83328        }
83329
83330        this._size = size;
83331      }
83332
83333      var retryDelays = this.options.retryDelays;
83334      if (retryDelays != null) {
83335        if (Object.prototype.toString.call(retryDelays) !== "[object Array]") {
83336          throw new Error("tus: the `retryDelays` option must either be an array or null");
83337        } else {
83338          (function () {
83339            var errorCallback = _this.options.onError;
83340            _this.options.onError = function (err) {
83341              // Restore the original error callback which may have been set.
83342              _this.options.onError = errorCallback;
83343
83344              // We will reset the attempt counter if
83345              // - we were already able to connect to the server (offset != null) and
83346              // - we were able to upload a small chunk of data to the server
83347              var shouldResetDelays = _this._offset != null && _this._offset > _this._offsetBeforeRetry;
83348              if (shouldResetDelays) {
83349                _this._retryAttempt = 0;
83350              }
83351
83352              var isOnline = true;
83353              if (typeof window !== "undefined" && "navigator" in window && window.navigator.onLine === false) {
83354                isOnline = false;
83355              }
83356
83357              // We only attempt a retry if
83358              // - we didn't exceed the maxium number of retries, yet, and
83359              // - this error was caused by a request or it's response and
83360              // - the error is not a client error (status 4xx) and
83361              // - the browser does not indicate that we are offline
83362              var shouldRetry = _this._retryAttempt < retryDelays.length && err.originalRequest != null && !inStatusCategory(err.originalRequest.status, 400) && isOnline;
83363
83364              if (!shouldRetry) {
83365                _this._emitError(err);
83366                return;
83367              }
83368
83369              var delay = retryDelays[_this._retryAttempt++];
83370
83371              _this._offsetBeforeRetry = _this._offset;
83372              _this.options.uploadUrl = _this.url;
83373
83374              _this._retryTimeout = setTimeout(function () {
83375                _this.start();
83376              }, delay);
83377            };
83378          })();
83379        }
83380      }
83381
83382      // Reset the aborted flag when the upload is started or else the
83383      // _startUpload will stop before sending a request if the upload has been
83384      // aborted previously.
83385      this._aborted = false;
83386
83387      // The upload had been started previously and we should reuse this URL.
83388      if (this.url != null) {
83389        this._resumeUpload();
83390        return;
83391      }
83392
83393      // A URL has manually been specified, so we try to resume
83394      if (this.options.uploadUrl != null) {
83395        this.url = this.options.uploadUrl;
83396        this._resumeUpload();
83397        return;
83398      }
83399
83400      // Try to find the endpoint for the file in the storage
83401      if (this.options.resume) {
83402        this._fingerprint = this.options.fingerprint(file, this.options);
83403        var resumedUrl = Storage.getItem(this._fingerprint);
83404
83405        if (resumedUrl != null) {
83406          this.url = resumedUrl;
83407          this._resumeUpload();
83408          return;
83409        }
83410      }
83411
83412      // An upload has not started for the file yet, so we start a new one
83413      this._createUpload();
83414    }
83415  }, {
83416    key: "abort",
83417    value: function abort() {
83418      if (this._xhr !== null) {
83419        this._xhr.abort();
83420        this._source.close();
83421        this._aborted = true;
83422      }
83423
83424      if (this._retryTimeout != null) {
83425        clearTimeout(this._retryTimeout);
83426        this._retryTimeout = null;
83427      }
83428    }
83429  }, {
83430    key: "_emitXhrError",
83431    value: function _emitXhrError(xhr, err, causingErr) {
83432      this._emitError(new _error2.default(err, causingErr, xhr));
83433    }
83434  }, {
83435    key: "_emitError",
83436    value: function _emitError(err) {
83437      if (typeof this.options.onError === "function") {
83438        this.options.onError(err);
83439      } else {
83440        throw err;
83441      }
83442    }
83443  }, {
83444    key: "_emitSuccess",
83445    value: function _emitSuccess() {
83446      if (typeof this.options.onSuccess === "function") {
83447        this.options.onSuccess();
83448      }
83449    }
83450
83451    /**
83452     * Publishes notification when data has been sent to the server. This
83453     * data may not have been accepted by the server yet.
83454     * @param  {number} bytesSent  Number of bytes sent to the server.
83455     * @param  {number} bytesTotal Total number of bytes to be sent to the server.
83456     */
83457
83458  }, {
83459    key: "_emitProgress",
83460    value: function _emitProgress(bytesSent, bytesTotal) {
83461      if (typeof this.options.onProgress === "function") {
83462        this.options.onProgress(bytesSent, bytesTotal);
83463      }
83464    }
83465
83466    /**
83467     * Publishes notification when a chunk of data has been sent to the server
83468     * and accepted by the server.
83469     * @param  {number} chunkSize  Size of the chunk that was accepted by the
83470     *                             server.
83471     * @param  {number} bytesAccepted Total number of bytes that have been
83472     *                                accepted by the server.
83473     * @param  {number} bytesTotal Total number of bytes to be sent to the server.
83474     */
83475
83476  }, {
83477    key: "_emitChunkComplete",
83478    value: function _emitChunkComplete(chunkSize, bytesAccepted, bytesTotal) {
83479      if (typeof this.options.onChunkComplete === "function") {
83480        this.options.onChunkComplete(chunkSize, bytesAccepted, bytesTotal);
83481      }
83482    }
83483
83484    /**
83485     * Set the headers used in the request and the withCredentials property
83486     * as defined in the options
83487     *
83488     * @param {XMLHttpRequest} xhr
83489     */
83490
83491  }, {
83492    key: "_setupXHR",
83493    value: function _setupXHR(xhr) {
83494      this._xhr = xhr;
83495
83496      xhr.setRequestHeader("Tus-Resumable", "1.0.0");
83497      var headers = this.options.headers;
83498
83499      for (var name in headers) {
83500        xhr.setRequestHeader(name, headers[name]);
83501      }
83502
83503      xhr.withCredentials = this.options.withCredentials;
83504    }
83505
83506    /**
83507     * Create a new upload using the creation extension by sending a POST
83508     * request to the endpoint. After successful creation the file will be
83509     * uploaded
83510     *
83511     * @api private
83512     */
83513
83514  }, {
83515    key: "_createUpload",
83516    value: function _createUpload() {
83517      var _this2 = this;
83518
83519      if (!this.options.endpoint) {
83520        this._emitError(new Error("tus: unable to create upload because no endpoint is provided"));
83521        return;
83522      }
83523
83524      var xhr = (0, _request.newRequest)();
83525      xhr.open("HEAD", this.options.endpoint, true);
83526
83527      xhr.onload = function () {
83528        if (!inStatusCategory(xhr.status, 200)) {
83529          _this2._emitXhrError(xhr, new Error("tus: unexpected response while creating upload"));
83530          return;
83531        }
83532
83533        // var location = xhr.getResponseHeader("Location");
83534        // if (location == null) {
83535        //   _this2._emitXhrError(xhr, new Error("tus: invalid or missing Location header"));
83536        //   return;
83537        // }
83538
83539        _this2.url = (0, _request.resolveUrl)(_this2.options.endpoint, location);
83540
83541        if (_this2._size === 0) {
83542          // Nothing to upload and file was successfully created
83543          _this2._emitSuccess();
83544          _this2._source.close();
83545          return;
83546        }
83547
83548        if (_this2.options.resume) {
83549          Storage.setItem(_this2._fingerprint, _this2.url);
83550        }
83551
83552        _this2._offset = 0;
83553        _this2._startUpload();
83554      };
83555
83556      xhr.onerror = function (err) {
83557        _this2._emitXhrError(xhr, new Error("tus: failed to create upload"), err);
83558      };
83559
83560      this._setupXHR(xhr);
83561      xhr.setRequestHeader("Upload-Length", this._size);
83562
83563      // Add metadata if values have been added
83564      var metadata = encodeMetadata(this.options.metadata);
83565      if (metadata !== "") {
83566        xhr.setRequestHeader("Upload-Metadata", metadata);
83567      }
83568
83569      xhr.send(null);
83570    }
83571
83572    /*
83573     * Try to resume an existing upload. First a HEAD request will be sent
83574     * to retrieve the offset. If the request fails a new upload will be
83575     * created. In the case of a successful response the file will be uploaded.
83576     *
83577     * @api private
83578     */
83579
83580  }, {
83581    key: "_resumeUpload",
83582    value: function _resumeUpload() {
83583      var _this3 = this;
83584
83585      var xhr = (0, _request.newRequest)();
83586      xhr.open("HEAD", this.url, true);
83587
83588      xhr.onload = function () {
83589        if (!inStatusCategory(xhr.status, 200)) {
83590          if (_this3.options.resume && inStatusCategory(xhr.status, 400)) {
83591            // Remove stored fingerprint and corresponding endpoint,
83592            // on client errors since the file can not be found
83593            Storage.removeItem(_this3._fingerprint);
83594          }
83595
83596          // If the upload is locked (indicated by the 423 Locked status code), we
83597          // emit an error instead of directly starting a new upload. This way the
83598          // retry logic can catch the error and will retry the upload. An upload
83599          // is usually locked for a short period of time and will be available
83600          // afterwards.
83601          if (xhr.status === 423) {
83602            _this3._emitXhrError(xhr, new Error("tus: upload is currently locked; retry later"));
83603            return;
83604          }
83605
83606          if (!_this3.options.endpoint) {
83607            // Don't attempt to create a new upload if no endpoint is provided.
83608            _this3._emitXhrError(xhr, new Error("tus: unable to resume upload (new upload cannot be created without an endpoint)"));
83609            return;
83610          }
83611
83612          // Try to create a new upload
83613          _this3.url = null;
83614          _this3._createUpload();
83615          return;
83616        }
83617
83618        var offset = parseInt(xhr.getResponseHeader("Upload-Offset"), 10);
83619        if (isNaN(offset)) {
83620          _this3._emitXhrError(xhr, new Error("tus: invalid or missing offset value"));
83621          return;
83622        }
83623
83624        var length = parseInt(xhr.getResponseHeader("Upload-Length"), 10);
83625        if (isNaN(length)) {
83626          _this3._emitXhrError(xhr, new Error("tus: invalid or missing length value"));
83627          return;
83628        }
83629
83630        // Upload has already been completed and we do not need to send additional
83631        // data to the server
83632        if (offset === length) {
83633          _this3._emitProgress(length, length);
83634          _this3._emitSuccess();
83635          return;
83636        }
83637
83638        _this3._offset = offset;
83639        _this3._startUpload();
83640      };
83641
83642      xhr.onerror = function (err) {
83643        _this3._emitXhrError(xhr, new Error("tus: failed to resume upload"), err);
83644      };
83645
83646      this._setupXHR(xhr);
83647      xhr.send(null);
83648    }
83649
83650    /**
83651     * Start uploading the file using PATCH requests. The file will be divided
83652     * into chunks as specified in the chunkSize option. During the upload
83653     * the onProgress event handler may be invoked multiple times.
83654     *
83655     * @api private
83656     */
83657
83658  }, {
83659    key: "_startUpload",
83660    value: function _startUpload() {
83661      var _this4 = this;
83662
83663      // If the upload has been aborted, we will not send the next PATCH request.
83664      // This is important if the abort method was called during a callback, such
83665      // as onChunkComplete or onProgress.
83666      if (this._aborted) {
83667        return;
83668      }
83669
83670      var xhr = (0, _request.newRequest)();
83671
83672      // Some browser and servers may not support the PATCH method. For those
83673      // cases, you can tell tus-js-client to use a POST request with the
83674      // X-HTTP-Method-Override header for simulating a PATCH request.
83675      if (this.options.overridePatchMethod) {
83676        xhr.open("POST", this.url, true);
83677        xhr.setRequestHeader("X-HTTP-Method-Override", "PATCH");
83678      } else {
83679        xhr.open("PATCH", this.url, true);
83680      }
83681
83682      xhr.onload = function () {
83683        if (!inStatusCategory(xhr.status, 200)) {
83684          _this4._emitXhrError(xhr, new Error("tus: unexpected response while uploading chunk"));
83685          return;
83686        }
83687
83688        var offset = parseInt(xhr.getResponseHeader("Upload-Offset"), 10);
83689        if (isNaN(offset)) {
83690          _this4._emitXhrError(xhr, new Error("tus: invalid or missing offset value"));
83691          return;
83692        }
83693
83694        _this4._emitProgress(offset, _this4._size);
83695        _this4._emitChunkComplete(offset - _this4._offset, offset, _this4._size);
83696
83697        _this4._offset = offset;
83698
83699        if (offset == _this4._size) {
83700          if (_this4.options.removeFingerprintOnSuccess && _this4.options.resume) {
83701            // Remove stored fingerprint and corresponding endpoint. This causes
83702            // new upload of the same file must be treated as a different file.
83703            Storage.removeItem(_this4._fingerprint);
83704          }
83705
83706          // Yay, finally done :)
83707          _this4._emitSuccess();
83708          _this4._source.close();
83709          return;
83710        }
83711
83712        _this4._startUpload();
83713      };
83714
83715      xhr.onerror = function (err) {
83716        // Don't emit an error if the upload was aborted manually
83717        if (_this4._aborted) {
83718          return;
83719        }
83720
83721        _this4._emitXhrError(xhr, new Error("tus: failed to upload chunk at offset " + _this4._offset), err);
83722      };
83723
83724      // Test support for progress events before attaching an event listener
83725      if ("upload" in xhr) {
83726        xhr.upload.onprogress = function (e) {
83727          if (!e.lengthComputable) {
83728            return;
83729          }
83730
83731          _this4._emitProgress(start + e.loaded, _this4._size);
83732        };
83733      }
83734
83735      this._setupXHR(xhr);
83736
83737      xhr.setRequestHeader("Upload-Offset", this._offset);
83738      xhr.setRequestHeader("Content-Type", "application/offset+octet-stream");
83739
83740      var start = this._offset;
83741      var end = this._offset + this.options.chunkSize;
83742
83743      // The specified chunkSize may be Infinity or the calcluated end position
83744      // may exceed the file's size. In both cases, we limit the end position to
83745      // the input's total size for simpler calculations and correctness.
83746      if (end === Infinity || end > this._size) {
83747        end = this._size;
83748      }
83749
83750      xhr.send(this._source.slice(start, end));
83751
83752      // Emit an progress event when a new chunk begins being uploaded.
83753      this._emitProgress(this._offset, this._size);
83754    }
83755  }]);
83756
83757  return Upload;
83758}();
83759
83760function encodeMetadata(metadata) {
83761  if (!Base64.isSupported) {
83762    return "";
83763  }
83764
83765  var encoded = [];
83766
83767  for (var key in metadata) {
83768    encoded.push(key + " " + Base64.encode(metadata[key]));
83769  }
83770
83771  return encoded.join(",");
83772}
83773
83774/**
83775 * Checks whether a given status is in the range of the expected category.
83776 * For example, only a status between 200 and 299 will satisfy the category 200.
83777 *
83778 * @api private
83779 */
83780function inStatusCategory(status, category) {
83781  return status >= category && status < category + 100;
83782}
83783
83784Upload.defaultOptions = defaultOptions;
83785
83786exports.default = Upload;
83787
83788},{"./error":5,"./fingerprint":6,"./node/base64":1,"./node/request":2,"./node/source":3,"./node/storage":4,"extend":9}],9:[function(_dereq_,module,exports){
83789'use strict';
83790
83791var hasOwn = Object.prototype.hasOwnProperty;
83792var toStr = Object.prototype.toString;
83793
83794var isArray = function isArray(arr) {
83795	if (typeof Array.isArray === 'function') {
83796		return Array.isArray(arr);
83797	}
83798
83799	return toStr.call(arr) === '[object Array]';
83800};
83801
83802var isPlainObject = function isPlainObject(obj) {
83803	if (!obj || toStr.call(obj) !== '[object Object]') {
83804		return false;
83805	}
83806
83807	var hasOwnConstructor = hasOwn.call(obj, 'constructor');
83808	var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf');
83809	// Not own constructor property must be Object
83810	if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) {
83811		return false;
83812	}
83813
83814	// Own properties are enumerated firstly, so to speed up,
83815	// if last one is own, then all properties are own.
83816	var key;
83817	for (key in obj) {/**/}
83818
83819	return typeof key === 'undefined' || hasOwn.call(obj, key);
83820};
83821
83822module.exports = function extend() {
83823	var options, name, src, copy, copyIsArray, clone,
83824		target = arguments[0],
83825		i = 1,
83826		length = arguments.length,
83827		deep = false;
83828
83829	// Handle a deep copy situation
83830	if (typeof target === 'boolean') {
83831		deep = target;
83832		target = arguments[1] || {};
83833		// skip the boolean and the target
83834		i = 2;
83835	} else if ((typeof target !== 'object' && typeof target !== 'function') || target == null) {
83836		target = {};
83837	}
83838
83839	for (; i < length; ++i) {
83840		options = arguments[i];
83841		// Only deal with non-null/undefined values
83842		if (options != null) {
83843			// Extend the base object
83844			for (name in options) {
83845				src = target[name];
83846				copy = options[name];
83847
83848				// Prevent never-ending loop
83849				if (target !== copy) {
83850					// Recurse if we're merging plain objects or arrays
83851					if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) {
83852						if (copyIsArray) {
83853							copyIsArray = false;
83854							clone = src && isArray(src) ? src : [];
83855						} else {
83856							clone = src && isPlainObject(src) ? src : {};
83857						}
83858
83859						// Never move original objects, clone them
83860						target[name] = extend(deep, clone, copy);
83861
83862					// Don't bring in undefined values
83863					} else if (typeof copy !== 'undefined') {
83864						target[name] = copy;
83865					}
83866				}
83867			}
83868		}
83869	}
83870
83871	// Return the modified object
83872	return target;
83873};
83874
83875
83876},{}],10:[function(_dereq_,module,exports){
83877// Copyright 2014 Simon Lydell
83878// X11 (“MIT”) Licensed. (See LICENSE.)
83879
83880void (function(root, factory) {
83881  if (typeof define === "function" && define.amd) {
83882    define(factory)
83883  } else if (typeof exports === "object") {
83884    module.exports = factory()
83885  } else {
83886    root.resolveUrl = factory()
83887  }
83888}(this, function() {
83889
83890  function resolveUrl(/* ...urls */) {
83891    var numUrls = arguments.length
83892
83893    if (numUrls === 0) {
83894      throw new Error("resolveUrl requires at least one argument; got none.")
83895    }
83896
83897    var base = document.createElement("base")
83898    base.href = arguments[0]
83899
83900    if (numUrls === 1) {
83901      return base.href
83902    }
83903
83904    var head = document.getElementsByTagName("head")[0]
83905    head.insertBefore(base, head.firstChild)
83906
83907    var a = document.createElement("a")
83908    var resolved
83909
83910    for (var index = 1; index < numUrls; index++) {
83911      a.href = arguments[index]
83912      resolved = a.href
83913      base.href = resolved
83914    }
83915
83916    head.removeChild(base)
83917
83918    return resolved
83919  }
83920
83921  return resolveUrl
83922
83923}));
83924
83925},{}]},{},[7])(7)
83926});
83927$(document).ready(function() {
83928  $('.material-upload-btn').on('click', function(e) {
83929    e.preventDefault()
83930    this.parentElement.getElementsByClassName("material-upload")[0].disabled = false
83931    this.parentElement.getElementsByClassName("material-upload")[0].click()
83932  })
83933});
83934function upload_image_files(files, school_id, imagable_type, imagable_id, relative_image_path, successCall, errorCall) {
83935  files.forEach((file) => {
83936    const uploadParams = {
83937      upload_image: {
83938        image_file_size: file.size,
83939        image_content_type: file.type,
83940        relative_path: (relative_image_path || "") + file.name
83941      },
83942      imagable: {
83943        type: imagable_type,
83944        id: imagable_id
83945      },
83946    }
83947
83948    $.ajax({
83949      url: `/admin/schools/${school_id}/images`,
83950      type: 'POST',
83951      data: uploadParams,
83952      success: function(data) {
83953        // データの作成
83954        const formData = new FormData()
83955        for (let name in data.form)
83956          if (data.form.hasOwnProperty(name)) {
83957            formData.append(name, data.form[name])
83958          }
83959        formData.append('file', file)
83960        formData.set('content-type', file.type)
83961
83962        // S3 Upload
83963        upload_form_data_to_s3(
83964          data.url,
83965          formData,
83966          function() {
83967            if (successCall) {
83968              successCall(file)
83969            }
83970          },
83971          errorCall
83972        )
83973      }
83974    })
83975  })
83976}
83977
83978function upload_form_data_to_s3(url, formData, successCall, errorCall) {
83979  $.ajax({
83980    url: url,
83981    type: 'POST',
83982    data: formData,
83983    processData: false,
83984    contentType: false,
83985    success: function(res) {
83986      if (successCall) {
83987        successCall()
83988      }
83989    },
83990    error: function(err) {
83991      if (errorCall) {
83992        errorCall(err)
83993      }
83994    }
83995  })
83996};
83997$(document).on("click", "#search-filter-btn", function(){
83998  var value = encodeURIComponent($(this).closest("form").find("[name=name]").val())
83999  if ($("#pickup_course").length) { // school design
84000    value = $("#pickup_course [name=name]").val()
84001  }
84002
84003  var from_school_id_ele = $(this).closest("form").find("[name=from_school_id]")
84004  if(from_school_id_ele){
84005    var from_school_id = encodeURIComponent(from_school_id_ele.val())
84006    $.get($(this).data("url")+"&q="+ value + "&from_school_id=" + from_school_id)
84007  } else {
84008    $.get($(this).data("url")+"&q="+value)
84009  }
84010})
84011
84012function showAddModal(elm){
84013  url = $(elm).data("url")+".js?user_id="+$(elm).data("user_id")
84014  $.get(url, function() {
84015    $("#add-to-users").find("[name=name]").attr("placeholder", $(elm).data("placeholder"))
84016    $("#add-to-users").find("#search-filter-btn").attr("data-url", url)
84017    $("#add-to-users").find(".modal-title").text($(elm).data("title"))
84018    $("#add-to-users").modal("show")
84019  })
84020}
84021
84022$(document).on('hidden.bs.modal', '#add-to-users', function () {
84023  // TODO 
84024})
84025
84026$(document).on("keydown", ".filter-search-input", function(event){
84027  if(event.keyCode == 13) {
84028    event.preventDefault();
84029    $("#search-filter-btn").trigger("click");
84030    return false;
84031  }
84032});
84033/*
84034 | Vimeo-Upload: Upload videos to your Vimeo account directly from a
84035 |               browser or a Node.js app
84036 |
84037 |  ╭───╮╭─╮
84038 |  │   ││ │╭─╮╭──┬──┬─╮╭───╮╭───╮
84039 |  │   ││ │├─┤│ ╭╮ ╭╮ ││ ─ ││╭╮ │  ╭────────┬─────────────────────╮
84040 |  ╰╮  ╰╯╭╯│ ││ ││ ││ ││  ─┤│╰╯ │  | UPLOAD │ ▒▒▒▒▒▒▒▒▒▒▒░░░░ %75 |
84041 |   ╰────╯ ╰─╯╰─╯╰─╯╰─╯╰───╯╰───╯  ╰────────┴─────────────────────╯
84042 |
84043 |
84044 | This project was released under Apache 2.0" license.
84045 |
84046 | @link      http://websemantics.ca
84047 | @author    Web Semantics, Inc. Dev Team <[email protected]>
84048 | @author    Adnan M.Sagar, PhD. <[email protected]>
84049 | @credits   Built on cors-upload-sample, https://github.com/googledrive/cors-upload-sample
84050 */
84051
84052;
84053(function(root, factory) {
84054    if (typeof define === 'function' && define.amd) {
84055        define([], function() {
84056            return (root.VimeoUpload = factory())
84057        })
84058    } else if (typeof module === 'object' && module.exports) {
84059        module.exports = factory()
84060    } else {
84061        root.VimeoUpload = factory()
84062    }
84063}(this, function() {
84064
84065    // -------------------------------------------------------------------------
84066    // RetryHandler Class
84067
84068    /**
84069     * Helper for implementing retries with backoff. Initial retry
84070     * delay is 1 second, increasing by 2x (+jitter) for subsequent retries
84071     *
84072     * @constructor
84073     */
84074    var RetryHandler = function() {
84075        this.interval = 1000 // Start at one second
84076        this.maxInterval = 60 * 1000; // Don't wait longer than a minute
84077    }
84078
84079    /**
84080     * Invoke the function after waiting
84081     *
84082     * @param {function} fn Function to invoke
84083     */
84084    RetryHandler.prototype.retry = function(fn) {
84085        setTimeout(fn, this.interval)
84086        this.interval = this.nextInterval_()
84087    }
84088
84089    /**
84090     * Reset the counter (e.g. after successful request)
84091     */
84092    RetryHandler.prototype.reset = function() {
84093        this.interval = 1000
84094    }
84095
84096    /**
84097     * Calculate the next wait time.
84098     * @return {number} Next wait interval, in milliseconds
84099     *
84100     * @private
84101     */
84102    RetryHandler.prototype.nextInterval_ = function() {
84103        var interval = this.interval * 2 + this.getRandomInt_(0, 1000)
84104        return Math.min(interval, this.maxInterval)
84105    }
84106
84107    /**
84108     * Get a random int in the range of min to max. Used to add jitter to wait times.
84109     *
84110     * @param {number} min Lower bounds
84111     * @param {number} max Upper bounds
84112     * @private
84113     */
84114    RetryHandler.prototype.getRandomInt_ = function(min, max) {
84115        return Math.floor(Math.random() * (max - min + 1) + min)
84116    }
84117
84118    // -------------------------------------------------------------------------
84119    // Private data
84120
84121    /* Library defaults, can be changed using the 'defaults' member method,
84122
84123    - api_url (string), vimeo api url
84124    - name (string), default video name
84125    - description (string), default video description
84126    - contentType (string), video content type
84127    - token (string), vimeo api token
84128    - file (object), video file
84129    - metadata (array), data to associate with the video
84130    - upgrade_to_1080 (boolean), set video resolution to high definition
84131    - offset (int),
84132    - chunkSize (int),
84133    - retryHandler (RetryHandler), hanlder class
84134    - onComplete (function), handler for onComplete event
84135    - onProgress (function), handler for onProgress event
84136    - onError (function), handler for onError event
84137
84138    */
84139
84140    var defaults = {
84141        api_url: 'https://api.vimeo.com',
84142        name: 'Default name',
84143        description: 'Default description',
84144        contentType: 'application/octet-stream',
84145        token: null,
84146        upload_url: '',
84147        file: {},
84148        metadata: [],
84149        upgrade_to_1080: false,
84150        offset: 0,
84151        chunkSize: 0,
84152        formData: "",
84153        retryHandler: new RetryHandler(),
84154        vimeo_uri: "",
84155        uploader: null,
84156        onComplete: function() {},
84157        onProgress: function() {},
84158        onError: function() {}
84159    }
84160
84161    /**
84162     * Helper class for resumable uploads using XHR/CORS. Can upload any Blob-like item, whether
84163     * files or in-memory constructs.
84164     *
84165     * @example
84166     * var content = new Blob(["Hello world"], {"type": "text/plain"})
84167     * var uploader = new VimeoUpload({
84168     *   file: content,
84169     *   token: accessToken,
84170     *   onComplete: function(data) { ... }
84171     *   onError: function(data) { ... }
84172     * })
84173     * uploader.upload()
84174     *
84175     * @constructor
84176     * @param {object} options Hash of options
84177     * @param {string} options.token Access token
84178     * @param {blob} options.file Blob-like item to upload
84179     * @param {string} [options.fileId] ID of file if replacing
84180     * @param {object} [options.params] Additional query parameters
84181     * @param {string} [options.contentType] Content-type, if overriding the type of the blob.
84182     * @param {object} [options.metadata] File metadata
84183     * @param {function} [options.onComplete] Callback for when upload is complete
84184     * @param {function} [options.onProgress] Callback for status for the in-progress upload
84185     * @param {function} [options.onError] Callback if upload fails
84186     */
84187    var me = function(opts) {
84188
84189        /* copy user options or use default values */
84190        for (var i in defaults) {
84191            this[i] = (opts[i] !== undefined) ? opts[i] : defaults[i]
84192        }
84193
84194        this.contentType = opts.contentType || this.file.type || defaults.contentType
84195        this.httpMethod = opts.fileId ? 'PUT' : 'POST'
84196
84197        this.videoData = {
84198            name: (opts.name > '') ? opts.name : defaults.name,
84199            description: (opts.description > '') ? opts.description : defaults.description,
84200            'privacy.view': opts.private ? 'nobody' : 'anybody'
84201        }
84202
84203        if (!(this.url = opts.url)) {
84204            var params = opts.params || {} /*  TODO params.uploadType = 'resumable' */
84205            this.url = this.buildUrl_(opts.fileId, params, opts.baseUrl)
84206        }
84207    }
84208
84209    // -------------------------------------------------------------------------
84210    // Public methods
84211
84212    /*
84213      Override class defaults
84214
84215        Parameters:
84216        - opts (object): name value pairs
84217
84218    */
84219
84220    me.prototype.defaults = function(opts) {
84221        return defaults /* TODO $.extend(true, defaults, opts) */
84222    }
84223
84224    /**
84225     * Initiate the upload (Get vimeo ticket number and upload url)
84226     */
84227    me.prototype.upload = function() {
84228        var xhr = new XMLHttpRequest()
84229        xhr.open(this.httpMethod, this.url, true)
84230        xhr.setRequestHeader("X-CSRF-Token", $("meta[name='csrf-token']").attr("content"))
84231        xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest")
84232        xhr.setRequestHeader('Content-Type', 'application/json')
84233        xhr.onload = function(e) {
84234            // get vimeo upload  url, user (for available quote), ticket id and complete url
84235            if (e.target.status < 400) {
84236                var response = JSON.parse(e.target.responseText)
84237                this.formData = response.upload.form
84238                this.url = response.upload.upload_link
84239                this.vimeo_uri = response.uri
84240                this.sendFile_()
84241            } else {
84242                this.onUploadError_(e)
84243            }
84244        }.bind(this)
84245
84246        xhr.onerror = this.onUploadError_.bind(this)
84247        xhr.send(JSON.stringify({
84248            type: 'streaming',
84249            upgrade_to_1080: this.upgrade_to_1080,
84250            size: this.file.size
84251        }))
84252        this._xhr = xhr;
84253    }
84254
84255    me.prototype.cancel = function() {
84256        if (this.uploader) this.uploader.abort();
84257    }
84258
84259    // -------------------------------------------------------------------------
84260    // Private methods
84261
84262    /**
84263     * Send the actual file content.
84264     *
84265     * @private
84266     */
84267    me.prototype.sendFile_ = function() {
84268        var content = this.file
84269        var url = this.url
84270        var onContentUploadError = this.onContentUploadError_
84271        var onContentUploadSuccess = this.onContentUploadSuccess_
84272        var progress = this.onProgress
84273        this.uploader = new tus.Upload(content, {
84274            endpoint: url,
84275            uploadUrl: url,
84276            retryDelays: [0, 1000, 3000, 5000],
84277            metadata: {
84278                filename: content.name,
84279                filetype: content.type
84280            },
84281            onError: onContentUploadError.bind(this),
84282            onProgress: progress,
84283            onSuccess: onContentUploadSuccess.bind(this)
84284        })
84285        this.uploader.start()
84286    }
84287
84288    /**
84289     * Query for the state of the file for resumption.
84290     *
84291     * @private
84292     */
84293    me.prototype.resume_ = function() {
84294        this.uploader._resumeUpload()
84295    }
84296
84297    /**
84298     * Extract the last saved range if available in the request.
84299     *
84300     * @param {XMLHttpRequest} xhr Request object
84301     */
84302    me.prototype.extractRange_ = function(xhr) {
84303        var range = xhr.getResponseHeader('Range')
84304        if (range) {
84305            this.offset = parseInt(range.match(/\d+/g).pop(), 10) + 1
84306        }
84307    }
84308
84309    /**
84310     * The final step is to call vimeo.videos.upload.complete to queue up
84311     * the video for transcoding.
84312     *
84313     * If successful call 'onUpdateVideoData_'
84314     *
84315     * @private
84316     */
84317    me.prototype.complete_ = function(xhr) {
84318        this.onComplete(this)
84319    }
84320
84321    /**
84322     * Update the Video Data and add the metadata to the upload object
84323     *
84324     * @private
84325     * @param {string} [id] Video Id
84326     */
84327    me.prototype.onUpdateVideoData_ = function(video_id) {
84328        var url = this.buildUrl_(video_id, [], defaults.api_url + '/vi
84328deos/')
84329        var httpMethod = 'PATCH'
84330        var xhr = new XMLHttpRequest()
84331
84332        xhr.open(httpMethod, url, true)
84333        xhr.setRequestHeader('Authorization', 'Bearer ' + this.token)
84334        xhr.onload = function(e) {
84335            // add the metadata
84336            this.onGetMetadata_(e, video_id)
84337        }.bind(this)
84338        xhr.send(this.buildQuery_(this.videoData))
84339    }
84340
84341    /**
84342     * Retrieve the metadata from a successful onUpdateVideoData_ response
84343     * This is is useful when uploading unlisted videos as the URI has changed.
84344     *
84345     * If successful call 'onUpdateVideoData_'
84346     *
84347     * @private
84348     * @param {object} e XHR event
84349     * @param {string} [id] Video Id
84350     */
84351    me.prototype.onGetMetadata_ = function(e, video_id) {
84352        // Get the video location (videoId)
84353        if (e.target.status < 400) {
84354            if (e.target.response) {
84355                // add the returned metadata to the metadata array
84356                var meta = JSON.parse(e.target.response)
84357                    // get the new index of the item
84358                var index = this.metadata.push(meta) - 1
84359                    // call the complete method
84360                this.onComplete(video_id, index)
84361            } else {
84362                this.onCompleteError_(e)
84363            }
84364        }
84365    }
84366
84367    /**
84368     * Handle successful responses for uploads. Depending on the context,
84369     * may continue with uploading the next chunk of the file or, if complete,
84370     * invokes vimeo complete service.
84371     *
84372     * @private
84373     * @param {object} e XHR event
84374     */
84375    me.prototype.onContentUploadSuccess_ = function(e) {
84376      this.complete_()
84377    }
84378
84379    /**
84380     * Handles errors for uploads. Either retries or aborts depending
84381     * on the error.
84382     *
84383     * @private
84384     * @param {object} e XHR event
84385     */
84386    me.prototype.onContentUploadError_ = function(e) {
84387        this.retryHandler.retry(this.resume_())
84388    }
84389
84390    /**
84391     * Handles errors for the complete request.
84392     *
84393     * @private
84394     * @param {object} e XHR event
84395     */
84396    me.prototype.onCompleteError_ = function(e) {
84397        this._xhr = null;
84398        this.onError(e.target.response); // TODO - Retries for initial upload
84399    }
84400
84401    /**
84402     * Handles errors for the initial request.
84403     *
84404     * @private
84405     * @param {object} e XHR event
84406     */
84407    me.prototype.onUploadError_ = function(e) {
84408        this._xhr = null;
84409        this.onError(e.target.response); // TODO - Retries for initial upload
84410    }
84411
84412    /**
84413     * Construct a query string from a hash/object
84414     *
84415     * @private
84416     * @param {object} [params] Key/value pairs for query string
84417     * @return {string} query string
84418     */
84419    me.prototype.buildQuery_ = function(params) {
84420        params = params || {}
84421        return Object.keys(params).map(function(key) {
84422            return encodeURIComponent(key) + '=' + encodeURIComponent(params[key])
84423        }).join('&')
84424    }
84425
84426    /**
84427     * Build the drive upload URL
84428     *
84429     * @private
84430     * @param {string} [id] File ID if replacing
84431     * @param {object} [params] Query parameters
84432     * @return {string} URL
84433     */
84434    me.prototype.buildUrl_ = function(id, params, baseUrl) {
84435        var url = baseUrl || this.upload_url
84436        if (id) {
84437            url += id
84438        }
84439        var query = this.buildQuery_(params)
84440        if (query) {
84441            url += '?' + query
84442        }
84443        return url
84444    }
84445
84446    return me
84447}));
84448$(document).on("click", ".remove-video", function () {
84449  if (confirm("本当に削除しますか?")) {
84450    $("#lesson_vimeo_complete_uri").val("destroy")
84451    $("#results").html("")
84452    $("#dropzone").show()
84453    $(".vimeo-url").hide()
84454    window.vimeo_changing = true
84455    return false;
84456  }
84457})
84458
84459function uploadVimeo(files) {
84460  $(".actions input[type='submit']").attr("disabled", true)
84461  var upload_url = $("#browse").data("upload-url");
84462  var check_url = $("#browse").data("check-url");
84463  $("#results").hide()
84464  $("#dropzone").show()
84465  $(".vimeo-url").hide()
84466
84467  window.vimeo_changing = true;
84468
84469  /* Rest the progress bar and show it */
84470  updateProgress(0)
84471  $(".upload-videmo").hide()
84472  $(".progress-container").show()
84473
84474  /* Instantiate Vimeo Uploader */
84475  var vimeo_uploader = new VimeoUpload({
84476    name: "test",
84477    description: "test descript",
84478    private: true,
84479    file: files[0],
84480    upload_url: upload_url,
84481    onError: function (data) {
84482      var errorData;
84483
84484      // Try to parse JSON, fallback to plain text error
84485      try {
84486        errorData = JSON.parse(data);
84487      } catch (e) {
84488        errorData = {
84489          error: 'アップロードに失敗しました。もう一度お試しください。',
84490          limit_reached: false
84491        };
84492      }
84493
84494      // Check if the error is due to vimeo limit reached
84495      if (errorData && errorData.limit_reached) {
84496        // Show persistent error message instead of alert
84497        var errorHtml = '<div class="alert alert-danger alert-dismissible fade show mt-3" role="alert">' +
84498          '<strong>⚠️ エラー</strong><br>' +
84499          errorData.error + '<br>' +
84500          '<small>現在 ' + errorData.current_count + '/' + errorData.limit + ' 本のビデオがアップロードされています。</small>' +
84501          '<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
84502          '</div>';
84503
84504        // Insert error message before the upload area
84505        if ($('#vimeo-limit-error').length) {
84506          $('#vimeo-limit-error').html(errorHtml);
84507        } else {
84508          $('.admin-vimeo-video').prepend('<div id="vimeo-limit-error">' + errorHtml + '</div>');
84509        }
84510      } else {
84511        // Generic error message
84512        var genericErrorHtml = '<div class="alert alert-danger alert-dismissible fade show mt-3" role="alert">' +
84513          '<strong>⚠️ エラー</strong><br>' +
84514          (errorData.error || 'アップロードに失敗しました。もう一度お試しください。') +
84515          '<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
84516          '</div>';
84517
84518        if ($('#vimeo-limit-error').length) {
84519          $('#vimeo-limit-error').html(genericErrorHtml);
84520        } else {
84521          $('.admin-vimeo-video').prepend('<div id="vimeo-limit-error">' + genericErrorHtml + '</div>');
84522        }
84523      }
84524      $(".progress-container").hide()
84525      $("#results").show();
84526      $(".upload-videmo").show();
84527      $(".actions input[type='submit']").attr("disabled", false);
84528    },
84529    onProgress: function (loaded, total) {
84530      updateProgress(loaded / total, loaded, total)
84531    },
84532    onComplete: function (vimeo_uploader) {
84533      $("#lesson_vimeo_complete_uri").val(vimeo_uploader.vimeo_uri)
84534      $("#results").html(vimeo_uploader.file.name + ' (' + formatBytes(vimeo_uploader.file.size) + ') <a href="#" class="remove-video">この動画を削除する</a>')
84535      $(".remove-video").hide()
84536      $("#results").show()
84537      $("#dropzone").hide()
84538      $(".progress-container").hide()
84539      $(".upload-videmo").hide()
84540      $(".actions input[type='submit']").attr("disabled", false)
84541      $("#browse").val("");
84542
84543      // Show sidebar timeline tab and update generate-text-btn
84544      $("#sidebar-timeline-tab-btn").removeClass("d-none");
84545      $("#generate-text-btn").data("has-video", "true");
84546
84547      if ($(".vimeo-url").length) {
84548        $(".vimeo-url").hide()
84549        $(".vimeo-processing").show()
84550
84551        // Start 1-second timer
84552        $(document).trigger('vimeo:processing:start');
84553
84554        var vimeo_id = vimeo_uploader.vimeo_uri.split("/")[2]
84555
84556        $(".refresh-btn").attr("data-url", "https://player.vimeo.com/video/" + vimeo_id + "?h=9f19d6f0ce")
84557        $(".refresh-btn").attr("data-vimeo-id", vimeo_id)
84558
84559        $.ajax({
84560          url: check_url + "?vimeo_id=" + vimeo_id,
84561          method: "GET",
84562        })
84563      }
84564    }
84565  })
84566
84567  vimeo_uploader.upload();
84568}
84569
84570/**
84571 * Called when files are dropped on to the drop target or selected by the browse button.
84572 * For each file, uploads the content to Drive & displays the results when complete.
84573 */
84574function handleFileSelect(evt) {
84575  evt.stopPropagation()
84576  evt.preventDefault()
84577  var files = evt.dataTransfer ? evt.dataTransfer.files : $(this).get(0).files
84578
84579  uploadVimeo(files);
84580}
84581
84582/**
84583 * Dragover handler to set the drop effect.
84584 */
84585function handleDragOver(evt) {
84586  evt.stopPropagation()
84587  evt.preventDefault()
84588  evt.dataTransfer.dropEffect = 'copy'
84589}
84590
84591/**
84592 * Format bytes to human readable size.
84593 */
84594function formatBytes(bytes) {
84595  if (bytes === 0) return '0 B';
84596  var k = 1024;
84597  var sizes = ['B', 'KB', 'MB', 'GB'];
84598  var i = Math.floor(Math.log(bytes) / Math.log(k));
84599  return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
84600}
84601
84602/**
84603 * Update progress bar.
84604 */
84605function updateProgress(progress, loaded, total) {
84606  var pct = parseInt(progress * 100);
84607  var label = pct + '%';
84608  if (loaded !== undefined && total !== undefined) {
84609    label = pct + '% (' + formatBytes(loaded) + ' / ' + formatBytes(total) + ')';
84610    $(".upload-status-label").text("アップロード中...");
84611    $(".upload-size-label").text(formatBytes(loaded) + ' / ' + formatBytes(total));
84612  }
84613  $("#upload-progress-bar").css("width", pct + "%")
84614    .attr("aria-valuenow", pct)
84615  $("#upload-progress-bar").text(label)
84616  $("#dropzone").hide()
84617}
84618
84619$(document).on("change", "#browse", handleFileSelect);
84620
84621$(document).ready(function() {
84622  initialize();
84623});
84624
84625$(function() {
84626  initialize();
84627});
84628
84629function initialize() {
84630  var tag = document.createElement("script");
84631
84632  tag.src = "https://www.youtube.com/iframe_api";
84633  var firstScriptTag = document.getElementsByTagName("script")[0];
84634  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
84635}
84636
84637var player;
84638function onYouTubeIframeAPIReady() {
84639  player = new YT.Player("player", {
84640    height: "360",
84641    width: "640",
84642    videoId: $("#player").data("video-id"),
84643    events: {
84644      "onReady": onPlayerReady,
84645      "onStateChange": onPlayerStateChange,
84646    }
84647  });
84648}
84649
84650// 4. The API will call this function when the video player is ready.
84651function onPlayerReady(event) {
84652  event.target.playVideo();
84653}
84654
84655var done = false;
84656function onPlayerStateChange(event) {
84657  if (event.data == YT.PlayerState.ENDED) {
84658    var next_path = $("#player").data("next-path");
84659    if (next_path) {
84660      window.top.location.href= next_path;
84661    }
84662  }
84663}
84664
84665function stopVideo() {
84666  player.stopVideo();
84667};
84668function cfTogglePublished(checkbox) {
84669  var url = checkbox.dataset.url;
84670  var csrfToken = $('meta[name="csrf-token"]').attr('content');
84671
84672  $.ajax({
84673    url: url,
84674    method: 'PATCH',
84675    headers: { 'X-CSRF-Token': csrfToken },
84676    dataType: 'json',
84677    success: function(data) {
84678      cfShowToast(data.message, 'success');
84679    },
84680    error: function() {
84681      checkbox.checked = !checkbox.checked;
84682      cfShowToast('エラーが発生しました。', 'danger');
84683    }
84684  });
84685}
84686
84687function cfShowToast(message, type) {
84688  var icon = type === 'success' ? 'check_circle' : 'error';
84689  var toast = $(
84690    '<div class="alert alert-' + type + ' alert-dismissible fade show toast-message" role="alert"' +
84691    ' style="position:fixed;top:80px;right:20px;z-index:9999;min-width:300px;box-shadow:0 4px 12px rgba(0,0,0,0.15);">' +
84692    '<div class="d-flex align-items-center">' +
84693    '<i class="material-icons me-2" style="font-size:20px;">' + icon + '</i>' +
84694    '<div class="flex-grow-1">' + message + '</div>' +
84695    '<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
84696    '</div></div>'
84697  );
84698  $('body').append(toast);
84699  setTimeout(function() { toast.fadeOut(400, function() { $(this).remove(); }); }, 3000);
84700};
84701// admin-script.js
84702
84703document.addEventListener('DOMContentLoaded', function() {
84704  // 必要に応じて初期化処理をここに書く
84705});
84706
84707/* 
84708  以下は例示的な関数。実際にはバックエンドと連携して
84709  新規チケット登録やクーポン登録などの処理を行ってください。
84710*/
84711
84712// チケットプラン選択デモ
84713function selectTicketPlan(element) {
84714  document.querySelectorAll('.ticket-card.selected').forEach(el => {
84715    el.classList.remove('selected');
84716  });
84717  element.classList.add('selected');
84718}
84719
84720// 新規チケット登録デモ
84721function registerNewTicket() {
84722  const ticketName = document.getElementById('newTicketName').value;
84723  const ticketPrice = document.getElementById('newTicketPrice').value;
84724  const ticketDesc = document.getElementById('newTicketDesc').value;
84725
84726  // ここでバックエンドにPOSTするなどの処理を想定
84727  alert(`チケット「${ticketName}」を登録しました(価格: ${ticketPrice}, 内容: ${ticketDesc})`);
84728}
84729
84730// 新規クーポン登録デモ
84731function registerNewCoupon() {
84732  const couponCode = document.getElementById('newCouponCode').value;
84733  const discountRate = document.getElementById('newCouponDiscount').value;
84734  // ここでバックエンドにPOSTするなどの処理を想定
84735  alert(`クーポン「${couponCode}」を登録しました(割引率: ${discountRate}%)`);
84736};
84737(function() {
84738
84739
84740}).call(this);
84741(function() {
84742
84743
84744}).call(this);
84745// This [jQuery](https://jquery.com/) plugin implements an `<iframe>`
84746// [transport](https://api.jquery.com/jQuery.ajax/#extending-ajax) so that
84747// `$.ajax()` calls support the uploading of files using standard HTML file
84748// input fields. This is done by switching the exchange from `XMLHttpRequest`
84749// to a hidden `iframe` element containing a form that is submitted.
84750
84751// The [source for the plugin](https://github.com/cmlenz/jquery-iframe-transport)
84752// is available on [Github](https://github.com/) and licensed under the [MIT
84753// license](https://github.com/cmlenz/jquery-iframe-transport/blob/master/LICENSE).
84754
84755// ## Usage
84756
84757// To use this plugin, you simply add an `iframe` option with the value `true`
84758// to the Ajax settings an `$.ajax()` call, and specify the file fields to
84759// include in the submssion using the `files` option, which can be a selector,
84760// jQuery object, or a list of DOM elements containing one or more
84761// `<input type="file">` elements:
84762
84763//     $("#myform").submit(function() {
84764//         $.ajax(this.action, {
84765//             files: $(":file", this),
84766//             iframe: true
84767//         }).complete(function(data) {
84768//             console.log(data);
84769//         });
84770//     });
84771
84772// The plugin will construct hidden `<iframe>` and `<form>` elements, add the
84773// file field(s) to that form, submit the form, and process the response.
84774
84775// If you want to include other form fields in the form submission, include
84776// them in the `data` option, and set the `processData` option to `false`:
84777
84778//     $("#myform").submit(function() {
84779//         $.ajax(this.action, {
84780//             data: $(":text", this).serializeArray(),
84781//             files: $(":file", this),
84782//             iframe: true,
84783//             processData: false
84784//         }).complete(function(data) {
84785//             console.log(data);
84786//         });
84787//     });
84788
84789// ### Response Data Types
84790
84791// As the transport does not have access to the HTTP headers of the server
84792// response, it is not as simple to make use of the automatic content type
84793// detection provided by jQuery as with regular XHR. If you can't set the
84794// expected response data type (for example because it may vary depending on
84795// the outcome of processing by the server), you will need to employ a
84796// workaround on the server side: Send back an HTML document containing just a
84797// `<textarea>` element with a `data-type` attribute that specifies the MIME
84798// type, and put the actual payload in the textarea:
84799
84800//     <textarea data-type="application/json">
84801//       {"ok": true, "message": "Thanks so much"}
84802//     </textarea>
84803
84804// The iframe transport plugin will detect this and pass the value of the
84805// `data-type` attribute on to jQuery as if it was the "Content-Type" response
84806// header, thereby enabling the same kind of conversions that jQuery applies
84807// to regular responses. For the example above you should get a Javascript
84808// object as the `data` parameter of the `complete` callback, with the
84809// properties `ok: true` and `message: "Thanks so much"`.
84810
84811// ### Handling Server Errors
84812
84813// Another problem with using an `iframe` for file uploads is that it is
84814// impossible for the javascript code to determine the HTTP status code of the
84815// servers response. Effectively, all of the calls you make will look like they
84816// are getting successful responses, and thus invoke the `done()` or
84817// `complete()` callbacks. You can only communicate problems using the content
84818// of the response payload. For example, consider using a JSON response such as
84819// the following to indicate a problem with an uploaded file:
84820
84821//     <textarea data-type="application/json">
84822//       {"ok": false, "message": "Please only upload reasonably sized files."}
84823//     </textarea>
84824
84825// ### Compatibility
84826
84827// This plugin has primarily been tested on Safari 5 (or later), Firefox 4 (or
84828// later), and Internet Explorer (all the way back to version 6). While I
84829// haven't found any issues with it so far, I'm fairly sure it still doesn't
84830// work around all the quirks in all different browsers. But the code is still
84831// pretty simple overall, so you should be able to fix it and contribute a
84832// patch :)
84833
84834// ## Annotated Source
84835
84836(function($, undefined) {
84837  "use strict";
84838
84839  // Register a prefilter that checks whether the `iframe` option is set, and
84840  // switches to the "iframe" data type if it is `true`.
84841  $.ajaxPrefilter(function(options, origOptions, jqXHR) {
84842    if (options.iframe) {
84843      options.originalURL = options.url;
84844      return "iframe";
84845    }
84846  });
84847
84848  // Register a transport for the "iframe" data type. It will only activate
84849  // when the "files" option has been set to a non-empty list of enabled file
84850  // inputs.
84851  $.ajaxTransport("iframe", function(options, origOptions, jqXHR) {
84852    var form = null,
84853        iframe = null,
84854        name = "iframe-" + $.now(),
84855        files = $(options.files).filter(":file:enabled"),
84856        markers = null,
84857        accepts = null;
84858
84859    // This function gets called after a successful submission or an abortion
84860    // and should revert all changes made to the page to enable the
84861    // submission via this transport.
84862    function cleanUp() {
84863      files.each(function(i, file) {
84864        var $file = $(file);
84865        $file.data("clone").replaceWith($file);
84866      });
84867      form.remove();
84868      iframe.one("load", function() { iframe.remove(); });
84869      iframe.attr("src", "about:blank");
84870    }
84871
84872    // Remove "iframe" from the data types list so that further processing is
84873    // based on the content type returned by the server, without attempting an
84874    // (unsupported) conversion from "iframe" to the actual type.
84875    options.dataTypes.shift();
84876
84877    // Use the data from the original AJAX options, as it doesn't seem to be 
84878    // copied over since jQuery 1.7.
84879    // See https://github.com/cmlenz/jquery-iframe-transport/issues/6
84880    options.data = origOptions.data;
84881
84882    if (files.length) {
84883      form = $("<form enctype='multipart/form-data' method='post'></form>").
84884        hide().attr({action: options.originalURL, target: name});
84885
84886      // If there is any additional data specified via the `data` option,
84887      // we add it as hidden fields to the form. This (currently) requires
84888      // the `processData` option to be set to false so that the data doesn't
84889      // get serialized to a string.
84890      if (typeof(options.data) === "string" && options.data.length > 0) {
84891        $.error("data must not be serialized");
84892      }
84893      $.each(options.data || {}, function(name, value) {
84894        if ($.isPlainObject(value)) {
84895          name = value.name;
84896          value = value.value;
84897        }
84898        $("<input type='hidden' />").attr({name:  name, value: value}).
84899          appendTo(form);
84900      });
84901
84902      // Add a hidden `X-Requested-With` field with the value `IFrame` to the
84903      // field, to help server-side code to determine that the upload happened
84904      // through this transport.
84905      $("<input type='hidden' value='IFrame' name='X-Requested-With' />").
84906        appendTo(form);
84907
84908      // Borrowed straight from the JQuery source.
84909      // Provides a way of specifying the accepted data type similar to the
84910      // HTTP "Accept" header
84911      if (options.dataTypes[0] && options.accepts[options.dataTypes[0]]) {
84912        accepts = options.accepts[options.dataTypes[0]] +
84913                  (options.dataTypes[0] !== "*" ? ", */*; q=0.01" : "");
84914      } else {
84915        accepts = options.accepts["*"];
84916      }
84917      $("<input type='hidden' name='X-HTTP-Accept'>").
84918        attr("value", accepts).appendTo(form);
84919
84920      // Move the file fields into the hidden form, but first remember their
84921      // original locations in the document by replacing them with disabled
84922      // clones. This should also avoid introducing unwanted changes to the
84923      // page layout during submission.
84924      markers = files.after(function(idx) {
84925        var $this = $(this),
84926            $clone = $this.clone().prop("disabled", true);
84927        $this.data("clone", $clone);
84928        return $clone;
84929      }).next();
84930      files.appendTo(form);
84931
84932      return {
84933
84934        // The `send` function is called by jQuery when the request should be
84935        // sent.
84936        send: function(headers, completeCallback) {
84937          iframe = $("<iframe src='about:blank' name='" + name +
84938            "' id='" + name + "' style='display:none'></iframe>");
84939
84940          // The first load event gets fired after the iframe has been injected
84941          // into the DOM, and is used to prepare the actual submission.
84942          iframe.one("load", function() {
84943
84944            // The second load event gets fired when the response to the form
84945            // submission is received. The implementation detects whether the
84946            // actual payload is embedded in a `<textarea>` element, and
84947            // prepares the required conversions to be made in that case.
84948            iframe.one("load", function() {
84949              var doc = this.contentWindow ? this.contentWindow.document :
84950                (this.contentDocument ? this.contentDocument : this.document),
84951                root = doc.documentElement ? doc.documentElement : doc.body,
84952                textarea = root.getElementsByTagName("textarea")[0],
84953                type = textarea && textarea.getAttribute("data-type") || null,
84954                status = textarea && textarea.getAttribute("data-status") || 200,
84955                statusText = textarea && textarea.getAttribute("data-statusText") || "OK",
84956                content = {
84957                  text: type ?
84958                    textarea.value :
84959                    root ? (root.textContent || root.innerText) : null
84960                };
84961              cleanUp();
84962              if (!jqXHR.responseText) {
84963                jqXHR.responseText = content.text;
84964              }
84965              completeCallback(status, statusText, content, type ?
84966                ("Content-Type: " + type) :
84967                null);
84968            });
84969
84970            // Now that the load handler has been set up, submit the form.
84971            form[0].submit();
84972          });
84973
84974          // After everything has been set up correctly, the form and iframe
84975          // get injected into the DOM so that the submission can be
84976          // initiated.
84977          $("body").append(form, iframe);
84978        },
84979
84980        // The `abort` function is called by jQuery when the request should be
84981        // aborted.
84982        abort: function() {
84983          if (iframe !== null) {
84984            iframe.unbind("load").attr("src", "about:blank");
84985            cleanUp();
84986          }
84987        }
84988
84989      };
84990    }
84991  });
84992
84993})(jQuery);
84994
84995
84996
84997(function($) {
84998
84999  var remotipart;
85000
85001  $.remotipart = remotipart = {
85002
85003    setup: function(form) {
85004      // Preserve form.data('ujs:submit-button') before it gets nulled by $.ajax.handleRemote
85005      var button = form.data('ujs:submit-button'),
85006          csrfParam = $('meta[name="csrf-param"]').attr('content'),
85007          csrfToken = $('meta[name="csrf-token"]').attr('content'),
85008          csrfInput = form.find('input[name="' + csrfParam + '"]').length;
85009
85010      form
85011        // Allow setup part of $.rails.handleRemote to setup remote settings before canceling default remote handler
85012        // This is required in order to change the remote settings using the form details
85013        .one('ajax:beforeSend.remotipart', function(e, xhr, settings){
85014          // Delete the beforeSend bindings, since we're about to re-submit via ajaxSubmit with the beforeSubmit
85015          // hook that was just setup and triggered via the default `$.rails.handleRemote`
85016          // delete settings.beforeSend;
85017          delete settings.beforeSend;
85018
85019          settings.iframe      = true;
85020          settings.files       = $($.rails.fileInputSelector, form);
85021          settings.data        = form.serializeArray();
85022
85023          // Insert the name/value of the clicked submit button, if any
85024          if (button)
85025            settings.data.push(button);
85026
85027          // jQuery 1.9 serializeArray() contains input:file entries
85028          // so exclude them from settings.data, otherwise files will not be sent
85029          settings.files.each(function(i, file){
85030            for (var j = settings.data.length - 1; j >= 0; j--)
85031              if (settings.data[j].name == file.name)
85032                settings.data.splice(j, 1);
85033          })
85034
85035          settings.processData = false;
85036
85037          // Modify some settings to integrate JS request with rails helpers and middleware
85038          if (settings.dataType === undefined) { settings.dataType = 'script *'; }
85039          settings.data.push({name: 'remotipart_submitted', value: true});
85040          if (csrfToken && csrfParam && !csrfInput) {
85041            settings.data.push({name: csrfParam, value: csrfToken});
85042          }
85043
85044          // Allow remotipartSubmit to be cancelled if needed
85045          if ($.rails.fire(form, 'ajax:remotipartSubmit', [xhr, settings])) {
85046            // Second verse, same as the first
85047            $.rails.ajax(settings).always(function(data){
85048              $.rails.fire(form, 'ajax:remotipartComplete', [data]);
85049            });
85050            setTimeout(function(){ $.rails.disableFormElements(form); }, 20);
85051          }
85052
85053          //Run cleanup
85054          remotipart.teardown(form);
85055
85056          // Cancel the jQuery UJS request
85057          return false;
85058        })
85059
85060        // Keep track that we just set this particular form with Remotipart bindings
85061        // Note: The `true` value will get over-written with the `settings.dataType` from the `ajax:beforeSend` handler
85062        .data('remotipartSubmitted', true);
85063    },
85064
85065    teardown: function(form) {
85066      form
85067        .unbind('ajax:beforeSend.remotipart')
85068        .removeData('remotipartSubmitted')
85069    }
85070  };
85071
85072  $(document).on('ajax:aborted:file', 'form', function(){
85073    var form = $(this);
85074
85075    remotipart.setup(form);
85076
85077    // Manually call jquery-ujs remote call so that it can setup form and settings as usual,
85078    // and trigger the `ajax:beforeSend` callback to which remotipart binds functionality.
85079    $.rails.handleRemote(form);
85080    return false;
85081  });
85082
85083})(jQuery);
85084// This is a manifest file that'll be compiled into application.js, which will include all the files
85085// listed below.
85086//
85087// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
85088// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
85089//
85090// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
85091// compiled file. JavaScript code in this file should be added after the last require_* statement.
85092//
85093// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
85094// about supported directives.
85095
85096
85097
85098
85099
85100
85101
85102
85103
85104
85105
85106
85107
85108
85109;

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.