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("<").split(">").join(">").split('"').join(""").split("'").join("'")}});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, '&') 4129 .replace(/"/g, '"') 4130 .replace(/'/g, ''') 4131 .replace(/</g, '<') 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 '&' 15401 if (e == '<') return '<' 15402 if (e == '>') return '>' 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'><click to see more...></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 `<` will render as `<`. 24321 * 24322 * @example 24323 * // Add support for unescaping quotes 24324 * Highcharts.SVGRenderer.prototype.escapes['"'] = '"'; 24325 * 24326 * @type {Object} 24327 */ 24328 escapes: { 24329 '&': '&', 24330 '<': '<', 24331 '>': '>', 24332 "'": ''', // eslint-disable-line quotes 24333 '"': '"' 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,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}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:[""],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(/ /g," ");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 '\\': '\', 64500 '&': '&', 64501 '<': '<', 64502 '>': '>', 64503 '"': '"', 64504 '\'': ''', 64505 '/': '/' 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 '×' + 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 '×' + 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": ["ï¼æ", "ï¼æ", "ï¼æ", "ï¼æ", "ï¼æ", "ï¼æ", "ï¼æ", "ï¼æ", "ï¼æ", "ï¼ï¼æ", "ï¼ï¼æ", "ï¼ï¼æ"] 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 '\\': '\', 72205 '&': '&', 72206 '<': '<', 72207 '>': '>', 72208 '"': '"', 72209 '\'': ''', 72210 '/': '/' 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 '×' + 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 '×' + 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(/[ï¼-ï¼]/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": ["ï¼æ", "ï¼æ", "ï¼æ", "ï¼æ", "ï¼æ", "ï¼æ", "ï¼æ", "ï¼æ", "ï¼æ", "ï¼ï¼æ", "ï¼ï¼æ", "ï¼ï¼æ"] 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,"&").replace(/</gm,"<").replace(/>/gm,">")}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: "", 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 = ""; 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)">▲</button>' + 82695 '<button type="button" class="simplemde-search-next" title="次ã®çµæ (Enter)">▼</button>' + 82696 '<button type="button" class="simplemde-search-close" title="éãã (Esc)">✕</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 = "🔍";
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.