comparison lib/GeoTemCo/platin.js @ 3:19f75fe342eb

minor changes
author Dirk Wintergruen <dwinter@mpiwg-berlin.mpg.de>
date Mon, 12 Oct 2015 08:33:28 +0200
parents b57c7821382f
children 35c11979b58b
comparison
equal deleted inserted replaced
0:b57c7821382f 3:19f75fe342eb
18301 done(); 18301 done();
18302 }); 18302 });
18303 }; 18303 };
18304 18304
18305 })(jQuery); 18305 })(jQuery);
18306 /*globals jQuery, define, exports, require, window, document, postMessage */
18307 (function (factory) {
18308 "use strict";
18309 if (typeof define === 'function' && define.amd) {
18310 define(['jquery'], factory);
18311 }
18312 else if(typeof exports === 'object') {
18313 factory(require('jquery'));
18314 }
18315 else {
18316 factory(jQuery);
18317 }
18318 }(function ($, undefined) {
18319 "use strict";
18320 /*!
18321 * jsTree 3.0.9
18322 * http://jstree.com/
18323 *
18324 * Copyright (c) 2014 Ivan Bozhanov (http://vakata.com)
18325 *
18326 * Licensed same as jquery - under the terms of the MIT License
18327 * http://www.opensource.org/licenses/mit-license.php
18328 */
18329 /*!
18330 * if using jslint please allow for the jQuery global and use following options:
18331 * jslint: browser: true, ass: true, bitwise: true, continue: true, nomen: true, plusplus: true, regexp: true, unparam: true, todo: true, white: true
18332 */
18333
18334 // prevent another load? maybe there is a better way?
18335 if($.jstree) {
18336 return;
18337 }
18338
18339 /**
18340 * ### jsTree core functionality
18341 */
18342
18343 // internal variables
18344 var instance_counter = 0,
18345 ccp_node = false,
18346 ccp_mode = false,
18347 ccp_inst = false,
18348 themes_loaded = [],
18349 src = $('script:last').attr('src'),
18350 _d = document, _node = _d.createElement('LI'), _temp1, _temp2;
18351
18352 _node.setAttribute('role', 'treeitem');
18353 _temp1 = _d.createElement('I');
18354 _temp1.className = 'jstree-icon jstree-ocl';
18355 _temp1.setAttribute('role', 'presentation');
18356 _node.appendChild(_temp1);
18357 _temp1 = _d.createElement('A');
18358 _temp1.className = 'jstree-anchor';
18359 _temp1.setAttribute('href','#');
18360 _temp1.setAttribute('tabindex','-1');
18361 _temp2 = _d.createElement('I');
18362 _temp2.className = 'jstree-icon jstree-themeicon';
18363 _temp2.setAttribute('role', 'presentation');
18364 _temp1.appendChild(_temp2);
18365 _node.appendChild(_temp1);
18366 _temp1 = _temp2 = null;
18367
18368
18369 /**
18370 * holds all jstree related functions and variables, including the actual class and methods to create, access and manipulate instances.
18371 * @name $.jstree
18372 */
18373 $.jstree = {
18374 /**
18375 * specifies the jstree version in use
18376 * @name $.jstree.version
18377 */
18378 version : '3.0.9',
18379 /**
18380 * holds all the default options used when creating new instances
18381 * @name $.jstree.defaults
18382 */
18383 defaults : {
18384 /**
18385 * configure which plugins will be active on an instance. Should be an array of strings, where each element is a plugin name. The default is `[]`
18386 * @name $.jstree.defaults.plugins
18387 */
18388 plugins : []
18389 },
18390 /**
18391 * stores all loaded jstree plugins (used internally)
18392 * @name $.jstree.plugins
18393 */
18394 plugins : {},
18395 path : src && src.indexOf('/') !== -1 ? src.replace(/\/[^\/]+$/,'') : '',
18396 idregex : /[\\:&!^|()\[\]<>@*'+~#";.,=\- \/${}%?`]/g
18397 };
18398 /**
18399 * creates a jstree instance
18400 * @name $.jstree.create(el [, options])
18401 * @param {DOMElement|jQuery|String} el the element to create the instance on, can be jQuery extended or a selector
18402 * @param {Object} options options for this instance (extends `$.jstree.defaults`)
18403 * @return {jsTree} the new instance
18404 */
18405 $.jstree.create = function (el, options) {
18406 var tmp = new $.jstree.core(++instance_counter),
18407 opt = options;
18408 options = $.extend(true, {}, $.jstree.defaults, options);
18409 if(opt && opt.plugins) {
18410 options.plugins = opt.plugins;
18411 }
18412 $.each(options.plugins, function (i, k) {
18413 if(i !== 'core') {
18414 tmp = tmp.plugin(k, options[k]);
18415 }
18416 });
18417 tmp.init(el, options);
18418 return tmp;
18419 };
18420 /**
18421 * remove all traces of jstree from the DOM and destroy all instances
18422 * @name $.jstree.destroy()
18423 */
18424 $.jstree.destroy = function () {
18425 $('.jstree:jstree').jstree('destroy');
18426 $(document).off('.jstree');
18427 };
18428 /**
18429 * the jstree class constructor, used only internally
18430 * @private
18431 * @name $.jstree.core(id)
18432 * @param {Number} id this instance's index
18433 */
18434 $.jstree.core = function (id) {
18435 this._id = id;
18436 this._cnt = 0;
18437 this._wrk = null;
18438 this._data = {
18439 core : {
18440 themes : {
18441 name : false,
18442 dots : false,
18443 icons : false
18444 },
18445 selected : [],
18446 last_error : {},
18447 working : false,
18448 worker_queue : [],
18449 focused : null
18450 }
18451 };
18452 };
18453 /**
18454 * get a reference to an existing instance
18455 *
18456 * __Examples__
18457 *
18458 * // provided a container with an ID of "tree", and a nested node with an ID of "branch"
18459 * // all of there will return the same instance
18460 * $.jstree.reference('tree');
18461 * $.jstree.reference('#tree');
18462 * $.jstree.reference($('#tree'));
18463 * $.jstree.reference(document.getElementByID('tree'));
18464 * $.jstree.reference('branch');
18465 * $.jstree.reference('#branch');
18466 * $.jstree.reference($('#branch'));
18467 * $.jstree.reference(document.getElementByID('branch'));
18468 *
18469 * @name $.jstree.reference(needle)
18470 * @param {DOMElement|jQuery|String} needle
18471 * @return {jsTree|null} the instance or `null` if not found
18472 */
18473 $.jstree.reference = function (needle) {
18474 var tmp = null,
18475 obj = null;
18476 if(needle && needle.id) { needle = needle.id; }
18477
18478 if(!obj || !obj.length) {
18479 try { obj = $(needle); } catch (ignore) { }
18480 }
18481 if(!obj || !obj.length) {
18482 try { obj = $('#' + needle.replace($.jstree.idregex,'\\$&')); } catch (ignore) { }
18483 }
18484 if(obj && obj.length && (obj = obj.closest('.jstree')).length && (obj = obj.data('jstree'))) {
18485 tmp = obj;
18486 }
18487 else {
18488 $('.jstree').each(function () {
18489 var inst = $(this).data('jstree');
18490 if(inst && inst._model.data[needle]) {
18491 tmp = inst;
18492 return false;
18493 }
18494 });
18495 }
18496 return tmp;
18497 };
18498 /**
18499 * Create an instance, get an instance or invoke a command on a instance.
18500 *
18501 * If there is no instance associated with the current node a new one is created and `arg` is used to extend `$.jstree.defaults` for this new instance. There would be no return value (chaining is not broken).
18502 *
18503 * If there is an existing instance and `arg` is a string the command specified by `arg` is executed on the instance, with any additional arguments passed to the function. If the function returns a value it will be returned (chaining could break depending on function).
18504 *
18505 * If there is an existing instance and `arg` is not a string the instance itself is returned (similar to `$.jstree.reference`).
18506 *
18507 * In any other case - nothing is returned and chaining is not broken.
18508 *
18509 * __Examples__
18510 *
18511 * $('#tree1').jstree(); // creates an instance
18512 * $('#tree2').jstree({ plugins : [] }); // create an instance with some options
18513 * $('#tree1').jstree('open_node', '#branch_1'); // call a method on an existing instance, passing additional arguments
18514 * $('#tree2').jstree(); // get an existing instance (or create an instance)
18515 * $('#tree2').jstree(true); // get an existing instance (will not create new instance)
18516 * $('#branch_1').jstree().select_node('#branch_1'); // get an instance (using a nested element and call a method)
18517 *
18518 * @name $().jstree([arg])
18519 * @param {String|Object} arg
18520 * @return {Mixed}
18521 */
18522 $.fn.jstree = function (arg) {
18523 // check for string argument
18524 var is_method = (typeof arg === 'string'),
18525 args = Array.prototype.slice.call(arguments, 1),
18526 result = null;
18527 if(arg === true && !this.length) { return false; }
18528 this.each(function () {
18529 // get the instance (if there is one) and method (if it exists)
18530 var instance = $.jstree.reference(this),
18531 method = is_method && instance ? instance[arg] : null;
18532 // if calling a method, and method is available - execute on the instance
18533 result = is_method && method ?
18534 method.apply(instance, args) :
18535 null;
18536 // if there is no instance and no method is being called - create one
18537 if(!instance && !is_method && (arg === undefined || $.isPlainObject(arg))) {
18538 $(this).data('jstree', new $.jstree.create(this, arg));
18539 }
18540 // if there is an instance and no method is called - return the instance
18541 if( (instance && !is_method) || arg === true ) {
18542 result = instance || false;
18543 }
18544 // if there was a method call which returned a result - break and return the value
18545 if(result !== null && result !== undefined) {
18546 return false;
18547 }
18548 });
18549 // if there was a method call with a valid return value - return that, otherwise continue the chain
18550 return result !== null && result !== undefined ?
18551 result : this;
18552 };
18553 /**
18554 * used to find elements containing an instance
18555 *
18556 * __Examples__
18557 *
18558 * $('div:jstree').each(function () {
18559 * $(this).jstree('destroy');
18560 * });
18561 *
18562 * @name $(':jstree')
18563 * @return {jQuery}
18564 */
18565 $.expr[':'].jstree = $.expr.createPseudo(function(search) {
18566 return function(a) {
18567 return $(a).hasClass('jstree') &&
18568 $(a).data('jstree') !== undefined;
18569 };
18570 });
18571
18572 /**
18573 * stores all defaults for the core
18574 * @name $.jstree.defaults.core
18575 */
18576 $.jstree.defaults.core = {
18577 /**
18578 * data configuration
18579 *
18580 * If left as `false` the HTML inside the jstree container element is used to populate the tree (that should be an unordered list with list items).
18581 *
18582 * You can also pass in a HTML string or a JSON array here.
18583 *
18584 * It is possible to pass in a standard jQuery-like AJAX config and jstree will automatically determine if the response is JSON or HTML and use that to populate the tree.
18585 * In addition to the standard jQuery ajax options here you can suppy functions for `data` and `url`, the functions will be run in the current instance's scope and a param will be passed indicating which node is being loaded, the return value of those functions will be used.
18586 *
18587 * The last option is to specify a function, that function will receive the node being loaded as argument and a second param which is a function which should be called with the result.
18588 *
18589 * __Examples__
18590 *
18591 * // AJAX
18592 * $('#tree').jstree({
18593 * 'core' : {
18594 * 'data' : {
18595 * 'url' : '/get/children/',
18596 * 'data' : function (node) {
18597 * return { 'id' : node.id };
18598 * }
18599 * }
18600 * });
18601 *
18602 * // direct data
18603 * $('#tree').jstree({
18604 * 'core' : {
18605 * 'data' : [
18606 * 'Simple root node',
18607 * {
18608 * 'id' : 'node_2',
18609 * 'text' : 'Root node with options',
18610 * 'state' : { 'opened' : true, 'selected' : true },
18611 * 'children' : [ { 'text' : 'Child 1' }, 'Child 2']
18612 * }
18613 * ]
18614 * });
18615 *
18616 * // function
18617 * $('#tree').jstree({
18618 * 'core' : {
18619 * 'data' : function (obj, callback) {
18620 * callback.call(this, ['Root 1', 'Root 2']);
18621 * }
18622 * });
18623 *
18624 * @name $.jstree.defaults.core.data
18625 */
18626 data : false,
18627 /**
18628 * configure the various strings used throughout the tree
18629 *
18630 * You can use an object where the key is the string you need to replace and the value is your replacement.
18631 * Another option is to specify a function which will be called with an argument of the needed string and should return the replacement.
18632 * If left as `false` no replacement is made.
18633 *
18634 * __Examples__
18635 *
18636 * $('#tree').jstree({
18637 * 'core' : {
18638 * 'strings' : {
18639 * 'Loading ...' : 'Please wait ...'
18640 * }
18641 * }
18642 * });
18643 *
18644 * @name $.jstree.defaults.core.strings
18645 */
18646 strings : false,
18647 /**
18648 * determines what happens when a user tries to modify the structure of the tree
18649 * If left as `false` all operations like create, rename, delete, move or copy are prevented.
18650 * You can set this to `true` to allow all interactions or use a function to have better control.
18651 *
18652 * __Examples__
18653 *
18654 * $('#tree').jstree({
18655 * 'core' : {
18656 * 'check_callback' : function (operation, node, node_parent, node_position, more) {
18657 * // operation can be 'create_node', 'rename_node', 'delete_node', 'move_node' or 'copy_node'
18658 * // in case of 'rename_node' node_position is filled with the new node name
18659 * return operation === 'rename_node' ? true : false;
18660 * }
18661 * }
18662 * });
18663 *
18664 * @name $.jstree.defaults.core.check_callback
18665 */
18666 check_callback : false,
18667 /**
18668 * a callback called with a single object parameter in the instance's scope when something goes wrong (operation prevented, ajax failed, etc)
18669 * @name $.jstree.defaults.core.error
18670 */
18671 error : $.noop,
18672 /**
18673 * the open / close animation duration in milliseconds - set this to `false` to disable the animation (default is `200`)
18674 * @name $.jstree.defaults.core.animation
18675 */
18676 animation : 200,
18677 /**
18678 * a boolean indicating if multiple nodes can be selected
18679 * @name $.jstree.defaults.core.multiple
18680 */
18681 multiple : true,
18682 /**
18683 * theme configuration object
18684 * @name $.jstree.defaults.core.themes
18685 */
18686 themes : {
18687 /**
18688 * the name of the theme to use (if left as `false` the default theme is used)
18689 * @name $.jstree.defaults.core.themes.name
18690 */
18691 name : false,
18692 /**
18693 * the URL of the theme's CSS file, leave this as `false` if you have manually included the theme CSS (recommended). You can set this to `true` too which will try to autoload the theme.
18694 * @name $.jstree.defaults.core.themes.url
18695 */
18696 url : false,
18697 /**
18698 * the location of all jstree themes - only used if `url` is set to `true`
18699 * @name $.jstree.defaults.core.themes.dir
18700 */
18701 dir : false,
18702 /**
18703 * a boolean indicating if connecting dots are shown
18704 * @name $.jstree.defaults.core.themes.dots
18705 */
18706 dots : true,
18707 /**
18708 * a boolean indicating if node icons are shown
18709 * @name $.jstree.defaults.core.themes.icons
18710 */
18711 icons : true,
18712 /**
18713 * a boolean indicating if the tree background is striped
18714 * @name $.jstree.defaults.core.themes.stripes
18715 */
18716 stripes : false,
18717 /**
18718 * a string (or boolean `false`) specifying the theme variant to use (if the theme supports variants)
18719 * @name $.jstree.defaults.core.themes.variant
18720 */
18721 variant : false,
18722 /**
18723 * a boolean specifying if a reponsive version of the theme should kick in on smaller screens (if the theme supports it). Defaults to `false`.
18724 * @name $.jstree.defaults.core.themes.responsive
18725 */
18726 responsive : false
18727 },
18728 /**
18729 * if left as `true` all parents of all selected nodes will be opened once the tree loads (so that all selected nodes are visible to the user)
18730 * @name $.jstree.defaults.core.expand_selected_onload
18731 */
18732 expand_selected_onload : true,
18733 /**
18734 * if left as `true` web workers will be used to parse incoming JSON data where possible, so that the UI will not be blocked by large requests. Workers are however about 30% slower. Defaults to `true`
18735 * @name $.jstree.defaults.core.worker
18736 */
18737 worker : true,
18738 /**
18739 * Force node text to plain text (and escape HTML). Defaults to `false`
18740 * @name $.jstree.defaults.core.force_text
18741 */
18742 force_text : false,
18743 /**
18744 * Should the node should be toggled if the text is double clicked . Defaults to `true`
18745 * @name $.jstree.defaults.core.dblclick_toggle
18746 */
18747 dblclick_toggle : true
18748 };
18749 $.jstree.core.prototype = {
18750 /**
18751 * used to decorate an instance with a plugin. Used internally.
18752 * @private
18753 * @name plugin(deco [, opts])
18754 * @param {String} deco the plugin to decorate with
18755 * @param {Object} opts options for the plugin
18756 * @return {jsTree}
18757 */
18758 plugin : function (deco, opts) {
18759 var Child = $.jstree.plugins[deco];
18760 if(Child) {
18761 this._data[deco] = {};
18762 Child.prototype = this;
18763 return new Child(opts, this);
18764 }
18765 return this;
18766 },
18767 /**
18768 * used to decorate an instance with a plugin. Used internally.
18769 * @private
18770 * @name init(el, optons)
18771 * @param {DOMElement|jQuery|String} el the element we are transforming
18772 * @param {Object} options options for this instance
18773 * @trigger init.jstree, loading.jstree, loaded.jstree, ready.jstree, changed.jstree
18774 */
18775 init : function (el, options) {
18776 this._model = {
18777 data : {
18778 '#' : {
18779 id : '#',
18780 parent : null,
18781 parents : [],
18782 children : [],
18783 children_d : [],
18784 state : { loaded : false }
18785 }
18786 },
18787 changed : [],
18788 force_full_redraw : false,
18789 redraw_timeout : false,
18790 default_state : {
18791 loaded : true,
18792 opened : false,
18793 selected : false,
18794 disabled : false
18795 }
18796 };
18797
18798 this.element = $(el).addClass('jstree jstree-' + this._id);
18799 this.settings = options;
18800
18801 this._data.core.ready = false;
18802 this._data.core.loaded = false;
18803 this._data.core.rtl = (this.element.css("direction") === "rtl");
18804 this.element[this._data.core.rtl ? 'addClass' : 'removeClass']("jstree-rtl");
18805 this.element.attr('role','tree');
18806 if(this.settings.core.multiple) {
18807 this.element.attr('aria-multiselectable', true);
18808 }
18809 if(!this.element.attr('tabindex')) {
18810 this.element.attr('tabindex','0');
18811 }
18812
18813 this.bind();
18814 /**
18815 * triggered after all events are bound
18816 * @event
18817 * @name init.jstree
18818 */
18819 this.trigger("init");
18820
18821 this._data.core.original_container_html = this.element.find(" > ul > li").clone(true);
18822 this._data.core.original_container_html
18823 .find("li").addBack()
18824 .contents().filter(function() {
18825 return this.nodeType === 3 && (!this.nodeValue || /^\s+$/.test(this.nodeValue));
18826 })
18827 .remove();
18828 this.element.html("<"+"ul class='jstree-container-ul jstree-children' role='group'><"+"li id='j"+this._id+"_loading' class='jstree-initial-node jstree-loading jstree-leaf jstree-last' role='tree-item'><i class='jstree-icon jstree-ocl'></i><"+"a class='jstree-anchor' href='#'><i class='jstree-icon jstree-themeicon-hidden'></i>" + this.get_string("Loading ...") + "</a></li></ul>");
18829 this.element.attr('aria-activedescendant','j' + this._id + '_loading');
18830 this._data.core.li_height = this.get_container_ul().children("li").first().height() || 24;
18831 /**
18832 * triggered after the loading text is shown and before loading starts
18833 * @event
18834 * @name loading.jstree
18835 */
18836 this.trigger("loading");
18837 this.load_node('#');
18838 },
18839 /**
18840 * destroy an instance
18841 * @name destroy()
18842 * @param {Boolean} keep_html if not set to `true` the container will be emptied, otherwise the current DOM elements will be kept intact
18843 */
18844 destroy : function (keep_html) {
18845 if(this._wrk) {
18846 try {
18847 window.URL.revokeObjectURL(this._wrk);
18848 this._wrk = null;
18849 }
18850 catch (ignore) { }
18851 }
18852 if(!keep_html) { this.element.empty(); }
18853 this.teardown();
18854 },
18855 /**
18856 * part of the destroying of an instance. Used internally.
18857 * @private
18858 * @name teardown()
18859 */
18860 teardown : function () {
18861 this.unbind();
18862 this.element
18863 .removeClass('jstree')
18864 .removeData('jstree')
18865 .find("[class^='jstree']")
18866 .addBack()
18867 .attr("class", function () { return this.className.replace(/jstree[^ ]*|$/ig,''); });
18868 this.element = null;
18869 },
18870 /**
18871 * bind all events. Used internally.
18872 * @private
18873 * @name bind()
18874 */
18875 bind : function () {
18876 var word = '',
18877 tout = null,
18878 was_click = 0;
18879 this.element
18880 .on("dblclick.jstree", function () {
18881 if(document.selection && document.selection.empty) {
18882 document.selection.empty();
18883 }
18884 else {
18885 if(window.getSelection) {
18886 var sel = window.getSelection();
18887 try {
18888 sel.removeAllRanges();
18889 sel.collapse();
18890 } catch (ignore) { }
18891 }
18892 }
18893 })
18894 .on("mousedown.jstree", $.proxy(function (e) {
18895 if(e.target === this.element[0]) {
18896 e.preventDefault(); // prevent losing focus when clicking scroll arrows (FF, Chrome)
18897 was_click = +(new Date()); // ie does not allow to prevent losing focus
18898 }
18899 }, this))
18900 .on("mousedown.jstree", ".jstree-ocl", function (e) {
18901 e.preventDefault(); // prevent any node inside from losing focus when clicking the open/close icon
18902 })
18903 .on("click.jstree", ".jstree-ocl", $.proxy(function (e) {
18904 this.toggle_node(e.target);
18905 }, this))
18906 .on("dblclick.jstree", ".jstree-anchor", $.proxy(function (e) {
18907 if(this.settings.core.dblclick_toggle) {
18908 this.toggle_node(e.target);
18909 }
18910 }, this))
18911 .on("click.jstree", ".jstree-anchor", $.proxy(function (e) {
18912 e.preventDefault();
18913 if(e.currentTarget !== document.activeElement) { $(e.currentTarget).focus(); }
18914 this.activate_node(e.currentTarget, e);
18915 }, this))
18916 .on('keydown.jstree', '.jstree-anchor', $.proxy(function (e) {
18917 if(e.target.tagName === "INPUT") { return true; }
18918 var o = null;
18919 if(this._data.core.rtl) {
18920 if(e.which === 37) { e.which = 39; }
18921 else if(e.which === 39) { e.which = 37; }
18922 }
18923 switch(e.which) {
18924 case 32: // aria defines space only with Ctrl
18925 if(e.ctrlKey) {
18926 e.type = "click";
18927 $(e.currentTarget).trigger(e);
18928 }
18929 break;
18930 case 13: // enter
18931 e.type = "click";
18932 $(e.currentTarget).trigger(e);
18933 break;
18934 case 37: // right
18935 e.preventDefault();
18936 if(this.is_open(e.currentTarget)) {
18937 this.close_node(e.currentTarget);
18938 }
18939 else {
18940 o = this.get_parent(e.currentTarget);
18941 if(o && o.id !== '#') { this.get_node(o, true).children('.jstree-anchor').focus(); }
18942 }
18943 break;
18944 case 38: // up
18945 e.preventDefault();
18946 o = this.get_prev_dom(e.currentTarget);
18947 if(o && o.length) { o.children('.jstree-anchor').focus(); }
18948 break;
18949 case 39: // left
18950 e.preventDefault();
18951 if(this.is_closed(e.currentTarget)) {
18952 this.open_node(e.currentTarget, function (o) { this.get_node(o, true).children('.jstree-anchor').focus(); });
18953 }
18954 else if (this.is_open(e.currentTarget)) {
18955 o = this.get_node(e.currentTarget, true).children('.jstree-children')[0];
18956 if(o) { $(this._firstChild(o)).children('.jstree-anchor').focus(); }
18957 }
18958 break;
18959 case 40: // down
18960 e.preventDefault();
18961 o = this.get_next_dom(e.currentTarget);
18962 if(o && o.length) { o.children('.jstree-anchor').focus(); }
18963 break;
18964 case 106: // aria defines * on numpad as open_all - not very common
18965 this.open_all();
18966 break;
18967 case 36: // home
18968 e.preventDefault();
18969 o = this._firstChild(this.get_container_ul()[0]);
18970 if(o) { $(o).children('.jstree-anchor').filter(':visible').focus(); }
18971 break;
18972 case 35: // end
18973 e.preventDefault();
18974 this.element.find('.jstree-anchor').filter(':visible').last().focus();
18975 break;
18976 /*
18977 // delete
18978 case 46:
18979 e.preventDefault();
18980 o = this.get_node(e.currentTarget);
18981 if(o && o.id && o.id !== '#') {
18982 o = this.is_selected(o) ? this.get_selected() : o;
18983 this.delete_node(o);
18984 }
18985 break;
18986 // f2
18987 case 113:
18988 e.preventDefault();
18989 o = this.get_node(e.currentTarget);
18990 if(o && o.id && o.id !== '#') {
18991 // this.edit(o);
18992 }
18993 break;
18994 default:
18995 // console.log(e.which);
18996 break;
18997 */
18998 }
18999 }, this))
19000 .on("load_node.jstree", $.proxy(function (e, data) {
19001 if(data.status) {
19002 if(data.node.id === '#' && !this._data.core.loaded) {
19003 this._data.core.loaded = true;
19004 if(this._firstChild(this.get_container_ul()[0])) {
19005 this.element.attr('aria-activedescendant',this._firstChild(this.get_container_ul()[0]).id);
19006 }
19007 /**
19008 * triggered after the root node is loaded for the first time
19009 * @event
19010 * @name loaded.jstree
19011 */
19012 this.trigger("loaded");
19013 }
19014 if(!this._data.core.ready) {
19015 setTimeout($.proxy(function() {
19016 if(!this.get_container_ul().find('.jstree-loading').length) {
19017 this._data.core.ready = true;
19018 if(this._data.core.selected.length) {
19019 if(this.settings.core.expand_selected_onload) {
19020 var tmp = [], i, j;
19021 for(i = 0, j = this._data.core.selected.length; i < j; i++) {
19022 tmp = tmp.concat(this._model.data[this._data.core.selected[i]].parents);
19023 }
19024 tmp = $.vakata.array_unique(tmp);
19025 for(i = 0, j = tmp.length; i < j; i++) {
19026 this.open_node(tmp[i], false, 0);
19027 }
19028 }
19029 this.trigger('changed', { 'action' : 'ready', 'selected' : this._data.core.selected });
19030 }
19031 /**
19032 * triggered after all nodes are finished loading
19033 * @event
19034 * @name ready.jstree
19035 */
19036 this.trigger("ready");
19037 }
19038 }, this), 0);
19039 }
19040 }
19041 }, this))
19042 // quick searching when the tree is focused
19043 .on('keypress.jstree', $.proxy(function (e) {
19044 if(e.target.tagName === "INPUT") { return true; }
19045 if(tout) { clearTimeout(tout); }
19046 tout = setTimeout(function () {
19047 word = '';
19048 }, 500);
19049
19050 var chr = String.fromCharCode(e.which).toLowerCase(),
19051 col = this.element.find('.jstree-anchor').filter(':visible'),
19052 ind = col.index(document.activeElement) || 0,
19053 end = false;
19054 word += chr;
19055
19056 // match for whole word from current node down (including the current node)
19057 if(word.length > 1) {
19058 col.slice(ind).each($.proxy(function (i, v) {
19059 if($(v).text().toLowerCase().indexOf(word) === 0) {
19060 $(v).focus();
19061 end = true;
19062 return false;
19063 }
19064 }, this));
19065 if(end) { return; }
19066
19067 // match for whole word from the beginning of the tree
19068 col.slice(0, ind).each($.proxy(function (i, v) {
19069 if($(v).text().toLowerCase().indexOf(word) === 0) {
19070 $(v).focus();
19071 end = true;
19072 return false;
19073 }
19074 }, this));
19075 if(end) { return; }
19076 }
19077 // list nodes that start with that letter (only if word consists of a single char)
19078 if(new RegExp('^' + chr + '+$').test(word)) {
19079 // search for the next node starting with that letter
19080 col.slice(ind + 1).each($.proxy(function (i, v) {
19081 if($(v).text().toLowerCase().charAt(0) === chr) {
19082 $(v).focus();
19083 end = true;
19084 return false;
19085 }
19086 }, this));
19087 if(end) { return; }
19088
19089 // search from the beginning
19090 col.slice(0, ind + 1).each($.proxy(function (i, v) {
19091 if($(v).text().toLowerCase().charAt(0) === chr) {
19092 $(v).focus();
19093 end = true;
19094 return false;
19095 }
19096 }, this));
19097 if(end) { return; }
19098 }
19099 }, this))
19100 // THEME RELATED
19101 .on("init.jstree", $.proxy(function () {
19102 var s = this.settings.core.themes;
19103 this._data.core.themes.dots = s.dots;
19104 this._data.core.themes.stripes = s.stripes;
19105 this._data.core.themes.icons = s.icons;
19106 this.set_theme(s.name || "default", s.url);
19107 this.set_theme_variant(s.variant);
19108 }, this))
19109 .on("loading.jstree", $.proxy(function () {
19110 this[ this._data.core.themes.dots ? "show_dots" : "hide_dots" ]();
19111 this[ this._data.core.themes.icons ? "show_icons" : "hide_icons" ]();
19112 this[ this._data.core.themes.stripes ? "show_stripes" : "hide_stripes" ]();
19113 }, this))
19114 .on('blur.jstree', '.jstree-anchor', $.proxy(function (e) {
19115 this._data.core.focused = null;
19116 $(e.currentTarget).filter('.jstree-hovered').mouseleave();
19117 this.element.attr('tabindex', '0');
19118 }, this))
19119 .on('focus.jstree', '.jstree-anchor', $.proxy(function (e) {
19120 var tmp = this.get_node(e.currentTarget);
19121 if(tmp && tmp.id) {
19122 this._data.core.focused = tmp.id;
19123 }
19124 this.element.find('.jstree-hovered').not(e.currentTarget).mouseleave();
19125 $(e.currentTarget).mouseenter();
19126 this.element.attr('tabindex', '-1');
19127 }, this))
19128 .on('focus.jstree', $.proxy(function () {
19129 if(+(new Date()) - was_click > 500 && !this._data.core.focused) {
19130 was_click = 0;
19131 this.get_node(this.element.attr('aria-activedescendant'), true).find('> .jstree-anchor').focus();
19132 }
19133 }, this))
19134 .on('mouseenter.jstree', '.jstree-anchor', $.proxy(function (e) {
19135 this.hover_node(e.currentTarget);
19136 }, this))
19137 .on('mouseleave.jstree', '.jstree-anchor', $.proxy(function (e) {
19138 this.dehover_node(e.currentTarget);
19139 }, this));
19140 },
19141 /**
19142 * part of the destroying of an instance. Used internally.
19143 * @private
19144 * @name unbind()
19145 */
19146 unbind : function () {
19147 this.element.off('.jstree');
19148 $(document).off('.jstree-' + this._id);
19149 },
19150 /**
19151 * trigger an event. Used internally.
19152 * @private
19153 * @name trigger(ev [, data])
19154 * @param {String} ev the name of the event to trigger
19155 * @param {Object} data additional data to pass with the event
19156 */
19157 trigger : function (ev, data) {
19158 if(!data) {
19159 data = {};
19160 }
19161 data.instance = this;
19162 this.element.triggerHandler(ev.replace('.jstree','') + '.jstree', data);
19163 },
19164 /**
19165 * returns the jQuery extended instance container
19166 * @name get_container()
19167 * @return {jQuery}
19168 */
19169 get_container : function () {
19170 return this.element;
19171 },
19172 /**
19173 * returns the jQuery extended main UL node inside the instance container. Used internally.
19174 * @private
19175 * @name get_container_ul()
19176 * @return {jQuery}
19177 */
19178 get_container_ul : function () {
19179 return this.element.children(".jstree-children").first();
19180 },
19181 /**
19182 * gets string replacements (localization). Used internally.
19183 * @private
19184 * @name get_string(key)
19185 * @param {String} key
19186 * @return {String}
19187 */
19188 get_string : function (key) {
19189 var a = this.settings.core.strings;
19190 if($.isFunction(a)) { return a.call(this, key); }
19191 if(a && a[key]) { return a[key]; }
19192 return key;
19193 },
19194 /**
19195 * gets the first child of a DOM node. Used internally.
19196 * @private
19197 * @name _firstChild(dom)
19198 * @param {DOMElement} dom
19199 * @return {DOMElement}
19200 */
19201 _firstChild : function (dom) {
19202 dom = dom ? dom.firstChild : null;
19203 while(dom !== null && dom.nodeType !== 1) {
19204 dom = dom.nextSibling;
19205 }
19206 return dom;
19207 },
19208 /**
19209 * gets the next sibling of a DOM node. Used internally.
19210 * @private
19211 * @name _nextSibling(dom)
19212 * @param {DOMElement} dom
19213 * @return {DOMElement}
19214 */
19215 _nextSibling : function (dom) {
19216 dom = dom ? dom.nextSibling : null;
19217 while(dom !== null && dom.nodeType !== 1) {
19218 dom = dom.nextSibling;
19219 }
19220 return dom;
19221 },
19222 /**
19223 * gets the previous sibling of a DOM node. Used internally.
19224 * @private
19225 * @name _previousSibling(dom)
19226 * @param {DOMElement} dom
19227 * @return {DOMElement}
19228 */
19229 _previousSibling : function (dom) {
19230 dom = dom ? dom.previousSibling : null;
19231 while(dom !== null && dom.nodeType !== 1) {
19232 dom = dom.previousSibling;
19233 }
19234 return dom;
19235 },
19236 /**
19237 * get the JSON representation of a node (or the actual jQuery extended DOM node) by using any input (child DOM element, ID string, selector, etc)
19238 * @name get_node(obj [, as_dom])
19239 * @param {mixed} obj
19240 * @param {Boolean} as_dom
19241 * @return {Object|jQuery}
19242 */
19243 get_node : function (obj, as_dom) {
19244 if(obj && obj.id) {
19245 obj = obj.id;
19246 }
19247 var dom;
19248 try {
19249 if(this._model.data[obj]) {
19250 obj = this._model.data[obj];
19251 }
19252 else if(typeof obj === "string" && this._model.data[obj.replace(/^#/, '')]) {
19253 obj = this._model.data[obj.replace(/^#/, '')];
19254 }
19255 else if(typeof obj === "string" && (dom = $('#' + obj.replace($.jstree.idregex,'\\$&'), this.element)).length && this._model.data[dom.closest('.jstree-node').attr('id')]) {
19256 obj = this._model.data[dom.closest('.jstree-node').attr('id')];
19257 }
19258 else if((dom = $(obj, this.element)).length && this._model.data[dom.closest('.jstree-node').attr('id')]) {
19259 obj = this._model.data[dom.closest('.jstree-node').attr('id')];
19260 }
19261 else if((dom = $(obj, this.element)).length && dom.hasClass('jstree')) {
19262 obj = this._model.data['#'];
19263 }
19264 else {
19265 return false;
19266 }
19267
19268 if(as_dom) {
19269 obj = obj.id === '#' ? this.element : $('#' + obj.id.replace($.jstree.idregex,'\\$&'), this.element);
19270 }
19271 return obj;
19272 } catch (ex) { return false; }
19273 },
19274 /**
19275 * get the path to a node, either consisting of node texts, or of node IDs, optionally glued together (otherwise an array)
19276 * @name get_path(obj [, glue, ids])
19277 * @param {mixed} obj the node
19278 * @param {String} glue if you want the path as a string - pass the glue here (for example '/'), if a falsy value is supplied here, an array is returned
19279 * @param {Boolean} ids if set to true build the path using ID, otherwise node text is used
19280 * @return {mixed}
19281 */
19282 get_path : function (obj, glue, ids) {
19283 obj = obj.parents ? obj : this.get_node(obj);
19284 if(!obj || obj.id === '#' || !obj.parents) {
19285 return false;
19286 }
19287 var i, j, p = [];
19288 p.push(ids ? obj.id : obj.text);
19289 for(i = 0, j = obj.parents.length; i < j; i++) {
19290 p.push(ids ? obj.parents[i] : this.get_text(obj.parents[i]));
19291 }
19292 p = p.reverse().slice(1);
19293 return glue ? p.join(glue) : p;
19294 },
19295 /**
19296 * get the next visible node that is below the `obj` node. If `strict` is set to `true` only sibling nodes are returned.
19297 * @name get_next_dom(obj [, strict])
19298 * @param {mixed} obj
19299 * @param {Boolean} strict
19300 * @return {jQuery}
19301 */
19302 get_next_dom : function (obj, strict) {
19303 var tmp;
19304 obj = this.get_node(obj, true);
19305 if(obj[0] === this.element[0]) {
19306 tmp = this._firstChild(this.get_container_ul()[0]);
19307 while (tmp && tmp.offsetHeight === 0) {
19308 tmp = this._nextSibling(tmp);
19309 }
19310 return tmp ? $(tmp) : false;
19311 }
19312 if(!obj || !obj.length) {
19313 return false;
19314 }
19315 if(strict) {
19316 tmp = obj[0];
19317 do {
19318 tmp = this._nextSibling(tmp);
19319 } while (tmp && tmp.offsetHeight === 0);
19320 return tmp ? $(tmp) : false;
19321 }
19322 if(obj.hasClass("jstree-open")) {
19323 tmp = this._firstChild(obj.children('.jstree-children')[0]);
19324 while (tmp && tmp.offsetHeight === 0) {
19325 tmp = this._nextSibling(tmp);
19326 }
19327 if(tmp !== null) {
19328 return $(tmp);
19329 }
19330 }
19331 tmp = obj[0];
19332 do {
19333 tmp = this._nextSibling(tmp);
19334 } while (tmp && tmp.offsetHeight === 0);
19335 if(tmp !== null) {
19336 return $(tmp);
19337 }
19338 return obj.parentsUntil(".jstree",".jstree-node").next(".jstree-node:visible").first();
19339 },
19340 /**
19341 * get the previous visible node that is above the `obj` node. If `strict` is set to `true` only sibling nodes are returned.
19342 * @name get_prev_dom(obj [, strict])
19343 * @param {mixed} obj
19344 * @param {Boolean} strict
19345 * @return {jQuery}
19346 */
19347 get_prev_dom : function (obj, strict) {
19348 var tmp;
19349 obj = this.get_node(obj, true);
19350 if(obj[0] === this.element[0]) {
19351 tmp = this.get_container_ul()[0].lastChild;
19352 while (tmp && tmp.offsetHeight === 0) {
19353 tmp = this._previousSibling(tmp);
19354 }
19355 return tmp ? $(tmp) : false;
19356 }
19357 if(!obj || !obj.length) {
19358 return false;
19359 }
19360 if(strict) {
19361 tmp = obj[0];
19362 do {
19363 tmp = this._previousSibling(tmp);
19364 } while (tmp && tmp.offsetHeight === 0);
19365 return tmp ? $(tmp) : false;
19366 }
19367 tmp = obj[0];
19368 do {
19369 tmp = this._previousSibling(tmp);
19370 } while (tmp && tmp.offsetHeight === 0);
19371 if(tmp !== null) {
19372 obj = $(tmp);
19373 while(obj.hasClass("jstree-open")) {
19374 obj = obj.children(".jstree-children").first().children(".jstree-node:visible:last");
19375 }
19376 return obj;
19377 }
19378 tmp = obj[0].parentNode.parentNode;
19379 return tmp && tmp.className && tmp.className.indexOf('jstree-node') !== -1 ? $(tmp) : false;
19380 },
19381 /**
19382 * get the parent ID of a node
19383 * @name get_parent(obj)
19384 * @param {mixed} obj
19385 * @return {String}
19386 */
19387 get_parent : function (obj) {
19388 obj = this.get_node(obj);
19389 if(!obj || obj.id === '#') {
19390 return false;
19391 }
19392 return obj.parent;
19393 },
19394 /**
19395 * get a jQuery collection of all the children of a node (node must be rendered)
19396 * @name get_children_dom(obj)
19397 * @param {mixed} obj
19398 * @return {jQuery}
19399 */
19400 get_children_dom : function (obj) {
19401 obj = this.get_node(obj, true);
19402 if(obj[0] === this.element[0]) {
19403 return this.get_container_ul().children(".jstree-node");
19404 }
19405 if(!obj || !obj.length) {
19406 return false;
19407 }
19408 return obj.children(".jstree-children").children(".jstree-node");
19409 },
19410 /**
19411 * checks if a node has children
19412 * @name is_parent(obj)
19413 * @param {mixed} obj
19414 * @return {Boolean}
19415 */
19416 is_parent : function (obj) {
19417 obj = this.get_node(obj);
19418 return obj && (obj.state.loaded === false || obj.children.length > 0);
19419 },
19420 /**
19421 * checks if a node is loaded (its children are available)
19422 * @name is_loaded(obj)
19423 * @param {mixed} obj
19424 * @return {Boolean}
19425 */
19426 is_loaded : function (obj) {
19427 obj = this.get_node(obj);
19428 return obj && obj.state.loaded;
19429 },
19430 /**
19431 * check if a node is currently loading (fetching children)
19432 * @name is_loading(obj)
19433 * @param {mixed} obj
19434 * @return {Boolean}
19435 */
19436 is_loading : function (obj) {
19437 obj = this.get_node(obj);
19438 return obj && obj.state && obj.state.loading;
19439 },
19440 /**
19441 * check if a node is opened
19442 * @name is_open(obj)
19443 * @param {mixed} obj
19444 * @return {Boolean}
19445 */
19446 is_open : function (obj) {
19447 obj = this.get_node(obj);
19448 return obj && obj.state.opened;
19449 },
19450 /**
19451 * check if a node is in a closed state
19452 * @name is_closed(obj)
19453 * @param {mixed} obj
19454 * @return {Boolean}
19455 */
19456 is_closed : function (obj) {
19457 obj = this.get_node(obj);
19458 return obj && this.is_parent(obj) && !obj.state.opened;
19459 },
19460 /**
19461 * check if a node has no children
19462 * @name is_leaf(obj)
19463 * @param {mixed} obj
19464 * @return {Boolean}
19465 */
19466 is_leaf : function (obj) {
19467 return !this.is_parent(obj);
19468 },
19469 /**
19470 * loads a node (fetches its children using the `core.data` setting). Multiple nodes can be passed to by using an array.
19471 * @name load_node(obj [, callback])
19472 * @param {mixed} obj
19473 * @param {function} callback a function to be executed once loading is complete, the function is executed in the instance's scope and receives two arguments - the node and a boolean status
19474 * @return {Boolean}
19475 * @trigger load_node.jstree
19476 */
19477 load_node : function (obj, callback) {
19478 var k, l, i, j, c;
19479 if($.isArray(obj)) {
19480 this._load_nodes(obj.slice(), callback);
19481 return true;
19482 }
19483 obj = this.get_node(obj);
19484 if(!obj) {
19485 if(callback) { callback.call(this, obj, false); }
19486 return false;
19487 }
19488 // if(obj.state.loading) { } // the node is already loading - just wait for it to load and invoke callback? but if called implicitly it should be loaded again?
19489 if(obj.state.loaded) {
19490 obj.state.loaded = false;
19491 for(k = 0, l = obj.children_d.length; k < l; k++) {
19492 for(i = 0, j = obj.parents.length; i < j; i++) {
19493 this._model.data[obj.parents[i]].children_d = $.vakata.array_remove_item(this._model.data[obj.parents[i]].children_d, obj.children_d[k]);
19494 }
19495 if(this._model.data[obj.children_d[k]].state.selected) {
19496 c = true;
19497 this._data.core.selected = $.vakata.array_remove_item(this._data.core.selected, obj.children_d[k]);
19498 }
19499 delete this._model.data[obj.children_d[k]];
19500 }
19501 obj.children = [];
19502 obj.children_d = [];
19503 if(c) {
19504 this.trigger('changed', { 'action' : 'load_node', 'node' : obj, 'selected' : this._data.core.selected });
19505 }
19506 }
19507 obj.state.loading = true;
19508 this.get_node(obj, true).addClass("jstree-loading").attr('aria-busy',true);
19509 this._load_node(obj, $.proxy(function (status) {
19510 obj = this._model.data[obj.id];
19511 obj.state.loading = false;
19512 obj.state.loaded = status;
19513 var dom = this.get_node(obj, true);
19514 if(obj.state.loaded && !obj.children.length && dom && dom.length && !dom.hasClass('jstree-leaf')) {
19515 dom.removeClass('jstree-closed jstree-open').addClass('jstree-leaf');
19516 }
19517 dom.removeClass("jstree-loading").attr('aria-busy',false);
19518 /**
19519 * triggered after a node is loaded
19520 * @event
19521 * @name load_node.jstree
19522 * @param {Object} node the node that was loading
19523 * @param {Boolean} status was the node loaded successfully
19524 */
19525 this.trigger('load_node', { "node" : obj, "status" : status });
19526 if(callback) {
19527 callback.call(this, obj, status);
19528 }
19529 }, this));
19530 return true;
19531 },
19532 /**
19533 * load an array of nodes (will also load unavailable nodes as soon as the appear in the structure). Used internally.
19534 * @private
19535 * @name _load_nodes(nodes [, callback])
19536 * @param {array} nodes
19537 * @param {function} callback a function to be executed once loading is complete, the function is executed in the instance's scope and receives one argument - the array passed to _load_nodes
19538 */
19539 _load_nodes : function (nodes, callback, is_callback) {
19540 var r = true,
19541 c = function () { this._load_nodes(nodes, callback, true); },
19542 m = this._model.data, i, j;
19543 for(i = 0, j = nodes.length; i < j; i++) {
19544 if(m[nodes[i]] && (!m[nodes[i]].state.loaded || !is_callback)) {
19545 if(!this.is_loading(nodes[i])) {
19546 this.load_node(nodes[i], c);
19547 }
19548 r = false;
19549 }
19550 }
19551 if(r) {
19552 if(callback && !callback.done) {
19553 callback.call(this, nodes);
19554 callback.done = true;
19555 }
19556 }
19557 },
19558 /**
19559 * loads all unloaded nodes
19560 * @name load_all([obj, callback])
19561 * @param {mixed} obj the node to load recursively, omit to load all nodes in the tree
19562 * @param {function} callback a function to be executed once loading all the nodes is complete,
19563 * @trigger load_all.jstree
19564 */
19565 load_all : function (obj, callback) {
19566 if(!obj) { obj = '#'; }
19567 obj = this.get_node(obj);
19568 if(!obj) { return false; }
19569 var to_load = [],
19570 m = this._model.data,
19571 c = m[obj.id].children_d,
19572 i, j;
19573 if(obj.state && !obj.state.loaded) {
19574 to_load.push(obj.id);
19575 }
19576 for(i = 0, j = c.length; i < j; i++) {
19577 if(m[c[i]] && m[c[i]].state && !m[c[i]].state.loaded) {
19578 to_load.push(c[i]);
19579 }
19580 }
19581 if(to_load.length) {
19582 this._load_nodes(to_load, function () {
19583 this.load_all(obj, callback);
19584 });
19585 }
19586 else {
19587 /**
19588 * triggered after a load_all call completes
19589 * @event
19590 * @name load_all.jstree
19591 * @param {Object} node the recursively loaded node
19592 */
19593 if(callback) { callback.call(this, obj); }
19594 this.trigger('load_all', { "node" : obj });
19595 }
19596 },
19597 /**
19598 * handles the actual loading of a node. Used only internally.
19599 * @private
19600 * @name _load_node(obj [, callback])
19601 * @param {mixed} obj
19602 * @param {function} callback a function to be executed once loading is complete, the function is executed in the instance's scope and receives one argument - a boolean status
19603 * @return {Boolean}
19604 */
19605 _load_node : function (obj, callback) {
19606 var s = this.settings.core.data, t;
19607 // use original HTML
19608 if(!s) {
19609 if(obj.id === '#') {
19610 return this._append_html_data(obj, this._data.core.original_container_html.clone(true), function (status) {
19611 callback.call(this, status);
19612 });
19613 }
19614 else {
19615 return callback.call(this, false);
19616 }
19617 // return callback.call(this, obj.id === '#' ? this._append_html_data(obj, this._data.core.original_container_html.clone(true)) : false);
19618 }
19619 if($.isFunction(s)) {
19620 return s.call(this, obj, $.proxy(function (d) {
19621 if(d === false) {
19622 callback.call(this, false);
19623 }
19624 this[typeof d === 'string' ? '_append_html_data' : '_append_json_data'](obj, typeof d === 'string' ? $(d) : d, function (status) {
19625 callback.call(this, status);
19626 });
19627 // return d === false ? callback.call(this, false) : callback.call(this, this[typeof d === 'string' ? '_append_html_data' : '_append_json_data'](obj, typeof d === 'string' ? $(d) : d));
19628 }, this));
19629 }
19630 if(typeof s === 'object') {
19631 if(s.url) {
19632 s = $.extend(true, {}, s);
19633 if($.isFunction(s.url)) {
19634 s.url = s.url.call(this, obj);
19635 }
19636 if($.isFunction(s.data)) {
19637 s.data = s.data.call(this, obj);
19638 }
19639 return $.ajax(s)
19640 .done($.proxy(function (d,t,x) {
19641 var type = x.getResponseHeader('Content-Type');
19642 if(type.indexOf('json') !== -1 || typeof d === "object") {
19643 return this._append_json_data(obj, d, function (status) { callback.call(this, status); });
19644 //return callback.call(this, this._append_json_data(obj, d));
19645 }
19646 if(type.indexOf('html') !== -1 || typeof d === "string") {
19647 return this._append_html_data(obj, $(d), function (status) { callback.call(this, status); });
19648 // return callback.call(this, this._append_html_data(obj, $(d)));
19649 }
19650 this._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'core', 'id' : 'core_04', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id, 'xhr' : x }) };
19651 this.settings.core.error.call(this, this._data.core.last_error);
19652 return callback.call(this, false);
19653 }, this))
19654 .fail($.proxy(function (f) {
19655 callback.call(this, false);
19656 this._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'core', 'id' : 'core_04', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id, 'xhr' : f }) };
19657 this.settings.core.error.call(this, this._data.core.last_error);
19658 }, this));
19659 }
19660 t = ($.isArray(s) || $.isPlainObject(s)) ? JSON.parse(JSON.stringify(s)) : s;
19661 if(obj.id === '#') {
19662 return this._append_json_data(obj, t, function (status) {
19663 callback.call(this, status);
19664 });
19665 }
19666 else {
19667 this._data.core.last_error = { 'error' : 'nodata', 'plugin' : 'core', 'id' : 'core_05', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id }) };
19668 this.settings.core.error.call(this, this._data.core.last_error);
19669 return callback.call(this, false);
19670 }
19671 //return callback.call(this, (obj.id === "#" ? this._append_json_data(obj, t) : false) );
19672 }
19673 if(typeof s === 'string') {
19674 if(obj.id === '#') {
19675 return this._append_html_data(obj, $(s), function (status) {
19676 callback.call(this, status);
19677 });
19678 }
19679 else {
19680 this._data.core.last_error = { 'error' : 'nodata', 'plugin' : 'core', 'id' : 'core_06', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id }) };
19681 this.settings.core.error.call(this, this._data.core.last_error);
19682 return callback.call(this, false);
19683 }
19684 //return callback.call(this, (obj.id === "#" ? this._append_html_data(obj, $(s)) : false) );
19685 }
19686 return callback.call(this, false);
19687 },
19688 /**
19689 * adds a node to the list of nodes to redraw. Used only internally.
19690 * @private
19691 * @name _node_changed(obj [, callback])
19692 * @param {mixed} obj
19693 */
19694 _node_changed : function (obj) {
19695 obj = this.get_node(obj);
19696 if(obj) {
19697 this._model.changed.push(obj.id);
19698 }
19699 },
19700 /**
19701 * appends HTML content to the tree. Used internally.
19702 * @private
19703 * @name _append_html_data(obj, data)
19704 * @param {mixed} obj the node to append to
19705 * @param {String} data the HTML string to parse and append
19706 * @trigger model.jstree, changed.jstree
19707 */
19708 _append_html_data : function (dom, data, cb) {
19709 dom = this.get_node(dom);
19710 dom.children = [];
19711 dom.children_d = [];
19712 var dat = data.is('ul') ? data.children() : data,
19713 par = dom.id,
19714 chd = [],
19715 dpc = [],
19716 m = this._model.data,
19717 p = m[par],
19718 s = this._data.core.selected.length,
19719 tmp, i, j;
19720 dat.each($.proxy(function (i, v) {
19721 tmp = this._parse_model_from_html($(v), par, p.parents.concat());
19722 if(tmp) {
19723 chd.push(tmp);
19724 dpc.push(tmp);
19725 if(m[tmp].children_d.length) {
19726 dpc = dpc.concat(m[tmp].children_d);
19727 }
19728 }
19729 }, this));
19730 p.children = chd;
19731 p.children_d = dpc;
19732 for(i = 0, j = p.parents.length; i < j; i++) {
19733 m[p.parents[i]].children_d = m[p.parents[i]].children_d.concat(dpc);
19734 }
19735 /**
19736 * triggered when new data is inserted to the tree model
19737 * @event
19738 * @name model.jstree
19739 * @param {Array} nodes an array of node IDs
19740 * @param {String} parent the parent ID of the nodes
19741 */
19742 this.trigger('model', { "nodes" : dpc, 'parent' : par });
19743 if(par !== '#') {
19744 this._node_changed(par);
19745 this.redraw();
19746 }
19747 else {
19748 this.get_container_ul().children('.jstree-initial-node').remove();
19749 this.redraw(true);
19750 }
19751 if(this._data.core.selected.length !== s) {
19752 this.trigger('changed', { 'action' : 'model', 'selected' : this._data.core.selected });
19753 }
19754 cb.call(this, true);
19755 },
19756 /**
19757 * appends JSON content to the tree. Used internally.
19758 * @private
19759 * @name _append_json_data(obj, data)
19760 * @param {mixed} obj the node to append to
19761 * @param {String} data the JSON object to parse and append
19762 * @param {Boolean} force_processing internal param - do not set
19763 * @trigger model.jstree, changed.jstree
19764 */
19765 _append_json_data : function (dom, data, cb, force_processing) {
19766 dom = this.get_node(dom);
19767 dom.children = [];
19768 dom.children_d = [];
19769 // *%$@!!!
19770 if(data.d) {
19771 data = data.d;
19772 if(typeof data === "string") {
19773 data = JSON.parse(data);
19774 }
19775 }
19776 if(!$.isArray(data)) { data = [data]; }
19777 var w = null,
19778 args = {
19779 'df' : this._model.default_state,
19780 'dat' : data,
19781 'par' : dom.id,
19782 'm' : this._model.data,
19783 't_id' : this._id,
19784 't_cnt' : this._cnt,
19785 'sel' : this._data.core.selected
19786 },
19787 func = function (data, undefined) {
19788 if(data.data) { data = data.data; }
19789 var dat = data.dat,
19790 par = data.par,
19791 chd = [],
19792 dpc = [],
19793 add = [],
19794 df = data.df,
19795 t_id = data.t_id,
19796 t_cnt = data.t_cnt,
19797 m = data.m,
19798 p = m[par],
19799 sel = data.sel,
19800 tmp, i, j, rslt,
19801 parse_flat = function (d, p, ps) {
19802 if(!ps) { ps = []; }
19803 else { ps = ps.concat(); }
19804 if(p) { ps.unshift(p); }
19805 var tid = d.id.toString(),
19806 i, j, c, e,
19807 tmp = {
19808 id : tid,
19809 text : d.text || '',
19810 icon : d.icon !== undefined ? d.icon : true,
19811 parent : p,
19812 parents : ps,
19813 children : d.children || [],
19814 children_d : d.children_d || [],
19815 data : d.data,
19816 state : { },
19817 li_attr : { id : false },
19818 a_attr : { href : '#' },
19819 original : false
19820 };
19821 for(i in df) {
19822 if(df.hasOwnProperty(i)) {
19823 tmp.state[i] = df[i];
19824 }
19825 }
19826 if(d && d.data && d.data.jstree && d.data.jstree.icon) {
19827 tmp.icon = d.data.jstree.icon;
19828 }
19829 if(d && d.data) {
19830 tmp.data = d.data;
19831 if(d.data.jstree) {
19832 for(i in d.data.jstree) {
19833 if(d.data.jstree.hasOwnProperty(i)) {
19834 tmp.state[i] = d.data.jstree[i];
19835 }
19836 }
19837 }
19838 }
19839 if(d && typeof d.state === 'object') {
19840 for (i in d.state) {
19841 if(d.state.hasOwnProperty(i)) {
19842 tmp.state[i] = d.state[i];
19843 }
19844 }
19845 }
19846 if(d && typeof d.li_attr === 'object') {
19847 for (i in d.li_attr) {
19848 if(d.li_attr.hasOwnProperty(i)) {
19849 tmp.li_attr[i] = d.li_attr[i];
19850 }
19851 }
19852 }
19853 if(!tmp.li_attr.id) {
19854 tmp.li_attr.id = tid;
19855 }
19856 if(d && typeof d.a_attr === 'object') {
19857 for (i in d.a_attr) {
19858 if(d.a_attr.hasOwnProperty(i)) {
19859 tmp.a_attr[i] = d.a_attr[i];
19860 }
19861 }
19862 }
19863 if(d && d.children && d.children === true) {
19864 tmp.state.loaded = false;
19865 tmp.children = [];
19866 tmp.children_d = [];
19867 }
19868 m[tmp.id] = tmp;
19869 for(i = 0, j = tmp.children.length; i < j; i++) {
19870 c = parse_flat(m[tmp.children[i]], tmp.id, ps);
19871 e = m[c];
19872 tmp.children_d.push(c);
19873 if(e.children_d.length) {
19874 tmp.children_d = tmp.children_d.concat(e.children_d);
19875 }
19876 }
19877 delete d.data;
19878 delete d.children;
19879 m[tmp.id].original = d;
19880 if(tmp.state.selected) {
19881 add.push(tmp.id);
19882 }
19883 return tmp.id;
19884 },
19885 parse_nest = function (d, p, ps) {
19886 if(!ps) { ps = []; }
19887 else { ps = ps.concat(); }
19888 if(p) { ps.unshift(p); }
19889 var tid = false, i, j, c, e, tmp;
19890 do {
19891 tid = 'j' + t_id + '_' + (++t_cnt);
19892 } while(m[tid]);
19893
19894 tmp = {
19895 id : false,
19896 text : typeof d === 'string' ? d : '',
19897 icon : typeof d === 'object' && d.icon !== undefined ? d.icon : true,
19898 parent : p,
19899 parents : ps,
19900 children : [],
19901 children_d : [],
19902 data : null,
19903 state : { },
19904 li_attr : { id : false },
19905 a_attr : { href : '#' },
19906 original : false
19907 };
19908 for(i in df) {
19909 if(df.hasOwnProperty(i)) {
19910 tmp.state[i] = df[i];
19911 }
19912 }
19913 if(d && d.id) { tmp.id = d.id.toString(); }
19914 if(d && d.text) { tmp.text = d.text; }
19915 if(d && d.data && d.data.jstree && d.data.jstree.icon) {
19916 tmp.icon = d.data.jstree.icon;
19917 }
19918 if(d && d.data) {
19919 tmp.data = d.data;
19920 if(d.data.jstree) {
19921 for(i in d.data.jstree) {
19922 if(d.data.jstree.hasOwnProperty(i)) {
19923 tmp.state[i] = d.data.jstree[i];
19924 }
19925 }
19926 }
19927 }
19928 if(d && typeof d.state === 'object') {
19929 for (i in d.state) {
19930 if(d.state.hasOwnProperty(i)) {
19931 tmp.state[i] = d.state[i];
19932 }
19933 }
19934 }
19935 if(d && typeof d.li_attr === 'object') {
19936 for (i in d.li_attr) {
19937 if(d.li_attr.hasOwnProperty(i)) {
19938 tmp.li_attr[i] = d.li_attr[i];
19939 }
19940 }
19941 }
19942 if(tmp.li_attr.id && !tmp.id) {
19943 tmp.id = tmp.li_attr.id.toString();
19944 }
19945 if(!tmp.id) {
19946 tmp.id = tid;
19947 }
19948 if(!tmp.li_attr.id) {
19949 tmp.li_attr.id = tmp.id;
19950 }
19951 if(d && typeof d.a_attr === 'object') {
19952 for (i in d.a_attr) {
19953 if(d.a_attr.hasOwnProperty(i)) {
19954 tmp.a_attr[i] = d.a_attr[i];
19955 }
19956 }
19957 }
19958 if(d && d.children && d.children.length) {
19959 for(i = 0, j = d.children.length; i < j; i++) {
19960 c = parse_nest(d.children[i], tmp.id, ps);
19961 e = m[c];
19962 tmp.children.push(c);
19963 if(e.children_d.length) {
19964 tmp.children_d = tmp.children_d.concat(e.children_d);
19965 }
19966 }
19967 tmp.children_d = tmp.children_d.concat(tmp.children);
19968 }
19969 if(d && d.children && d.children === true) {
19970 tmp.state.loaded = false;
19971 tmp.children = [];
19972 tmp.children_d = [];
19973 }
19974 delete d.data;
19975 delete d.children;
19976 tmp.original = d;
19977 m[tmp.id] = tmp;
19978 if(tmp.state.selected) {
19979 add.push(tmp.id);
19980 }
19981 return tmp.id;
19982 };
19983
19984 if(dat.length && dat[0].id !== undefined && dat[0].parent !== undefined) {
19985 // Flat JSON support (for easy import from DB):
19986 // 1) convert to object (foreach)
19987 for(i = 0, j = dat.length; i < j; i++) {
19988 if(!dat[i].children) {
19989 dat[i].children = [];
19990 }
19991 m[dat[i].id.toString()] = dat[i];
19992 }
19993 // 2) populate children (foreach)
19994 for(i = 0, j = dat.length; i < j; i++) {
19995 m[dat[i].parent.toString()].children.push(dat[i].id.toString());
19996 // populate parent.children_d
19997 p.children_d.push(dat[i].id.toString());
19998 }
19999 // 3) normalize && populate parents and children_d with recursion
20000 for(i = 0, j = p.children.length; i < j; i++) {
20001 tmp = parse_flat(m[p.children[i]], par, p.parents.concat());
20002 dpc.push(tmp);
20003 if(m[tmp].children_d.length) {
20004 dpc = dpc.concat(m[tmp].children_d);
20005 }
20006 }
20007 for(i = 0, j = p.parents.length; i < j; i++) {
20008 m[p.parents[i]].children_d = m[p.parents[i]].children_d.concat(dpc);
20009 }
20010 // ?) three_state selection - p.state.selected && t - (if three_state foreach(dat => ch) -> foreach(parents) if(parent.selected) child.selected = true;
20011 rslt = {
20012 'cnt' : t_cnt,
20013 'mod' : m,
20014 'sel' : sel,
20015 'par' : par,
20016 'dpc' : dpc,
20017 'add' : add
20018 };
20019 }
20020 else {
20021 for(i = 0, j = dat.length; i < j; i++) {
20022 tmp = parse_nest(dat[i], par, p.parents.concat());
20023 if(tmp) {
20024 chd.push(tmp);
20025 dpc.push(tmp);
20026 if(m[tmp].children_d.length) {
20027 dpc = dpc.concat(m[tmp].children_d);
20028 }
20029 }
20030 }
20031 p.children = chd;
20032 p.children_d = dpc;
20033 for(i = 0, j = p.parents.length; i < j; i++) {
20034 m[p.parents[i]].children_d = m[p.parents[i]].children_d.concat(dpc);
20035 }
20036 rslt = {
20037 'cnt' : t_cnt,
20038 'mod' : m,
20039 'sel' : sel,
20040 'par' : par,
20041 'dpc' : dpc,
20042 'add' : add
20043 };
20044 }
20045 if(typeof window === 'undefined' || typeof window.document === 'undefined') {
20046 postMessage(rslt);
20047 }
20048 else {
20049 return rslt;
20050 }
20051 },
20052 rslt = function (rslt, worker) {
20053 this._cnt = rslt.cnt;
20054 this._model.data = rslt.mod; // breaks the reference in load_node - careful
20055
20056 if(worker) {
20057 var i, j, a = rslt.add, r = rslt.sel, s = this._data.core.selected.slice(), m = this._model.data;
20058 // if selection was changed while calculating in worker
20059 if(r.length !== s.length || $.vakata.array_unique(r.concat(s)).length !== r.length) {
20060 // deselect nodes that are no longer selected
20061 for(i = 0, j = r.length; i < j; i++) {
20062 if($.inArray(r[i], a) === -1 && $.inArray(r[i], s) === -1) {
20063 m[r[i]].state.selected = false;
20064 }
20065 }
20066 // select nodes that were selected in the mean time
20067 for(i = 0, j = s.length; i < j; i++) {
20068 if($.inArray(s[i], r) === -1) {
20069 m[s[i]].state.selected = true;
20070 }
20071 }
20072 }
20073 }
20074 if(rslt.add.length) {
20075 this._data.core.selected = this._data.core.selected.concat(rslt.add);
20076 }
20077
20078 this.trigger('model', { "nodes" : rslt.dpc, 'parent' : rslt.par });
20079
20080 if(rslt.par !== '#') {
20081 this._node_changed(rslt.par);
20082 this.redraw();
20083 }
20084 else {
20085 // this.get_container_ul().children('.jstree-initial-node').remove();
20086 this.redraw(true);
20087 }
20088 if(rslt.add.length) {
20089 this.trigger('changed', { 'action' : 'model', 'selected' : this._data.core.selected });
20090 }
20091 cb.call(this, true);
20092 };
20093 if(this.settings.core.worker && window.Blob && window.URL && window.Worker) {
20094 try {
20095 if(this._wrk === null) {
20096 this._wrk = window.URL.createObjectURL(
20097 new window.Blob(
20098 ['self.onmessage = ' + func.toString()],
20099 {type:"text/javascript"}
20100 )
20101 );
20102 }
20103 if(!this._data.core.working || force_processing) {
20104 this._data.core.working = true;
20105 w = new window.Worker(this._wrk);
20106 w.onmessage = $.proxy(function (e) {
20107 rslt.call(this, e.data, true);
20108 try { w.terminate(); w = null; } catch(ignore) { }
20109 if(this._data.core.worker_queue.length) {
20110 this._append_json_data.apply(this, this._data.core.worker_queue.shift());
20111 }
20112 else {
20113 this._data.core.working = false;
20114 }
20115 }, this);
20116 if(!args.par) {
20117 if(this._data.core.worker_queue.length) {
20118 this._append_json_data.apply(this, this._data.core.worker_queue.shift());
20119 }
20120 else {
20121 this._data.core.working = false;
20122 }
20123 }
20124 else {
20125 w.postMessage(args);
20126 }
20127 }
20128 else {
20129 this._data.core.worker_queue.push([dom, data, cb, true]);
20130 }
20131 }
20132 catch(e) {
20133 rslt.call(this, func(args), false);
20134 if(this._data.core.worker_queue.length) {
20135 this._append_json_data.apply(this, this._data.core.worker_queue.shift());
20136 }
20137 else {
20138 this._data.core.working = false;
20139 }
20140 }
20141 }
20142 else {
20143 rslt.call(this, func(args), false);
20144 }
20145 },
20146 /**
20147 * parses a node from a jQuery object and appends them to the in memory tree model. Used internally.
20148 * @private
20149 * @name _parse_model_from_html(d [, p, ps])
20150 * @param {jQuery} d the jQuery object to parse
20151 * @param {String} p the parent ID
20152 * @param {Array} ps list of all parents
20153 * @return {String} the ID of the object added to the model
20154 */
20155 _parse_model_from_html : function (d, p, ps) {
20156 if(!ps) { ps = []; }
20157 else { ps = [].concat(ps); }
20158 if(p) { ps.unshift(p); }
20159 var c, e, m = this._model.data,
20160 data = {
20161 id : false,
20162 text : false,
20163 icon : true,
20164 parent : p,
20165 parents : ps,
20166 children : [],
20167 children_d : [],
20168 data : null,
20169 state : { },
20170 li_attr : { id : false },
20171 a_attr : { href : '#' },
20172 original : false
20173 }, i, tmp, tid;
20174 for(i in this._model.default_state) {
20175 if(this._model.default_state.hasOwnProperty(i)) {
20176 data.state[i] = this._model.default_state[i];
20177 }
20178 }
20179 tmp = $.vakata.attributes(d, true);
20180 $.each(tmp, function (i, v) {
20181 v = $.trim(v);
20182 if(!v.length) { return true; }
20183 data.li_attr[i] = v;
20184 if(i === 'id') {
20185 data.id = v.toString();
20186 }
20187 });
20188 tmp = d.children('a').first();
20189 if(tmp.length) {
20190 tmp = $.vakata.attributes(tmp, true);
20191 $.each(tmp, function (i, v) {
20192 v = $.trim(v);
20193 if(v.length) {
20194 data.a_attr[i] = v;
20195 }
20196 });
20197 }
20198 tmp = d.children("a").first().length ? d.children("a").first().clone() : d.clone();
20199 tmp.children("ins, i, ul").remove();
20200 tmp = tmp.html();
20201 tmp = $('<div />').html(tmp);
20202 data.text = this.settings.core.force_text ? tmp.text() : tmp.html();
20203 tmp = d.data();
20204 data.data = tmp ? $.extend(true, {}, tmp) : null;
20205 data.state.opened = d.hasClass('jstree-open');
20206 data.state.selected = d.children('a').hasClass('jstree-clicked');
20207 data.state.disabled = d.children('a').hasClass('jstree-disabled');
20208 if(data.data && data.data.jstree) {
20209 for(i in data.data.jstree) {
20210 if(data.data.jstree.hasOwnProperty(i)) {
20211 data.state[i] = data.data.jstree[i];
20212 }
20213 }
20214 }
20215 tmp = d.children("a").children(".jstree-themeicon");
20216 if(tmp.length) {
20217 data.icon = tmp.hasClass('jstree-themeicon-hidden') ? false : tmp.attr('rel');
20218 }
20219 if(data.state.icon) {
20220 data.icon = data.state.icon;
20221 }
20222 tmp = d.children("ul").children("li");
20223 do {
20224 tid = 'j' + this._id + '_' + (++this._cnt);
20225 } while(m[tid]);
20226 data.id = data.li_attr.id ? data.li_attr.id.toString() : tid;
20227 if(tmp.length) {
20228 tmp.each($.proxy(function (i, v) {
20229 c = this._parse_model_from_html($(v), data.id, ps);
20230 e = this._model.data[c];
20231 data.children.push(c);
20232 if(e.children_d.length) {
20233 data.children_d = data.children_d.concat(e.children_d);
20234 }
20235 }, this));
20236 data.children_d = data.children_d.concat(data.children);
20237 }
20238 else {
20239 if(d.hasClass('jstree-closed')) {
20240 data.state.loaded = false;
20241 }
20242 }
20243 if(data.li_attr['class']) {
20244 data.li_attr['class'] = data.li_attr['class'].replace('jstree-closed','').replace('jstree-open','');
20245 }
20246 if(data.a_attr['class']) {
20247 data.a_attr['class'] = data.a_attr['class'].replace('jstree-clicked','').replace('jstree-disabled','');
20248 }
20249 m[data.id] = data;
20250 if(data.state.selected) {
20251 this._data.core.selected.push(data.id);
20252 }
20253 return data.id;
20254 },
20255 /**
20256 * parses a node from a JSON object (used when dealing with flat data, which has no nesting of children, but has id and parent properties) and appends it to the in memory tree model. Used internally.
20257 * @private
20258 * @name _parse_model_from_flat_json(d [, p, ps])
20259 * @param {Object} d the JSON object to parse
20260 * @param {String} p the parent ID
20261 * @param {Array} ps list of all parents
20262 * @return {String} the ID of the object added to the model
20263 */
20264 _parse_model_from_flat_json : function (d, p, ps) {
20265 if(!ps) { ps = []; }
20266 else { ps = ps.concat(); }
20267 if(p) { ps.unshift(p); }
20268 var tid = d.id.toString(),
20269 m = this._model.data,
20270 df = this._model.default_state,
20271 i, j, c, e,
20272 tmp = {
20273 id : tid,
20274 text : d.text || '',
20275 icon : d.icon !== undefined ? d.icon : true,
20276 parent : p,
20277 parents : ps,
20278 children : d.children || [],
20279 children_d : d.children_d || [],
20280 data : d.data,
20281 state : { },
20282 li_attr : { id : false },
20283 a_attr : { href : '#' },
20284 original : false
20285 };
20286 for(i in df) {
20287 if(df.hasOwnProperty(i)) {
20288 tmp.state[i] = df[i];
20289 }
20290 }
20291 if(d && d.data && d.data.jstree && d.data.jstree.icon) {
20292 tmp.icon = d.data.jstree.icon;
20293 }
20294 if(d && d.data) {
20295 tmp.data = d.data;
20296 if(d.data.jstree) {
20297 for(i in d.data.jstree) {
20298 if(d.data.jstree.hasOwnProperty(i)) {
20299 tmp.state[i] = d.data.jstree[i];
20300 }
20301 }
20302 }
20303 }
20304 if(d && typeof d.state === 'object') {
20305 for (i in d.state) {
20306 if(d.state.hasOwnProperty(i)) {
20307 tmp.state[i] = d.state[i];
20308 }
20309 }
20310 }
20311 if(d && typeof d.li_attr === 'object') {
20312 for (i in d.li_attr) {
20313 if(d.li_attr.hasOwnProperty(i)) {
20314 tmp.li_attr[i] = d.li_attr[i];
20315 }
20316 }
20317 }
20318 if(!tmp.li_attr.id) {
20319 tmp.li_attr.id = tid;
20320 }
20321 if(d && typeof d.a_attr === 'object') {
20322 for (i in d.a_attr) {
20323 if(d.a_attr.hasOwnProperty(i)) {
20324 tmp.a_attr[i] = d.a_attr[i];
20325 }
20326 }
20327 }
20328 if(d && d.children && d.children === true) {
20329 tmp.state.loaded = false;
20330 tmp.children = [];
20331 tmp.children_d = [];
20332 }
20333 m[tmp.id] = tmp;
20334 for(i = 0, j = tmp.children.length; i < j; i++) {
20335 c = this._parse_model_from_flat_json(m[tmp.children[i]], tmp.id, ps);
20336 e = m[c];
20337 tmp.children_d.push(c);
20338 if(e.children_d.length) {
20339 tmp.children_d = tmp.children_d.concat(e.children_d);
20340 }
20341 }
20342 delete d.data;
20343 delete d.children;
20344 m[tmp.id].original = d;
20345 if(tmp.state.selected) {
20346 this._data.core.selected.push(tmp.id);
20347 }
20348 return tmp.id;
20349 },
20350 /**
20351 * parses a node from a JSON object and appends it to the in memory tree model. Used internally.
20352 * @private
20353 * @name _parse_model_from_json(d [, p, ps])
20354 * @param {Object} d the JSON object to parse
20355 * @param {String} p the parent ID
20356 * @param {Array} ps list of all parents
20357 * @return {String} the ID of the object added to the model
20358 */
20359 _parse_model_from_json : function (d, p, ps) {
20360 if(!ps) { ps = []; }
20361 else { ps = ps.concat(); }
20362 if(p) { ps.unshift(p); }
20363 var tid = false, i, j, c, e, m = this._model.data, df = this._model.default_state, tmp;
20364 do {
20365 tid = 'j' + this._id + '_' + (++this._cnt);
20366 } while(m[tid]);
20367
20368 tmp = {
20369 id : false,
20370 text : typeof d === 'string' ? d : '',
20371 icon : typeof d === 'object' && d.icon !== undefined ? d.icon : true,
20372 parent : p,
20373 parents : ps,
20374 children : [],
20375 children_d : [],
20376 data : null,
20377 state : { },
20378 li_attr : { id : false },
20379 a_attr : { href : '#' },
20380 original : false
20381 };
20382 for(i in df) {
20383 if(df.hasOwnProperty(i)) {
20384 tmp.state[i] = df[i];
20385 }
20386 }
20387 if(d && d.id) { tmp.id = d.id.toString(); }
20388 if(d && d.text) { tmp.text = d.text; }
20389 if(d && d.data && d.data.jstree && d.data.jstree.icon) {
20390 tmp.icon = d.data.jstree.icon;
20391 }
20392 if(d && d.data) {
20393 tmp.data = d.data;
20394 if(d.data.jstree) {
20395 for(i in d.data.jstree) {
20396 if(d.data.jstree.hasOwnProperty(i)) {
20397 tmp.state[i] = d.data.jstree[i];
20398 }
20399 }
20400 }
20401 }
20402 if(d && typeof d.state === 'object') {
20403 for (i in d.state) {
20404 if(d.state.hasOwnProperty(i)) {
20405 tmp.state[i] = d.state[i];
20406 }
20407 }
20408 }
20409 if(d && typeof d.li_attr === 'object') {
20410 for (i in d.li_attr) {
20411 if(d.li_attr.hasOwnProperty(i)) {
20412 tmp.li_attr[i] = d.li_attr[i];
20413 }
20414 }
20415 }
20416 if(tmp.li_attr.id && !tmp.id) {
20417 tmp.id = tmp.li_attr.id.toString();
20418 }
20419 if(!tmp.id) {
20420 tmp.id = tid;
20421 }
20422 if(!tmp.li_attr.id) {
20423 tmp.li_attr.id = tmp.id;
20424 }
20425 if(d && typeof d.a_attr === 'object') {
20426 for (i in d.a_attr) {
20427 if(d.a_attr.hasOwnProperty(i)) {
20428 tmp.a_attr[i] = d.a_attr[i];
20429 }
20430 }
20431 }
20432 if(d && d.children && d.children.length) {
20433 for(i = 0, j = d.children.length; i < j; i++) {
20434 c = this._parse_model_from_json(d.children[i], tmp.id, ps);
20435 e = m[c];
20436 tmp.children.push(c);
20437 if(e.children_d.length) {
20438 tmp.children_d = tmp.children_d.concat(e.children_d);
20439 }
20440 }
20441 tmp.children_d = tmp.children_d.concat(tmp.children);
20442 }
20443 if(d && d.children && d.children === true) {
20444 tmp.state.loaded = false;
20445 tmp.children = [];
20446 tmp.children_d = [];
20447 }
20448 delete d.data;
20449 delete d.children;
20450 tmp.original = d;
20451 m[tmp.id] = tmp;
20452 if(tmp.state.selected) {
20453 this._data.core.selected.push(tmp.id);
20454 }
20455 return tmp.id;
20456 },
20457 /**
20458 * redraws all nodes that need to be redrawn. Used internally.
20459 * @private
20460 * @name _redraw()
20461 * @trigger redraw.jstree
20462 */
20463 _redraw : function () {
20464 var nodes = this._model.force_full_redraw ? this._model.data['#'].children.concat([]) : this._model.changed.concat([]),
20465 f = document.createElement('UL'), tmp, i, j, fe = this._data.core.focused;
20466 for(i = 0, j = nodes.length; i < j; i++) {
20467 tmp = this.redraw_node(nodes[i], true, this._model.force_full_redraw);
20468 if(tmp && this._model.force_full_redraw) {
20469 f.appendChild(tmp);
20470 }
20471 }
20472 if(this._model.force_full_redraw) {
20473 f.className = this.get_container_ul()[0].className;
20474 f.setAttribute('role','group');
20475 this.element.empty().append(f);
20476 //this.get_container_ul()[0].appendChild(f);
20477 }
20478 if(fe !== null) {
20479 tmp = this.get_node(fe, true);
20480 if(tmp && tmp.length && tmp.children('.jstree-anchor')[0] !== document.activeElement) {
20481 tmp.children('.jstree-anchor').focus();
20482 }
20483 else {
20484 this._data.core.focused = null;
20485 }
20486 }
20487 this._model.force_full_redraw = false;
20488 this._model.changed = [];
20489 /**
20490 * triggered after nodes are redrawn
20491 * @event
20492 * @name redraw.jstree
20493 * @param {array} nodes the redrawn nodes
20494 */
20495 this.trigger('redraw', { "nodes" : nodes });
20496 },
20497 /**
20498 * redraws all nodes that need to be redrawn or optionally - the whole tree
20499 * @name redraw([full])
20500 * @param {Boolean} full if set to `true` all nodes are redrawn.
20501 */
20502 redraw : function (full) {
20503 if(full) {
20504 this._model.force_full_redraw = true;
20505 }
20506 //if(this._model.redraw_timeout) {
20507 // clearTimeout(this._model.redraw_timeout);
20508 //}
20509 //this._model.redraw_timeout = setTimeout($.proxy(this._redraw, this),0);
20510 this._redraw();
20511 },
20512 /**
20513 * redraws a single node's children. Used internally.
20514 * @private
20515 * @name draw_children(node)
20516 * @param {mixed} node the node whose children will be redrawn
20517 */
20518 draw_children : function (node) {
20519 var obj = this.get_node(node),
20520 i = false,
20521 j = false,
20522 k = false,
20523 d = document;
20524 if(!obj) { return false; }
20525 if(obj.id === '#') { return this.redraw(true); }
20526 node = this.get_node(node, true);
20527 if(!node || !node.length) { return false; } // TODO: quick toggle
20528
20529 node.children('.jstree-children').remove();
20530 node = node[0];
20531 if(obj.children.length && obj.state.loaded) {
20532 k = d.createElement('UL');
20533 k.setAttribute('role', 'group');
20534 k.className = 'jstree-children';
20535 for(i = 0, j = obj.children.length; i < j; i++) {
20536 k.appendChild(this.redraw_node(obj.children[i], true, true));
20537 }
20538 node.appendChild(k);
20539 }
20540 },
20541 /**
20542 * redraws a single node. Used internally.
20543 * @private
20544 * @name redraw_node(node, deep, is_callback, force_render)
20545 * @param {mixed} node the node to redraw
20546 * @param {Boolean} deep should child nodes be redrawn too
20547 * @param {Boolean} is_callback is this a recursion call
20548 * @param {Boolean} force_render should children of closed parents be drawn anyway
20549 */
20550 redraw_node : function (node, deep, is_callback, force_render) {
20551 var obj = this.get_node(node),
20552 par = false,
20553 ind = false,
20554 old = false,
20555 i = false,
20556 j = false,
20557 k = false,
20558 c = '',
20559 d = document,
20560 m = this._model.data,
20561 f = false,
20562 s = false,
20563 tmp = null,
20564 t = 0,
20565 l = 0;
20566 if(!obj) { return false; }
20567 if(obj.id === '#') { return this.redraw(true); }
20568 deep = deep || obj.children.length === 0;
20569 node = !document.querySelector ? document.getElementById(obj.id) : this.element[0].querySelector('#' + ("0123456789".indexOf(obj.id[0]) !== -1 ? '\\3' + obj.id[0] + ' ' + obj.id.substr(1).replace($.jstree.idregex,'\\$&') : obj.id.replace($.jstree.idregex,'\\$&')) ); //, this.element);
20570 if(!node) {
20571 deep = true;
20572 //node = d.createElement('LI');
20573 if(!is_callback) {
20574 par = obj.parent !== '#' ? $('#' + obj.parent.replace($.jstree.idregex,'\\$&'), this.element)[0] : null;
20575 if(par !== null && (!par || !m[obj.parent].state.opened)) {
20576 return false;
20577 }
20578 ind = $.inArray(obj.id, par === null ? m['#'].children : m[obj.parent].children);
20579 }
20580 }
20581 else {
20582 node = $(node);
20583 if(!is_callback) {
20584 par = node.parent().parent()[0];
20585 if(par === this.element[0]) {
20586 par = null;
20587 }
20588 ind = node.index();
20589 }
20590 // m[obj.id].data = node.data(); // use only node's data, no need to touch jquery storage
20591 if(!deep && obj.children.length && !node.children('.jstree-children').length) {
20592 deep = true;
20593 }
20594 if(!deep) {
20595 old = node.children('.jstree-children')[0];
20596 }
20597 f = node.children('.jstree-anchor')[0] === document.activeElement;
20598 node.remove();
20599 //node = d.createElement('LI');
20600 //node = node[0];
20601 }
20602 node = _node.cloneNode(true);
20603 // node is DOM, deep is boolean
20604
20605 c = 'jstree-node ';
20606 for(i in obj.li_attr) {
20607 if(obj.li_attr.hasOwnProperty(i)) {
20608 if(i === 'id') { continue; }
20609 if(i !== 'class') {
20610 node.setAttribute(i, obj.li_attr[i]);
20611 }
20612 else {
20613 c += obj.li_attr[i];
20614 }
20615 }
20616 }
20617 if(!obj.a_attr.id) {
20618 obj.a_attr.id = obj.id + '_anchor';
20619 }
20620 node.setAttribute('aria-selected', !!obj.state.selected);
20621 node.setAttribute('aria-level', obj.parents.length);
20622 node.setAttribute('aria-labelledby', obj.a_attr.id);
20623 if(obj.state.disabled) {
20624 node.setAttribute('aria-disabled', true);
20625 }
20626
20627 if(obj.state.loaded && !obj.children.length) {
20628 c += ' jstree-leaf';
20629 }
20630 else {
20631 c += obj.state.opened && obj.state.loaded ? ' jstree-open' : ' jstree-closed';
20632 node.setAttribute('aria-expanded', (obj.state.opened && obj.state.loaded) );
20633 }
20634 if(obj.parent !== null && m[obj.parent].children[m[obj.parent].children.length - 1] === obj.id) {
20635 c += ' jstree-last';
20636 }
20637 node.id = obj.id;
20638 node.className = c;
20639 c = ( obj.state.selected ? ' jstree-clicked' : '') + ( obj.state.disabled ? ' jstree-disabled' : '');
20640 for(j in obj.a_attr) {
20641 if(obj.a_attr.hasOwnProperty(j)) {
20642 if(j === 'href' && obj.a_attr[j] === '#') { continue; }
20643 if(j !== 'class') {
20644 node.childNodes[1].setAttribute(j, obj.a_attr[j]);
20645 }
20646 else {
20647 c += ' ' + obj.a_attr[j];
20648 }
20649 }
20650 }
20651 if(c.length) {
20652 node.childNodes[1].className = 'jstree-anchor ' + c;
20653 }
20654 if((obj.icon && obj.icon !== true) || obj.icon === false) {
20655 if(obj.icon === false) {
20656 node.childNodes[1].childNodes[0].className += ' jstree-themeicon-hidden';
20657 }
20658 else if(obj.icon.indexOf('/') === -1 && obj.icon.indexOf('.') === -1) {
20659 node.childNodes[1].childNodes[0].className += ' ' + obj.icon + ' jstree-themeicon-custom';
20660 }
20661 else {
20662 node.childNodes[1].childNodes[0].style.backgroundImage = 'url('+obj.icon+')';
20663 node.childNodes[1].childNodes[0].style.backgroundPosition = 'center center';
20664 node.childNodes[1].childNodes[0].style.backgroundSize = 'auto';
20665 node.childNodes[1].childNodes[0].className += ' jstree-themeicon-custom';
20666 }
20667 }
20668
20669 if(this.settings.core.force_text) {
20670 node.childNodes[1].appendChild(d.createTextNode(obj.text));
20671 }
20672 else {
20673 node.childNodes[1].innerHTML += obj.text;
20674 }
20675
20676
20677 if(deep && obj.children.length && (obj.state.opened || force_render) && obj.state.loaded) {
20678 k = d.createElement('UL');
20679 k.setAttribute('role', 'group');
20680 k.className = 'jstree-children';
20681 for(i = 0, j = obj.children.length; i < j; i++) {
20682 k.appendChild(this.redraw_node(obj.children[i], deep, true));
20683 }
20684 node.appendChild(k);
20685 }
20686 if(old) {
20687 node.appendChild(old);
20688 }
20689 if(!is_callback) {
20690 // append back using par / ind
20691 if(!par) {
20692 par = this.element[0];
20693 }
20694 for(i = 0, j = par.childNodes.length; i < j; i++) {
20695 if(par.childNodes[i] && par.childNodes[i].className && par.childNodes[i].className.indexOf('jstree-children') !== -1) {
20696 tmp = par.childNodes[i];
20697 break;
20698 }
20699 }
20700 if(!tmp) {
20701 tmp = d.createElement('UL');
20702 tmp.setAttribute('role', 'group');
20703 tmp.className = 'jstree-children';
20704 par.appendChild(tmp);
20705 }
20706 par = tmp;
20707
20708 if(ind < par.childNodes.length) {
20709 par.insertBefore(node, par.childNodes[ind]);
20710 }
20711 else {
20712 par.appendChild(node);
20713 }
20714 if(f) {
20715 t = this.element[0].scrollTop;
20716 l = this.element[0].scrollLeft;
20717 node.childNodes[1].focus();
20718 this.element[0].scrollTop = t;
20719 this.element[0].scrollLeft = l;
20720 }
20721 }
20722 if(obj.state.opened && !obj.state.loaded) {
20723 obj.state.opened = false;
20724 setTimeout($.proxy(function () {
20725 this.open_node(obj.id, false, 0);
20726 }, this), 0);
20727 }
20728 return node;
20729 },
20730 /**
20731 * opens a node, revaling its children. If the node is not loaded it will be loaded and opened once ready.
20732 * @name open_node(obj [, callback, animation])
20733 * @param {mixed} obj the node to open
20734 * @param {Function} callback a function to execute once the node is opened
20735 * @param {Number} animation the animation duration in milliseconds when opening the node (overrides the `core.animation` setting). Use `false` for no animation.
20736 * @trigger open_node.jstree, after_open.jstree, before_open.jstree
20737 */
20738 open_node : function (obj, callback, animation) {
20739 var t1, t2, d, t;
20740 if($.isArray(obj)) {
20741 obj = obj.slice();
20742 for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
20743 this.open_node(obj[t1], callback, animation);
20744 }
20745 return true;
20746 }
20747 obj = this.get_node(obj);
20748 if(!obj || obj.id === '#') {
20749 return false;
20750 }
20751 animation = animation === undefined ? this.settings.core.animation : animation;
20752 if(!this.is_closed(obj)) {
20753 if(callback) {
20754 callback.call(this, obj, false);
20755 }
20756 return false;
20757 }
20758 if(!this.is_loaded(obj)) {
20759 if(this.is_loading(obj)) {
20760 return setTimeout($.proxy(function () {
20761 this.open_node(obj, callback, animation);
20762 }, this), 500);
20763 }
20764 this.load_node(obj, function (o, ok) {
20765 return ok ? this.open_node(o, callback, animation) : (callback ? callback.call(this, o, false) : false);
20766 });
20767 }
20768 else {
20769 d = this.get_node(obj, true);
20770 t = this;
20771 if(d.length) {
20772 if(animation && d.children(".jstree-children").length) {
20773 d.children(".jstree-children").stop(true, true);
20774 }
20775 if(obj.children.length && !this._firstChild(d.children('.jstree-children')[0])) {
20776 this.draw_children(obj);
20777 //d = this.get_node(obj, true);
20778 }
20779 if(!animation) {
20780 this.trigger('before_open', { "node" : obj });
20781 d[0].className = d[0].className.replace('jstree-closed', 'jstree-open');
20782 d[0].setAttribute("aria-expanded", true);
20783 }
20784 else {
20785 this.trigger('before_open', { "node" : obj });
20786 d
20787 .children(".jstree-children").css("display","none").end()
20788 .removeClass("jstree-closed").addClass("jstree-open").attr("aria-expanded", true)
20789 .children(".jstree-children").stop(true, true)
20790 .slideDown(animation, function () {
20791 this.style.display = "";
20792 t.trigger("after_open", { "node" : obj });
20793 });
20794 }
20795 }
20796 obj.state.opened = true;
20797 if(callback) {
20798 callback.call(this, obj, true);
20799 }
20800 if(!d.length) {
20801 /**
20802 * triggered when a node is about to be opened (if the node is supposed to be in the DOM, it will be, but it won't be visible yet)
20803 * @event
20804 * @name before_open.jstree
20805 * @param {Object} node the opened node
20806 */
20807 this.trigger('before_open', { "node" : obj });
20808 }
20809 /**
20810 * triggered when a node is opened (if there is an animation it will not be completed yet)
20811 * @event
20812 * @name open_node.jstree
20813 * @param {Object} node the opened node
20814 */
20815 this.trigger('open_node', { "node" : obj });
20816 if(!animation || !d.length) {
20817 /**
20818 * triggered when a node is opened and the animation is complete
20819 * @event
20820 * @name after_open.jstree
20821 * @param {Object} node the opened node
20822 */
20823 this.trigger("after_open", { "node" : obj });
20824 }
20825 }
20826 },
20827 /**
20828 * opens every parent of a node (node should be loaded)
20829 * @name _open_to(obj)
20830 * @param {mixed} obj the node to reveal
20831 * @private
20832 */
20833 _open_to : function (obj) {
20834 obj = this.get_node(obj);
20835 if(!obj || obj.id === '#') {
20836 return false;
20837 }
20838 var i, j, p = obj.parents;
20839 for(i = 0, j = p.length; i < j; i+=1) {
20840 if(i !== '#') {
20841 this.open_node(p[i], false, 0);
20842 }
20843 }
20844 return $('#' + obj.id.replace($.jstree.idregex,'\\$&'), this.element);
20845 },
20846 /**
20847 * closes a node, hiding its children
20848 * @name close_node(obj [, animation])
20849 * @param {mixed} obj the node to close
20850 * @param {Number} animation the animation duration in milliseconds when closing the node (overrides the `core.animation` setting). Use `false` for no animation.
20851 * @trigger close_node.jstree, after_close.jstree
20852 */
20853 close_node : function (obj, animation) {
20854 var t1, t2, t, d;
20855 if($.isArray(obj)) {
20856 obj = obj.slice();
20857 for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
20858 this.close_node(obj[t1], animation);
20859 }
20860 return true;
20861 }
20862 obj = this.get_node(obj);
20863 if(!obj || obj.id === '#') {
20864 return false;
20865 }
20866 if(this.is_closed(obj)) {
20867 return false;
20868 }
20869 animation = animation === undefined ? this.settings.core.animation : animation;
20870 t = this;
20871 d = this.get_node(obj, true);
20872 if(d.length) {
20873 if(!animation) {
20874 d[0].className = d[0].className.replace('jstree-open', 'jstree-closed');
20875 d.attr("aria-expanded", false).children('.jstree-children').remove();
20876 }
20877 else {
20878 d
20879 .children(".jstree-children").attr("style","display:block !important").end()
20880 .removeClass("jstree-open").addClass("jstree-closed").attr("aria-expanded", false)
20881 .children(".jstree-children").stop(true, true).slideUp(animation, function () {
20882 this.style.display = "";
20883 d.children('.jstree-children').remove();
20884 t.trigger("after_close", { "node" : obj });
20885 });
20886 }
20887 }
20888 obj.state.opened = false;
20889 /**
20890 * triggered when a node is closed (if there is an animation it will not be complete yet)
20891 * @event
20892 * @name close_node.jstree
20893 * @param {Object} node the closed node
20894 */
20895 this.trigger('close_node',{ "node" : obj });
20896 if(!animation || !d.length) {
20897 /**
20898 * triggered when a node is closed and the animation is complete
20899 * @event
20900 * @name after_close.jstree
20901 * @param {Object} node the closed node
20902 */
20903 this.trigger("after_close", { "node" : obj });
20904 }
20905 },
20906 /**
20907 * toggles a node - closing it if it is open, opening it if it is closed
20908 * @name toggle_node(obj)
20909 * @param {mixed} obj the node to toggle
20910 */
20911 toggle_node : function (obj) {
20912 var t1, t2;
20913 if($.isArray(obj)) {
20914 obj = obj.slice();
20915 for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
20916 this.toggle_node(obj[t1]);
20917 }
20918 return true;
20919 }
20920 if(this.is_closed(obj)) {
20921 return this.open_node(obj);
20922 }
20923 if(this.is_open(obj)) {
20924 return this.close_node(obj);
20925 }
20926 },
20927 /**
20928 * opens all nodes within a node (or the tree), revaling their children. If the node is not loaded it will be loaded and opened once ready.
20929 * @name open_all([obj, animation, original_obj])
20930 * @param {mixed} obj the node to open recursively, omit to open all nodes in the tree
20931 * @param {Number} animation the animation duration in milliseconds when opening the nodes, the default is no animation
20932 * @param {jQuery} reference to the node that started the process (internal use)
20933 * @trigger open_all.jstree
20934 */
20935 open_all : function (obj, animation, original_obj) {
20936 if(!obj) { obj = '#'; }
20937 obj = this.get_node(obj);
20938 if(!obj) { return false; }
20939 var dom = obj.id === '#' ? this.get_container_ul() : this.get_node(obj, true), i, j, _this;
20940 if(!dom.length) {
20941 for(i = 0, j = obj.children_d.length; i < j; i++) {
20942 if(this.is_closed(this._model.data[obj.children_d[i]])) {
20943 this._model.data[obj.children_d[i]].state.opened = true;
20944 }
20945 }
20946 return this.trigger('open_all', { "node" : obj });
20947 }
20948 original_obj = original_obj || dom;
20949 _this = this;
20950 dom = this.is_closed(obj) ? dom.find('.jstree-closed').addBack() : dom.find('.jstree-closed');
20951 dom.each(function () {
20952 _this.open_node(
20953 this,
20954 function(node, status) { if(status && this.is_parent(node)) { this.open_all(node, animation, original_obj); } },
20955 animation || 0
20956 );
20957 });
20958 if(original_obj.find('.jstree-closed').length === 0) {
20959 /**
20960 * triggered when an `open_all` call completes
20961 * @event
20962 * @name open_all.jstree
20963 * @param {Object} node the opened node
20964 */
20965 this.trigger('open_all', { "node" : this.get_node(original_obj) });
20966 }
20967 },
20968 /**
20969 * closes all nodes within a node (or the tree), revaling their children
20970 * @name close_all([obj, animation])
20971 * @param {mixed} obj the node to close recursively, omit to close all nodes in the tree
20972 * @param {Number} animation the animation duration in milliseconds when closing the nodes, the default is no animation
20973 * @trigger close_all.jstree
20974 */
20975 close_all : function (obj, animation) {
20976 if(!obj) { obj = '#'; }
20977 obj = this.get_node(obj);
20978 if(!obj) { return false; }
20979 var dom = obj.id === '#' ? this.get_container_ul() : this.get_node(obj, true),
20980 _this = this, i, j;
20981 if(!dom.length) {
20982 for(i = 0, j = obj.children_d.length; i < j; i++) {
20983 this._model.data[obj.children_d[i]].state.opened = false;
20984 }
20985 return this.trigger('close_all', { "node" : obj });
20986 }
20987 dom = this.is_open(obj) ? dom.find('.jstree-open').addBack() : dom.find('.jstree-open');
20988 $(dom.get().reverse()).each(function () { _this.close_node(this, animation || 0); });
20989 /**
20990 * triggered when an `close_all` call completes
20991 * @event
20992 * @name close_all.jstree
20993 * @param {Object} node the closed node
20994 */
20995 this.trigger('close_all', { "node" : obj });
20996 },
20997 /**
20998 * checks if a node is disabled (not selectable)
20999 * @name is_disabled(obj)
21000 * @param {mixed} obj
21001 * @return {Boolean}
21002 */
21003 is_disabled : function (obj) {
21004 obj = this.get_node(obj);
21005 return obj && obj.state && obj.state.disabled;
21006 },
21007 /**
21008 * enables a node - so that it can be selected
21009 * @name enable_node(obj)
21010 * @param {mixed} obj the node to enable
21011 * @trigger enable_node.jstree
21012 */
21013 enable_node : function (obj) {
21014 var t1, t2;
21015 if($.isArray(obj)) {
21016 obj = obj.slice();
21017 for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
21018 this.enable_node(obj[t1]);
21019 }
21020 return true;
21021 }
21022 obj = this.get_node(obj);
21023 if(!obj || obj.id === '#') {
21024 return false;
21025 }
21026 obj.state.disabled = false;
21027 this.get_node(obj,true).children('.jstree-anchor').removeClass('jstree-disabled').attr('aria-disabled', false);
21028 /**
21029 * triggered when an node is enabled
21030 * @event
21031 * @name enable_node.jstree
21032 * @param {Object} node the enabled node
21033 */
21034 this.trigger('enable_node', { 'node' : obj });
21035 },
21036 /**
21037 * disables a node - so that it can not be selected
21038 * @name disable_node(obj)
21039 * @param {mixed} obj the node to disable
21040 * @trigger disable_node.jstree
21041 */
21042 disable_node : function (obj) {
21043 var t1, t2;
21044 if($.isArray(obj)) {
21045 obj = obj.slice();
21046 for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
21047 this.disable_node(obj[t1]);
21048 }
21049 return true;
21050 }
21051 obj = this.get_node(obj);
21052 if(!obj || obj.id === '#') {
21053 return false;
21054 }
21055 obj.state.disabled = true;
21056 this.get_node(obj,true).children('.jstree-anchor').addClass('jstree-disabled').attr('aria-disabled', true);
21057 /**
21058 * triggered when an node is disabled
21059 * @event
21060 * @name disable_node.jstree
21061 * @param {Object} node the disabled node
21062 */
21063 this.trigger('disable_node', { 'node' : obj });
21064 },
21065 /**
21066 * called when a node is selected by the user. Used internally.
21067 * @private
21068 * @name activate_node(obj, e)
21069 * @param {mixed} obj the node
21070 * @param {Object} e the related event
21071 * @trigger activate_node.jstree, changed.jstree
21072 */
21073 activate_node : function (obj, e) {
21074 if(this.is_disabled(obj)) {
21075 return false;
21076 }
21077
21078 // ensure last_clicked is still in the DOM, make it fresh (maybe it was moved?) and make sure it is still selected, if not - make last_clicked the last selected node
21079 this._data.core.last_clicked = this._data.core.last_clicked && this._data.core.last_clicked.id !== undefined ? this.get_node(this._data.core.last_clicked.id) : null;
21080 if(this._data.core.last_clicked && !this._data.core.last_clicked.state.selected) { this._data.core.last_clicked = null; }
21081 if(!this._data.core.last_clicked && this._data.core.selected.length) { this._data.core.last_clicked = this.get_node(this._data.core.selected[this._data.core.selected.length - 1]); }
21082
21083 if(!this.settings.core.multiple || (!e.metaKey && !e.ctrlKey && !e.shiftKey) || (e.shiftKey && (!this._data.core.last_clicked || !this.get_parent(obj) || this.get_parent(obj) !== this._data.core.last_clicked.parent ) )) {
21084 if(!this.settings.core.multiple && (e.metaKey || e.ctrlKey || e.shiftKey) && this.is_selected(obj)) {
21085 this.deselect_node(obj, false, e);
21086 }
21087 else {
21088 this.deselect_all(true);
21089 this.select_node(obj, false, false, e);
21090 this._data.core.last_clicked = this.get_node(obj);
21091 }
21092 }
21093 else {
21094 if(e.shiftKey) {
21095 var o = this.get_node(obj).id,
21096 l = this._data.core.last_clicked.id,
21097 p = this.get_node(this._data.core.last_clicked.parent).children,
21098 c = false,
21099 i, j;
21100 for(i = 0, j = p.length; i < j; i += 1) {
21101 // separate IFs work whem o and l are the same
21102 if(p[i] === o) {
21103 c = !c;
21104 }
21105 if(p[i] === l) {
21106 c = !c;
21107 }
21108 if(c || p[i] === o || p[i] === l) {
21109 this.select_node(p[i], true, false, e);
21110 }
21111 else {
21112 this.deselect_node(p[i], true, e);
21113 }
21114 }
21115 this.trigger('changed', { 'action' : 'select_node', 'node' : this.get_node(obj), 'selected' : this._data.core.selected, 'event' : e });
21116 }
21117 else {
21118 if(!this.is_selected(obj)) {
21119 this.select_node(obj, false, false, e);
21120 }
21121 else {
21122 this.deselect_node(obj, false, e);
21123 }
21124 }
21125 }
21126 /**
21127 * triggered when an node is clicked or intercated with by the user
21128 * @event
21129 * @name activate_node.jstree
21130 * @param {Object} node
21131 */
21132 this.trigger('activate_node', { 'node' : this.get_node(obj) });
21133 },
21134 /**
21135 * applies the hover state on a node, called when a node is hovered by the user. Used internally.
21136 * @private
21137 * @name hover_node(obj)
21138 * @param {mixed} obj
21139 * @trigger hover_node.jstree
21140 */
21141 hover_node : function (obj) {
21142 obj = this.get_node(obj, true);
21143 if(!obj || !obj.length || obj.children('.jstree-hovered').length) {
21144 return false;
21145 }
21146 var o = this.element.find('.jstree-hovered'), t = this.element;
21147 if(o && o.length) { this.dehover_node(o); }
21148
21149 obj.children('.jstree-anchor').addClass('jstree-hovered');
21150 /**
21151 * triggered when an node is hovered
21152 * @event
21153 * @name hover_node.jstree
21154 * @param {Object} node
21155 */
21156 this.trigger('hover_node', { 'node' : this.get_node(obj) });
21157 setTimeout(function () { t.attr('aria-activedescendant', obj[0].id); }, 0);
21158 },
21159 /**
21160 * removes the hover state from a nodecalled when a node is no longer hovered by the user. Used internally.
21161 * @private
21162 * @name dehover_node(obj)
21163 * @param {mixed} obj
21164 * @trigger dehover_node.jstree
21165 */
21166 dehover_node : function (obj) {
21167 obj = this.get_node(obj, true);
21168 if(!obj || !obj.length || !obj.children('.jstree-hovered').length) {
21169 return false;
21170 }
21171 obj.children('.jstree-anchor').removeClass('jstree-hovered');
21172 /**
21173 * triggered when an node is no longer hovered
21174 * @event
21175 * @name dehover_node.jstree
21176 * @param {Object} node
21177 */
21178 this.trigger('dehover_node', { 'node' : this.get_node(obj) });
21179 },
21180 /**
21181 * select a node
21182 * @name select_node(obj [, supress_event, prevent_open])
21183 * @param {mixed} obj an array can be used to select multiple nodes
21184 * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered
21185 * @param {Boolean} prevent_open if set to `true` parents of the selected node won't be opened
21186 * @trigger select_node.jstree, changed.jstree
21187 */
21188 select_node : function (obj, supress_event, prevent_open, e) {
21189 var dom, t1, t2, th;
21190 if($.isArray(obj)) {
21191 obj = obj.slice();
21192 for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
21193 this.select_node(obj[t1], supress_event, prevent_open, e);
21194 }
21195 return true;
21196 }
21197 obj = this.get_node(obj);
21198 if(!obj || obj.id === '#') {
21199 return false;
21200 }
21201 dom = this.get_node(obj, true);
21202 if(!obj.state.selected) {
21203 obj.state.selected = true;
21204 this._data.core.selected.push(obj.id);
21205 if(!prevent_open) {
21206 dom = this._open_to(obj);
21207 }
21208 if(dom && dom.length) {
21209 dom.attr('aria-selected', true).children('.jstree-anchor').addClass('jstree-clicked');
21210 }
21211 /**
21212 * triggered when an node is selected
21213 * @event
21214 * @name select_node.jstree
21215 * @param {Object} node
21216 * @param {Array} selected the current selection
21217 * @param {Object} event the event (if any) that triggered this select_node
21218 */
21219 this.trigger('select_node', { 'node' : obj, 'selected' : this._data.core.selected, 'event' : e });
21220 if(!supress_event) {
21221 /**
21222 * triggered when selection changes
21223 * @event
21224 * @name changed.jstree
21225 * @param {Object} node
21226 * @param {Object} action the action that caused the selection to change
21227 * @param {Array} selected the current selection
21228 * @param {Object} event the event (if any) that triggered this changed event
21229 */
21230 this.trigger('changed', { 'action' : 'select_node', 'node' : obj, 'selected' : this._data.core.selected, 'event' : e });
21231 }
21232 }
21233 },
21234 /**
21235 * deselect a node
21236 * @name deselect_node(obj [, supress_event])
21237 * @param {mixed} obj an array can be used to deselect multiple nodes
21238 * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered
21239 * @trigger deselect_node.jstree, changed.jstree
21240 */
21241 deselect_node : function (obj, supress_event, e) {
21242 var t1, t2, dom;
21243 if($.isArray(obj)) {
21244 obj = obj.slice();
21245 for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
21246 this.deselect_node(obj[t1], supress_event, e);
21247 }
21248 return true;
21249 }
21250 obj = this.get_node(obj);
21251 if(!obj || obj.id === '#') {
21252 return false;
21253 }
21254 dom = this.get_node(obj, true);
21255 if(obj.state.selected) {
21256 obj.state.selected = false;
21257 this._data.core.selected = $.vakata.array_remove_item(this._data.core.selected, obj.id);
21258 if(dom.length) {
21259 dom.attr('aria-selected', false).children('.jstree-anchor').removeClass('jstree-clicked');
21260 }
21261 /**
21262 * triggered when an node is deselected
21263 * @event
21264 * @name deselect_node.jstree
21265 * @param {Object} node
21266 * @param {Array} selected the current selection
21267 * @param {Object} event the event (if any) that triggered this deselect_node
21268 */
21269 this.trigger('deselect_node', { 'node' : obj, 'selected' : this._data.core.selected, 'event' : e });
21270 if(!supress_event) {
21271 this.trigger('changed', { 'action' : 'deselect_node', 'node' : obj, 'selected' : this._data.core.selected, 'event' : e });
21272 }
21273 }
21274 },
21275 /**
21276 * select all nodes in the tree
21277 * @name select_all([supress_event])
21278 * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered
21279 * @trigger select_all.jstree, changed.jstree
21280 */
21281 select_all : function (supress_event) {
21282 var tmp = this._data.core.selected.concat([]), i, j;
21283 this._data.core.selected = this._model.data['#'].children_d.concat();
21284 for(i = 0, j = this._data.core.selected.length; i < j; i++) {
21285 if(this._model.data[this._data.core.selected[i]]) {
21286 this._model.data[this._data.core.selected[i]].state.selected = true;
21287 }
21288 }
21289 this.redraw(true);
21290 /**
21291 * triggered when all nodes are selected
21292 * @event
21293 * @name select_all.jstree
21294 * @param {Array} selected the current selection
21295 */
21296 this.trigger('select_all', { 'selected' : this._data.core.selected });
21297 if(!supress_event) {
21298 this.trigger('changed', { 'action' : 'select_all', 'selected' : this._data.core.selected, 'old_selection' : tmp });
21299 }
21300 },
21301 /**
21302 * deselect all selected nodes
21303 * @name deselect_all([supress_event])
21304 * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered
21305 * @trigger deselect_all.jstree, changed.jstree
21306 */
21307 deselect_all : function (supress_event) {
21308 var tmp = this._data.core.selected.concat([]), i, j;
21309 for(i = 0, j = this._data.core.selected.length; i < j; i++) {
21310 if(this._model.data[this._data.core.selected[i]]) {
21311 this._model.data[this._data.core.selected[i]].state.selected = false;
21312 }
21313 }
21314 this._data.core.selected = [];
21315 this.element.find('.jstree-clicked').removeClass('jstree-clicked').parent().attr('aria-selected', false);
21316 /**
21317 * triggered when all nodes are deselected
21318 * @event
21319 * @name deselect_all.jstree
21320 * @param {Object} node the previous selection
21321 * @param {Array} selected the current selection
21322 */
21323 this.trigger('deselect_all', { 'selected' : this._data.core.selected, 'node' : tmp });
21324 if(!supress_event) {
21325 this.trigger('changed', { 'action' : 'deselect_all', 'selected' : this._data.core.selected, 'old_selection' : tmp });
21326 }
21327 },
21328 /**
21329 * checks if a node is selected
21330 * @name is_selected(obj)
21331 * @param {mixed} obj
21332 * @return {Boolean}
21333 */
21334 is_selected : function (obj) {
21335 obj = this.get_node(obj);
21336 if(!obj || obj.id === '#') {
21337 return false;
21338 }
21339 return obj.state.selected;
21340 },
21341 /**
21342 * get an array of all selected nodes
21343 * @name get_selected([full])
21344 * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned
21345 * @return {Array}
21346 */
21347 get_selected : function (full) {
21348 return full ? $.map(this._data.core.selected, $.proxy(function (i) { return this.get_node(i); }, this)) : this._data.core.selected.slice();
21349 },
21350 /**
21351 * get an array of all top level selected nodes (ignoring children of selected nodes)
21352 * @name get_top_selected([full])
21353 * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned
21354 * @return {Array}
21355 */
21356 get_top_selected : function (full) {
21357 var tmp = this.get_selected(true),
21358 obj = {}, i, j, k, l;
21359 for(i = 0, j = tmp.length; i < j; i++) {
21360 obj[tmp[i].id] = tmp[i];
21361 }
21362 for(i = 0, j = tmp.length; i < j; i++) {
21363 for(k = 0, l = tmp[i].children_d.length; k < l; k++) {
21364 if(obj[tmp[i].children_d[k]]) {
21365 delete obj[tmp[i].children_d[k]];
21366 }
21367 }
21368 }
21369 tmp = [];
21370 for(i in obj) {
21371 if(obj.hasOwnProperty(i)) {
21372 tmp.push(i);
21373 }
21374 }
21375 return full ? $.map(tmp, $.proxy(function (i) { return this.get_node(i); }, this)) : tmp;
21376 },
21377 /**
21378 * get an array of all bottom level selected nodes (ignoring selected parents)
21379 * @name get_bottom_selected([full])
21380 * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned
21381 * @return {Array}
21382 */
21383 get_bottom_selected : function (full) {
21384 var tmp = this.get_selected(true),
21385 obj = [], i, j;
21386 for(i = 0, j = tmp.length; i < j; i++) {
21387 if(!tmp[i].children.length) {
21388 obj.push(tmp[i].id);
21389 }
21390 }
21391 return full ? $.map(obj, $.proxy(function (i) { return this.get_node(i); }, this)) : obj;
21392 },
21393 /**
21394 * gets the current state of the tree so that it can be restored later with `set_state(state)`. Used internally.
21395 * @name get_state()
21396 * @private
21397 * @return {Object}
21398 */
21399 get_state : function () {
21400 var state = {
21401 'core' : {
21402 'open' : [],
21403 'scroll' : {
21404 'left' : this.element.scrollLeft(),
21405 'top' : this.element.scrollTop()
21406 },
21407 /*!
21408 'themes' : {
21409 'name' : this.get_theme(),
21410 'icons' : this._data.core.themes.icons,
21411 'dots' : this._data.core.themes.dots
21412 },
21413 */
21414 'selected' : []
21415 }
21416 }, i;
21417 for(i in this._model.data) {
21418 if(this._model.data.hasOwnProperty(i)) {
21419 if(i !== '#') {
21420 if(this._model.data[i].state.opened) {
21421 state.core.open.push(i);
21422 }
21423 if(this._model.data[i].state.selected) {
21424 state.core.selected.push(i);
21425 }
21426 }
21427 }
21428 }
21429 return state;
21430 },
21431 /**
21432 * sets the state of the tree. Used internally.
21433 * @name set_state(state [, callback])
21434 * @private
21435 * @param {Object} state the state to restore
21436 * @param {Function} callback an optional function to execute once the state is restored.
21437 * @trigger set_state.jstree
21438 */
21439 set_state : function (state, callback) {
21440 if(state) {
21441 if(state.core) {
21442 var res, n, t, _this;
21443 if(state.core.open) {
21444 if(!$.isArray(state.core.open)) {
21445 delete state.core.open;
21446 this.set_state(state, callback);
21447 return false;
21448 }
21449 res = true;
21450 n = false;
21451 t = this;
21452 $.each(state.core.open.concat([]), function (i, v) {
21453 n = t.get_node(v);
21454 if(n) {
21455 if(t.is_loaded(v)) {
21456 if(t.is_closed(v)) {
21457 t.open_node(v, false, 0);
21458 }
21459 if(state && state.core && state.core.open) {
21460 $.vakata.array_remove_item(state.core.open, v);
21461 }
21462 }
21463 else {
21464 if(!t.is_loading(v)) {
21465 t.open_node(v, $.proxy(function (o, s) {
21466 if(!s && state && state.core && state.core.open) {
21467 $.vakata.array_remove_item(state.core.open, o.id);
21468 }
21469 this.set_state(state, callback);
21470 }, t), 0);
21471 }
21472 // there will be some async activity - so wait for it
21473 res = false;
21474 }
21475 }
21476 });
21477 if(res) {
21478 delete state.core.open;
21479 this.set_state(state, callback);
21480 }
21481 return false;
21482 }
21483 if(state.core.scroll) {
21484 if(state.core.scroll && state.core.scroll.left !== undefined) {
21485 this.element.scrollLeft(state.core.scroll.left);
21486 }
21487 if(state.core.scroll && state.core.scroll.top !== undefined) {
21488 this.element.scrollTop(state.core.scroll.top);
21489 }
21490 delete state.core.scroll;
21491 this.set_state(state, callback);
21492 return false;
21493 }
21494 /*!
21495 if(state.core.themes) {
21496 if(state.core.themes.name) {
21497 this.set_theme(state.core.themes.name);
21498 }
21499 if(typeof state.core.themes.dots !== 'undefined') {
21500 this[ state.core.themes.dots ? "show_dots" : "hide_dots" ]();
21501 }
21502 if(typeof state.core.themes.icons !== 'undefined') {
21503 this[ state.core.themes.icons ? "show_icons" : "hide_icons" ]();
21504 }
21505 delete state.core.themes;
21506 delete state.core.open;
21507 this.set_state(state, callback);
21508 return false;
21509 }
21510 */
21511 if(state.core.selected) {
21512 _this = this;
21513 this.deselect_all();
21514 $.each(state.core.selected, function (i, v) {
21515 _this.select_node(v);
21516 });
21517 delete state.core.selected;
21518 this.set_state(state, callback);
21519 return false;
21520 }
21521 if($.isEmptyObject(state.core)) {
21522 delete state.core;
21523 this.set_state(state, callback);
21524 return false;
21525 }
21526 }
21527 if($.isEmptyObject(state)) {
21528 state = null;
21529 if(callback) { callback.call(this); }
21530 /**
21531 * triggered when a `set_state` call completes
21532 * @event
21533 * @name set_state.jstree
21534 */
21535 this.trigger('set_state');
21536 return false;
21537 }
21538 return true;
21539 }
21540 return false;
21541 },
21542 /**
21543 * refreshes the tree - all nodes are reloaded with calls to `load_node`.
21544 * @name refresh()
21545 * @param {Boolean} skip_loading an option to skip showing the loading indicator
21546 * @param {Mixed} forget_state if set to `true` state will not be reapplied, if set to a function (receiving the current state as argument) the result of that function will be used as state
21547 * @trigger refresh.jstree
21548 */
21549 refresh : function (skip_loading, forget_state) {
21550 this._data.core.state = forget_state === true ? {} : this.get_state();
21551 if(forget_state && $.isFunction(forget_state)) { this._data.core.state = forget_state.call(this, this._data.core.state); }
21552 this._cnt = 0;
21553 this._model.data = {
21554 '#' : {
21555 id : '#',
21556 parent : null,
21557 parents : [],
21558 children : [],
21559 children_d : [],
21560 state : { loaded : false }
21561 }
21562 };
21563 var c = this.get_container_ul()[0].className;
21564 if(!skip_loading) {
21565 this.element.html("<"+"ul class='"+c+"' role='group'><"+"li class='jstree-initial-node jstree-loading jstree-leaf jstree-last' role='treeitem' id='j"+this._id+"_loading'><i class='jstree-icon jstree-ocl'></i><"+"a class='jstree-anchor' href='#'><i class='jstree-icon jstree-themeicon-hidden'></i>" + this.get_string("Loading ...") + "</a></li></ul>");
21566 this.element.attr('aria-activedescendant','j'+this._id+'_loading');
21567 }
21568 this.load_node('#', function (o, s) {
21569 if(s) {
21570 this.get_container_ul()[0].className = c;
21571 if(this._firstChild(this.get_container_ul()[0])) {
21572 this.element.attr('aria-activedescendant',this._firstChild(this.get_container_ul()[0]).id);
21573 }
21574 this.set_state($.extend(true, {}, this._data.core.state), function () {
21575 /**
21576 * triggered when a `refresh` call completes
21577 * @event
21578 * @name refresh.jstree
21579 */
21580 this.trigger('refresh');
21581 });
21582 }
21583 this._data.core.state = null;
21584 });
21585 },
21586 /**
21587 * refreshes a node in the tree (reload its children) all opened nodes inside that node are reloaded with calls to `load_node`.
21588 * @name refresh_node(obj)
21589 * @param {mixed} obj the node
21590 * @trigger refresh_node.jstree
21591 */
21592 refresh_node : function (obj) {
21593 obj = this.get_node(obj);
21594 if(!obj || obj.id === '#') { return false; }
21595 var opened = [], to_load = [], s = this._data.core.selected.concat([]);
21596 to_load.push(obj.id);
21597 if(obj.state.opened === true) { opened.push(obj.id); }
21598 this.get_node(obj, true).find('.jstree-open').each(function() { opened.push(this.id); });
21599 this._load_nodes(to_load, $.proxy(function (nodes) {
21600 this.open_node(opened, false, 0);
21601 this.select_node(this._data.core.selected);
21602 /**
21603 * triggered when a node is refreshed
21604 * @event
21605 * @name refresh_node.jstree
21606 * @param {Object} node - the refreshed node
21607 * @param {Array} nodes - an array of the IDs of the nodes that were reloaded
21608 */
21609 this.trigger('refresh_node', { 'node' : obj, 'nodes' : nodes });
21610 }, this));
21611 },
21612 /**
21613 * set (change) the ID of a node
21614 * @name set_id(obj, id)
21615 * @param {mixed} obj the node
21616 * @param {String} id the new ID
21617 * @return {Boolean}
21618 */
21619 set_id : function (obj, id) {
21620 obj = this.get_node(obj);
21621 if(!obj || obj.id === '#') { return false; }
21622 var i, j, m = this._model.data;
21623 id = id.toString();
21624 // update parents (replace current ID with new one in children and children_d)
21625 m[obj.parent].children[$.inArray(obj.id, m[obj.parent].children)] = id;
21626 for(i = 0, j = obj.parents.length; i < j; i++) {
21627 m[obj.parents[i]].children_d[$.inArray(obj.id, m[obj.parents[i]].children_d)] = id;
21628 }
21629 // update children (replace current ID with new one in parent and parents)
21630 for(i = 0, j = obj.children.length; i < j; i++) {
21631 m[obj.children[i]].parent = id;
21632 }
21633 for(i = 0, j = obj.children_d.length; i < j; i++) {
21634 m[obj.children_d[i]].parents[$.inArray(obj.id, m[obj.children_d[i]].parents)] = id;
21635 }
21636 i = $.inArray(obj.id, this._data.core.selected);
21637 if(i !== -1) { this._data.core.selected[i] = id; }
21638 // update model and obj itself (obj.id, this._model.data[KEY])
21639 i = this.get_node(obj.id, true);
21640 if(i) {
21641 i.attr('id', id);
21642 }
21643 delete m[obj.id];
21644 obj.id = id;
21645 m[id] = obj;
21646 return true;
21647 },
21648 /**
21649 * get the text value of a node
21650 * @name get_text(obj)
21651 * @param {mixed} obj the node
21652 * @return {String}
21653 */
21654 get_text : function (obj) {
21655 obj = this.get_node(obj);
21656 return (!obj || obj.id === '#') ? false : obj.text;
21657 },
21658 /**
21659 * set the text value of a node. Used internally, please use `rename_node(obj, val)`.
21660 * @private
21661 * @name set_text(obj, val)
21662 * @param {mixed} obj the node, you can pass an array to set the text on multiple nodes
21663 * @param {String} val the new text value
21664 * @return {Boolean}
21665 * @trigger set_text.jstree
21666 */
21667 set_text : function (obj, val) {
21668 var t1, t2;
21669 if($.isArray(obj)) {
21670 obj = obj.slice();
21671 for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
21672 this.set_text(obj[t1], val);
21673 }
21674 return true;
21675 }
21676 obj = this.get_node(obj);
21677 if(!obj || obj.id === '#') { return false; }
21678 obj.text = val;
21679 if(this.get_node(obj, true).length) {
21680 this.redraw_node(obj.id);
21681 }
21682 /**
21683 * triggered when a node text value is changed
21684 * @event
21685 * @name set_text.jstree
21686 * @param {Object} obj
21687 * @param {String} text the new value
21688 */
21689 this.trigger('set_text',{ "obj" : obj, "text" : val });
21690 return true;
21691 },
21692 /**
21693 * gets a JSON representation of a node (or the whole tree)
21694 * @name get_json([obj, options])
21695 * @param {mixed} obj
21696 * @param {Object} options
21697 * @param {Boolean} options.no_state do not return state information
21698 * @param {Boolean} options.no_id do not return ID
21699 * @param {Boolean} options.no_children do not include children
21700 * @param {Boolean} options.no_data do not include node data
21701 * @param {Boolean} options.flat return flat JSON instead of nested
21702 * @return {Object}
21703 */
21704 get_json : function (obj, options, flat) {
21705 obj = this.get_node(obj || '#');
21706 if(!obj) { return false; }
21707 if(options && options.flat && !flat) { flat = []; }
21708 var tmp = {
21709 'id' : obj.id,
21710 'text' : obj.text,
21711 'icon' : this.get_icon(obj),
21712 'li_attr' : $.extend(true, {}, obj.li_attr),
21713 'a_attr' : $.extend(true, {}, obj.a_attr),
21714 'state' : {},
21715 'data' : options && options.no_data ? false : $.extend(true, {}, obj.data)
21716 //( this.get_node(obj, true).length ? this.get_node(obj, true).data() : obj.data ),
21717 }, i, j;
21718 if(options && options.flat) {
21719 tmp.parent = obj.parent;
21720 }
21721 else {
21722 tmp.children = [];
21723 }
21724 if(!options || !options.no_state) {
21725 for(i in obj.state) {
21726 if(obj.state.hasOwnProperty(i)) {
21727 tmp.state[i] = obj.state[i];
21728 }
21729 }
21730 }
21731 if(options && options.no_id) {
21732 delete tmp.id;
21733 if(tmp.li_attr && tmp.li_attr.id) {
21734 delete tmp.li_attr.id;
21735 }
21736 if(tmp.a_attr && tmp.a_attr.id) {
21737 delete tmp.a_attr.id;
21738 }
21739 }
21740 if(options && options.flat && obj.id !== '#') {
21741 flat.push(tmp);
21742 }
21743 if(!options || !options.no_children) {
21744 for(i = 0, j = obj.children.length; i < j; i++) {
21745 if(options && options.flat) {
21746 this.get_json(obj.children[i], options, flat);
21747 }
21748 else {
21749 tmp.children.push(this.get_json(obj.children[i], options));
21750 }
21751 }
21752 }
21753 return options && options.flat ? flat : (obj.id === '#' ? tmp.children : tmp);
21754 },
21755 /**
21756 * create a new node (do not confuse with load_node)
21757 * @name create_node([obj, node, pos, callback, is_loaded])
21758 * @param {mixed} par the parent node (to create a root node use either "#" (string) or `null`)
21759 * @param {mixed} node the data for the new node (a valid JSON object, or a simple string with the name)
21760 * @param {mixed} pos the index at which to insert the node, "first" and "last" are also supported, default is "last"
21761 * @param {Function} callback a function to be called once the node is created
21762 * @param {Boolean} is_loaded internal argument indicating if the parent node was succesfully loaded
21763 * @return {String} the ID of the newly create node
21764 * @trigger model.jstree, create_node.jstree
21765 */
21766 create_node : function (par, node, pos, callback, is_loaded) {
21767 if(par === null) { par = "#"; }
21768 par = this.get_node(par);
21769 if(!par) { return false; }
21770 pos = pos === undefined ? "last" : pos;
21771 if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) {
21772 return this.load_node(par, function () { this.create_node(par, node, pos, callback, true); });
21773 }
21774 if(!node) { node = { "text" : this.get_string('New node') }; }
21775 if(typeof node === "string") { node = { "text" : node }; }
21776 if(node.text === undefined) { node.text = this.get_string('New node'); }
21777 var tmp, dpc, i, j;
21778
21779 if(par.id === '#') {
21780 if(pos === "before") { pos = "first"; }
21781 if(pos === "after") { pos = "last"; }
21782 }
21783 switch(pos) {
21784 case "before":
21785 tmp = this.get_node(par.parent);
21786 pos = $.inArray(par.id, tmp.children);
21787 par = tmp;
21788 break;
21789 case "after" :
21790 tmp = this.get_node(par.parent);
21791 pos = $.inArray(par.id, tmp.children) + 1;
21792 par = tmp;
21793 break;
21794 case "inside":
21795 case "first":
21796 pos = 0;
21797 break;
21798 case "last":
21799 pos = par.children.length;
21800 break;
21801 default:
21802 if(!pos) { pos = 0; }
21803 break;
21804 }
21805 if(pos > par.children.length) { pos = par.children.length; }
21806 if(!node.id) { node.id = true; }
21807 if(!this.check("create_node", node, par, pos)) {
21808 this.settings.core.error.call(this, this._data.core.last_error);
21809 return false;
21810 }
21811 if(node.id === true) { delete node.id; }
21812 node = this._parse_model_from_json(node, par.id, par.parents.concat());
21813 if(!node) { return false; }
21814 tmp = this.get_node(node);
21815 dpc = [];
21816 dpc.push(node);
21817 dpc = dpc.concat(tmp.children_d);
21818 this.trigger('model', { "nodes" : dpc, "parent" : par.id });
21819
21820 par.children_d = par.children_d.concat(dpc);
21821 for(i = 0, j = par.parents.length; i < j; i++) {
21822 this._model.data[par.parents[i]].children_d = this._model.data[par.parents[i]].children_d.concat(dpc);
21823 }
21824 node = tmp;
21825 tmp = [];
21826 for(i = 0, j = par.children.length; i < j; i++) {
21827 tmp[i >= pos ? i+1 : i] = par.children[i];
21828 }
21829 tmp[pos] = node.id;
21830 par.children = tmp;
21831
21832 this.redraw_node(par, true);
21833 if(callback) { callback.call(this, this.get_node(node)); }
21834 /**
21835 * triggered when a node is created
21836 * @event
21837 * @name create_node.jstree
21838 * @param {Object} node
21839 * @param {String} parent the parent's ID
21840 * @param {Number} position the position of the new node among the parent's children
21841 */
21842 this.trigger('create_node', { "node" : this.get_node(node), "parent" : par.id, "position" : pos });
21843 return node.id;
21844 },
21845 /**
21846 * set the text value of a node
21847 * @name rename_node(obj, val)
21848 * @param {mixed} obj the node, you can pass an array to rename multiple nodes to the same name
21849 * @param {String} val the new text value
21850 * @return {Boolean}
21851 * @trigger rename_node.jstree
21852 */
21853 rename_node : function (obj, val) {
21854 var t1, t2, old;
21855 if($.isArray(obj)) {
21856 obj = obj.slice();
21857 for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
21858 this.rename_node(obj[t1], val);
21859 }
21860 return true;
21861 }
21862 obj = this.get_node(obj);
21863 if(!obj || obj.id === '#') { return false; }
21864 old = obj.text;
21865 if(!this.check("rename_node", obj, this.get_parent(obj), val)) {
21866 this.settings.core.error.call(this, this._data.core.last_error);
21867 return false;
21868 }
21869 this.set_text(obj, val); // .apply(this, Array.prototype.slice.call(arguments))
21870 /**
21871 * triggered when a node is renamed
21872 * @event
21873 * @name rename_node.jstree
21874 * @param {Object} node
21875 * @param {String} text the new value
21876 * @param {String} old the old value
21877 */
21878 this.trigger('rename_node', { "node" : obj, "text" : val, "old" : old });
21879 return true;
21880 },
21881 /**
21882 * remove a node
21883 * @name delete_node(obj)
21884 * @param {mixed} obj the node, you can pass an array to delete multiple nodes
21885 * @return {Boolean}
21886 * @trigger delete_node.jstree, changed.jstree
21887 */
21888 delete_node : function (obj) {
21889 var t1, t2, par, pos, tmp, i, j, k, l, c;
21890 if($.isArray(obj)) {
21891 obj = obj.slice();
21892 for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
21893 this.delete_node(obj[t1]);
21894 }
21895 return true;
21896 }
21897 obj = this.get_node(obj);
21898 if(!obj || obj.id === '#') { return false; }
21899 par = this.get_node(obj.parent);
21900 pos = $.inArray(obj.id, par.children);
21901 c = false;
21902 if(!this.check("delete_node", obj, par, pos)) {
21903 this.settings.core.error.call(this, this._data.core.last_error);
21904 return false;
21905 }
21906 if(pos !== -1) {
21907 par.children = $.vakata.array_remove(par.children, pos);
21908 }
21909 tmp = obj.children_d.concat([]);
21910 tmp.push(obj.id);
21911 for(k = 0, l = tmp.length; k < l; k++) {
21912 for(i = 0, j = obj.parents.length; i < j; i++) {
21913 pos = $.inArray(tmp[k], this._model.data[obj.parents[i]].children_d);
21914 if(pos !== -1) {
21915 this._model.data[obj.parents[i]].children_d = $.vakata.array_remove(this._model.data[obj.parents[i]].children_d, pos);
21916 }
21917 }
21918 if(this._model.data[tmp[k]].state.selected) {
21919 c = true;
21920 pos = $.inArray(tmp[k], this._data.core.selected);
21921 if(pos !== -1) {
21922 this._data.core.selected = $.vakata.array_remove(this._data.core.selected, pos);
21923 }
21924 }
21925 }
21926 /**
21927 * triggered when a node is deleted
21928 * @event
21929 * @name delete_node.jstree
21930 * @param {Object} node
21931 * @param {String} parent the parent's ID
21932 */
21933 this.trigger('delete_node', { "node" : obj, "parent" : par.id });
21934 if(c) {
21935 this.trigger('changed', { 'action' : 'delete_node', 'node' : obj, 'selected' : this._data.core.selected, 'parent' : par.id });
21936 }
21937 for(k = 0, l = tmp.length; k < l; k++) {
21938 delete this._model.data[tmp[k]];
21939 }
21940 this.redraw_node(par, true);
21941 return true;
21942 },
21943 /**
21944 * check if an operation is premitted on the tree. Used internally.
21945 * @private
21946 * @name check(chk, obj, par, pos)
21947 * @param {String} chk the operation to check, can be "create_node", "rename_node", "delete_node", "copy_node" or "move_node"
21948 * @param {mixed} obj the node
21949 * @param {mixed} par the parent
21950 * @param {mixed} pos the position to insert at, or if "rename_node" - the new name
21951 * @param {mixed} more some various additional information, for example if a "move_node" operations is triggered by DND this will be the hovered node
21952 * @return {Boolean}
21953 */
21954 check : function (chk, obj, par, pos, more) {
21955 obj = obj && obj.id ? obj : this.get_node(obj);
21956 par = par && par.id ? par : this.get_node(par);
21957 var tmp = chk.match(/^move_node|copy_node|create_node$/i) ? par : obj,
21958 chc = this.settings.core.check_callback;
21959 if(chk === "move_node" || chk === "copy_node") {
21960 if((!more || !more.is_multi) && (obj.id === par.id || $.inArray(obj.id, par.children) === pos || $.inArray(par.id, obj.children_d) !== -1)) {
21961 this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_01', 'reason' : 'Moving parent inside child', 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
21962 return false;
21963 }
21964 }
21965 if(tmp && tmp.data) { tmp = tmp.data; }
21966 if(tmp && tmp.functions && (tmp.functions[chk] === false || tmp.functions[chk] === true)) {
21967 if(tmp.functions[chk] === false) {
21968 this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_02', 'reason' : 'Node data prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
21969 }
21970 return tmp.functions[chk];
21971 }
21972 if(chc === false || ($.isFunction(chc) && chc.call(this, chk, obj, par, pos, more) === false) || (chc && chc[chk] === false)) {
21973 this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_03', 'reason' : 'User config for core.check_callback prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
21974 return false;
21975 }
21976 return true;
21977 },
21978 /**
21979 * get the last error
21980 * @name last_error()
21981 * @return {Object}
21982 */
21983 last_error : function () {
21984 return this._data.core.last_error;
21985 },
21986 /**
21987 * move a node to a new parent
21988 * @name move_node(obj, par [, pos, callback, is_loaded])
21989 * @param {mixed} obj the node to move, pass an array to move multiple nodes
21990 * @param {mixed} par the new parent
21991 * @param {mixed} pos the position to insert at (besides integer values, "first" and "last" are supported, as well as "before" and "after"), defaults to integer `0`
21992 * @param {function} callback a function to call once the move is completed, receives 3 arguments - the node, the new parent and the position
21993 * @param {Boolean} internal parameter indicating if the parent node has been loaded
21994 * @param {Boolean} internal parameter indicating if the tree should be redrawn
21995 * @trigger move_node.jstree
21996 */
21997 move_node : function (obj, par, pos, callback, is_loaded, skip_redraw) {
21998 var t1, t2, old_par, old_pos, new_par, old_ins, is_multi, dpc, tmp, i, j, k, l, p;
21999
22000 par = this.get_node(par);
22001 pos = pos === undefined ? 0 : pos;
22002 if(!par) { return false; }
22003 if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) {
22004 return this.load_node(par, function () { this.move_node(obj, par, pos, callback, true); });
22005 }
22006
22007 if($.isArray(obj)) {
22008 obj = obj.slice();
22009 for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
22010 if(this.move_node(obj[t1], par, pos, callback, is_loaded, true)) {
22011 par = obj[t1];
22012 pos = "after";
22013 }
22014 }
22015 this.redraw();
22016 return true;
22017 }
22018 obj = obj && obj.id ? obj : this.get_node(obj);
22019
22020 if(!obj || obj.id === '#') { return false; }
22021
22022 old_par = (obj.parent || '#').toString();
22023 new_par = (!pos.toString().match(/^(before|after)$/) || par.id === '#') ? par : this.get_node(par.parent);
22024 old_ins = obj.instance ? obj.instance : (this._model.data[obj.id] ? this : $.jstree.reference(obj.id));
22025 is_multi = !old_ins || !old_ins._id || (this._id !== old_ins._id);
22026 old_pos = old_ins && old_ins._id && old_par && old_ins._model.data[old_par] && old_ins._model.data[old_par].children ? $.inArray(obj.id, old_ins._model.data[old_par].children) : -1;
22027 if(is_multi) {
22028 if(this.copy_node(obj, par, pos, callback, is_loaded)) {
22029 if(old_ins) { old_ins.delete_node(obj); }
22030 return true;
22031 }
22032 return false;
22033 }
22034 //var m = this._model.data;
22035 if(par.id === '#') {
22036 if(pos === "before") { pos = "first"; }
22037 if(pos === "after") { pos = "last"; }
22038 }
22039 switch(pos) {
22040 case "before":
22041 pos = $.inArray(par.id, new_par.children);
22042 break;
22043 case "after" :
22044 pos = $.inArray(par.id, new_par.children) + 1;
22045 break;
22046 case "inside":
22047 case "first":
22048 pos = 0;
22049 break;
22050 case "last":
22051 pos = new_par.children.length;
22052 break;
22053 default:
22054 if(!pos) { pos = 0; }
22055 break;
22056 }
22057 if(pos > new_par.children.length) { pos = new_par.children.length; }
22058 if(!this.check("move_node", obj, new_par, pos, { 'core' : true, 'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id) })) {
22059 this.settings.core.error.call(this, this._data.core.last_error);
22060 return false;
22061 }
22062 if(obj.parent === new_par.id) {
22063 dpc = new_par.children.concat();
22064 tmp = $.inArray(obj.id, dpc);
22065 if(tmp !== -1) {
22066 dpc = $.vakata.array_remove(dpc, tmp);
22067 if(pos > tmp) { pos--; }
22068 }
22069 tmp = [];
22070 for(i = 0, j = dpc.length; i < j; i++) {
22071 tmp[i >= pos ? i+1 : i] = dpc[i];
22072 }
22073 tmp[pos] = obj.id;
22074 new_par.children = tmp;
22075 this._node_changed(new_par.id);
22076 this.redraw(new_par.id === '#');
22077 }
22078 else {
22079 // clean old parent and up
22080 tmp = obj.children_d.concat();
22081 tmp.push(obj.id);
22082 for(i = 0, j = obj.parents.length; i < j; i++) {
22083 dpc = [];
22084 p = old_ins._model.data[obj.parents[i]].children_d;
22085 for(k = 0, l = p.length; k < l; k++) {
22086 if($.inArray(p[k], tmp) === -1) {
22087 dpc.push(p[k]);
22088 }
22089 }
22090 old_ins._model.data[obj.parents[i]].children_d = dpc;
22091 }
22092 old_ins._model.data[old_par].children = $.vakata.array_remove_item(old_ins._model.data[old_par].children, obj.id);
22093
22094 // insert into new parent and up
22095 for(i = 0, j = new_par.parents.length; i < j; i++) {
22096 this._model.data[new_par.parents[i]].children_d = this._model.data[new_par.parents[i]].children_d.concat(tmp);
22097 }
22098 dpc = [];
22099 for(i = 0, j = new_par.children.length; i < j; i++) {
22100 dpc[i >= pos ? i+1 : i] = new_par.children[i];
22101 }
22102 dpc[pos] = obj.id;
22103 new_par.children = dpc;
22104 new_par.children_d.push(obj.id);
22105 new_par.children_d = new_par.children_d.concat(obj.children_d);
22106
22107 // update object
22108 obj.parent = new_par.id;
22109 tmp = new_par.parents.concat();
22110 tmp.unshift(new_par.id);
22111 p = obj.parents.length;
22112 obj.parents = tmp;
22113
22114 // update object children
22115 tmp = tmp.concat();
22116 for(i = 0, j = obj.children_d.length; i < j; i++) {
22117 this._model.data[obj.children_d[i]].parents = this._model.data[obj.children_d[i]].parents.slice(0,p*-1);
22118 Array.prototype.push.apply(this._model.data[obj.children_d[i]].parents, tmp);
22119 }
22120
22121 if(old_par === '#' || new_par.id === '#') {
22122 this._model.force_full_redraw = true;
22123 }
22124 if(!this._model.force_full_redraw) {
22125 this._node_changed(old_par);
22126 this._node_changed(new_par.id);
22127 }
22128 if(!skip_redraw) {
22129 this.redraw();
22130 }
22131 }
22132 if(callback) { callback.call(this, obj, new_par, pos); }
22133 /**
22134 * triggered when a node is moved
22135 * @event
22136 * @name move_node.jstree
22137 * @param {Object} node
22138 * @param {String} parent the parent's ID
22139 * @param {Number} position the position of the node among the parent's children
22140 * @param {String} old_parent the old parent of the node
22141 * @param {Number} old_position the old position of the node
22142 * @param {Boolean} is_multi do the node and new parent belong to different instances
22143 * @param {jsTree} old_instance the instance the node came from
22144 * @param {jsTree} new_instance the instance of the new parent
22145 */
22146 this.trigger('move_node', { "node" : obj, "parent" : new_par.id, "position" : pos, "old_parent" : old_par, "old_position" : old_pos, 'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id), 'old_instance' : old_ins, 'new_instance' : this });
22147 return true;
22148 },
22149 /**
22150 * copy a node to a new parent
22151 * @name copy_node(obj, par [, pos, callback, is_loaded])
22152 * @param {mixed} obj the node to copy, pass an array to copy multiple nodes
22153 * @param {mixed} par the new parent
22154 * @param {mixed} pos the position to insert at (besides integer values, "first" and "last" are supported, as well as "before" and "after"), defaults to integer `0`
22155 * @param {function} callback a function to call once the move is completed, receives 3 arguments - the node, the new parent and the position
22156 * @param {Boolean} internal parameter indicating if the parent node has been loaded
22157 * @param {Boolean} internal parameter indicating if the tree should be redrawn
22158 * @trigger model.jstree copy_node.jstree
22159 */
22160 copy_node : function (obj, par, pos, callback, is_loaded, skip_redraw) {
22161 var t1, t2, dpc, tmp, i, j, node, old_par, new_par, old_ins, is_multi;
22162
22163 par = this.get_node(par);
22164 pos = pos === undefined ? 0 : pos;
22165 if(!par) { return false; }
22166 if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) {
22167 return this.load_node(par, function () { this.copy_node(obj, par, pos, callback, true); });
22168 }
22169
22170 if($.isArray(obj)) {
22171 obj = obj.slice();
22172 for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
22173 tmp = this.copy_node(obj[t1], par, pos, callback, is_loaded, true);
22174 if(tmp) {
22175 par = tmp;
22176 pos = "after";
22177 }
22178 }
22179 this.redraw();
22180 return true;
22181 }
22182 obj = obj && obj.id ? obj : this.get_node(obj);
22183 if(!obj || obj.id === '#') { return false; }
22184
22185 old_par = (obj.parent || '#').toString();
22186 new_par = (!pos.toString().match(/^(before|after)$/) || par.id === '#') ? par : this.get_node(par.parent);
22187 old_ins = obj.instance ? obj.instance : (this._model.data[obj.id] ? this : $.jstree.reference(obj.id));
22188 is_multi = !old_ins || !old_ins._id || (this._id !== old_ins._id);
22189 if(par.id === '#') {
22190 if(pos === "before") { pos = "first"; }
22191 if(pos === "after") { pos = "last"; }
22192 }
22193 switch(pos) {
22194 case "before":
22195 pos = $.inArray(par.id, new_par.children);
22196 break;
22197 case "after" :
22198 pos = $.inArray(par.id, new_par.children) + 1;
22199 break;
22200 case "inside":
22201 case "first":
22202 pos = 0;
22203 break;
22204 case "last":
22205 pos = new_par.children.length;
22206 break;
22207 default:
22208 if(!pos) { pos = 0; }
22209 break;
22210 }
22211 if(pos > new_par.children.length) { pos = new_par.children.length; }
22212 if(!this.check("copy_node", obj, new_par, pos, { 'core' : true, 'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id) })) {
22213 this.settings.core.error.call(this, this._data.core.last_error);
22214 return false;
22215 }
22216 node = old_ins ? old_ins.get_json(obj, { no_id : true, no_data : true, no_state : true }) : obj;
22217 if(!node) { return false; }
22218 if(node.id === true) { delete node.id; }
22219 node = this._parse_model_from_json(node, new_par.id, new_par.parents.concat());
22220 if(!node) { return false; }
22221 tmp = this.get_node(node);
22222 if(obj && obj.state && obj.state.loaded === false) { tmp.state.loaded = false; }
22223 dpc = [];
22224 dpc.push(node);
22225 dpc = dpc.concat(tmp.children_d);
22226 this.trigger('model', { "nodes" : dpc, "parent" : new_par.id });
22227
22228 // insert into new parent and up
22229 for(i = 0, j = new_par.parents.length; i < j; i++) {
22230 this._model.data[new_par.parents[i]].children_d = this._model.data[new_par.parents[i]].children_d.concat(dpc);
22231 }
22232 dpc = [];
22233 for(i = 0, j = new_par.children.length; i < j; i++) {
22234 dpc[i >= pos ? i+1 : i] = new_par.children[i];
22235 }
22236 dpc[pos] = tmp.id;
22237 new_par.children = dpc;
22238 new_par.children_d.push(tmp.id);
22239 new_par.children_d = new_par.children_d.concat(tmp.children_d);
22240
22241 if(new_par.id === '#') {
22242 this._model.force_full_redraw = true;
22243 }
22244 if(!this._model.force_full_redraw) {
22245 this._node_changed(new_par.id);
22246 }
22247 if(!skip_redraw) {
22248 this.redraw(new_par.id === '#');
22249 }
22250 if(callback) { callback.call(this, tmp, new_par, pos); }
22251 /**
22252 * triggered when a node is copied
22253 * @event
22254 * @name copy_node.jstree
22255 * @param {Object} node the copied node
22256 * @param {Object} original the original node
22257 * @param {String} parent the parent's ID
22258 * @param {Number} position the position of the node among the parent's children
22259 * @param {String} old_parent the old parent of the node
22260 * @param {Number} old_position the position of the original node
22261 * @param {Boolean} is_multi do the node and new parent belong to different instances
22262 * @param {jsTree} old_instance the instance the node came from
22263 * @param {jsTree} new_instance the instance of the new parent
22264 */
22265 this.trigger('copy_node', { "node" : tmp, "original" : obj, "parent" : new_par.id, "position" : pos, "old_parent" : old_par, "old_position" : old_ins && old_ins._id && old_par && old_ins._model.data[old_par] && old_ins._model.data[old_par].children ? $.inArray(obj.id, old_ins._model.data[old_par].children) : -1,'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id), 'old_instance' : old_ins, 'new_instance' : this });
22266 return tmp.id;
22267 },
22268 /**
22269 * cut a node (a later call to `paste(obj)` would move the node)
22270 * @name cut(obj)
22271 * @param {mixed} obj multiple objects can be passed using an array
22272 * @trigger cut.jstree
22273 */
22274 cut : function (obj) {
22275 if(!obj) { obj = this._data.core.selected.concat(); }
22276 if(!$.isArray(obj)) { obj = [obj]; }
22277 if(!obj.length) { return false; }
22278 var tmp = [], o, t1, t2;
22279 for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
22280 o = this.get_node(obj[t1]);
22281 if(o && o.id && o.id !== '#') { tmp.push(o); }
22282 }
22283 if(!tmp.length) { return false; }
22284 ccp_node = tmp;
22285 ccp_inst = this;
22286 ccp_mode = 'move_node';
22287 /**
22288 * triggered when nodes are added to the buffer for moving
22289 * @event
22290 * @name cut.jstree
22291 * @param {Array} node
22292 */
22293 this.trigger('cut', { "node" : obj });
22294 },
22295 /**
22296 * copy a node (a later call to `paste(obj)` would copy the node)
22297 * @name copy(obj)
22298 * @param {mixed} obj multiple objects can be passed using an array
22299 * @trigger copy.jstre
22300 */
22301 copy : function (obj) {
22302 if(!obj) { obj = this._data.core.selected.concat(); }
22303 if(!$.isArray(obj)) { obj = [obj]; }
22304 if(!obj.length) { return false; }
22305 var tmp = [], o, t1, t2;
22306 for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
22307 o = this.get_node(obj[t1]);
22308 if(o && o.id && o.id !== '#') { tmp.push(o); }
22309 }
22310 if(!tmp.length) { return false; }
22311 ccp_node = tmp;
22312 ccp_inst = this;
22313 ccp_mode = 'copy_node';
22314 /**
22315 * triggered when nodes are added to the buffer for copying
22316 * @event
22317 * @name copy.jstree
22318 * @param {Array} node
22319 */
22320 this.trigger('copy', { "node" : obj });
22321 },
22322 /**
22323 * get the current buffer (any nodes that are waiting for a paste operation)
22324 * @name get_buffer()
22325 * @return {Object} an object consisting of `mode` ("copy_node" or "move_node"), `node` (an array of objects) and `inst` (the instance)
22326 */
22327 get_buffer : function () {
22328 return { 'mode' : ccp_mode, 'node' : ccp_node, 'inst' : ccp_inst };
22329 },
22330 /**
22331 * check if there is something in the buffer to paste
22332 * @name can_paste()
22333 * @return {Boolean}
22334 */
22335 can_paste : function () {
22336 return ccp_mode !== false && ccp_node !== false; // && ccp_inst._model.data[ccp_node];
22337 },
22338 /**
22339 * copy or move the previously cut or copied nodes to a new parent
22340 * @name paste(obj [, pos])
22341 * @param {mixed} obj the new parent
22342 * @param {mixed} pos the position to insert at (besides integer, "first" and "last" are supported), defaults to integer `0`
22343 * @trigger paste.jstree
22344 */
22345 paste : function (obj, pos) {
22346 obj = this.get_node(obj);
22347 if(!obj || !ccp_mode || !ccp_mode.match(/^(copy_node|move_node)$/) || !ccp_node) { return false; }
22348 if(this[ccp_mode](ccp_node, obj, pos)) {
22349 /**
22350 * triggered when paste is invoked
22351 * @event
22352 * @name paste.jstree
22353 * @param {String} parent the ID of the receiving node
22354 * @param {Array} node the nodes in the buffer
22355 * @param {String} mode the performed operation - "copy_node" or "move_node"
22356 */
22357 this.trigger('paste', { "parent" : obj.id, "node" : ccp_node, "mode" : ccp_mode });
22358 }
22359 ccp_node = false;
22360 ccp_mode = false;
22361 ccp_inst = false;
22362 },
22363 /**
22364 * clear the buffer of previously copied or cut nodes
22365 * @name clear_buffer()
22366 * @trigger clear_buffer.jstree
22367 */
22368 clear_buffer : function () {
22369 ccp_node = false;
22370 ccp_mode = false;
22371 ccp_inst = false;
22372 /**
22373 * triggered when the copy / cut buffer is cleared
22374 * @event
22375 * @name clear_buffer.jstree
22376 */
22377 this.trigger('clear_buffer');
22378 },
22379 /**
22380 * put a node in edit mode (input field to rename the node)
22381 * @name edit(obj [, default_text])
22382 * @param {mixed} obj
22383 * @param {String} default_text the text to populate the input with (if omitted the node text value is used)
22384 */
22385 edit : function (obj, default_text) {
22386 obj = this.get_node(obj);
22387 if(!obj) { return false; }
22388 if(this.settings.core.check_callback === false) {
22389 this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_07', 'reason' : 'Could not edit node because of check_callback' };
22390 this.settings.core.error.call(this, this._data.core.last_error);
22391 return false;
22392 }
22393 default_text = typeof default_text === 'string' ? default_text : obj.text;
22394 this.set_text(obj, "");
22395 obj = this._open_to(obj);
22396
22397 var rtl = this._data.core.rtl,
22398 w = this.element.width(),
22399 a = obj.children('.jstree-anchor'),
22400 s = $('<span>'),
22401 /*!
22402 oi = obj.children("i:visible"),
22403 ai = a.children("i:visible"),
22404 w1 = oi.width() * oi.length,
22405 w2 = ai.width() * ai.length,
22406 */
22407 t = default_text,
22408 h1 = $("<"+"div />", { css : { "position" : "absolute", "top" : "-200px", "left" : (rtl ? "0px" : "-1000px"), "visibility" : "hidden" } }).appendTo("body"),
22409 h2 = $("<"+"input />", {
22410 "value" : t,
22411 "class" : "jstree-rename-input",
22412 // "size" : t.length,
22413 "css" : {
22414 "padding" : "0",
22415 "border" : "1px solid silver",
22416 "box-sizing" : "border-box",
22417 "display" : "inline-block",
22418 "height" : (this._data.core.li_height) + "px",
22419 "lineHeight" : (this._data.core.li_height) + "px",
22420 "width" : "150px" // will be set a bit further down
22421 },
22422 "blur" : $.proxy(function () {
22423 var i = s.children(".jstree-rename-input"),
22424 v = i.val();
22425 if(v === "") { v = t; }
22426 h1.remove();
22427 s.replaceWith(a);
22428 s.remove();
22429 this.set_text(obj, t);
22430 if(this.rename_node(obj, $('<div></div>').text(v)[this.settings.core.force_text ? 'text' : 'html']()) === false) {
22431 this.set_text(obj, t); // move this up? and fix #483
22432 }
22433 }, this),
22434 "keydown" : function (event) {
22435 var key = event.which;
22436 if(key === 27) {
22437 this.value = t;
22438 }
22439 if(key === 27 || key === 13 || key === 37 || key === 38 || key === 39 || key === 40 || key === 32) {
22440 event.stopImmediatePropagation();
22441 }
22442 if(key === 27 || key === 13) {
22443 event.preventDefault();
22444 this.blur();
22445 }
22446 },
22447 "click" : function (e) { e.stopImmediatePropagation(); },
22448 "mousedown" : function (e) { e.stopImmediatePropagation(); },
22449 "keyup" : function (event) {
22450 h2.width(Math.min(h1.text("pW" + this.value).width(),w));
22451 },
22452 "keypress" : function(event) {
22453 if(event.which === 13) { return false; }
22454 }
22455 }),
22456 fn = {
22457 fontFamily : a.css('fontFamily') || '',
22458 fontSize : a.css('fontSize') || '',
22459 fontWeight : a.css('fontWeight') || '',
22460 fontStyle : a.css('fontStyle') || '',
22461 fontStretch : a.css('fontStretch') || '',
22462 fontVariant : a.css('fontVariant') || '',
22463 letterSpacing : a.css('letterSpacing') || '',
22464 wordSpacing : a.css('wordSpacing') || ''
22465 };
22466 s.attr('class', a.attr('class')).append(a.contents().clone()).append(h2);
22467 a.replaceWith(s);
22468 h1.css(fn);
22469 h2.css(fn).width(Math.min(h1.text("pW" + h2[0].value).width(),w))[0].select();
22470 },
22471
22472
22473 /**
22474 * changes the theme
22475 * @name set_theme(theme_name [, theme_url])
22476 * @param {String} theme_name the name of the new theme to apply
22477 * @param {mixed} theme_url the location of the CSS file for this theme. Omit or set to `false` if you manually included the file. Set to `true` to autoload from the `core.themes.dir` directory.
22478 * @trigger set_theme.jstree
22479 */
22480 set_theme : function (theme_name, theme_url) {
22481 if(!theme_name) { return false; }
22482 if(theme_url === true) {
22483 var dir = this.settings.core.themes.dir;
22484 if(!dir) { dir = $.jstree.path + '/themes'; }
22485 theme_url = dir + '/' + theme_name + '/style.css';
22486 }
22487 if(theme_url && $.inArray(theme_url, themes_loaded) === -1) {
22488 $('head').append('<'+'link rel="stylesheet" href="' + theme_url + '" type="text/css" />');
22489 themes_loaded.push(theme_url);
22490 }
22491 if(this._data.core.themes.name) {
22492 this.element.removeClass('jstree-' + this._data.core.themes.name);
22493 }
22494 this._data.core.themes.name = theme_name;
22495 this.element.addClass('jstree-' + theme_name);
22496 this.element[this.settings.core.themes.responsive ? 'addClass' : 'removeClass' ]('jstree-' + theme_name + '-responsive');
22497 /**
22498 * triggered when a theme is set
22499 * @event
22500 * @name set_theme.jstree
22501 * @param {String} theme the new theme
22502 */
22503 this.trigger('set_theme', { 'theme' : theme_name });
22504 },
22505 /**
22506 * gets the name of the currently applied theme name
22507 * @name get_theme()
22508 * @return {String}
22509 */
22510 get_theme : function () { return this._data.core.themes.name; },
22511 /**
22512 * changes the theme variant (if the theme has variants)
22513 * @name set_theme_variant(variant_name)
22514 * @param {String|Boolean} variant_name the variant to apply (if `false` is used the current variant is removed)
22515 */
22516 set_theme_variant : function (variant_name) {
22517 if(this._data.core.themes.variant) {
22518 this.element.removeClass('jstree-' + this._data.core.themes.name + '-' + this._data.core.themes.variant);
22519 }
22520 this._data.core.themes.variant = variant_name;
22521 if(variant_name) {
22522 this.element.addClass('jstree-' + this._data.core.themes.name + '-' + this._data.core.themes.variant);
22523 }
22524 },
22525 /**
22526 * gets the name of the currently applied theme variant
22527 * @name get_theme()
22528 * @return {String}
22529 */
22530 get_theme_variant : function () { return this._data.core.themes.variant; },
22531 /**
22532 * shows a striped background on the container (if the theme supports it)
22533 * @name show_stripes()
22534 */
22535 show_stripes : function () { this._data.core.themes.stripes = true; this.get_container_ul().addClass("jstree-striped"); },
22536 /**
22537 * hides the striped background on the container
22538 * @name hide_stripes()
22539 */
22540 hide_stripes : function () { this._data.core.themes.stripes = false; this.get_container_ul().removeClass("jstree-striped"); },
22541 /**
22542 * toggles the striped background on the container
22543 * @name toggle_stripes()
22544 */
22545 toggle_stripes : function () { if(this._data.core.themes.stripes) { this.hide_stripes(); } else { this.show_stripes(); } },
22546 /**
22547 * shows the connecting dots (if the theme supports it)
22548 * @name show_dots()
22549 */
22550 show_dots : function () { this._data.core.themes.dots = true; this.get_container_ul().removeClass("jstree-no-dots"); },
22551 /**
22552 * hides the connecting dots
22553 * @name hide_dots()
22554 */
22555 hide_dots : function () { this._data.core.themes.dots = false; this.get_container_ul().addClass("jstree-no-dots"); },
22556 /**
22557 * toggles the connecting dots
22558 * @name toggle_dots()
22559 */
22560 toggle_dots : function () { if(this._data.core.themes.dots) { this.hide_dots(); } else { this.show_dots(); } },
22561 /**
22562 * show the node icons
22563 * @name show_icons()
22564 */
22565 show_icons : function () { this._data.core.themes.icons = true; this.get_container_ul().removeClass("jstree-no-icons"); },
22566 /**
22567 * hide the node icons
22568 * @name hide_icons()
22569 */
22570 hide_icons : function () { this._data.core.themes.icons = false; this.get_container_ul().addClass("jstree-no-icons"); },
22571 /**
22572 * toggle the node icons
22573 * @name toggle_icons()
22574 */
22575 toggle_icons : function () { if(this._data.core.themes.icons) { this.hide_icons(); } else { this.show_icons(); } },
22576 /**
22577 * set the node icon for a node
22578 * @name set_icon(obj, icon)
22579 * @param {mixed} obj
22580 * @param {String} icon the new icon - can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class
22581 */
22582 set_icon : function (obj, icon) {
22583 var t1, t2, dom, old;
22584 if($.isArray(obj)) {
22585 obj = obj.slice();
22586 for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
22587 this.set_icon(obj[t1], icon);
22588 }
22589 return true;
22590 }
22591 obj = this.get_node(obj);
22592 if(!obj || obj.id === '#') { return false; }
22593 old = obj.icon;
22594 obj.icon = icon;
22595 dom = this.get_node(obj, true).children(".jstree-anchor").children(".jstree-themeicon");
22596 if(icon === false) {
22597 this.hide_icon(obj);
22598 }
22599 else if(icon === true) {
22600 dom.removeClass('jstree-themeicon-custom ' + old).css("background","").removeAttr("rel");
22601 if(old === false) { this.show_icon(obj); }
22602 }
22603 else if(icon.indexOf("/") === -1 && icon.indexOf(".") === -1) {
22604 dom.removeClass(old).css("background","");
22605 dom.addClass(icon + ' jstree-themeicon-custom').attr("rel",icon);
22606 if(old === false) { this.show_icon(obj); }
22607 }
22608 else {
22609 dom.removeClass(old).css("background","");
22610 dom.addClass('jstree-themeicon-custom').css("background", "url('" + icon + "') center center no-repeat").attr("rel",icon);
22611 if(old === false) { this.show_icon(obj); }
22612 }
22613 return true;
22614 },
22615 /**
22616 * get the node icon for a node
22617 * @name get_icon(obj)
22618 * @param {mixed} obj
22619 * @return {String}
22620 */
22621 get_icon : function (obj) {
22622 obj = this.get_node(obj);
22623 return (!obj || obj.id === '#') ? false : obj.icon;
22624 },
22625 /**
22626 * hide the icon on an individual node
22627 * @name hide_icon(obj)
22628 * @param {mixed} obj
22629 */
22630 hide_icon : function (obj) {
22631 var t1, t2;
22632 if($.isArray(obj)) {
22633 obj = obj.slice();
22634 for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
22635 this.hide_icon(obj[t1]);
22636 }
22637 return true;
22638 }
22639 obj = this.get_node(obj);
22640 if(!obj || obj === '#') { return false; }
22641 obj.icon = false;
22642 this.get_node(obj, true).children(".jstree-anchor").children(".jstree-themeicon").addClass('jstree-themeicon-hidden');
22643 return true;
22644 },
22645 /**
22646 * show the icon on an individual node
22647 * @name show_icon(obj)
22648 * @param {mixed} obj
22649 */
22650 show_icon : function (obj) {
22651 var t1, t2, dom;
22652 if($.isArray(obj)) {
22653 obj = obj.slice();
22654 for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
22655 this.show_icon(obj[t1]);
22656 }
22657 return true;
22658 }
22659 obj = this.get_node(obj);
22660 if(!obj || obj === '#') { return false; }
22661 dom = this.get_node(obj, true);
22662 obj.icon = dom.length ? dom.children(".jstree-anchor").children(".jstree-themeicon").attr('rel') : true;
22663 if(!obj.icon) { obj.icon = true; }
22664 dom.children(".jstree-anchor").children(".jstree-themeicon").removeClass('jstree-themeicon-hidden');
22665 return true;
22666 }
22667 };
22668
22669 // helpers
22670 $.vakata = {};
22671 // collect attributes
22672 $.vakata.attributes = function(node, with_values) {
22673 node = $(node)[0];
22674 var attr = with_values ? {} : [];
22675 if(node && node.attributes) {
22676 $.each(node.attributes, function (i, v) {
22677 if($.inArray(v.name.toLowerCase(),['style','contenteditable','hasfocus','tabindex']) !== -1) { return; }
22678 if(v.value !== null && $.trim(v.value) !== '') {
22679 if(with_values) { attr[v.name] = v.value; }
22680 else { attr.push(v.name); }
22681 }
22682 });
22683 }
22684 return attr;
22685 };
22686 $.vakata.array_unique = function(array) {
22687 var a = [], i, j, l;
22688 for(i = 0, l = array.length; i < l; i++) {
22689 for(j = 0; j <= i; j++) {
22690 if(array[i] === array[j]) {
22691 break;
22692 }
22693 }
22694 if(j === i) { a.push(array[i]); }
22695 }
22696 return a;
22697 };
22698 // remove item from array
22699 $.vakata.array_remove = function(array, from, to) {
22700 var rest = array.slice((to || from) + 1 || array.length);
22701 array.length = from < 0 ? array.length + from : from;
22702 array.push.apply(array, rest);
22703 return array;
22704 };
22705 // remove item from array
22706 $.vakata.array_remove_item = function(array, item) {
22707 var tmp = $.inArray(item, array);
22708 return tmp !== -1 ? $.vakata.array_remove(array, tmp) : array;
22709 };
22710
22711
18306 /** 22712 /**
22713 * ### Checkbox plugin
22714 *
22715 * This plugin renders checkbox icons in front of each node, making multiple selection much easier.
22716 * It also supports tri-state behavior, meaning that if a node has a few of its children checked it will be rendered as undetermined, and state will be propagated up.
22717 */
22718
22719 var _i = document.createElement('I');
22720 _i.className = 'jstree-icon jstree-checkbox';
22721 _i.setAttribute('role', 'presentation');
22722 /**
22723 * stores all defaults for the checkbox plugin
22724 * @name $.jstree.defaults.checkbox
22725 * @plugin checkbox
22726 */
22727 $.jstree.defaults.checkbox = {
22728 /**
22729 * a boolean indicating if checkboxes should be visible (can be changed at a later time using `show_checkboxes()` and `hide_checkboxes`). Defaults to `true`.
22730 * @name $.jstree.defaults.checkbox.visible
22731 * @plugin checkbox
22732 */
22733 visible : true,
22734 /**
22735 * a boolean indicating if checkboxes should cascade down and have an undetermined state. Defaults to `true`.
22736 * @name $.jstree.defaults.checkbox.three_state
22737 * @plugin checkbox
22738 */
22739 three_state : true,
22740 /**
22741 * a boolean indicating if clicking anywhere on the node should act as clicking on the checkbox. Defaults to `true`.
22742 * @name $.jstree.defaults.checkbox.whole_node
22743 * @plugin checkbox
22744 */
22745 whole_node : true,
22746 /**
22747 * a boolean indicating if the selected style of a node should be kept, or removed. Defaults to `true`.
22748 * @name $.jstree.defaults.checkbox.keep_selected_style
22749 * @plugin checkbox
22750 */
22751 keep_selected_style : true,
22752 /**
22753 * This setting controls how cascading and undetermined nodes are applied.
22754 * If 'up' is in the string - cascading up is enabled, if 'down' is in the string - cascading down is enabled, if 'undetermined' is in the string - undetermined nodes will be used.
22755 * If `three_state` is set to `true` this setting is automatically set to 'up+down+undetermined'. Defaults to ''.
22756 * @name $.jstree.defaults.checkbox.cascade
22757 * @plugin checkbox
22758 */
22759 cascade : '',
22760 /**
22761 * This setting controls if checkbox are bound to the general tree selection or to an internal array maintained by the checkbox plugin. Defaults to `true`, only set to `false` if you know exactly what you are doing.
22762 * @name $.jstree.defaults.checkbox.tie_selection
22763 * @plugin checkbox
22764 */
22765 tie_selection : true
22766 };
22767 $.jstree.plugins.checkbox = function (options, parent) {
22768 this.bind = function () {
22769 parent.bind.call(this);
22770 this._data.checkbox.uto = false;
22771 this._data.checkbox.selected = [];
22772 if(this.settings.checkbox.three_state) {
22773 this.settings.checkbox.cascade = 'up+down+undetermined';
22774 }
22775 this.element
22776 .on("init.jstree", $.proxy(function () {
22777 this._data.checkbox.visible = this.settings.checkbox.visible;
22778 if(!this.settings.checkbox.keep_selected_style) {
22779 this.element.addClass('jstree-checkbox-no-clicked');
22780 }
22781 if(this.settings.checkbox.tie_selection) {
22782 this.element.addClass('jstree-checkbox-selection');
22783 }
22784 }, this))
22785 .on("loading.jstree", $.proxy(function () {
22786 this[ this._data.checkbox.visible ? 'show_checkboxes' : 'hide_checkboxes' ]();
22787 }, this));
22788 if(this.settings.checkbox.cascade.indexOf('undetermined') !== -1) {
22789 this.element
22790 .on('changed.jstree uncheck_node.jstree check_node.jstree uncheck_all.jstree check_all.jstree move_node.jstree copy_node.jstree redraw.jstree open_node.jstree', $.proxy(function () {
22791 // only if undetermined is in setting
22792 if(this._data.checkbox.uto) { clearTimeout(this._data.checkbox.uto); }
22793 this._data.checkbox.uto = setTimeout($.proxy(this._undetermined, this), 50);
22794 }, this));
22795 }
22796 if(!this.settings.checkbox.tie_selection) {
22797 this.element
22798 .on('model.jstree', $.proxy(function (e, data) {
22799 var m = this._model.data,
22800 p = m[data.parent],
22801 dpc = data.nodes,
22802 i, j;
22803 for(i = 0, j = dpc.length; i < j; i++) {
22804 m[dpc[i]].state.checked = (m[dpc[i]].original && m[dpc[i]].original.state && m[dpc[i]].original.state.checked);
22805 if(m[dpc[i]].state.checked) {
22806 this._data.checkbox.selected.push(dpc[i]);
22807 }
22808 }
22809 }, this));
22810 }
22811 if(this.settings.checkbox.cascade.indexOf('up') !== -1 || this.settings.checkbox.cascade.indexOf('down') !== -1) {
22812 this.element
22813 .on('model.jstree', $.proxy(function (e, data) {
22814 var m = this._model.data,
22815 p = m[data.parent],
22816 dpc = data.nodes,
22817 chd = [],
22818 c, i, j, k, l, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection;
22819
22820 if(s.indexOf('down') !== -1) {
22821 // apply down
22822 if(p.state[ t ? 'selected' : 'checked' ]) {
22823 for(i = 0, j = dpc.length; i < j; i++) {
22824 m[dpc[i]].state[ t ? 'selected' : 'checked' ] = true;
22825 }
22826 this._data[ t ? 'core' : 'checkbox' ].selected = this._data[ t ? 'core' : 'checkbox' ].selected.concat(dpc);
22827 }
22828 else {
22829 for(i = 0, j = dpc.length; i < j; i++) {
22830 if(m[dpc[i]].state[ t ? 'selected' : 'checked' ]) {
22831 for(k = 0, l = m[dpc[i]].children_d.length; k < l; k++) {
22832 m[m[dpc[i]].children_d[k]].state[ t ? 'selected' : 'checked' ] = true;
22833 }
22834 this._data[ t ? 'core' : 'checkbox' ].selected = this._data[ t ? 'core' : 'checkbox' ].selected.concat(m[dpc[i]].children_d);
22835 }
22836 }
22837 }
22838 }
22839
22840 if(s.indexOf('up') !== -1) {
22841 // apply up
22842 for(i = 0, j = p.children_d.length; i < j; i++) {
22843 if(!m[p.children_d[i]].children.length) {
22844 chd.push(m[p.children_d[i]].parent);
22845 }
22846 }
22847 chd = $.vakata.array_unique(chd);
22848 for(k = 0, l = chd.length; k < l; k++) {
22849 p = m[chd[k]];
22850 while(p && p.id !== '#') {
22851 c = 0;
22852 for(i = 0, j = p.children.length; i < j; i++) {
22853 c += m[p.children[i]].state[ t ? 'selected' : 'checked' ];
22854 }
22855 if(c === j) {
22856 p.state[ t ? 'selected' : 'checked' ] = true;
22857 this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id);
22858 tmp = this.get_node(p, true);
22859 if(tmp && tmp.length) {
22860 tmp.attr('aria-selected', true).children('.jstree-anchor').addClass( t ? 'jstree-clicked' : 'jstree-checked');
22861 }
22862 }
22863 else {
22864 break;
22865 }
22866 p = this.get_node(p.parent);
22867 }
22868 }
22869 }
22870
22871 this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_unique(this._data[ t ? 'core' : 'checkbox' ].selected);
22872 }, this))
22873 .on(this.settings.checkbox.tie_selection ? 'select_node.jstree' : 'check_node.jstree', $.proxy(function (e, data) {
22874 var obj = data.node,
22875 m = this._model.data,
22876 par = this.get_node(obj.parent),
22877 dom = this.get_node(obj, true),
22878 i, j, c, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection;
22879
22880 // apply down
22881 if(s.indexOf('down') !== -1) {
22882 this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_unique(this._data[ t ? 'core' : 'checkbox' ].selected.concat(obj.children_d));
22883 for(i = 0, j = obj.children_d.length; i < j; i++) {
22884 tmp = m[obj.children_d[i]];
22885 tmp.state[ t ? 'selected' : 'checked' ] = true;
22886 if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) {
22887 tmp.original.state.undetermined = false;
22888 }
22889 }
22890 }
22891
22892 // apply up
22893 if(s.indexOf('up') !== -1) {
22894 while(par && par.id !== '#') {
22895 c = 0;
22896 for(i = 0, j = par.children.length; i < j; i++) {
22897 c += m[par.children[i]].state[ t ? 'selected' : 'checked' ];
22898 }
22899 if(c === j) {
22900 par.state[ t ? 'selected' : 'checked' ] = true;
22901 this._data[ t ? 'core' : 'checkbox' ].selected.push(par.id);
22902 tmp = this.get_node(par, true);
22903 if(tmp && tmp.length) {
22904 tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked');
22905 }
22906 }
22907 else {
22908 break;
22909 }
22910 par = this.get_node(par.parent);
22911 }
22912 }
22913
22914 // apply down (process .children separately?)
22915 if(s.indexOf('down') !== -1 && dom.length) {
22916 dom.find('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked').parent().attr('aria-selected', true);
22917 }
22918 }, this))
22919 .on(this.settings.checkbox.tie_selection ? 'deselect_all.jstree' : 'uncheck_all.jstree', $.proxy(function (e, data) {
22920 var obj = this.get_node('#'),
22921 m = this._model.data,
22922 i, j, tmp;
22923 for(i = 0, j = obj.children_d.length; i < j; i++) {
22924 tmp = m[obj.children_d[i]];
22925 if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) {
22926 tmp.original.state.undetermined = false;
22927 }
22928 }
22929 }, this))
22930 .on(this.settings.checkbox.tie_selection ? 'deselect_node.jstree' : 'uncheck_node.jstree', $.proxy(function (e, data) {
22931 var obj = data.node,
22932 dom = this.get_node(obj, true),
22933 i, j, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection;
22934 if(obj && obj.original && obj.original.state && obj.original.state.undetermined) {
22935 obj.original.state.undetermined = false;
22936 }
22937
22938 // apply down
22939 if(s.indexOf('down') !== -1) {
22940 for(i = 0, j = obj.children_d.length; i < j; i++) {
22941 tmp = this._model.data[obj.children_d[i]];
22942 tmp.state[ t ? 'selected' : 'checked' ] = false;
22943 if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) {
22944 tmp.original.state.undetermined = false;
22945 }
22946 }
22947 }
22948
22949 // apply up
22950 if(s.indexOf('up') !== -1) {
22951 for(i = 0, j = obj.parents.length; i < j; i++) {
22952 tmp = this._model.data[obj.parents[i]];
22953 tmp.state[ t ? 'selected' : 'checked' ] = false;
22954 if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) {
22955 tmp.original.state.undetermined = false;
22956 }
22957 tmp = this.get_node(obj.parents[i], true);
22958 if(tmp && tmp.length) {
22959 tmp.attr('aria-selected', false).children('.jstree-anchor').removeClass(t ? 'jstree-clicked' : 'jstree-checked');
22960 }
22961 }
22962 }
22963 tmp = [];
22964 for(i = 0, j = this._data[ t ? 'core' : 'checkbox' ].selected.length; i < j; i++) {
22965 // apply down + apply up
22966 if(
22967 (s.indexOf('down') === -1 || $.inArray(this._data[ t ? 'core' : 'checkbox' ].selected[i], obj.children_d) === -1) &&
22968 (s.indexOf('up') === -1 || $.inArray(this._data[ t ? 'core' : 'checkbox' ].selected[i], obj.parents) === -1)
22969 ) {
22970 tmp.push(this._data[ t ? 'core' : 'checkbox' ].selected[i]);
22971 }
22972 }
22973 this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_unique(tmp);
22974
22975 // apply down (process .children separately?)
22976 if(s.indexOf('down') !== -1 && dom.length) {
22977 dom.find('.jstree-anchor').removeClass(t ? 'jstree-clicked' : 'jstree-checked').parent().attr('aria-selected', false);
22978 }
22979 }, this));
22980 }
22981 if(this.settings.checkbox.cascade.indexOf('up') !== -1) {
22982 this.element
22983 .on('delete_node.jstree', $.proxy(function (e, data) {
22984 // apply up (whole handler)
22985 var p = this.get_node(data.parent),
22986 m = this._model.data,
22987 i, j, c, tmp, t = this.settings.checkbox.tie_selection;
22988 while(p && p.id !== '#') {
22989 c = 0;
22990 for(i = 0, j = p.children.length; i < j; i++) {
22991 c += m[p.children[i]].state[ t ? 'selected' : 'checked' ];
22992 }
22993 if(c === j) {
22994 p.state[ t ? 'selected' : 'checked' ] = true;
22995 this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id);
22996 tmp = this.get_node(p, true);
22997 if(tmp && tmp.length) {
22998 tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked');
22999 }
23000 }
23001 else {
23002 break;
23003 }
23004 p = this.get_node(p.parent);
23005 }
23006 }, this))
23007 .on('move_node.jstree', $.proxy(function (e, data) {
23008 // apply up (whole handler)
23009 var is_multi = data.is_multi,
23010 old_par = data.old_parent,
23011 new_par = this.get_node(data.parent),
23012 m = this._model.data,
23013 p, c, i, j, tmp, t = this.settings.checkbox.tie_selection;
23014 if(!is_multi) {
23015 p = this.get_node(old_par);
23016 while(p && p.id !== '#') {
23017 c = 0;
23018 for(i = 0, j = p.children.length; i < j; i++) {
23019 c += m[p.children[i]].state[ t ? 'selected' : 'checked' ];
23020 }
23021 if(c === j) {
23022 p.state[ t ? 'selected' : 'checked' ] = true;
23023 this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id);
23024 tmp = this.get_node(p, true);
23025 if(tmp && tmp.length) {
23026 tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked');
23027 }
23028 }
23029 else {
23030 break;
23031 }
23032 p = this.get_node(p.parent);
23033 }
23034 }
23035 p = new_par;
23036 while(p && p.id !== '#') {
23037 c = 0;
23038 for(i = 0, j = p.children.length; i < j; i++) {
23039 c += m[p.children[i]].state[ t ? 'selected' : 'checked' ];
23040 }
23041 if(c === j) {
23042 if(!p.state[ t ? 'selected' : 'checked' ]) {
23043 p.state[ t ? 'selected' : 'checked' ] = true;
23044 this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id);
23045 tmp = this.get_node(p, true);
23046 if(tmp && tmp.length) {
23047 tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked');
23048 }
23049 }
23050 }
23051 else {
23052 if(p.state[ t ? 'selected' : 'checked' ]) {
23053 p.state[ t ? 'selected' : 'checked' ] = false;
23054 this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_remove_item(this._data[ t ? 'core' : 'checkbox' ].selected, p.id);
23055 tmp = this.get_node(p, true);
23056 if(tmp && tmp.length) {
23057 tmp.attr('aria-selected', false).children('.jstree-anchor').removeClass(t ? 'jstree-clicked' : 'jstree-checked');
23058 }
23059 }
23060 else {
23061 break;
23062 }
23063 }
23064 p = this.get_node(p.parent);
23065 }
23066 }, this));
23067 }
23068 };
23069 /**
23070 * set the undetermined state where and if necessary. Used internally.
23071 * @private
23072 * @name _undetermined()
23073 * @plugin checkbox
23074 */
23075 this._undetermined = function () {
23076 var i, j, m = this._model.data, t = this.settings.checkbox.tie_selection, s = this._data[ t ? 'core' : 'checkbox' ].selected, p = [], tt = this;
23077 for(i = 0, j = s.length; i < j; i++) {
23078 if(m[s[i]] && m[s[i]].parents) {
23079 p = p.concat(m[s[i]].parents);
23080 }
23081 }
23082 // attempt for server side undetermined state
23083 this.element.find('.jstree-closed').not(':has(.jstree-children)')
23084 .each(function () {
23085 var tmp = tt.get_node(this), tmp2;
23086 if(!tmp.state.loaded) {
23087 if(tmp.original && tmp.original.state && tmp.original.state.undetermined && tmp.original.state.undetermined === true) {
23088 p.push(tmp.id);
23089 p = p.concat(tmp.parents);
23090 }
23091 }
23092 else {
23093 for(i = 0, j = tmp.children_d.length; i < j; i++) {
23094 tmp2 = m[tmp.children_d[i]];
23095 if(!tmp2.state.loaded && tmp2.original && tmp2.original.state && tmp2.original.state.undetermined && tmp2.original.state.undetermined === true) {
23096 p.push(tmp2.id);
23097 p = p.concat(tmp2.parents);
23098 }
23099 }
23100 }
23101 });
23102 p = $.vakata.array_unique(p);
23103 p = $.vakata.array_remove_item(p,'#');
23104
23105 this.element.find('.jstree-undetermined').removeClass('jstree-undetermined');
23106 for(i = 0, j = p.length; i < j; i++) {
23107 if(!m[p[i]].state[ t ? 'selected' : 'checked' ]) {
23108 s = this.get_node(p[i], true);
23109 if(s && s.length) {
23110 s.children('.jstree-anchor').children('.jstree-checkbox').addClass('jstree-undetermined');
23111 }
23112 }
23113 }
23114 };
23115 this.redraw_node = function(obj, deep, is_callback, force_render) {
23116 obj = parent.redraw_node.apply(this, arguments);
23117 if(obj) {
23118 var i, j, tmp = null;
23119 for(i = 0, j = obj.childNodes.length; i < j; i++) {
23120 if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) {
23121 tmp = obj.childNodes[i];
23122 break;
23123 }
23124 }
23125 if(tmp) {
23126 if(!this.settings.checkbox.tie_selection && this._model.data[obj.id].state.checked) { tmp.className += ' jstree-checked'; }
23127 tmp.insertBefore(_i.cloneNode(false), tmp.childNodes[0]);
23128 }
23129 }
23130 if(!is_callback && this.settings.checkbox.cascade.indexOf('undetermined') !== -1) {
23131 if(this._data.checkbox.uto) { clearTimeout(this._data.checkbox.uto); }
23132 this._data.checkbox.uto = setTimeout($.proxy(this._undetermined, this), 50);
23133 }
23134 return obj;
23135 };
23136 /**
23137 * show the node checkbox icons
23138 * @name show_checkboxes()
23139 * @plugin checkbox
23140 */
23141 this.show_checkboxes = function () { this._data.core.themes.checkboxes = true; this.get_container_ul().removeClass("jstree-no-checkboxes"); };
23142 /**
23143 * hide the node checkbox icons
23144 * @name hide_checkboxes()
23145 * @plugin checkbox
23146 */
23147 this.hide_checkboxes = function () { this._data.core.themes.checkboxes = false; this.get_container_ul().addClass("jstree-no-checkboxes"); };
23148 /**
23149 * toggle the node icons
23150 * @name toggle_checkboxes()
23151 * @plugin checkbox
23152 */
23153 this.toggle_checkboxes = function () { if(this._data.core.themes.checkboxes) { this.hide_checkboxes(); } else { this.show_checkboxes(); } };
23154 /**
23155 * checks if a node is in an undetermined state
23156 * @name is_undetermined(obj)
23157 * @param {mixed} obj
23158 * @return {Boolean}
23159 */
23160 this.is_undetermined = function (obj) {
23161 obj = this.get_node(obj);
23162 var s = this.settings.checkbox.cascade, i, j, t = this.settings.checkbox.tie_selection, d = this._data[ t ? 'core' : 'checkbox' ].selected, m = this._model.data;
23163 if(!obj || obj.state[ t ? 'selected' : 'checked' ] === true || s.indexOf('undetermined') === -1 || (s.indexOf('down') === -1 && s.indexOf('up') === -1)) {
23164 return false;
23165 }
23166 if(!obj.state.loaded && obj.original.state.undetermined === true) {
23167 return true;
23168 }
23169 for(i = 0, j = obj.children_d.length; i < j; i++) {
23170 if($.inArray(obj.children_d[i], d) !== -1 || (!m[obj.children_d[i]].state.loaded && m[obj.children_d[i]].original.state.undetermined)) {
23171 return true;
23172 }
23173 }
23174 return false;
23175 };
23176
23177 this.activate_node = function (obj, e) {
23178 if(this.settings.checkbox.tie_selection && (this.settings.checkbox.whole_node || $(e.target).hasClass('jstree-checkbox'))) {
23179 e.ctrlKey = true;
23180 }
23181 if(this.settings.checkbox.tie_selection || (!this.settings.checkbox.whole_node && !$(e.target).hasClass('jstree-checkbox'))) {
23182 return parent.activate_node.call(this, obj, e);
23183 }
23184 if(this.is_disabled(obj)) {
23185 return false;
23186 }
23187 if(this.is_checked(obj)) {
23188 this.uncheck_node(obj, e);
23189 }
23190 else {
23191 this.check_node(obj, e);
23192 }
23193 this.trigger('activate_node', { 'node' : this.get_node(obj) });
23194 };
23195
23196 /**
23197 * check a node (only if tie_selection in checkbox settings is false, otherwise select_node will be called internally)
23198 * @name check_node(obj)
23199 * @param {mixed} obj an array can be used to check multiple nodes
23200 * @trigger check_node.jstree
23201 * @plugin checkbox
23202 */
23203 this.check_node = function (obj, e) {
23204 if(this.settings.checkbox.tie_selection) { return this.select_node(obj, false, true, e); }
23205 var dom, t1, t2, th;
23206 if($.isArray(obj)) {
23207 obj = obj.slice();
23208 for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
23209 this.check_node(obj[t1], e);
23210 }
23211 return true;
23212 }
23213 obj = this.get_node(obj);
23214 if(!obj || obj.id === '#') {
23215 return false;
23216 }
23217 dom = this.get_node(obj, true);
23218 if(!obj.state.checked) {
23219 obj.state.checked = true;
23220 this._data.checkbox.selected.push(obj.id);
23221 if(dom && dom.length) {
23222 dom.children('.jstree-anchor').addClass('jstree-checked');
23223 }
23224 /**
23225 * triggered when an node is checked (only if tie_selection in checkbox settings is false)
23226 * @event
23227 * @name check_node.jstree
23228 * @param {Object} node
23229 * @param {Array} selected the current selection
23230 * @param {Object} event the event (if any) that triggered this check_node
23231 * @plugin checkbox
23232 */
23233 this.trigger('check_node', { 'node' : obj, 'selected' : this._data.checkbox.selected, 'event' : e });
23234 }
23235 };
23236 /**
23237 * uncheck a node (only if tie_selection in checkbox settings is false, otherwise deselect_node will be called internally)
23238 * @name deselect_node(obj)
23239 * @param {mixed} obj an array can be used to deselect multiple nodes
23240 * @trigger uncheck_node.jstree
23241 * @plugin checkbox
23242 */
23243 this.uncheck_node = function (obj, e) {
23244 if(this.settings.checkbox.tie_selection) { return this.deselect_node(obj, false, e); }
23245 var t1, t2, dom;
23246 if($.isArray(obj)) {
23247 obj = obj.slice();
23248 for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
23249 this.uncheck_node(obj[t1], e);
23250 }
23251 return true;
23252 }
23253 obj = this.get_node(obj);
23254 if(!obj || obj.id === '#') {
23255 return false;
23256 }
23257 dom = this.get_node(obj, true);
23258 if(obj.state.checked) {
23259 obj.state.checked = false;
23260 this._data.checkbox.selected = $.vakata.array_remove_item(this._data.checkbox.selected, obj.id);
23261 if(dom.length) {
23262 dom.children('.jstree-anchor').removeClass('jstree-checked');
23263 }
23264 /**
23265 * triggered when an node is unchecked (only if tie_selection in checkbox settings is false)
23266 * @event
23267 * @name uncheck_node.jstree
23268 * @param {Object} node
23269 * @param {Array} selected the current selection
23270 * @param {Object} event the event (if any) that triggered this uncheck_node
23271 * @plugin checkbox
23272 */
23273 this.trigger('uncheck_node', { 'node' : obj, 'selected' : this._data.checkbox.selected, 'event' : e });
23274 }
23275 };
23276 /**
23277 * checks all nodes in the tree (only if tie_selection in checkbox settings is false, otherwise select_all will be called internally)
23278 * @name check_all()
23279 * @trigger check_all.jstree, changed.jstree
23280 * @plugin checkbox
23281 */
23282 this.check_all = function () {
23283 if(this.settings.checkbox.tie_selection) { return this.select_all(); }
23284 var tmp = this._data.checkbox.selected.concat([]), i, j;
23285 this._data.checkbox.selected = this._model.data['#'].children_d.concat();
23286 for(i = 0, j = this._data.checkbox.selected.length; i < j; i++) {
23287 if(this._model.data[this._data.checkbox.selected[i]]) {
23288 this._model.data[this._data.checkbox.selected[i]].state.checked = true;
23289 }
23290 }
23291 this.redraw(true);
23292 /**
23293 * triggered when all nodes are checked (only if tie_selection in checkbox settings is false)
23294 * @event
23295 * @name check_all.jstree
23296 * @param {Array} selected the current selection
23297 * @plugin checkbox
23298 */
23299 this.trigger('check_all', { 'selected' : this._data.checkbox.selected });
23300 };
23301 /**
23302 * uncheck all checked nodes (only if tie_selection in checkbox settings is false, otherwise deselect_all will be called internally)
23303 * @name uncheck_all()
23304 * @trigger uncheck_all.jstree
23305 * @plugin checkbox
23306 */
23307 this.uncheck_all = function () {
23308 if(this.settings.checkbox.tie_selection) { return this.deselect_all(); }
23309 var tmp = this._data.checkbox.selected.concat([]), i, j;
23310 for(i = 0, j = this._data.checkbox.selected.length; i < j; i++) {
23311 if(this._model.data[this._data.checkbox.selected[i]]) {
23312 this._model.data[this._data.checkbox.selected[i]].state.checked = false;
23313 }
23314 }
23315 this._data.checkbox.selected = [];
23316 this.element.find('.jstree-checked').removeClass('jstree-checked');
23317 /**
23318 * triggered when all nodes are unchecked (only if tie_selection in checkbox settings is false)
23319 * @event
23320 * @name uncheck_all.jstree
23321 * @param {Object} node the previous selection
23322 * @param {Array} selected the current selection
23323 * @plugin checkbox
23324 */
23325 this.trigger('uncheck_all', { 'selected' : this._data.checkbox.selected, 'node' : tmp });
23326 };
23327 /**
23328 * checks if a node is checked (if tie_selection is on in the settings this function will return the same as is_selected)
23329 * @name is_checked(obj)
23330 * @param {mixed} obj
23331 * @return {Boolean}
23332 * @plugin checkbox
23333 */
23334 this.is_checked = function (obj) {
23335 if(this.settings.checkbox.tie_selection) { return this.is_selected(obj); }
23336 obj = this.get_node(obj);
23337 if(!obj || obj.id === '#') { return false; }
23338 return obj.state.checked;
23339 };
23340 /**
23341 * get an array of all checked nodes (if tie_selection is on in the settings this function will return the same as get_selected)
23342 * @name get_checked([full])
23343 * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned
23344 * @return {Array}
23345 * @plugin checkbox
23346 */
23347 this.get_checked = function (full) {
23348 if(this.settings.checkbox.tie_selection) { return this.get_selected(full); }
23349 return full ? $.map(this._data.checkbox.selected, $.proxy(function (i) { return this.get_node(i); }, this)) : this._data.checkbox.selected;
23350 };
23351 /**
23352 * get an array of all top level checked nodes (ignoring children of checked nodes) (if tie_selection is on in the settings this function will return the same as get_top_selected)
23353 * @name get_top_checked([full])
23354 * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned
23355 * @return {Array}
23356 * @plugin checkbox
23357 */
23358 this.get_top_checked = function (full) {
23359 if(this.settings.checkbox.tie_selection) { return this.get_top_selected(full); }
23360 var tmp = this.get_checked(true),
23361 obj = {}, i, j, k, l;
23362 for(i = 0, j = tmp.length; i < j; i++) {
23363 obj[tmp[i].id] = tmp[i];
23364 }
23365 for(i = 0, j = tmp.length; i < j; i++) {
23366 for(k = 0, l = tmp[i].children_d.length; k < l; k++) {
23367 if(obj[tmp[i].children_d[k]]) {
23368 delete obj[tmp[i].children_d[k]];
23369 }
23370 }
23371 }
23372 tmp = [];
23373 for(i in obj) {
23374 if(obj.hasOwnProperty(i)) {
23375 tmp.push(i);
23376 }
23377 }
23378 return full ? $.map(tmp, $.proxy(function (i) { return this.get_node(i); }, this)) : tmp;
23379 };
23380 /**
23381 * get an array of all bottom level checked nodes (ignoring selected parents) (if tie_selection is on in the settings this function will return the same as get_bottom_selected)
23382 * @name get_bottom_checked([full])
23383 * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned
23384 * @return {Array}
23385 * @plugin checkbox
23386 */
23387 this.get_bottom_checked = function (full) {
23388 if(this.settings.checkbox.tie_selection) { return this.get_bottom_selected(full); }
23389 var tmp = this.get_checked(true),
23390 obj = [], i, j;
23391 for(i = 0, j = tmp.length; i < j; i++) {
23392 if(!tmp[i].children.length) {
23393 obj.push(tmp[i].id);
23394 }
23395 }
23396 return full ? $.map(obj, $.proxy(function (i) { return this.get_node(i); }, this)) : obj;
23397 };
23398 this.load_node = function (obj, callback) {
23399 var k, l, i, j, c, tmp;
23400 if(!$.isArray(obj) && !this.settings.checkbox.tie_selection) {
23401 tmp = this.get_node(obj);
23402 if(tmp && tmp.state.loaded) {
23403 for(k = 0, l = tmp.children_d.length; k < l; k++) {
23404 if(this._model.data[tmp.children_d[k]].state.checked) {
23405 c = true;
23406 this._data.checkbox.selected = $.vakata.array_remove_item(this._data.checkbox.selected, tmp.children_d[k]);
23407 }
23408 }
23409 }
23410 }
23411 return parent.load_node.apply(this, arguments);
23412 };
23413 this.get_state = function () {
23414 var state = parent.get_state.apply(this, arguments);
23415 if(this.settings.checkbox.tie_selection) { return state; }
23416 state.checkbox = this._data.checkbox.selected.slice();
23417 return state;
23418 };
23419 this.set_state = function (state, callback) {
23420 var res = parent.set_state.apply(this, arguments);
23421 if(res && state.checkbox) {
23422 if(!this.settings.checkbox.tie_selection) {
23423 this.uncheck_all();
23424 var _this = this;
23425 $.each(state.checkbox, function (i, v) {
23426 _this.check_node(v);
23427 });
23428 }
23429 delete state.checkbox;
23430 return false;
23431 }
23432 return res;
23433 };
23434 };
23435
23436 // include the checkbox plugin by default
23437 // $.jstree.defaults.plugins.push("checkbox");
23438
23439 /**
23440 * ### Contextmenu plugin
23441 *
23442 * Shows a context menu when a node is right-clicked.
23443 */
23444
23445 var cto = null, ex, ey;
23446
23447 /**
23448 * stores all defaults for the contextmenu plugin
23449 * @name $.jstree.defaults.contextmenu
23450 * @plugin contextmenu
23451 */
23452 $.jstree.defaults.contextmenu = {
23453 /**
23454 * a boolean indicating if the node should be selected when the context menu is invoked on it. Defaults to `true`.
23455 * @name $.jstree.defaults.contextmenu.select_node
23456 * @plugin contextmenu
23457 */
23458 select_node : true,
23459 /**
23460 * a boolean indicating if the menu should be shown aligned with the node. Defaults to `true`, otherwise the mouse coordinates are used.
23461 * @name $.jstree.defaults.contextmenu.show_at_node
23462 * @plugin contextmenu
23463 */
23464 show_at_node : true,
23465 /**
23466 * an object of actions, or a function that accepts a node and a callback function and calls the callback function with an object of actions available for that node (you can also return the items too).
23467 *
23468 * Each action consists of a key (a unique name) and a value which is an object with the following properties (only label and action are required):
23469 *
23470 * * `separator_before` - a boolean indicating if there should be a separator before this item
23471 * * `separator_after` - a boolean indicating if there should be a separator after this item
23472 * * `_disabled` - a boolean indicating if this action should be disabled
23473 * * `label` - a string - the name of the action (could be a function returning a string)
23474 * * `action` - a function to be executed if this item is chosen
23475 * * `icon` - a string, can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class
23476 * * `shortcut` - keyCode which will trigger the action if the menu is open (for example `113` for rename, which equals F2)
23477 * * `shortcut_label` - shortcut label (like for example `F2` for rename)
23478 *
23479 * @name $.jstree.defaults.contextmenu.items
23480 * @plugin contextmenu
23481 */
23482 items : function (o, cb) { // Could be an object directly
23483 return {
23484 "create" : {
23485 "separator_before" : false,
23486 "separator_after" : true,
23487 "_disabled" : false, //(this.check("create_node", data.reference, {}, "last")),
23488 "label" : "Create",
23489 "action" : function (data) {
23490 var inst = $.jstree.reference(data.reference),
23491 obj = inst.get_node(data.reference);
23492 inst.create_node(obj, {}, "last", function (new_node) {
23493 setTimeout(function () { inst.edit(new_node); },0);
23494 });
23495 }
23496 },
23497 "rename" : {
23498 "separator_before" : false,
23499 "separator_after" : false,
23500 "_disabled" : false, //(this.check("rename_node", data.reference, this.get_parent(data.reference), "")),
23501 "label" : "Rename",
23502 /*
23503 "shortcut" : 113,
23504 "shortcut_label" : 'F2',
23505 "icon" : "glyphicon glyphicon-leaf",
23506 */
23507 "action" : function (data) {
23508 var inst = $.jstree.reference(data.reference),
23509 obj = inst.get_node(data.reference);
23510 inst.edit(obj);
23511 }
23512 },
23513 "remove" : {
23514 "separator_before" : false,
23515 "icon" : false,
23516 "separator_after" : false,
23517 "_disabled" : false, //(this.check("delete_node", data.reference, this.get_parent(data.reference), "")),
23518 "label" : "Delete",
23519 "action" : function (data) {
23520 var inst = $.jstree.reference(data.reference),
23521 obj = inst.get_node(data.reference);
23522 if(inst.is_selected(obj)) {
23523 inst.delete_node(inst.get_selected());
23524 }
23525 else {
23526 inst.delete_node(obj);
23527 }
23528 }
23529 },
23530 "ccp" : {
23531 "separator_before" : true,
23532 "icon" : false,
23533 "separator_after" : false,
23534 "label" : "Edit",
23535 "action" : false,
23536 "submenu" : {
23537 "cut" : {
23538 "separator_before" : false,
23539 "separator_after" : false,
23540 "label" : "Cut",
23541 "action" : function (data) {
23542 var inst = $.jstree.reference(data.reference),
23543 obj = inst.get_node(data.reference);
23544 if(inst.is_selected(obj)) {
23545 inst.cut(inst.get_selected());
23546 }
23547 else {
23548 inst.cut(obj);
23549 }
23550 }
23551 },
23552 "copy" : {
23553 "separator_before" : false,
23554 "icon" : false,
23555 "separator_after" : false,
23556 "label" : "Copy",
23557 "action" : function (data) {
23558 var inst = $.jstree.reference(data.reference),
23559 obj = inst.get_node(data.reference);
23560 if(inst.is_selected(obj)) {
23561 inst.copy(inst.get_selected());
23562 }
23563 else {
23564 inst.copy(obj);
23565 }
23566 }
23567 },
23568 "paste" : {
23569 "separator_before" : false,
23570 "icon" : false,
23571 "_disabled" : function (data) {
23572 return !$.jstree.reference(data.reference).can_paste();
23573 },
23574 "separator_after" : false,
23575 "label" : "Paste",
23576 "action" : function (data) {
23577 var inst = $.jstree.reference(data.reference),
23578 obj = inst.get_node(data.reference);
23579 inst.paste(obj);
23580 }
23581 }
23582 }
23583 }
23584 };
23585 }
23586 };
23587
23588 $.jstree.plugins.contextmenu = function (options, parent) {
23589 this.bind = function () {
23590 parent.bind.call(this);
23591
23592 var last_ts = 0;
23593 this.element
23594 .on("contextmenu.jstree", ".jstree-anchor", $.proxy(function (e, data) {
23595 e.preventDefault();
23596 last_ts = e.ctrlKey ? +new Date() : 0;
23597 if(data || cto) {
23598 last_ts = (+new Date()) + 10000;
23599 }
23600 if(cto) {
23601 clearTimeout(cto);
23602 }
23603 if(!this.is_loading(e.currentTarget)) {
23604 this.show_contextmenu(e.currentTarget, e.pageX, e.pageY, e);
23605 }
23606 }, this))
23607 .on("click.jstree", ".jstree-anchor", $.proxy(function (e) {
23608 if(this._data.contextmenu.visible && (!last_ts || (+new Date()) - last_ts > 250)) { // work around safari & macOS ctrl+click
23609 $.vakata.context.hide();
23610 }
23611 last_ts = 0;
23612 }, this))
23613 .on("touchstart.jstree", ".jstree-anchor", function (e) {
23614 if(!e.originalEvent || !e.originalEvent.changedTouches || !e.originalEvent.changedTouches[0]) {
23615 return;
23616 }
23617 ex = e.pageX;
23618 ey = e.pageY;
23619 cto = setTimeout(function () {
23620 $(e.currentTarget).trigger('contextmenu', true);
23621 }, 750);
23622 });
23623 /*
23624 if(!('oncontextmenu' in document.body) && ('ontouchstart' in document.body)) {
23625 var el = null, tm = null;
23626 this.element
23627 .on("touchstart", ".jstree-anchor", function (e) {
23628 el = e.currentTarget;
23629 tm = +new Date();
23630 $(document).one("touchend", function (e) {
23631 e.target = document.elementFromPoint(e.originalEvent.targetTouches[0].pageX - window.pageXOffset, e.originalEvent.targetTouches[0].pageY - window.pageYOffset);
23632 e.currentTarget = e.target;
23633 tm = ((+(new Date())) - tm);
23634 if(e.target === el && tm > 600 && tm < 1000) {
23635 e.preventDefault();
23636 $(el).trigger('contextmenu', e);
23637 }
23638 el = null;
23639 tm = null;
23640 });
23641 });
23642 }
23643 */
23644 $(document).on("context_hide.vakata.jstree", $.proxy(function () { this._data.contextmenu.visible = false; }, this));
23645 };
23646 this.teardown = function () {
23647 if(this._data.contextmenu.visible) {
23648 $.vakata.context.hide();
23649 }
23650 parent.teardown.call(this);
23651 };
23652
23653 /**
23654 * prepare and show the context menu for a node
23655 * @name show_contextmenu(obj [, x, y])
23656 * @param {mixed} obj the node
23657 * @param {Number} x the x-coordinate relative to the document to show the menu at
23658 * @param {Number} y the y-coordinate relative to the document to show the menu at
23659 * @param {Object} e the event if available that triggered the contextmenu
23660 * @plugin contextmenu
23661 * @trigger show_contextmenu.jstree
23662 */
23663 this.show_contextmenu = function (obj, x, y, e) {
23664 obj = this.get_node(obj);
23665 if(!obj || obj.id === '#') { return false; }
23666 var s = this.settings.contextmenu,
23667 d = this.get_node(obj, true),
23668 a = d.children(".jstree-anchor"),
23669 o = false,
23670 i = false;
23671 if(s.show_at_node || x === undefined || y === undefined) {
23672 o = a.offset();
23673 x = o.left;
23674 y = o.top + this._data.core.li_height;
23675 }
23676 if(this.settings.contextmenu.select_node && !this.is_selected(obj)) {
23677 this.activate_node(obj, e);
23678 }
23679
23680 i = s.items;
23681 if($.isFunction(i)) {
23682 i = i.call(this, obj, $.proxy(function (i) {
23683 this._show_contextmenu(obj, x, y, i);
23684 }, this));
23685 }
23686 if($.isPlainObject(i)) {
23687 this._show_contextmenu(obj, x, y, i);
23688 }
23689 };
23690 /**
23691 * show the prepared context menu for a node
23692 * @name _show_contextmenu(obj, x, y, i)
23693 * @param {mixed} obj the node
23694 * @param {Number} x the x-coordinate relative to the document to show the menu at
23695 * @param {Number} y the y-coordinate relative to the document to show the menu at
23696 * @param {Number} i the object of items to show
23697 * @plugin contextmenu
23698 * @trigger show_contextmenu.jstree
23699 * @private
23700 */
23701 this._show_contextmenu = function (obj, x, y, i) {
23702 var d = this.get_node(obj, true),
23703 a = d.children(".jstree-anchor");
23704 $(document).one("context_show.vakata.jstree", $.proxy(function (e, data) {
23705 var cls = 'jstree-contextmenu jstree-' + this.get_theme() + '-contextmenu';
23706 $(data.element).addClass(cls);
23707 }, this));
23708 this._data.contextmenu.visible = true;
23709 $.vakata.context.show(a, { 'x' : x, 'y' : y }, i);
23710 /**
23711 * triggered when the contextmenu is shown for a node
23712 * @event
23713 * @name show_contextmenu.jstree
23714 * @param {Object} node the node
23715 * @param {Number} x the x-coordinate of the menu relative to the document
23716 * @param {Number} y the y-coordinate of the menu relative to the document
23717 * @plugin contextmenu
23718 */
23719 this.trigger('show_contextmenu', { "node" : obj, "x" : x, "y" : y });
23720 };
23721 };
23722
23723 $(function () {
23724 $(document)
23725 .on('touchmove.vakata.jstree', function (e) {
23726 if(cto && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0] && (Math.abs(ex - e.pageX) > 50 || Math.abs(ey - e.pageY) > 50)) {
23727 clearTimeout(cto);
23728 }
23729 })
23730 .on('touchend.vakata.jstree', function (e) {
23731 if(cto) {
23732 clearTimeout(cto);
23733 }
23734 });
23735 });
23736
23737 // contextmenu helper
23738 (function ($) {
23739 var right_to_left = false,
23740 vakata_context = {
23741 element : false,
23742 reference : false,
23743 position_x : 0,
23744 position_y : 0,
23745 items : [],
23746 html : "",
23747 is_visible : false
23748 };
23749
23750 $.vakata.context = {
23751 settings : {
23752 hide_onmouseleave : 0,
23753 icons : true
23754 },
23755 _trigger : function (event_name) {
23756 $(document).triggerHandler("context_" + event_name + ".vakata", {
23757 "reference" : vakata_context.reference,
23758 "element" : vakata_context.element,
23759 "position" : {
23760 "x" : vakata_context.position_x,
23761 "y" : vakata_context.position_y
23762 }
23763 });
23764 },
23765 _execute : function (i) {
23766 i = vakata_context.items[i];
23767 return i && (!i._disabled || ($.isFunction(i._disabled) && !i._disabled({ "item" : i, "reference" : vakata_context.reference, "element" : vakata_context.element }))) && i.action ? i.action.call(null, {
23768 "item" : i,
23769 "reference" : vakata_context.reference,
23770 "element" : vakata_context.element,
23771 "position" : {
23772 "x" : vakata_context.position_x,
23773 "y" : vakata_context.position_y
23774 }
23775 }) : false;
23776 },
23777 _parse : function (o, is_callback) {
23778 if(!o) { return false; }
23779 if(!is_callback) {
23780 vakata_context.html = "";
23781 vakata_context.items = [];
23782 }
23783 var str = "",
23784 sep = false,
23785 tmp;
23786
23787 if(is_callback) { str += "<"+"ul>"; }
23788 $.each(o, function (i, val) {
23789 if(!val) { return true; }
23790 vakata_context.items.push(val);
23791 if(!sep && val.separator_before) {
23792 str += "<"+"li class='vakata-context-separator'><"+"a href='#' " + ($.vakata.context.settings.icons ? '' : 'style="margin-left:0px;"') + ">&#160;<"+"/a><"+"/li>";
23793 }
23794 sep = false;
23795 str += "<"+"li class='" + (val._class || "") + (val._disabled === true || ($.isFunction(val._disabled) && val._disabled({ "item" : val, "reference" : vakata_context.reference, "element" : vakata_context.element })) ? " vakata-contextmenu-disabled " : "") + "' "+(val.shortcut?" data-shortcut='"+val.shortcut+"' ":'')+">";
23796 str += "<"+"a href='#' rel='" + (vakata_context.items.length - 1) + "'>";
23797 if($.vakata.context.settings.icons) {
23798 str += "<"+"i ";
23799 if(val.icon) {
23800 if(val.icon.indexOf("/") !== -1 || val.icon.indexOf(".") !== -1) { str += " style='background:url(\"" + val.icon + "\") center center no-repeat' "; }
23801 else { str += " class='" + val.icon + "' "; }
23802 }
23803 str += "><"+"/i><"+"span class='vakata-contextmenu-sep'>&#160;<"+"/span>";
23804 }
23805 str += ($.isFunction(val.label) ? val.label({ "item" : i, "reference" : vakata_context.reference, "element" : vakata_context.element }) : val.label) + (val.shortcut?' <span class="vakata-contextmenu-shortcut vakata-contextmenu-shortcut-'+val.shortcut+'">'+ (val.shortcut_label || '') +'</span>':'') + "<"+"/a>";
23806 if(val.submenu) {
23807 tmp = $.vakata.context._parse(val.submenu, true);
23808 if(tmp) { str += tmp; }
23809 }
23810 str += "<"+"/li>";
23811 if(val.separator_after) {
23812 str += "<"+"li class='vakata-context-separator'><"+"a href='#' " + ($.vakata.context.settings.icons ? '' : 'style="margin-left:0px;"') + ">&#160;<"+"/a><"+"/li>";
23813 sep = true;
23814 }
23815 });
23816 str = str.replace(/<li class\='vakata-context-separator'\><\/li\>$/,"");
23817 if(is_callback) { str += "</ul>"; }
23818 /**
23819 * triggered on the document when the contextmenu is parsed (HTML is built)
23820 * @event
23821 * @plugin contextmenu
23822 * @name context_parse.vakata
23823 * @param {jQuery} reference the element that was right clicked
23824 * @param {jQuery} element the DOM element of the menu itself
23825 * @param {Object} position the x & y coordinates of the menu
23826 */
23827 if(!is_callback) { vakata_context.html = str; $.vakata.context._trigger("parse"); }
23828 return str.length > 10 ? str : false;
23829 },
23830 _show_submenu : function (o) {
23831 o = $(o);
23832 if(!o.length || !o.children("ul").length) { return; }
23833 var e = o.children("ul"),
23834 x = o.offset().left + o.outerWidth(),
23835 y = o.offset().top,
23836 w = e.width(),
23837 h = e.height(),
23838 dw = $(window).width() + $(window).scrollLeft(),
23839 dh = $(window).height() + $(window).scrollTop();
23840 // може да се спести е една проверка - дали няма някой от класовете вече нагоре
23841 if(right_to_left) {
23842 o[x - (w + 10 + o.outerWidth()) < 0 ? "addClass" : "removeClass"]("vakata-context-left");
23843 }
23844 else {
23845 o[x + w + 10 > dw ? "addClass" : "removeClass"]("vakata-context-right");
23846 }
23847 if(y + h + 10 > dh) {
23848 e.css("bottom","-1px");
23849 }
23850 e.show();
23851 },
23852 show : function (reference, position, data) {
23853 var o, e, x, y, w, h, dw, dh, cond = true;
23854 if(vakata_context.element && vakata_context.element.length) {
23855 vakata_context.element.width('');
23856 }
23857 switch(cond) {
23858 case (!position && !reference):
23859 return false;
23860 case (!!position && !!reference):
23861 vakata_context.reference = reference;
23862 vakata_context.position_x = position.x;
23863 vakata_context.position_y = position.y;
23864 break;
23865 case (!position && !!reference):
23866 vakata_context.reference = reference;
23867 o = reference.offset();
23868 vakata_context.position_x = o.left + reference.outerHeight();
23869 vakata_context.position_y = o.top;
23870 break;
23871 case (!!position && !reference):
23872 vakata_context.position_x = position.x;
23873 vakata_context.position_y = position.y;
23874 break;
23875 }
23876 if(!!reference && !data && $(reference).data('vakata_contextmenu')) {
23877 data = $(reference).data('vakata_contextmenu');
23878 }
23879 if($.vakata.context._parse(data)) {
23880 vakata_context.element.html(vakata_context.html);
23881 }
23882 if(vakata_context.items.length) {
23883 vakata_context.element.appendTo("body");
23884 e = vakata_context.element;
23885 x = vakata_context.position_x;
23886 y = vakata_context.position_y;
23887 w = e.width();
23888 h = e.height();
23889 dw = $(window).width() + $(window).scrollLeft();
23890 dh = $(window).height() + $(window).scrollTop();
23891 if(right_to_left) {
23892 x -= (e.outerWidth() - $(reference).outerWidth());
23893 if(x < $(window).scrollLeft() + 20) {
23894 x = $(window).scrollLeft() + 20;
23895 }
23896 }
23897 if(x + w + 20 > dw) {
23898 x = dw - (w + 20);
23899 }
23900 if(y + h + 20 > dh) {
23901 y = dh - (h + 20);
23902 }
23903
23904 vakata_context.element
23905 .css({ "left" : x, "top" : y })
23906 .show()
23907 .find('a').first().focus().parent().addClass("vakata-context-hover");
23908 vakata_context.is_visible = true;
23909 /**
23910 * triggered on the document when the contextmenu is shown
23911 * @event
23912 * @plugin contextmenu
23913 * @name context_show.vakata
23914 * @param {jQuery} reference the element that was right clicked
23915 * @param {jQuery} element the DOM element of the menu itself
23916 * @param {Object} position the x & y coordinates of the menu
23917 */
23918 $.vakata.context._trigger("show");
23919 }
23920 },
23921 hide : function () {
23922 if(vakata_context.is_visible) {
23923 vakata_context.element.hide().find("ul").hide().end().find(':focus').blur().end().detach();
23924 vakata_context.is_visible = false;
23925 /**
23926 * triggered on the document when the contextmenu is hidden
23927 * @event
23928 * @plugin contextmenu
23929 * @name context_hide.vakata
23930 * @param {jQuery} reference the element that was right clicked
23931 * @param {jQuery} element the DOM element of the menu itself
23932 * @param {Object} position the x & y coordinates of the menu
23933 */
23934 $.vakata.context._trigger("hide");
23935 }
23936 }
23937 };
23938 $(function () {
23939 right_to_left = $("body").css("direction") === "rtl";
23940 var to = false;
23941
23942 vakata_context.element = $("<ul class='vakata-context'></ul>");
23943 vakata_context.element
23944 .on("mouseenter", "li", function (e) {
23945 e.stopImmediatePropagation();
23946
23947 if($.contains(this, e.relatedTarget)) {
23948 // премахнато заради delegate mouseleave по-долу
23949 // $(this).find(".vakata-context-hover").removeClass("vakata-context-hover");
23950 return;
23951 }
23952
23953 if(to) { clearTimeout(to); }
23954 vakata_context.element.find(".vakata-context-hover").removeClass("vakata-context-hover").end();
23955
23956 $(this)
23957 .siblings().find("ul").hide().end().end()
23958 .parentsUntil(".vakata-context", "li").addBack().addClass("vakata-context-hover");
23959 $.vakata.context._show_submenu(this);
23960 })
23961 // тестово - дали не натоварва?
23962 .on("mouseleave", "li", function (e) {
23963 if($.contains(this, e.relatedTarget)) { return; }
23964 $(this).find(".vakata-context-hover").addBack().removeClass("vakata-context-hover");
23965 })
23966 .on("mouseleave", function (e) {
23967 $(this).find(".vakata-context-hover").removeClass("vakata-context-hover");
23968 if($.vakata.context.settings.hide_onmouseleave) {
23969 to = setTimeout(
23970 (function (t) {
23971 return function () { $.vakata.context.hide(); };
23972 }(this)), $.vakata.context.settings.hide_onmouseleave);
23973 }
23974 })
23975 .on("click", "a", function (e) {
23976 e.preventDefault();
23977 //})
23978 //.on("mouseup", "a", function (e) {
23979 if(!$(this).blur().parent().hasClass("vakata-context-disabled") && $.vakata.context._execute($(this).attr("rel")) !== false) {
23980 $.vakata.context.hide();
23981 }
23982 })
23983 .on('keydown', 'a', function (e) {
23984 var o = null;
23985 switch(e.which) {
23986 case 13:
23987 case 32:
23988 e.type = "mouseup";
23989 e.preventDefault();
23990 $(e.currentTarget).trigger(e);
23991 break;
23992 case 37:
23993 if(vakata_context.is_visible) {
23994 vakata_context.element.find(".vakata-context-hover").last().closest("li").first().find("ul").hide().find(".vakata-context-hover").removeClass("vakata-context-hover").end().end().children('a').focus();
23995 e.stopImmediatePropagation();
23996 e.preventDefault();
23997 }
23998 break;
23999 case 38:
24000 if(vakata_context.is_visible) {
24001 o = vakata_context.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").prevAll("li:not(.vakata-context-separator)").first();
24002 if(!o.length) { o = vakata_context.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").last(); }
24003 o.addClass("vakata-context-hover").children('a').focus();
24004 e.stopImmediatePropagation();
24005 e.preventDefault();
24006 }
24007 break;
24008 case 39:
24009 if(vakata_context.is_visible) {
24010 vakata_context.element.find(".vakata-context-hover").last().children("ul").show().children("li:not(.vakata-context-separator)").removeClass("vakata-context-hover").first().addClass("vakata-context-hover").children('a').focus();
24011 e.stopImmediatePropagation();
24012 e.preventDefault();
24013 }
24014 break;
24015 case 40:
24016 if(vakata_context.is_visible) {
24017 o = vakata_context.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").nextAll("li:not(.vakata-context-separator)").first();
24018 if(!o.length) { o = vakata_context.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").first(); }
24019 o.addClass("vakata-context-hover").children('a').focus();
24020 e.stopImmediatePropagation();
24021 e.preventDefault();
24022 }
24023 break;
24024 case 27:
24025 $.vakata.context.hide();
24026 e.preventDefault();
24027 break;
24028 default:
24029 //console.log(e.which);
24030 break;
24031 }
24032 })
24033 .on('keydown', function (e) {
24034 e.preventDefault();
24035 var a = vakata_context.element.find('.vakata-contextmenu-shortcut-' + e.which).parent();
24036 if(a.parent().not('.vakata-context-disabled')) {
24037 a.click();
24038 }
24039 });
24040
24041 $(document)
24042 .on("mousedown.vakata.jstree", function (e) {
24043 if(vakata_context.is_visible && !$.contains(vakata_context.element[0], e.target)) {
24044 $.vakata.context.hide();
24045 }
24046 })
24047 .on("context_show.vakata.jstree", function (e, data) {
24048 vakata_context.element.find("li:has(ul)").children("a").addClass("vakata-context-parent");
24049 if(right_to_left) {
24050 vakata_context.element.addClass("vakata-context-rtl").css("direction", "rtl");
24051 }
24052 // also apply a RTL class?
24053 vakata_context.element.find("ul").hide().end();
24054 });
24055 });
24056 }($));
24057 // $.jstree.defaults.plugins.push("contextmenu");
24058
24059 /**
24060 * ### Drag'n'drop plugin
24061 *
24062 * Enables dragging and dropping of nodes in the tree, resulting in a move or copy operations.
24063 */
24064
24065 /**
24066 * stores all defaults for the drag'n'drop plugin
24067 * @name $.jstree.defaults.dnd
24068 * @plugin dnd
24069 */
24070 $.jstree.defaults.dnd = {
24071 /**
24072 * a boolean indicating if a copy should be possible while dragging (by pressint the meta key or Ctrl). Defaults to `true`.
24073 * @name $.jstree.defaults.dnd.copy
24074 * @plugin dnd
24075 */
24076 copy : true,
24077 /**
24078 * a number indicating how long a node should remain hovered while dragging to be opened. Defaults to `500`.
24079 * @name $.jstree.defaults.dnd.open_timeout
24080 * @plugin dnd
24081 */
24082 open_timeout : 500,
24083 /**
24084 * a function invoked each time a node is about to be dragged, invoked in the tree's scope and receives the nodes about to be dragged as an argument (array) - return `false` to prevent dragging
24085 * @name $.jstree.defaults.dnd.is_draggable
24086 * @plugin dnd
24087 */
24088 is_draggable : true,
24089 /**
24090 * a boolean indicating if checks should constantly be made while the user is dragging the node (as opposed to checking only on drop), default is `true`
24091 * @name $.jstree.defaults.dnd.check_while_dragging
24092 * @plugin dnd
24093 */
24094 check_while_dragging : true,
24095 /**
24096 * a boolean indicating if nodes from this tree should only be copied with dnd (as opposed to moved), default is `false`
24097 * @name $.jstree.defaults.dnd.always_copy
24098 * @plugin dnd
24099 */
24100 always_copy : false,
24101 /**
24102 * when dropping a node "inside", this setting indicates the position the node should go to - it can be an integer or a string: "first" (same as 0) or "last", default is `0`
24103 * @name $.jstree.defaults.dnd.inside_pos
24104 * @plugin dnd
24105 */
24106 inside_pos : 0,
24107 /**
24108 * when starting the drag on a node that is selected this setting controls if all selected nodes are dragged or only the single node, default is `true`, which means all selected nodes are dragged when the drag is started on a selected node
24109 * @name $.jstree.defaults.dnd.drag_selection
24110 * @plugin dnd
24111 */
24112 drag_selection : true,
24113 /**
24114 * controls whether dnd works on touch devices. If left as boolean true dnd will work the same as in desktop browsers, which in some cases may impair scrolling. If set to boolean false dnd will not work on touch devices. There is a special third option - string "selected" which means only selected nodes can be dragged on touch devices.
24115 * @name $.jstree.defaults.dnd.touch
24116 * @plugin dnd
24117 */
24118 touch : true
24119 };
24120 // TODO: now check works by checking for each node individually, how about max_children, unique, etc?
24121 $.jstree.plugins.dnd = function (options, parent) {
24122 this.bind = function () {
24123 parent.bind.call(this);
24124
24125 this.element
24126 .on('mousedown.jstree touchstart.jstree', '.jstree-anchor', $.proxy(function (e) {
24127 if(e.type === "touchstart" && (!this.settings.dnd.touch || (this.settings.dnd.touch === 'selected' && !$(e.currentTarget).hasClass('jstree-clicked')))) {
24128 return true;
24129 }
24130 var obj = this.get_node(e.target),
24131 mlt = this.is_selected(obj) && this.settings.drag_selection ? this.get_selected().length : 1,
24132 txt = (mlt > 1 ? mlt + ' ' + this.get_string('nodes') : this.get_text(e.currentTarget));
24133 if(this.settings.core.force_text) {
24134 txt = $('<div />').text(txt).html();
24135 }
24136 if(obj && obj.id && obj.id !== "#" && (e.which === 1 || e.type === "touchstart") &&
24137 (this.settings.dnd.is_draggable === true || ($.isFunction(this.settings.dnd.is_draggable) && this.settings.dnd.is_draggable.call(this, (mlt > 1 ? this.get_selected(true) : [obj]))))
24138 ) {
24139 this.element.trigger('mousedown.jstree');
24140 return $.vakata.dnd.start(e, { 'jstree' : true, 'origin' : this, 'obj' : this.get_node(obj,true), 'nodes' : mlt > 1 ? this.get_selected() : [obj.id] }, '<div id="jstree-dnd" class="jstree-' + this.get_theme() + ' jstree-' + this.get_theme() + '-' + this.get_theme_variant() + ' ' + ( this.settings.core.themes.responsive ? ' jstree-dnd-responsive' : '' ) + '"><i class="jstree-icon jstree-er"></i>' + txt + '<ins class="jstree-copy" style="display:none;">+</ins></div>');
24141 }
24142 }, this));
24143 };
24144 };
24145
24146 $(function() {
24147 // bind only once for all instances
24148 var lastmv = false,
24149 laster = false,
24150 opento = false,
24151 marker = $('<div id="jstree-marker">&#160;</div>').hide(); //.appendTo('body');
24152
24153 $(document)
24154 .on('dnd_start.vakata.jstree', function (e, data) {
24155 lastmv = false;
24156 if(!data || !data.data || !data.data.jstree) { return; }
24157 marker.appendTo('body'); //.show();
24158 })
24159 .on('dnd_move.vakata.jstree', function (e, data) {
24160 if(opento) { clearTimeout(opento); }
24161 if(!data || !data.data || !data.data.jstree) { return; }
24162
24163 // if we are hovering the marker image do nothing (can happen on "inside" drags)
24164 if(data.event.target.id && data.event.target.id === 'jstree-marker') {
24165 return;
24166 }
24167
24168 var ins = $.jstree.reference(data.event.target),
24169 ref = false,
24170 off = false,
24171 rel = false,
24172 l, t, h, p, i, o, ok, t1, t2, op, ps, pr, ip, tm;
24173 // if we are over an instance
24174 if(ins && ins._data && ins._data.dnd) {
24175 marker.attr('class', 'jstree-' + ins.get_theme() + ( ins.settings.core.themes.responsive ? ' jstree-dnd-responsive' : '' ));
24176 data.helper
24177 .children().attr('class', 'jstree-' + ins.get_theme() + ' jstree-' + ins.get_theme() + '-' + ins.get_theme_variant() + ' ' + ( ins.settings.core.themes.responsive ? ' jstree-dnd-responsive' : '' ))
24178 .find('.jstree-copy').first()[ data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))) ? 'show' : 'hide' ]();
24179
24180
24181 // if are hovering the container itself add a new root node
24182 if( (data.event.target === ins.element[0] || data.event.target === ins.get_container_ul()[0]) && ins.get_container_ul().children().length === 0) {
24183 ok = true;
24184 for(t1 = 0, t2 = data.data.nodes.length; t1 < t2; t1++) {
24185 ok = ok && ins.check( (data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey)) ) ? "copy_node" : "move_node"), (data.data.origin && data.data.origin !== ins ? data.data.origin.get_node(data.data.nodes[t1]) : data.data.nodes[t1]), '#', 'last', { 'dnd' : true, 'ref' : ins.get_node('#'), 'pos' : 'i', 'is_multi' : (data.data.origin && data.data.origin !== ins), 'is_foreign' : (!data.data.origin) });
24186 if(!ok) { break; }
24187 }
24188 if(ok) {
24189 lastmv = { 'ins' : ins, 'par' : '#', 'pos' : 'last' };
24190 marker.hide();
24191 data.helper.find('.jstree-icon').first().removeClass('jstree-er').addClass('jstree-ok');
24192 return;
24193 }
24194 }
24195 else {
24196 // if we are hovering a tree node
24197 ref = $(data.event.target).closest('.jstree-anchor');
24198 if(ref && ref.length && ref.parent().is('.jstree-closed, .jstree-open, .jstree-leaf')) {
24199 off = ref.offset();
24200 rel = data.event.pageY - off.top;
24201 h = ref.height();
24202 if(rel < h / 3) {
24203 o = ['b', 'i', 'a'];
24204 }
24205 else if(rel > h - h / 3) {
24206 o = ['a', 'i', 'b'];
24207 }
24208 else {
24209 o = rel > h / 2 ? ['i', 'a', 'b'] : ['i', 'b', 'a'];
24210 }
24211 $.each(o, function (j, v) {
24212 switch(v) {
24213 case 'b':
24214 l = off.left - 6;
24215 t = off.top;
24216 p = ins.get_parent(ref);
24217 i = ref.parent().index();
24218 break;
24219 case 'i':
24220 ip = ins.settings.dnd.inside_pos;
24221 tm = ins.get_node(ref.parent());
24222 l = off.left - 2;
24223 t = off.top + h / 2 + 1;
24224 p = tm.id;
24225 i = ip === 'first' ? 0 : (ip === 'last' ? tm.children.length : Math.min(ip, tm.children.length));
24226 break;
24227 case 'a':
24228 l = off.left - 6;
24229 t = off.top + h;
24230 p = ins.get_parent(ref);
24231 i = ref.parent().index() + 1;
24232 break;
24233 }
24234 ok = true;
24235 for(t1 = 0, t2 = data.data.nodes.length; t1 < t2; t1++) {
24236 op = data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))) ? "copy_node" : "move_node";
24237 ps = i;
24238 if(op === "move_node" && v === 'a' && (data.data.origin && data.data.origin === ins) && p === ins.get_parent(data.data.nodes[t1])) {
24239 pr = ins.get_node(p);
24240 if(ps > $.inArray(data.data.nodes[t1], pr.children)) {
24241 ps -= 1;
24242 }
24243 }
24244 ok = ok && ( (ins && ins.settings && ins.settings.dnd && ins.settings.dnd.check_while_dragging === false) || ins.check(op, (data.data.origin && data.data.origin !== ins ? data.data.origin.get_node(data.data.nodes[t1]) : data.data.nodes[t1]), p, ps, { 'dnd' : true, 'ref' : ins.get_node(ref.parent()), 'pos' : v, 'is_multi' : (data.data.origin && data.data.origin !== ins), 'is_foreign' : (!data.data.origin) }) );
24245 if(!ok) {
24246 if(ins && ins.last_error) { laster = ins.last_error(); }
24247 break;
24248 }
24249 }
24250 if(v === 'i' && ref.parent().is('.jstree-closed') && ins.settings.dnd.open_timeout) {
24251 opento = setTimeout((function (x, z) { return function () { x.open_node(z); }; }(ins, ref)), ins.settings.dnd.open_timeout);
24252 }
24253 if(ok) {
24254 lastmv = { 'ins' : ins, 'par' : p, 'pos' : v === 'i' && ip === 'last' && i === 0 && !ins.is_loaded(tm) ? 'last' : i };
24255 marker.css({ 'left' : l + 'px', 'top' : t + 'px' }).show();
24256 data.helper.find('.jstree-icon').first().removeClass('jstree-er').addClass('jstree-ok');
24257 laster = {};
24258 o = true;
24259 return false;
24260 }
24261 });
24262 if(o === true) { return; }
24263 }
24264 }
24265 }
24266 lastmv = false;
24267 data.helper.find('.jstree-icon').removeClass('jstree-ok').addClass('jstree-er');
24268 marker.hide();
24269 })
24270 .on('dnd_scroll.vakata.jstree', function (e, data) {
24271 if(!data || !data.data || !data.data.jstree) { return; }
24272 marker.hide();
24273 lastmv = false;
24274 data.helper.find('.jstree-icon').first().removeClass('jstree-ok').addClass('jstree-er');
24275 })
24276 .on('dnd_stop.vakata.jstree', function (e, data) {
24277 if(opento) { clearTimeout(opento); }
24278 if(!data || !data.data || !data.data.jstree) { return; }
24279 marker.hide().detach();
24280 var i, j, nodes = [];
24281 if(lastmv) {
24282 for(i = 0, j = data.data.nodes.length; i < j; i++) {
24283 nodes[i] = data.data.origin ? data.data.origin.get_node(data.data.nodes[i]) : data.data.nodes[i];
24284 if(data.data.origin) {
24285 nodes[i].instance = data.data.origin;
24286 }
24287 }
24288 lastmv.ins[ data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))) ? 'copy_node' : 'move_node' ](nodes, lastmv.par, lastmv.pos);
24289 for(i = 0, j = nodes.length; i < j; i++) {
24290 if(nodes[i].instance) {
24291 nodes[i].instance = null;
24292 }
24293 }
24294 }
24295 else {
24296 i = $(data.event.target).closest('.jstree');
24297 if(i.length && laster && laster.error && laster.error === 'check') {
24298 i = i.jstree(true);
24299 if(i) {
24300 i.settings.core.error.call(this, laster);
24301 }
24302 }
24303 }
24304 })
24305 .on('keyup.jstree keydown.jstree', function (e, data) {
24306 data = $.vakata.dnd._get();
24307 if(data && data.data && data.data.jstree) {
24308 data.helper.find('.jstree-copy').first()[ data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (e.metaKey || e.ctrlKey))) ? 'show' : 'hide' ]();
24309 }
24310 });
24311 });
24312
24313 // helpers
24314 (function ($) {
24315 // private variable
24316 var vakata_dnd = {
24317 element : false,
24318 target : false,
24319 is_down : false,
24320 is_drag : false,
24321 helper : false,
24322 helper_w: 0,
24323 data : false,
24324 init_x : 0,
24325 init_y : 0,
24326 scroll_l: 0,
24327 scroll_t: 0,
24328 scroll_e: false,
24329 scroll_i: false,
24330 is_touch: false
24331 };
24332 $.vakata.dnd = {
24333 settings : {
24334 scroll_speed : 10,
24335 scroll_proximity : 20,
24336 helper_left : 5,
24337 helper_top : 10,
24338 threshold : 5,
24339 threshold_touch : 50
24340 },
24341 _trigger : function (event_name, e) {
24342 var data = $.vakata.dnd._get();
24343 data.event = e;
24344 $(document).triggerHandler("dnd_" + event_name + ".vakata", data);
24345 },
24346 _get : function () {
24347 return {
24348 "data" : vakata_dnd.data,
24349 "element" : vakata_dnd.element,
24350 "helper" : vakata_dnd.helper
24351 };
24352 },
24353 _clean : function () {
24354 if(vakata_dnd.helper) { vakata_dnd.helper.remove(); }
24355 if(vakata_dnd.scroll_i) { clearInterval(vakata_dnd.scroll_i); vakata_dnd.scroll_i = false; }
24356 vakata_dnd = {
24357 element : false,
24358 target : false,
24359 is_down : false,
24360 is_drag : false,
24361 helper : false,
24362 helper_w: 0,
24363 data : false,
24364 init_x : 0,
24365 init_y : 0,
24366 scroll_l: 0,
24367 scroll_t: 0,
24368 scroll_e: false,
24369 scroll_i: false,
24370 is_touch: false
24371 };
24372 $(document).off("mousemove.vakata.jstree touchmove.vakata.jstree", $.vakata.dnd.drag);
24373 $(document).off("mouseup.vakata.jstree touchend.vakata.jstree", $.vakata.dnd.stop);
24374 },
24375 _scroll : function (init_only) {
24376 if(!vakata_dnd.scroll_e || (!vakata_dnd.scroll_l && !vakata_dnd.scroll_t)) {
24377 if(vakata_dnd.scroll_i) { clearInterval(vakata_dnd.scroll_i); vakata_dnd.scroll_i = false; }
24378 return false;
24379 }
24380 if(!vakata_dnd.scroll_i) {
24381 vakata_dnd.scroll_i = setInterval($.vakata.dnd._scroll, 100);
24382 return false;
24383 }
24384 if(init_only === true) { return false; }
24385
24386 var i = vakata_dnd.scroll_e.scrollTop(),
24387 j = vakata_dnd.scroll_e.scrollLeft();
24388 vakata_dnd.scroll_e.scrollTop(i + vakata_dnd.scroll_t * $.vakata.dnd.settings.scroll_speed);
24389 vakata_dnd.scroll_e.scrollLeft(j + vakata_dnd.scroll_l * $.vakata.dnd.settings.scroll_speed);
24390 if(i !== vakata_dnd.scroll_e.scrollTop() || j !== vakata_dnd.scroll_e.scrollLeft()) {
24391 /**
24392 * triggered on the document when a drag causes an element to scroll
24393 * @event
24394 * @plugin dnd
24395 * @name dnd_scroll.vakata
24396 * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start
24397 * @param {DOM} element the DOM element being dragged
24398 * @param {jQuery} helper the helper shown next to the mouse
24399 * @param {jQuery} event the element that is scrolling
24400 */
24401 $.vakata.dnd._trigger("scroll", vakata_dnd.scroll_e);
24402 }
24403 },
24404 start : function (e, data, html) {
24405 if(e.type === "touchstart" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) {
24406 e.pageX = e.originalEvent.changedTouches[0].pageX;
24407 e.pageY = e.originalEvent.changedTouches[0].pageY;
24408 e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset);
24409 }
24410 if(vakata_dnd.is_drag) { $.vakata.dnd.stop({}); }
24411 try {
24412 e.currentTarget.unselectable = "on";
24413 e.currentTarget.onselectstart = function() { return false; };
24414 if(e.currentTarget.style) { e.currentTarget.style.MozUserSelect = "none"; }
24415 } catch(ignore) { }
24416 vakata_dnd.init_x = e.pageX;
24417 vakata_dnd.init_y = e.pageY;
24418 vakata_dnd.data = data;
24419 vakata_dnd.is_down = true;
24420 vakata_dnd.element = e.currentTarget;
24421 vakata_dnd.target = e.target;
24422 vakata_dnd.is_touch = e.type === "touchstart";
24423 if(html !== false) {
24424 vakata_dnd.helper = $("<div id='vakata-dnd'></div>").html(html).css({
24425 "display" : "block",
24426 "margin" : "0",
24427 "padding" : "0",
24428 "position" : "absolute",
24429 "top" : "-2000px",
24430 "lineHeight" : "16px",
24431 "zIndex" : "10000"
24432 });
24433 }
24434 $(document).on("mousemove.vakata.jstree touchmove.vakata.jstree", $.vakata.dnd.drag);
24435 $(document).on("mouseup.vakata.jstree touchend.vakata.jstree", $.vakata.dnd.stop);
24436 return false;
24437 },
24438 drag : function (e) {
24439 if(e.type === "touchmove" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) {
24440 e.pageX = e.originalEvent.changedTouches[0].pageX;
24441 e.pageY = e.originalEvent.changedTouches[0].pageY;
24442 e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset);
24443 }
24444 if(!vakata_dnd.is_down) { return; }
24445 if(!vakata_dnd.is_drag) {
24446 if(
24447 Math.abs(e.pageX - vakata_dnd.init_x) > (vakata_dnd.is_touch ? $.vakata.dnd.settings.threshold_touch : $.vakata.dnd.settings.threshold) ||
24448 Math.abs(e.pageY - vakata_dnd.init_y) > (vakata_dnd.is_touch ? $.vakata.dnd.settings.threshold_touch : $.vakata.dnd.settings.threshold)
24449 ) {
24450 if(vakata_dnd.helper) {
24451 vakata_dnd.helper.appendTo("body");
24452 vakata_dnd.helper_w = vakata_dnd.helper.outerWidth();
24453 }
24454 vakata_dnd.is_drag = true;
24455 /**
24456 * triggered on the document when a drag starts
24457 * @event
24458 * @plugin dnd
24459 * @name dnd_start.vakata
24460 * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start
24461 * @param {DOM} element the DOM element being dragged
24462 * @param {jQuery} helper the helper shown next to the mouse
24463 * @param {Object} event the event that caused the start (probably mousemove)
24464 */
24465 $.vakata.dnd._trigger("start", e);
24466 }
24467 else { return; }
24468 }
24469
24470 var d = false, w = false,
24471 dh = false, wh = false,
24472 dw = false, ww = false,
24473 dt = false, dl = false,
24474 ht = false, hl = false;
24475
24476 vakata_dnd.scroll_t = 0;
24477 vakata_dnd.scroll_l = 0;
24478 vakata_dnd.scroll_e = false;
24479 $($(e.target).parentsUntil("body").addBack().get().reverse())
24480 .filter(function () {
24481 return (/^auto|scroll$/).test($(this).css("overflow")) &&
24482 (this.scrollHeight > this.offsetHeight || this.scrollWidth > this.offsetWidth);
24483 })
24484 .each(function () {
24485 var t = $(this), o = t.offset();
24486 if(this.scrollHeight > this.offsetHeight) {
24487 if(o.top + t.height() - e.pageY < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = 1; }
24488 if(e.pageY - o.top < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = -1; }
24489 }
24490 if(this.scrollWidth > this.offsetWidth) {
24491 if(o.left + t.width() - e.pageX < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = 1; }
24492 if(e.pageX - o.left < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = -1; }
24493 }
24494 if(vakata_dnd.scroll_t || vakata_dnd.scroll_l) {
24495 vakata_dnd.scroll_e = $(this);
24496 return false;
24497 }
24498 });
24499
24500 if(!vakata_dnd.scroll_e) {
24501 d = $(document); w = $(window);
24502 dh = d.height(); wh = w.height();
24503 dw = d.width(); ww = w.width();
24504 dt = d.scrollTop(); dl = d.scrollLeft();
24505 if(dh > wh && e.pageY - dt < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = -1; }
24506 if(dh > wh && wh - (e.pageY - dt) < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = 1; }
24507 if(dw > ww && e.pageX - dl < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = -1; }
24508 if(dw > ww && ww - (e.pageX - dl) < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = 1; }
24509 if(vakata_dnd.scroll_t || vakata_dnd.scroll_l) {
24510 vakata_dnd.scroll_e = d;
24511 }
24512 }
24513 if(vakata_dnd.scroll_e) { $.vakata.dnd._scroll(true); }
24514
24515 if(vakata_dnd.helper) {
24516 ht = parseInt(e.pageY + $.vakata.dnd.settings.helper_top, 10);
24517 hl = parseInt(e.pageX + $.vakata.dnd.settings.helper_left, 10);
24518 if(dh && ht + 25 > dh) { ht = dh - 50; }
24519 if(dw && hl + vakata_dnd.helper_w > dw) { hl = dw - (vakata_dnd.helper_w + 2); }
24520 vakata_dnd.helper.css({
24521 left : hl + "px",
24522 top : ht + "px"
24523 });
24524 }
24525 /**
24526 * triggered on the document when a drag is in progress
24527 * @event
24528 * @plugin dnd
24529 * @name dnd_move.vakata
24530 * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start
24531 * @param {DOM} element the DOM element being dragged
24532 * @param {jQuery} helper the helper shown next to the mouse
24533 * @param {Object} event the event that caused this to trigger (most likely mousemove)
24534 */
24535 $.vakata.dnd._trigger("move", e);
24536 return false;
24537 },
24538 stop : function (e) {
24539 if(e.type === "touchend" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) {
24540 e.pageX = e.originalEvent.changedTouches[0].pageX;
24541 e.pageY = e.originalEvent.changedTouches[0].pageY;
24542 e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset);
24543 }
24544 if(vakata_dnd.is_drag) {
24545 /**
24546 * triggered on the document when a drag stops (the dragged element is dropped)
24547 * @event
24548 * @plugin dnd
24549 * @name dnd_stop.vakata
24550 * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start
24551 * @param {DOM} element the DOM element being dragged
24552 * @param {jQuery} helper the helper shown next to the mouse
24553 * @param {Object} event the event that caused the stop
24554 */
24555 $.vakata.dnd._trigger("stop", e);
24556 }
24557 else {
24558 if(e.type === "touchend" && e.target === vakata_dnd.target) {
24559 var to = setTimeout(function () { $(e.target).click(); }, 100);
24560 $(e.target).one('click', function() { if(to) { clearTimeout(to); } });
24561 }
24562 }
24563 $.vakata.dnd._clean();
24564 return false;
24565 }
24566 };
24567 }($));
24568
24569 // include the dnd plugin by default
24570 // $.jstree.defaults.plugins.push("dnd");
24571
24572
24573 /**
24574 * ### Search plugin
24575 *
24576 * Adds search functionality to jsTree.
24577 */
24578
24579 /**
24580 * stores all defaults for the search plugin
24581 * @name $.jstree.defaults.search
24582 * @plugin search
24583 */
24584 $.jstree.defaults.search = {
24585 /**
24586 * a jQuery-like AJAX config, which jstree uses if a server should be queried for results.
24587 *
24588 * A `str` (which is the search string) parameter will be added with the request. The expected result is a JSON array with nodes that need to be opened so that matching nodes will be revealed.
24589 * Leave this setting as `false` to not query the server. You can also set this to a function, which will be invoked in the instance's scope and receive 2 parameters - the search string and the callback to call with the array of nodes to load.
24590 * @name $.jstree.defaults.search.ajax
24591 * @plugin search
24592 */
24593 ajax : false,
24594 /**
24595 * Indicates if the search should be fuzzy or not (should `chnd3` match `child node 3`). Default is `false`.
24596 * @name $.jstree.defaults.search.fuzzy
24597 * @plugin search
24598 */
24599 fuzzy : false,
24600 /**
24601 * Indicates if the search should be case sensitive. Default is `false`.
24602 * @name $.jstree.defaults.search.case_sensitive
24603 * @plugin search
24604 */
24605 case_sensitive : false,
24606 /**
24607 * Indicates if the tree should be filtered (by default) to show only matching nodes (keep in mind this can be a heavy on large trees in old browsers).
24608 * This setting can be changed at runtime when calling the search method. Default is `false`.
24609 * @name $.jstree.defaults.search.show_only_matches
24610 * @plugin search
24611 */
24612 show_only_matches : false,
24613 /**
24614 * Indicates if all nodes opened to reveal the search result, should be closed when the search is cleared or a new search is performed. Default is `true`.
24615 * @name $.jstree.defaults.search.close_opened_onclear
24616 * @plugin search
24617 */
24618 close_opened_onclear : true,
24619 /**
24620 * Indicates if only leaf nodes should be included in search results. Default is `false`.
24621 * @name $.jstree.defaults.search.search_leaves_only
24622 * @plugin search
24623 */
24624 search_leaves_only : false,
24625 /**
24626 * If set to a function it wil be called in the instance's scope with two arguments - search string and node (where node will be every node in the structure, so use with caution).
24627 * If the function returns a truthy value the node will be considered a match (it might not be displayed if search_only_leaves is set to true and the node is not a leaf). Default is `false`.
24628 * @name $.jstree.defaults.search.search_callback
24629 * @plugin search
24630 */
24631 search_callback : false
24632 };
24633
24634 $.jstree.plugins.search = function (options, parent) {
24635 this.bind = function () {
24636 parent.bind.call(this);
24637
24638 this._data.search.str = "";
24639 this._data.search.dom = $();
24640 this._data.search.res = [];
24641 this._data.search.opn = [];
24642 this._data.search.som = false;
24643
24644 this.element
24645 .on('before_open.jstree', $.proxy(function (e, data) {
24646 var i, j, f, r = this._data.search.res, s = [], o = $();
24647 if(r && r.length) {
24648 this._data.search.dom = $(this.element[0].querySelectorAll('#' + $.map(r, function (v) { return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&'); }).join(', #')));
24649 this._data.search.dom.children(".jstree-anchor").addClass('jstree-search');
24650 if(this._data.search.som && this._data.search.res.length) {
24651 for(i = 0, j = r.length; i < j; i++) {
24652 s = s.concat(this.get_node(r[i]).parents);
24653 }
24654 s = $.vakata.array_remove_item($.vakata.array_unique(s),'#');
24655 o = s.length ? $(this.element[0].querySelectorAll('#' + $.map(s, function (v) { return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&'); }).join(', #'))) : $();
24656
24657 this.element.find(".jstree-node").hide().filter('.jstree-last').filter(function() { return this.nextSibling; }).removeClass('jstree-last');
24658 o = o.add(this._data.search.dom);
24659 o.parentsUntil(".jstree").addBack().show()
24660 .filter(".jstree-children").each(function () { $(this).children(".jstree-node:visible").eq(-1).addClass("jstree-last"); });
24661 }
24662 }
24663 }, this))
24664 .on("search.jstree", $.proxy(function (e, data) {
24665 if(this._data.search.som) {
24666 if(data.nodes.length) {
24667 this.element.find(".jstree-node").hide().filter('.jstree-last').filter(function() { return this.nextSibling; }).removeClass('jstree-last');
24668 data.nodes.parentsUntil(".jstree").addBack().show()
24669 .filter(".jstree-children").each(function () { $(this).children(".jstree-node:visible").eq(-1).addClass("jstree-last"); });
24670 }
24671 }
24672 }, this))
24673 .on("clear_search.jstree", $.proxy(function (e, data) {
24674 if(this._data.search.som && data.nodes.length) {
24675 this.element.find(".jstree-node").css("display","").filter('.jstree-last').filter(function() { return this.nextSibling; }).removeClass('jstree-last');
24676 }
24677 }, this));
24678 };
24679 /**
24680 * used to search the tree nodes for a given string
24681 * @name search(str [, skip_async])
24682 * @param {String} str the search string
24683 * @param {Boolean} skip_async if set to true server will not be queried even if configured
24684 * @param {Boolean} show_only_matches if set to true only matching nodes will be shown (keep in mind this can be very slow on large trees or old browsers)
24685 * @plugin search
24686 * @trigger search.jstree
24687 */
24688 this.search = function (str, skip_async, show_only_matches) {
24689 if(str === false || $.trim(str.toString()) === "") {
24690 return this.clear_search();
24691 }
24692 str = str.toString();
24693 var s = this.settings.search,
24694 a = s.ajax ? s.ajax : false,
24695 f = null,
24696 r = [],
24697 p = [], i, j;
24698 if(this._data.search.res.length) {
24699 this.clear_search();
24700 }
24701 if(show_only_matches === undefined) {
24702 show_only_matches = s.show_only_matches;
24703 }
24704 if(!skip_async && a !== false) {
24705 if($.isFunction(a)) {
24706 return a.call(this, str, $.proxy(function (d) {
24707 if(d && d.d) { d = d.d; }
24708 this._load_nodes(!$.isArray(d) ? [] : $.vakata.array_unique(d), function () {
24709 this.search(str, true, show_only_matches);
24710 }, true);
24711 }, this));
24712 }
24713 else {
24714 a = $.extend({}, a);
24715 if(!a.data) { a.data = {}; }
24716 a.data.str = str;
24717 return $.ajax(a)
24718 .fail($.proxy(function () {
24719 this._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'search', 'id' : 'search_01', 'reason' : 'Could not load search parents', 'data' : JSON.stringify(a) };
24720 this.settings.core.error.call(this, this._data.core.last_error);
24721 }, this))
24722 .done($.proxy(function (d) {
24723 if(d && d.d) { d = d.d; }
24724 this._load_nodes(!$.isArray(d) ? [] : $.vakata.array_unique(d), function () {
24725 this.search(str, true, show_only_matches);
24726 }, true);
24727 }, this));
24728 }
24729 }
24730 this._data.search.str = str;
24731 this._data.search.dom = $();
24732 this._data.search.res = [];
24733 this._data.search.opn = [];
24734 this._data.search.som = show_only_matches;
24735
24736 f = new $.vakata.search(str, true, { caseSensitive : s.case_sensitive, fuzzy : s.fuzzy });
24737
24738 $.each(this._model.data, function (i, v) {
24739 if(v.text && ( (s.search_callback && s.search_callback.call(this, str, v)) || (!s.search_callback && f.search(v.text).isMatch) ) && (!s.search_leaves_only || (v.state.loaded && v.children.length === 0)) ) {
24740 r.push(i);
24741 p = p.concat(v.parents);
24742 }
24743 });
24744 if(r.length) {
24745 p = $.vakata.array_unique(p);
24746 this._search_open(p);
24747 this._data.search.dom = $(this.element[0].querySelectorAll('#' + $.map(r, function (v) { return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&'); }).join(', #')));
24748 this._data.search.res = r;
24749 this._data.search.dom.children(".jstree-anchor").addClass('jstree-search');
24750 }
24751 /**
24752 * triggered after search is complete
24753 * @event
24754 * @name search.jstree
24755 * @param {jQuery} nodes a jQuery collection of matching nodes
24756 * @param {String} str the search string
24757 * @param {Array} res a collection of objects represeing the matching nodes
24758 * @plugin search
24759 */
24760 this.trigger('search', { nodes : this._data.search.dom, str : str, res : this._data.search.res, show_only_matches : show_only_matches });
24761 };
24762 /**
24763 * used to clear the last search (removes classes and shows all nodes if filtering is on)
24764 * @name clear_search()
24765 * @plugin search
24766 * @trigger clear_search.jstree
24767 */
24768 this.clear_search = function () {
24769 this._data.search.dom.children(".jstree-anchor").removeClass("jstree-search");
24770 if(this.settings.search.close_opened_onclear) {
24771 this.close_node(this._data.search.opn, 0);
24772 }
24773 /**
24774 * triggered after search is complete
24775 * @event
24776 * @name clear_search.jstree
24777 * @param {jQuery} nodes a jQuery collection of matching nodes (the result from the last search)
24778 * @param {String} str the search string (the last search string)
24779 * @param {Array} res a collection of objects represeing the matching nodes (the result from the last search)
24780 * @plugin search
24781 */
24782 this.trigger('clear_search', { 'nodes' : this._data.search.dom, str : this._data.search.str, res : this._data.search.res });
24783 this._data.search.str = "";
24784 this._data.search.res = [];
24785 this._data.search.opn = [];
24786 this._data.search.dom = $();
24787 };
24788 /**
24789 * opens nodes that need to be opened to reveal the search results. Used only internally.
24790 * @private
24791 * @name _search_open(d)
24792 * @param {Array} d an array of node IDs
24793 * @plugin search
24794 */
24795 this._search_open = function (d) {
24796 var t = this;
24797 $.each(d.concat([]), function (i, v) {
24798 if(v === "#") { return true; }
24799 try { v = $('#' + v.replace($.jstree.idregex,'\\$&'), t.element); } catch(ignore) { }
24800 if(v && v.length) {
24801 if(t.is_closed(v)) {
24802 t._data.search.opn.push(v[0].id);
24803 t.open_node(v, function () { t._search_open(d); }, 0);
24804 }
24805 }
24806 });
24807 };
24808 };
24809
24810 // helpers
24811 (function ($) {
24812 // from http://kiro.me/projects/fuse.html
24813 $.vakata.search = function(pattern, txt, options) {
24814 options = options || {};
24815 if(options.fuzzy !== false) {
24816 options.fuzzy = true;
24817 }
24818 pattern = options.caseSensitive ? pattern : pattern.toLowerCase();
24819 var MATCH_LOCATION = options.location || 0,
24820 MATCH_DISTANCE = options.distance || 100,
24821 MATCH_THRESHOLD = options.threshold || 0.6,
24822 patternLen = pattern.length,
24823 matchmask, pattern_alphabet, match_bitapScore, search;
24824 if(patternLen > 32) {
24825 options.fuzzy = false;
24826 }
24827 if(options.fuzzy) {
24828 matchmask = 1 << (patternLen - 1);
24829 pattern_alphabet = (function () {
24830 var mask = {},
24831 i = 0;
24832 for (i = 0; i < patternLen; i++) {
24833 mask[pattern.charAt(i)] = 0;
24834 }
24835 for (i = 0; i < patternLen; i++) {
24836 mask[pattern.charAt(i)] |= 1 << (patternLen - i - 1);
24837 }
24838 return mask;
24839 }());
24840 match_bitapScore = function (e, x) {
24841 var accuracy = e / patternLen,
24842 proximity = Math.abs(MATCH_LOCATION - x);
24843 if(!MATCH_DISTANCE) {
24844 return proximity ? 1.0 : accuracy;
24845 }
24846 return accuracy + (proximity / MATCH_DISTANCE);
24847 };
24848 }
24849 search = function (text) {
24850 text = options.caseSensitive ? text : text.toLowerCase();
24851 if(pattern === text || text.indexOf(pattern) !== -1) {
24852 return {
24853 isMatch: true,
24854 score: 0
24855 };
24856 }
24857 if(!options.fuzzy) {
24858 return {
24859 isMatch: false,
24860 score: 1
24861 };
24862 }
24863 var i, j,
24864 textLen = text.length,
24865 scoreThreshold = MATCH_THRESHOLD,
24866 bestLoc = text.indexOf(pattern, MATCH_LOCATION),
24867 binMin, binMid,
24868 binMax = patternLen + textLen,
24869 lastRd, start, finish, rd, charMatch,
24870 score = 1,
24871 locations = [];
24872 if (bestLoc !== -1) {
24873 scoreThreshold = Math.min(match_bitapScore(0, bestLoc), scoreThreshold);
24874 bestLoc = text.lastIndexOf(pattern, MATCH_LOCATION + patternLen);
24875 if (bestLoc !== -1) {
24876 scoreThreshold = Math.min(match_bitapScore(0, bestLoc), scoreThreshold);
24877 }
24878 }
24879 bestLoc = -1;
24880 for (i = 0; i < patternLen; i++) {
24881 binMin = 0;
24882 binMid = binMax;
24883 while (binMin < binMid) {
24884 if (match_bitapScore(i, MATCH_LOCATION + binMid) <= scoreThreshold) {
24885 binMin = binMid;
24886 } else {
24887 binMax = binMid;
24888 }
24889 binMid = Math.floor((binMax - binMin) / 2 + binMin);
24890 }
24891 binMax = binMid;
24892 start = Math.max(1, MATCH_LOCATION - binMid + 1);
24893 finish = Math.min(MATCH_LOCATION + binMid, textLen) + patternLen;
24894 rd = new Array(finish + 2);
24895 rd[finish + 1] = (1 << i) - 1;
24896 for (j = finish; j >= start; j--) {
24897 charMatch = pattern_alphabet[text.charAt(j - 1)];
24898 if (i === 0) {
24899 rd[j] = ((rd[j + 1] << 1) | 1) & charMatch;
24900 } else {
24901 rd[j] = ((rd[j + 1] << 1) | 1) & charMatch | (((lastRd[j + 1] | lastRd[j]) << 1) | 1) | lastRd[j + 1];
24902 }
24903 if (rd[j] & matchmask) {
24904 score = match_bitapScore(i, j - 1);
24905 if (score <= scoreThreshold) {
24906 scoreThreshold = score;
24907 bestLoc = j - 1;
24908 locations.push(bestLoc);
24909 if (bestLoc > MATCH_LOCATION) {
24910 start = Math.max(1, 2 * MATCH_LOCATION - bestLoc);
24911 } else {
24912 break;
24913 }
24914 }
24915 }
24916 }
24917 if (match_bitapScore(i + 1, MATCH_LOCATION) > scoreThreshold) {
24918 break;
24919 }
24920 lastRd = rd;
24921 }
24922 return {
24923 isMatch: bestLoc >= 0,
24924 score: score
24925 };
24926 };
24927 return txt === true ? { 'search' : search } : search(txt);
24928 };
24929 }($));
24930
24931 // include the search plugin by default
24932 // $.jstree.defaults.plugins.push("search");
24933
24934 /**
24935 * ### Sort plugin
24936 *
24937 * Automatically sorts all siblings in the tree according to a sorting function.
24938 */
24939
24940 /**
24941 * the settings function used to sort the nodes.
24942 * It is executed in the tree's context, accepts two nodes as arguments and should return `1` or `-1`.
24943 * @name $.jstree.defaults.sort
24944 * @plugin sort
24945 */
24946 $.jstree.defaults.sort = function (a, b) {
24947 //return this.get_type(a) === this.get_type(b) ? (this.get_text(a) > this.get_text(b) ? 1 : -1) : this.get_type(a) >= this.get_type(b);
24948 return this.get_text(a) > this.get_text(b) ? 1 : -1;
24949 };
24950 $.jstree.plugins.sort = function (options, parent) {
24951 this.bind = function () {
24952 parent.bind.call(this);
24953 this.element
24954 .on("model.jstree", $.proxy(function (e, data) {
24955 this.sort(data.parent, true);
24956 }, this))
24957 .on("rename_node.jstree create_node.jstree", $.proxy(function (e, data) {
24958 this.sort(data.parent || data.node.parent, false);
24959 this.redraw_node(data.parent || data.node.parent, true);
24960 }, this))
24961 .on("move_node.jstree copy_node.jstree", $.proxy(function (e, data) {
24962 this.sort(data.parent, false);
24963 this.redraw_node(data.parent, true);
24964 }, this));
24965 };
24966 /**
24967 * used to sort a node's children
24968 * @private
24969 * @name sort(obj [, deep])
24970 * @param {mixed} obj the node
24971 * @param {Boolean} deep if set to `true` nodes are sorted recursively.
24972 * @plugin sort
24973 * @trigger search.jstree
24974 */
24975 this.sort = function (obj, deep) {
24976 var i, j;
24977 obj = this.get_node(obj);
24978 if(obj && obj.children && obj.children.length) {
24979 obj.children.sort($.proxy(this.settings.sort, this));
24980 if(deep) {
24981 for(i = 0, j = obj.children_d.length; i < j; i++) {
24982 this.sort(obj.children_d[i], false);
24983 }
24984 }
24985 }
24986 };
24987 };
24988
24989 // include the sort plugin by default
24990 // $.jstree.defaults.plugins.push("sort");
24991
24992 /**
24993 * ### State plugin
24994 *
24995 * Saves the state of the tree (selected nodes, opened nodes) on the user's computer using available options (localStorage, cookies, etc)
24996 */
24997
24998 var to = false;
24999 /**
25000 * stores all defaults for the state plugin
25001 * @name $.jstree.defaults.state
25002 * @plugin state
25003 */
25004 $.jstree.defaults.state = {
25005 /**
25006 * A string for the key to use when saving the current tree (change if using multiple trees in your project). Defaults to `jstree`.
25007 * @name $.jstree.defaults.state.key
25008 * @plugin state
25009 */
25010 key : 'jstree',
25011 /**
25012 * A space separated list of events that trigger a state save. Defaults to `changed.jstree open_node.jstree close_node.jstree`.
25013 * @name $.jstree.defaults.state.events
25014 * @plugin state
25015 */
25016 events : 'changed.jstree open_node.jstree close_node.jstree check_node.jstree uncheck_node.jstree',
25017 /**
25018 * Time in milliseconds after which the state will expire. Defaults to 'false' meaning - no expire.
25019 * @name $.jstree.defaults.state.ttl
25020 * @plugin state
25021 */
25022 ttl : false,
25023 /**
25024 * A function that will be executed prior to restoring state with one argument - the state object. Can be used to clear unwanted parts of the state.
25025 * @name $.jstree.defaults.state.filter
25026 * @plugin state
25027 */
25028 filter : false
25029 };
25030 $.jstree.plugins.state = function (options, parent) {
25031 this.bind = function () {
25032 parent.bind.call(this);
25033 var bind = $.proxy(function () {
25034 this.element.on(this.settings.state.events, $.proxy(function () {
25035 if(to) { clearTimeout(to); }
25036 to = setTimeout($.proxy(function () { this.save_state(); }, this), 100);
25037 }, this));
25038 /**
25039 * triggered when the state plugin is finished restoring the state (and immediately after ready if there is no state to restore).
25040 * @event
25041 * @name state_ready.jstree
25042 * @plugin state
25043 */
25044 this.trigger('state_ready');
25045 }, this);
25046 this.element
25047 .on("ready.jstree", $.proxy(function (e, data) {
25048 this.element.one("restore_state.jstree", bind);
25049 if(!this.restore_state()) { bind(); }
25050 }, this));
25051 };
25052 /**
25053 * save the state
25054 * @name save_state()
25055 * @plugin state
25056 */
25057 this.save_state = function () {
25058 var st = { 'state' : this.get_state(), 'ttl' : this.settings.state.ttl, 'sec' : +(new Date()) };
25059 $.vakata.storage.set(this.settings.state.key, JSON.stringify(st));
25060 };
25061 /**
25062 * restore the state from the user's computer
25063 * @name restore_state()
25064 * @plugin state
25065 */
25066 this.restore_state = function () {
25067 var k = $.vakata.storage.get(this.settings.state.key);
25068 if(!!k) { try { k = JSON.parse(k); } catch(ex) { return false; } }
25069 if(!!k && k.ttl && k.sec && +(new Date()) - k.sec > k.ttl) { return false; }
25070 if(!!k && k.state) { k = k.state; }
25071 if(!!k && $.isFunction(this.settings.state.filter)) { k = this.settings.state.filter.call(this, k); }
25072 if(!!k) {
25073 this.element.one("set_state.jstree", function (e, data) { data.instance.trigger('restore_state', { 'state' : $.extend(true, {}, k) }); });
25074 this.set_state(k);
25075 return true;
25076 }
25077 return false;
25078 };
25079 /**
25080 * clear the state on the user's computer
25081 * @name clear_state()
25082 * @plugin state
25083 */
25084 this.clear_state = function () {
25085 return $.vakata.storage.del(this.settings.state.key);
25086 };
25087 };
25088
25089 (function ($, undefined) {
25090 $.vakata.storage = {
25091 // simply specifying the functions in FF throws an error
25092 set : function (key, val) { return window.localStorage.setItem(key, val); },
25093 get : function (key) { return window.localStorage.getItem(key); },
25094 del : function (key) { return window.localStorage.removeItem(key); }
25095 };
25096 }($));
25097
25098 // include the state plugin by default
25099 // $.jstree.defaults.plugins.push("state");
25100
25101 /**
25102 * ### Types plugin
25103 *
25104 * Makes it possible to add predefined types for groups of nodes, which make it possible to easily control nesting rules and icon for each group.
25105 */
25106
25107 /**
25108 * An object storing all types as key value pairs, where the key is the type name and the value is an object that could contain following keys (all optional).
25109 *
25110 * * `max_children` the maximum number of immediate children this node type can have. Do not specify or set to `-1` for unlimited.
25111 * * `max_depth` the maximum number of nesting this node type can have. A value of `1` would mean that the node can have children, but no grandchildren. Do not specify or set to `-1` for unlimited.
25112 * * `valid_children` an array of node type strings, that nodes of this type can have as children. Do not specify or set to `-1` for no limits.
25113 * * `icon` a string - can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class. Omit to use the default icon from your theme.
25114 *
25115 * There are two predefined types:
25116 *
25117 * * `#` represents the root of the tree, for example `max_children` would control the maximum number of root nodes.
25118 * * `default` represents the default node - any settings here will be applied to all nodes that do not have a type specified.
25119 *
25120 * @name $.jstree.defaults.types
25121 * @plugin types
25122 */
25123 $.jstree.defaults.types = {
25124 '#' : {},
25125 'default' : {}
25126 };
25127
25128 $.jstree.plugins.types = function (options, parent) {
25129 this.init = function (el, options) {
25130 var i, j;
25131 if(options && options.types && options.types['default']) {
25132 for(i in options.types) {
25133 if(i !== "default" && i !== "#" && options.types.hasOwnProperty(i)) {
25134 for(j in options.types['default']) {
25135 if(options.types['default'].hasOwnProperty(j) && options.types[i][j] === undefined) {
25136 options.types[i][j] = options.types['default'][j];
25137 }
25138 }
25139 }
25140 }
25141 }
25142 parent.init.call(this, el, options);
25143 this._model.data['#'].type = '#';
25144 };
25145 this.refresh = function (skip_loading, forget_state) {
25146 parent.refresh.call(this, skip_loading, forget_state);
25147 this._model.data['#'].type = '#';
25148 };
25149 this.bind = function () {
25150 this.element
25151 .on('model.jstree', $.proxy(function (e, data) {
25152 var m = this._model.data,
25153 dpc = data.nodes,
25154 t = this.settings.types,
25155 i, j, c = 'default';
25156 for(i = 0, j = dpc.length; i < j; i++) {
25157 c = 'default';
25158 if(m[dpc[i]].original && m[dpc[i]].original.type && t[m[dpc[i]].original.type]) {
25159 c = m[dpc[i]].original.type;
25160 }
25161 if(m[dpc[i]].data && m[dpc[i]].data.jstree && m[dpc[i]].data.jstree.type && t[m[dpc[i]].data.jstree.type]) {
25162 c = m[dpc[i]].data.jstree.type;
25163 }
25164 m[dpc[i]].type = c;
25165 if(m[dpc[i]].icon === true && t[c].icon !== undefined) {
25166 m[dpc[i]].icon = t[c].icon;
25167 }
25168 }
25169 m['#'].type = '#';
25170 }, this));
25171 parent.bind.call(this);
25172 };
25173 this.get_json = function (obj, options, flat) {
25174 var i, j,
25175 m = this._model.data,
25176 opt = options ? $.extend(true, {}, options, {no_id:false}) : {},
25177 tmp = parent.get_json.call(this, obj, opt, flat);
25178 if(tmp === false) { return false; }
25179 if($.isArray(tmp)) {
25180 for(i = 0, j = tmp.length; i < j; i++) {
25181 tmp[i].type = tmp[i].id && m[tmp[i].id] && m[tmp[i].id].type ? m[tmp[i].id].type : "default";
25182 if(options && options.no_id) {
25183 delete tmp[i].id;
25184 if(tmp[i].li_attr && tmp[i].li_attr.id) {
25185 delete tmp[i].li_attr.id;
25186 }
25187 if(tmp[i].a_attr && tmp[i].a_attr.id) {
25188 delete tmp[i].a_attr.id;
25189 }
25190 }
25191 }
25192 }
25193 else {
25194 tmp.type = tmp.id && m[tmp.id] && m[tmp.id].type ? m[tmp.id].type : "default";
25195 if(options && options.no_id) {
25196 tmp = this._delete_ids(tmp);
25197 }
25198 }
25199 return tmp;
25200 };
25201 this._delete_ids = function (tmp) {
25202 if($.isArray(tmp)) {
25203 for(var i = 0, j = tmp.length; i < j; i++) {
25204 tmp[i] = this._delete_ids(tmp[i]);
25205 }
25206 return tmp;
25207 }
25208 delete tmp.id;
25209 if(tmp.li_attr && tmp.li_attr.id) {
25210 delete tmp.li_attr.id;
25211 }
25212 if(tmp.a_attr && tmp.a_attr.id) {
25213 delete tmp.a_attr.id;
25214 }
25215 if(tmp.children && $.isArray(tmp.children)) {
25216 tmp.children = this._delete_ids(tmp.children);
25217 }
25218 return tmp;
25219 };
25220 this.check = function (chk, obj, par, pos, more) {
25221 if(parent.check.call(this, chk, obj, par, pos, more) === false) { return false; }
25222 obj = obj && obj.id ? obj : this.get_node(obj);
25223 par = par && par.id ? par : this.get_node(par);
25224 var m = obj && obj.id ? $.jstree.reference(obj.id) : null, tmp, d, i, j;
25225 m = m && m._model && m._model.data ? m._model.data : null;
25226 switch(chk) {
25227 case "create_node":
25228 case "move_node":
25229 case "copy_node":
25230 if(chk !== 'move_node' || $.inArray(obj.id, par.children) === -1) {
25231 tmp = this.get_rules(par);
25232 if(tmp.max_children !== undefined && tmp.max_children !== -1 && tmp.max_children === par.children.length) {
25233 this._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_01', 'reason' : 'max_children prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
25234 return false;
25235 }
25236 if(tmp.valid_children !== undefined && tmp.valid_children !== -1 && $.inArray((obj.type || 'default'), tmp.valid_children) === -1) {
25237 this._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_02', 'reason' : 'valid_children prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
25238 return false;
25239 }
25240 if(m && obj.children_d && obj.parents) {
25241 d = 0;
25242 for(i = 0, j = obj.children_d.length; i < j; i++) {
25243 d = Math.max(d, m[obj.children_d[i]].parents.length);
25244 }
25245 d = d - obj.parents.length + 1;
25246 }
25247 if(d <= 0 || d === undefined) { d = 1; }
25248 do {
25249 if(tmp.max_depth !== undefined && tmp.max_depth !== -1 && tmp.max_depth < d) {
25250 this._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_03', 'reason' : 'max_depth prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
25251 return false;
25252 }
25253 par = this.get_node(par.parent);
25254 tmp = this.get_rules(par);
25255 d++;
25256 } while(par);
25257 }
25258 break;
25259 }
25260 return true;
25261 };
25262 /**
25263 * used to retrieve the type settings object for a node
25264 * @name get_rules(obj)
25265 * @param {mixed} obj the node to find the rules for
25266 * @return {Object}
25267 * @plugin types
25268 */
25269 this.get_rules = function (obj) {
25270 obj = this.get_node(obj);
25271 if(!obj) { return false; }
25272 var tmp = this.get_type(obj, true);
25273 if(tmp.max_depth === undefined) { tmp.max_depth = -1; }
25274 if(tmp.max_children === undefined) { tmp.max_children = -1; }
25275 if(tmp.valid_children === undefined) { tmp.valid_children = -1; }
25276 return tmp;
25277 };
25278 /**
25279 * used to retrieve the type string or settings object for a node
25280 * @name get_type(obj [, rules])
25281 * @param {mixed} obj the node to find the rules for
25282 * @param {Boolean} rules if set to `true` instead of a string the settings object will be returned
25283 * @return {String|Object}
25284 * @plugin types
25285 */
25286 this.get_type = function (obj, rules) {
25287 obj = this.get_node(obj);
25288 return (!obj) ? false : ( rules ? $.extend({ 'type' : obj.type }, this.settings.types[obj.type]) : obj.type);
25289 };
25290 /**
25291 * used to change a node's type
25292 * @name set_type(obj, type)
25293 * @param {mixed} obj the node to change
25294 * @param {String} type the new type
25295 * @plugin types
25296 */
25297 this.set_type = function (obj, type) {
25298 var t, t1, t2, old_type, old_icon;
25299 if($.isArray(obj)) {
25300 obj = obj.slice();
25301 for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
25302 this.set_type(obj[t1], type);
25303 }
25304 return true;
25305 }
25306 t = this.settings.types;
25307 obj = this.get_node(obj);
25308 if(!t[type] || !obj) { return false; }
25309 old_type = obj.type;
25310 old_icon = this.get_icon(obj);
25311 obj.type = type;
25312 if(old_icon === true || (t[old_type] && t[old_type].icon !== undefined && old_icon === t[old_type].icon)) {
25313 this.set_icon(obj, t[type].icon !== undefined ? t[type].icon : true);
25314 }
25315 return true;
25316 };
25317 };
25318 // include the types plugin by default
25319 // $.jstree.defaults.plugins.push("types");
25320
25321 /**
25322 * ### Unique plugin
25323 *
25324 * Enforces that no nodes with the same name can coexist as siblings.
25325 */
25326
25327 /**
25328 * stores all defaults for the unique plugin
25329 * @name $.jstree.defaults.unique
25330 * @plugin unique
25331 */
25332 $.jstree.defaults.unique = {
25333 /**
25334 * Indicates if the comparison should be case sensitive. Default is `false`.
25335 * @name $.jstree.defaults.unique.case_sensitive
25336 * @plugin unique
25337 */
25338 case_sensitive : false,
25339 /**
25340 * A callback executed in the instance's scope when a new node is created and the name is already taken, the two arguments are the conflicting name and the counter. The default will produce results like `New node (2)`.
25341 * @name $.jstree.defaults.unique.duplicate
25342 * @plugin unique
25343 */
25344 duplicate : function (name, counter) {
25345 return name + ' (' + counter + ')';
25346 }
25347 };
25348
25349 $.jstree.plugins.unique = function (options, parent) {
25350 this.check = function (chk, obj, par, pos, more) {
25351 if(parent.check.call(this, chk, obj, par, pos, more) === false) { return false; }
25352 obj = obj && obj.id ? obj : this.get_node(obj);
25353 par = par && par.id ? par : this.get_node(par);
25354 if(!par || !par.children) { return true; }
25355 var n = chk === "rename_node" ? pos : obj.text,
25356 c = [],
25357 s = this.settings.unique.case_sensitive,
25358 m = this._model.data, i, j;
25359 for(i = 0, j = par.children.length; i < j; i++) {
25360 c.push(s ? m[par.children[i]].text : m[par.children[i]].text.toLowerCase());
25361 }
25362 if(!s) { n = n.toLowerCase(); }
25363 switch(chk) {
25364 case "delete_node":
25365 return true;
25366 case "rename_node":
25367 i = ($.inArray(n, c) === -1 || (obj.text && obj.text[ s ? 'toString' : 'toLowerCase']() === n));
25368 if(!i) {
25369 this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_01', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
25370 }
25371 return i;
25372 case "create_node":
25373 i = ($.inArray(n, c) === -1);
25374 if(!i) {
25375 this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_04', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
25376 }
25377 return i;
25378 case "copy_node":
25379 i = ($.inArray(n, c) === -1);
25380 if(!i) {
25381 this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_02', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
25382 }
25383 return i;
25384 case "move_node":
25385 i = (obj.parent === par.id || $.inArray(n, c) === -1);
25386 if(!i) {
25387 this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_03', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
25388 }
25389 return i;
25390 }
25391 return true;
25392 };
25393 this.create_node = function (par, node, pos, callback, is_loaded) {
25394 if(!node || node.text === undefined) {
25395 if(par === null) {
25396 par = "#";
25397 }
25398 par = this.get_node(par);
25399 if(!par) {
25400 return parent.create_node.call(this, par, node, pos, callback, is_loaded);
25401 }
25402 pos = pos === undefined ? "last" : pos;
25403 if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) {
25404 return parent.create_node.call(this, par, node, pos, callback, is_loaded);
25405 }
25406 if(!node) { node = {}; }
25407 var tmp, n, dpc, i, j, m = this._model.data, s = this.settings.unique.case_sensitive, cb = this.settings.unique.duplicate;
25408 n = tmp = this.get_string('New node');
25409 dpc = [];
25410 for(i = 0, j = par.children.length; i < j; i++) {
25411 dpc.push(s ? m[par.children[i]].text : m[par.children[i]].text.toLowerCase());
25412 }
25413 i = 1;
25414 while($.inArray(s ? n : n.toLowerCase(), dpc) !== -1) {
25415 n = cb.call(this, tmp, (++i)).toString();
25416 }
25417 node.text = n;
25418 }
25419 return parent.create_node.call(this, par, node, pos, callback, is_loaded);
25420 };
25421 };
25422
25423 // include the unique plugin by default
25424 // $.jstree.defaults.plugins.push("unique");
25425
25426
25427 /**
25428 * ### Wholerow plugin
25429 *
25430 * Makes each node appear block level. Making selection easier. May cause slow down for large trees in old browsers.
25431 */
25432
25433 var div = document.createElement('DIV');
25434 div.setAttribute('unselectable','on');
25435 div.setAttribute('role','presentation');
25436 div.className = 'jstree-wholerow';
25437 div.innerHTML = '&#160;';
25438 $.jstree.plugins.wholerow = function (options, parent) {
25439 this.bind = function () {
25440 parent.bind.call(this);
25441
25442 this.element
25443 .on('ready.jstree set_state.jstree', $.proxy(function () {
25444 this.hide_dots();
25445 }, this))
25446 .on("init.jstree loading.jstree ready.jstree", $.proxy(function () {
25447 //div.style.height = this._data.core.li_height + 'px';
25448 this.get_container_ul().addClass('jstree-wholerow-ul');
25449 }, this))
25450 .on("deselect_all.jstree", $.proxy(function (e, data) {
25451 this.element.find('.jstree-wholerow-clicked').removeClass('jstree-wholerow-clicked');
25452 }, this))
25453 .on("changed.jstree", $.proxy(function (e, data) {
25454 this.element.find('.jstree-wholerow-clicked').removeClass('jstree-wholerow-clicked');
25455 var tmp = false, i, j;
25456 for(i = 0, j = data.selected.length; i < j; i++) {
25457 tmp = this.get_node(data.selected[i], true);
25458 if(tmp && tmp.length) {
25459 tmp.children('.jstree-wholerow').addClass('jstree-wholerow-clicked');
25460 }
25461 }
25462 }, this))
25463 .on("open_node.jstree", $.proxy(function (e, data) {
25464 this.get_node(data.node, true).find('.jstree-clicked').parent().children('.jstree-wholerow').addClass('jstree-wholerow-clicked');
25465 }, this))
25466 .on("hover_node.jstree dehover_node.jstree", $.proxy(function (e, data) {
25467 if(e.type === "hover_node" && this.is_disabled(data.node)) { return; }
25468 this.get_node(data.node, true).children('.jstree-wholerow')[e.type === "hover_node"?"addClass":"removeClass"]('jstree-wholerow-hovered');
25469 }, this))
25470 .on("contextmenu.jstree", ".jstree-wholerow", $.proxy(function (e) {
25471 e.preventDefault();
25472 var tmp = $.Event('contextmenu', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey, pageX : e.pageX, pageY : e.pageY });
25473 $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp);
25474 }, this))
25475 .on("click.jstree", ".jstree-wholerow", function (e) {
25476 e.stopImmediatePropagation();
25477 var tmp = $.Event('click', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey });
25478 $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp).focus();
25479 })
25480 .on("click.jstree", ".jstree-leaf > .jstree-ocl", $.proxy(function (e) {
25481 e.stopImmediatePropagation();
25482 var tmp = $.Event('click', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey });
25483 $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp).focus();
25484 }, this))
25485 .on("mouseover.jstree", ".jstree-wholerow, .jstree-icon", $.proxy(function (e) {
25486 e.stopImmediatePropagation();
25487 if(!this.is_disabled(e.currentTarget)) {
25488 this.hover_node(e.currentTarget);
25489 }
25490 return false;
25491 }, this))
25492 .on("mouseleave.jstree", ".jstree-node", $.proxy(function (e) {
25493 this.dehover_node(e.currentTarget);
25494 }, this));
25495 };
25496 this.teardown = function () {
25497 if(this.settings.wholerow) {
25498 this.element.find(".jstree-wholerow").remove();
25499 }
25500 parent.teardown.call(this);
25501 };
25502 this.redraw_node = function(obj, deep, callback, force_render) {
25503 obj = parent.redraw_node.apply(this, arguments);
25504 if(obj) {
25505 var tmp = div.cloneNode(true);
25506 //tmp.style.height = this._data.core.li_height + 'px';
25507 if($.inArray(obj.id, this._data.core.selected) !== -1) { tmp.className += ' jstree-wholerow-clicked'; }
25508 if(this._data.core.focused && this._data.core.focused === obj.id) { tmp.className += ' jstree-wholerow-hovered'; }
25509 obj.insertBefore(tmp, obj.childNodes[0]);
25510 }
25511 return obj;
25512 };
25513 };
25514 // include the wholerow plugin by default
25515 // $.jstree.defaults.plugins.push("wholerow");
25516
25517
25518 (function ($) {
25519 if(document.registerElement && Object && Object.create) {
25520 var proto = Object.create(HTMLElement.prototype);
25521 proto.createdCallback = function () {
25522 var c = { core : {}, plugins : [] }, i;
25523 for(i in $.jstree.plugins) {
25524 if($.jstree.plugins.hasOwnProperty(i) && this.attributes[i]) {
25525 c.plugins.push(i);
25526 if(this.getAttribute(i) && JSON.parse(this.getAttribute(i))) {
25527 c[i] = JSON.parse(this.getAttribute(i));
25528 }
25529 }
25530 }
25531 for(i in $.jstree.defaults.core) {
25532 if($.jstree.defaults.core.hasOwnProperty(i) && this.attributes[i]) {
25533 c.core[i] = JSON.parse(this.getAttribute(i)) || this.getAttribute(i);
25534 }
25535 }
25536 jQuery(this).jstree(c);
25537 };
25538 // proto.attributeChangedCallback = function (name, previous, value) { };
25539 try {
25540 document.registerElement("vakata-jstree", { prototype: proto });
25541 } catch(ignore) { }
25542 }
25543 }(jQuery));
25544 }));
25545 /*!
18307 25546
18308 JSZip - A Javascript class for generating and reading zip files 25547 JSZip - A Javascript class for generating and reading zip files
18309 <http://stuartk.com/jszip> 25548 <http://stuartk.com/jszip>
18310 25549
18311 (c) 2009-2012 Stuart Knightley <stuart [at] stuartk.com> 25550 (c) 2009-2014 Stuart Knightley <stuart [at] stuartk.com>
18312 Dual licenced under the MIT license or GPLv3. See LICENSE.markdown. 25551 Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/master/LICENSE.markdown.
18313 25552
18314 Usage: 25553 JSZip uses the library pako released under the MIT license :
18315 zip = new JSZip(); 25554 https://github.com/nodeca/pako/blob/master/LICENSE
18316 zip.file("hello.txt", "Hello, World!").add("tempfile", "nothing"); 25555 */
18317 zip.folder("images").file("smile.gif", base64Data, {base64: true}); 25556 !function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;"undefined"!=typeof window?b=window:"undefined"!=typeof global?b=global:"undefined"!=typeof self&&(b=self),b.JSZip=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b,c){"use strict";var d="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";c.encode=function(a){for(var b,c,e,f,g,h,i,j="",k=0;k<a.length;)b=a.charCodeAt(k++),c=a.charCodeAt(k++),e=a.charCodeAt(k++),f=b>>2,g=(3&b)<<4|c>>4,h=(15&c)<<2|e>>6,i=63&e,isNaN(c)?h=i=64:isNaN(e)&&(i=64),j=j+d.charAt(f)+d.charAt(g)+d.charAt(h)+d.charAt(i);return j},c.decode=function(a){var b,c,e,f,g,h,i,j="",k=0;for(a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");k<a.length;)f=d.indexOf(a.charAt(k++)),g=d.indexOf(a.charAt(k++)),h=d.indexOf(a.charAt(k++)),i=d.indexOf(a.charAt(k++)),b=f<<2|g>>4,c=(15&g)<<4|h>>2,e=(3&h)<<6|i,j+=String.fromCharCode(b),64!=h&&(j+=String.fromCharCode(c)),64!=i&&(j+=String.fromCharCode(e));return j}},{}],2:[function(a,b){"use strict";function c(){this.compressedSize=0,this.uncompressedSize=0,this.crc32=0,this.compressionMethod=null,this.compressedContent=null}c.prototype={getContent:function(){return null},getCompressedContent:function(){return null}},b.exports=c},{}],3:[function(a,b,c){"use strict";c.STORE={magic:"\x00\x00",compress:function(a){return a},uncompress:function(a){return a},compressInputType:null,uncompressInputType:null},c.DEFLATE=a("./flate")},{"./flate":8}],4:[function(a,b){"use strict";var c=a("./utils"),d=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117];b.exports=function(a,b){if("undefined"==typeof a||!a.length)return 0;var e="string"!==c.getTypeOf(a);"undefined"==typeof b&&(b=0);var f=0,g=0,h=0;b=-1^b;for(var i=0,j=a.length;j>i;i++)h=e?a[i]:a.charCodeAt(i),g=255&(b^h),f=d[g],b=b>>>8^f;return-1^b}},{"./utils":21}],5:[function(a,b){"use strict";function c(){this.data=null,this.length=0,this.index=0}var d=a("./utils");c.prototype={checkOffset:function(a){this.checkIndex(this.index+a)},checkIndex:function(a){if(this.length<a||0>a)throw new Error("End of data reached (data length = "+this.length+", asked index = "+a+"). Corrupted zip ?")},setIndex:function(a){this.checkIndex(a),this.index=a},skip:function(a){this.setIndex(this.index+a)},byteAt:function(){},readInt:function(a){var b,c=0;for(this.checkOffset(a),b=this.index+a-1;b>=this.index;b--)c=(c<<8)+this.byteAt(b);return this.index+=a,c},readString:function(a){return d.transformTo("string",this.readData(a))},readData:function(){},lastIndexOfSignature:function(){},readDate:function(){var a=this.readInt(4);return new Date((a>>25&127)+1980,(a>>21&15)-1,a>>16&31,a>>11&31,a>>5&63,(31&a)<<1)}},b.exports=c},{"./utils":21}],6:[function(a,b,c){"use strict";c.base64=!1,c.binary=!1,c.dir=!1,c.createFolders=!1,c.date=null,c.compression=null,c.comment=null},{}],7:[function(a,b,c){"use strict";var d=a("./utils");c.string2binary=function(a){return d.string2binary(a)},c.string2Uint8Array=function(a){return d.transformTo("uint8array",a)},c.uint8Array2String=function(a){return d.transformTo("string",a)},c.string2Blob=function(a){var b=d.transformTo("arraybuffer",a);return d.arrayBuffer2Blob(b)},c.arrayBuffer2Blob=function(a){return d.arrayBuffer2Blob(a)},c.transformTo=function(a,b){return d.transformTo(a,b)},c.getTypeOf=function(a){return d.getTypeOf(a)},c.checkSupport=function(a){return d.checkSupport(a)},c.MAX_VALUE_16BITS=d.MAX_VALUE_16BITS,c.MAX_VALUE_32BITS=d.MAX_VALUE_32BITS,c.pretty=function(a){return d.pretty(a)},c.findCompression=function(a){return d.findCompression(a)},c.isRegExp=function(a){return d.isRegExp(a)}},{"./utils":21}],8:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array,e=a("pako");c.uncompressInputType=d?"uint8array":"array",c.compressInputType=d?"uint8array":"array",c.magic="\b\x00",c.compress=function(a){return e.deflateRaw(a)},c.uncompress=function(a){return e.inflateRaw(a)}},{pako:24}],9:[function(a,b){"use strict";function c(a,b){return this instanceof c?(this.files={},this.comment=null,this.root="",a&&this.load(a,b),void(this.clone=function(){var a=new c;for(var b in this)"function"!=typeof this[b]&&(a[b]=this[b]);return a})):new c(a,b)}var d=a("./base64");c.prototype=a("./object"),c.prototype.load=a("./load"),c.support=a("./support"),c.defaults=a("./defaults"),c.utils=a("./deprecatedPublicUtils"),c.base64={encode:function(a){return d.encode(a)},decode:function(a){return d.decode(a)}},c.compressions=a("./compressions"),b.exports=c},{"./base64":1,"./compressions":3,"./defaults":6,"./deprecatedPublicUtils":7,"./load":10,"./object":13,"./support":17}],10:[function(a,b){"use strict";var c=a("./base64"),d=a("./zipEntries");b.exports=function(a,b){var e,f,g,h;for(b=b||{},b.base64&&(a=c.decode(a)),f=new d(a,b),e=f.files,g=0;g<e.length;g++)h=e[g],this.file(h.fileName,h.decompressed,{binary:!0,optimizedBinaryString:!0,date:h.date,dir:h.dir,comment:h.fileComment.length?h.fileComment:null,createFolders:b.createFolders});return f.zipComment.length&&(this.comment=f.zipComment),this}},{"./base64":1,"./zipEntries":22}],11:[function(a,b){(function(a){"use strict";b.exports=function(b,c){return new a(b,c)},b.exports.test=function(b){return a.isBuffer(b)}}).call(this,"undefined"!=typeof Buffer?Buffer:void 0)},{}],12:[function(a,b){"use strict";function c(a){this.data=a,this.length=this.data.length,this.index=0}var d=a("./uint8ArrayReader");c.prototype=new d,c.prototype.readData=function(a){this.checkOffset(a);var b=this.data.slice(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./uint8ArrayReader":18}],13:[function(a,b){"use strict";var c=a("./support"),d=a("./utils"),e=a("./crc32"),f=a("./signature"),g=a("./defaults"),h=a("./base64"),i=a("./compressions"),j=a("./compressedObject"),k=a("./nodeBuffer"),l=a("./utf8"),m=a("./stringWriter"),n=a("./uint8ArrayWriter"),o=function(a){if(a._data instanceof j&&(a._data=a._data.getContent(),a.options.binary=!0,a.options.base64=!1,"uint8array"===d.getTypeOf(a._data))){var b=a._data;a._data=new Uint8Array(b.length),0!==b.length&&a._data.set(b,0)}return a._data},p=function(a){var b=o(a),e=d.getTypeOf(b);return"string"===e?!a.options.binary&&c.nodebuffer?k(b,"utf-8"):a.asBinary():b},q=function(a){var b=o(this);return null===b||"undefined"==typeof b?"":(this.options.base64&&(b=h.decode(b)),b=a&&this.options.binary?A.utf8decode(b):d.transformTo("string",b),a||this.options.binary||(b=d.transformTo("string",A.utf8encode(b))),b)},r=function(a,b,c){this.name=a,this.dir=c.dir,this.date=c.date,this.comment=c.comment,this._data=b,this.options=c,this._initialMetadata={dir:c.dir,date:c.date}};r.prototype={asText:function(){return q.call(this,!0)},asBinary:function(){return q.call(this,!1)},asNodeBuffer:function(){var a=p(this);return d.transformTo("nodebuffer",a)},asUint8Array:function(){var a=p(this);return d.transformTo("uint8array",a)},asArrayBuffer:function(){return this.asUint8Array().buffer}};var s=function(a,b){var c,d="";for(c=0;b>c;c++)d+=String.fromCharCode(255&a),a>>>=8;return d},t=function(){var a,b,c={};for(a=0;a<arguments.length;a++)for(b in arguments[a])arguments[a].hasOwnProperty(b)&&"undefined"==typeof c[b]&&(c[b]=arguments[a][b]);return c},u=function(a){return a=a||{},a.base64!==!0||null!==a.binary&&void 0!==a.binary||(a.binary=!0),a=t(a,g),a.date=a.date||new Date,null!==a.compression&&(a.compression=a.compression.toUpperCase()),a},v=function(a,b,c){var e,f=d.getTypeOf(b);if(c=u(c),c.createFolders&&(e=w(a))&&x.call(this,e,!0),c.dir||null===b||"undefined"==typeof b)c.base64=!1,c.binary=!1,b=null;else if("string"===f)c.binary&&!c.base64&&c.optimizedBinaryString!==!0&&(b=d.string2binary(b));else{if(c.base64=!1,c.binary=!0,!(f||b instanceof j))throw new Error("The data of '"+a+"' is in an unsupported format !");"arraybuffer"===f&&(b=d.transformTo("uint8array",b))}var g=new r(a,b,c);return this.files[a]=g,g},w=function(a){"/"==a.slice(-1)&&(a=a.substring(0,a.length-1));var b=a.lastIndexOf("/");return b>0?a.substring(0,b):""},x=function(a,b){return"/"!=a.slice(-1)&&(a+="/"),b="undefined"!=typeof b?b:!1,this.files[a]||v.call(this,a,null,{dir:!0,createFolders:b}),this.files[a]},y=function(a,b){var c,f=new j;return a._data instanceof j?(f.uncompressedSize=a._data.uncompressedSize,f.crc32=a._data.crc32,0===f.uncompressedSize||a.dir?(b=i.STORE,f.compressedContent="",f.crc32=0):a._data.compressionMethod===b.magic?f.compressedContent=a._data.getCompressedContent():(c=a._data.getContent(),f.compressedContent=b.compress(d.transformTo(b.compressInputType,c)))):(c=p(a),(!c||0===c.length||a.dir)&&(b=i.STORE,c=""),f.uncompressedSize=c.length,f.crc32=e(c),f.compressedContent=b.compress(d.transformTo(b.compressInputType,c))),f.compressedSize=f.compressedContent.length,f.compressionMethod=b.magic,f},z=function(a,b,c,g){var h,i,j,k,m=(c.compressedContent,d.transformTo("string",l.utf8encode(b.name))),n=b.comment||"",o=d.transformTo("string",l.utf8encode(n)),p=m.length!==b.name.length,q=o.length!==n.length,r=b.options,t="",u="",v="";j=b._initialMetadata.dir!==b.dir?b.dir:r.dir,k=b._initialMetadata.date!==b.date?b.date:r.date,h=k.getHours(),h<<=6,h|=k.getMinutes(),h<<=5,h|=k.getSeconds()/2,i=k.getFullYear()-1980,i<<=4,i|=k.getMonth()+1,i<<=5,i|=k.getDate(),p&&(u=s(1,1)+s(e(m),4)+m,t+="up"+s(u.length,2)+u),q&&(v=s(1,1)+s(this.crc32(o),4)+o,t+="uc"+s(v.length,2)+v);var w="";w+="\n\x00",w+=p||q?"\x00\b":"\x00\x00",w+=c.compressionMethod,w+=s(h,2),w+=s(i,2),w+=s(c.crc32,4),w+=s(c.compressedSize,4),w+=s(c.uncompressedSize,4),w+=s(m.length,2),w+=s(t.length,2);var x=f.LOCAL_FILE_HEADER+w+m+t,y=f.CENTRAL_FILE_HEADER+"\x00"+w+s(o.length,2)+"\x00\x00\x00\x00"+(j===!0?"\x00\x00\x00":"\x00\x00\x00\x00")+s(g,4)+m+t+o;return{fileRecord:x,dirRecord:y,compressedObject:c}},A={load:function(){throw new Error("Load method is not defined. Is the file jszip-load.js included ?")},filter:function(a){var b,c,d,e,f=[];for(b in this.files)this.files.hasOwnProperty(b)&&(d=this.files[b],e=new r(d.name,d._data,t(d.options)),c=b.slice(this.root.length,b.length),b.slice(0,this.root.length)===this.root&&a(c,e)&&f.push(e));return f},file:function(a,b,c){if(1===arguments.length){if(d.isRegExp(a)){var e=a;return this.filter(function(a,b){return!b.dir&&e.test(a)})}return this.filter(function(b,c){return!c.dir&&b===a})[0]||null}return a=this.root+a,v.call(this,a,b,c),this},folder:function(a){if(!a)return this;if(d.isRegExp(a))return this.filter(function(b,c){return c.dir&&a.test(b)});var b=this.root+a,c=x.call(this,b),e=this.clone();return e.root=c.name,e},remove:function(a){a=this.root+a;var b=this.files[a];if(b||("/"!=a.slice(-1)&&(a+="/"),b=this.files[a]),b&&!b.dir)delete this.files[a];else for(var c=this.filter(function(b,c){return c.name.slice(0,a.length)===a}),d=0;d<c.length;d++)delete this.files[c[d].name];return this},generate:function(a){a=t(a||{},{base64:!0,compression:"STORE",type:"base64",comment:null}),d.checkSupport(a.type);var b,c,e=[],g=0,j=0,k=d.transformTo("string",this.utf8encode(a.comment||this.comment||""));for(var l in this.files)if(this.files.hasOwnProperty(l)){var o=this.files[l],p=o.options.compression||a.compression.toUpperCase(),q=i[p];if(!q)throw new Error(p+" is not a valid compression method !");var r=y.call(this,o,q),u=z.call(this,l,o,r,g);g+=u.fileRecord.length+r.compressedSize,j+=u.dirRecord.length,e.push(u)}var v="";v=f.CENTRAL_DIRECTORY_END+"\x00\x00\x00\x00"+s(e.length,2)+s(e.length,2)+s(j,4)+s(g,4)+s(k.length,2)+k;var w=a.type.toLowerCase();for(b="uint8array"===w||"arraybuffer"===w||"blob"===w||"nodebuffer"===w?new n(g+j+v.length):new m(g+j+v.length),c=0;c<e.length;c++)b.append(e[c].fileRecord),b.append(e[c].compressedObject.compressedContent);for(c=0;c<e.length;c++)b.append(e[c].dirRecord);b.append(v);var x=b.finalize();switch(a.type.toLowerCase()){case"uint8array":case"arraybuffer":case"nodebuffer":return d.transformTo(a.type.toLowerCase(),x);case"blob":return d.arrayBuffer2Blob(d.transformTo("arraybuffer",x));case"base64":return a.base64?h.encode(x):x;default:return x}},crc32:function(a,b){return e(a,b)},utf8encode:function(a){return d.transformTo("string",l.utf8encode(a))},utf8decode:function(a){return l.utf8decode(a)}};b.exports=A},{"./base64":1,"./compressedObject":2,"./compressions":3,"./crc32":4,"./defaults":6,"./nodeBuffer":11,"./signature":14,"./stringWriter":16,"./support":17,"./uint8ArrayWriter":19,"./utf8":20,"./utils":21}],14:[function(a,b,c){"use strict";c.LOCAL_FILE_HEADER="PK",c.CENTRAL_FILE_HEADER="PK",c.CENTRAL_DIRECTORY_END="PK",c.ZIP64_CENTRAL_DIRECTORY_LOCATOR="PK",c.ZIP64_CENTRAL_DIRECTORY_END="PK",c.DATA_DESCRIPTOR="PK\b"},{}],15:[function(a,b){"use strict";function c(a,b){this.data=a,b||(this.data=e.string2binary(this.data)),this.length=this.data.length,this.index=0}var d=a("./dataReader"),e=a("./utils");c.prototype=new d,c.prototype.byteAt=function(a){return this.data.charCodeAt(a)},c.prototype.lastIndexOfSignature=function(a){return this.data.lastIndexOf(a)},c.prototype.readData=function(a){this.checkOffset(a);var b=this.data.slice(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./dataReader":5,"./utils":21}],16:[function(a,b){"use strict";var c=a("./utils"),d=function(){this.data=[]};d.prototype={append:function(a){a=c.transformTo("string",a),this.data.push(a)},finalize:function(){return this.data.join("")}},b.exports=d},{"./utils":21}],17:[function(a,b,c){(function(a){"use strict";if(c.base64=!0,c.array=!0,c.string=!0,c.arraybuffer="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array,c.nodebuffer="undefined"!=typeof a,c.uint8array="undefined"!=typeof Uint8Array,"undefined"==typeof ArrayBuffer)c.blob=!1;else{var b=new ArrayBuffer(0);try{c.blob=0===new Blob([b],{type:"application/zip"}).size}catch(d){try{var e=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,f=new e;f.append(b),c.blob=0===f.getBlob("application/zip").size}catch(d){c.blob=!1}}}}).call(this,"undefined"!=typeof Buffer?Buffer:void 0)},{}],18:[function(a,b){"use strict";function c(a){a&&(this.data=a,this.length=this.data.length,this.index=0)}var d=a("./dataReader");c.prototype=new d,c.prototype.byteAt=function(a){return this.data[a]},c.prototype.lastIndexOfSignature=function(a){for(var b=a.charCodeAt(0),c=a.charCodeAt(1),d=a.charCodeAt(2),e=a.charCodeAt(3),f=this.length-4;f>=0;--f)if(this.data[f]===b&&this.data[f+1]===c&&this.data[f+2]===d&&this.data[f+3]===e)return f;return-1},c.prototype.readData=function(a){if(this.checkOffset(a),0===a)return new Uint8Array(0);var b=this.data.subarray(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./dataReader":5}],19:[function(a,b){"use strict";var c=a("./utils"),d=function(a){this.data=new Uint8Array(a),this.index=0};d.prototype={append:function(a){0!==a.length&&(a=c.transformTo("uint8array",a),this.data.set(a,this.index),this.index+=a.length)},finalize:function(){return this.data}},b.exports=d},{"./utils":21}],20:[function(a,b,c){"use strict";for(var d=a("./utils"),e=a("./support"),f=a("./nodeBuffer"),g=new Array(256),h=0;256>h;h++)g[h]=h>=252?6:h>=248?5:h>=240?4:h>=224?3:h>=192?2:1;g[254]=g[254]=1;var i=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;h>f;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=128>c?1:2048>c?2:65536>c?3:4;for(b=e.uint8array?new Uint8Array(i):new Array(i),g=0,f=0;i>g;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),128>c?b[g++]=c:2048>c?(b[g++]=192|c>>>6,b[g++]=128|63&c):65536>c?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},j=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return 0>c?b:0===c?b:c+g[a[c]]>b?c:b},k=function(a){var b,c,e,f,h=a.length,i=new Array(2*h);for(c=0,b=0;h>b;)if(e=a[b++],128>e)i[c++]=e;else if(f=g[e],f>4)i[c++]=65533,b+=f-1;else{for(e&=2===f?31:3===f?15:7;f>1&&h>b;)e=e<<6|63&a[b++],f--;f>1?i[c++]=65533:65536>e?i[c++]=e:(e-=65536,i[c++]=55296|e>>10&1023,i[c++]=56320|1023&e)}return i.length!==c&&(i.subarray?i=i.subarray(0,c):i.length=c),d.applyFromCharCode(i)};c.utf8encode=function(a){return e.nodebuffer?f(a,"utf-8"):i(a)},c.utf8decode=function(a){if(e.nodebuffer)return d.transformTo("nodebuffer",a).toString("utf-8");a=d.transformTo(e.uint8array?"uint8array":"array",a);for(var b=[],c=0,f=a.length,g=65536;f>c;){var h=j(a,Math.min(c+g,f));b.push(e.uint8array?k(a.subarray(c,h)):k(a.slice(c,h))),c=h}return b.join("")}},{"./nodeBuffer":11,"./support":17,"./utils":21}],21:[function(a,b,c){"use strict";function d(a){return a}function e(a,b){for(var c=0;c<a.length;++c)b[c]=255&a.charCodeAt(c);return b}function f(a){var b=65536,d=[],e=a.length,f=c.getTypeOf(a),g=0,h=!0;try{switch(f){case"uint8array":String.fromCharCode.apply(null,new Uint8Array(0));break;case"nodebuffer":String.fromCharCode.apply(null,j(0))}}catch(i){h=!1}if(!h){for(var k="",l=0;l<a.length;l++)k+=String.fromCharCode(a[l]);return k}for(;e>g&&b>1;)try{d.push("array"===f||"nodebuffer"===f?String.fromCharCode.apply(null,a.slice(g,Math.min(g+b,e))):String.fromCharCode.apply(null,a.subarray(g,Math.min(g+b,e)))),g+=b}catch(i){b=Math.floor(b/2)}return d.join("")}function g(a,b){for(var c=0;c<a.length;c++)b[c]=a[c];return b}var h=a("./support"),i=a("./compressions"),j=a("./nodeBuffer");c.string2binary=function(a){for(var b="",c=0;c<a.length;c++)b+=String.fromCharCode(255&a.charCodeAt(c));return b},c.arrayBuffer2Blob=function(a){c.checkSupport("blob");try{return new Blob([a],{type:"application/zip"})}catch(b){try{var d=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,e=new d;return e.append(a),e.getBlob("application/zip")}catch(b){throw new Error("Bug : can't construct the Blob.")}}},c.applyFromCharCode=f;var k={};k.string={string:d,array:function(a){return e(a,new Array(a.length))},arraybuffer:function(a){return k.string.uint8array(a).buffer},uint8array:function(a){return e(a,new Uint8Array(a.length))},nodebuffer:function(a){return e(a,j(a.length))}},k.array={string:f,array:d,arraybuffer:function(a){return new Uint8Array(a).buffer},uint8array:function(a){return new Uint8Array(a)},nodebuffer:function(a){return j(a)}},k.arraybuffer={string:function(a){return f(new Uint8Array(a))},array:function(a){return g(new Uint8Array(a),new Array(a.byteLength))},arraybuffer:d,uint8array:function(a){return new Uint8Array(a)},nodebuffer:function(a){return j(new Uint8Array(a))}},k.uint8array={string:f,array:function(a){return g(a,new Array(a.length))},arraybuffer:function(a){return a.buffer},uint8array:d,nodebuffer:function(a){return j(a)}},k.nodebuffer={string:f,array:function(a){return g(a,new Array(a.length))},arraybuffer:function(a){return k.nodebuffer.uint8array(a).buffer},uint8array:function(a){return g(a,new Uint8Array(a.length))},nodebuffer:d},c.transformTo=function(a,b){if(b||(b=""),!a)return b;c.checkSupport(a);var d=c.getTypeOf(b),e=k[d][a](b);return e},c.getTypeOf=function(a){return"string"==typeof a?"string":"[object Array]"===Object.prototype.toString.call(a)?"array":h.nodebuffer&&j.test(a)?"nodebuffer":h.uint8array&&a instanceof Uint8Array?"uint8array":h.arraybuffer&&a instanceof ArrayBuffer?"arraybuffer":void 0},c.checkSupport=function(a){var b=h[a.toLowerCase()];if(!b)throw new Error(a+" is not supported by this browser")},c.MAX_VALUE_16BITS=65535,c.MAX_VALUE_32BITS=-1,c.pretty=function(a){var b,c,d="";for(c=0;c<(a||"").length;c++)b=a.charCodeAt(c),d+="\\x"+(16>b?"0":"")+b.toString(16).toUpperCase();return d},c.findCompression=function(a){for(var b in i)if(i.hasOwnProperty(b)&&i[b].magic===a)return i[b];return null},c.isRegExp=function(a){return"[object RegExp]"===Object.prototype.toString.call(a)}},{"./compressions":3,"./nodeBuffer":11,"./support":17}],22:[function(a,b){"use strict";function c(a,b){this.files=[],this.loadOptions=b,a&&this.load(a)}var d=a("./stringReader"),e=a("./nodeBufferReader"),f=a("./uint8ArrayReader"),g=a("./utils"),h=a("./signature"),i=a("./zipEntry"),j=a("./support"),k=a("./object");c.prototype={checkSignature:function(a){var b=this.reader.readString(4);if(b!==a)throw new Error("Corrupted zip or bug : unexpected signature ("+g.pretty(b)+", expected "+g.pretty(a)+")")},readBlockEndOfCentral:function(){this.diskNumber=this.reader.readInt(2),this.diskWithCentralDirStart=this.reader.readInt(2),this.centralDirRecordsOnThisDisk=this.reader.readInt(2),this.centralDirRecords=this.reader.readInt(2),this.centralDirSize=this.reader.readInt(4),this.centralDirOffset=this.reader.readInt(4),this.zipCommentLength=this.reader.readInt(2),this.zipComment=this.reader.readString(this.zipCommentLength),this.zipComment=k.utf8decode(this.zipComment)},readBlockZip64EndOfCentral:function(){this.zip64EndOfCentralSize=this.reader.readInt(8),this.versionMadeBy=this.reader.readString(2),this.versionNeeded=this.reader.readInt(2),this.diskNumber=this.reader.readInt(4),this.diskWithCentralDirStart=this.reader.readInt(4),this.centralDirRecordsOnThisDisk=this.reader.readInt(8),this.centralDirRecords=this.reader.readInt(8),this.centralDirSize=this.reader.readInt(8),this.centralDirOffset=this.reader.readInt(8),this.zip64ExtensibleData={};for(var a,b,c,d=this.zip64EndOfCentralSize-44,e=0;d>e;)a=this.reader.readInt(2),b=this.reader.readInt(4),c=this.reader.readString(b),this.zip64ExtensibleData[a]={id:a,length:b,value:c}},readBlockZip64EndOfCentralLocator:function(){if(this.diskWithZip64CentralDirStart=this.reader.readInt(4),this.relativeOffsetEndOfZip64CentralDir=this.reader.readInt(8),this.disksCount=this.reader.readInt(4),this.disksCount>1)throw new Error("Multi-volumes zip are not supported")},readLocalFiles:function(){var a,b;for(a=0;a<this.files.length;a++)b=this.files[a],this.reader.setIndex(b.localHeaderOffset),this.checkSignature(h.LOCAL_FILE_HEADER),b.readLocalPart(this.reader),b.handleUTF8()},readCentralDir:function(){var a;for(this.reader.setIndex(this.centralDirOffset);this.reader.readString(4)===h.CENTRAL_FILE_HEADER;)a=new i({zip64:this.zip64},this.loadOptions),a.readCentralPart(this.reader),this.files.push(a)},readEndOfCentral:function(){var a=this.reader.lastIndexOfSignature(h.CENTRAL_DIRECTORY_END);if(-1===a)throw new Error("Corrupted zip : can't find end of central directory");if(this.reader.setIndex(a),this.checkSignature(h.CENTRAL_DIRECTORY_END),this.readBlockEndOfCentral(),this.diskNumber===g.MAX_VALUE_16BITS||this.diskWithCentralDirStart===g.MAX_VALUE_16BITS||this.centralDirRecordsOnThisDisk===g.MAX_VALUE_16BITS||this.centralDirRecords===g.MAX_VALUE_16BITS||this.centralDirSize===g.MAX_VALUE_32BITS||this.centralDirOffset===g.MAX_VALUE_32BITS){if(this.zip64=!0,a=this.reader.lastIndexOfSignature(h.ZIP64_CENTRAL_DIRECTORY_LOCATOR),-1===a)throw new Error("Corrupted zip : can't find the ZIP64 end of central directory locator");this.reader.setIndex(a),this.checkSignature(h.ZIP64_CENTRAL_DIRECTORY_LOCATOR),this.readBlockZip64EndOfCentralLocator(),this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir),this.checkSignature(h.ZIP64_CENTRAL_DIRECTORY_END),this.readBlockZip64EndOfCentral()}},prepareReader:function(a){var b=g.getTypeOf(a);this.reader="string"!==b||j.uint8array?"nodebuffer"===b?new e(a):new f(g.transformTo("uint8array",a)):new d(a,this.loadOptions.optimizedBinaryString)},load:function(a){this.prepareReader(a),this.readEndOfCentral(),this.readCentralDir(),this.readLocalFiles()}},b.exports=c},{"./nodeBufferReader":12,"./object":13,"./signature":14,"./stringReader":15,"./support":17,"./uint8ArrayReader":18,"./utils":21,"./zipEntry":23}],23:[function(a,b){"use strict";function c(a,b){this.options=a,this.loadOptions=b}var d=a("./stringReader"),e=a("./utils"),f=a("./compressedObject"),g=a("./object");c.prototype={isEncrypted:function(){return 1===(1&this.bitFlag)},useUTF8:function(){return 2048===(2048&this.bitFlag)},prepareCompressedContent:function(a,b,c){return function(){var d=a.index;a.setIndex(b);var e=a.readData(c);return a.setIndex(d),e}},prepareContent:function(a,b,c,d,f){return function(){var a=e.transformTo(d.uncompressInputType,this.getCompressedContent()),b=d.uncompress(a);if(b.length!==f)throw new Error("Bug : uncompressed data size mismatch");return b}},readLocalPart:function(a){var b,c;if(a.skip(22),this.fileNameLength=a.readInt(2),c=a.readInt(2),this.fileName=a.readString(this.fileNameLength),a.skip(c),-1==this.compressedSize||-1==this.uncompressedSize)throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory (compressedSize == -1 || uncompressedSize == -1)");if(b=e.findCompression(this.compressionMethod),null===b)throw new Error("Corrupted zip : compression "+e.pretty(this.compressionMethod)+" unknown (inner file : "+this.fileName+")");if(this.decompressed=new f,this.decompressed.compressedSize=this.compressedSize,this.decompressed.uncompressedSize=this.uncompressedSize,this.decompressed.crc32=this.crc32,this.decompressed.compressionMethod=this.compressionMethod,this.decompressed.getCompressedContent=this.prepareCompressedContent(a,a.index,this.compressedSize,b),this.decompressed.getContent=this.prepareContent(a,a.index,this.compressedSize,b,this.uncompressedSize),this.loadOptions.checkCRC32&&(this.decompressed=e.transformTo("string",this.decompressed.getContent()),g.crc32(this.decompressed)!==this.crc32))throw new Error("Corrupted zip : CRC32 mismatch")},readCentralPart:function(a){if(this.versionMadeBy=a.readString(2),this.versionNeeded=a.readInt(2),this.bitFlag=a.readInt(2),this.compressionMethod=a.readString(2),this.date=a.readDate(),this.crc32=a.readInt(4),this.compressedSize=a.readInt(4),this.uncompressedSize=a.readInt(4),this.fileNameLength=a.readInt(2),this.extraFieldsLength=a.readInt(2),this.fileCommentLength=a.readInt(2),this.diskNumberStart=a.readInt(2),this.internalFileAttributes=a.readInt(2),this.externalFileAttributes=a.readInt(4),this.localHeaderOffset=a.readInt(4),this.isEncrypted())throw new Error("Encrypted zip are not supported");this.fileName=a.readString(this.fileNameLength),this.readExtraFields(a),this.parseZIP64ExtraField(a),this.fileComment=a.readString(this.fileCommentLength),this.dir=16&this.externalFileAttributes?!0:!1},parseZIP64ExtraField:function(){if(this.extraFields[1]){var a=new d(this.extraFields[1].value);this.uncompressedSize===e.MAX_VALUE_32BITS&&(this.uncompressedSize=a.readInt(8)),this.compressedSize===e.MAX_VALUE_32BITS&&(this.compressedSize=a.readInt(8)),this.localHeaderOffset===e.MAX_VALUE_32BITS&&(this.localHeaderOffset=a.readInt(8)),this.diskNumberStart===e.MAX_VALUE_32BITS&&(this.diskNumberStart=a.readInt(4))}},readExtraFields:function(a){var b,c,d,e=a.index;for(this.extraFields=this.extraFields||{};a.index<e+this.extraFieldsLength;)b=a.readInt(2),c=a.readInt(2),d=a.readString(c),this.extraFields[b]={id:b,length:c,value:d}},handleUTF8:function(){if(this.useUTF8())this.fileName=g.utf8decode(this.fileName),this.fileComment=g.utf8decode(this.fileComment);else{var a=this.findExtraFieldUnicodePath();null!==a&&(this.fileName=a);var b=this.findExtraFieldUnicodeComment();null!==b&&(this.fileComment=b)}},findExtraFieldUnicodePath:function(){var a=this.extraFields[28789];if(a){var b=new d(a.value);return 1!==b.readInt(1)?null:g.crc32(this.fileName)!==b.readInt(4)?null:g.utf8decode(b.readString(a.length-5))}return null},findExtraFieldUnicodeComment:function(){var a=this.extraFields[25461];if(a){var b=new d(a.value);return 1!==b.readInt(1)?null:g.crc32(this.fileComment)!==b.readInt(4)?null:g.utf8decode(b.readString(a.length-5))}return null}},b.exports=c},{"./compressedObject":2,"./object":13,"./stringReader":15,"./utils":21}],24:[function(a,b){"use strict";var c=a("./lib/utils/common").assign,d=a("./lib/deflate"),e=a("./lib/inflate"),f=a("./lib/zlib/constants"),g={};c(g,d,e,f),b.exports=g},{"./lib/deflate":25,"./lib/inflate":26,"./lib/utils/common":27,"./lib/zlib/constants":30}],25:[function(a,b,c){"use strict";function d(a,b){var c=new s(b);if(c.push(a,!0),c.err)throw c.msg;return c.result}function e(a,b){return b=b||{},b.raw=!0,d(a,b)}function f(a,b){return b=b||{},b.gzip=!0,d(a,b)}var g=a("./zlib/deflate.js"),h=a("./utils/common"),i=a("./utils/strings"),j=a("./zlib/messages"),k=a("./zlib/zstream"),l=0,m=4,n=0,o=1,p=-1,q=0,r=8,s=function(a){this.options=h.assign({level:p,method:r,chunkSize:16384,windowBits:15,memLevel:8,strategy:q,to:""},a||{});var b=this.options;b.raw&&b.windowBits>0?b.windowBits=-b.windowBits:b.gzip&&b.windowBits>0&&b.windowBits<16&&(b.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new k,this.strm.avail_out=0;var c=g.deflateInit2(this.strm,b.level,b.method,b.windowBits,b.memLevel,b.strategy);if(c!==n)throw new Error(j[c]);b.header&&g.deflateSetHeader(this.strm,b.header)
18318 zip.file("Xmas.txt", "Ho ho ho !", {date : new Date("December 25, 2007 00:00:01")}); 25557 };s.prototype.push=function(a,b){var c,d,e=this.strm,f=this.options.chunkSize;if(this.ended)return!1;d=b===~~b?b:b===!0?m:l,e.input="string"==typeof a?i.string2buf(a):a,e.next_in=0,e.avail_in=e.input.length;do{if(0===e.avail_out&&(e.output=new h.Buf8(f),e.next_out=0,e.avail_out=f),c=g.deflate(e,d),c!==o&&c!==n)return this.onEnd(c),this.ended=!0,!1;(0===e.avail_out||0===e.avail_in&&d===m)&&this.onData("string"===this.options.to?i.buf2binstring(h.shrinkBuf(e.output,e.next_out)):h.shrinkBuf(e.output,e.next_out))}while((e.avail_in>0||0===e.avail_out)&&c!==o);return d===m?(c=g.deflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===n):!0},s.prototype.onData=function(a){this.chunks.push(a)},s.prototype.onEnd=function(a){a===n&&(this.result="string"===this.options.to?this.chunks.join(""):h.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Deflate=s,c.deflate=d,c.deflateRaw=e,c.gzip=f},{"./utils/common":27,"./utils/strings":28,"./zlib/deflate.js":32,"./zlib/messages":37,"./zlib/zstream":39}],26:[function(a,b,c){"use strict";function d(a,b){var c=new m(b);if(c.push(a,!0),c.err)throw c.msg;return c.result}function e(a,b){return b=b||{},b.raw=!0,d(a,b)}var f=a("./zlib/inflate.js"),g=a("./utils/common"),h=a("./utils/strings"),i=a("./zlib/constants"),j=a("./zlib/messages"),k=a("./zlib/zstream"),l=a("./zlib/gzheader"),m=function(a){this.options=g.assign({chunkSize:16384,windowBits:0,to:""},a||{});var b=this.options;b.raw&&b.windowBits>=0&&b.windowBits<16&&(b.windowBits=-b.windowBits,0===b.windowBits&&(b.windowBits=-15)),!(b.windowBits>=0&&b.windowBits<16)||a&&a.windowBits||(b.windowBits+=32),b.windowBits>15&&b.windowBits<48&&0===(15&b.windowBits)&&(b.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new k,this.strm.avail_out=0;var c=f.inflateInit2(this.strm,b.windowBits);if(c!==i.Z_OK)throw new Error(j[c]);this.header=new l,f.inflateGetHeader(this.strm,this.header)};m.prototype.push=function(a,b){var c,d,e,j,k,l=this.strm,m=this.options.chunkSize;if(this.ended)return!1;d=b===~~b?b:b===!0?i.Z_FINISH:i.Z_NO_FLUSH,l.input="string"==typeof a?h.binstring2buf(a):a,l.next_in=0,l.avail_in=l.input.length;do{if(0===l.avail_out&&(l.output=new g.Buf8(m),l.next_out=0,l.avail_out=m),c=f.inflate(l,i.Z_NO_FLUSH),c!==i.Z_STREAM_END&&c!==i.Z_OK)return this.onEnd(c),this.ended=!0,!1;l.next_out&&(0===l.avail_out||c===i.Z_STREAM_END||0===l.avail_in&&d===i.Z_FINISH)&&("string"===this.options.to?(e=h.utf8border(l.output,l.next_out),j=l.next_out-e,k=h.buf2string(l.output,e),l.next_out=j,l.avail_out=m-j,j&&g.arraySet(l.output,l.output,e,j,0),this.onData(k)):this.onData(g.shrinkBuf(l.output,l.next_out)))}while(l.avail_in>0&&c!==i.Z_STREAM_END);return c===i.Z_STREAM_END&&(d=i.Z_FINISH),d===i.Z_FINISH?(c=f.inflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===i.Z_OK):!0},m.prototype.onData=function(a){this.chunks.push(a)},m.prototype.onEnd=function(a){a===i.Z_OK&&(this.result="string"===this.options.to?this.chunks.join(""):g.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Inflate=m,c.inflate=d,c.inflateRaw=e,c.ungzip=d},{"./utils/common":27,"./utils/strings":28,"./zlib/constants":30,"./zlib/gzheader":33,"./zlib/inflate.js":35,"./zlib/messages":37,"./zlib/zstream":39}],27:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;c.assign=function(a){for(var b=Array.prototype.slice.call(arguments,1);b.length;){var c=b.shift();if(c){if("object"!=typeof c)throw new TypeError(c+"must be non-object");for(var d in c)c.hasOwnProperty(d)&&(a[d]=c[d])}}return a},c.shrinkBuf=function(a,b){return a.length===b?a:a.subarray?a.subarray(0,b):(a.length=b,a)};var e={arraySet:function(a,b,c,d,e){if(b.subarray&&a.subarray)return void a.set(b.subarray(c,c+d),e);for(var f=0;d>f;f++)a[e+f]=b[c+f]},flattenChunks:function(a){var b,c,d,e,f,g;for(d=0,b=0,c=a.length;c>b;b++)d+=a[b].length;for(g=new Uint8Array(d),e=0,b=0,c=a.length;c>b;b++)f=a[b],g.set(f,e),e+=f.length;return g}},f={arraySet:function(a,b,c,d,e){for(var f=0;d>f;f++)a[e+f]=b[c+f]},flattenChunks:function(a){return[].concat.apply([],a)}};c.setTyped=function(a){a?(c.Buf8=Uint8Array,c.Buf16=Uint16Array,c.Buf32=Int32Array,c.assign(c,e)):(c.Buf8=Array,c.Buf16=Array,c.Buf32=Array,c.assign(c,f))},c.setTyped(d)},{}],28:[function(a,b,c){"use strict";function d(a,b){if(65537>b&&(a.subarray&&g||!a.subarray&&f))return String.fromCharCode.apply(null,e.shrinkBuf(a,b));for(var c="",d=0;b>d;d++)c+=String.fromCharCode(a[d]);return c}var e=a("./common"),f=!0,g=!0;try{String.fromCharCode.apply(null,[0])}catch(h){f=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(h){g=!1}for(var i=new e.Buf8(256),j=0;256>j;j++)i[j]=j>=252?6:j>=248?5:j>=240?4:j>=224?3:j>=192?2:1;i[254]=i[254]=1,c.string2buf=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;h>f;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=128>c?1:2048>c?2:65536>c?3:4;for(b=new e.Buf8(i),g=0,f=0;i>g;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),128>c?b[g++]=c:2048>c?(b[g++]=192|c>>>6,b[g++]=128|63&c):65536>c?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},c.buf2binstring=function(a){return d(a,a.length)},c.binstring2buf=function(a){for(var b=new e.Buf8(a.length),c=0,d=b.length;d>c;c++)b[c]=a.charCodeAt(c);return b},c.buf2string=function(a,b){var c,e,f,g,h=b||a.length,j=new Array(2*h);for(e=0,c=0;h>c;)if(f=a[c++],128>f)j[e++]=f;else if(g=i[f],g>4)j[e++]=65533,c+=g-1;else{for(f&=2===g?31:3===g?15:7;g>1&&h>c;)f=f<<6|63&a[c++],g--;g>1?j[e++]=65533:65536>f?j[e++]=f:(f-=65536,j[e++]=55296|f>>10&1023,j[e++]=56320|1023&f)}return d(j,e)},c.utf8border=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return 0>c?b:0===c?b:c+i[a[c]]>b?c:b}},{"./common":27}],29:[function(a,b){"use strict";function c(a,b,c,d){for(var e=65535&a|0,f=a>>>16&65535|0,g=0;0!==c;){g=c>2e3?2e3:c,c-=g;do e=e+b[d++]|0,f=f+e|0;while(--g);e%=65521,f%=65521}return e|f<<16|0}b.exports=c},{}],30:[function(a,b){b.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],31:[function(a,b){"use strict";function c(){for(var a,b=[],c=0;256>c;c++){a=c;for(var d=0;8>d;d++)a=1&a?3988292384^a>>>1:a>>>1;b[c]=a}return b}function d(a,b,c,d){var f=e,g=d+c;a=-1^a;for(var h=d;g>h;h++)a=a>>>8^f[255&(a^b[h])];return-1^a}var e=c();b.exports=d},{}],32:[function(a,b,c){"use strict";function d(a,b){return a.msg=G[b],b}function e(a){return(a<<1)-(a>4?9:0)}function f(a){for(var b=a.length;--b>=0;)a[b]=0}function g(a){var b=a.state,c=b.pending;c>a.avail_out&&(c=a.avail_out),0!==c&&(C.arraySet(a.output,b.pending_buf,b.pending_out,c,a.next_out),a.next_out+=c,b.pending_out+=c,a.total_out+=c,a.avail_out-=c,b.pending-=c,0===b.pending&&(b.pending_out=0))}function h(a,b){D._tr_flush_block(a,a.block_start>=0?a.block_start:-1,a.strstart-a.block_start,b),a.block_start=a.strstart,g(a.strm)}function i(a,b){a.pending_buf[a.pending++]=b}function j(a,b){a.pending_buf[a.pending++]=b>>>8&255,a.pending_buf[a.pending++]=255&b}function k(a,b,c,d){var e=a.avail_in;return e>d&&(e=d),0===e?0:(a.avail_in-=e,C.arraySet(b,a.input,a.next_in,e,c),1===a.state.wrap?a.adler=E(a.adler,b,e,c):2===a.state.wrap&&(a.adler=F(a.adler,b,e,c)),a.next_in+=e,a.total_in+=e,e)}function l(a,b){var c,d,e=a.max_chain_length,f=a.strstart,g=a.prev_length,h=a.nice_match,i=a.strstart>a.w_size-jb?a.strstart-(a.w_size-jb):0,j=a.window,k=a.w_mask,l=a.prev,m=a.strstart+ib,n=j[f+g-1],o=j[f+g];a.prev_length>=a.good_match&&(e>>=2),h>a.lookahead&&(h=a.lookahead);do if(c=b,j[c+g]===o&&j[c+g-1]===n&&j[c]===j[f]&&j[++c]===j[f+1]){f+=2,c++;do;while(j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&m>f);if(d=ib-(m-f),f=m-ib,d>g){if(a.match_start=b,g=d,d>=h)break;n=j[f+g-1],o=j[f+g]}}while((b=l[b&k])>i&&0!==--e);return g<=a.lookahead?g:a.lookahead}function m(a){var b,c,d,e,f,g=a.w_size;do{if(e=a.window_size-a.lookahead-a.strstart,a.strstart>=g+(g-jb)){C.arraySet(a.window,a.window,g,g,0),a.match_start-=g,a.strstart-=g,a.block_start-=g,c=a.hash_size,b=c;do d=a.head[--b],a.head[b]=d>=g?d-g:0;while(--c);c=g,b=c;do d=a.prev[--b],a.prev[b]=d>=g?d-g:0;while(--c);e+=g}if(0===a.strm.avail_in)break;if(c=k(a.strm,a.window,a.strstart+a.lookahead,e),a.lookahead+=c,a.lookahead+a.insert>=hb)for(f=a.strstart-a.insert,a.ins_h=a.window[f],a.ins_h=(a.ins_h<<a.hash_shift^a.window[f+1])&a.hash_mask;a.insert&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[f+hb-1])&a.hash_mask,a.prev[f&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=f,f++,a.insert--,!(a.lookahead+a.insert<hb)););}while(a.lookahead<jb&&0!==a.strm.avail_in)}function n(a,b){var c=65535;for(c>a.pending_buf_size-5&&(c=a.pending_buf_size-5);;){if(a.lookahead<=1){if(m(a),0===a.lookahead&&b===H)return sb;if(0===a.lookahead)break}a.strstart+=a.lookahead,a.lookahead=0;var d=a.block_start+c;if((0===a.strstart||a.strstart>=d)&&(a.lookahead=a.strstart-d,a.strstart=d,h(a,!1),0===a.strm.avail_out))return sb;if(a.strstart-a.block_start>=a.w_size-jb&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.strstart>a.block_start&&(h(a,!1),0===a.strm.avail_out)?sb:sb}function o(a,b){for(var c,d;;){if(a.lookahead<jb){if(m(a),a.lookahead<jb&&b===H)return sb;if(0===a.lookahead)break}if(c=0,a.lookahead>=hb&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart),0!==c&&a.strstart-c<=a.w_size-jb&&(a.match_length=l(a,c)),a.match_length>=hb)if(d=D._tr_tally(a,a.strstart-a.match_start,a.match_length-hb),a.lookahead-=a.match_length,a.match_length<=a.max_lazy_match&&a.lookahead>=hb){a.match_length--;do a.strstart++,a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart;while(0!==--a.match_length);a.strstart++}else a.strstart+=a.match_length,a.match_length=0,a.ins_h=a.window[a.strstart],a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+1])&a.hash_mask;else d=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++;if(d&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=a.strstart<hb-1?a.strstart:hb-1,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function p(a,b){for(var c,d,e;;){if(a.lookahead<jb){if(m(a),a.lookahead<jb&&b===H)return sb;if(0===a.lookahead)break}if(c=0,a.lookahead>=hb&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart),a.prev_length=a.match_length,a.prev_match=a.match_start,a.match_length=hb-1,0!==c&&a.prev_length<a.max_lazy_match&&a.strstart-c<=a.w_size-jb&&(a.match_length=l(a,c),a.match_length<=5&&(a.strategy===S||a.match_length===hb&&a.strstart-a.match_start>4096)&&(a.match_length=hb-1)),a.prev_length>=hb&&a.match_length<=a.prev_length){e=a.strstart+a.lookahead-hb,d=D._tr_tally(a,a.strstart-1-a.prev_match,a.prev_length-hb),a.lookahead-=a.prev_length-1,a.prev_length-=2;do++a.strstart<=e&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart);while(0!==--a.prev_length);if(a.match_available=0,a.match_length=hb-1,a.strstart++,d&&(h(a,!1),0===a.strm.avail_out))return sb}else if(a.match_available){if(d=D._tr_tally(a,0,a.window[a.strstart-1]),d&&h(a,!1),a.strstart++,a.lookahead--,0===a.strm.avail_out)return sb}else a.match_available=1,a.strstart++,a.lookahead--}return a.match_available&&(d=D._tr_tally(a,0,a.window[a.strstart-1]),a.match_available=0),a.insert=a.strstart<hb-1?a.strstart:hb-1,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function q(a,b){for(var c,d,e,f,g=a.window;;){if(a.lookahead<=ib){if(m(a),a.lookahead<=ib&&b===H)return sb;if(0===a.lookahead)break}if(a.match_length=0,a.lookahead>=hb&&a.strstart>0&&(e=a.strstart-1,d=g[e],d===g[++e]&&d===g[++e]&&d===g[++e])){f=a.strstart+ib;do;while(d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&f>e);a.match_length=ib-(f-e),a.match_length>a.lookahead&&(a.match_length=a.lookahead)}if(a.match_length>=hb?(c=D._tr_tally(a,1,a.match_length-hb),a.lookahead-=a.match_length,a.strstart+=a.match_length,a.match_length=0):(c=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++),c&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function r(a,b){for(var c;;){if(0===a.lookahead&&(m(a),0===a.lookahead)){if(b===H)return sb;break}if(a.match_length=0,c=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++,c&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function s(a){a.window_size=2*a.w_size,f(a.head),a.max_lazy_match=B[a.level].max_lazy,a.good_match=B[a.level].good_length,a.nice_match=B[a.level].nice_length,a.max_chain_length=B[a.level].max_chain,a.strstart=0,a.block_start=0,a.lookahead=0,a.insert=0,a.match_length=a.prev_length=hb-1,a.match_available=0,a.ins_h=0}function t(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=Y,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new C.Buf16(2*fb),this.dyn_dtree=new C.Buf16(2*(2*db+1)),this.bl_tree=new C.Buf16(2*(2*eb+1)),f(this.dyn_ltree),f(this.dyn_dtree),f(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new C.Buf16(gb+1),this.heap=new C.Buf16(2*cb+1),f(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new C.Buf16(2*cb+1),f(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}function u(a){var b;return a&&a.state?(a.total_in=a.total_out=0,a.data_type=X,b=a.state,b.pending=0,b.pending_out=0,b.wrap<0&&(b.wrap=-b.wrap),b.status=b.wrap?lb:qb,a.adler=2===b.wrap?0:1,b.last_flush=H,D._tr_init(b),M):d(a,O)}function v(a){var b=u(a);return b===M&&s(a.state),b}function w(a,b){return a&&a.state?2!==a.state.wrap?O:(a.state.gzhead=b,M):O}function x(a,b,c,e,f,g){if(!a)return O;var h=1;if(b===R&&(b=6),0>e?(h=0,e=-e):e>15&&(h=2,e-=16),1>f||f>Z||c!==Y||8>e||e>15||0>b||b>9||0>g||g>V)return d(a,O);8===e&&(e=9);var i=new t;return a.state=i,i.strm=a,i.wrap=h,i.gzhead=null,i.w_bits=e,i.w_size=1<<i.w_bits,i.w_mask=i.w_size-1,i.hash_bits=f+7,i.hash_size=1<<i.hash_bits,i.hash_mask=i.hash_size-1,i.hash_shift=~~((i.hash_bits+hb-1)/hb),i.window=new C.Buf8(2*i.w_size),i.head=new C.Buf16(i.hash_size),i.prev=new C.Buf16(i.w_size),i.lit_bufsize=1<<f+6,i.pending_buf_size=4*i.lit_bufsize,i.pending_buf=new C.Buf8(i.pending_buf_size),i.d_buf=i.lit_bufsize>>1,i.l_buf=3*i.lit_bufsize,i.level=b,i.strategy=g,i.method=c,v(a)}function y(a,b){return x(a,b,Y,$,_,W)}function z(a,b){var c,h,k,l;if(!a||!a.state||b>L||0>b)return a?d(a,O):O;if(h=a.state,!a.output||!a.input&&0!==a.avail_in||h.status===rb&&b!==K)return d(a,0===a.avail_out?Q:O);if(h.strm=a,c=h.last_flush,h.last_flush=b,h.status===lb)if(2===h.wrap)a.adler=0,i(h,31),i(h,139),i(h,8),h.gzhead?(i(h,(h.gzhead.text?1:0)+(h.gzhead.hcrc?2:0)+(h.gzhead.extra?4:0)+(h.gzhead.name?8:0)+(h.gzhead.comment?16:0)),i(h,255&h.gzhead.time),i(h,h.gzhead.time>>8&255),i(h,h.gzhead.time>>16&255),i(h,h.gzhead.time>>24&255),i(h,9===h.level?2:h.strategy>=T||h.level<2?4:0),i(h,255&h.gzhead.os),h.gzhead.extra&&h.gzhead.extra.length&&(i(h,255&h.gzhead.extra.length),i(h,h.gzhead.extra.length>>8&255)),h.gzhead.hcrc&&(a.adler=F(a.adler,h.pending_buf,h.pending,0)),h.gzindex=0,h.status=mb):(i(h,0),i(h,0),i(h,0),i(h,0),i(h,0),i(h,9===h.level?2:h.strategy>=T||h.level<2?4:0),i(h,wb),h.status=qb);else{var m=Y+(h.w_bits-8<<4)<<8,n=-1;n=h.strategy>=T||h.level<2?0:h.level<6?1:6===h.level?2:3,m|=n<<6,0!==h.strstart&&(m|=kb),m+=31-m%31,h.status=qb,j(h,m),0!==h.strstart&&(j(h,a.adler>>>16),j(h,65535&a.adler)),a.adler=1}if(h.status===mb)if(h.gzhead.extra){for(k=h.pending;h.gzindex<(65535&h.gzhead.extra.length)&&(h.pending!==h.pending_buf_size||(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending!==h.pending_buf_size));)i(h,255&h.gzhead.extra[h.gzindex]),h.gzindex++;h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),h.gzindex===h.gzhead.extra.length&&(h.gzindex=0,h.status=nb)}else h.status=nb;if(h.status===nb)if(h.gzhead.name){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindex<h.gzhead.name.length?255&h.gzhead.name.charCodeAt(h.gzindex++):0,i(h,l)}while(0!==l);h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.gzindex=0,h.status=ob)}else h.status=ob;if(h.status===ob)if(h.gzhead.comment){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindex<h.gzhead.comment.length?255&h.gzhead.comment.charCodeAt(h.gzindex++):0,i(h,l)}while(0!==l);h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.status=pb)}else h.status=pb;if(h.status===pb&&(h.gzhead.hcrc?(h.pending+2>h.pending_buf_size&&g(a),h.pending+2<=h.pending_buf_size&&(i(h,255&a.adler),i(h,a.adler>>8&255),a.adler=0,h.status=qb)):h.status=qb),0!==h.pending){if(g(a),0===a.avail_out)return h.last_flush=-1,M}else if(0===a.avail_in&&e(b)<=e(c)&&b!==K)return d(a,Q);if(h.status===rb&&0!==a.avail_in)return d(a,Q);if(0!==a.avail_in||0!==h.lookahead||b!==H&&h.status!==rb){var o=h.strategy===T?r(h,b):h.strategy===U?q(h,b):B[h.level].func(h,b);if((o===ub||o===vb)&&(h.status=rb),o===sb||o===ub)return 0===a.avail_out&&(h.last_flush=-1),M;if(o===tb&&(b===I?D._tr_align(h):b!==L&&(D._tr_stored_block(h,0,0,!1),b===J&&(f(h.head),0===h.lookahead&&(h.strstart=0,h.block_start=0,h.insert=0))),g(a),0===a.avail_out))return h.last_flush=-1,M}return b!==K?M:h.wrap<=0?N:(2===h.wrap?(i(h,255&a.adler),i(h,a.adler>>8&255),i(h,a.adler>>16&255),i(h,a.adler>>24&255),i(h,255&a.total_in),i(h,a.total_in>>8&255),i(h,a.total_in>>16&255),i(h,a.total_in>>24&255)):(j(h,a.adler>>>16),j(h,65535&a.adler)),g(a),h.wrap>0&&(h.wrap=-h.wrap),0!==h.pending?M:N)}function A(a){var b;return a&&a.state?(b=a.state.status,b!==lb&&b!==mb&&b!==nb&&b!==ob&&b!==pb&&b!==qb&&b!==rb?d(a,O):(a.state=null,b===qb?d(a,P):M)):O}var B,C=a("../utils/common"),D=a("./trees"),E=a("./adler32"),F=a("./crc32"),G=a("./messages"),H=0,I=1,J=3,K=4,L=5,M=0,N=1,O=-2,P=-3,Q=-5,R=-1,S=1,T=2,U=3,V=4,W=0,X=2,Y=8,Z=9,$=15,_=8,ab=29,bb=256,cb=bb+1+ab,db=30,eb=19,fb=2*cb+1,gb=15,hb=3,ib=258,jb=ib+hb+1,kb=32,lb=42,mb=69,nb=73,ob=91,pb=103,qb=113,rb=666,sb=1,tb=2,ub=3,vb=4,wb=3,xb=function(a,b,c,d,e){this.good_length=a,this.max_lazy=b,this.nice_length=c,this.max_chain=d,this.func=e};B=[new xb(0,0,0,0,n),new xb(4,4,8,4,o),new xb(4,5,16,8,o),new xb(4,6,32,32,o),new xb(4,4,16,16,p),new xb(8,16,32,32,p),new xb(8,16,128,128,p),new xb(8,32,128,256,p),new xb(32,128,258,1024,p),new xb(32,258,258,4096,p)],c.deflateInit=y,c.deflateInit2=x,c.deflateReset=v,c.deflateResetKeep=u,c.deflateSetHeader=w,c.deflate=z,c.deflateEnd=A,c.deflateInfo="pako deflate (from Nodeca project)"},{"../utils/common":27,"./adler32":29,"./crc32":31,"./messages":37,"./trees":38}],33:[function(a,b){"use strict";function c(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}b.exports=c},{}],34:[function(a,b){"use strict";var c=30,d=12;b.exports=function(a,b){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C;e=a.state,f=a.next_in,B=a.input,g=f+(a.avail_in-5),h=a.next_out,C=a.output,i=h-(b-a.avail_out),j=h+(a.avail_out-257),k=e.dmax,l=e.wsize,m=e.whave,n=e.wnext,o=e.window,p=e.hold,q=e.bits,r=e.lencode,s=e.distcode,t=(1<<e.lenbits)-1,u=(1<<e.distbits)-1;a:do{15>q&&(p+=B[f++]<<q,q+=8,p+=B[f++]<<q,q+=8),v=r[p&t];b:for(;;){if(w=v>>>24,p>>>=w,q-=w,w=v>>>16&255,0===w)C[h++]=65535&v;else{if(!(16&w)){if(0===(64&w)){v=r[(65535&v)+(p&(1<<w)-1)];continue b}if(32&w){e.mode=d;break a}a.msg="invalid literal/length code",e.mode=c;break a}x=65535&v,w&=15,w&&(w>q&&(p+=B[f++]<<q,q+=8),x+=p&(1<<w)-1,p>>>=w,q-=w),15>q&&(p+=B[f++]<<q,q+=8,p+=B[f++]<<q,q+=8),v=s[p&u];c:for(;;){if(w=v>>>24,p>>>=w,q-=w,w=v>>>16&255,!(16&w)){if(0===(64&w)){v=s[(65535&v)+(p&(1<<w)-1)];continue c}a.msg="invalid distance code",e.mode=c;break a}if(y=65535&v,w&=15,w>q&&(p+=B[f++]<<q,q+=8,w>q&&(p+=B[f++]<<q,q+=8)),y+=p&(1<<w)-1,y>k){a.msg="invalid distance too far back",e.mode=c;break a}if(p>>>=w,q-=w,w=h-i,y>w){if(w=y-w,w>m&&e.sane){a.msg="invalid distance too far back",e.mode=c;break a}if(z=0,A=o,0===n){if(z+=l-w,x>w){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}else if(w>n){if(z+=l+n-w,w-=n,x>w){x-=w;do C[h++]=o[z++];while(--w);if(z=0,x>n){w=n,x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}}else if(z+=n-w,x>w){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}for(;x>2;)C[h++]=A[z++],C[h++]=A[z++],C[h++]=A[z++],x-=3;x&&(C[h++]=A[z++],x>1&&(C[h++]=A[z++]))}else{z=h-y;do C[h++]=C[z++],C[h++]=C[z++],C[h++]=C[z++],x-=3;while(x>2);x&&(C[h++]=C[z++],x>1&&(C[h++]=C[z++]))}break}}break}}while(g>f&&j>h);x=q>>3,f-=x,q-=x<<3,p&=(1<<q)-1,a.next_in=f,a.next_out=h,a.avail_in=g>f?5+(g-f):5-(f-g),a.avail_out=j>h?257+(j-h):257-(h-j),e.hold=p,e.bits=q}},{}],35:[function(a,b,c){"use strict";function d(a){return(a>>>24&255)+(a>>>8&65280)+((65280&a)<<8)+((255&a)<<24)}function e(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new r.Buf16(320),this.work=new r.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function f(a){var b;return a&&a.state?(b=a.state,a.total_in=a.total_out=b.total=0,a.msg="",b.wrap&&(a.adler=1&b.wrap),b.mode=K,b.last=0,b.havedict=0,b.dmax=32768,b.head=null,b.hold=0,b.bits=0,b.lencode=b.lendyn=new r.Buf32(ob),b.distcode=b.distdyn=new r.Buf32(pb),b.sane=1,b.back=-1,C):F}function g(a){var b;return a&&a.state?(b=a.state,b.wsize=0,b.whave=0,b.wnext=0,f(a)):F}function h(a,b){var c,d;return a&&a.state?(d=a.state,0>b?(c=0,b=-b):(c=(b>>4)+1,48>b&&(b&=15)),b&&(8>b||b>15)?F:(null!==d.window&&d.wbits!==b&&(d.window=null),d.wrap=c,d.wbits=b,g(a))):F}function i(a,b){var c,d;return a?(d=new e,a.state=d,d.window=null,c=h(a,b),c!==C&&(a.state=null),c):F}function j(a){return i(a,rb)}function k(a){if(sb){var b;for(p=new r.Buf32(512),q=new r.Buf32(32),b=0;144>b;)a.lens[b++]=8;for(;256>b;)a.lens[b++]=9;for(;280>b;)a.lens[b++]=7;for(;288>b;)a.lens[b++]=8;for(v(x,a.lens,0,288,p,0,a.work,{bits:9}),b=0;32>b;)a.lens[b++]=5;v(y,a.lens,0,32,q,0,a.work,{bits:5}),sb=!1}a.lencode=p,a.lenbits=9,a.distcode=q,a.distbits=5}function l(a,b,c,d){var e,f=a.state;return null===f.window&&(f.wsize=1<<f.wbits,f.wnext=0,f.whave=0,f.window=new r.Buf8(f.wsize)),d>=f.wsize?(r.arraySet(f.window,b,c-f.wsize,f.wsize,0),f.wnext=0,f.whave=f.wsize):(e=f.wsize-f.wnext,e>d&&(e=d),r.arraySet(f.window,b,c-d,e,f.wnext),d-=e,d?(r.arraySet(f.window,b,c-d,d,0),f.wnext=d,f.whave=f.wsize):(f.wnext+=e,f.wnext===f.wsize&&(f.wnext=0),f.whave<f.wsize&&(f.whave+=e))),0}function m(a,b){var c,e,f,g,h,i,j,m,n,o,p,q,ob,pb,qb,rb,sb,tb,ub,vb,wb,xb,yb,zb,Ab=0,Bb=new r.Buf8(4),Cb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];if(!a||!a.state||!a.output||!a.input&&0!==a.avail_in)return F;c=a.state,c.mode===V&&(c.mode=W),h=a.next_out,f=a.output,j=a.avail_out,g=a.next_in,e=a.input,i=a.avail_in,m=c.hold,n=c.bits,o=i,p=j,xb=C;a:for(;;)switch(c.mode){case K:if(0===c.wrap){c.mode=W;break}for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(2&c.wrap&&35615===m){c.check=0,Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0),m=0,n=0,c.mode=L;break}if(c.flags=0,c.head&&(c.head.done=!1),!(1&c.wrap)||(((255&m)<<8)+(m>>8))%31){a.msg="incorrect header check",c.mode=lb;break}if((15&m)!==J){a.msg="unknown compression method",c.mode=lb;break}if(m>>>=4,n-=4,wb=(15&m)+8,0===c.wbits)c.wbits=wb;else if(wb>c.wbits){a.msg="invalid window size",c.mode=lb;break}c.dmax=1<<wb,a.adler=c.check=1,c.mode=512&m?T:V,m=0,n=0;break;case L:for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(c.flags=m,(255&c.flags)!==J){a.msg="unknown compression method",c.mode=lb;break}if(57344&c.flags){a.msg="unknown header flags set",c.mode=lb;break}c.head&&(c.head.text=m>>8&1),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0,c.mode=M;case M:for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.head&&(c.head.time=m),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,Bb[2]=m>>>16&255,Bb[3]=m>>>24&255,c.check=t(c.check,Bb,4,0)),m=0,n=0,c.mode=N;case N:for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.head&&(c.head.xflags=255&m,c.head.os=m>>8),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0,c.mode=O;case O:if(1024&c.flags){for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.length=m,c.head&&(c.head.extra_len=m),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0}else c.head&&(c.head.extra=null);c.mode=P;case P:if(1024&c.flags&&(q=c.length,q>i&&(q=i),q&&(c.head&&(wb=c.head.extra_len-c.length,c.head.extra||(c.head.extra=new Array(c.head.extra_len)),r.arraySet(c.head.extra,e,g,q,wb)),512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,c.length-=q),c.length))break a;c.length=0,c.mode=Q;case Q:if(2048&c.flags){if(0===i)break a;q=0;do wb=e[g+q++],c.head&&wb&&c.length<65536&&(c.head.name+=String.fromCharCode(wb));while(wb&&i>q);if(512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,wb)break a}else c.head&&(c.head.name=null);c.length=0,c.mode=R;case R:if(4096&c.flags){if(0===i)break a;q=0;do wb=e[g+q++],c.head&&wb&&c.length<65536&&(c.head.comment+=String.fromCharCode(wb));while(wb&&i>q);if(512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,wb)break a}else c.head&&(c.head.comment=null);c.mode=S;case S:if(512&c.flags){for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m!==(65535&c.check)){a.msg="header crc mismatch",c.mode=lb;break}m=0,n=0}c.head&&(c.head.hcrc=c.flags>>9&1,c.head.done=!0),a.adler=c.check=0,c.mode=V;break;case T:for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}a.adler=c.check=d(m),m=0,n=0,c.mode=U;case U:if(0===c.havedict)return a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,E;a.adler=c.check=1,c.mode=V;case V:if(b===A||b===B)break a;case W:if(c.last){m>>>=7&n,n-=7&n,c.mode=ib;break}for(;3>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}switch(c.last=1&m,m>>>=1,n-=1,3&m){case 0:c.mode=X;break;case 1:if(k(c),c.mode=bb,b===B){m>>>=2,n-=2;break a}break;case 2:c.mode=$;break;case 3:a.msg="invalid block type",c.mode=lb}m>>>=2,n-=2;break;case X:for(m>>>=7&n,n-=7&n;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if((65535&m)!==(m>>>16^65535)){a.msg="invalid stored block lengths",c.mode=lb;break}if(c.length=65535&m,m=0,n=0,c.mode=Y,b===B)break a;case Y:c.mode=Z;case Z:if(q=c.length){if(q>i&&(q=i),q>j&&(q=j),0===q)break a;r.arraySet(f,e,g,q,h),i-=q,g+=q,j-=q,h+=q,c.length-=q;break}c.mode=V;break;case $:for(;14>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(c.nlen=(31&m)+257,m>>>=5,n-=5,c.ndist=(31&m)+1,m>>>=5,n-=5,c.ncode=(15&m)+4,m>>>=4,n-=4,c.nlen>286||c.ndist>30){a.msg="too many length or distance symbols",c.mode=lb;break}c.have=0,c.mode=_;case _:for(;c.have<c.ncode;){for(;3>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.lens[Cb[c.have++]]=7&m,m>>>=3,n-=3}for(;c.have<19;)c.lens[Cb[c.have++]]=0;if(c.lencode=c.lendyn,c.lenbits=7,yb={bits:c.lenbits},xb=v(w,c.lens,0,19,c.lencode,0,c.work,yb),c.lenbits=yb.bits,xb){a.msg="invalid code lengths set",c.mode=lb;break}c.have=0,c.mode=ab;case ab:for(;c.have<c.nlen+c.ndist;){for(;Ab=c.lencode[m&(1<<c.lenbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(16>sb)m>>>=qb,n-=qb,c.lens[c.have++]=sb;else{if(16===sb){for(zb=qb+2;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m>>>=qb,n-=qb,0===c.have){a.msg="invalid bit length repeat",c.mode=lb;break}wb=c.lens[c.have-1],q=3+(3&m),m>>>=2,n-=2}else if(17===sb){for(zb=qb+3;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=qb,n-=qb,wb=0,q=3+(7&m),m>>>=3,n-=3}else{for(zb=qb+7;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=qb,n-=qb,wb=0,q=11+(127&m),m>>>=7,n-=7}if(c.have+q>c.nlen+c.ndist){a.msg="invalid bit length repeat",c.mode=lb;break}for(;q--;)c.lens[c.have++]=wb}}if(c.mode===lb)break;if(0===c.lens[256]){a.msg="invalid code -- missing end-of-block",c.mode=lb;break}if(c.lenbits=9,yb={bits:c.lenbits},xb=v(x,c.lens,0,c.nlen,c.lencode,0,c.work,yb),c.lenbits=yb.bits,xb){a.msg="invalid literal/lengths set",c.mode=lb;break}if(c.distbits=6,c.distcode=c.distdyn,yb={bits:c.distbits},xb=v(y,c.lens,c.nlen,c.ndist,c.distcode,0,c.work,yb),c.distbits=yb.bits,xb){a.msg="invalid distances set",c.mode=lb;break}if(c.mode=bb,b===B)break a;case bb:c.mode=cb;case cb:if(i>=6&&j>=258){a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,u(a,p),h=a.next_out,f=a.output,j=a.avail_out,g=a.next_in,e=a.input,i=a.avail_in,m=c.hold,n=c.bits,c.mode===V&&(c.back=-1);break}for(c.back=0;Ab=c.lencode[m&(1<<c.lenbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(rb&&0===(240&rb)){for(tb=qb,ub=rb,vb=sb;Ab=c.lencode[vb+((m&(1<<tb+ub)-1)>>tb)],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=tb+qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=tb,n-=tb,c.back+=tb}if(m>>>=qb,n-=qb,c.back+=qb,c.length=sb,0===rb){c.mode=hb;break}if(32&rb){c.back=-1,c.mode=V;break}if(64&rb){a.msg="invalid literal/length code",c.mode=lb;break}c.extra=15&rb,c.mode=db;case db:if(c.extra){for(zb=c.extra;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.length+=m&(1<<c.extra)-1,m>>>=c.extra,n-=c.extra,c.back+=c.extra}c.was=c.length,c.mode=eb;case eb:for(;Ab=c.distcode[m&(1<<c.distbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(0===(240&rb)){for(tb=qb,ub=rb,vb=sb;Ab=c.distcode[vb+((m&(1<<tb+ub)-1)>>tb)],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=tb+qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=tb,n-=tb,c.back+=tb}if(m>>>=qb,n-=qb,c.back+=qb,64&rb){a.msg="invalid distance code",c.mode=lb;break}c.offset=sb,c.extra=15&rb,c.mode=fb;case fb:if(c.extra){for(zb=c.extra;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.offset+=m&(1<<c.extra)-1,m>>>=c.extra,n-=c.extra,c.back+=c.extra}if(c.offset>c.dmax){a.msg="invalid distance too far back",c.mode=lb;break}c.mode=gb;case gb:if(0===j)break a;
18319 zip.remove("tempfile"); 25558 if(q=p-j,c.offset>q){if(q=c.offset-q,q>c.whave&&c.sane){a.msg="invalid distance too far back",c.mode=lb;break}q>c.wnext?(q-=c.wnext,ob=c.wsize-q):ob=c.wnext-q,q>c.length&&(q=c.length),pb=c.window}else pb=f,ob=h-c.offset,q=c.length;q>j&&(q=j),j-=q,c.length-=q;do f[h++]=pb[ob++];while(--q);0===c.length&&(c.mode=cb);break;case hb:if(0===j)break a;f[h++]=c.length,j--,c.mode=cb;break;case ib:if(c.wrap){for(;32>n;){if(0===i)break a;i--,m|=e[g++]<<n,n+=8}if(p-=j,a.total_out+=p,c.total+=p,p&&(a.adler=c.check=c.flags?t(c.check,f,p,h-p):s(c.check,f,p,h-p)),p=j,(c.flags?m:d(m))!==c.check){a.msg="incorrect data check",c.mode=lb;break}m=0,n=0}c.mode=jb;case jb:if(c.wrap&&c.flags){for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m!==(4294967295&c.total)){a.msg="incorrect length check",c.mode=lb;break}m=0,n=0}c.mode=kb;case kb:xb=D;break a;case lb:xb=G;break a;case mb:return H;case nb:default:return F}return a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,(c.wsize||p!==a.avail_out&&c.mode<lb&&(c.mode<ib||b!==z))&&l(a,a.output,a.next_out,p-a.avail_out)?(c.mode=mb,H):(o-=a.avail_in,p-=a.avail_out,a.total_in+=o,a.total_out+=p,c.total+=p,c.wrap&&p&&(a.adler=c.check=c.flags?t(c.check,f,p,a.next_out-p):s(c.check,f,p,a.next_out-p)),a.data_type=c.bits+(c.last?64:0)+(c.mode===V?128:0)+(c.mode===bb||c.mode===Y?256:0),(0===o&&0===p||b===z)&&xb===C&&(xb=I),xb)}function n(a){if(!a||!a.state)return F;var b=a.state;return b.window&&(b.window=null),a.state=null,C}function o(a,b){var c;return a&&a.state?(c=a.state,0===(2&c.wrap)?F:(c.head=b,b.done=!1,C)):F}var p,q,r=a("../utils/common"),s=a("./adler32"),t=a("./crc32"),u=a("./inffast"),v=a("./inftrees"),w=0,x=1,y=2,z=4,A=5,B=6,C=0,D=1,E=2,F=-2,G=-3,H=-4,I=-5,J=8,K=1,L=2,M=3,N=4,O=5,P=6,Q=7,R=8,S=9,T=10,U=11,V=12,W=13,X=14,Y=15,Z=16,$=17,_=18,ab=19,bb=20,cb=21,db=22,eb=23,fb=24,gb=25,hb=26,ib=27,jb=28,kb=29,lb=30,mb=31,nb=32,ob=852,pb=592,qb=15,rb=qb,sb=!0;c.inflateReset=g,c.inflateReset2=h,c.inflateResetKeep=f,c.inflateInit=j,c.inflateInit2=i,c.inflate=m,c.inflateEnd=n,c.inflateGetHeader=o,c.inflateInfo="pako inflate (from Nodeca project)"},{"../utils/common":27,"./adler32":29,"./crc32":31,"./inffast":34,"./inftrees":36}],36:[function(a,b){"use strict";var c=a("../utils/common"),d=15,e=852,f=592,g=0,h=1,i=2,j=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],k=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],l=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],m=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];b.exports=function(a,b,n,o,p,q,r,s){var t,u,v,w,x,y,z,A,B,C=s.bits,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=null,O=0,P=new c.Buf16(d+1),Q=new c.Buf16(d+1),R=null,S=0;for(D=0;d>=D;D++)P[D]=0;for(E=0;o>E;E++)P[b[n+E]]++;for(H=C,G=d;G>=1&&0===P[G];G--);if(H>G&&(H=G),0===G)return p[q++]=20971520,p[q++]=20971520,s.bits=1,0;for(F=1;G>F&&0===P[F];F++);for(F>H&&(H=F),K=1,D=1;d>=D;D++)if(K<<=1,K-=P[D],0>K)return-1;if(K>0&&(a===g||1!==G))return-1;for(Q[1]=0,D=1;d>D;D++)Q[D+1]=Q[D]+P[D];for(E=0;o>E;E++)0!==b[n+E]&&(r[Q[b[n+E]]++]=E);if(a===g?(N=R=r,y=19):a===h?(N=j,O-=257,R=k,S-=257,y=256):(N=l,R=m,y=-1),M=0,E=0,D=F,x=q,I=H,J=0,v=-1,L=1<<H,w=L-1,a===h&&L>e||a===i&&L>f)return 1;for(var T=0;;){T++,z=D-J,r[E]<y?(A=0,B=r[E]):r[E]>y?(A=R[S+r[E]],B=N[O+r[E]]):(A=96,B=0),t=1<<D-J,u=1<<I,F=u;do u-=t,p[x+(M>>J)+u]=z<<24|A<<16|B|0;while(0!==u);for(t=1<<D-1;M&t;)t>>=1;if(0!==t?(M&=t-1,M+=t):M=0,E++,0===--P[D]){if(D===G)break;D=b[n+r[E]]}if(D>H&&(M&w)!==v){for(0===J&&(J=H),x+=F,I=D-J,K=1<<I;G>I+J&&(K-=P[I+J],!(0>=K));)I++,K<<=1;if(L+=1<<I,a===h&&L>e||a===i&&L>f)return 1;v=M&w,p[v]=H<<24|I<<16|x-q|0}}return 0!==M&&(p[x+M]=D-J<<24|64<<16|0),s.bits=H,0}},{"../utils/common":27}],37:[function(a,b){"use strict";b.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],38:[function(a,b,c){"use strict";function d(a){for(var b=a.length;--b>=0;)a[b]=0}function e(a){return 256>a?gb[a]:gb[256+(a>>>7)]}function f(a,b){a.pending_buf[a.pending++]=255&b,a.pending_buf[a.pending++]=b>>>8&255}function g(a,b,c){a.bi_valid>V-c?(a.bi_buf|=b<<a.bi_valid&65535,f(a,a.bi_buf),a.bi_buf=b>>V-a.bi_valid,a.bi_valid+=c-V):(a.bi_buf|=b<<a.bi_valid&65535,a.bi_valid+=c)}function h(a,b,c){g(a,c[2*b],c[2*b+1])}function i(a,b){var c=0;do c|=1&a,a>>>=1,c<<=1;while(--b>0);return c>>>1}function j(a){16===a.bi_valid?(f(a,a.bi_buf),a.bi_buf=0,a.bi_valid=0):a.bi_valid>=8&&(a.pending_buf[a.pending++]=255&a.bi_buf,a.bi_buf>>=8,a.bi_valid-=8)}function k(a,b){var c,d,e,f,g,h,i=b.dyn_tree,j=b.max_code,k=b.stat_desc.static_tree,l=b.stat_desc.has_stree,m=b.stat_desc.extra_bits,n=b.stat_desc.extra_base,o=b.stat_desc.max_length,p=0;for(f=0;U>=f;f++)a.bl_count[f]=0;for(i[2*a.heap[a.heap_max]+1]=0,c=a.heap_max+1;T>c;c++)d=a.heap[c],f=i[2*i[2*d+1]+1]+1,f>o&&(f=o,p++),i[2*d+1]=f,d>j||(a.bl_count[f]++,g=0,d>=n&&(g=m[d-n]),h=i[2*d],a.opt_len+=h*(f+g),l&&(a.static_len+=h*(k[2*d+1]+g)));if(0!==p){do{for(f=o-1;0===a.bl_count[f];)f--;a.bl_count[f]--,a.bl_count[f+1]+=2,a.bl_count[o]--,p-=2}while(p>0);for(f=o;0!==f;f--)for(d=a.bl_count[f];0!==d;)e=a.heap[--c],e>j||(i[2*e+1]!==f&&(a.opt_len+=(f-i[2*e+1])*i[2*e],i[2*e+1]=f),d--)}}function l(a,b,c){var d,e,f=new Array(U+1),g=0;for(d=1;U>=d;d++)f[d]=g=g+c[d-1]<<1;for(e=0;b>=e;e++){var h=a[2*e+1];0!==h&&(a[2*e]=i(f[h]++,h))}}function m(){var a,b,c,d,e,f=new Array(U+1);for(c=0,d=0;O-1>d;d++)for(ib[d]=c,a=0;a<1<<_[d];a++)hb[c++]=d;for(hb[c-1]=d,e=0,d=0;16>d;d++)for(jb[d]=e,a=0;a<1<<ab[d];a++)gb[e++]=d;for(e>>=7;R>d;d++)for(jb[d]=e<<7,a=0;a<1<<ab[d]-7;a++)gb[256+e++]=d;for(b=0;U>=b;b++)f[b]=0;for(a=0;143>=a;)eb[2*a+1]=8,a++,f[8]++;for(;255>=a;)eb[2*a+1]=9,a++,f[9]++;for(;279>=a;)eb[2*a+1]=7,a++,f[7]++;for(;287>=a;)eb[2*a+1]=8,a++,f[8]++;for(l(eb,Q+1,f),a=0;R>a;a++)fb[2*a+1]=5,fb[2*a]=i(a,5);kb=new nb(eb,_,P+1,Q,U),lb=new nb(fb,ab,0,R,U),mb=new nb(new Array(0),bb,0,S,W)}function n(a){var b;for(b=0;Q>b;b++)a.dyn_ltree[2*b]=0;for(b=0;R>b;b++)a.dyn_dtree[2*b]=0;for(b=0;S>b;b++)a.bl_tree[2*b]=0;a.dyn_ltree[2*X]=1,a.opt_len=a.static_len=0,a.last_lit=a.matches=0}function o(a){a.bi_valid>8?f(a,a.bi_buf):a.bi_valid>0&&(a.pending_buf[a.pending++]=a.bi_buf),a.bi_buf=0,a.bi_valid=0}function p(a,b,c,d){o(a),d&&(f(a,c),f(a,~c)),E.arraySet(a.pending_buf,a.window,b,c,a.pending),a.pending+=c}function q(a,b,c,d){var e=2*b,f=2*c;return a[e]<a[f]||a[e]===a[f]&&d[b]<=d[c]}function r(a,b,c){for(var d=a.heap[c],e=c<<1;e<=a.heap_len&&(e<a.heap_len&&q(b,a.heap[e+1],a.heap[e],a.depth)&&e++,!q(b,d,a.heap[e],a.depth));)a.heap[c]=a.heap[e],c=e,e<<=1;a.heap[c]=d}function s(a,b,c){var d,f,i,j,k=0;if(0!==a.last_lit)do d=a.pending_buf[a.d_buf+2*k]<<8|a.pending_buf[a.d_buf+2*k+1],f=a.pending_buf[a.l_buf+k],k++,0===d?h(a,f,b):(i=hb[f],h(a,i+P+1,b),j=_[i],0!==j&&(f-=ib[i],g(a,f,j)),d--,i=e(d),h(a,i,c),j=ab[i],0!==j&&(d-=jb[i],g(a,d,j)));while(k<a.last_lit);h(a,X,b)}function t(a,b){var c,d,e,f=b.dyn_tree,g=b.stat_desc.static_tree,h=b.stat_desc.has_stree,i=b.stat_desc.elems,j=-1;for(a.heap_len=0,a.heap_max=T,c=0;i>c;c++)0!==f[2*c]?(a.heap[++a.heap_len]=j=c,a.depth[c]=0):f[2*c+1]=0;for(;a.heap_len<2;)e=a.heap[++a.heap_len]=2>j?++j:0,f[2*e]=1,a.depth[e]=0,a.opt_len--,h&&(a.static_len-=g[2*e+1]);for(b.max_code=j,c=a.heap_len>>1;c>=1;c--)r(a,f,c);e=i;do c=a.heap[1],a.heap[1]=a.heap[a.heap_len--],r(a,f,1),d=a.heap[1],a.heap[--a.heap_max]=c,a.heap[--a.heap_max]=d,f[2*e]=f[2*c]+f[2*d],a.depth[e]=(a.depth[c]>=a.depth[d]?a.depth[c]:a.depth[d])+1,f[2*c+1]=f[2*d+1]=e,a.heap[1]=e++,r(a,f,1);while(a.heap_len>=2);a.heap[--a.heap_max]=a.heap[1],k(a,b),l(f,j,a.bl_count)}function u(a,b,c){var d,e,f=-1,g=b[1],h=0,i=7,j=4;for(0===g&&(i=138,j=3),b[2*(c+1)+1]=65535,d=0;c>=d;d++)e=g,g=b[2*(d+1)+1],++h<i&&e===g||(j>h?a.bl_tree[2*e]+=h:0!==e?(e!==f&&a.bl_tree[2*e]++,a.bl_tree[2*Y]++):10>=h?a.bl_tree[2*Z]++:a.bl_tree[2*$]++,h=0,f=e,0===g?(i=138,j=3):e===g?(i=6,j=3):(i=7,j=4))}function v(a,b,c){var d,e,f=-1,i=b[1],j=0,k=7,l=4;for(0===i&&(k=138,l=3),d=0;c>=d;d++)if(e=i,i=b[2*(d+1)+1],!(++j<k&&e===i)){if(l>j){do h(a,e,a.bl_tree);while(0!==--j)}else 0!==e?(e!==f&&(h(a,e,a.bl_tree),j--),h(a,Y,a.bl_tree),g(a,j-3,2)):10>=j?(h(a,Z,a.bl_tree),g(a,j-3,3)):(h(a,$,a.bl_tree),g(a,j-11,7));j=0,f=e,0===i?(k=138,l=3):e===i?(k=6,l=3):(k=7,l=4)}}function w(a){var b;for(u(a,a.dyn_ltree,a.l_desc.max_code),u(a,a.dyn_dtree,a.d_desc.max_code),t(a,a.bl_desc),b=S-1;b>=3&&0===a.bl_tree[2*cb[b]+1];b--);return a.opt_len+=3*(b+1)+5+5+4,b}function x(a,b,c,d){var e;for(g(a,b-257,5),g(a,c-1,5),g(a,d-4,4),e=0;d>e;e++)g(a,a.bl_tree[2*cb[e]+1],3);v(a,a.dyn_ltree,b-1),v(a,a.dyn_dtree,c-1)}function y(a){var b,c=4093624447;for(b=0;31>=b;b++,c>>>=1)if(1&c&&0!==a.dyn_ltree[2*b])return G;if(0!==a.dyn_ltree[18]||0!==a.dyn_ltree[20]||0!==a.dyn_ltree[26])return H;for(b=32;P>b;b++)if(0!==a.dyn_ltree[2*b])return H;return G}function z(a){pb||(m(),pb=!0),a.l_desc=new ob(a.dyn_ltree,kb),a.d_desc=new ob(a.dyn_dtree,lb),a.bl_desc=new ob(a.bl_tree,mb),a.bi_buf=0,a.bi_valid=0,n(a)}function A(a,b,c,d){g(a,(J<<1)+(d?1:0),3),p(a,b,c,!0)}function B(a){g(a,K<<1,3),h(a,X,eb),j(a)}function C(a,b,c,d){var e,f,h=0;a.level>0?(a.strm.data_type===I&&(a.strm.data_type=y(a)),t(a,a.l_desc),t(a,a.d_desc),h=w(a),e=a.opt_len+3+7>>>3,f=a.static_len+3+7>>>3,e>=f&&(e=f)):e=f=c+5,e>=c+4&&-1!==b?A(a,b,c,d):a.strategy===F||f===e?(g(a,(K<<1)+(d?1:0),3),s(a,eb,fb)):(g(a,(L<<1)+(d?1:0),3),x(a,a.l_desc.max_code+1,a.d_desc.max_code+1,h+1),s(a,a.dyn_ltree,a.dyn_dtree)),n(a),d&&o(a)}function D(a,b,c){return a.pending_buf[a.d_buf+2*a.last_lit]=b>>>8&255,a.pending_buf[a.d_buf+2*a.last_lit+1]=255&b,a.pending_buf[a.l_buf+a.last_lit]=255&c,a.last_lit++,0===b?a.dyn_ltree[2*c]++:(a.matches++,b--,a.dyn_ltree[2*(hb[c]+P+1)]++,a.dyn_dtree[2*e(b)]++),a.last_lit===a.lit_bufsize-1}var E=a("../utils/common"),F=4,G=0,H=1,I=2,J=0,K=1,L=2,M=3,N=258,O=29,P=256,Q=P+1+O,R=30,S=19,T=2*Q+1,U=15,V=16,W=7,X=256,Y=16,Z=17,$=18,_=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],ab=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],bb=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],cb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],db=512,eb=new Array(2*(Q+2));d(eb);var fb=new Array(2*R);d(fb);var gb=new Array(db);d(gb);var hb=new Array(N-M+1);d(hb);var ib=new Array(O);d(ib);var jb=new Array(R);d(jb);var kb,lb,mb,nb=function(a,b,c,d,e){this.static_tree=a,this.extra_bits=b,this.extra_base=c,this.elems=d,this.max_length=e,this.has_stree=a&&a.length},ob=function(a,b){this.dyn_tree=a,this.max_code=0,this.stat_desc=b},pb=!1;c._tr_init=z,c._tr_stored_block=A,c._tr_flush_block=C,c._tr_tally=D,c._tr_align=B},{"../utils/common":27}],39:[function(a,b){"use strict";function c(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}b.exports=c},{}]},{},[9])(9)});
18320 25559 // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
18321 base64zip = zip.generate(); 25560 if (!Object.keys) {
18322 25561 Object.keys = (function () {
18323 **/ 25562 var hasOwnProperty = Object.prototype.hasOwnProperty,
18324 25563 hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
18325 /** 25564 dontEnums = [
18326 * Representation a of zip file in js 25565 'toString',
18327 * @constructor 25566 'toLocaleString',
18328 * @param {String=|ArrayBuffer=|Uint8Array=} data the data to load, if any (optional). 25567 'valueOf',
18329 * @param {Object=} options the options for creating this objects (optional). 25568 'hasOwnProperty',
18330 */ 25569 'isPrototypeOf',
18331 var JSZip = function(data, options) { 25570 'propertyIsEnumerable',
18332 // object containing the files : 25571 'constructor'
18333 // { 25572 ],
18334 // "folder/" : {...}, 25573 dontEnumsLength = dontEnums.length;
18335 // "folder/data.txt" : {...} 25574
18336 // } 25575 return function (obj) {
18337 this.files = {}; 25576 if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object');
18338 25577
18339 // Where we are in the hierarchy 25578 var result = [];
18340 this.root = ""; 25579
18341 25580 for (var prop in obj) {
18342 if (data) { 25581 if (hasOwnProperty.call(obj, prop)) result.push(prop);
18343 this.load(data, options);
18344 }
18345 };
18346
18347 JSZip.signature = {
18348 LOCAL_FILE_HEADER : "\x50\x4b\x03\x04",
18349 CENTRAL_FILE_HEADER : "\x50\x4b\x01\x02",
18350 CENTRAL_DIRECTORY_END : "\x50\x4b\x05\x06",
18351 ZIP64_CENTRAL_DIRECTORY_LOCATOR : "\x50\x4b\x06\x07",
18352 ZIP64_CENTRAL_DIRECTORY_END : "\x50\x4b\x06\x06",
18353 DATA_DESCRIPTOR : "\x50\x4b\x07\x08"
18354 };
18355
18356 // Default properties for a new file
18357 JSZip.defaults = {
18358 base64: false,
18359 binary: false,
18360 dir: false,
18361 date: null
18362 };
18363
18364
18365 JSZip.prototype = (function () {
18366 /**
18367 * A simple object representing a file in the zip file.
18368 * @constructor
18369 * @param {string} name the name of the file
18370 * @param {string} data the data
18371 * @param {Object} options the options of the file
18372 */
18373 var ZipObject = function (name, data, options) {
18374 this.name = name;
18375 this.data = data;
18376 this.options = options;
18377 };
18378
18379 ZipObject.prototype = {
18380 /**
18381 * Return the content as UTF8 string.
18382 * @return {string} the UTF8 string.
18383 */
18384 asText : function () {
18385 var result = this.data;
18386 if (result === null || typeof result === "undefined") {
18387 return "";
18388 }
18389 if (this.options.base64) {
18390 result = JSZipBase64.decode(result);
18391 }
18392 if (this.options.binary) {
18393 result = JSZip.prototype.utf8decode(result);
18394 }
18395 return result;
18396 },
18397 /**
18398 * Returns the binary content.
18399 * @return {string} the content as binary.
18400 */
18401 asBinary : function () {
18402 var result = this.data;
18403 if (result === null || typeof result === "undefined") {
18404 return "";
18405 }
18406 if (this.options.base64) {
18407 result = JSZipBase64.decode(result);
18408 }
18409 if (!this.options.binary) {
18410 result = JSZip.prototype.utf8encode(result);
18411 }
18412 return result;
18413 },
18414 /**
18415 * Returns the content as an Uint8Array.
18416 * @return {Uint8Array} the content as an Uint8Array.
18417 */
18418 asUint8Array : function () {
18419 return JSZip.utils.string2Uint8Array(this.asBinary());
18420 },
18421 /**
18422 * Returns the content as an ArrayBuffer.
18423 * @return {ArrayBuffer} the content as an ArrayBufer.
18424 */
18425 asArrayBuffer : function () {
18426 return JSZip.utils.string2Uint8Array(this.asBinary()).buffer;
18427 } 25582 }
18428 }; 25583
18429 25584 if (hasDontEnumBug) {
18430 /** 25585 for (var i=0; i < dontEnumsLength; i++) {
18431 * Transform an integer into a string in hexadecimal. 25586 if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]);
18432 * @private 25587 }
18433 * @param {number} dec the number to convert.
18434 * @param {number} bytes the number of bytes to generate.
18435 * @returns {string} the result.
18436 */
18437 var decToHex = function(dec, bytes) {
18438 var hex = "", i;
18439 for(i = 0; i < bytes; i++) {
18440 hex += String.fromCharCode(dec&0xff);
18441 dec=dec>>>8;
18442 }
18443 return hex;
18444 };
18445
18446 /**
18447 * Merge the objects passed as parameters into a new one.
18448 * @private
18449 * @param {...Object} var_args All objects to merge.
18450 * @return {Object} a new object with the data of the others.
18451 */
18452 var extend = function () {
18453 var result = {}, i, attr;
18454 for (i = 0; i < arguments.length; i++) { // arguments is not enumerable in some browsers
18455 for (attr in arguments[i]) {
18456 if (arguments[i].hasOwnProperty(attr) && typeof result[attr] === "undefined") {
18457 result[attr] = arguments[i][attr];
18458 }
18459 }
18460 } 25588 }
18461 return result; 25589 return result;
18462 }; 25590 };
18463 25591 })();
18464 /** 25592 }
18465 * Transforms the (incomplete) options from the user into the complete 25593
18466 * set of options to create a file. 25594 // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
18467 * @private 25595 if (!Array.prototype.filter)
18468 * @param {Object} o the options from the user. 25596 {
18469 * @return {Object} the complete set of options. 25597 Array.prototype.filter = function(fun /*, thisp */)
18470 */ 25598 {
18471 var prepareFileAttrs = function (o) { 25599 "use strict";
18472 o = o || {}; 25600
18473 if (o.base64 === true && o.binary == null) { 25601 if (this == null)
18474 o.binary = true; 25602 throw new TypeError();
25603
25604 var t = Object(this);
25605 var len = t.length >>> 0;
25606 if (typeof fun != "function")
25607 throw new TypeError();
25608
25609 var res = [];
25610 var thisp = arguments[1];
25611 for (var i = 0; i < len; i++)
25612 {
25613 if (i in t)
25614 {
25615 var val = t[i]; // in case fun mutates this
25616 if (fun.call(thisp, val, i, t))
25617 res.push(val);
18475 } 25618 }
18476 o = extend(o, JSZip.defaults); 25619 }
18477 o.date = o.date || new Date(); 25620
18478 25621 return res;
18479 return o; 25622 };
18480 }; 25623 }
18481 25624
18482 /** 25625 // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim
18483 * Add a file in the current folder. 25626 if (!String.prototype.trim) {
18484 * @private 25627 String.prototype.trim = function () {
18485 * @param {string} name the name of the file 25628 return this.replace(/^\s+|\s+$/g, '');
18486 * @param {String|ArrayBuffer|Uint8Array} data the data of the file 25629 };
18487 * @param {Object} o the options of the file 25630 }
18488 * @return {Object} the new file. 25631
18489 */ 25632 // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
18490 var fileAdd = function (name, data, o) { 25633 if (!Array.prototype.forEach)
18491 // be sure sub folders exist 25634 {
18492 var parent = parentFolder(name); 25635 Array.prototype.forEach = function(fun /*, thisArg */)
18493 if (parent) { 25636 {
18494 folderAdd.call(this, parent); 25637 "use strict";
25638
25639 if (this === void 0 || this === null)
25640 throw new TypeError();
25641
25642 var t = Object(this);
25643 var len = t.length >>> 0;
25644 if (typeof fun !== "function")
25645 throw new TypeError();
25646
25647 var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
25648 for (var i = 0; i < len; i++)
25649 {
25650 if (i in t)
25651 fun.call(thisArg, t[i], i, t);
25652 }
25653 };
25654 }
25655
25656 // Production steps of ECMA-262, Edition 5, 15.4.4.19
25657 // Reference: http://es5.github.com/#x15.4.4.19
25658 if (!Array.prototype.map) {
25659 Array.prototype.map = function(callback, thisArg) {
25660
25661 var T, A, k;
25662
25663 if (this == null) {
25664 throw new TypeError(" this is null or not defined");
25665 }
25666
25667 // 1. Let O be the result of calling ToObject passing the |this| value as the argument.
25668 var O = Object(this);
25669
25670 // 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
25671 // 3. Let len be ToUint32(lenValue).
25672 var len = O.length >>> 0;
25673
25674 // 4. If IsCallable(callback) is false, throw a TypeError exception.
25675 // See: http://es5.github.com/#x9.11
25676 if (typeof callback !== "function") {
25677 throw new TypeError(callback + " is not a function");
25678 }
25679
25680 // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
25681 if (thisArg) {
25682 T = thisArg;
25683 }
25684
25685 // 6. Let A be a new array created as if by the expression new Array(len) where Array is
25686 // the standard built-in constructor with that name and len is the value of len.
25687 A = new Array(len);
25688
25689 // 7. Let k be 0
25690 k = 0;
25691
25692 // 8. Repeat, while k < len
25693 while(k < len) {
25694
25695 var kValue, mappedValue;
25696
25697 // a. Let Pk be ToString(k).
25698 // This is implicit for LHS operands of the in operator
25699 // b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
25700 // This step can be combined with c
25701 // c. If kPresent is true, then
25702 if (k in O) {
25703
25704 // i. Let kValue be the result of calling the Get internal method of O with argument Pk.
25705 kValue = O[ k ];
25706
25707 // ii. Let mappedValue be the result of calling the Call internal method of callback
25708 // with T as the this value and argument list containing kValue, k, and O.
25709 mappedValue = callback.call(T, kValue, k, O);
25710
25711 // iii. Call the DefineOwnProperty internal method of A with arguments
25712 // Pk, Property Descriptor {Value: mappedValue, : true, Enumerable: true, Configurable: true},
25713 // and false.
25714
25715 // In browsers that support Object.defineProperty, use the following:
25716 // Object.defineProperty(A, Pk, { value: mappedValue, writable: true, enumerable: true, configurable: true });
25717
25718 // For best browser support, use the following:
25719 A[ k ] = mappedValue;
18495 } 25720 }
18496 25721 // d. Increase k by 1.
18497 o = prepareFileAttrs(o); 25722 k++;
18498 25723 }
18499 if (o.dir || data === null || typeof data === "undefined") { 25724
18500 o.base64 = false; 25725 // 9. return A
18501 o.binary = false; 25726 return A;
18502 data = null; 25727 };
18503 } else if (JSZip.support.uint8array && data instanceof Uint8Array) { 25728 }
18504 o.base64 = false; 25729
18505 o.binary = true; 25730 // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf
18506 data = JSZip.utils.uint8Array2String(data); 25731 if (!Array.prototype.indexOf) {
18507 } else if (JSZip.support.arraybuffer && data instanceof ArrayBuffer) { 25732 Array.prototype.indexOf = function (searchElement, fromIndex) {
18508 o.base64 = false; 25733 if ( this === undefined || this === null ) {
18509 o.binary = true; 25734 throw new TypeError( '"this" is null or not defined' );
18510 var bufferView = new Uint8Array(data); 25735 }
18511 data = JSZip.utils.uint8Array2String(bufferView); 25736
18512 } else if (o.binary && !o.base64) { 25737 var length = this.length >>> 0; // Hack to convert object.length to a UInt32
18513 // optimizedBinaryString == true means that the file has already been filtered with a 0xFF mask 25738
18514 if (o.optimizedBinaryString !== true) { 25739 fromIndex = +fromIndex || 0;
18515 // this is a string, not in a base64 format. 25740
18516 // Be sure that this is a correct "binary string" 25741 if (Math.abs(fromIndex) === Infinity) {
18517 data = JSZip.utils.string2binary(data); 25742 fromIndex = 0;
18518 } 25743 }
18519 // we remove this option since it's only relevant here 25744
18520 delete o.optimizedBinaryString; 25745 if (fromIndex < 0) {
25746 fromIndex += length;
25747 if (fromIndex < 0) {
25748 fromIndex = 0;
18521 } 25749 }
18522 25750 }
18523 return this.files[name] = new ZipObject(name, data, o); 25751
18524 }; 25752 for (;fromIndex < length; fromIndex++) {
18525 25753 if (this[fromIndex] === searchElement) {
18526 25754 return fromIndex;
18527 /**
18528 * Find the parent folder of the path.
18529 * @private
18530 * @param {string} path the path to use
18531 * @return {string} the parent folder, or ""
18532 */
18533 var parentFolder = function (path) {
18534 if (path.slice(-1) == '/') {
18535 path = path.substring(0, path.length - 1);
18536 } 25755 }
18537 var lastSlash = path.lastIndexOf('/'); 25756 }
18538 return (lastSlash > 0) ? path.substring(0, lastSlash) : ""; 25757
18539 }; 25758 return -1;
18540 25759 };
18541 /** 25760 }
18542 * Add a (sub) folder in the current folder. 25761 // Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
18543 * @private 25762
18544 * @param {string} name the folder's name 25763 if (! Array.isArray) {
18545 * @return {Object} the new folder. 25764 Array.isArray = function(obj) {
18546 */ 25765 return Object.prototype.toString.call(obj) === "[object Array]";
18547 var folderAdd = function (name) { 25766 };
18548 // Check the name ends with a / 25767 }
18549 if (name.slice(-1) != "/") { 25768
18550 name += "/"; // IE doesn't like substr(-1) 25769 // https://github.com/ttaubert/node-arraybuffer-slice
18551 } 25770 // (c) 2013 Tim Taubert <tim@timtaubert.de>
18552 25771 // arraybuffer-slice may be freely distributed under the MIT license.
18553 // Does this folder already exist? 25772
18554 if (!this.files[name]) { 25773 "use strict";
18555 // be sure sub folders exist 25774
18556 var parent = parentFolder(name); 25775 if (typeof ArrayBuffer !== 'undefined' && !ArrayBuffer.prototype.slice) {
18557 if (parent) { 25776 ArrayBuffer.prototype.slice = function (begin, end) {
18558 folderAdd.call(this, parent); 25777 begin = (begin|0) || 0;
18559 } 25778 var num = this.byteLength;
18560 25779 end = end === (void 0) ? num : (end|0);
18561 fileAdd.call(this, name, null, {dir:true}); 25780
18562 } 25781 // Handle negative values.
18563 return this.files[name]; 25782 if (begin < 0) begin += num;
18564 }; 25783 if (end < 0) end += num;
18565 25784
18566 /** 25785 if (num === 0 || begin >= num || begin >= end) {
18567 * Generate the data found in the local header of a zip file. 25786 return new ArrayBuffer(0);
18568 * Do not create it now, as some parts are re-used later. 25787 }
18569 * @private 25788
18570 * @param {Object} file the file to use. 25789 var length = Math.min(num - begin, end - begin);
18571 * @param {string} utfEncodedFileName the file name, utf8 encoded. 25790 var target = new ArrayBuffer(length);
18572 * @param {string} compressionType the compression to use. 25791 var targetArray = new Uint8Array(target);
18573 * @return {Object} an object containing header and compressedData. 25792 targetArray.set(new Uint8Array(this, begin, length));
18574 */ 25793 return target;
18575 var prepareLocalHeaderData = function(file, utfEncodedFileName, compressionType) { 25794 };
18576 var useUTF8 = utfEncodedFileName !== file.name, 25795 }
18577 data = file.asBinary(), 25796 /* xls.js (C) 2013-2014 SheetJS -- http://sheetjs.com */
18578 o = file.options, 25797 var XLS={};(function make_xls(XLS){XLS.version="0.7.1";var current_codepage=1252,current_cptable;if(typeof module!=="undefined"&&typeof require!=="undefined"){if(typeof cptable==="undefined")cptable=require("./dist/cpexcel");current_cptable=cptable[current_codepage]}function reset_cp(){set_cp(1252)}function set_cp(cp){current_codepage=cp;if(typeof cptable!=="undefined")current_cptable=cptable[cp]}var _getchar=function _gc1(x){return String.fromCharCode(x)};if(typeof cptable!=="undefined")_getchar=function _gc2(x){if(current_codepage===1200)return String.fromCharCode(x);return cptable.utils.decode(current_codepage,[x&255,x>>8])[0]};var has_buf=typeof Buffer!=="undefined";function new_buf(len){return new(has_buf?Buffer:Array)(len)}var Base64=function make_b64(){var map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";return{decode:function b64_decode(input,utf8){var o="";var c1,c2,c3;var e1,e2,e3,e4;input=input.replace(/[^A-Za-z0-9\+\/\=]/g,"");for(var i=0;i<input.length;){e1=map.indexOf(input.charAt(i++));e2=map.indexOf(input.charAt(i++));e3=map.indexOf(input.charAt(i++));e4=map.indexOf(input.charAt(i++));c1=e1<<2|e2>>4;c2=(e2&15)<<4|e3>>2;c3=(e3&3)<<6|e4;o+=String.fromCharCode(c1);if(e3!=64){o+=String.fromCharCode(c2)}if(e4!=64){o+=String.fromCharCode(c3)}}return o}}}();function s2a(s){if(has_buf)return new Buffer(s,"binary");var w=s.split("").map(function(x){return x.charCodeAt(0)&255});return w}function readIEEE754(buf,idx,isLE,nl,ml){if(isLE===undefined)isLE=true;if(!nl)nl=8;if(!ml&&nl===8)ml=52;var e,m,el=nl*8-ml-1,eMax=(1<<el)-1,eBias=eMax>>1;var bits=-7,d=isLE?-1:1,i=isLE?nl-1:0,s=buf[idx+i];i+=d;e=s&(1<<-bits)-1;s>>>=-bits;bits+=el;for(;bits>0;e=e*256+buf[idx+i],i+=d,bits-=8);m=e&(1<<-bits)-1;e>>>=-bits;bits+=ml;for(;bits>0;m=m*256+buf[idx+i],i+=d,bits-=8);if(e===eMax)return m?NaN:(s?-1:1)*Infinity;else if(e===0)e=1-eBias;else{m=m+Math.pow(2,ml);e=e-eBias}return(s?-1:1)*m*Math.pow(2,e-ml)}var chr0=/\u0000/g,chr1=/[\u0001-\u0006]/;var __toBuffer,___toBuffer;__toBuffer=___toBuffer=function toBuffer_(bufs){var x=[];for(var i=0;i<bufs[0].length;++i){x.push.apply(x,bufs[0][i])}return x};var __utf16le,___utf16le;__utf16le=___utf16le=function utf16le_(b,s,e){var ss=[];for(var i=s;i<e;i+=2)ss.push(String.fromCharCode(__readUInt16LE(b,i)));return ss.join("")};var __hexlify,___hexlify;__hexlify=___hexlify=function hexlify_(b,s,l){return b.slice(s,s+l).map(function(x){return(x<16?"0":"")+x.toString(16)}).join("")};var __utf8,___utf8;__utf8=___utf8=function(b,s,e){var ss=[];for(var i=s;i<e;i++)ss.push(String.fromCharCode(__readUInt8(b,i)));return ss.join("")};var __lpstr,___lpstr;__lpstr=___lpstr=function lpstr_(b,i){var len=__readUInt32LE(b,i);return len>0?__utf8(b,i+4,i+4+len-1):""};var __lpwstr,___lpwstr;__lpwstr=___lpwstr=function lpwstr_(b,i){var len=2*__readUInt32LE(b,i);return len>0?__utf8(b,i+4,i+4+len-1):""};var __double,___double;__double=___double=function(b,idx){return readIEEE754(b,idx)};var bconcat=function(bufs){return[].concat.apply([],bufs)};if(typeof Buffer!=="undefined"){__utf16le=function utf16le_b(b,s,e){if(!Buffer.isBuffer(b))return ___utf16le(b,s,e);return b.toString("utf16le",s,e)};__hexlify=function(b,s,l){return Buffer.isBuffer(b)?b.toString("hex",s,s+l):___hexlify(b,s,l)};__lpstr=function lpstr_b(b,i){if(!Buffer.isBuffer(b))return ___lpstr(b,i);var len=b.readUInt32LE(i);return len>0?b.toString("utf8",i+4,i+4+len-1):""};__lpwstr=function lpwstr_b(b,i){if(!Buffer.isBuffer(b))return ___lpwstr(b,i);var len=2*b.readUInt32LE(i);return b.toString("utf16le",i+4,i+4+len-1)};__utf8=function utf8_b(s,e){return this.toString("utf8",s,e)};__toBuffer=function(bufs){return bufs[0].length>0&&Buffer.isBuffer(bufs[0][0])?Buffer.concat(bufs[0]):___toBuffer(bufs)};bconcat=function(bufs){return Buffer.isBuffer(bufs[0])?Buffer.concat(bufs):[].concat.apply([],bufs)};__double=function double_(b,i){if(Buffer.isBuffer(b))return b.readDoubleLE(i);return ___double(b,i)}}var __readUInt8=function(b,idx){return b[idx]};var __readUInt16LE=function(b,idx){return b[idx+1]*(1<<8)+b[idx]};var __readInt16LE=function(b,idx){var u=b[idx+1]*(1<<8)+b[idx];return u<32768?u:(65535-u+1)*-1};var __readUInt32LE=function(b,idx){return b[idx+3]*(1<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]};var __readInt32LE=function(b,idx){return b[idx+3]<<24|b[idx+2]<<16|b[idx+1]<<8|b[idx]};var ___unhexlify=function(s){return s.match(/../g).map(function(x){return parseInt(x,16)})};var __unhexlify=typeof Buffer!=="undefined"?function(s){return Buffer.isBuffer(s)?new Buffer(s,"hex"):___unhexlify(s)}:___unhexlify;if(typeof cptable!=="undefined"){__utf16le=function(b,s,e){return cptable.utils.decode(1200,b.slice(s,e))};__utf8=function(b,s,e){return cptable.utils.decode(65001,b.slice(s,e))};__lpstr=function(b,i){var len=__readUInt32LE(b,i);return len>0?cptable.utils.decode(current_codepage,b.slice(i+4,i+4+len-1)):""};__lpwstr=function(b,i){var len=2*__readUInt32LE(b,i);return len>0?cptable.utils.decode(1200,b.slice(i+4,i+4+len-1)):""}}function ReadShift(size,t){var o,oI,oR,oo=[],w,vv,i,loc;switch(t){case"lpstr":o=__lpstr(this,this.l);size=5+o.length;break;case"lpwstr":o=__lpwstr(this,this.l);size=5+o.length;if(o[o.length-1]=="\x00")size+=2;break;case"cstr":size=0;o="";while((w=__readUInt8(this,this.l+size++))!==0)oo.push(_getchar(w));o=oo.join("");break;case"wstr":size=0;o="";while((w=__readUInt16LE(this,this.l+size))!==0){oo.push(_getchar(w));size+=2}size+=2;o=oo.join("");break;case"dbcs":o="";loc=this.l;for(i=0;i!=size;++i){if(this.lens&&this.lens.indexOf(loc)!==-1){w=__readUInt8(this,loc);this.l=loc+1;vv=ReadShift.call(this,size-i,w?"dbcs":"sbcs");return oo.join("")+vv}oo.push(_getchar(__readUInt16LE(this,loc)));loc+=2}o=oo.join("");size*=2;break;case"sbcs":o="";loc=this.l;for(i=0;i!=size;++i){if(this.lens&&this.lens.indexOf(loc)!==-1){w=__readUInt8(this,loc);this.l=loc+1;vv=ReadShift.call(this,size-i,w?"dbcs":"sbcs");return oo.join("")+vv}oo.push(_getchar(__readUInt8(this,loc)));loc+=1}o=oo.join("");break;case"utf8":o=__utf8(this,this.l,this.l+size);break;case"utf16le":size*=2;o=__utf16le(this,this.l,this.l+size);break;default:switch(size){case 1:oI=__readUInt8(this,this.l);this.l++;return oI;case 2:oI=t!=="i"?__readUInt16LE(this,this.l):__readInt16LE(this,this.l);this.l+=2;return oI;case 4:if(t==="i"||(this[this.l+3]&128)===0){oI=__readInt32LE(this,this.l);this.l+=4;return oI}else{oR=__readUInt32LE(this,this.l);this.l+=4;return oR}break;case 8:if(t==="f"){oR=__double(this,this.l);this.l+=8;return oR}case 16:o=__hexlify(this,this.l,size);break}}this.l+=size;return o}function CheckField(hexstr,fld){var m=__hexlify(this,this.l,hexstr.length>>1);if(m!==hexstr)throw fld+"Expected "+hexstr+" saw "+m;this.l+=hexstr.length>>1}function prep_blob(blob,pos){blob.l=pos;blob.read_shift=ReadShift;blob.chk=CheckField}var SSF={};var make_ssf=function make_ssf(SSF){SSF.version="0.8.1";function _strrev(x){var o="",i=x.length-1;while(i>=0)o+=x.charAt(i--);return o}function fill(c,l){var o="";while(o.length<l)o+=c;return o}function pad0(v,d){var t=""+v;return t.length>=d?t:fill("0",d-t.length)+t}function pad_(v,d){var t=""+v;return t.length>=d?t:fill(" ",d-t.length)+t}function rpad_(v,d){var t=""+v;return t.length>=d?t:t+fill(" ",d-t.length)}function pad0r1(v,d){var t=""+Math.round(v);return t.length>=d?t:fill("0",d-t.length)+t}function pad0r2(v,d){var t=""+v;return t.length>=d?t:fill("0",d-t.length)+t}var p2_32=Math.pow(2,32);function pad0r(v,d){if(v>p2_32||v<-p2_32)return pad0r1(v,d);var i=Math.round(v);return pad0r2(i,d)}function isgeneral(s,i){return s.length>=7+i&&(s.charCodeAt(i)|32)===103&&(s.charCodeAt(i+1)|32)===101&&(s.charCodeAt(i+2)|32)===110&&(s.charCodeAt(i+3)|32)===101&&(s.charCodeAt(i+4)|32)===114&&(s.charCodeAt(i+5)|32)===97&&(s.charCodeAt(i+6)|32)===108}var opts_fmt=[["date1904",0],["output",""],["WTF",false]];function fixopts(o){for(var y=0;y!=opts_fmt.length;++y)if(o[opts_fmt[y][0]]===undefined)o[opts_fmt[y][0]]=opts_fmt[y][1]}SSF.opts=opts_fmt;var table_fmt={0:"General",1:"0",2:"0.00",3:"#,##0",4:"#,##0.00",9:"0%",10:"0.00%",11:"0.00E+00",12:"# ?/?",13:"# ??/??",14:"m/d/yy",15:"d-mmm-yy",16:"d-mmm",17:"mmm-yy",18:"h:mm AM/PM",19:"h:mm:ss AM/PM",20:"h:mm",21:"h:mm:ss",22:"m/d/yy h:mm",37:"#,##0 ;(#,##0)",38:"#,##0 ;[Red](#,##0)",39:"#,##0.00;(#,##0.00)",40:"#,##0.00;[Red](#,##0.00)",45:"mm:ss",46:"[h]:mm:ss",47:"mmss.0",48:"##0.0E+0",49:"@",56:'"上午/下午 "hh"時"mm"分"ss"秒 "',65535:"General"};var days=[["Sun","Sunday"],["Mon","Monday"],["Tue","Tuesday"],["Wed","Wednesday"],["Thu","Thursday"],["Fri","Friday"],["Sat","Saturday"]];var months=[["J","Jan","January"],["F","Feb","February"],["M","Mar","March"],["A","Apr","April"],["M","May","May"],["J","Jun","June"],["J","Jul","July"],["A","Aug","August"],["S","Sep","September"],["O","Oct","October"],["N","Nov","November"],["D","Dec","December"]];function frac(x,D,mixed){var sgn=x<0?-1:1;var B=x*sgn;var P_2=0,P_1=1,P=0;var Q_2=1,Q_1=0,Q=0;var A=Math.floor(B);while(Q_1<D){A=Math.floor(B);P=A*P_1+P_2;Q=A*Q_1+Q_2;if(B-A<5e-10)break;B=1/(B-A);P_2=P_1;P_1=P;Q_2=Q_1;Q_1=Q}if(Q>D){Q=Q_1;P=P_1}if(Q>D){Q=Q_2;P=P_2}if(!mixed)return[0,sgn*P,Q];if(Q===0)throw"Unexpected state: "+P+" "+P_1+" "+P_2+" "+Q+" "+Q_1+" "+Q_2;var q=Math.floor(sgn*P/Q);return[q,sgn*P-q*Q,Q]}function general_fmt_int(v,opts){return""+v}SSF._general_int=general_fmt_int;var general_fmt_num=function make_general_fmt_num(){var gnr1=/\.(\d*[1-9])0+$/,gnr2=/\.0*$/,gnr4=/\.(\d*[1-9])0+/,gnr5=/\.0*[Ee]/,gnr6=/(E[+-])(\d)$/;function gfn2(v){var w=v<0?12:11;var o=gfn5(v.toFixed(12));if(o.length<=w)return o;o=v.toPrecision(10);if(o.length<=w)return o;return v.toExponential(5)}function gfn3(v){var o=v.toFixed(11).replace(gnr1,".$1");if(o.length>(v<0?12:11))o=v.toPrecision(6);return o}function gfn4(o){for(var i=0;i!=o.length;++i)if((o.charCodeAt(i)|32)===101)return o.replace(gnr4,".$1").replace(gnr5,"E").replace("e","E").replace(gnr6,"$10$2");return o}function gfn5(o){return o.indexOf(".")>-1?o.replace(gnr2,"").replace(gnr1,".$1"):o}return function general_fmt_num(v,opts){var V=Math.floor(Math.log(Math.abs(v))*Math.LOG10E),o;if(V>=-4&&V<=-1)o=v.toPrecision(10+V);else if(Math.abs(V)<=9)o=gfn2(v);else if(V===10)o=v.toFixed(10).substr(0,12);else o=gfn3(v);return gfn5(gfn4(o))}}();SSF._general_num=general_fmt_num;function general_fmt(v,opts){switch(typeof v){case"string":return v;case"boolean":return v?"TRUE":"FALSE";case"number":return(v|0)===v?general_fmt_int(v,opts):general_fmt_num(v,opts)}throw new Error("unsupported value in General format: "+v)}SSF._general=general_fmt;function fix_hijri(date,o){return 0}function parse_date_code(v,opts,b2){if(v>2958465||v<0)return null;var date=v|0,time=Math.floor(86400*(v-date)),dow=0;var dout=[];var out={D:date,T:time,u:86400*(v-date)-time,y:0,m:0,d:0,H:0,M:0,S:0,q:0};if(Math.abs(out.u)<1e-6)out.u=0;fixopts(opts!=null?opts:opts=[]);if(opts.date1904)date+=1462;if(out.u>.999){out.u=0;if(++time==86400){time=0;++date}}if(date===60){dout=b2?[1317,10,29]:[1900,2,29];dow=3}else if(date===0){dout=b2?[1317,8,29]:[1900,1,0];dow=6}else{if(date>60)--date;var d=new Date(1900,0,1);d.setDate(d.getDate()+date-1);dout=[d.getFullYear(),d.getMonth()+1,d.getDate()];dow=d.getDay();if(date<60)dow=(dow+6)%7;if(b2)dow=fix_hijri(d,dout)}out.y=dout[0];out.m=dout[1];out.d=dout[2];out.S=time%60;time=Math.floor(time/60);out.M=time%60;time=Math.floor(time/60);out.H=time;out.q=dow;return out}SSF.parse_date_code=parse_date_code;function write_date(type,fmt,val,ss0){var o="",ss=0,tt=0,y=val.y,out,outl=0;switch(type){case 98:y=val.y+543;case 121:switch(fmt.length){case 1:case 2:out=y%100;outl=2;break;default:out=y%1e4;outl=4;break}break;case 109:switch(fmt.length){case 1:case 2:out=val.m;outl=fmt.length;break;case 3:return months[val.m-1][1];case 5:return months[val.m-1][0];default:return months[val.m-1][2]}break;case 100:switch(fmt.length){case 1:case 2:out=val.d;outl=fmt.length;break;case 3:return days[val.q][0];default:return days[val.q][1]}break;case 104:switch(fmt.length){case 1:case 2:out=1+(val.H+11)%12;outl=fmt.length;break;default:throw"bad hour format: "+fmt}break;case 72:switch(fmt.length){case 1:case 2:out=val.H;outl=fmt.length;break;default:throw"bad hour format: "+fmt}break;case 77:switch(fmt.length){case 1:case 2:out=val.M;outl=fmt.length;break;default:throw"bad minute format: "+fmt}break;case 115:if(val.u===0)switch(fmt){case"s":case"ss":return pad0(val.S,fmt.length);case".0":case".00":case".000":}switch(fmt){case"s":case"ss":case".0":case".00":case".000":if(ss0>=2)tt=ss0===3?1e3:100;else tt=ss0===1?10:1;ss=Math.round(tt*(val.S+val.u));if(ss>=60*tt)ss=0;if(fmt==="s")return ss===0?"0":""+ss/tt;o=pad0(ss,2+ss0);if(fmt==="ss")return o.substr(0,2);return"."+o.substr(2,fmt.length-1);default:throw"bad second format: "+fmt}case 90:switch(fmt){case"[h]":case"[hh]":out=val.D*24+val.H;break;case"[m]":case"[mm]":out=(val.D*24+val.H)*60+val.M;break;case"[s]":case"[ss]":out=((val.D*24+val.H)*60+val.M)*60+Math.round(val.S+val.u);break;default:throw"bad abstime format: "+fmt}outl=fmt.length===3?1:2;break;case 101:out=y;outl=1}if(outl>0)return pad0(out,outl);else return""}function commaify(s){if(s.length<=3)return s;var j=s.length%3,o=s.substr(0,j);for(;j!=s.length;j+=3)o+=(o.length>0?",":"")+s.substr(j,3);return o}var write_num=function make_write_num(){var pct1=/%/g;function write_num_pct(type,fmt,val){var sfmt=fmt.replace(pct1,""),mul=fmt.length-sfmt.length;return write_num(type,sfmt,val*Math.pow(10,2*mul))+fill("%",mul)}function write_num_cm(type,fmt,val){var idx=fmt.length-1;while(fmt.charCodeAt(idx-1)===44)--idx;return write_num(type,fmt.substr(0,idx),val/Math.pow(10,3*(fmt.length-idx)))}function write_num_exp(fmt,val){var o;var idx=fmt.indexOf("E")-fmt.indexOf(".")-1;if(fmt.match(/^#+0.0E\+0$/)){var period=fmt.indexOf(".");if(period===-1)period=fmt.indexOf("E");var ee=Math.floor(Math.log(Math.abs(val))*Math.LOG10E)%period;if(ee<0)ee+=period;o=(val/Math.pow(10,ee)).toPrecision(idx+1+(period+ee)%period);if(o.indexOf("e")===-1){var fakee=Math.floor(Math.log(Math.abs(val))*Math.LOG10E);if(o.indexOf(".")===-1)o=o[0]+"."+o.substr(1)+"E+"+(fakee-o.length+ee);else o+="E+"+(fakee-ee);while(o.substr(0,2)==="0."){o=o[0]+o.substr(2,period)+"."+o.substr(2+period);o=o.replace(/^0+([1-9])/,"$1").replace(/^0+\./,"0.")}o=o.replace(/\+-/,"-")}o=o.replace(/^([+-]?)(\d*)\.(\d*)[Ee]/,function($$,$1,$2,$3){return $1+$2+$3.substr(0,(period+ee)%period)+"."+$3.substr(ee)+"E"})}else o=val.toExponential(idx);if(fmt.match(/E\+00$/)&&o.match(/e[+-]\d$/))o=o.substr(0,o.length-1)+"0"+o[o.length-1];if(fmt.match(/E\-/)&&o.match(/e\+/))o=o.replace(/e\+/,"e");return o.replace("e","E")}var frac1=/# (\?+)( ?)\/( ?)(\d+)/;function write_num_f1(r,aval,sign){var den=parseInt(r[4]),rr=Math.round(aval*den),base=Math.floor(rr/den);var myn=rr-base*den,myd=den;return sign+(base===0?"":""+base)+" "+(myn===0?fill(" ",r[1].length+1+r[4].length):pad_(myn,r[1].length)+r[2]+"/"+r[3]+pad0(myd,r[4].length))}function write_num_f2(r,aval,sign){return sign+(aval===0?"":""+aval)+fill(" ",r[1].length+2+r[4].length)}var dec1=/^#*0*\.(0+)/;var closeparen=/\).*[0#]/;var phone=/\(###\) ###\\?-####/;function hashq(str){var o="",cc;for(var i=0;i!=str.length;++i)switch(cc=str.charCodeAt(i)){case 35:break;case 63:o+=" ";break;case 48:o+="0";break;default:o+=String.fromCharCode(cc)}return o}function rnd(val,d){var dd=Math.pow(10,d);return""+Math.round(val*dd)/dd}function dec(val,d){return Math.round((val-Math.floor(val))*Math.pow(10,d))}function flr(val){if(val<2147483647&&val>-2147483648)return""+(val>=0?val|0:val-1|0);return""+Math.floor(val)}function write_num_flt(type,fmt,val){if(type.charCodeAt(0)===40&&!fmt.match(closeparen)){var ffmt=fmt.replace(/\( */,"").replace(/ \)/,"").replace(/\)/,"");if(val>=0)return write_num_flt("n",ffmt,val);return"("+write_num_flt("n",ffmt,-val)+")"}if(fmt.charCodeAt(fmt.length-1)===44)return write_num_cm(type,fmt,val);if(fmt.indexOf("%")!==-1)return write_num_pct(type,fmt,val);if(fmt.indexOf("E")!==-1)return write_num_exp(fmt,val);if(fmt.charCodeAt(0)===36)return"$"+write_num_flt(type,fmt.substr(fmt[1]==" "?2:1),val);var o,oo;var r,ri,ff,aval=Math.abs(val),sign=val<0?"-":"";if(fmt.match(/^00+$/))return sign+pad0r(aval,fmt.length);if(fmt.match(/^[#?]+$/)){o=pad0r(val,0);if(o==="0")o="";return o.length>fmt.length?o:hashq(fmt.substr(0,fmt.length-o.length))+o}if((r=fmt.match(frac1))!==null)return write_num_f1(r,aval,sign);if(fmt.match(/^#+0+$/)!==null)return sign+pad0r(aval,fmt.length-fmt.indexOf("0"));if((r=fmt.match(dec1))!==null){o=rnd(val,r[1].length).replace(/^([^\.]+)$/,"$1."+r[1]).replace(/\.$/,"."+r[1]).replace(/\.(\d*)$/,function($$,$1){return"."+$1+fill("0",r[1].length-$1.length)});return fmt.indexOf("0.")!==-1?o:o.replace(/^0\./,".")}fmt=fmt.replace(/^#+([0.])/,"$1");if((r=fmt.match(/^(0*)\.(#*)$/))!==null){return sign+rnd(aval,r[2].length).replace(/\.(\d*[1-9])0*$/,".$1").replace(/^(-?\d*)$/,"$1.").replace(/^0\./,r[1].length?"0.":".")}if((r=fmt.match(/^#,##0(\.?)$/))!==null)return sign+commaify(pad0r(aval,0));if((r=fmt.match(/^#,##0\.([#0]*0)$/))!==null){return val<0?"-"+write_num_flt(type,fmt,-val):commaify(""+Math.floor(val))+"."+pad0(dec(val,r[1].length),r[1].length)}if((r=fmt.match(/^#,#*,#0/))!==null)return write_num_flt(type,fmt.replace(/^#,#*,/,""),val);if((r=fmt.match(/^([0#]+)(\\?-([0#]+))+$/))!==null){o=_strrev(write_num_flt(type,fmt.replace(/[\\-]/g,""),val));ri=0;return _strrev(_strrev(fmt.replace(/\\/g,"")).replace(/[0#]/g,function(x){return ri<o.length?o[ri++]:x==="0"?"0":""}))}if(fmt.match(phone)!==null){o=write_num_flt(type,"##########",val);return"("+o.substr(0,3)+") "+o.substr(3,3)+"-"+o.substr(6)}var oa="";if((r=fmt.match(/^([#0?]+)( ?)\/( ?)([#0?]+)/))!==null){ri=Math.min(r[4].length,7);ff=frac(aval,Math.pow(10,ri)-1,false);o=""+sign;oa=write_num("n",r[1],ff[1]);if(oa[oa.length-1]==" ")oa=oa.substr(0,oa.length-1)+"0";o+=oa+r[2]+"/"+r[3];oa=rpad_(ff[2],ri);if(oa.length<r[4].length)oa=hashq(r[4].substr(r[4].length-oa.length))+oa;o+=oa;return o}if((r=fmt.match(/^# ([#0?]+)( ?)\/( ?)([#0?]+)/))!==null){ri=Math.min(Math.max(r[1].length,r[4].length),7);ff=frac(aval,Math.pow(10,ri)-1,true);return sign+(ff[0]||(ff[1]?"":"0"))+" "+(ff[1]?pad_(ff[1],ri)+r[2]+"/"+r[3]+rpad_(ff[2],ri):fill(" ",2*ri+1+r[2].length+r[3].length))}if((r=fmt.match(/^[#0?]+$/))!==null){o=pad0r(val,0);if(fmt.length<=o.length)return o;return hashq(fmt.substr(0,fmt.length-o.length))+o}if((r=fmt.match(/^([#0?]+)\.([#0]+)$/))!==null){o=""+val.toFixed(Math.min(r[2].length,10)).replace(/([^0])0+$/,"$1");ri=o.indexOf(".");var lres=fmt.indexOf(".")-ri,rres=fmt.length-o.length-lres;return hashq(fmt.substr(0,lres)+o+fmt.substr(fmt.length-rres))}if((r=fmt.match(/^00,000\.([#0]*0)$/))!==null){ri=dec(val,r[1].length);return val<0?"-"+write_num_flt(type,fmt,-val):commaify(flr(val)).replace(/^\d,\d{3}$/,"0$&").replace(/^\d*$/,function($$){return"00,"+($$.length<3?pad0(0,3-$$.length):"")+$$})+"."+pad0(ri,r[1].length)}switch(fmt){case"#,###":var x=commaify(pad0r(aval,0));return x!=="0"?sign+x:"";default:}throw new Error("unsupported format |"+fmt+"|")}function write_num_cm2(type,fmt,val){var idx=fmt.length-1;while(fmt.charCodeAt(idx-1)===44)--idx;return write_num(type,fmt.substr(0,idx),val/Math.pow(10,3*(fmt.length-idx)))}function write_num_pct2(type,fmt,val){var sfmt=fmt.replace(pct1,""),mul=fmt.length-sfmt.length;return write_num(type,sfmt,val*Math.pow(10,2*mul))+fill("%",mul)}function write_num_exp2(fmt,val){var o;var idx=fmt.indexOf("E")-fmt.indexOf(".")-1;if(fmt.match(/^#+0.0E\+0$/)){var period=fmt.indexOf(".");if(period===-1)period=fmt.indexOf("E");var ee=Math.floor(Math.log(Math.abs(val))*Math.LOG10E)%period;if(ee<0)ee+=period;o=(val/Math.pow(10,ee)).toPrecision(idx+1+(period+ee)%period);if(!o.match(/[Ee]/)){var fakee=Math.floor(Math.log(Math.abs(val))*Math.LOG10E);if(o.indexOf(".")===-1)o=o[0]+"."+o.substr(1)+"E+"+(fakee-o.length+ee);else o+="E+"+(fakee-ee);o=o.replace(/\+-/,"-")}o=o.replace(/^([+-]?)(\d*)\.(\d*)[Ee]/,function($$,$1,$2,$3){return $1+$2+$3.substr(0,(period+ee)%period)+"."+$3.substr(ee)+"E"})}else o=val.toExponential(idx);if(fmt.match(/E\+00$/)&&o.match(/e[+-]\d$/))o=o.substr(0,o.length-1)+"0"+o[o.length-1];if(fmt.match(/E\-/)&&o.match(/e\+/))o=o.replace(/e\+/,"e");return o.replace("e","E")}function write_num_int(type,fmt,val){if(type.charCodeAt(0)===40&&!fmt.match(closeparen)){var ffmt=fmt.replace(/\( */,"").replace(/ \)/,"").replace(/\)/,"");if(val>=0)return write_num_int("n",ffmt,val);return"("+write_num_int("n",ffmt,-val)+")"}if(fmt.charCodeAt(fmt.length-1)===44)return write_num_cm2(type,fmt,val);if(fmt.indexOf("%")!==-1)return write_num_pct2(type,fmt,val);if(fmt.indexOf("E")!==-1)return write_num_exp2(fmt,val);if(fmt.charCodeAt(0)===36)return"$"+write_num_int(type,fmt.substr(fmt[1]==" "?2:1),val);var o;var r,ri,ff,aval=Math.abs(val),sign=val<0?"-":"";if(fmt.match(/^00+$/))return sign+pad0(aval,fmt.length);if(fmt.match(/^[#?]+$/)){o=""+val;if(val===0)o="";return o.length>fmt.length?o:hashq(fmt.substr(0,fmt.length-o.length))+o}if((r=fmt.match(frac1))!==null)return write_num_f2(r,aval,sign);if(fmt.match(/^#+0+$/)!==null)return sign+pad0(aval,fmt.length-fmt.indexOf("0"));if((r=fmt.match(dec1))!==null){o=(""+val).replace(/^([^\.]+)$/,"$1."+r[1]).replace(/\.$/,"."+r[1]).replace(/\.(\d*)$/,function($$,$1){return"."+$1+fill("0",r[1].length-$1.length)});return fmt.indexOf("0.")!==-1?o:o.replace(/^0\./,".")}fmt=fmt.replace(/^#+([0.])/,"$1");if((r=fmt.match(/^(0*)\.(#*)$/))!==null){return sign+(""+aval).replace(/\.(\d*[1-9])0*$/,".$1").replace(/^(-?\d*)$/,"$1.").replace(/^0\./,r[1].length?"0.":".")}if((r=fmt.match(/^#,##0(\.?)$/))!==null)return sign+commaify(""+aval);if((r=fmt.match(/^#,##0\.([#0]*0)$/))!==null){return val<0?"-"+write_num_int(type,fmt,-val):commaify(""+val)+"."+fill("0",r[1].length)}if((r=fmt.match(/^#,#*,#0/))!==null)return write_num_int(type,fmt.replace(/^#,#*,/,""),val);if((r=fmt.match(/^([0#]+)(\\?-([0#]+))+$/))!==null){o=_strrev(write_num_int(type,fmt.replace(/[\\-]/g,""),val));ri=0;return _strrev(_strrev(fmt.replace(/\\/g,"")).replace(/[0#]/g,function(x){return ri<o.length?o[ri++]:x==="0"?"0":""}))}if(fmt.match(phone)!==null){o=write_num_int(type,"##########",val);return"("+o.substr(0,3)+") "+o.substr(3,3)+"-"+o.substr(6)}var oa="";if((r=fmt.match(/^([#0?]+)( ?)\/( ?)([#0?]+)/))!==null){ri=Math.min(r[4].length,7);ff=frac(aval,Math.pow(10,ri)-1,false);o=""+sign;oa=write_num("n",r[1],ff[1]);if(oa[oa.length-1]==" ")oa=oa.substr(0,oa.length-1)+"0";o+=oa+r[2]+"/"+r[3];oa=rpad_(ff[2],ri);if(oa.length<r[4].length)oa=hashq(r[4].substr(r[4].length-oa.length))+oa;o+=oa;return o}if((r=fmt.match(/^# ([#0?]+)( ?)\/( ?)([#0?]+)/))!==null){ri=Math.min(Math.max(r[1].length,r[4].length),7);ff=frac(aval,Math.pow(10,ri)-1,true);return sign+(ff[0]||(ff[1]?"":"0"))+" "+(ff[1]?pad_(ff[1],ri)+r[2]+"/"+r[3]+rpad_(ff[2],ri):fill(" ",2*ri+1+r[2].length+r[3].length))}if((r=fmt.match(/^[#0?]+$/))!==null){o=""+val;if(fmt.length<=o.length)return o;return hashq(fmt.substr(0,fmt.length-o.length))+o}if((r=fmt.match(/^([#0]+)\.([#0]+)$/))!==null){o=""+val.toFixed(Math.min(r[2].length,10)).replace(/([^0])0+$/,"$1");ri=o.indexOf(".");var lres=fmt.indexOf(".")-ri,rres=fmt.length-o.length-lres;return hashq(fmt.substr(0,lres)+o+fmt.substr(fmt.length-rres))}if((r=fmt.match(/^00,000\.([#0]*0)$/))!==null){return val<0?"-"+write_num_int(type,fmt,-val):commaify(""+val).replace(/^\d,\d{3}$/,"0$&").replace(/^\d*$/,function($$){return"00,"+($$.length<3?pad0(0,3-$$.length):"")+$$})+"."+pad0(0,r[1].length)}switch(fmt){case"#,###":var x=commaify(""+aval);return x!=="0"?sign+x:"";default:}throw new Error("unsupported format |"+fmt+"|")}return function write_num(type,fmt,val){return(val|0)===val?write_num_int(type,fmt,val):write_num_flt(type,fmt,val)}}();function split_fmt(fmt){var out=[];var in_str=false,cc;for(var i=0,j=0;i<fmt.length;++i)switch(cc=fmt.charCodeAt(i)){case 34:in_str=!in_str;break;case 95:case 42:case 92:++i;break;case 59:out[out.length]=fmt.substr(j,i-j);j=i+1}out[out.length]=fmt.substr(j);if(in_str===true)throw new Error("Format |"+fmt+"| unterminated string ");return out}SSF._split=split_fmt;var abstime=/\[[HhMmSs]*\]/;function eval_fmt(fmt,v,opts,flen){var out=[],o="",i=0,c="",lst="t",q,dt,j,cc;var hr="H";while(i<fmt.length){switch(c=fmt[i]){case"G":if(!isgeneral(fmt,i))throw new Error("unrecognized character "+c+" in "+fmt);out[out.length]={t:"G",v:"General"};i+=7;break;case'"':for(o="";(cc=fmt.charCodeAt(++i))!==34&&i<fmt.length;)o+=String.fromCharCode(cc);out[out.length]={t:"t",v:o};++i;break;case"\\":var w=fmt[++i],t=w==="("||w===")"?w:"t";out[out.length]={t:t,v:w};++i;break;case"_":out[out.length]={t:"t",v:" "};i+=2;break;case"@":out[out.length]={t:"T",v:v};++i;break;case"B":case"b":if(fmt[i+1]==="1"||fmt[i+1]==="2"){if(dt==null){dt=parse_date_code(v,opts,fmt[i+1]==="2");if(dt==null)return""}out[out.length]={t:"X",v:fmt.substr(i,2)};lst=c;i+=2;break}case"M":case"D":case"Y":case"H":case"S":case"E":c=c.toLowerCase();case"m":case"d":case"y":case"h":case"s":case"e":case"g":if(v<0)return"";if(dt==null){dt=parse_date_code(v,opts);if(dt==null)return""}o=c;while(++i<fmt.length&&fmt[i].toLowerCase()===c)o+=c;if(c==="m"&&lst.toLowerCase()==="h")c="M";if(c==="h")c=hr;out[out.length]={t:c,v:o};lst=c;break;case"A":q={t:c,v:"A"};if(dt==null)dt=parse_date_code(v,opts);if(fmt.substr(i,3)==="A/P"){if(dt!=null)q.v=dt.H>=12?"P":"A";q.t="T";hr="h";i+=3}else if(fmt.substr(i,5)==="AM/PM"){if(dt!=null)q.v=dt.H>=12?"PM":"AM";q.t="T";i+=5;hr="h"}else{q.t="t";++i}if(dt==null&&q.t==="T")return"";out[out.length]=q;lst=c;break;case"[":o=c;while(fmt[i++]!=="]"&&i<fmt.length)o+=fmt[i];if(o.substr(-1)!=="]")throw'unterminated "[" block: |'+o+"|";if(o.match(abstime)){if(dt==null){dt=parse_date_code(v,opts);if(dt==null)return""}out[out.length]={t:"Z",v:o.toLowerCase()}}else{o=""}break;case".":if(dt!=null){o=c;while((c=fmt[++i])==="0")o+=c;out[out.length]={t:"s",v:o};break}case"0":case"#":o=c;while("0#?.,E+-%".indexOf(c=fmt[++i])>-1||c=="\\"&&fmt[i+1]=="-"&&"0#".indexOf(fmt[i+2])>-1)o+=c;out[out.length]={t:"n",v:o};break;case"?":o=c;while(fmt[++i]===c)o+=c;q={t:c,v:o};out[out.length]=q;lst=c;break;case"*":++i;if(fmt[i]==" "||fmt[i]=="*")++i;break;case"(":case")":out[out.length]={t:flen===1?"t":c,v:c};++i;break;case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":o=c;while("0123456789".indexOf(fmt[++i])>-1)o+=fmt[i];out[out.length]={t:"D",v:o};break;case" ":out[out.length]={t:c,v:c};++i;break;default:if(",$-+/():!^&'~{}<>=€acfijklopqrtuvwxz".indexOf(c)===-1)throw new Error("unrecognized character "+c+" in "+fmt);out[out.length]={t:"t",v:c};++i;break}}var bt=0,ss0=0,ssm;for(i=out.length-1,lst="t";i>=0;--i){switch(out[i].t){case"h":case"H":out[i].t=hr;lst="h";if(bt<1)bt=1;break;case"s":if(ssm=out[i].v.match(/\.0+$/))ss0=Math.max(ss0,ssm[0].length-1);if(bt<3)bt=3;case"d":case"y":case"M":case"e":lst=out[i].t;break;case"m":if(lst==="s"){out[i].t="M";if(bt<2)bt=2}break;case"X":if(out[i].v==="B2");break;case"Z":if(bt<1&&out[i].v.match(/[Hh]/))bt=1;if(bt<2&&out[i].v.match(/[Mm]/))bt=2;if(bt<3&&out[i].v.match(/[Ss]/))bt=3}}switch(bt){case 0:break;case 1:if(dt.u>=.5){dt.u=0;++dt.S}if(dt.S>=60){dt.S=0;++dt.M}if(dt.M>=60){dt.M=0;++dt.H}break;case 2:if(dt.u>=.5){dt.u=0;++dt.S}if(dt.S>=60){dt.S=0;++dt.M}break}var nstr="",jj;for(i=0;i<out.length;++i){switch(out[i].t){case"t":case"T":case" ":case"D":break;case"X":out[i]=undefined;break;case"d":case"m":case"y":case"h":case"H":case"M":case"s":case"e":case"b":case"Z":out[i].v=write_date(out[i].t.charCodeAt(0),out[i].v,dt,ss0);out[i].t="t";break;case"n":case"(":case"?":jj=i+1;while(out[jj]!=null&&((c=out[jj].t)==="?"||c==="D"||(c===" "||c==="t")&&out[jj+1]!=null&&(out[jj+1].t==="?"||out[jj+1].t==="t"&&out[jj+1].v==="/")||out[i].t==="("&&(c===" "||c==="n"||c===")")||c==="t"&&(out[jj].v==="/"||"$€".indexOf(out[jj].v)>-1||out[jj].v===" "&&out[jj+1]!=null&&out[jj+1].t=="?"))){out[i].v+=out[jj].v;out[jj]=undefined;++jj}nstr+=out[i].v;i=jj-1;break;case"G":out[i].t="t";out[i].v=general_fmt(v,opts);break}}var vv="",myv,ostr;if(nstr.length>0){myv=v<0&&nstr.charCodeAt(0)===45?-v:v;ostr=write_num(nstr.charCodeAt(0)===40?"(":"n",nstr,myv);jj=ostr.length-1;var decpt=out.length;for(i=0;i<out.length;++i)if(out[i]!=null&&out[i].v.indexOf(".")>-1){decpt=i;break}var lasti=out.length;if(decpt===out.length&&ostr.indexOf("E")===-1){for(i=out.length-1;i>=0;--i){if(out[i]==null||"n?(".indexOf(out[i].t)===-1)continue;if(jj>=out[i].v.length-1){jj-=out[i].v.length;out[i].v=ostr.substr(jj+1,out[i].v.length)}else if(jj<0)out[i].v="";else{out[i].v=ostr.substr(0,jj+1);jj=-1}out[i].t="t";lasti=i}if(jj>=0&&lasti<out.length)out[lasti].v=ostr.substr(0,jj+1)+out[lasti].v}else if(decpt!==out.length&&ostr.indexOf("E")===-1){jj=ostr.indexOf(".")-1;for(i=decpt;i>=0;--i){if(out[i]==null||"n?(".indexOf(out[i].t)===-1)continue;j=out[i].v.indexOf(".")>-1&&i===decpt?out[i].v.indexOf(".")-1:out[i].v.length-1;vv=out[i].v.substr(j+1);for(;j>=0;--j){if(jj>=0&&(out[i].v[j]==="0"||out[i].v[j]==="#"))vv=ostr[jj--]+vv}out[i].v=vv;out[i].t="t";lasti=i}if(jj>=0&&lasti<out.length)out[lasti].v=ostr.substr(0,jj+1)+out[lasti].v;jj=ostr.indexOf(".")+1;for(i=decpt;i<out.length;++i){if(out[i]==null||"n?(".indexOf(out[i].t)===-1&&i!==decpt)continue;j=out[i].v.indexOf(".")>-1&&i===decpt?out[i].v.indexOf(".")+1:0;vv=out[i].v.substr(0,j);for(;j<out[i].v.length;++j){if(jj<ostr.length)vv+=ostr[jj++]}out[i].v=vv;out[i].t="t";lasti=i}}}for(i=0;i<out.length;++i)if(out[i]!=null&&"n(?".indexOf(out[i].t)>-1){myv=flen>1&&v<0&&i>0&&out[i-1].v==="-"?-v:v;out[i].v=write_num(out[i].t,out[i].v,myv);out[i].t="t"}var retval="";for(i=0;i!==out.length;++i)if(out[i]!=null)retval+=out[i].v;return retval}SSF._eval=eval_fmt;var cfregex=/\[[=<>]/;var cfregex2=/\[([=<>]*)(-?\d+\.?\d*)\]/;function chkcond(v,rr){if(rr==null)return false;var thresh=parseFloat(rr[2]);switch(rr[1]){case"=":if(v==thresh)return true;break;case">":if(v>thresh)return true;break;case"<":if(v<thresh)return true;break;case"<>":if(v!=thresh)return true;break;case">=":if(v>=thresh)return true;break;case"<=":if(v<=thresh)return true;break}return false}function choose_fmt(f,v){var fmt=split_fmt(f);var l=fmt.length,lat=fmt[l-1].indexOf("@");if(l<4&&lat>-1)--l;if(fmt.length>4)throw"cannot find right format for |"+fmt+"|";if(typeof v!=="number")return[4,fmt.length===4||lat>-1?fmt[fmt.length-1]:"@"];switch(fmt.length){case 1:fmt=lat>-1?["General","General","General",fmt[0]]:[fmt[0],fmt[0],fmt[0],"@"];break;case 2:fmt=lat>-1?[fmt[0],fmt[0],fmt[0],fmt[1]]:[fmt[0],fmt[1],fmt[0],"@"];break;case 3:fmt=lat>-1?[fmt[0],fmt[1],fmt[0],fmt[2]]:[fmt[0],fmt[1],fmt[2],"@"];break;case 4:break}var ff=v>0?fmt[0]:v<0?fmt[1]:fmt[2];if(fmt[0].indexOf("[")===-1&&fmt[1].indexOf("[")===-1)return[l,ff];if(fmt[0].match(cfregex)!=null||fmt[1].match(cfregex)!=null){var m1=fmt[0].match(cfregex2);var m2=fmt[1].match(cfregex2);return chkcond(v,m1)?[l,fmt[0]]:chkcond(v,m2)?[l,fmt[1]]:[l,fmt[m1!=null&&m2!=null?2:1]]}return[l,ff]}function format(fmt,v,o){fixopts(o!=null?o:o=[]);var sfmt="";switch(typeof fmt){case"string":sfmt=fmt;break;case"number":sfmt=(o.table!=null?o.table:table_fmt)[fmt];break}if(isgeneral(sfmt,0))return general_fmt(v,o);var f=choose_fmt(sfmt,v);if(isgeneral(f[1]))return general_fmt(v,o);if(v===true)v="TRUE";else if(v===false)v="FALSE";else if(v===""||v==null)return"";return eval_fmt(f[1],v,o,f[0])}SSF._table=table_fmt;SSF.load=function load_entry(fmt,idx){table_fmt[idx]=fmt};SSF.format=format;SSF.get_table=function get_table(){return table_fmt};SSF.load_table=function load_table(tbl){for(var i=0;i!=392;++i)if(tbl[i]!==undefined)SSF.load(tbl[i],i)}};make_ssf(SSF);{var VT_EMPTY=0;var VT_NULL=1;var VT_I2=2;var VT_I4=3;var VT_R4=4;var VT_R8=5;var VT_CY=6;var VT_DATE=7;var VT_BSTR=8;var VT_ERROR=10;var VT_BOOL=11;var VT_VARIANT=12;var VT_DECIMAL=14;var VT_I1=16;var VT_UI1=17;var VT_UI2=18;var VT_UI4=19;var VT_I8=20;var VT_UI8=21;var VT_INT=22;var VT_UINT=23;var VT_LPSTR=30;var VT_LPWSTR=31;var VT_FILETIME=64;var VT_BLOB=65;var VT_STREAM=66;var VT_STORAGE=67;var VT_STREAMED_Object=68;
18579 dosTime, 25798 var VT_STORED_Object=69;var VT_BLOB_Object=70;var VT_CF=71;var VT_CLSID=72;var VT_VERSIONED_STREAM=73;var VT_VECTOR=4096;var VT_ARRAY=8192;var VT_STRING=80;var VT_USTR=81;var VT_CUSTOM=[VT_STRING,VT_USTR]}var DocSummaryPIDDSI={1:{n:"CodePage",t:VT_I2},2:{n:"Category",t:VT_STRING},3:{n:"PresentationFormat",t:VT_STRING},4:{n:"ByteCount",t:VT_I4},5:{n:"LineCount",t:VT_I4},6:{n:"ParagraphCount",t:VT_I4},7:{n:"SlideCount",t:VT_I4},8:{n:"NoteCount",t:VT_I4},9:{n:"HiddenCount",t:VT_I4},10:{n:"MultimediaClipCount",t:VT_I4},11:{n:"Scale",t:VT_BOOL},12:{n:"HeadingPair",t:VT_VECTOR|VT_VARIANT},13:{n:"DocParts",t:VT_VECTOR|VT_LPSTR},14:{n:"Manager",t:VT_STRING},15:{n:"Company",t:VT_STRING},16:{n:"LinksDirty",t:VT_BOOL},17:{n:"CharacterCount",t:VT_I4},19:{n:"SharedDoc",t:VT_BOOL},22:{n:"HLinksChanged",t:VT_BOOL},23:{n:"AppVersion",t:VT_I4,p:"version"},26:{n:"ContentType",t:VT_STRING},27:{n:"ContentStatus",t:VT_STRING},28:{n:"Language",t:VT_STRING},29:{n:"Version",t:VT_STRING},255:{}};var SummaryPIDSI={1:{n:"CodePage",t:VT_I2},2:{n:"Title",t:VT_STRING},3:{n:"Subject",t:VT_STRING},4:{n:"Author",t:VT_STRING},5:{n:"Keywords",t:VT_STRING},6:{n:"Comments",t:VT_STRING},7:{n:"Template",t:VT_STRING},8:{n:"LastAuthor",t:VT_STRING},9:{n:"RevNumber",t:VT_STRING},10:{n:"EditTime",t:VT_FILETIME},11:{n:"LastPrinted",t:VT_FILETIME},12:{n:"CreatedDate",t:VT_FILETIME},13:{n:"ModifiedDate",t:VT_FILETIME},14:{n:"PageCount",t:VT_I4},15:{n:"WordCount",t:VT_I4},16:{n:"CharCount",t:VT_I4},17:{n:"Thumbnail",t:VT_CF},18:{n:"ApplicationName",t:VT_LPSTR},19:{n:"DocumentSecurity",t:VT_I4},255:{}};var SpecialProperties={2147483648:{n:"Locale",t:VT_UI4},2147483651:{n:"Behavior",t:VT_UI4},1768515945:{}};(function(){for(var y in SpecialProperties)if(SpecialProperties.hasOwnProperty(y))DocSummaryPIDDSI[y]=SummaryPIDSI[y]=SpecialProperties[y]})();function parse_FILETIME(blob){var dwLowDateTime=blob.read_shift(4),dwHighDateTime=blob.read_shift(4);return new Date((dwHighDateTime/1e7*Math.pow(2,32)+dwLowDateTime/1e7-11644473600)*1e3).toISOString().replace(/\.000/,"")}function parse_lpstr(blob,type,pad){var str=blob.read_shift(0,"lpstr");if(pad)blob.l+=4-(str.length+1&3)&3;return str}function parse_lpwstr(blob,type,pad){var str=blob.read_shift(0,"lpwstr");if(pad)blob.l+=4-(str.length+1&3)&3;return str}function parse_VtStringBase(blob,stringType,pad){if(stringType===31)return parse_lpwstr(blob);return parse_lpstr(blob,stringType,pad)}function parse_VtString(blob,t,pad){return parse_VtStringBase(blob,t,pad===false?0:4)}function parse_VtUnalignedString(blob,t){if(!t)throw new Error("dafuq?");return parse_VtStringBase(blob,t,0)}function parse_VtVecUnalignedLpstrValue(blob){var length=blob.read_shift(4);var ret=[];for(var i=0;i!=length;++i)ret[i]=blob.read_shift(0,"lpstr");return ret}function parse_VtVecUnalignedLpstr(blob){return parse_VtVecUnalignedLpstrValue(blob)}function parse_VtHeadingPair(blob){var headingString=parse_TypedPropertyValue(blob,VT_USTR);var headerParts=parse_TypedPropertyValue(blob,VT_I4);return[headingString,headerParts]}function parse_VtVecHeadingPairValue(blob){var cElements=blob.read_shift(4);var out=[];for(var i=0;i!=cElements/2;++i)out.push(parse_VtHeadingPair(blob));return out}function parse_VtVecHeadingPair(blob){return parse_VtVecHeadingPairValue(blob)}function parse_dictionary(blob,CodePage){var cnt=blob.read_shift(4);var dict={};for(var j=0;j!=cnt;++j){var pid=blob.read_shift(4);var len=blob.read_shift(4);dict[pid]=blob.read_shift(len,CodePage===1200?"utf16le":"utf8").replace(chr0,"").replace(chr1,"!")}if(blob.l&3)blob.l=blob.l>>2+1<<2;return dict}function parse_BLOB(blob){var size=blob.read_shift(4);var bytes=blob.slice(blob.l,blob.l+size);if(size&3>0)blob.l+=4-(size&3)&3;return bytes}function parse_ClipboardData(blob){var o={};o.Size=blob.read_shift(4);blob.l+=o.Size;return o}function parse_VtVector(blob,cb){}function parse_TypedPropertyValue(blob,type,_opts){var t=blob.read_shift(2),ret,opts=_opts||{};blob.l+=2;if(type!==VT_VARIANT)if(t!==type&&VT_CUSTOM.indexOf(type)===-1)throw new Error("Expected type "+type+" saw "+t);switch(type===VT_VARIANT?t:type){case 2:ret=blob.read_shift(2,"i");if(!opts.raw)blob.l+=2;return ret;case 3:ret=blob.read_shift(4,"i");return ret;case 11:return blob.read_shift(4)!==0;case 19:ret=blob.read_shift(4);return ret;case 30:return parse_lpstr(blob,t,4).replace(chr0,"");case 31:return parse_lpwstr(blob);case 64:return parse_FILETIME(blob);case 65:return parse_BLOB(blob);case 71:return parse_ClipboardData(blob);case 80:return parse_VtString(blob,t,!opts.raw&&4).replace(chr0,"");case 81:return parse_VtUnalignedString(blob,t,4).replace(chr0,"");case 4108:return parse_VtVecHeadingPair(blob);case 4126:return parse_VtVecUnalignedLpstr(blob);default:throw new Error("TypedPropertyValue unrecognized type "+type+" "+t)}}function parse_PropertySet(blob,PIDSI){var start_addr=blob.l;var size=blob.read_shift(4);var NumProps=blob.read_shift(4);var Props=[],i=0;var CodePage=0;var Dictionary=-1,DictObj;for(i=0;i!=NumProps;++i){var PropID=blob.read_shift(4);var Offset=blob.read_shift(4);Props[i]=[PropID,Offset+start_addr]}var PropH={};for(i=0;i!=NumProps;++i){if(blob.l!==Props[i][1]){var fail=true;if(i>0&&PIDSI)switch(PIDSI[Props[i-1][0]].t){case 2:if(blob.l+2===Props[i][1]){blob.l+=2;fail=false}break;case 80:if(blob.l<=Props[i][1]){blob.l=Props[i][1];fail=false}break;case 4108:if(blob.l<=Props[i][1]){blob.l=Props[i][1];fail=false}break}if(!PIDSI&&blob.l<=Props[i][1]){fail=false;blob.l=Props[i][1]}if(fail)throw new Error("Read Error: Expected address "+Props[i][1]+" at "+blob.l+" :"+i)}if(PIDSI){var piddsi=PIDSI[Props[i][0]];PropH[piddsi.n]=parse_TypedPropertyValue(blob,piddsi.t,{raw:true});if(piddsi.p==="version")PropH[piddsi.n]=String(PropH[piddsi.n]>>16)+"."+String(PropH[piddsi.n]&65535);if(piddsi.n=="CodePage")switch(PropH[piddsi.n]){case 0:PropH[piddsi.n]=1252;case 1e4:case 1252:case 874:case 1250:case 1251:case 1253:case 1254:case 1255:case 1256:case 1257:case 1258:case 932:case 936:case 949:case 950:case 1200:case 1201:case 65e3:case-536:case 65001:case-535:set_cp(CodePage=PropH[piddsi.n]);break;default:throw new Error("Unsupported CodePage: "+PropH[piddsi.n])}}else{if(Props[i][0]===1){CodePage=PropH.CodePage=parse_TypedPropertyValue(blob,VT_I2);set_cp(CodePage);if(Dictionary!==-1){var oldpos=blob.l;blob.l=Props[Dictionary][1];DictObj=parse_dictionary(blob,CodePage);blob.l=oldpos}}else if(Props[i][0]===0){if(CodePage===0){Dictionary=i;blob.l=Props[i+1][1];continue}DictObj=parse_dictionary(blob,CodePage)}else{var name=DictObj[Props[i][0]];var val;switch(blob[blob.l]){case 65:blob.l+=4;val=parse_BLOB(blob);break;case 30:blob.l+=4;val=parse_VtString(blob,blob[blob.l-4]);break;case 31:blob.l+=4;val=parse_VtString(blob,blob[blob.l-4]);break;case 3:blob.l+=4;val=blob.read_shift(4,"i");break;case 19:blob.l+=4;val=blob.read_shift(4);break;case 5:blob.l+=4;val=blob.read_shift(8,"f");break;case 11:blob.l+=4;val=parsebool(blob,4);break;case 64:blob.l+=4;val=new Date(parse_FILETIME(blob));break;default:throw new Error("unparsed value: "+blob[blob.l])}PropH[name]=val}}}blob.l=start_addr+size;return PropH}function parse_PropertySetStream(file,PIDSI){var blob=file.content;prep_blob(blob,0);var NumSets,FMTID0,FMTID1,Offset0,Offset1;blob.chk("feff","Byte Order: ");var vers=blob.read_shift(2);var SystemIdentifier=blob.read_shift(4);blob.chk(CFB.utils.consts.HEADER_CLSID,"CLSID: ");NumSets=blob.read_shift(4);if(NumSets!==1&&NumSets!==2)throw"Unrecognized #Sets: "+NumSets;FMTID0=blob.read_shift(16);Offset0=blob.read_shift(4);if(NumSets===1&&Offset0!==blob.l)throw"Length mismatch";else if(NumSets===2){FMTID1=blob.read_shift(16);Offset1=blob.read_shift(4)}var PSet0=parse_PropertySet(blob,PIDSI);var rval={SystemIdentifier:SystemIdentifier};for(var y in PSet0)rval[y]=PSet0[y];rval.FMTID=FMTID0;if(NumSets===1)return rval;if(blob.l!==Offset1)throw"Length mismatch 2: "+blob.l+" !== "+Offset1;var PSet1;try{PSet1=parse_PropertySet(blob,null)}catch(e){}for(y in PSet1)rval[y]=PSet1[y];rval.FMTID=[FMTID0,FMTID1];return rval}var DO_NOT_EXPORT_CFB=true;var CFB=function _CFB(){var exports={};exports.version="0.10.0";function parse(file){var mver=3;var ssz=512;var nmfs=0;var ndfs=0;var dir_start=0;var minifat_start=0;var difat_start=0;var fat_addrs=[];var blob=file.slice(0,512);prep_blob(blob,0);mver=check_get_mver(blob);switch(mver){case 3:ssz=512;break;case 4:ssz=4096;break;default:throw"Major Version: Expected 3 or 4 saw "+mver}if(ssz!==512){blob=file.slice(0,ssz);prep_blob(blob,28)}var header=file.slice(0,ssz);check_shifts(blob,mver);var nds=blob.read_shift(4,"i");if(mver===3&&nds!==0)throw"# Directory Sectors: Expected 0 saw "+nds;blob.l+=4;dir_start=blob.read_shift(4,"i");blob.l+=4;blob.chk("00100000","Mini Stream Cutoff Size: ");minifat_start=blob.read_shift(4,"i");nmfs=blob.read_shift(4,"i");difat_start=blob.read_shift(4,"i");ndfs=blob.read_shift(4,"i");for(var q,j=0;j<109;++j){q=blob.read_shift(4,"i");if(q<0)break;fat_addrs[j]=q}var sectors=sectorify(file,ssz);sleuth_fat(difat_start,ndfs,sectors,ssz,fat_addrs);var sector_list=make_sector_list(sectors,dir_start,fat_addrs,ssz);sector_list[dir_start].name="!Directory";if(nmfs>0&&minifat_start!==ENDOFCHAIN)sector_list[minifat_start].name="!MiniFAT";sector_list[fat_addrs[0]].name="!FAT";var files={},Paths=[],FileIndex=[],FullPaths=[],FullPathDir={};read_directory(dir_start,sector_list,sectors,Paths,nmfs,files,FileIndex);build_full_paths(FileIndex,FullPathDir,FullPaths,Paths);var root_name=Paths.shift();Paths.root=root_name;var find_path=make_find_path(FullPaths,Paths,FileIndex,files,root_name);return{raw:{header:header,sectors:sectors},FileIndex:FileIndex,FullPaths:FullPaths,FullPathDir:FullPathDir,find:find_path}}function check_get_mver(blob){blob.chk(HEADER_SIGNATURE,"Header Signature: ");blob.chk(HEADER_CLSID,"CLSID: ");blob.l+=2;return blob.read_shift(2,"u")}function check_shifts(blob,mver){var shift=9;blob.chk("feff","Byte Order: ");switch(shift=blob.read_shift(2)){case 9:if(mver!==3)throw"MajorVersion/SectorShift Mismatch";break;case 12:if(mver!==4)throw"MajorVersion/SectorShift Mismatch";break;default:throw"Sector Shift: Expected 9 or 12 saw "+shift}blob.chk("0600","Mini Sector Shift: ");blob.chk("000000000000","Reserved: ")}function sectorify(file,ssz){var nsectors=Math.ceil(file.length/ssz)-1;var sectors=new Array(nsectors);for(var i=1;i<nsectors;++i)sectors[i-1]=file.slice(i*ssz,(i+1)*ssz);sectors[nsectors-1]=file.slice(nsectors*ssz);return sectors}function build_full_paths(FI,FPD,FP,Paths){var i=0,L=0,R=0,C=0,j=0,pl=Paths.length;var dad=new Array(pl),q=new Array(pl);for(;i<pl;++i){dad[i]=q[i]=i;FP[i]=Paths[i]}for(;j<q.length;++j){i=q[j];L=FI[i].L;R=FI[i].R;C=FI[i].C;if(dad[i]===i){if(L!==-1&&dad[L]!==L)dad[i]=dad[L];if(R!==-1&&dad[R]!==R)dad[i]=dad[R]}if(C!==-1)dad[C]=i;if(L!==-1){dad[L]=dad[i];q.push(L)}if(R!==-1){dad[R]=dad[i];q.push(R)}}for(i=1;i!==pl;++i)if(dad[i]===i){if(R!==-1&&dad[R]!==R)dad[i]=dad[R];else if(L!==-1&&dad[L]!==L)dad[i]=dad[L]}for(i=1;i<pl;++i){if(FI[i].type===0)continue;j=dad[i];if(j===0)FP[i]=FP[0]+"/"+FP[i];else while(j!==0){FP[i]=FP[j]+"/"+FP[i];j=dad[j]}dad[i]=0}FP[0]+="/";for(i=1;i<pl;++i){if(FI[i].type!==2)FP[i]+="/";FPD[FP[i]]=FI[i]}}function make_find_path(FullPaths,Paths,FileIndex,files,root_name){var UCFullPaths=new Array(FullPaths.length);var UCPaths=new Array(Paths.length),i;for(i=0;i<FullPaths.length;++i)UCFullPaths[i]=FullPaths[i].toUpperCase();for(i=0;i<Paths.length;++i)UCPaths[i]=Paths[i].toUpperCase();return function find_path(path){var k;if(path.charCodeAt(0)===47){k=true;path=root_name+path}else k=path.indexOf("/")!==-1;var UCPath=path.toUpperCase();var w=k===true?UCFullPaths.indexOf(UCPath):UCPaths.indexOf(UCPath);if(w===-1)return null;return k===true?FileIndex[w]:files[Paths[w]]}}function sleuth_fat(idx,cnt,sectors,ssz,fat_addrs){var q;if(idx===ENDOFCHAIN){if(cnt!==0)throw"DIFAT chain shorter than expected"}else if(idx!==-1){var sector=sectors[idx],m=(ssz>>>2)-1;for(var i=0;i<m;++i){if((q=__readInt32LE(sector,i*4))===ENDOFCHAIN)break;fat_addrs.push(q)}sleuth_fat(__readInt32LE(sector,ssz-4),cnt-1,sectors,ssz,fat_addrs)}}function make_sector_list(sectors,dir_start,fat_addrs,ssz){var sl=sectors.length,sector_list=new Array(sl);var chkd=new Array(sl),buf,buf_chain;var modulus=ssz-1,i,j,k,jj;for(i=0;i<sl;++i){buf=[];k=i+dir_start;if(k>=sl)k-=sl;if(chkd[k]===true)continue;buf_chain=[];for(j=k;j>=0;){chkd[j]=true;buf[buf.length]=j;buf_chain.push(sectors[j]);var addr=fat_addrs[Math.floor(j*4/ssz)];jj=j*4&modulus;if(ssz<4+jj)throw"FAT boundary crossed: "+j+" 4 "+ssz;j=__readInt32LE(sectors[addr],jj)}sector_list[k]={nodes:buf,data:__toBuffer([buf_chain])}}return sector_list}function read_directory(dir_start,sector_list,sectors,Paths,nmfs,files,FileIndex){var blob;var minifat_store=0,pl=Paths.length?2:0;var sector=sector_list[dir_start].data;var i=0,namelen=0,name,o,ctime,mtime;for(;i<sector.length;i+=128){blob=sector.slice(i,i+128);prep_blob(blob,64);namelen=blob.read_shift(2);if(namelen===0)continue;name=__utf16le(blob,0,namelen-pl).replace(chr0,"").replace(chr1,"!");Paths.push(name);o={name:name,type:blob.read_shift(1),color:blob.read_shift(1),L:blob.read_shift(4,"i"),R:blob.read_shift(4,"i"),C:blob.read_shift(4,"i"),clsid:blob.read_shift(16),state:blob.read_shift(4,"i")};ctime=blob.read_shift(2)+blob.read_shift(2)+blob.read_shift(2)+blob.read_shift(2);if(ctime!==0){o.ctime=ctime;o.ct=read_date(blob,blob.l-8)}mtime=blob.read_shift(2)+blob.read_shift(2)+blob.read_shift(2)+blob.read_shift(2);if(mtime!==0){o.mtime=mtime;o.mt=read_date(blob,blob.l-8)}o.start=blob.read_shift(4,"i");o.size=blob.read_shift(4,"i");if(o.type===5){minifat_store=o.start;if(nmfs>0&&minifat_store!==ENDOFCHAIN)sector_list[minifat_store].name="!StreamData"}else if(o.size>=4096){o.storage="fat";if(sector_list[o.start]===undefined)if((o.start+=dir_start)>=sectors.length)o.start-=sectors.length;sector_list[o.start].name=o.name;o.content=sector_list[o.start].data.slice(0,o.size);prep_blob(o.content,0)}else{o.storage="minifat";if(minifat_store!==ENDOFCHAIN&&o.start!==ENDOFCHAIN){o.content=sector_list[minifat_store].data.slice(o.start*MSSZ,o.start*MSSZ+o.size);prep_blob(o.content,0)}}files[name]=o;FileIndex.push(o)}}function read_date(blob,offset){return new Date((__readUInt32LE(blob,offset+4)/1e7*Math.pow(2,32)+__readUInt32LE(blob,offset)/1e7-11644473600)*1e3)}var fs;function readFileSync(filename){if(fs===undefined)fs=require("fs");return parse(fs.readFileSync(filename))}function readSync(blob,options){switch(options!==undefined&&options.type!==undefined?options.type:"base64"){case"file":return readFileSync(blob);case"base64":return parse(s2a(Base64.decode(blob)));case"binary":return parse(s2a(blob))}return parse(blob)}var MSSZ=64;var ENDOFCHAIN=-2;var HEADER_SIGNATURE="d0cf11e0a1b11ae1";var HEADER_CLSID="00000000000000000000000000000000";var consts={MAXREGSECT:-6,DIFSECT:-4,FATSECT:-3,ENDOFCHAIN:ENDOFCHAIN,FREESECT:-1,HEADER_SIGNATURE:HEADER_SIGNATURE,HEADER_MINOR_VERSION:"3e00",MAXREGSID:-6,NOSTREAM:-1,HEADER_CLSID:HEADER_CLSID,EntryTypes:["unknown","storage","stream","lockbytes","property","root"]};exports.read=readSync;exports.parse=parse;exports.utils={ReadShift:ReadShift,CheckField:CheckField,prep_blob:prep_blob,bconcat:bconcat,consts:consts};return exports}();if(typeof require!=="undefined"&&typeof module!=="undefined"&&typeof DO_NOT_EXPORT_CFB==="undefined"){module.exports=CFB}function parsenoop(blob,length){blob.read_shift(length);return}function parsenoop2(blob,length){blob.read_shift(length);return null}function parslurp(blob,length,cb){var arr=[],target=blob.l+length;while(blob.l<target)arr.push(cb(blob,target-blob.l));if(target!==blob.l)throw new Error("Slurp error");return arr}function parslurp2(blob,length,cb){var arr=[],target=blob.l+length,len=blob.read_shift(2);while(len--!==0)arr.push(cb(blob,target-blob.l));if(target!==blob.l)throw new Error("Slurp error");return arr}function parsebool(blob,length){return blob.read_shift(length)===1}function parseuint16(blob){return blob.read_shift(2,"u")}function parseuint16a(blob,length){return parslurp(blob,length,parseuint16)}var parse_Boolean=parsebool;function parse_Bes(blob){var v=blob.read_shift(1),t=blob.read_shift(1);return t===1?BERR[v]:v===1}function parse_ShortXLUnicodeString(blob,length,opts){var cch=blob.read_shift(1);var width=1,encoding="sbcs";if(opts===undefined||opts.biff!==5){var fHighByte=blob.read_shift(1);if(fHighByte){width=2;encoding="dbcs"}}return cch?blob.read_shift(cch,encoding):""}function parse_XLUnicodeRichExtendedString(blob){var cch=blob.read_shift(2),flags=blob.read_shift(1);var fHighByte=flags&1,fExtSt=flags&4,fRichSt=flags&8;var width=1+(flags&1);var cRun,cbExtRst;var z={};if(fRichSt)cRun=blob.read_shift(2);if(fExtSt)cbExtRst=blob.read_shift(4);var encoding=flags&1?"dbcs":"sbcs";var msg=cch===0?"":blob.read_shift(cch,encoding);if(fRichSt)blob.l+=4*cRun;if(fExtSt)blob.l+=cbExtRst;z.t=msg;if(!fRichSt){z.raw="<t>"+z.t+"</t>";z.r=z.t}return z}function parse_XLUnicodeStringNoCch(blob,cch,opts){var retval;var fHighByte=blob.read_shift(1);if(fHighByte===0){retval=blob.read_shift(cch,"sbcs")}else{retval=blob.read_shift(cch,"dbcs")}return retval}function parse_XLUnicodeString(blob,length,opts){var cch=blob.read_shift(opts!==undefined&&opts.biff===5?1:2);if(cch===0){blob.l++;return""}return parse_XLUnicodeStringNoCch(blob,cch,opts)}function parse_XLUnicodeString2(blob,length,opts){if(opts.biff!==5)return parse_XLUnicodeString(blob,length,opts);var cch=blob.read_shift(1);if(cch===0){blob.l++;return""}return blob.read_shift(cch,"sbcs")}function parse_Xnum(blob){return blob.read_shift(8,"f")}var parse_ControlInfo=parsenoop;var parse_URLMoniker=function(blob,length){var len=blob.read_shift(4),start=blob.l;var extra=false;if(len>24){blob.l+=len-24;if(blob.read_shift(16)==="795881f43b1d7f48af2c825dc4852763")extra=true;blob.l=start}var url=blob.read_shift((extra?len-24:len)>>1,"utf16le").replace(chr0,"");if(extra)blob.l+=24;return url};var parse_FileMoniker=function(blob,length){var cAnti=blob.read_shift(2);var ansiLength=blob.read_shift(4);var ansiPath=blob.read_shift(ansiLength,"cstr");var endServer=blob.read_shift(2);var versionNumber=blob.read_shift(2);var cbUnicodePathSize=blob.read_shift(4);if(cbUnicodePathSize===0)return ansiPath.replace(/\\/g,"/");var cbUnicodePathBytes=blob.read_shift(4);var usKeyValue=blob.read_shift(2);var unicodePath=blob.read_shift(cbUnicodePathBytes>>1,"utf16le").replace(chr0,"");return unicodePath};var parse_HyperlinkMoniker=function(blob,length){var clsid=blob.read_shift(16);length-=16;switch(clsid){case"e0c9ea79f9bace118c8200aa004ba90b":return parse_URLMoniker(blob,length);case"0303000000000000c000000000000046":return parse_FileMoniker(blob,length);default:throw"unsupported moniker "+clsid}};var parse_HyperlinkString=function(blob,length){var len=blob.read_shift(4);var o=blob.read_shift(len,"utf16le").replace(chr0,"");return o};var parse_Hyperlink=function(blob,length){var end=blob.l+length;var sVer=blob.read_shift(4);if(sVer!==2)throw new Error("Unrecognized streamVersion: "+sVer);var flags=blob.read_shift(2);blob.l+=2;var displayName,targetFrameName,moniker,oleMoniker,location,guid,fileTime;if(flags&16)displayName=parse_HyperlinkString(blob,end-blob.l);if(flags&128)targetFrameName=parse_HyperlinkString(blob,end-blob.l);if((flags&257)===257)moniker=parse_HyperlinkString(blob,end-blob.l);if((flags&257)===1)oleMoniker=parse_HyperlinkMoniker(blob,end-blob.l);if(flags&8)location=parse_HyperlinkString(blob,end-blob.l);if(flags&32)guid=blob.read_shift(16);if(flags&64)fileTime=parse_FILETIME(blob,8);blob.l=end;var target=targetFrameName||moniker||oleMoniker;if(location)target+="#"+location;return{Target:target}};function isval(x){return x!==undefined&&x!==null}function keys(o){return Object.keys(o)}function evert(obj,arr){var o={};var K=keys(obj);for(var i=0;i<K.length;++i){var k=K[i];if(!arr)o[obj[k]]=k;else(o[obj[k]]=o[obj[k]]||[]).push(k)}return o}function parse_Cell(blob,length){var rw=blob.read_shift(2);var col=blob.read_shift(2);var ixfe=blob.read_shift(2);return{r:rw,c:col,ixfe:ixfe}}function parse_frtHeader(blob){var rt=blob.read_shift(2);var flags=blob.read_shift(2);blob.l+=8;return{type:rt,flags:flags}}function parse_OptXLUnicodeString(blob,length,opts){return length===0?"":parse_XLUnicodeString2(blob,length,opts)}var HIDEOBJENUM=["SHOWALL","SHOWPLACEHOLDER","HIDEALL"];var parse_HideObjEnum=parseuint16;function parse_XTI(blob,length){var iSupBook=blob.read_shift(2),itabFirst=blob.read_shift(2,"i"),itabLast=blob.read_shift(2,"i");return[iSupBook,itabFirst,itabLast]}function parse_RkNumber(blob){var b=blob.slice(blob.l,blob.l+4);var fX100=b[0]&1,fInt=b[0]&2;blob.l+=4;b[0]&=~3;var RK=fInt===0?__double([0,0,0,0,b[0],b[1],b[2],b[3]],0):__readInt32LE(b,0)>>2;return fX100?RK/100:RK}function parse_RkRec(blob,length){var ixfe=blob.read_shift(2);var RK=parse_RkNumber(blob);return[ixfe,RK]}function parse_AddinUdf(blob,length){blob.l+=4;length-=4;var l=blob.l+length;var udfName=parse_ShortXLUnicodeString(blob,length);var cb=blob.read_shift(2);l-=blob.l;if(cb!==l)throw"Malformed AddinUdf: padding = "+l+" != "+cb;blob.l+=cb;return udfName}function parse_Ref8U(blob,length){var rwFirst=blob.read_shift(2);var rwLast=blob.read_shift(2);var colFirst=blob.read_shift(2);var colLast=blob.read_shift(2);return{s:{c:colFirst,r:rwFirst},e:{c:colLast,r:rwLast}}}function parse_RefU(blob,length){var rwFirst=blob.read_shift(2);var rwLast=blob.read_shift(2);var colFirst=blob.read_shift(1);var colLast=blob.read_shift(1);return{s:{c:colFirst,r:rwFirst},e:{c:colLast,r:rwLast}}}var parse_Ref=parse_RefU;function parse_FtCmo(blob,length){blob.l+=4;var ot=blob.read_shift(2);var id=blob.read_shift(2);var flags=blob.read_shift(2);blob.l+=12;return[id,ot,flags]}function parse_FtNts(blob,length){var out={};blob.l+=4;blob.l+=16;out.fSharedNote=blob.read_shift(2);blob.l+=4;return out}function parse_FtCf(blob,length){var out={};blob.l+=4;blob.cf=blob.read_shift(2);return out}var FtTab={21:parse_FtCmo,19:parsenoop,18:function(blob,length){blob.l+=12},17:function(blob,length){blob.l+=8},16:parsenoop,15:parsenoop,13:parse_FtNts,12:function(blob,length){blob.l+=24},11:function(blob,length){blob.l+=10},10:function(blob,length){blob.l+=16},9:parsenoop,8:function(blob,length){blob.l+=6},7:parse_FtCf,6:function(blob,length){blob.l+=6},4:parsenoop,0:function(blob,length){blob.l+=4}};function parse_FtArray(blob,length,ot){var s=blob.l;var fts=[];while(blob.l<s+length){var ft=blob.read_shift(2);blob.l-=2;try{fts.push(FtTab[ft](blob,s+length-blob.l))}catch(e){blob.l=s+length;return fts}}if(blob.l!=s+length)blob.l=s+length;return fts}var parse_FontIndex=parseuint16;function parse_BOF(blob,length){var o={};o.BIFFVer=blob.read_shift(2);length-=2;if(o.BIFFVer!==1536&&o.BIFFVer!==1280)throw"Unexpected BIFF Ver "+o.BIFFVer;blob.read_shift(length);return o}function parse_InterfaceHdr(blob,length){if(length===0)return 1200;var q;if((q=blob.read_shift(2))!==1200)throw"InterfaceHdr codePage "+q;return 1200}function parse_WriteAccess(blob,length,opts){if(opts.enc){blob.l+=length;return""}var l=blob.l;var UserName=parse_XLUnicodeString(blob,0,opts);blob.read_shift(length+l-blob.l);return UserName}function parse_BoundSheet8(blob,length,opts){var pos=blob.read_shift(4);var hidden=blob.read_shift(1)>>6;var dt=blob.read_shift(1);switch(dt){case 0:dt="Worksheet";break;case 1:dt="Macrosheet";break;case 2:dt="Chartsheet";break;case 6:dt="VBAModule";break}var name=parse_ShortXLUnicodeString(blob,0,opts);return{pos:pos,hs:hidden,dt:dt,name:name}}function parse_SST(blob,length){var cnt=blob.read_shift(4);var ucnt=blob.read_shift(4);var strs=[];for(var i=0;i!=ucnt;++i){strs.push(parse_XLUnicodeRichExtendedString(blob))}strs.Count=cnt;strs.Unique=ucnt;return strs}function parse_ExtSST(blob,length){var extsst={};extsst.dsst=blob.read_shift(2);blob.l+=length-2;return extsst}function parse_Row(blob,length){var rw=blob.read_shift(2),col=blob.read_shift(2),Col=blob.read_shift(2),rht=blob.read_shift(2);blob.read_shift(4);var flags=blob.read_shift(1);blob.read_shift(1);blob.read_shift(2);return{r:rw,c:col,cnt:Col-col}}function parse_ForceFullCalculation(blob,length){var header=parse_frtHeader(blob);if(header.type!=2211)throw"Invalid Future Record "+header.type;var fullcalc=blob.read_shift(4);return fullcalc!==0}var parse_CompressPictures=parsenoop2;function parse_RecalcId(blob,length){blob.read_shift(2);return blob.read_shift(4)}function parse_DefaultRowHeight(blob,length){var f=blob.read_shift(2),miyRw;miyRw=blob.read_shift(2);var fl={Unsynced:f&1,DyZero:(f&2)>>1,ExAsc:(f&4)>>2,ExDsc:(f&8)>>3};return[fl,miyRw]}function parse_Window1(blob,length){var xWn=blob.read_shift(2),yWn=blob.read_shift(2),dxWn=blob.read_shift(2),dyWn=blob.read_shift(2);var flags=blob.read_shift(2),iTabCur=blob.read_shift(2),iTabFirst=blob.read_shift(2);var ctabSel=blob.read_shift(2),wTabRatio=blob.read_shift(2);return{Pos:[xWn,yWn],Dim:[dxWn,dyWn],Flags:flags,CurTab:iTabCur,FirstTab:iTabFirst,Selected:ctabSel,TabRatio:wTabRatio}}function parse_Font(blob,length,opts){blob.l+=14;var name=parse_ShortXLUnicodeString(blob,0,opts);return name}function parse_LabelSst(blob,length){var cell=parse_Cell(blob);cell.isst=blob.read_shift(4);return cell}function parse_Label(blob,length,opts){var cell=parse_Cell(blob,6);var str=parse_XLUnicodeString(blob,length-6,opts);cell.val=str;return cell}function parse_Format(blob,length,opts){var ifmt=blob.read_shift(2);var fmtstr=parse_XLUnicodeString2(blob,0,opts);return[ifmt,fmtstr]}function parse_Dimensions(blob,length){var w=length===10?2:4;var r=blob.read_shift(w),R=blob.read_shift(w),c=blob.read_shift(2),C=blob.read_shift(2);blob.l+=2;return{s:{r:r,c:c},e:{r:R,c:C}}}function parse_RK(blob,length){var rw=blob.read_shift(2),col=blob.read_shift(2);var rkrec=parse_RkRec(blob);return{r:rw,c:col,ixfe:rkrec[0],rknum:rkrec[1]}}function parse_MulRk(blob,length){var target=blob.l+length-2;var rw=blob.read_shift(2),col=blob.read_shift(2);var rkrecs=[];while(blob.l<target)rkrecs.push(parse_RkRec(blob));if(blob.l!==target)throw"MulRK read error";var lastcol=blob.read_shift(2);if(rkrecs.length!=lastcol-col+1)throw"MulRK length mismatch";return{r:rw,c:col,C:lastcol,rkrec:rkrecs}}var parse_CellXF=parsenoop;var parse_StyleXF=parsenoop;function parse_XF(blob,length){var o={};o.ifnt=blob.read_shift(2);o.ifmt=blob.read_shift(2);o.flags=blob.read_shift(2);o.fStyle=o.flags>>2&1;length-=6;o.data=o.fStyle?parse_StyleXF(blob,length):parse_CellXF(blob,length);return o}function parse_Guts(blob,length){blob.l+=4;var out=[blob.read_shift(2),blob.read_shift(2)];if(out[0]!==0)out[0]--;if(out[1]!==0)out[1]--;if(out[0]>7||out[1]>7)throw"Bad Gutters: "+out;return out}function parse_BoolErr(blob,length){var cell=parse_Cell(blob,6);var val=parse_Bes(blob,2);cell.val=val;cell.t=val===true||val===false?"b":"e";return cell}function parse_Number(blob,length){var cell=parse_Cell(blob,6);var xnum=parse_Xnum(blob,8);cell.val=xnum;return cell}var parse_XLHeaderFooter=parse_OptXLUnicodeString;function parse_SupBook(blob,length,opts){var end=blob.l+length;var ctab=blob.read_shift(2);var cch=blob.read_shift(2);var virtPath;if(cch>=1&&cch<=255)virtPath=parse_XLUnicodeStringNoCch(blob,cch);var rgst=blob.read_shift(end-blob.l);opts.sbcch=cch;return[cch,ctab,virtPath,rgst]}function parse_ExternName(blob,length,opts){var flags=blob.read_shift(2);var body;var o={fBuiltIn:flags&1,fWantAdvise:flags>>>1&1,fWantPict:flags>>>2&1,fOle:flags>>>3&1,fOleLink:flags>>>4&1,cf:flags>>>5&1023,fIcon:flags>>>15&1};if(opts.sbcch===14849)body=parse_AddinUdf(blob,length-2);o.body=body||blob.read_shift(length-2);return o}function parse_Lbl(blob,length,opts){if(opts.biff<8)return parse_Label(blob,length,opts);var target=blob.l+length;var flags=blob.read_shift(2);var chKey=blob.read_shift(1);var cch=blob.read_shift(1);var cce=blob.read_shift(2);blob.l+=2;var itab=blob.read_shift(2);blob.l+=4;var name=parse_XLUnicodeStringNoCch(blob,cch,opts);var rgce=parse_NameParsedFormula(blob,target-blob.l,opts,cce);return{chKey:chKey,Name:name,rgce:rgce}}function parse_ExternSheet(blob,length,opts){if(opts.biff<8)return parse_ShortXLUnicodeString(blob,length,opts);var o=parslurp2(blob,length,parse_XTI);var oo=[];if(opts.sbcch===1025){for(var i=0;i!=o.length;++i)oo.push(opts.snames[o[i][1]]);return oo}else return o}function parse_ShrFmla(blob,length,opts){var ref=parse_RefU(blob,6);blob.l++;var cUse=blob.read_shift(1);length-=8;return[parse_SharedParsedFormula(blob,length,opts),cUse]}function parse_Array(blob,length,opts){var ref=parse_Ref(blob,6);blob.l+=6;length-=12;return[ref,parse_ArrayParsedFormula(blob,length,opts,ref)]}function parse_MTRSettings(blob,length){var fMTREnabled=blob.read_shift(4)!==0;var fUserSetThreadCount=blob.read_shift(4)!==0;var cUserThreadCount=blob.read_shift(4);return[fMTREnabled,fUserSetThreadCount,cUserThreadCount]}function parse_NoteSh(blob,length,opts){if(opts.biff<8)return;var row=blob.read_shift(2),col=blob.read_shift(2);var flags=blob.read_shift(2),idObj=blob.read_shift(2);var stAuthor=parse_XLUnicodeString2(blob,0,opts);if(opts.biff<8)blob.read_shift(1);return[{r:row,c:col},stAuthor,idObj,flags]}function parse_Note(blob,length,opts){return parse_NoteSh(blob,length,opts)}function parse_MergeCells(blob,length){var merges=[];var cmcs=blob.read_shift(2);while(cmcs--)merges.push(parse_Ref8U(blob,length));return merges}function parse_Obj(blob,length){var cmo=parse_FtCmo(blob,22);var fts=parse_FtArray(blob,length-22,cmo[1]);return{cmo:cmo,ft:fts}}function parse_TxO(blob,length,opts){var s=blob.l;try{blob.l+=4;var ot=(opts.lastobj||{cmo:[0,0]}).cmo[1];var controlInfo;if([0,5,7,11,12,14].indexOf(ot)==-1)blob.l+=6;else controlInfo=parse_ControlInfo(blob,6,opts);var cchText=blob.read_shift(2);var cbRuns=blob.read_shift(2);var ifntEmpty=parse_FontIndex(blob,2);var len=blob.read_shift(2);blob.l+=len;var texts="";for(var i=1;i<blob.lens.length-1;++i){if(blob.l-s!=blob.lens[i])throw"TxO: bad continue record";var hdr=blob[blob.l];var t=parse_XLUnicodeStringNoCch(blob,blob.lens[i+1]-blob.lens[i]-1);texts+=t;if(texts.length>=(hdr?cchText:2*cchText))break}if(texts.length!==cchText&&texts.length!==cchText*2){throw"cchText: "+cchText+" != "+texts.length}blob.l=s+length;return{t:texts}}catch(e){blob.l=s+length;return{t:texts||""}}}var parse_HLink=function(blob,length){var ref=parse_Ref8U(blob,8);blob.l+=16;var hlink=parse_Hyperlink(blob,length-24);return[ref,hlink]};var parse_HLinkTooltip=function(blob,length){var end=blob.l+length;blob.read_shift(2);var ref=parse_Ref8U(blob,8);var wzTooltip=blob.read_shift((length-10)/2,"dbcs");wzTooltip=wzTooltip.replace(chr0,"");return[ref,wzTooltip]};function parse_Country(blob,length){var o=[],d;d=blob.read_shift(2);o[0]=CountryEnum[d]||d;d=blob.read_shift(2);o[1]=CountryEnum[d]||d;return o}var parse_Backup=parsebool;var parse_Blank=parse_Cell;var parse_BottomMargin=parse_Xnum;var parse_BuiltInFnGroupCount=parseuint16;var parse_CalcCount=parseuint16;var parse_CalcDelta=parse_Xnum;var parse_CalcIter=parsebool;var parse_CalcMode=parseuint16;var parse_CalcPrecision=parsebool;var parse_CalcRefMode=parsenoop2;var parse_CalcSaveRecalc=parsebool;var parse_CodePage=parseuint16;var parse_Compat12=parsebool;var parse_Date1904=parsebool;var parse_DefColWidth=parseuint16;var parse_DSF=parsenoop2;var parse_EntExU2=parsenoop2;var parse_EOF=parsenoop2;var parse_Excel9File=parsenoop2;var parse_FeatHdr=parsenoop2;var parse_FontX=parseuint16;var parse_Footer=parse_XLHeaderFooter;var parse_GridSet=parseuint16;var parse_HCenter=parsebool;var parse_Header=parse_XLHeaderFooter;var parse_HideObj=parse_HideObjEnum;var parse_InterfaceEnd=parsenoop2;var parse_LeftMargin=parse_Xnum;var parse_Mms=parsenoop2;var parse_ObjProtect=parsebool;var parse_Password=parseuint16;var parse_PrintGrid=parsebool;var parse_PrintRowCol=parsebool;var parse_PrintSize=parseuint16;var parse_Prot4Rev=parsebool;var parse_Prot4RevPass=parseuint16;var parse_Protect=parsebool;var parse_RefreshAll=parsebool;var parse_RightMargin=parse_Xnum;
18580 dosDate; 25799 var parse_RRTabId=parseuint16a;var parse_ScenarioProtect=parsebool;var parse_Scl=parseuint16a;var parse_String=parse_XLUnicodeString;var parse_SxBool=parsebool;var parse_TopMargin=parse_Xnum;var parse_UsesELFs=parsebool;var parse_VCenter=parsebool;var parse_WinProtect=parsebool;var parse_WriteProtect=parsenoop;var parse_VerticalPageBreaks=parsenoop;var parse_HorizontalPageBreaks=parsenoop;var parse_Selection=parsenoop;var parse_Continue=parsenoop;var parse_Pane=parsenoop;var parse_Pls=parsenoop;var parse_DCon=parsenoop;var parse_DConRef=parsenoop;var parse_DConName=parsenoop;var parse_XCT=parsenoop;var parse_CRN=parsenoop;var parse_FileSharing=parsenoop;var parse_Uncalced=parsenoop;var parse_Template=parsenoop;var parse_Intl=parsenoop;var parse_ColInfo=parsenoop;var parse_WsBool=parsenoop;var parse_Sort=parsenoop;var parse_Palette=parsenoop;var parse_Sync=parsenoop;var parse_LPr=parsenoop;var parse_DxGCol=parsenoop;var parse_FnGroupName=parsenoop;var parse_FilterMode=parsenoop;var parse_AutoFilterInfo=parsenoop;var parse_AutoFilter=parsenoop;var parse_Setup=parsenoop;var parse_ScenMan=parsenoop;var parse_SCENARIO=parsenoop;var parse_SxView=parsenoop;var parse_Sxvd=parsenoop;var parse_SXVI=parsenoop;var parse_SxIvd=parsenoop;var parse_SXLI=parsenoop;var parse_SXPI=parsenoop;var parse_DocRoute=parsenoop;var parse_RecipName=parsenoop;var parse_MulBlank=parsenoop;var parse_SXDI=parsenoop;var parse_SXDB=parsenoop;var parse_SXFDB=parsenoop;var parse_SXDBB=parsenoop;var parse_SXNum=parsenoop;var parse_SxErr=parsenoop;var parse_SXInt=parsenoop;var parse_SXString=parsenoop;var parse_SXDtr=parsenoop;var parse_SxNil=parsenoop;var parse_SXTbl=parsenoop;var parse_SXTBRGIITM=parsenoop;var parse_SxTbpg=parsenoop;var parse_ObProj=parsenoop;var parse_SXStreamID=parsenoop;var parse_DBCell=parsenoop;var parse_SXRng=parsenoop;var parse_SxIsxoper=parsenoop;var parse_BookBool=parsenoop;var parse_DbOrParamQry=parsenoop;var parse_OleObjectSize=parsenoop;var parse_SXVS=parsenoop;var parse_BkHim=parsenoop;var parse_MsoDrawingGroup=parsenoop;var parse_MsoDrawing=parsenoop;var parse_MsoDrawingSelection=parsenoop;var parse_PhoneticInfo=parsenoop;var parse_SxRule=parsenoop;var parse_SXEx=parsenoop;var parse_SxFilt=parsenoop;var parse_SxDXF=parsenoop;var parse_SxItm=parsenoop;var parse_SxName=parsenoop;var parse_SxSelect=parsenoop;var parse_SXPair=parsenoop;var parse_SxFmla=parsenoop;var parse_SxFormat=parsenoop;var parse_SXVDEx=parsenoop;var parse_SXFormula=parsenoop;var parse_SXDBEx=parsenoop;var parse_RRDInsDel=parsenoop;var parse_RRDHead=parsenoop;var parse_RRDChgCell=parsenoop;var parse_RRDRenSheet=parsenoop;var parse_RRSort=parsenoop;var parse_RRDMove=parsenoop;var parse_RRFormat=parsenoop;var parse_RRAutoFmt=parsenoop;var parse_RRInsertSh=parsenoop;var parse_RRDMoveBegin=parsenoop;var parse_RRDMoveEnd=parsenoop;var parse_RRDInsDelBegin=parsenoop;var parse_RRDInsDelEnd=parsenoop;var parse_RRDConflict=parsenoop;var parse_RRDDefName=parsenoop;var parse_RRDRstEtxp=parsenoop;var parse_LRng=parsenoop;var parse_CUsr=parsenoop;var parse_CbUsr=parsenoop;var parse_UsrInfo=parsenoop;var parse_UsrExcl=parsenoop;var parse_FileLock=parsenoop;var parse_RRDInfo=parsenoop;var parse_BCUsrs=parsenoop;var parse_UsrChk=parsenoop;var parse_UserBView=parsenoop;var parse_UserSViewBegin=parsenoop;var parse_UserSViewEnd=parsenoop;var parse_RRDUserView=parsenoop;var parse_Qsi=parsenoop;var parse_CondFmt=parsenoop;var parse_CF=parsenoop;var parse_DVal=parsenoop;var parse_DConBin=parsenoop;var parse_Lel=parsenoop;var parse_CodeName=parse_XLUnicodeString;var parse_SXFDBType=parsenoop;var parse_ObNoMacros=parsenoop;var parse_Dv=parsenoop;var parse_Index=parsenoop;var parse_Table=parsenoop;var parse_Window2=parsenoop;var parse_Style=parsenoop;var parse_BigName=parsenoop;var parse_ContinueBigName=parsenoop;var parse_WebPub=parsenoop;var parse_QsiSXTag=parsenoop;var parse_DBQueryExt=parsenoop;var parse_ExtString=parsenoop;var parse_TxtQry=parsenoop;var parse_Qsir=parsenoop;var parse_Qsif=parsenoop;var parse_RRDTQSIF=parsenoop;var parse_OleDbConn=parsenoop;var parse_WOpt=parsenoop;var parse_SXViewEx=parsenoop;var parse_SXTH=parsenoop;var parse_SXPIEx=parsenoop;var parse_SXVDTEx=parsenoop;var parse_SXViewEx9=parsenoop;var parse_ContinueFrt=parsenoop;var parse_RealTimeData=parsenoop;var parse_ChartFrtInfo=parsenoop;var parse_FrtWrapper=parsenoop;var parse_StartBlock=parsenoop;var parse_EndBlock=parsenoop;var parse_StartObject=parsenoop;var parse_EndObject=parsenoop;var parse_CatLab=parsenoop;var parse_YMult=parsenoop;var parse_SXViewLink=parsenoop;var parse_PivotChartBits=parsenoop;var parse_FrtFontList=parsenoop;var parse_SheetExt=parsenoop;var parse_BookExt=parsenoop;var parse_SXAddl=parsenoop;var parse_CrErr=parsenoop;var parse_HFPicture=parsenoop;var parse_Feat=parsenoop;var parse_DataLabExt=parsenoop;var parse_DataLabExtContents=parsenoop;var parse_CellWatch=parsenoop;var parse_FeatHdr11=parsenoop;var parse_Feature11=parsenoop;var parse_DropDownObjIds=parsenoop;var parse_ContinueFrt11=parsenoop;var parse_DConn=parsenoop;var parse_List12=parsenoop;var parse_Feature12=parsenoop;var parse_CondFmt12=parsenoop;var parse_CF12=parsenoop;var parse_CFEx=parsenoop;var parse_XFCRC=parsenoop;var parse_XFExt=parsenoop;var parse_AutoFilter12=parsenoop;var parse_ContinueFrt12=parsenoop;var parse_MDTInfo=parsenoop;var parse_MDXStr=parsenoop;var parse_MDXTuple=parsenoop;var parse_MDXSet=parsenoop;var parse_MDXProp=parsenoop;var parse_MDXKPI=parsenoop;var parse_MDB=parsenoop;var parse_PLV=parsenoop;var parse_DXF=parsenoop;var parse_TableStyles=parsenoop;var parse_TableStyle=parsenoop;var parse_TableStyleElement=parsenoop;var parse_StyleExt=parsenoop;var parse_NamePublish=parsenoop;var parse_NameCmt=parsenoop;var parse_SortData=parsenoop;var parse_Theme=parsenoop;var parse_GUIDTypeLib=parsenoop;var parse_FnGrp12=parsenoop;var parse_NameFnGrp12=parsenoop;var parse_HeaderFooter=parsenoop;var parse_CrtLayout12=parsenoop;var parse_CrtMlFrt=parsenoop;var parse_CrtMlFrtContinue=parsenoop;var parse_ShapePropsStream=parsenoop;var parse_TextPropsStream=parsenoop;var parse_RichTextStream=parsenoop;var parse_CrtLayout12A=parsenoop;var parse_Units=parsenoop;var parse_Chart=parsenoop;var parse_Series=parsenoop;var parse_DataFormat=parsenoop;var parse_LineFormat=parsenoop;var parse_MarkerFormat=parsenoop;var parse_AreaFormat=parsenoop;var parse_PieFormat=parsenoop;var parse_AttachedLabel=parsenoop;var parse_SeriesText=parsenoop;var parse_ChartFormat=parsenoop;var parse_Legend=parsenoop;var parse_SeriesList=parsenoop;var parse_Bar=parsenoop;var parse_Line=parsenoop;var parse_Pie=parsenoop;var parse_Area=parsenoop;var parse_Scatter=parsenoop;var parse_CrtLine=parsenoop;var parse_Axis=parsenoop;var parse_Tick=parsenoop;var parse_ValueRange=parsenoop;var parse_CatSerRange=parsenoop;var parse_AxisLine=parsenoop;var parse_CrtLink=parsenoop;var parse_DefaultText=parsenoop;var parse_Text=parsenoop;var parse_ObjectLink=parsenoop;var parse_Frame=parsenoop;var parse_Begin=parsenoop;var parse_End=parsenoop;var parse_PlotArea=parsenoop;var parse_Chart3d=parsenoop;var parse_PicF=parsenoop;var parse_DropBar=parsenoop;var parse_Radar=parsenoop;var parse_Surf=parsenoop;var parse_RadarArea=parsenoop;var parse_AxisParent=parsenoop;var parse_LegendException=parsenoop;var parse_ShtProps=parsenoop;var parse_SerToCrt=parsenoop;var parse_AxesUsed=parsenoop;var parse_SBaseRef=parsenoop;var parse_SerParent=parsenoop;var parse_SerAuxTrend=parsenoop;var parse_IFmtRecord=parsenoop;var parse_Pos=parsenoop;var parse_AlRuns=parsenoop;var parse_BRAI=parsenoop;var parse_SerAuxErrBar=parsenoop;var parse_ClrtClient=parsenoop;var parse_SerFmt=parsenoop;var parse_Chart3DBarShape=parsenoop;var parse_Fbi=parsenoop;var parse_BopPop=parsenoop;var parse_AxcExt=parsenoop;var parse_Dat=parsenoop;var parse_PlotGrowth=parsenoop;var parse_SIIndex=parsenoop;var parse_GelFrame=parsenoop;var parse_BopPopCustom=parsenoop;var parse_Fbi2=parsenoop;function parse_BIFF5String(blob){var len=blob.read_shift(1);return blob.read_shift(len,"sbcs")}var _chr=function(c){return String.fromCharCode(c)};var attregexg=/([\w:]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:'))/g;var attregex=/([\w:]+)=((?:")(?:[^"]*)(?:")|(?:')(?:[^']*)(?:'))/;function parsexmltag(tag,skip_root){var words=tag.split(/\s+/);var z=[];if(!skip_root)z[0]=words[0];if(words.length===1)return z;var m=tag.match(attregexg),y,j,w,i;if(m)for(i=0;i!=m.length;++i){y=m[i].match(attregex);if((j=y[1].indexOf(":"))===-1)z[y[1]]=y[2].substr(1,y[2].length-2);else{if(y[1].substr(0,6)==="xmlns:")w="xmlns"+y[1].substr(6);else w=y[1].substr(j+1);z[w]=y[2].substr(1,y[2].length-2)}}return z}function parsexmltagobj(tag){var words=tag.split(/\s+/);var z={};if(words.length===1)return z;var m=tag.match(attregexg),y,j,w,i;if(m)for(i=0;i!=m.length;++i){y=m[i].match(attregex);if((j=y[1].indexOf(":"))===-1)z[y[1]]=y[2].substr(1,y[2].length-2);else{if(y[1].substr(0,6)==="xmlns:")w="xmlns"+y[1].substr(6);else w=y[1].substr(j+1);z[w]=y[2].substr(1,y[2].length-2)}}return z}var encodings={"&quot;":'"',"&apos;":"'","&gt;":">","&lt;":"<","&amp;":"&"};var rencoding=evert(encodings);var rencstr="&<>'\"".split("");var XML_HEADER='<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n';var OFFCRYPTO={};var make_offcrypto=function(O,_crypto){var crypto;if(typeof _crypto!=="undefined")crypto=_crypto;else if(typeof require!=="undefined"){try{crypto=require("cry"+"pto")}catch(e){crypto=null}}O.rc4=function(key,data){var S=new Array(256);var c=0,i=0,j=0,t=0;for(i=0;i!=256;++i)S[i]=i;for(i=0;i!=256;++i){j=j+S[i]+key[i%key.length].charCodeAt(0)&255;t=S[i];S[i]=S[j];S[j]=t}i=j=0;out=Buffer(data.length);for(c=0;c!=data.length;++c){i=i+1&255;j=(j+S[i])%256;t=S[i];S[i]=S[j];S[j]=t;out[c]=data[c]^S[S[i]+S[j]&255]}return out};if(crypto){O.md5=function(hex){return crypto.createHash("md5").update(hex).digest("hex")}}else{O.md5=function(hex){throw"unimplemented"}}};make_offcrypto(OFFCRYPTO,typeof crypto!=="undefined"?crypto:undefined);function _JS2ANSI(str){if(typeof cptable!=="undefined")return cptable.utils.encode(1252,str);return str.split("").map(function(x){return x.charCodeAt(0)})}function parse_Version(blob,length){var o={};o.Major=blob.read_shift(2);o.Minor=blob.read_shift(2);return o}function parse_EncryptionHeader(blob,length){var o={};o.Flags=blob.read_shift(4);var tmp=blob.read_shift(4);if(tmp!==0)throw"Unrecognized SizeExtra: "+tmp;o.AlgID=blob.read_shift(4);switch(o.AlgID){case 0:case 26625:case 26126:case 26127:case 26128:break;default:throw"Unrecognized encryption algorithm: "+o.AlgID}parsenoop(blob,length-12);return o}function parse_EncryptionVerifier(blob,length){return parsenoop(blob,length)}function parse_RC4CryptoHeader(blob,length){var o={};var vers=o.EncryptionVersionInfo=parse_Version(blob,4);length-=4;if(vers.Minor!=2)throw"unrecognized minor version code: "+vers.Minor;if(vers.Major>4||vers.Major<2)throw"unrecognized major version code: "+vers.Major;o.Flags=blob.read_shift(4);length-=4;var sz=blob.read_shift(4);length-=4;o.EncryptionHeader=parse_EncryptionHeader(blob,sz);length-=sz;o.EncryptionVerifier=parse_EncryptionVerifier(blob,length);return o}function parse_RC4Header(blob,length){var o={};var vers=o.EncryptionVersionInfo=parse_Version(blob,4);length-=4;if(vers.Major!=1||vers.Minor!=1)throw"unrecognized version code "+vers.Major+" : "+vers.Minor;o.Salt=blob.read_shift(16);o.EncryptedVerifier=blob.read_shift(16);o.EncryptedVerifierHash=blob.read_shift(16);return o}function crypto_CreatePasswordVerifier_Method1(Password){var Verifier=0,PasswordArray;var PasswordDecoded=_JS2ANSI(Password);var len=PasswordDecoded.length+1,i,PasswordByte;var Intermediate1,Intermediate2,Intermediate3;PasswordArray=new_buf(len);PasswordArray[0]=PasswordDecoded.length;for(i=1;i!=len;++i)PasswordArray[i]=PasswordDecoded[i-1];for(i=len-1;i>=0;--i){PasswordByte=PasswordArray[i];Intermediate1=(Verifier&16384)===0?0:1;Intermediate2=Verifier<<1&32767;Intermediate3=Intermediate1|Intermediate2;Verifier=Intermediate3^PasswordByte}return Verifier^52811}var crypto_CreateXorArray_Method1=function(){var PadArray=[187,255,255,186,255,255,185,128,0,190,15,0,191,15,0];var InitialCode=[57840,7439,52380,33984,4364,3600,61902,12606,6258,57657,54287,34041,10252,43370,20163];var XorMatrix=[44796,19929,39858,10053,20106,40212,10761,31585,63170,64933,60267,50935,40399,11199,17763,35526,1453,2906,5812,11624,23248,885,1770,3540,7080,14160,28320,56640,55369,41139,20807,41614,21821,43642,17621,28485,56970,44341,19019,38038,14605,29210,60195,50791,40175,10751,21502,43004,24537,18387,36774,3949,7898,15796,31592,63184,47201,24803,49606,37805,14203,28406,56812,17824,35648,1697,3394,6788,13576,27152,43601,17539,35078,557,1114,2228,4456,30388,60776,51953,34243,7079,14158,28316,14128,28256,56512,43425,17251,34502,7597,13105,26210,52420,35241,883,1766,3532,4129,8258,16516,33032,4657,9314,18628];var Ror=function(Byte){return(Byte/2|Byte*128)&255};var XorRor=function(byte1,byte2){return Ror(byte1^byte2)};var CreateXorKey_Method1=function(Password){var XorKey=InitialCode[Password.length-1];var CurrentElement=104;for(var i=Password.length-1;i>=0;--i){var Char=Password[i];for(var j=0;j!=7;++j){if(Char&64)XorKey^=XorMatrix[CurrentElement];Char*=2;--CurrentElement}}return XorKey};return function(password){var Password=_JS2ANSI(password);var XorKey=CreateXorKey_Method1(Password);var Index=Password.length;var ObfuscationArray=new_buf(16);for(var i=0;i!=16;++i)ObfuscationArray[i]=0;var Temp,PasswordLastChar,PadIndex;if((Index&1)===1){Temp=XorKey>>8;ObfuscationArray[Index]=XorRor(PadArray[0],Temp);--Index;Temp=XorKey&255;PasswordLastChar=Password[Password.length-1];ObfuscationArray[Index]=XorRor(PasswordLastChar,Temp)}while(Index>0){--Index;Temp=XorKey>>8;ObfuscationArray[Index]=XorRor(Password[Index],Temp);--Index;Temp=XorKey&255;ObfuscationArray[Index]=XorRor(Password[Index],Temp)}Index=15;PadIndex=15-Password.length;while(PadIndex>0){Temp=XorKey>>8;ObfuscationArray[Index]=XorRor(PadArray[PadIndex],Temp);--Index;--PadIndex;Temp=XorKey&255;ObfuscationArray[Index]=XorRor(Password[Index],Temp);--Index;--PadIndex}return ObfuscationArray}}();var crypto_DecryptData_Method1=function(password,Data,XorArrayIndex,XorArray,O){if(!O)O=Data;if(!XorArray)XorArray=crypto_CreateXorArray_Method1(password);var Index,Value;for(Index=0;Index!=Data.length;++Index){Value=Data[Index];Value^=XorArray[XorArrayIndex];Value=(Value>>5|Value<<3)&255;O[Index]=Value;++XorArrayIndex}return[O,XorArrayIndex,XorArray]};var crypto_MakeXorDecryptor=function(password){var XorArrayIndex=0,XorArray=crypto_CreateXorArray_Method1(password);return function(Data){var O=crypto_DecryptData_Method1(null,Data,XorArrayIndex,XorArray);XorArrayIndex=O[1];return O[0]}};function parse_XORObfuscation(blob,length,opts,out){var o={key:parseuint16(blob),verificationBytes:parseuint16(blob)};if(opts.password)o.verifier=crypto_CreatePasswordVerifier_Method1(opts.password);out.valid=o.verificationBytes===o.verifier;if(out.valid)out.insitu_decrypt=crypto_MakeXorDecryptor(opts.password);return o}function parse_FilePassHeader(blob,length,oo){var o=oo||{};o.Info=blob.read_shift(2);blob.l-=2;if(o.Info===1)o.Data=parse_RC4Header(blob,length);else o.Data=parse_RC4CryptoHeader(blob,length);return o}function parse_FilePass(blob,length,opts){var o={Type:blob.read_shift(2)};if(o.Type)parse_FilePassHeader(blob,length-2,o);else parse_XORObfuscation(blob,length-2,opts,o);return o}function parseread(l){return function(blob,length){blob.l+=l;return}}function parseread1(blob,length){blob.l+=1;return}function parse_ColRelU(blob,length){var c=blob.read_shift(2);return[c&16383,c>>14&1,c>>15&1]}function parse_RgceArea(blob,length){var r=blob.read_shift(2),R=blob.read_shift(2);var c=parse_ColRelU(blob,2);var C=parse_ColRelU(blob,2);return{s:{r:r,c:c[0],cRel:c[1],rRel:c[2]},e:{r:R,c:C[0],cRel:C[1],rRel:C[2]}}}function parse_RgceAreaRel(blob,length){var r=blob.read_shift(2),R=blob.read_shift(2);var c=parse_ColRelU(blob,2);var C=parse_ColRelU(blob,2);return{s:{r:r,c:c[0],cRel:c[1],rRel:c[2]},e:{r:R,c:C[0],cRel:C[1],rRel:C[2]}}}function parse_RgceLoc(blob,length){var r=blob.read_shift(2);var c=parse_ColRelU(blob,2);return{r:r,c:c[0],cRel:c[1],rRel:c[2]}}function parse_RgceLocRel(blob,length){var r=blob.read_shift(2);var cl=blob.read_shift(2);var cRel=(cl&32768)>>15,rRel=(cl&16384)>>14;cl&=16383;if(cRel!==0)while(cl>=256)cl-=256;return{r:r,c:cl,cRel:cRel,rRel:rRel}}function parse_PtgArea(blob,length){var type=(blob[blob.l++]&96)>>5;var area=parse_RgceArea(blob,8);return[type,area]}function parse_PtgArea3d(blob,length){var type=(blob[blob.l++]&96)>>5;var ixti=blob.read_shift(2);var area=parse_RgceArea(blob,8);return[type,ixti,area]}function parse_PtgAreaErr(blob,length){var type=(blob[blob.l++]&96)>>5;blob.l+=8;return[type]}function parse_PtgAreaErr3d(blob,length){var type=(blob[blob.l++]&96)>>5;var ixti=blob.read_shift(2);blob.l+=8;return[type,ixti]}function parse_PtgAreaN(blob,length){var type=(blob[blob.l++]&96)>>5;var area=parse_RgceAreaRel(blob,8);return[type,area]}function parse_PtgArray(blob,length){var type=(blob[blob.l++]&96)>>5;blob.l+=7;return[type]}function parse_PtgAttrBaxcel(blob,length){var bitSemi=blob[blob.l+1]&1;var bitBaxcel=1;blob.l+=4;return[bitSemi,bitBaxcel]}function parse_PtgAttrChoose(blob,length){blob.l+=2;var offset=blob.read_shift(2);var o=[];for(var i=0;i<=offset;++i)o.push(blob.read_shift(2));return o}function parse_PtgAttrGoto(blob,length){var bitGoto=blob[blob.l+1]&255?1:0;blob.l+=2;return[bitGoto,blob.read_shift(2)]}function parse_PtgAttrIf(blob,length){var bitIf=blob[blob.l+1]&255?1:0;blob.l+=2;return[bitIf,blob.read_shift(2)]}function parse_PtgAttrSemi(blob,length){var bitSemi=blob[blob.l+1]&255?1:0;blob.l+=4;return[bitSemi]}function parse_PtgAttrSpaceType(blob,length){var type=blob.read_shift(1),cch=blob.read_shift(1);return[type,cch]}function parse_PtgAttrSpace(blob,length){blob.read_shift(2);return parse_PtgAttrSpaceType(blob,2)}function parse_PtgAttrSpaceSemi(blob,length){blob.read_shift(2);return parse_PtgAttrSpaceType(blob,2)}function parse_PtgRef(blob,length){var ptg=blob[blob.l]&31;var type=(blob[blob.l]&96)>>5;blob.l+=1;var loc=parse_RgceLoc(blob,4);return[type,loc]}function parse_PtgRefN(blob,length){var ptg=blob[blob.l]&31;var type=(blob[blob.l]&96)>>5;blob.l+=1;var loc=parse_RgceLocRel(blob,4);return[type,loc]}function parse_PtgRef3d(blob,length){var ptg=blob[blob.l]&31;var type=(blob[blob.l]&96)>>5;blob.l+=1;var ixti=blob.read_shift(2);var loc=parse_RgceLoc(blob,4);return[type,ixti,loc]}function parse_PtgFunc(blob,length){var ptg=blob[blob.l]&31;var type=(blob[blob.l]&96)>>5;blob.l+=1;var iftab=blob.read_shift(2);return[FtabArgc[iftab],Ftab[iftab]]}function parse_PtgFuncVar(blob,length){blob.l++;var cparams=blob.read_shift(1),tab=parsetab(blob);return[cparams,(tab[0]===0?Ftab:Cetab)[tab[1]]]}function parsetab(blob,length){return[blob[blob.l+1]>>7,blob.read_shift(2)&32767]}var parse_PtgAttrSum=parseread(4);var parse_PtgConcat=parseread1;function parse_PtgExp(blob,length){blob.l++;var row=blob.read_shift(2);var col=blob.read_shift(2);return[row,col]}function parse_PtgErr(blob,length){blob.l++;return BERR[blob.read_shift(1)]}function parse_PtgInt(blob,length){blob.l++;return blob.read_shift(2)}function parse_PtgBool(blob,length){blob.l++;return blob.read_shift(1)!==0}function parse_PtgNum(blob,length){blob.l++;return parse_Xnum(blob,8)}function parse_PtgStr(blob,length){blob.l++;return parse_ShortXLUnicodeString(blob)}function parse_SerAr(blob){var val=[];switch(val[0]=blob.read_shift(1)){case 4:val[1]=parsebool(blob,1)?"TRUE":"FALSE";blob.l+=7;break;case 16:val[1]=BERR[blob[blob.l]];blob.l+=8;break;case 0:blob.l+=8;break;case 1:val[1]=parse_Xnum(blob,8);break;case 2:val[1]=parse_XLUnicodeString(blob);break}return val}function parse_PtgExtraMem(blob,cce){var count=blob.read_shift(2);var out=[];for(var i=0;i!=count;++i)out.push(parse_Ref8U(blob,8));return out}function parse_PtgExtraArray(blob){var cols=1+blob.read_shift(1);var rows=1+blob.read_shift(2);for(var i=0,o=[];i!=rows&&(o[i]=[]);++i)for(var j=0;j!=cols;++j)o[i][j]=parse_SerAr(blob);return o}function parse_PtgName(blob,length){var type=blob.read_shift(1)>>>5&3;var nameindex=blob.read_shift(4);return[type,0,nameindex]}function parse_PtgNameX(blob,length){var type=blob.read_shift(1)>>>5&3;var ixti=blob.read_shift(2);var nameindex=blob.read_shift(4);return[type,ixti,nameindex]}function parse_PtgMemArea(blob,length){var type=blob.read_shift(1)>>>5&3;blob.l+=4;var cce=blob.read_shift(2);return[type,cce]}function parse_PtgMemFunc(blob,length){var type=blob.read_shift(1)>>>5&3;var cce=blob.read_shift(2);return[type,cce]}function parse_PtgRefErr(blob,length){var type=blob.read_shift(1)>>>5&3;blob.l+=4;return[type]}var parse_PtgAdd=parseread1;var parse_PtgDiv=parseread1;var parse_PtgEq=parseread1;var parse_PtgGe=parseread1;var parse_PtgGt=parseread1;var parse_PtgIsect=parseread1;var parse_PtgLe=parseread1;var parse_PtgLt=parseread1;var parse_PtgMissArg=parseread1;var parse_PtgMul=parseread1;var parse_PtgNe=parseread1;var parse_PtgParen=parseread1;var parse_PtgPercent=parseread1;var parse_PtgPower=parseread1;var parse_PtgRange=parseread1;var parse_PtgSub=parseread1;var parse_PtgUminus=parseread1;var parse_PtgUnion=parseread1;var parse_PtgUplus=parseread1;var parse_PtgMemErr=parsenoop;var parse_PtgMemNoMem=parsenoop;var parse_PtgRefErr3d=parsenoop;var parse_PtgTbl=parsenoop;var PtgTypes={1:{n:"PtgExp",f:parse_PtgExp},2:{n:"PtgTbl",f:parse_PtgTbl},3:{n:"PtgAdd",f:parse_PtgAdd},4:{n:"PtgSub",f:parse_PtgSub},5:{n:"PtgMul",f:parse_PtgMul},6:{n:"PtgDiv",f:parse_PtgDiv},7:{n:"PtgPower",f:parse_PtgPower},8:{n:"PtgConcat",f:parse_PtgConcat},9:{n:"PtgLt",f:parse_PtgLt},10:{n:"PtgLe",f:parse_PtgLe},11:{n:"PtgEq",f:parse_PtgEq},12:{n:"PtgGe",f:parse_PtgGe},13:{n:"PtgGt",f:parse_PtgGt},14:{n:"PtgNe",f:parse_PtgNe},15:{n:"PtgIsect",f:parse_PtgIsect},16:{n:"PtgUnion",f:parse_PtgUnion},17:{n:"PtgRange",f:parse_PtgRange},18:{n:"PtgUplus",f:parse_PtgUplus},19:{n:"PtgUminus",f:parse_PtgUminus},20:{n:"PtgPercent",f:parse_PtgPercent},21:{n:"PtgParen",f:parse_PtgParen},22:{n:"PtgMissArg",f:parse_PtgMissArg},23:{n:"PtgStr",f:parse_PtgStr},28:{n:"PtgErr",f:parse_PtgErr},29:{n:"PtgBool",f:parse_PtgBool},30:{n:"PtgInt",f:parse_PtgInt},31:{n:"PtgNum",f:parse_PtgNum},32:{n:"PtgArray",f:parse_PtgArray},33:{n:"PtgFunc",f:parse_PtgFunc},34:{n:"PtgFuncVar",f:parse_PtgFuncVar},35:{n:"PtgName",f:parse_PtgName},36:{n:"PtgRef",f:parse_PtgRef},37:{n:"PtgArea",f:parse_PtgArea},38:{n:"PtgMemArea",f:parse_PtgMemArea},39:{n:"PtgMemErr",f:parse_PtgMemErr},40:{n:"PtgMemNoMem",f:parse_PtgMemNoMem},41:{n:"PtgMemFunc",f:parse_PtgMemFunc},42:{n:"PtgRefErr",f:parse_PtgRefErr},43:{n:"PtgAreaErr",f:parse_PtgAreaErr},44:{n:"PtgRefN",f:parse_PtgRefN},45:{n:"PtgAreaN",f:parse_PtgAreaN},57:{n:"PtgNameX",f:parse_PtgNameX},58:{n:"PtgRef3d",f:parse_PtgRef3d},59:{n:"PtgArea3d",f:parse_PtgArea3d},60:{n:"PtgRefErr3d",f:parse_PtgRefErr3d},61:{n:"PtgAreaErr3d",f:parse_PtgAreaErr3d},255:{}};var PtgDupes={64:32,96:32,65:33,97:33,66:34,98:34,67:35,99:35,68:36,100:36,69:37,101:37,70:38,102:38,71:39,103:39,72:40,104:40,73:41,105:41,74:42,106:42,75:43,107:43,76:44,108:44,77:45,109:45,89:57,121:57,90:58,122:58,91:59,123:59,92:60,124:60,93:61,125:61};(function(){for(var y in PtgDupes)PtgTypes[y]=PtgTypes[PtgDupes[y]]})();var Ptg18={};var Ptg19={1:{n:"PtgAttrSemi",f:parse_PtgAttrSemi},2:{n:"PtgAttrIf",f:parse_PtgAttrIf},4:{n:"PtgAttrChoose",f:parse_PtgAttrChoose},8:{n:"PtgAttrGoto",f:parse_PtgAttrGoto},16:{n:"PtgAttrSum",f:parse_PtgAttrSum},32:{n:"PtgAttrBaxcel",f:parse_PtgAttrBaxcel},64:{n:"PtgAttrSpace",f:parse_PtgAttrSpace},65:{n:"PtgAttrSpaceSemi",f:parse_PtgAttrSpaceSemi},255:{}};var rcregex=/(^|[^A-Za-z])R(\[?)(-?\d+|)\]?C(\[?)(-?\d+|)\]?/g;var rcbase;function rcfunc($$,$1,$2,$3,$4,$5){var R=$3.length>0?parseInt($3,10)|0:0,C=$5.length>0?parseInt($5,10)|0:0;if(C<0&&$4.length===0)C=0;if($4.length>0)C+=rcbase.c;if($2.length>0)R+=rcbase.r;return $1+encode_col(C)+encode_row(R)}function rc_to_a1(fstr,base){rcbase=base;return fstr.replace(rcregex,rcfunc)}function parse_Formula(blob,length,opts){var cell=parse_Cell(blob,6);var val=parse_FormulaValue(blob,8);var flags=blob.read_shift(1);blob.read_shift(1);var chn=blob.read_shift(4);var cbf="";if(opts.biff===5)blob.l+=length-20;else cbf=parse_CellParsedFormula(blob,length-20,opts);return{cell:cell,val:val[0],formula:cbf,shared:flags>>3&1,tt:val[1]}}function parse_FormulaValue(blob){var b;if(__readUInt16LE(blob,blob.l+6)!==65535)return[parse_Xnum(blob),"n"];switch(blob[blob.l]){case 0:blob.l+=8;return["String","s"];case 1:b=blob[blob.l+2]===1;blob.l+=8;return[b,"b"];case 2:b=BERR[blob[blob.l+2]];blob.l+=8;return[b,"e"];case 3:blob.l+=8;return["","s"]}}function parse_RgbExtra(blob,length,rgce,opts){if(opts.biff<8)return parsenoop(blob,length);var target=blob.l+length;var o=[];for(var i=0;i!==rgce.length;++i){switch(rgce[i][0]){case"PtgArray":rgce[i][1]=parse_PtgExtraArray(blob);o.push(rgce[i][1]);break;case"PtgMemArea":rgce[i][2]=parse_PtgExtraMem(blob,rgce[i][1]);o.push(rgce[i][2]);break;default:break}}length=target-blob.l;if(length!==0)o.push(parsenoop(blob,length));return o}function parse_NameParsedFormula(blob,length,opts,cce){var target=blob.l+length;var rgce=parse_Rgce(blob,cce);var rgcb;if(target!==blob.l)rgcb=parse_RgbExtra(blob,target-blob.l,rgce,opts);return[rgce,rgcb]}function parse_CellParsedFormula(blob,length,opts){var target=blob.l+length;var rgcb,cce=blob.read_shift(2);if(cce==65535)return[[],parsenoop(blob,length-2)];var rgce=parse_Rgce(blob,cce);if(length!==cce+2)rgcb=parse_RgbExtra(blob,length-cce-2,rgce,opts);return[rgce,rgcb]}function parse_SharedParsedFormula(blob,length,opts){var target=blob.l+length;var rgcb,cce=blob.read_shift(2);var rgce=parse_Rgce(blob,cce);if(cce==65535)return[[],parsenoop(blob,length-2)];if(length!==cce+2)rgcb=parse_RgbExtra(blob,target-cce-2,rgce,opts);return[rgce,rgcb]}function parse_ArrayParsedFormula(blob,length,opts,ref){var target=blob.l+length;var rgcb,cce=blob.read_shift(2);if(cce==65535)return[[],parsenoop(blob,length-2)];var rgce=parse_Rgce(blob,cce);if(length!==cce+2)rgcb=parse_RgbExtra(blob,target-cce-2,rgce,opts);return[rgce,rgcb]}function parse_Rgce(blob,length){var target=blob.l+length;var R,id,ptgs=[];while(target!=blob.l){length=target-blob.l;id=blob[blob.l];R=PtgTypes[id];if(id===24||id===25){id=blob[blob.l+1];R=(id===24?Ptg18:Ptg19)[id]}if(!R||!R.f){ptgs.push(parsenoop(blob,length))}else{ptgs.push([R.n,R.f(blob,length)])}}return ptgs}function mapper(x){return x.map(function f2(y){return y[1]}).join(",")}function stringify_formula(formula,range,cell,supbooks,opts){if(opts!==undefined&&opts.biff===5)return"BIFF5??";var _range=range!==undefined?range:{s:{c:0,r:0}};var stack=[],e1,e2,type,c,ixti,nameidx,r;if(!formula[0]||!formula[0][0])return"";for(var ff=0,fflen=formula[0].length;ff<fflen;++ff){var f=formula[0][ff];switch(f[0]){case"PtgUminus":stack.push("-"+stack.pop());break;case"PtgUplus":stack.push("+"+stack.pop());break;case"PtgPercent":stack.push(stack.pop()+"%");break;case"PtgAdd":e1=stack.pop();e2=stack.pop();stack.push(e2+"+"+e1);break;case"PtgSub":e1=stack.pop();e2=stack.pop();stack.push(e2+"-"+e1);break;case"PtgMul":e1=stack.pop();e2=stack.pop();stack.push(e2+"*"+e1);break;case"PtgDiv":e1=stack.pop();e2=stack.pop();stack.push(e2+"/"+e1);break;case"PtgPower":e1=stack.pop();e2=stack.pop();stack.push(e2+"^"+e1);break;case"PtgConcat":e1=stack.pop();e2=stack.pop();stack.push(e2+"&"+e1);break;case"PtgLt":e1=stack.pop();e2=stack.pop();stack.push(e2+"<"+e1);break;case"PtgLe":e1=stack.pop();e2=stack.pop();stack.push(e2+"<="+e1);break;case"PtgEq":e1=stack.pop();e2=stack.pop();stack.push(e2+"="+e1);break;case"PtgGe":e1=stack.pop();e2=stack.pop();stack.push(e2+">="+e1);break;case"PtgGt":e1=stack.pop();e2=stack.pop();stack.push(e2+">"+e1);break;case"PtgNe":e1=stack.pop();e2=stack.pop();stack.push(e2+"<>"+e1);break;case"PtgIsect":e1=stack.pop();e2=stack.pop();stack.push(e2+" "+e1);break;case"PtgUnion":e1=stack.pop();e2=stack.pop();stack.push(e2+","+e1);break;case"PtgRange":break;case"PtgAttrChoose":break;case"PtgAttrGoto":break;case"PtgAttrIf":break;case"PtgRef":type=f[1][0];c=shift_cell(decode_cell(encode_cell(f[1][1])),_range);stack.push(encode_cell(c));break;case"PtgRefN":type=f[1][0];c=shift_cell(decode_cell(encode_cell(f[1][1])),cell);stack.push(encode_cell(c));break;case"PtgRef3d":type=f[1][0];ixti=f[1][1];c=shift_cell(f[1][2],_range);stack.push(supbooks[1][ixti+1]+"!"+encode_cell(c));break;case"PtgFunc":case"PtgFuncVar":var argc=f[1][0],func=f[1][1];if(!argc)argc=0;var args=stack.slice(-argc);stack.length-=argc;if(func==="User")func=args.shift();stack.push(func+"("+args.join(",")+")");break;case"PtgBool":stack.push(f[1]?"TRUE":"FALSE");break;case"PtgInt":stack.push(f[1]);break;case"PtgNum":stack.push(String(f[1]));break;case"PtgStr":stack.push('"'+f[1]+'"');break;case"PtgErr":stack.push(f[1]);break;case"PtgArea":type=f[1][0];r=shift_range(f[1][1],_range);stack.push(encode_range(r));break;case"PtgArea3d":type=f[1][0];ixti=f[1][1];r=f[1][2];stack.push(supbooks[1][ixti+1]+"!"+encode_range(r));break;case"PtgAttrSum":stack.push("SUM("+stack.pop()+")");break;case"PtgAttrSemi":break;case"PtgName":nameidx=f[1][2];var lbl=supbooks[0][nameidx];var name=lbl.Name;if(name in XLSXFutureFunctions)name=XLSXFutureFunctions[name];stack.push(name);break;case"PtgNameX":var bookidx=f[1][1];nameidx=f[1][2];var externbook;if(supbooks[bookidx+1])externbook=supbooks[bookidx+1][nameidx];else if(supbooks[bookidx-1])externbook=supbooks[bookidx-1][nameidx];if(!externbook)externbook={body:"??NAMEX??"};stack.push(externbook.body);break;case"PtgParen":stack.push("("+stack.pop()+")");break;case"PtgRefErr":stack.push("#REF!");break;case"PtgExp":c={c:f[1][1],r:f[1][0]};var q={c:cell.c,r:cell.r};if(supbooks.sharedf[encode_cell(c)]){var parsedf=supbooks.sharedf[encode_cell(c)];stack.push(stringify_formula(parsedf,_range,q,supbooks,opts))}else{var fnd=false;for(e1=0;e1!=supbooks.arrayf.length;++e1){e2=supbooks.arrayf[e1];if(c.c<e2[0].s.c||c.c>e2[0].e.c)continue;if(c.r<e2[0].s.r||c.r>e2[0].e.r)continue;stack.push(stringify_formula(e2[1],_range,q,supbooks,opts))}if(!fnd)stack.push(f[1])}break;case"PtgArray":stack.push("{"+f[1].map(mapper).join(";")+"}");break;case"PtgMemArea":break;case"PtgAttrSpace":break;case"PtgTbl":break;case"PtgMemErr":break;case"PtgMissArg":stack.push("");break;case"PtgAreaErr":break;case"PtgAreaN":stack.push("");break;case"PtgRefErr3d":break;case"PtgMemFunc":break;default:throw"Unrecognized Formula Token: "+f}}return stack[0]}var PtgDataType={1:"REFERENCE",2:"VALUE",3:"ARRAY"};var BERR={0:"#NULL!",7:"#DIV/0!",15:"#VALUE!",23:"#REF!",29:"#NAME?",36:"#NUM!",42:"#N/A",43:"#GETTING_DATA",255:"#WTF?"};var Cetab={0:"BEEP",1:"OPEN",2:"OPEN.LINKS",3:"CLOSE.ALL",4:"SAVE",5:"SAVE.AS",6:"FILE.DELETE",7:"PAGE.SETUP",8:"PRINT",9:"PRINTER.SETUP",10:"QUIT",11:"NEW.WINDOW",12:"ARRANGE.ALL",13:"WINDOW.SIZE",14:"WINDOW.MOVE",15:"FULL",16:"CLOSE",17:"RUN",22:"SET.PRINT.AREA",23:"SET.PRINT.TITLES",24:"SET.PAGE.BREAK",25:"REMOVE.PAGE.BREAK",26:"FONT",27:"DISPLAY",28:"PROTECT.DOCUMENT",29:"PRECISION",30:"A1.R1C1",31:"CALCULATE.NOW",32:"CALCULATION",34:"DATA.FIND",35:"EXTRACT",36:"DATA.DELETE",37:"SET.DATABASE",38:"SET.CRITERIA",39:"SORT",40:"DATA.SERIES",41:"TABLE",42:"FORMAT.NUMBER",43:"ALIGNMENT",44:"STYLE",45:"BORDER",46:"CELL.PROTECTION",47:"COLUMN.WIDTH",48:"UNDO",49:"CUT",50:"COPY",51:"PASTE",52:"CLEAR",53:"PASTE.SPECIAL",54:"EDIT.DELETE",55:"INSERT",56:"FILL.RIGHT",57:"FILL.DOWN",61:"DEFINE.NAME",62:"CREATE.NAMES",63:"FORMULA.GOTO",64:"FORMULA.FIND",65:"SELECT.LAST.CELL",66:"SHOW.ACTIVE.CELL",67:"GALLERY.AREA",68:"GALLERY.BAR",69:"GALLERY.COLUMN",70:"GALLERY.LINE",71:"GALLERY.PIE",72:"GALLERY.SCATTER",73:"COMBINATION",74:"PREFERRED",75:"ADD.OVERLAY",76:"GRIDLINES",77:"SET.PREFERRED",78:"AXES",79:"LEGEND",80:"ATTACH.TEXT",81:"ADD.ARROW",82:"SELECT.CHART",83:"SELECT.PLOT.AREA",84:"PATTERNS",85:"MAIN.CHART",86:"OVERLAY",87:"SCALE",88:"FORMAT.LEGEND",89:"FORMAT.TEXT",90:"EDIT.REPEAT",91:"PARSE",92:"JUSTIFY",93:"HIDE",94:"UNHIDE",95:"WORKSPACE",96:"FORMULA",97:"FORMULA.FILL",98:"FORMULA.ARRAY",99:"DATA.FIND.NEXT",100:"DATA.FIND.PREV",101:"FORMULA.FIND.NEXT",102:"FORMULA.FIND.PREV",103:"ACTIVATE",104:"ACTIVATE.NEXT",105:"ACTIVATE.PREV",106:"UNLOCKED.NEXT",107:"UNLOCKED.PREV",108:"COPY.PICTURE",109:"SELECT",110:"DELETE.NAME",111:"DELETE.FORMAT",112:"VLINE",113:"HLINE",114:"VPAGE",115:"HPAGE",116:"VSCROLL",117:"HSCROLL",118:"ALERT",119:"NEW",120:"CANCEL.COPY",121:"SHOW.CLIPBOARD",122:"MESSAGE",124:"PASTE.LINK",125:"APP.ACTIVATE",126:"DELETE.ARROW",127:"ROW.HEIGHT",128:"FORMAT.MOVE",129:"FORMAT.SIZE",130:"FORMULA.REPLACE",131:"SEND.KEYS",132:"SELECT.SPECIAL",133:"APPLY.NAMES",134:"REPLACE.FONT",135:"FREEZE.PANES",136:"SHOW.INFO",137:"SPLIT",138:"ON.WINDOW",139:"ON.DATA",140:"DISABLE.INPUT",142:"OUTLINE",143:"LIST.NAMES",144:"FILE.CLOSE",145:"SAVE.WORKBOOK",146:"DATA.FORM",147:"COPY.CHART",148:"ON.TIME",149:"WAIT",150:"FORMAT.FONT",151:"FILL.UP",152:"FILL.LEFT",153:"DELETE.OVERLAY",155:"SHORT.MENUS",159:"SET.UPDATE.STATUS",161:"COLOR.PALETTE",162:"DELETE.STYLE",163:"WINDOW.RESTORE",164:"WINDOW.MAXIMIZE",166:"CHANGE.LINK",167:"CALCULATE.DOCUMENT",168:"ON.KEY",169:"APP.RESTORE",170:"APP.MOVE",171:"APP.SIZE",172:"APP.MINIMIZE",173:"APP.MAXIMIZE",174:"BRING.TO.FRONT",175:"SEND.TO.BACK",185:"MAIN.CHART.TYPE",186:"OVERLAY.CHART.TYPE",187:"SELECT.END",188:"OPEN.MAIL",189:"SEND.MAIL",190:"STANDARD.FONT",191:"CONSOLIDATE",192:"SORT.SPECIAL",193:"GALLERY.3D.AREA",194:"GALLERY.3D.COLUMN",195:"GALLERY.3D.LINE",196:"GALLERY.3D.PIE",197:"VIEW.3D",198:"GOAL.SEEK",199:"WORKGROUP",200:"FILL.GROUP",201:"UPDATE.LINK",202:"PROMOTE",203:"DEMOTE",204:"SHOW.DETAIL",206:"UNGROUP",207:"OBJECT.PROPERTIES",208:"SAVE.NEW.OBJECT",209:"SHARE",210:"SHARE.NAME",211:"DUPLICATE",212:"APPLY.STYLE",213:"ASSIGN.TO.OBJECT",214:"OBJECT.PROTECTION",215:"HIDE.OBJECT",216:"SET.EXTRACT",217:"CREATE.PUBLISHER",218:"SUBSCRIBE.TO",219:"ATTRIBUTES",220:"SHOW.TOOLBAR",222:"PRINT.PREVIEW",223:"EDIT.COLOR",224:"SHOW.LEVELS",225:"FORMAT.MAIN",226:"FORMAT.OVERLAY",227:"ON.RECALC",228:"EDIT.SERIES",229:"DEFINE.STYLE",240:"LINE.PRINT",243:"ENTER.DATA",249:"GALLERY.RADAR",250:"MERGE.STYLES",251:"EDITION.OPTIONS",252:"PASTE.PICTURE",253:"PASTE.PICTURE.LINK",254:"SPELLING",256:"ZOOM",259:"INSERT.OBJECT",260:"WINDOW.MINIMIZE",265:"SOUND.NOTE",266:"SOUND.PLAY",267:"FORMAT.SHAPE",268:"EXTEND.POLYGON",269:"FORMAT.AUTO",272:"GALLERY.3D.BAR",273:"GALLERY.3D.SURFACE",274:"FILL.AUTO",276:"CUSTOMIZE.TOOLBAR",277:"ADD.TOOL",278:"EDIT.OBJECT",279:"ON.DOUBLECLICK",280:"ON.ENTRY",281:"WORKBOOK.ADD",282:"WORKBOOK.MOVE",283:"WORKBOOK.COPY",284:"WORKBOOK.OPTIONS",285:"SAVE.WORKSPACE",288:"CHART.WIZARD",289:"DELETE.TOOL",290:"MOVE.TOOL",291:"WORKBOOK.SELECT",292:"WORKBOOK.ACTIVATE",293:"ASSIGN.TO.TOOL",295:"COPY.TOOL",296:"RESET.TOOL",297:"CONSTRAIN.NUMERIC",298:"PASTE.TOOL",302:"WORKBOOK.NEW",305:"SCENARIO.CELLS",306:"SCENARIO.DELETE",307:"SCENARIO.ADD",308:"SCENARIO.EDIT",309:"SCENARIO.SHOW",310:"SCENARIO.SHOW.NEXT",311:"SCENARIO.SUMMARY",312:"PIVOT.TABLE.WIZARD",313:"PIVOT.FIELD.PROPERTIES",314:"PIVOT.FIELD",315:"PIVOT.ITEM",316:"PIVOT.ADD.FIELDS",318:"OPTIONS.CALCULATION",319:"OPTIONS.EDIT",320:"OPTIONS.VIEW",321:"ADDIN.MANAGER",322:"MENU.EDITOR",323:"ATTACH.TOOLBARS",324:"VBAActivate",325:"OPTIONS.CHART",328:"VBA.INSERT.FILE",330:"VBA.PROCEDURE.DEFINITION",336:"ROUTING.SLIP",338:"ROUTE.DOCUMENT",339:"MAIL.LOGON",342:"INSERT.PICTURE",343:"EDIT.TOOL",344:"GALLERY.DOUGHNUT",350:"CHART.TREND",352:"PIVOT.ITEM.PROPERTIES",354:"WORKBOOK.INSERT",355:"OPTIONS.TRANSITION",356:"OPTIONS.GENERAL",370:"FILTER.ADVANCED",373:"MAIL.ADD.MAILER",374:"MAIL.DELETE.MAILER",375:"MAIL.REPLY",376:"MAIL.REPLY.ALL",377:"MAIL.FORWARD",378:"MAIL.NEXT.LETTER",379:"DATA.LABEL",380:"INSERT.TITLE",381:"FONT.PROPERTIES",382:"MACRO.OPTIONS",383:"WORKBOOK.HIDE",384:"WORKBOOK.UNHIDE",385:"WORKBOOK.DELETE",386:"WORKBOOK.NAME",388:"GALLERY.CUSTOM",390:"ADD.CHART.AUTOFORMAT",391:"DELETE.CHART.AUTOFORMAT",392:"CHART.ADD.DATA",393:"AUTO.OUTLINE",394:"TAB.ORDER",395:"SHOW.DIALOG",396:"SELECT.ALL",397:"UNGROUP.SHEETS",398:"SUBTOTAL.CREATE",399:"SUBTOTAL.REMOVE",400:"RENAME.OBJECT",412:"WORKBOOK.SCROLL",413:"WORKBOOK.NEXT",414:"WORKBOOK.PREV",415:"WORKBOOK.TAB.SPLIT",416:"FULL.SCREEN",417:"WORKBOOK.PROTECT",420:"SCROLLBAR.PROPERTIES",421:"PIVOT.SHOW.PAGES",422:"TEXT.TO.COLUMNS",423:"FORMAT.CHARTTYPE",424:"LINK.FORMAT",425:"TRACER.DISPLAY",430:"TRACER.NAVIGATE",431:"TRACER.CLEAR",432:"TRACER.ERROR",433:"PIVOT.FIELD.GROUP",434:"PIVOT.FIELD.UNGROUP",435:"CHECKBOX.PROPERTIES",436:"LABEL.PROPERTIES",437:"LISTBOX.PROPERTIES",438:"EDITBOX.PROPERTIES",439:"PIVOT.REFRESH",440:"LINK.COMBO",441:"OPEN.TEXT",442:"HIDE.DIALOG",443:"SET.DIALOG.FOCUS",444:"ENABLE.OBJECT",445:"PUSHBUTTON.PROPERTIES",446:"SET.DIALOG.DEFAULT",447:"FILTER",448:"FILTER.SHOW.ALL",449:"CLEAR.OUTLINE",450:"FUNCTION.WIZARD",451:"ADD.LIST.ITEM",452:"SET.LIST.ITEM",453:"REMOVE.LIST.ITEM",454:"SELECT.LIST.ITEM",455:"SET.CONTROL.VALUE",456:"SAVE.COPY.AS",458:"OPTIONS.LISTS.ADD",459:"OPTIONS.LISTS.DELETE",460:"SERIES.AXES",461:"SERIES.X",462:"SERIES.Y",463:"ERRORBAR.X",464:"ERRORBAR.Y",465:"FORMAT.CHART",466:"SERIES.ORDER",467:"MAIL.LOGOFF",468:"CLEAR.ROUTING.SLIP",469:"APP.ACTIVATE.MICROSOFT",470:"MAIL.EDIT.MAILER",471:"ON.SHEET",472:"STANDARD.WIDTH",473:"SCENARIO.MERGE",474:"SUMMARY.INFO",475:"FIND.FILE",476:"ACTIVE.CELL.FONT",477:"ENABLE.TIPWIZARD",478:"VBA.MAKE.ADDIN",480:"INSERTDATATABLE",481:"WORKGROUP.OPTIONS",482:"MAIL.SEND.MAILER",485:"AUTOCORRECT",489:"POST.DOCUMENT",491:"PICKLIST",493:"VIEW.SHOW",494:"VIEW.DEFINE",495:"VIEW.DELETE",509:"SHEET.BACKGROUND",510:"INSERT.MAP.OBJECT",511:"OPTIONS.MENONO",517:"MSOCHECKS",518:"NORMAL",519:"LAYOUT",520:"RM.PRINT.AREA",521:"CLEAR.PRINT.AREA",522:"ADD.PRINT.AREA",523:"MOVE.BRK",545:"HIDECURR.NOTE",546:"HIDEALL.NOTES",547:"DELETE.NOTE",548:"TRAVERSE.NOTES",549:"ACTIVATE.NOTES",620:"PROTECT.REVISIONS",621:"UNPROTECT.REVISIONS",647:"OPTIONS.ME",653:"WEB.PUBLISH",667:"NEWWEBQUERY",673:"PIVOT.TABLE.CHART",753:"OPTIONS.SAVE",755:"OPTIONS.SPELL",808:"HIDEALL.INKANNOTS"};
18581 25800 var Ftab={0:"COUNT",1:"IF",2:"ISNA",3:"ISERROR",4:"SUM",5:"AVERAGE",6:"MIN",7:"MAX",8:"ROW",9:"COLUMN",10:"NA",11:"NPV",12:"STDEV",13:"DOLLAR",14:"FIXED",15:"SIN",16:"COS",17:"TAN",18:"ATAN",19:"PI",20:"SQRT",21:"EXP",22:"LN",23:"LOG10",24:"ABS",25:"INT",26:"SIGN",27:"ROUND",28:"LOOKUP",29:"INDEX",30:"REPT",31:"MID",32:"LEN",33:"VALUE",34:"TRUE",35:"FALSE",36:"AND",37:"OR",38:"NOT",39:"MOD",40:"DCOUNT",41:"DSUM",42:"DAVERAGE",43:"DMIN",44:"DMAX",45:"DSTDEV",46:"VAR",47:"DVAR",48:"TEXT",49:"LINEST",50:"TREND",51:"LOGEST",52:"GROWTH",53:"GOTO",54:"HALT",55:"RETURN",56:"PV",57:"FV",58:"NPER",59:"PMT",60:"RATE",61:"MIRR",62:"IRR",63:"RAND",64:"MATCH",65:"DATE",66:"TIME",67:"DAY",68:"MONTH",69:"YEAR",70:"WEEKDAY",71:"HOUR",72:"MINUTE",73:"SECOND",74:"NOW",75:"AREAS",76:"ROWS",77:"COLUMNS",78:"OFFSET",79:"ABSREF",80:"RELREF",81:"ARGUMENT",82:"SEARCH",83:"TRANSPOSE",84:"ERROR",85:"STEP",86:"TYPE",87:"ECHO",88:"SET.NAME",89:"CALLER",90:"DEREF",91:"WINDOWS",92:"SERIES",93:"DOCUMENTS",94:"ACTIVE.CELL",95:"SELECTION",96:"RESULT",97:"ATAN2",98:"ASIN",99:"ACOS",100:"CHOOSE",101:"HLOOKUP",102:"VLOOKUP",103:"LINKS",104:"INPUT",105:"ISREF",106:"GET.FORMULA",107:"GET.NAME",108:"SET.VALUE",109:"LOG",110:"EXEC",111:"CHAR",112:"LOWER",113:"UPPER",114:"PROPER",115:"LEFT",116:"RIGHT",117:"EXACT",118:"TRIM",119:"REPLACE",120:"SUBSTITUTE",121:"CODE",122:"NAMES",123:"DIRECTORY",124:"FIND",125:"CELL",126:"ISERR",127:"ISTEXT",128:"ISNUMBER",129:"ISBLANK",130:"T",131:"N",132:"FOPEN",133:"FCLOSE",134:"FSIZE",135:"FREADLN",136:"FREAD",137:"FWRITELN",138:"FWRITE",139:"FPOS",140:"DATEVALUE",141:"TIMEVALUE",142:"SLN",143:"SYD",144:"DDB",145:"GET.DEF",146:"REFTEXT",147:"TEXTREF",148:"INDIRECT",149:"REGISTER",150:"CALL",151:"ADD.BAR",152:"ADD.MENU",153:"ADD.COMMAND",154:"ENABLE.COMMAND",155:"CHECK.COMMAND",156:"RENAME.COMMAND",157:"SHOW.BAR",158:"DELETE.MENU",159:"DELETE.COMMAND",160:"GET.CHART.ITEM",161:"DIALOG.BOX",162:"CLEAN",163:"MDETERM",164:"MINVERSE",165:"MMULT",166:"FILES",167:"IPMT",168:"PPMT",169:"COUNTA",170:"CANCEL.KEY",171:"FOR",172:"WHILE",173:"BREAK",174:"NEXT",175:"INITIATE",176:"REQUEST",177:"POKE",178:"EXECUTE",179:"TERMINATE",180:"RESTART",181:"HELP",182:"GET.BAR",183:"PRODUCT",184:"FACT",185:"GET.CELL",186:"GET.WORKSPACE",187:"GET.WINDOW",188:"GET.DOCUMENT",189:"DPRODUCT",190:"ISNONTEXT",191:"GET.NOTE",192:"NOTE",193:"STDEVP",194:"VARP",195:"DSTDEVP",196:"DVARP",197:"TRUNC",198:"ISLOGICAL",199:"DCOUNTA",200:"DELETE.BAR",201:"UNREGISTER",204:"USDOLLAR",205:"FINDB",206:"SEARCHB",207:"REPLACEB",208:"LEFTB",209:"RIGHTB",210:"MIDB",211:"LENB",212:"ROUNDUP",213:"ROUNDDOWN",214:"ASC",215:"DBCS",216:"RANK",219:"ADDRESS",220:"DAYS360",221:"TODAY",222:"VDB",223:"ELSE",224:"ELSE.IF",225:"END.IF",226:"FOR.CELL",227:"MEDIAN",228:"SUMPRODUCT",229:"SINH",230:"COSH",231:"TANH",232:"ASINH",233:"ACOSH",234:"ATANH",235:"DGET",236:"CREATE.OBJECT",237:"VOLATILE",238:"LAST.ERROR",239:"CUSTOM.UNDO",240:"CUSTOM.REPEAT",241:"FORMULA.CONVERT",242:"GET.LINK.INFO",243:"TEXT.BOX",244:"INFO",245:"GROUP",246:"GET.OBJECT",247:"DB",248:"PAUSE",251:"RESUME",252:"FREQUENCY",253:"ADD.TOOLBAR",254:"DELETE.TOOLBAR",255:"User",256:"RESET.TOOLBAR",257:"EVALUATE",258:"GET.TOOLBAR",259:"GET.TOOL",260:"SPELLING.CHECK",261:"ERROR.TYPE",262:"APP.TITLE",263:"WINDOW.TITLE",264:"SAVE.TOOLBAR",265:"ENABLE.TOOL",266:"PRESS.TOOL",267:"REGISTER.ID",268:"GET.WORKBOOK",269:"AVEDEV",270:"BETADIST",271:"GAMMALN",272:"BETAINV",273:"BINOMDIST",274:"CHIDIST",275:"CHIINV",276:"COMBIN",277:"CONFIDENCE",278:"CRITBINOM",279:"EVEN",280:"EXPONDIST",281:"FDIST",282:"FINV",283:"FISHER",284:"FISHERINV",285:"FLOOR",286:"GAMMADIST",287:"GAMMAINV",288:"CEILING",289:"HYPGEOMDIST",290:"LOGNORMDIST",291:"LOGINV",292:"NEGBINOMDIST",293:"NORMDIST",294:"NORMSDIST",295:"NORMINV",296:"NORMSINV",297:"STANDARDIZE",298:"ODD",299:"PERMUT",300:"POISSON",301:"TDIST",302:"WEIBULL",303:"SUMXMY2",304:"SUMX2MY2",305:"SUMX2PY2",306:"CHITEST",307:"CORREL",308:"COVAR",309:"FORECAST",310:"FTEST",311:"INTERCEPT",312:"PEARSON",313:"RSQ",314:"STEYX",315:"SLOPE",316:"TTEST",317:"PROB",318:"DEVSQ",319:"GEOMEAN",320:"HARMEAN",321:"SUMSQ",322:"KURT",323:"SKEW",324:"ZTEST",325:"LARGE",326:"SMALL",327:"QUARTILE",328:"PERCENTILE",329:"PERCENTRANK",330:"MODE",331:"TRIMMEAN",332:"TINV",334:"MOVIE.COMMAND",335:"GET.MOVIE",336:"CONCATENATE",337:"POWER",338:"PIVOT.ADD.DATA",339:"GET.PIVOT.TABLE",340:"GET.PIVOT.FIELD",341:"GET.PIVOT.ITEM",342:"RADIANS",343:"DEGREES",344:"SUBTOTAL",345:"SUMIF",346:"COUNTIF",347:"COUNTBLANK",348:"SCENARIO.GET",349:"OPTIONS.LISTS.GET",350:"ISPMT",351:"DATEDIF",352:"DATESTRING",353:"NUMBERSTRING",354:"ROMAN",355:"OPEN.DIALOG",356:"SAVE.DIALOG",357:"VIEW.GET",358:"GETPIVOTDATA",359:"HYPERLINK",360:"PHONETIC",361:"AVERAGEA",362:"MAXA",363:"MINA",364:"STDEVPA",365:"VARPA",366:"STDEVA",367:"VARA",368:"BAHTTEXT",369:"THAIDAYOFWEEK",370:"THAIDIGIT",371:"THAIMONTHOFYEAR",372:"THAINUMSOUND",373:"THAINUMSTRING",374:"THAISTRINGLENGTH",375:"ISTHAIDIGIT",376:"ROUNDBAHTDOWN",377:"ROUNDBAHTUP",378:"THAIYEAR",379:"RTD"};var FtabArgc={2:1,3:1,15:1,16:1,17:1,18:1,20:1,21:1,22:1,23:1,24:1,25:1,26:1,27:2,30:2,31:3,32:1,33:1,38:1,39:2,40:3,41:3,42:3,43:3,44:3,45:3,47:3,48:2,53:1,61:3,65:3,66:3,67:1,68:1,69:1,71:1,72:1,73:1,75:1,76:1,77:1,79:2,80:2,83:1,86:1,90:1,97:2,98:1,99:1,105:1,111:1,112:1,113:1,114:1,117:2,118:1,119:4,121:1,126:1,127:1,128:1,129:1,130:1,131:1,133:1,134:1,135:1,136:2,137:2,138:2,140:1,141:1,142:3,143:4,162:1,163:1,164:1,165:2,172:1,175:2,176:2,177:3,178:2,179:1,184:1,189:3,190:1,195:3,196:3,198:1,199:3,201:1,207:4,210:3,211:1,212:2,213:2,214:1,215:1,229:1,230:1,231:1,232:1,233:1,234:1,235:3,244:1,252:2,257:1,261:1,271:1,273:4,274:2,275:2,276:2,277:3,278:3,279:1,280:3,281:3,282:3,283:1,284:1,285:2,286:4,287:3,288:2,289:4,290:3,291:3,292:3,293:4,294:1,295:3,296:1,297:3,298:1,299:2,300:3,301:3,302:4,303:2,304:2,305:2,306:2,307:2,308:2,309:3,310:2,311:2,312:2,313:2,314:2,315:2,316:4,325:2,326:2,327:2,328:2,331:2,332:2,337:2,342:1,343:1,346:2,347:1,350:4,351:3,352:1,353:2,360:1,368:1,369:1,370:1,371:1,372:1,373:1,374:1,375:1,376:1,377:1,378:1,65535:0};var XLSXFutureFunctions={"_xlfn.ACOT":"ACOT","_xlfn.ACOTH":"ACOTH","_xlfn.AGGREGATE":"AGGREGATE","_xlfn.ARABIC":"ARABIC","_xlfn.AVERAGEIF":"AVERAGEIF","_xlfn.AVERAGEIFS":"AVERAGEIFS","_xlfn.BASE":"BASE","_xlfn.BETA.DIST":"BETA.DIST","_xlfn.BETA.INV":"BETA.INV","_xlfn.BINOM.DIST":"BINOM.DIST","_xlfn.BINOM.DIST.RANGE":"BINOM.DIST.RANGE","_xlfn.BINOM.INV":"BINOM.INV","_xlfn.BITAND":"BITAND","_xlfn.BITLSHIFT":"BITLSHIFT","_xlfn.BITOR":"BITOR","_xlfn.BITRSHIFT":"BITRSHIFT","_xlfn.BITXOR":"BITXOR","_xlfn.CEILING.MATH":"CEILING.MATH","_xlfn.CEILING.PRECISE":"CEILING.PRECISE","_xlfn.CHISQ.DIST":"CHISQ.DIST","_xlfn.CHISQ.DIST.RT":"CHISQ.DIST.RT","_xlfn.CHISQ.INV":"CHISQ.INV","_xlfn.CHISQ.INV.RT":"CHISQ.INV.RT","_xlfn.CHISQ.TEST":"CHISQ.TEST","_xlfn.COMBINA":"COMBINA","_xlfn.CONFIDENCE.NORM":"CONFIDENCE.NORM","_xlfn.CONFIDENCE.T":"CONFIDENCE.T","_xlfn.COT":"COT","_xlfn.COTH":"COTH","_xlfn.COUNTIFS":"COUNTIFS","_xlfn.COVARIANCE.P":"COVARIANCE.P","_xlfn.COVARIANCE.S":"COVARIANCE.S","_xlfn.CSC":"CSC","_xlfn.CSCH":"CSCH","_xlfn.DAYS":"DAYS","_xlfn.DECIMAL":"DECIMAL","_xlfn.ECMA.CEILING":"ECMA.CEILING","_xlfn.ERF.PRECISE":"ERF.PRECISE","_xlfn.ERFC.PRECISE":"ERFC.PRECISE","_xlfn.EXPON.DIST":"EXPON.DIST","_xlfn.F.DIST":"F.DIST","_xlfn.F.DIST.RT":"F.DIST.RT","_xlfn.F.INV":"F.INV","_xlfn.F.INV.RT":"F.INV.RT","_xlfn.F.TEST":"F.TEST","_xlfn.FILTERXML":"FILTERXML","_xlfn.FLOOR.MATH":"FLOOR.MATH","_xlfn.FLOOR.PRECISE":"FLOOR.PRECISE","_xlfn.FORMULATEXT":"FORMULATEXT","_xlfn.GAMMA":"GAMMA","_xlfn.GAMMA.DIST":"GAMMA.DIST","_xlfn.GAMMA.INV":"GAMMA.INV","_xlfn.GAMMALN.PRECISE":"GAMMALN.PRECISE","_xlfn.GAUSS":"GAUSS","_xlfn.HYPGEOM.DIST":"HYPGEOM.DIST","_xlfn.IFNA":"IFNA","_xlfn.IFERROR":"IFERROR","_xlfn.IMCOSH":"IMCOSH","_xlfn.IMCOT":"IMCOT","_xlfn.IMCSC":"IMCSC","_xlfn.IMCSCH":"IMCSCH","_xlfn.IMSEC":"IMSEC","_xlfn.IMSECH":"IMSECH","_xlfn.IMSINH":"IMSINH","_xlfn.IMTAN":"IMTAN","_xlfn.ISFORMULA":"ISFORMULA","_xlfn.ISO.CEILING":"ISO.CEILING","_xlfn.ISOWEEKNUM":"ISOWEEKNUM","_xlfn.LOGNORM.DIST":"LOGNORM.DIST","_xlfn.LOGNORM.INV":"LOGNORM.INV","_xlfn.MODE.MULT":"MODE.MULT","_xlfn.MODE.SNGL":"MODE.SNGL","_xlfn.MUNIT":"MUNIT","_xlfn.NEGBINOM.DIST":"NEGBINOM.DIST","_xlfn.NETWORKDAYS.INTL":"NETWORKDAYS.INTL","_xlfn.NIGBINOM":"NIGBINOM","_xlfn.NORM.DIST":"NORM.DIST","_xlfn.NORM.INV":"NORM.INV","_xlfn.NORM.S.DIST":"NORM.S.DIST","_xlfn.NORM.S.INV":"NORM.S.INV","_xlfn.NUMBERVALUE":"NUMBERVALUE","_xlfn.PDURATION":"PDURATION","_xlfn.PERCENTILE.EXC":"PERCENTILE.EXC","_xlfn.PERCENTILE.INC":"PERCENTILE.INC","_xlfn.PERCENTRANK.EXC":"PERCENTRANK.EXC","_xlfn.PERCENTRANK.INC":"PERCENTRANK.INC","_xlfn.PERMUTATIONA":"PERMUTATIONA","_xlfn.PHI":"PHI","_xlfn.POISSON.DIST":"POISSON.DIST","_xlfn.QUARTILE.EXC":"QUARTILE.EXC","_xlfn.QUARTILE.INC":"QUARTILE.INC","_xlfn.QUERYSTRING":"QUERYSTRING","_xlfn.RANK.AVG":"RANK.AVG","_xlfn.RANK.EQ":"RANK.EQ","_xlfn.RRI":"RRI","_xlfn.SEC":"SEC","_xlfn.SECH":"SECH","_xlfn.SHEET":"SHEET","_xlfn.SHEETS":"SHEETS","_xlfn.SKEW.P":"SKEW.P","_xlfn.STDEV.P":"STDEV.P","_xlfn.STDEV.S":"STDEV.S","_xlfn.SUMIFS":"SUMIFS","_xlfn.T.DIST":"T.DIST","_xlfn.T.DIST.2T":"T.DIST.2T","_xlfn.T.DIST.RT":"T.DIST.RT","_xlfn.T.INV":"T.INV","_xlfn.T.INV.2T":"T.INV.2T","_xlfn.T.TEST":"T.TEST","_xlfn.UNICHAR":"UNICHAR","_xlfn.UNICODE":"UNICODE","_xlfn.VAR.P":"VAR.P","_xlfn.VAR.S":"VAR.S","_xlfn.WEBSERVICE":"WEBSERVICE","_xlfn.WEIBULL.DIST":"WEIBULL.DIST","_xlfn.WORKDAY.INTL":"WORKDAY.INTL","_xlfn.XOR":"XOR","_xlfn.Z.TEST":"Z.TEST"};var RecordEnum={6:{n:"Formula",f:parse_Formula},10:{n:"EOF",f:parse_EOF},12:{n:"CalcCount",f:parse_CalcCount},13:{n:"CalcMode",f:parse_CalcMode},14:{n:"CalcPrecision",f:parse_CalcPrecision},15:{n:"CalcRefMode",f:parse_CalcRefMode},16:{n:"CalcDelta",f:parse_CalcDelta},17:{n:"CalcIter",f:parse_CalcIter},18:{n:"Protect",f:parse_Protect},19:{n:"Password",f:parse_Password},20:{n:"Header",f:parse_Header},21:{n:"Footer",f:parse_Footer},23:{n:"ExternSheet",f:parse_ExternSheet},24:{n:"Lbl",f:parse_Lbl},25:{n:"WinProtect",f:parse_WinProtect},26:{n:"VerticalPageBreaks",f:parse_VerticalPageBreaks},27:{n:"HorizontalPageBreaks",f:parse_HorizontalPageBreaks},28:{n:"Note",f:parse_Note},29:{n:"Selection",f:parse_Selection},34:{n:"Date1904",f:parse_Date1904},35:{n:"ExternName",f:parse_ExternName},38:{n:"LeftMargin",f:parse_LeftMargin},39:{n:"RightMargin",f:parse_RightMargin},40:{n:"TopMargin",f:parse_TopMargin},41:{n:"BottomMargin",f:parse_BottomMargin},42:{n:"PrintRowCol",f:parse_PrintRowCol},43:{n:"PrintGrid",f:parse_PrintGrid},47:{n:"FilePass",f:parse_FilePass},49:{n:"Font",f:parse_Font},51:{n:"PrintSize",f:parse_PrintSize},60:{n:"Continue",f:parse_Continue},61:{n:"Window1",f:parse_Window1},64:{n:"Backup",f:parse_Backup},65:{n:"Pane",f:parse_Pane},66:{n:"CodePage",f:parse_CodePage},77:{n:"Pls",f:parse_Pls},80:{n:"DCon",f:parse_DCon},81:{n:"DConRef",f:parse_DConRef},82:{n:"DConName",f:parse_DConName},85:{n:"DefColWidth",f:parse_DefColWidth},89:{n:"XCT",f:parse_XCT},90:{n:"CRN",f:parse_CRN},91:{n:"FileSharing",f:parse_FileSharing},92:{n:"WriteAccess",f:parse_WriteAccess},93:{n:"Obj",f:parse_Obj},94:{n:"Uncalced",f:parse_Uncalced},95:{n:"CalcSaveRecalc",f:parse_CalcSaveRecalc},96:{n:"Template",f:parse_Template},97:{n:"Intl",f:parse_Intl},99:{n:"ObjProtect",f:parse_ObjProtect},125:{n:"ColInfo",f:parse_ColInfo},128:{n:"Guts",f:parse_Guts},129:{n:"WsBool",f:parse_WsBool},130:{n:"GridSet",f:parse_GridSet},131:{n:"HCenter",f:parse_HCenter},132:{n:"VCenter",f:parse_VCenter},133:{n:"BoundSheet8",f:parse_BoundSheet8},134:{n:"WriteProtect",f:parse_WriteProtect},140:{n:"Country",f:parse_Country},141:{n:"HideObj",f:parse_HideObj},144:{n:"Sort",f:parse_Sort},146:{n:"Palette",f:parse_Palette},151:{n:"Sync",f:parse_Sync},152:{n:"LPr",f:parse_LPr},153:{n:"DxGCol",f:parse_DxGCol},154:{n:"FnGroupName",f:parse_FnGroupName},155:{n:"FilterMode",f:parse_FilterMode},156:{n:"BuiltInFnGroupCount",f:parse_BuiltInFnGroupCount},157:{n:"AutoFilterInfo",f:parse_AutoFilterInfo},158:{n:"AutoFilter",f:parse_AutoFilter},160:{n:"Scl",f:parse_Scl},161:{n:"Setup",f:parse_Setup},174:{n:"ScenMan",f:parse_ScenMan},175:{n:"SCENARIO",f:parse_SCENARIO},176:{n:"SxView",f:parse_SxView},177:{n:"Sxvd",f:parse_Sxvd},178:{n:"SXVI",f:parse_SXVI},180:{n:"SxIvd",f:parse_SxIvd},181:{n:"SXLI",f:parse_SXLI},182:{n:"SXPI",f:parse_SXPI},184:{n:"DocRoute",f:parse_DocRoute},185:{n:"RecipName",f:parse_RecipName},189:{n:"MulRk",f:parse_MulRk},190:{n:"MulBlank",f:parse_MulBlank},193:{n:"Mms",f:parse_Mms},197:{n:"SXDI",f:parse_SXDI},198:{n:"SXDB",f:parse_SXDB},199:{n:"SXFDB",f:parse_SXFDB},200:{n:"SXDBB",f:parse_SXDBB},201:{n:"SXNum",f:parse_SXNum},202:{n:"SxBool",f:parse_SxBool},203:{n:"SxErr",f:parse_SxErr},204:{n:"SXInt",f:parse_SXInt},205:{n:"SXString",f:parse_SXString},206:{n:"SXDtr",f:parse_SXDtr},207:{n:"SxNil",f:parse_SxNil},208:{n:"SXTbl",f:parse_SXTbl},209:{n:"SXTBRGIITM",f:parse_SXTBRGIITM},210:{n:"SxTbpg",f:parse_SxTbpg},211:{n:"ObProj",f:parse_ObProj},213:{n:"SXStreamID",f:parse_SXStreamID},215:{n:"DBCell",f:parse_DBCell},216:{n:"SXRng",f:parse_SXRng},217:{n:"SxIsxoper",f:parse_SxIsxoper},218:{n:"BookBool",f:parse_BookBool},220:{n:"DbOrParamQry",f:parse_DbOrParamQry},221:{n:"ScenarioProtect",f:parse_ScenarioProtect},222:{n:"OleObjectSize",f:parse_OleObjectSize},224:{n:"XF",f:parse_XF},225:{n:"InterfaceHdr",f:parse_InterfaceHdr},226:{n:"InterfaceEnd",f:parse_InterfaceEnd},227:{n:"SXVS",f:parse_SXVS},229:{n:"MergeCells",f:parse_MergeCells},233:{n:"BkHim",f:parse_BkHim},235:{n:"MsoDrawingGroup",f:parse_MsoDrawingGroup},236:{n:"MsoDrawing",f:parse_MsoDrawing},237:{n:"MsoDrawingSelection",f:parse_MsoDrawingSelection},239:{n:"PhoneticInfo",f:parse_PhoneticInfo},240:{n:"SxRule",f:parse_SxRule},241:{n:"SXEx",f:parse_SXEx},242:{n:"SxFilt",f:parse_SxFilt},244:{n:"SxDXF",f:parse_SxDXF},245:{n:"SxItm",f:parse_SxItm},246:{n:"SxName",f:parse_SxName},247:{n:"SxSelect",f:parse_SxSelect},248:{n:"SXPair",f:parse_SXPair},249:{n:"SxFmla",f:parse_SxFmla},251:{n:"SxFormat",f:parse_SxFormat},252:{n:"SST",f:parse_SST},253:{n:"LabelSst",f:parse_LabelSst},255:{n:"ExtSST",f:parse_ExtSST},256:{n:"SXVDEx",f:parse_SXVDEx},259:{n:"SXFormula",f:parse_SXFormula},290:{n:"SXDBEx",f:parse_SXDBEx},311:{n:"RRDInsDel",f:parse_RRDInsDel},312:{n:"RRDHead",f:parse_RRDHead},315:{n:"RRDChgCell",f:parse_RRDChgCell},317:{n:"RRTabId",f:parse_RRTabId},318:{n:"RRDRenSheet",f:parse_RRDRenSheet},319:{n:"RRSort",f:parse_RRSort},320:{n:"RRDMove",f:parse_RRDMove},330:{n:"RRFormat",f:parse_RRFormat},331:{n:"RRAutoFmt",f:parse_RRAutoFmt},333:{n:"RRInsertSh",f:parse_RRInsertSh},334:{n:"RRDMoveBegin",f:parse_RRDMoveBegin},335:{n:"RRDMoveEnd",f:parse_RRDMoveEnd},336:{n:"RRDInsDelBegin",f:parse_RRDInsDelBegin},337:{n:"RRDInsDelEnd",f:parse_RRDInsDelEnd},338:{n:"RRDConflict",f:parse_RRDConflict},339:{n:"RRDDefName",f:parse_RRDDefName},340:{n:"RRDRstEtxp",f:parse_RRDRstEtxp},351:{n:"LRng",f:parse_LRng},352:{n:"UsesELFs",f:parse_UsesELFs},353:{n:"DSF",f:parse_DSF},401:{n:"CUsr",f:parse_CUsr},402:{n:"CbUsr",f:parse_CbUsr},403:{n:"UsrInfo",f:parse_UsrInfo},404:{n:"UsrExcl",f:parse_UsrExcl},405:{n:"FileLock",f:parse_FileLock},406:{n:"RRDInfo",f:parse_RRDInfo},407:{n:"BCUsrs",f:parse_BCUsrs},408:{n:"UsrChk",f:parse_UsrChk},425:{n:"UserBView",f:parse_UserBView},426:{n:"UserSViewBegin",f:parse_UserSViewBegin},427:{n:"UserSViewEnd",f:parse_UserSViewEnd},428:{n:"RRDUserView",f:parse_RRDUserView},429:{n:"Qsi",f:parse_Qsi},430:{n:"SupBook",f:parse_SupBook},431:{n:"Prot4Rev",f:parse_Prot4Rev},432:{n:"CondFmt",f:parse_CondFmt},433:{n:"CF",f:parse_CF},434:{n:"DVal",f:parse_DVal},437:{n:"DConBin",f:parse_DConBin},438:{n:"TxO",f:parse_TxO},439:{n:"RefreshAll",f:parse_RefreshAll},440:{n:"HLink",f:parse_HLink},441:{n:"Lel",f:parse_Lel},442:{n:"CodeName",f:parse_CodeName},443:{n:"SXFDBType",f:parse_SXFDBType},444:{n:"Prot4RevPass",f:parse_Prot4RevPass},445:{n:"ObNoMacros",f:parse_ObNoMacros},446:{n:"Dv",f:parse_Dv},448:{n:"Excel9File",f:parse_Excel9File},449:{n:"RecalcId",f:parse_RecalcId,r:2},450:{n:"EntExU2",f:parse_EntExU2},512:{n:"Dimensions",f:parse_Dimensions},513:{n:"Blank",f:parse_Blank},515:{n:"Number",f:parse_Number},516:{n:"Label",f:parse_Label},517:{n:"BoolErr",f:parse_BoolErr},519:{n:"String",f:parse_String},520:{n:"Row",f:parse_Row},523:{n:"Index",f:parse_Index},545:{n:"Array",f:parse_Array},549:{n:"DefaultRowHeight",f:parse_DefaultRowHeight},566:{n:"Table",f:parse_Table},574:{n:"Window2",f:parse_Window2},638:{n:"RK",f:parse_RK},659:{n:"Style",f:parse_Style},1048:{n:"BigName",f:parse_BigName},1054:{n:"Format",f:parse_Format},1084:{n:"ContinueBigName",f:parse_ContinueBigName},1212:{n:"ShrFmla",f:parse_ShrFmla},2048:{n:"HLinkTooltip",f:parse_HLinkTooltip},2049:{n:"WebPub",f:parse_WebPub},2050:{n:"QsiSXTag",f:parse_QsiSXTag},2051:{n:"DBQueryExt",f:parse_DBQueryExt},2052:{n:"ExtString",f:parse_ExtString},2053:{n:"TxtQry",f:parse_TxtQry},2054:{n:"Qsir",f:parse_Qsir},2055:{n:"Qsif",f:parse_Qsif},2056:{n:"RRDTQSIF",f:parse_RRDTQSIF},2057:{n:"BOF",f:parse_BOF},2058:{n:"OleDbConn",f:parse_OleDbConn},2059:{n:"WOpt",f:parse_WOpt},2060:{n:"SXViewEx",f:parse_SXViewEx},2061:{n:"SXTH",f:parse_SXTH},2062:{n:"SXPIEx",f:parse_SXPIEx},2063:{n:"SXVDTEx",f:parse_SXVDTEx},2064:{n:"SXViewEx9",f:parse_SXViewEx9},2066:{n:"ContinueFrt",f:parse_ContinueFrt},2067:{n:"RealTimeData",f:parse_RealTimeData},2128:{n:"ChartFrtInfo",f:parse_ChartFrtInfo},2129:{n:"FrtWrapper",f:parse_FrtWrapper},2130:{n:"StartBlock",f:parse_StartBlock},2131:{n:"EndBlock",f:parse_EndBlock},2132:{n:"StartObject",f:parse_StartObject},2133:{n:"EndObject",f:parse_EndObject},2134:{n:"CatLab",f:parse_CatLab},2135:{n:"YMult",f:parse_YMult},2136:{n:"SXViewLink",f:parse_SXViewLink},2137:{n:"PivotChartBits",f:parse_PivotChartBits},2138:{n:"FrtFontList",f:parse_FrtFontList},2146:{n:"SheetExt",f:parse_SheetExt},2147:{n:"BookExt",f:parse_BookExt,r:12},2148:{n:"SXAddl",f:parse_SXAddl},2149:{n:"CrErr",f:parse_CrErr},2150:{n:"HFPicture",f:parse_HFPicture},2151:{n:"FeatHdr",f:parse_FeatHdr},2152:{n:"Feat",f:parse_Feat},2154:{n:"DataLabExt",f:parse_DataLabExt},2155:{n:"DataLabExtContents",f:parse_DataLabExtContents},2156:{n:"CellWatch",f:parse_CellWatch},2161:{n:"FeatHdr11",f:parse_FeatHdr11},2162:{n:"Feature11",f:parse_Feature11},2164:{n:"DropDownObjIds",f:parse_DropDownObjIds},2165:{n:"ContinueFrt11",f:parse_ContinueFrt11},2166:{n:"DConn",f:parse_DConn},2167:{n:"List12",f:parse_List12},2168:{n:"Feature12",f:parse_Feature12},2169:{n:"CondFmt12",f:parse_CondFmt12},2170:{n:"CF12",f:parse_CF12},2171:{n:"CFEx",f:parse_CFEx},2172:{n:"XFCRC",f:parse_XFCRC},2173:{n:"XFExt",f:parse_XFExt},2174:{n:"AutoFilter12",f:parse_AutoFilter12},2175:{n:"ContinueFrt12",f:parse_ContinueFrt12},2180:{n:"MDTInfo",f:parse_MDTInfo},2181:{n:"MDXStr",f:parse_MDXStr},2182:{n:"MDXTuple",f:parse_MDXTuple},2183:{n:"MDXSet",f:parse_MDXSet},2184:{n:"MDXProp",f:parse_MDXProp},2185:{n:"MDXKPI",f:parse_MDXKPI},2186:{n:"MDB",f:parse_MDB},2187:{n:"PLV",f:parse_PLV},2188:{n:"Compat12",f:parse_Compat12,r:12},2189:{n:"DXF",f:parse_DXF},2190:{n:"TableStyles",f:parse_TableStyles,r:12},2191:{n:"TableStyle",f:parse_TableStyle},2192:{n:"TableStyleElement",f:parse_TableStyleElement},2194:{n:"StyleExt",f:parse_StyleExt},2195:{n:"NamePublish",f:parse_NamePublish},2196:{n:"NameCmt",f:parse_NameCmt},2197:{n:"SortData",f:parse_SortData},2198:{n:"Theme",f:parse_Theme},2199:{n:"GUIDTypeLib",f:parse_GUIDTypeLib},2200:{n:"FnGrp12",f:parse_FnGrp12},2201:{n:"NameFnGrp12",f:parse_NameFnGrp12},2202:{n:"MTRSettings",f:parse_MTRSettings,r:12},2203:{n:"CompressPictures",f:parse_CompressPictures},2204:{n:"HeaderFooter",f:parse_HeaderFooter},2205:{n:"CrtLayout12",f:parse_CrtLayout12},2206:{n:"CrtMlFrt",f:parse_CrtMlFrt},2207:{n:"CrtMlFrtContinue",f:parse_CrtMlFrtContinue},2211:{n:"ForceFullCalculation",f:parse_ForceFullCalculation},2212:{n:"ShapePropsStream",f:parse_ShapePropsStream},2213:{n:"TextPropsStream",f:parse_TextPropsStream},2214:{n:"RichTextStream",f:parse_RichTextStream},2215:{n:"CrtLayout12A",f:parse_CrtLayout12A},4097:{n:"Units",f:parse_Units},4098:{n:"Chart",f:parse_Chart},4099:{n:"Series",f:parse_Series},4102:{n:"DataFormat",f:parse_DataFormat},4103:{n:"LineFormat",f:parse_LineFormat},4105:{n:"MarkerFormat",f:parse_MarkerFormat},4106:{n:"AreaFormat",f:parse_AreaFormat},4107:{n:"PieFormat",f:parse_PieFormat},4108:{n:"AttachedLabel",f:parse_AttachedLabel},4109:{n:"SeriesText",f:parse_SeriesText},4116:{n:"ChartFormat",f:parse_ChartFormat},4117:{n:"Legend",f:parse_Legend},4118:{n:"SeriesList",f:parse_SeriesList},4119:{n:"Bar",f:parse_Bar},4120:{n:"Line",f:parse_Line},4121:{n:"Pie",f:parse_Pie},4122:{n:"Area",f:parse_Area},4123:{n:"Scatter",f:parse_Scatter},4124:{n:"CrtLine",f:parse_CrtLine},4125:{n:"Axis",f:parse_Axis},4126:{n:"Tick",f:parse_Tick},4127:{n:"ValueRange",f:parse_ValueRange},4128:{n:"CatSerRange",f:parse_CatSerRange},4129:{n:"AxisLine",f:parse_AxisLine},4130:{n:"CrtLink",f:parse_CrtLink},4132:{n:"DefaultText",f:parse_DefaultText},4133:{n:"Text",f:parse_Text},4134:{n:"FontX",f:parse_FontX},4135:{n:"ObjectLink",f:parse_ObjectLink},4146:{n:"Frame",f:parse_Frame},4147:{n:"Begin",f:parse_Begin},4148:{n:"End",f:parse_End},4149:{n:"PlotArea",f:parse_PlotArea},4154:{n:"Chart3d",f:parse_Chart3d},4156:{n:"PicF",f:parse_PicF},4157:{n:"DropBar",f:parse_DropBar},4158:{n:"Radar",f:parse_Radar},4159:{n:"Surf",f:parse_Surf},4160:{n:"RadarArea",f:parse_RadarArea},4161:{n:"AxisParent",f:parse_AxisParent},4163:{n:"LegendException",f:parse_LegendException},4164:{n:"ShtProps",f:parse_ShtProps},4165:{n:"SerToCrt",f:parse_SerToCrt},4166:{n:"AxesUsed",f:parse_AxesUsed},4168:{n:"SBaseRef",f:parse_SBaseRef},4170:{n:"SerParent",f:parse_SerParent},4171:{n:"SerAuxTrend",f:parse_SerAuxTrend},4174:{n:"IFmtRecord",f:parse_IFmtRecord},4175:{n:"Pos",f:parse_Pos},4176:{n:"AlRuns",f:parse_AlRuns},4177:{n:"BRAI",f:parse_BRAI},4187:{n:"SerAuxErrBar",f:parse_SerAuxErrBar},4188:{n:"ClrtClient",f:parse_ClrtClient},4189:{n:"SerFmt",f:parse_SerFmt},4191:{n:"Chart3DBarShape",f:parse_Chart3DBarShape},4192:{n:"Fbi",f:parse_Fbi},4193:{n:"BopPop",f:parse_BopPop},4194:{n:"AxcExt",f:parse_AxcExt},4195:{n:"Dat",f:parse_Dat},4196:{n:"PlotGrowth",f:parse_PlotGrowth},4197:{n:"SIIndex",f:parse_SIIndex},4198:{n:"GelFrame",f:parse_GelFrame},4199:{n:"BopPopCustom",f:parse_BopPopCustom},4200:{n:"Fbi2",f:parse_Fbi2},22:{n:"ExternCount",f:parsenoop},126:{n:"RK",f:parsenoop},127:{n:"ImData",f:parsenoop},135:{n:"Addin",f:parsenoop},136:{n:"Edg",f:parsenoop},137:{n:"Pub",f:parsenoop},145:{n:"Sub",f:parsenoop},148:{n:"LHRecord",f:parsenoop},149:{n:"LHNGraph",f:parsenoop},150:{n:"Sound",f:parsenoop},169:{n:"CoordList",f:parsenoop},171:{n:"GCW",f:parsenoop},188:{n:"ShrFmla",f:parsenoop},194:{n:"AddMenu",f:parsenoop},195:{n:"DelMenu",f:parsenoop},214:{n:"RString",f:parsenoop},223:{n:"UDDesc",f:parsenoop},234:{n:"TabIdConf",f:parsenoop},354:{n:"XL5Modify",f:parsenoop},421:{n:"FileSharing2",f:parsenoop},536:{n:"Name",f:parsenoop},547:{n:"ExternName",f:parse_ExternName},561:{n:"Font",f:parsenoop},1030:{n:"Formula",f:parse_Formula},2157:{n:"FeatInfo",f:parsenoop},2163:{n:"FeatInfo11",f:parsenoop},2177:{n:"SXAddl12",f:parsenoop},2240:{n:"AutoWebPub",f:parsenoop},2241:{n:"ListObj",f:parsenoop},2242:{n:"ListField",f:parsenoop},2243:{n:"ListDV",f:parsenoop},2244:{n:"ListCondFmt",f:parsenoop},2245:{n:"ListCF",f:parsenoop},2246:{n:"FMQry",f:parsenoop},2247:{n:"FMSQry",f:parsenoop},2248:{n:"PLV",f:parsenoop},2249:{n:"LnExt",f:parsenoop},2250:{n:"MkrExt",f:parsenoop},2251:{n:"CrtCoopt",f:parsenoop},0:{}};var CountryEnum={1:"US",2:"CA",3:"",7:"RU",20:"EG",30:"GR",31:"NL",32:"BE",33:"FR",34:"ES",36:"HU",39:"IT",41:"CH",43:"AT",44:"GB",45:"DK",46:"SE",47:"NO",48:"PL",49:"DE",52:"MX",55:"BR",61:"AU",64:"NZ",66:"TH",81:"JP",82:"KR",84:"VN",86:"CN",90:"TR",105:"JS",213:"DZ",216:"MA",218:"LY",351:"PT",354:"IS",358:"FI",420:"CZ",886:"TW",961:"LB",962:"JO",963:"SY",964:"IQ",965:"KW",966:"SA",971:"AE",972:"IL",974:"QA",981:"IR",65535:"US"};function fix_opts_func(defaults){return function fix_opts(opts){for(var i=0;i!=defaults.length;++i){var d=defaults[i];if(typeof opts[d[0]]==="undefined")opts[d[0]]=d[1];if(d[2]==="n")opts[d[0]]=Number(opts[d[0]])}}}var fixopts=fix_opts_func([["cellNF",false],["cellFormula",true],["sheetRows",0,"n"],["bookSheets",false],["bookProps",false],["bookFiles",false],["password",""],["WTF",false]]);function parse_compobj(obj){var v={};var o=obj.content;var l=28,m;m=__lpstr(o,l);l+=4+__readUInt32LE(o,l);v.UserType=m;m=__readUInt32LE(o,l);l+=4;switch(m){case 0:break;case 4294967295:case 4294967294:l+=4;break;default:if(m>400)throw new Error("Unsupported Clipboard: "+m.toString(16));l+=m}m=__lpstr(o,l);l+=m.length===0?0:5+m.length;v.Reserved1=m;if((m=__readUInt32LE(o,l))!==1907550708)return v;throw"Unsupported Unicode Extension"}function parse_xlscfb(cfb,options){if(!options)options={};fixopts(options);reset_cp();var CompObj=cfb.find("!CompObj");var Summary=cfb.find("!SummaryInformation");var Workbook=cfb.find("/Workbook");if(!Workbook)Workbook=cfb.find("/Book");var CompObjP,SummaryP,WorkbookP;function slurp(R,blob,length,opts){var l=length;var bufs=[];var d=blob.slice(blob.l,blob.l+l);if(opts.enc&&opts.enc.insitu_decrypt)switch(R.n){case"BOF":case"FilePass":case"FileLock":case"InterfaceHdr":case"RRDInfo":case"RRDHead":case"UsrExcl":break;default:if(d.length===0)break;opts.enc.insitu_decrypt(d)}bufs.push(d);blob.l+=l;var next=RecordEnum[__readUInt16LE(blob,blob.l)];while(next!=null&&next.n==="Continue"){l=__readUInt16LE(blob,blob.l+2);bufs.push(blob.slice(blob.l+4,blob.l+4+l));blob.l+=4+l;next=RecordEnum[__readUInt16LE(blob,blob.l)]}var b=bconcat(bufs);prep_blob(b,0);var ll=0;b.lens=[];for(var j=0;j<bufs.length;++j){b.lens.push(ll);ll+=bufs[j].length}return R.f(b,b.length,opts)}function safe_format_xf(p,opts){if(!p.XF)return;try{var fmtid=p.XF.ifmt||0;if(fmtid===0){if(p.t==="n"){if((p.v|0)===p.v)p.w=SSF._general_int(p.v);else p.w=SSF._general_num(p.v)}else p.w=SSF._general(p.v)}else p.w=SSF.format(fmtid,p.v);if(opts.cellNF)p.z=SSF._table[fmtid]}catch(e){if(opts.WTF)throw e}}function make_cell(val,ixfe,t){return{v:val,ixfe:ixfe,t:t}}function parse_workbook(blob,options){var wb={opts:{}};var Sheets={};var out={};var Directory={};var found_sheet=false;var range={};var last_formula=null;var sst=[];var cur_sheet="";var Preamble={};var lastcell,last_cell,cc,cmnt,rng,rngC,rngR;var shared_formulae={};var array_formulae=[];var temp_val;var country;var cell_valid=true;var XFs=[];var addline=function addline(cell,line,options){if(!cell_valid)return;lastcell=cell;last_cell=encode_cell(cell);if(range.s){if(cell.r<range.s.r)range.s.r=cell.r;if(cell.c<range.s.c)range.s.c=cell.c}if(range.e){if(cell.r+1>range.e.r)range.e.r=cell.r+1;if(cell.c+1>range.e.c)range.e.c=cell.c+1}if(options.sheetRows&&lastcell.r>=options.sheetRows)cell_valid=false;else out[last_cell]=line};var opts={enc:false,sbcch:0,snames:[],sharedf:shared_formulae,arrayf:array_formulae,rrtabid:[],lastuser:"",biff:8,codepage:0,winlocked:0,wtf:false};if(options.password)opts.password=options.password;var mergecells=[];var objects=[];var supbooks=[[]];var sbc=0,sbci=0,sbcli=0;supbooks.SheetNames=opts.snames;supbooks.sharedf=opts.sharedf;supbooks.arrayf=opts.arrayf;var last_Rn="";var file_depth=0;while(blob.l<blob.length-1){var s=blob.l;var RecordType=blob.read_shift(2);if(RecordType===0&&last_Rn==="EOF")break;var length=blob.l===blob.length?0:blob.read_shift(2),y;var R=RecordEnum[RecordType];if(R&&R.f){if(options.bookSheets){if(last_Rn==="BoundSheet8"&&R.n!=="BoundSheet8")break}last_Rn=R.n;if(R.r===2||R.r==12){var rt=blob.read_shift(2);length-=2;if(!opts.enc&&rt!==RecordType)throw"rt mismatch";if(R.r==12){blob.l+=10;length-=10}}var val;if(R.n==="EOF")val=R.f(blob,length,opts);else val=slurp(R,blob,length,opts);var Rn=R.n;if(opts.biff===5)switch(Rn){case"Lbl":Rn="Label";break}switch(Rn){case"Date1904":wb.opts.Date1904=val;break;case"WriteProtect":wb.opts.WriteProtect=true;break;case"FilePass":if(!opts.enc)blob.l=0;opts.enc=val;if(opts.WTF)console.error(val);if(!options.password)throw new Error("File is password-protected");if(val.Type!==0)throw new Error("Encryption scheme unsupported");if(!val.valid)throw new Error("Password is incorrect");break;case"WriteAccess":opts.lastuser=val;break;case"FileSharing":break;case"CodePage":if(val===21010)val=1200;opts.codepage=val;set_cp(val);break;case"RRTabId":opts.rrtabid=val;break;case"WinProtect":opts.winlocked=val;break;case"Template":break;case"RefreshAll":wb.opts.RefreshAll=val;break;case"BookBool":break;case"UsesELFs":break;case"MTRSettings":{if(val[0]&&val[1])throw"Unsupported threads: "+val}break;case"CalcCount":wb.opts.CalcCount=val;break;case"CalcDelta":wb.opts.CalcDelta=val;break;case"CalcIter":wb.opts.CalcIter=val;break;case"CalcMode":wb.opts.CalcMode=val;break;case"CalcPrecision":wb.opts.CalcPrecision=val;break;case"CalcSaveRecalc":wb.opts.CalcSaveRecalc=val;break;case"CalcRefMode":opts.CalcRefMode=val;break;case"Uncalced":break;case"ForceFullCalculation":wb.opts.FullCalc=val;break;case"WsBool":break;case"XF":XFs.push(val);break;case"ExtSST":break;case"BookExt":break;case"RichTextStream":break;case"BkHim":break;case"SupBook":supbooks[++sbc]=[val];sbci=0;break;case"ExternName":supbooks[sbc][++sbci]=val;break;case"Index":break;case"Lbl":supbooks[0][++sbcli]=val;break;case"ExternSheet":supbooks[sbc]=supbooks[sbc].concat(val);sbci+=val.length;break;case"Protect":out["!protect"]=val;break;case"Password":if(val!==0&&opts.WTF)console.error("Password verifier: "+val);break;case"Prot4Rev":case"Prot4RevPass":break;case"BoundSheet8":{Directory[val.pos]=val;opts.snames.push(val.name)}break;case"EOF":{if(--file_depth)break;if(range.e){out["!range"]=range;if(range.e.r>0&&range.e.c>0){range.e.r--;range.e.c--;out["!ref"]=encode_range(range);range.e.r++;range.e.c++}if(mergecells.length>0)out["!merges"]=mergecells;if(objects.length>0)out["!objects"]=objects}if(cur_sheet==="")Preamble=out;else Sheets[cur_sheet]=out;out={}}break;case"BOF":{if(val.BIFFVer===1280)opts.biff=5;if(file_depth++)break;cell_valid=true;out={};cur_sheet=(Directory[s]||{name:""}).name;mergecells=[];objects=[]}break;case"Number":{temp_val={ixfe:val.ixfe,XF:XFs[val.ixfe],v:val.val,t:"n"};if(temp_val.XF)safe_format_xf(temp_val,options);addline({c:val.c,r:val.r},temp_val,options)}break;case"BoolErr":{temp_val={ixfe:val.ixfe,XF:XFs[val.ixfe],v:val.val,t:val.t};if(temp_val.XF)safe_format_xf(temp_val,options);addline({c:val.c,r:val.r},temp_val,options)}break;case"RK":{temp_val={ixfe:val.ixfe,XF:XFs[val.ixfe],v:val.rknum,t:"n"};if(temp_val.XF)safe_format_xf(temp_val,options);addline({c:val.c,r:val.r},temp_val,options)}break;case"MulRk":{for(var j=val.c;j<=val.C;++j){var ixfe=val.rkrec[j-val.c][0];temp_val={ixfe:ixfe,XF:XFs[ixfe],v:val.rkrec[j-val.c][1],t:"n"};if(temp_val.XF)safe_format_xf(temp_val,options);addline({c:j,r:val.r},temp_val,options)}}break;case"Formula":{switch(val.val){case"String":last_formula=val;break;case"Array Formula":throw"Array Formula unsupported";default:temp_val={v:val.val,ixfe:val.cell.ixfe,t:val.tt};temp_val.XF=XFs[temp_val.ixfe];if(options.cellFormula)temp_val.f="="+stringify_formula(val.formula,range,val.cell,supbooks,opts);if(temp_val.XF)safe_format_xf(temp_val,options);addline(val.cell,temp_val,options);last_formula=val}}break;case"String":{if(last_formula){last_formula.val=val;temp_val={v:last_formula.val,ixfe:last_formula.cell.ixfe,t:"s"};temp_val.XF=XFs[temp_val.ixfe];if(options.cellFormula)temp_val.f="="+stringify_formula(last_formula.formula,range,last_formula.cell,supbooks,opts);if(temp_val.XF)safe_format_xf(temp_val,options);addline(last_formula.cell,temp_val,options);last_formula=null}}break;case"Array":{array_formulae.push(val)}break;case"ShrFmla":{if(!cell_valid)break;shared_formulae[encode_cell(last_formula.cell)]=val[0]}break;case"LabelSst":temp_val=make_cell(sst[val.isst].t,val.ixfe,"s");temp_val.XF=XFs[temp_val.ixfe];if(temp_val.XF)safe_format_xf(temp_val,options);addline({c:val.c,r:val.r},temp_val,options);break;case"Label":temp_val=make_cell(val.val,val.ixfe,"s");temp_val.XF=XFs[temp_val.ixfe];
18582 // date 25801 if(temp_val.XF)safe_format_xf(temp_val,options);addline({c:val.c,r:val.r},temp_val,options);break;case"Dimensions":{if(file_depth===1)range=val}break;case"SST":{sst=val}break;case"Format":{SSF.load(val[1],val[0])}break;case"MergeCells":mergecells=mergecells.concat(val);break;case"Obj":objects[val.cmo[0]]=opts.lastobj=val;break;case"TxO":opts.lastobj.TxO=val;break;case"HLink":{for(rngR=val[0].s.r;rngR<=val[0].e.r;++rngR)for(rngC=val[0].s.c;rngC<=val[0].e.c;++rngC)if(out[encode_cell({c:rngC,r:rngR})])out[encode_cell({c:rngC,r:rngR})].l=val[1]}break;case"HLinkTooltip":{for(rngR=val[0].s.r;rngR<=val[0].e.r;++rngR)for(rngC=val[0].s.c;rngC<=val[0].e.c;++rngC)if(out[encode_cell({c:rngC,r:rngR})])out[encode_cell({c:rngC,r:rngR})].l.tooltip=val[1]}break;case"Note":{if(opts.biff===5)break;cc=out[encode_cell(val[0])];var noteobj=objects[val[2]];if(!cc)break;if(!cc.c)cc.c=[];cmnt={a:val[1],t:noteobj.TxO.t};cc.c.push(cmnt)}break;case"NameCmt":break;default:switch(R.n){case"Header":break;case"Footer":break;case"HCenter":break;case"VCenter":break;case"Pls":break;case"Setup":break;case"DefColWidth":break;case"GCW":break;case"LHRecord":break;case"ColInfo":break;case"Row":break;case"DBCell":break;case"MulBlank":break;case"EntExU2":break;case"SxView":break;case"Sxvd":break;case"SXVI":break;case"SXVDEx":break;case"SxIvd":break;case"SXDI":break;case"SXLI":break;case"SXEx":break;case"QsiSXTag":break;case"Selection":break;case"Feat":break;case"FeatHdr":case"FeatHdr11":break;case"Feature11":case"Feature12":case"List12":break;case"Blank":break;case"Country":country=val;break;case"RecalcId":break;case"DefaultRowHeight":case"DxGCol":break;case"Fbi":case"Fbi2":case"GelFrame":break;case"Font":break;case"XFCRC":break;case"XFExt":break;case"Style":break;case"StyleExt":break;case"Palette":break;case"ClrtClient":break;case"Theme":break;case"ScenarioProtect":break;case"ObjProtect":break;case"CondFmt12":break;case"Table":break;case"TableStyles":break;case"TableStyle":break;case"TableStyleElement":break;case"SXStreamID":break;case"SXVS":break;case"DConRef":break;case"SXAddl":break;case"DConName":break;case"SXPI":break;case"SxFormat":break;case"SxSelect":break;case"SxRule":break;case"SxFilt":break;case"SxItm":break;case"SxDXF":break;case"ScenMan":break;case"DCon":break;case"CellWatch":break;case"PrintRowCol":break;case"PrintGrid":break;case"PrintSize":break;case"XCT":break;case"CRN":break;case"Scl":{}break;case"SheetExt":{}break;case"SheetExtOptional":{}break;case"ObNoMacros":{}break;case"ObProj":{}break;case"CodeName":{}break;case"GUIDTypeLib":{}break;case"WOpt":break;case"PhoneticInfo":break;case"OleObjectSize":break;case"DXF":case"DXFN":case"DXFN12":case"DXFN12List":case"DXFN12NoCB":break;case"Dv":case"DVal":break;case"BRAI":case"Series":case"SeriesText":break;case"DConn":break;case"DbOrParamQry":break;case"DBQueryExt":break;case"IFmtRecord":break;case"CondFmt":case"CF":case"CF12":case"CFEx":break;case"Excel9File":break;case"Units":break;case"InterfaceHdr":case"Mms":case"InterfaceEnd":case"DSF":case"BuiltInFnGroupCount":case"Window1":case"Window2":case"HideObj":case"GridSet":case"Guts":case"UserBView":case"UserSViewBegin":case"UserSViewEnd":case"Pane":break;default:switch(R.n){case"Dat":case"Begin":case"End":case"StartBlock":case"EndBlock":case"Frame":case"Area":case"Axis":case"AxisLine":case"Tick":break;case"AxesUsed":case"CrtLayout12":case"CrtLayout12A":case"CrtLink":case"CrtLine":case"CrtMlFrt":break;case"LineFormat":case"AreaFormat":case"Chart":case"Chart3d":case"Chart3DBarShape":case"ChartFormat":case"ChartFrtInfo":break;case"PlotArea":case"PlotGrowth":break;case"SeriesList":case"SerParent":case"SerAuxTrend":break;case"DataFormat":case"SerToCrt":case"FontX":break;case"CatSerRange":case"AxcExt":case"SerFmt":break;case"ShtProps":break;case"DefaultText":case"Text":case"CatLab":break;case"DataLabExtContents":break;case"Legend":case"LegendException":break;case"Pie":case"Scatter":break;case"PieFormat":case"MarkerFormat":break;case"StartObject":case"EndObject":break;case"AlRuns":case"ObjectLink":break;case"SIIndex":break;case"AttachedLabel":break;case"Line":case"Bar":break;case"Surf":break;case"AxisParent":break;case"Pos":break;case"ValueRange":break;case"SXViewEx9":break;case"SXViewLink":break;case"PivotChartBits":break;case"SBaseRef":break;case"TextPropsStream":break;case"LnExt":break;case"MkrExt":break;case"CrtCoopt":break;case"Qsi":case"Qsif":case"Qsir":case"QsiSXTag":break;case"TxtQry":break;case"FilterMode":break;case"AutoFilter":case"AutoFilterInfo":break;case"AutoFilter12":break;case"DropDownObjIds":break;case"Sort":break;case"SortData":break;case"ShapePropsStream":break;case"MsoDrawing":case"MsoDrawingGroup":case"MsoDrawingSelection":break;case"ImData":break;case"WebPub":case"AutoWebPub":case"RightMargin":case"LeftMargin":case"TopMargin":case"BottomMargin":case"HeaderFooter":case"HFPicture":case"PLV":case"HorizontalPageBreaks":case"VerticalPageBreaks":case"Backup":case"CompressPictures":case"Compat12":break;case"Continue":case"ContinueFrt12":break;case"ExternCount":break;case"RString":break;case"TabIdConf":case"Radar":case"RadarArea":case"DropBar":case"Intl":case"CoordList":case"SerAuxErrBar":break;default:if(options.WTF)throw"Unrecognized Record "+R.n}}}}else blob.l+=length}var sheetnamesraw=Object.keys(Directory).sort(function(a,b){return Number(a)-Number(b)}).map(function(x){return Directory[x].name});var sheetnames=sheetnamesraw.slice();wb.Directory=sheetnamesraw;wb.SheetNames=sheetnamesraw;if(!options.bookSheets)wb.Sheets=Sheets;wb.Preamble=Preamble;wb.Strings=sst;wb.SSF=SSF.get_table();if(opts.enc)wb.Encryption=opts.enc;wb.Metadata={};if(country!==undefined)wb.Metadata.Country=country;return wb}if(CompObj)CompObjP=parse_compobj(CompObj);if(options.bookProps&&!options.bookSheets)WorkbookP={};else{if(Workbook)WorkbookP=parse_workbook(Workbook.content,options);else throw new Error("Cannot find Workbook stream")}parse_props(cfb);var props={};for(var y in cfb.Summary)props[y]=cfb.Summary[y];for(y in cfb.DocSummary)props[y]=cfb.DocSummary[y];WorkbookP.Props=WorkbookP.Custprops=props;if(options.bookFiles)WorkbookP.cfb=cfb;WorkbookP.CompObjP=CompObjP;return WorkbookP}function parse_props(cfb){var DSI=cfb.find("!DocumentSummaryInformation");if(DSI)try{cfb.DocSummary=parse_PropertySetStream(DSI,DocSummaryPIDDSI)}catch(e){}var SI=cfb.find("!SummaryInformation");if(SI)try{cfb.Summary=parse_PropertySetStream(SI,SummaryPIDSI)}catch(e){}}var encregex=/&[a-z]*;/g,coderegex=/_x([0-9a-fA-F]+)_/g;function coderepl(m,c){return _chr(parseInt(c,16))}function encrepl($$){return encodings[$$]}function unescapexml(s){if(s.indexOf("&")>-1)s=s.replace(encregex,encrepl);return s.indexOf("_")===-1?s:s.replace(coderegex,coderepl)}function parsexmlbool(value,tag){switch(value){case"1":case"true":case"TRUE":return true;default:return false}}function matchtag(f,g){return new RegExp("<"+f+'(?: xml:space="preserve")?>([^☃]*)</'+f+">",(g||"")+"m")}var entregex=/&#(\d+);/g;function entrepl($$,$1){return String.fromCharCode(parseInt($1,10))}function fixstr(str){return str.replace(entregex,entrepl)}var everted_BERR=evert(BERR);var magic_formats={"General Number":"General","General Date":SSF._table[22],"Long Date":"dddd, mmmm dd, yyyy","Medium Date":SSF._table[15],"Short Date":SSF._table[14],"Long Time":SSF._table[19],"Medium Time":SSF._table[18],"Short Time":SSF._table[20],Currency:'"$"#,##0.00_);[Red]\\("$"#,##0.00\\)',Fixed:SSF._table[2],Standard:SSF._table[4],Percent:SSF._table[10],Scientific:SSF._table[11],"Yes/No":'"Yes";"Yes";"No";@',"True/False":'"True";"True";"False";@',"On/Off":'"Yes";"Yes";"No";@'};function xlml_format(format,value){var fmt=magic_formats[format]||unescapexml(format);if(fmt==="General")return SSF._general(value);return SSF.format(fmt,value)}function xlml_set_prop(Props,tag,val){switch(tag){case"Description":tag="Comments";break}Props[tag]=val}function xlml_set_custprop(Custprops,Rn,cp,val){switch((cp[0].match(/dt:dt="([\w.]+)"/)||["",""])[1]){case"boolean":val=parsexmlbool(val);break;case"i2":case"int":val=parseInt(val,10);break;case"r4":case"float":val=parseFloat(val);break;case"date":case"dateTime.tz":val=new Date(val);break;case"i8":case"string":case"fixed":case"uuid":case"bin.base64":break;default:throw"bad custprop:"+cp[0]}Custprops[unescapexml(Rn[3])]=val}function safe_format_xlml(cell,nf,o){try{if(nf==="General"){if(cell.t==="n"){if((cell.v|0)===cell.v)cell.w=SSF._general_int(cell.v);else cell.w=SSF._general_num(cell.v)}else cell.w=SSF._general(cell.v)}else cell.w=xlml_format(nf||"General",cell.v);if(o.cellNF)cell.z=magic_formats[nf]||nf||"General"}catch(e){if(o.WTF)throw e}}function parse_xlml_data(xml,ss,data,cell,base,styles,csty,o){var nf="General",sid=cell.StyleID;o=o||{};if(sid===undefined&&csty)sid=csty.StyleID;while(styles[sid]!==undefined){if(styles[sid].nf)nf=styles[sid].nf;if(!styles[sid].Parent)break;sid=styles[sid].Parent}switch(data.Type){case"Boolean":cell.t="b";cell.v=parsexmlbool(xml);break;case"String":cell.t="str";cell.r=fixstr(unescapexml(xml));cell.v=xml.indexOf("<")>-1?ss:cell.r;break;case"DateTime":cell.v=(Date.parse(xml)-new Date(Date.UTC(1899,11,30)))/(24*60*60*1e3);if(cell.v!==cell.v)cell.v=unescapexml(xml);else if(cell.v>=1&&cell.v<60)cell.v=cell.v-1;if(!nf||nf=="General")nf="yyyy-mm-dd";case"Number":if(cell.v===undefined)cell.v=+xml;if(!cell.t)cell.t="n";break;case"Error":cell.t="e";cell.v=xml;cell.w=xml;break;default:cell.t="s";cell.v=fixstr(ss);break}if(cell.t!=="e")safe_format_xlml(cell,nf,o);if(o.cellFormula!=null&&cell.Formula){cell.f=rc_to_a1(unescapexml(cell.Formula),base);cell.Formula=undefined}cell.ixfe=cell.StyleID!==undefined?cell.StyleID:"Default"}function xlml_clean_comment(comment){comment.t=comment.v;comment.v=comment.w=comment.ixfe=undefined}function xlml_normalize(d){if(has_buf&&Buffer.isBuffer(d))return d.toString("utf8");if(typeof d==="string")return d;throw"badf"}var xlmlregex=/<(\/?)([a-z0-9]*:|)(\w+)[^>]*>/gm;function parse_xlml_xml(d,opts){var str=xlml_normalize(d);var Rn;var state=[],tmp;var sheets={},sheetnames=[],cursheet={},sheetname="";var table={},cell={},row={},dtag,didx;var c=0,r=0;var refguess={s:{r:1e6,c:1e6},e:{r:0,c:0}};var styles={},stag={};var ss="",fidx=0;var mergecells=[];var Props={},Custprops={},pidx=0,cp={};var comments=[],comment={};var cstys=[],csty;while(Rn=xlmlregex.exec(str))switch(Rn[3]){case"Data":if(state[state.length-1][1])break;if(Rn[1]==="/")parse_xlml_data(str.slice(didx,Rn.index),ss,dtag,state[state.length-1][0]=="Comment"?comment:cell,{c:c,r:r},styles,cstys[c],opts);else{ss="";dtag=parsexmltag(Rn[0]);didx=Rn.index+Rn[0].length}break;case"Cell":if(Rn[1]==="/"){if(comments.length>0)cell.c=comments;if((!opts.sheetRows||opts.sheetRows>r)&&cell.v!==undefined)cursheet[encode_col(c)+encode_row(r)]=cell;if(cell.HRef){cell.l={Target:cell.HRef,tooltip:cell.HRefScreenTip};cell.HRef=cell.HRefScreenTip=undefined}if(cell.MergeAcross||cell.MergeDown){var cc=c+(parseInt(cell.MergeAcross,10)|0);var rr=r+(parseInt(cell.MergeDown,10)|0);mergecells.push({s:{c:c,r:r},e:{c:cc,r:rr}})}++c;if(cell.MergeAcross)c+=+cell.MergeAcross}else{cell=parsexmltagobj(Rn[0]);if(cell.Index)c=+cell.Index-1;if(c<refguess.s.c)refguess.s.c=c;if(c>refguess.e.c)refguess.e.c=c;if(Rn[0].substr(-2)==="/>")++c;comments=[]}break;case"Row":if(Rn[1]==="/"||Rn[0].substr(-2)==="/>"){if(r<refguess.s.r)refguess.s.r=r;if(r>refguess.e.r)refguess.e.r=r;if(Rn[0].substr(-2)==="/>"){row=parsexmltag(Rn[0]);if(row.Index)r=+row.Index-1}c=0;++r}else{row=parsexmltag(Rn[0]);if(row.Index)r=+row.Index-1}break;case"Worksheet":if(Rn[1]==="/"){if((tmp=state.pop())[0]!==Rn[3])throw"Bad state: "+tmp;sheetnames.push(sheetname);if(refguess.s.r<=refguess.e.r&&refguess.s.c<=refguess.e.c)cursheet["!ref"]=encode_range(refguess);if(mergecells.length)cursheet["!merges"]=mergecells;sheets[sheetname]=cursheet}else{refguess={s:{r:1e6,c:1e6},e:{r:0,c:0}};r=c=0;state.push([Rn[3],false]);tmp=parsexmltag(Rn[0]);sheetname=tmp.Name;cursheet={};mergecells=[]}break;case"Table":if(Rn[1]==="/"){if((tmp=state.pop())[0]!==Rn[3])throw"Bad state: "+tmp}else if(Rn[0].slice(-2)=="/>")break;else{table=parsexmltag(Rn[0]);state.push([Rn[3],false]);cstys=[]}break;case"Style":if(Rn[1]==="/")styles[stag.ID]=stag;else stag=parsexmltag(Rn[0]);break;case"NumberFormat":stag.nf=parsexmltag(Rn[0]).Format||"General";break;case"Column":if(state[state.length-1][0]!=="Table")break;csty=parsexmltag(Rn[0]);cstys[csty.Index-1||cstys.length]=csty;for(var i=0;i<+csty.Span;++i)cstys[cstys.length]=csty;break;case"NamedRange":break;case"NamedCell":break;case"B":break;case"I":break;case"U":break;case"S":break;case"Sub":break;case"Sup":break;case"Span":break;case"Border":break;case"Alignment":break;case"Borders":break;case"Font":if(Rn[0].substr(-2)==="/>")break;else if(Rn[1]==="/")ss+=str.slice(fidx,Rn.index);else fidx=Rn.index+Rn[0].length;break;case"Interior":break;case"Protection":break;case"Author":case"Title":case"Description":case"Created":case"Keywords":case"Subject":case"Category":case"Company":case"LastAuthor":case"LastSaved":case"LastPrinted":case"Version":case"Revision":case"TotalTime":case"HyperlinkBase":case"Manager":if(Rn[0].substr(-2)==="/>")break;else if(Rn[1]==="/")xlml_set_prop(Props,Rn[3],str.slice(pidx,Rn.index));else pidx=Rn.index+Rn[0].length;break;case"Paragraphs":break;case"Styles":case"Workbook":if(Rn[1]==="/"){if((tmp=state.pop())[0]!==Rn[3])throw"Bad state: "+tmp}else state.push([Rn[3],false]);break;case"Comment":if(Rn[1]==="/"){if((tmp=state.pop())[0]!==Rn[3])throw"Bad state: "+tmp;xlml_clean_comment(comment);comments.push(comment)}else{state.push([Rn[3],false]);tmp=parsexmltag(Rn[0]);comment={a:tmp.Author}}break;case"Name":break;case"ComponentOptions":case"DocumentProperties":case"CustomDocumentProperties":case"OfficeDocumentSettings":case"PivotTable":case"PivotCache":case"Names":case"MapInfo":case"PageBreaks":case"QueryTable":case"DataValidation":case"AutoFilter":case"Sorting":case"Schema":case"data":case"ConditionalFormatting":case"SmartTagType":case"SmartTags":case"ExcelWorkbook":case"WorkbookOptions":case"WorksheetOptions":if(Rn[1]==="/"){if((tmp=state.pop())[0]!==Rn[3])throw"Bad state: "+tmp}else if(Rn[0].charAt(Rn[0].length-2)!=="/")state.push([Rn[3],true]);break;default:var seen=true;switch(state[state.length-1][0]){case"OfficeDocumentSettings":switch(Rn[3]){case"AllowPNG":break;case"RemovePersonalInformation":break;case"DownloadComponents":break;case"LocationOfComponents":break;case"Colors":break;case"Color":break;case"Index":break;case"RGB":break;case"PixelsPerInch":break;case"TargetScreenSize":break;case"ReadOnlyRecommended":break;default:seen=false}break;case"ComponentOptions":switch(Rn[3]){case"Toolbar":break;case"HideOfficeLogo":break;case"SpreadsheetAutoFit":break;case"Label":break;case"Caption":break;case"MaxHeight":break;case"MaxWidth":break;case"NextSheetNumber":break;default:seen=false}break;case"ExcelWorkbook":switch(Rn[3]){case"WindowHeight":break;case"WindowWidth":break;case"WindowTopX":break;case"WindowTopY":break;case"TabRatio":break;case"ProtectStructure":break;case"ProtectWindows":break;case"ActiveSheet":break;case"DisplayInkNotes":break;case"FirstVisibleSheet":break;case"SupBook":break;case"SheetName":break;case"SheetIndex":break;case"SheetIndexFirst":break;case"SheetIndexLast":break;case"Dll":break;case"AcceptLabelsInFormulas":break;case"DoNotSaveLinkValues":break;case"Date1904":break;case"Iteration":break;case"MaxIterations":break;case"MaxChange":break;case"Path":break;case"Xct":break;case"Count":break;case"SelectedSheets":break;case"Calculation":break;case"Uncalced":break;case"StartupPrompt":break;case"Crn":break;case"ExternName":break;case"Formula":break;case"ColFirst":break;case"ColLast":break;case"WantAdvise":break;case"Boolean":break;case"Error":break;case"Text":break;case"OLE":break;case"NoAutoRecover":break;case"PublishObjects":break;case"DoNotCalculateBeforeSave":break;case"Number":break;case"RefModeR1C1":break;case"EmbedSaveSmartTags":break;default:seen=false}break;case"WorkbookOptions":switch(Rn[3]){case"OWCVersion":break;case"Height":break;case"Width":break;default:seen=false}break;case"WorksheetOptions":switch(Rn[3]){case"Unsynced":break;case"Visible":break;case"Print":break;case"Panes":break;case"Scale":break;case"Pane":break;case"Number":break;case"Layout":break;case"Header":break;case"Footer":break;case"PageSetup":break;case"PageMargins":break;case"Selected":break;case"ProtectObjects":break;case"EnableSelection":break;case"ProtectScenarios":break;case"ValidPrinterInfo":break;case"HorizontalResolution":break;case"VerticalResolution":break;case"NumberofCopies":break;case"ActiveRow":break;case"ActiveCol":break;case"ActivePane":break;case"TopRowVisible":break;case"TopRowBottomPane":break;case"LeftColumnVisible":break;case"LeftColumnRightPane":break;case"FitToPage":break;case"RangeSelection":break;case"PaperSizeIndex":break;case"PageLayoutZoom":break;case"PageBreakZoom":break;case"FilterOn":break;case"DoNotDisplayGridlines":break;case"SplitHorizontal":break;case"SplitVertical":break;case"FreezePanes":break;case"FrozenNoSplit":break;case"FitWidth":break;case"FitHeight":break;case"CommentsLayout":break;case"Zoom":break;case"LeftToRight":break;case"Gridlines":break;case"AllowSort":break;case"AllowFilter":break;case"AllowInsertRows":break;case"AllowDeleteRows":break;case"AllowInsertCols":break;case"AllowDeleteCols":break;case"AllowInsertHyperlinks":break;case"AllowFormatCells":break;case"AllowSizeCols":break;case"AllowSizeRows":break;case"NoSummaryRowsBelowDetail":break;case"TabColorIndex":break;case"DoNotDisplayHeadings":break;case"ShowPageLayoutZoom":break;case"NoSummaryColumnsRightDetail":break;case"BlackAndWhite":break;case"DoNotDisplayZeros":break;case"DisplayPageBreak":break;case"RowColHeadings":break;case"DoNotDisplayOutline":break;case"NoOrientation":break;case"AllowUsePivotTables":break;case"ZeroHeight":break;case"ViewableRange":break;case"Selection":break;case"ProtectContents":break;default:seen=false}break;case"PivotTable":case"PivotCache":switch(Rn[3]){case"ImmediateItemsOnDrop":break;case"ShowPageMultipleItemLabel":break;case"CompactRowIndent":break;case"Location":break;case"PivotField":break;case"Orientation":break;case"LayoutForm":break;case"LayoutSubtotalLocation":break;case"LayoutCompactRow":break;case"Position":break;case"PivotItem":break;case"DataType":break;case"DataField":break;case"SourceName":break;case"ParentField":break;case"PTLineItems":break;case"PTLineItem":break;case"CountOfSameItems":break;case"Item":break;case"ItemType":break;case"PTSource":break;case"CacheIndex":break;case"ConsolidationReference":break;case"FileName":break;case"Reference":break;case"NoColumnGrand":break;case"NoRowGrand":break;case"BlankLineAfterItems":break;case"Hidden":break;case"Subtotal":break;case"BaseField":break;case"MapChildItems":break;case"Function":break;case"RefreshOnFileOpen":break;case"PrintSetTitles":break;case"MergeLabels":break;case"DefaultVersion":break;case"RefreshName":break;case"RefreshDate":break;case"RefreshDateCopy":break;case"VersionLastRefresh":break;case"VersionLastUpdate":break;case"VersionUpdateableMin":break;case"VersionRefreshableMin":break;case"Calculation":break;default:seen=false}break;case"PageBreaks":switch(Rn[3]){case"ColBreaks":break;case"ColBreak":break;case"RowBreaks":break;case"RowBreak":break;case"ColStart":break;case"ColEnd":break;case"RowEnd":break;default:seen=false}break;case"AutoFilter":switch(Rn[3]){case"AutoFilterColumn":break;case"AutoFilterCondition":break;case"AutoFilterAnd":break;case"AutoFilterOr":break;default:seen=false}break;case"QueryTable":switch(Rn[3]){case"Id":break;case"AutoFormatFont":break;case"AutoFormatPattern":break;case"QuerySource":break;case"QueryType":break;case"EnableRedirections":break;case"RefreshedInXl9":break;case"URLString":break;case"HTMLTables":break;case"Connection":break;case"CommandText":break;case"RefreshInfo":break;case"NoTitles":break;case"NextId":break;case"ColumnInfo":break;case"OverwriteCells":break;case"DoNotPromptForFile":break;case"TextWizardSettings":break;case"Source":break;case"Number":break;case"Decimal":break;case"ThousandSeparator":break;case"TrailingMinusNumbers":break;case"FormatSettings":break;case"FieldType":break;case"Delimiters":break;case"Tab":break;case"Comma":break;case"AutoFormatName":break;case"VersionLastEdit":break;case"VersionLastRefresh":break;default:seen=false}break;case"Sorting":case"ConditionalFormatting":case"DataValidation":switch(Rn[3]){case"Range":break;case"Type":break;case"Min":break;case"Max":break;case"Sort":break;case"Descending":break;case"Order":break;case"CaseSensitive":break;case"Value":break;case"ErrorStyle":break;case"ErrorMessage":break;case"ErrorTitle":break;case"CellRangeList":break;case"InputMessage":break;case"InputTitle":break;case"ComboHide":break;case"InputHide":break;case"Condition":break;case"Qualifier":break;case"UseBlank":break;case"Value1":break;case"Value2":break;case"Format":break;default:seen=false}break;case"MapInfo":case"Schema":case"data":switch(Rn[3]){case"Map":break;case"Entry":break;case"Range":break;case"XPath":break;case"Field":break;case"XSDType":break;case"FilterOn":break;case"Aggregate":break;case"ElementType":break;case"AttributeType":break;case"schema":case"element":case"complexType":case"datatype":case"all":case"attribute":case"extends":break;case"row":break;default:seen=false}break;case"SmartTags":break;default:seen=false;break}if(seen)break;if(!state[state.length-1][1])throw"Unrecognized tag: "+Rn[3]+"|"+state.join("|");if(state[state.length-1][0]==="CustomDocumentProperties"){if(Rn[0].substr(-2)==="/>")break;else if(Rn[1]==="/")xlml_set_custprop(Custprops,Rn,cp,str.slice(pidx,Rn.index));else{cp=Rn;pidx=Rn.index+Rn[0].length}break}if(opts.WTF)throw"Unrecognized tag: "+Rn[3]+"|"+state.join("|")}var out={};if(!opts.bookSheets&&!opts.bookProps)out.Sheets=sheets;out.SheetNames=sheetnames;out.SSF=SSF.get_table();out.Props=Props;out.Custprops=Custprops;return out}function parse_xlml(data,opts){fixopts(opts=opts||{});switch(opts.type||"base64"){case"base64":return parse_xlml_xml(Base64.decode(data),opts);case"binary":case"buffer":case"file":return parse_xlml_xml(data,opts);case"array":return parse_xlml_xml(data.map(_chr).join(""),opts)}}function write_xlml(wb,opts){}var fs;if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports){fs=require("fs")}}function firstbyte(f,o){switch((o||{}).type||"base64"){case"buffer":return f[0];case"base64":return Base64.decode(f.substr(0,12)).charCodeAt(0);case"binary":return f.charCodeAt(0);case"array":return f[0];default:throw new Error("Unrecognized type "+o.type)}}function xlsread(f,o){if(!o)o={};if(!o.type)o.type=has_buf&&Buffer.isBuffer(f)?"buffer":"base64";switch(firstbyte(f,o)){case 208:return parse_xlscfb(CFB.read(f,o),o);case 60:return parse_xlml(f,o);default:throw"Unsupported file"}}var readFile=function(f,o){var d=fs.readFileSync(f);if(!o)o={};switch(firstbyte(d,{type:"buffer"})){case 208:return parse_xlscfb(CFB.read(d,{type:"buffer"}),o);case 60:return parse_xlml(d,(o.type="buffer",o));default:throw"Unsupported file"}};function writeSync(wb,opts){var o=opts||{};switch(o.bookType){case"xml":return write_xlml(wb,o);default:throw"unsupported output format "+o.bookType}}function writeFileSync(wb,filename,opts){var o=opts|{};o.type="file";o.file=filename;switch(o.file.substr(-4).toLowerCase()){case".xls":o.bookType="xls";break;case".xml":o.bookType="xml";break}return writeSync(wb,o)}function shift_cell(cell,tgt){if(tgt.s){if(cell.cRel)cell.c+=tgt.s.c;if(cell.rRel)cell.r+=tgt.s.r}else{cell.c+=tgt.c;cell.r+=tgt.r}cell.cRel=cell.rRel=0;while(cell.c>=256)cell.c-=256;while(cell.r>=65536)cell.r-=65536;return cell}function shift_range(cell,range){cell.s=shift_cell(cell.s,range.s);cell.e=shift_cell(cell.e,range.s);return cell}function decode_row(rowstr){return parseInt(unfix_row(rowstr),10)-1}function encode_row(row){return""+(row+1)}function fix_row(cstr){return cstr.replace(/([A-Z]|^)(\d+)$/,"$1$$$2")}function unfix_row(cstr){return cstr.replace(/\$(\d+)$/,"$1")}function decode_col(colstr){var c=unfix_col(colstr),d=0,i=0;for(;i!==c.length;++i)d=26*d+c.charCodeAt(i)-64;return d-1}function encode_col(col){var s="";for(++col;col;col=Math.floor((col-1)/26))s=String.fromCharCode((col-1)%26+65)+s;return s}function fix_col(cstr){return cstr.replace(/^([A-Z])/,"$$$1")}function unfix_col(cstr){return cstr.replace(/^\$([A-Z])/,"$1")}function split_cell(cstr){return cstr.replace(/(\$?[A-Z]*)(\$?\d*)/,"$1,$2").split(",")}function decode_cell(cstr){var splt=split_cell(cstr);return{c:decode_col(splt[0]),r:decode_row(splt[1])}}function encode_cell(cell){return encode_col(cell.c)+encode_row(cell.r)}function fix_cell(cstr){return fix_col(fix_row(cstr))}function unfix_cell(cstr){return unfix_col(unfix_row(cstr))}function decode_range(range){var x=range.split(":").map(decode_cell);return{s:x[0],e:x[x.length-1]}}function encode_range(cs,ce){if(ce===undefined||typeof ce==="number")return encode_range(cs.s,cs.e);if(typeof cs!=="string")cs=encode_cell(cs);if(typeof ce!=="string")ce=encode_cell(ce);return cs==ce?cs:cs+":"+ce}function safe_decode_range(range){var o={s:{c:0,r:0},e:{c:0,r:0}};var idx=0,i=0,cc=0;var len=range.length;for(idx=0;i<len;++i){if((cc=range.charCodeAt(i)-64)<1||cc>26)break;idx=26*idx+cc}o.s.c=--idx;for(idx=0;i<len;++i){if((cc=range.charCodeAt(i)-48)<0||cc>9)break;idx=10*idx+cc}o.s.r=--idx;if(i===len||range.charCodeAt(++i)===58){o.e.c=o.s.c;o.e.r=o.s.r;return o}for(idx=0;i!=len;++i){if((cc=range.charCodeAt(i)-64)<1||cc>26)break;idx=26*idx+cc}o.e.c=--idx;for(idx=0;i!=len;++i){if((cc=range.charCodeAt(i)-48)<0||cc>9)break;idx=10*idx+cc}o.e.r=--idx;return o}function safe_format_cell(cell,v){if(cell.z!==undefined)try{return cell.w=SSF.format(cell.z,v)}catch(e){}if(!cell.XF)return v;try{return cell.w=SSF.format(cell.XF.ifmt||0,v)}catch(e){return""+v}}function format_cell(cell,v){if(cell==null||cell.t==null)return"";if(cell.w!==undefined)return cell.w;if(v===undefined)return safe_format_cell(cell,cell.v);return safe_format_cell(cell,v)}function sheet_to_json(sheet,opts){var val,row,range,header=0,offset=1,r,hdr=[],isempty,R,C,v;var o=opts!=null?opts:{};var raw=o.raw;if(sheet==null||sheet["!ref"]==null)return[];range=o.range!==undefined?o.range:sheet["!ref"];if(o.header===1)header=1;else if(o.header==="A")header=2;else if(Array.isArray(o.header))header=3;switch(typeof range){case"string":r=safe_decode_range(range);break;case"number":r=safe_decode_range(sheet["!ref"]);r.s.r=range;break;default:r=range}if(header>0)offset=0;var rr=encode_row(r.s.r);var cols=new Array(r.e.c-r.s.c+1);var out=new Array(r.e.r-r.s.r-offset+1);var outi=0;for(C=r.s.c;C<=r.e.c;++C){cols[C]=encode_col(C);val=sheet[cols[C]+rr];switch(header){case 1:hdr[C]=C;break;case 2:hdr[C]=cols[C];break;case 3:hdr[C]=o.header[C-r.s.c];break;default:if(val===undefined)continue;hdr[C]=format_cell(val)}}for(R=r.s.r+offset;R<=r.e.r;++R){rr=encode_row(R);isempty=true;row=header===1?[]:Object.create({__rowNum__:R});for(C=r.s.c;C<=r.e.c;++C){val=sheet[cols[C]+rr];if(val===undefined||val.t===undefined)continue;v=val.v;switch(val.t){case"e":continue;case"s":case"str":break;case"b":case"n":break;default:throw"unrecognized type "+val.t}if(v!==undefined){row[hdr[C]]=raw?v:format_cell(val,v);isempty=false}}if(isempty===false)out[outi++]=row}out.length=outi;return out}function sheet_to_row_object_array(sheet,opts){return sheet_to_json(sheet,opts!=null?opts:{})}function sheet_to_csv(sheet,opts){var out="",txt="",qreg=/"/g;var o=opts==null?{}:opts;if(sheet==null||sheet["!ref"]==null)return"";var r=safe_decode_range(sheet["!ref"]);var FS=o.FS!==undefined?o.FS:",",fs=FS.charCodeAt(0);var RS=o.RS!==undefined?o.RS:"\n",rs=RS.charCodeAt(0);var row="",rr="",cols=[];var i=0,cc=0,val;var R=0,C=0;for(C=r.s.c;C<=r.e.c;++C)cols[C]=encode_col(C);for(R=r.s.r;R<=r.e.r;++R){row="";rr=encode_row(R);for(C=r.s.c;C<=r.e.c;++C){val=sheet[cols[C]+rr];txt=val!==undefined?""+format_cell(val):"";for(i=0,cc=0;i!==txt.length;++i)if((cc=txt.charCodeAt(i))===fs||cc===rs||cc===34){txt='"'+txt.replace(qreg,'""')+'"';break}row+=(C===r.s.c?"":FS)+txt}out+=row+RS}return out}var make_csv=sheet_to_csv;function sheet_to_formulae(sheet){var cmds,y="",x,val="";if(sheet==null||sheet["!ref"]==null)return"";var r=safe_decode_range(sheet["!ref"]),rr="",cols=[],C;cmds=new Array((r.e.r-r.s.r+1)*(r.e.c-r.s.c+1));var i=0;for(C=r.s.c;C<=r.e.c;++C)cols[C]=encode_col(C);for(var R=r.s.r;R<=r.e.r;++R){rr=encode_row(R);for(C=r.s.c;C<=r.e.c;++C){y=cols[C]+rr;x=sheet[y];val="";if(x===undefined)continue;if(x.f!=null)val=x.f;else if(x.w!==undefined)val="'"+x.w;else if(x.v===undefined)continue;else val=""+x.v;cmds[i++]=y+"="+val}}cmds.length=i;return cmds}var utils={encode_col:encode_col,encode_row:encode_row,encode_cell:encode_cell,encode_range:encode_range,decode_col:decode_col,decode_row:decode_row,split_cell:split_cell,decode_cell:decode_cell,decode_range:decode_range,format_cell:format_cell,get_formulae:sheet_to_formulae,make_csv:sheet_to_csv,make_json:sheet_to_json,make_formulae:sheet_to_formulae,sheet_to_csv:sheet_to_csv,sheet_to_json:sheet_to_json,sheet_to_formulae:sheet_to_formulae,sheet_to_row_object_array:sheet_to_row_object_array};XLS.parse_xlscfb=parse_xlscfb;XLS.read=xlsread;XLS.readFile=readFile;XLS.utils=utils;XLS.CFB=CFB;XLS.SSF=SSF})(typeof exports!=="undefined"?exports:XLS);
18583 // @see http://www.delorie.com/djgpp/doc/rbinter/it/52/13.html 25802 //@ sourceMappingURL=dist/xls.min.map
18584 // @see http://www.delorie.com/djgpp/doc/rbinter/it/65/16.html 25803 /* xlsx.js (C) 2013-2014 SheetJS -- http://sheetjs.com */
18585 // @see http://www.delorie.com/djgpp/doc/rbinter/it/66/16.html 25804 /* vim: set ts=2: */
18586 25805 /*jshint -W041 */
18587 dosTime = o.date.getHours(); 25806 var XLSX = {};
18588 dosTime = dosTime << 6; 25807 (function(XLSX){
18589 dosTime = dosTime | o.date.getMinutes(); 25808 XLSX.version = '0.7.8';
18590 dosTime = dosTime << 5; 25809 var current_codepage = 1252, current_cptable;
18591 dosTime = dosTime | o.date.getSeconds() / 2; 25810 if(typeof module !== "undefined" && typeof require !== 'undefined') {
18592 25811 if(typeof cptable === 'undefined') cptable = require('./dist/cpexcel');
18593 dosDate = o.date.getFullYear() - 1980; 25812 current_cptable = cptable[current_codepage];
18594 dosDate = dosDate << 4; 25813 }
18595 dosDate = dosDate | (o.date.getMonth() + 1); 25814 function reset_cp() { set_cp(1252); }
18596 dosDate = dosDate << 5; 25815 var set_cp = function(cp) { current_codepage = cp; };
18597 dosDate = dosDate | o.date.getDate(); 25816
18598 25817 function char_codes(data) { var o = []; for(var i = 0, len = data.length; i < len; ++i) o[i] = data.charCodeAt(i); return o; }
18599 var hasData = data !== null && data.length !== 0; 25818 var debom_xml = function(data) { return data; };
18600 25819
18601 var compression = JSZip.compressions[compressionType]; 25820 if(typeof cptable !== 'undefined') {
18602 var compressedData = hasData ? compression.compress(data) : ''; 25821 set_cp = function(cp) { current_codepage = cp; current_cptable = cptable[cp]; };
18603 25822 debom_xml = function(data) {
18604 var header = ""; 25823 if(data.charCodeAt(0) === 0xFF && data.charCodeAt(1) === 0xFE) { return cptable.utils.decode(1200, char_codes(data.substr(2))); }
18605 25824 return data;
18606 // version needed to extract 25825 };
18607 header += "\x0A\x00"; 25826 }
18608 // general purpose bit flag 25827 /* ssf.js (C) 2013-2014 SheetJS -- http://sheetjs.com */
18609 // set bit 11 if utf8 25828 /*jshint -W041 */
18610 header += useUTF8 ? "\x00\x08" : "\x00\x00"; 25829 var SSF = {};
18611 // compression method 25830 var make_ssf = function make_ssf(SSF){
18612 header += hasData ? compression.magic : JSZip.compressions['STORE'].magic; 25831 SSF.version = '0.8.1';
18613 // last mod file time 25832 function _strrev(x) { var o = "", i = x.length-1; while(i>=0) o += x.charAt(i--); return o; }
18614 header += decToHex(dosTime, 2); 25833 function fill(c,l) { var o = ""; while(o.length < l) o+=c; return o; }
18615 // last mod file date 25834 function pad0(v,d){var t=""+v; return t.length>=d?t:fill('0',d-t.length)+t;}
18616 header += decToHex(dosDate, 2); 25835 function pad_(v,d){var t=""+v;return t.length>=d?t:fill(' ',d-t.length)+t;}
18617 // crc-32 25836 function rpad_(v,d){var t=""+v; return t.length>=d?t:t+fill(' ',d-t.length);}
18618 header += hasData ? decToHex(this.crc32(data), 4) : '\x00\x00\x00\x00'; 25837 function pad0r1(v,d){var t=""+Math.round(v); return t.length>=d?t:fill('0',d-t.length)+t;}
18619 // compressed size 25838 function pad0r2(v,d){var t=""+v; return t.length>=d?t:fill('0',d-t.length)+t;}
18620 header += hasData ? decToHex(compressedData.length, 4) : '\x00\x00\x00\x00'; 25839 var p2_32 = Math.pow(2,32);
18621 // uncompressed size 25840 function pad0r(v,d){if(v>p2_32||v<-p2_32) return pad0r1(v,d); var i = Math.round(v); return pad0r2(i,d); }
18622 header += hasData ? decToHex(data.length, 4) : '\x00\x00\x00\x00'; 25841 function isgeneral(s, i) { return s.length >= 7 + i && (s.charCodeAt(i)|32) === 103 && (s.charCodeAt(i+1)|32) === 101 && (s.charCodeAt(i+2)|32) === 110 && (s.charCodeAt(i+3)|32) === 101 && (s.charCodeAt(i+4)|32) === 114 && (s.charCodeAt(i+5)|32) === 97 && (s.charCodeAt(i+6)|32) === 108; }
18623 // file name length 25842 /* Options */
18624 header += decToHex(utfEncodedFileName.length, 2); 25843 var opts_fmt = [
18625 // extra field length 25844 ["date1904", 0],
18626 header += "\x00\x00"; 25845 ["output", ""],
18627 25846 ["WTF", false]
18628 return { 25847 ];
18629 header:header, 25848 function fixopts(o){
18630 compressedData:compressedData 25849 for(var y = 0; y != opts_fmt.length; ++y) if(o[opts_fmt[y][0]]===undefined) o[opts_fmt[y][0]]=opts_fmt[y][1];
18631 }; 25850 }
18632 }; 25851 SSF.opts = opts_fmt;
18633 25852 var table_fmt = {
18634 25853 0: 'General',
18635 // return the actual prototype of JSZip 25854 1: '0',
18636 return { 25855 2: '0.00',
18637 /** 25856 3: '#,##0',
18638 * Read an existing zip and merge the data in the current JSZip object. 25857 4: '#,##0.00',
18639 * The implementation is in jszip-load.js, don't forget to include it. 25858 9: '0%',
18640 * @param {String|ArrayBuffer|Uint8Array} stream The stream to load 25859 10: '0.00%',
18641 * @param {Object} options Options for loading the stream. 25860 11: '0.00E+00',
18642 * options.base64 : is the stream in base64 ? default : false 25861 12: '# ?/?',
18643 * @return {JSZip} the current JSZip object 25862 13: '# ??/??',
18644 */ 25863 14: 'm/d/yy',
18645 load : function (stream, options) { 25864 15: 'd-mmm-yy',
18646 throw new Error("Load method is not defined. Is the file jszip-load.js included ?"); 25865 16: 'd-mmm',
18647 }, 25866 17: 'mmm-yy',
18648 25867 18: 'h:mm AM/PM',
18649 /** 25868 19: 'h:mm:ss AM/PM',
18650 * Filter nested files/folders with the specified function. 25869 20: 'h:mm',
18651 * @param {Function} search the predicate to use : 25870 21: 'h:mm:ss',
18652 * function (relativePath, file) {...} 25871 22: 'm/d/yy h:mm',
18653 * It takes 2 arguments : the relative path and the file. 25872 37: '#,##0 ;(#,##0)',
18654 * @return {Array} An array of matching elements. 25873 38: '#,##0 ;[Red](#,##0)',
18655 */ 25874 39: '#,##0.00;(#,##0.00)',
18656 filter : function (search) { 25875 40: '#,##0.00;[Red](#,##0.00)',
18657 var result = [], filename, relativePath, file, fileClone; 25876 45: 'mm:ss',
18658 for (filename in this.files) { 25877 46: '[h]:mm:ss',
18659 if ( !this.files.hasOwnProperty(filename) ) { continue; } 25878 47: 'mmss.0',
18660 file = this.files[filename]; 25879 48: '##0.0E+0',
18661 // return a new object, don't let the user mess with our internal objects :) 25880 49: '@',
18662 fileClone = new ZipObject(file.name, file.data, extend(file.options)); 25881 56: '"上午/下午 "hh"時"mm"分"ss"秒 "',
18663 relativePath = filename.slice(this.root.length, filename.length); 25882 65535: 'General'
18664 if (filename.slice(0, this.root.length) === this.root && // the file is in the current root 25883 };
18665 search(relativePath, fileClone)) { // and the file matches the function 25884 var days = [
18666 result.push(fileClone); 25885 ['Sun', 'Sunday'],
18667 } 25886 ['Mon', 'Monday'],
18668 } 25887 ['Tue', 'Tuesday'],
18669 return result; 25888 ['Wed', 'Wednesday'],
18670 }, 25889 ['Thu', 'Thursday'],
18671 25890 ['Fri', 'Friday'],
18672 /** 25891 ['Sat', 'Saturday']
18673 * Add a file to the zip file, or search a file. 25892 ];
18674 * @param {string|RegExp} name The name of the file to add (if data is defined), 25893 var months = [
18675 * the name of the file to find (if no data) or a regex to match files. 25894 ['J', 'Jan', 'January'],
18676 * @param {String|ArrayBuffer|Uint8Array} data The file data, either raw or base64 encoded 25895 ['F', 'Feb', 'February'],
18677 * @param {Object} o File options 25896 ['M', 'Mar', 'March'],
18678 * @return {JSZip|Object|Array} this JSZip object (when adding a file), 25897 ['A', 'Apr', 'April'],
18679 * a file (when searching by string) or an array of files (when searching by regex). 25898 ['M', 'May', 'May'],
18680 */ 25899 ['J', 'Jun', 'June'],
18681 file : function(name, data, o) { 25900 ['J', 'Jul', 'July'],
18682 if (arguments.length === 1) { 25901 ['A', 'Aug', 'August'],
18683 if (name instanceof RegExp) { 25902 ['S', 'Sep', 'September'],
18684 var regexp = name; 25903 ['O', 'Oct', 'October'],
18685 return this.filter(function(relativePath, file) { 25904 ['N', 'Nov', 'November'],
18686 return !file.options.dir && regexp.test(relativePath); 25905 ['D', 'Dec', 'December']
18687 }); 25906 ];
18688 } else { // text 25907 function frac(x, D, mixed) {
18689 return this.filter(function (relativePath, file) { 25908 var sgn = x < 0 ? -1 : 1;
18690 return !file.options.dir && relativePath === name; 25909 var B = x * sgn;
18691 })[0]||null; 25910 var P_2 = 0, P_1 = 1, P = 0;
18692 } 25911 var Q_2 = 1, Q_1 = 0, Q = 0;
18693 } else { // more than one argument : we have data ! 25912 var A = Math.floor(B);
18694 name = this.root+name; 25913 while(Q_1 < D) {
18695 fileAdd.call(this, name, data, o); 25914 A = Math.floor(B);
18696 } 25915 P = A * P_1 + P_2;
18697 return this; 25916 Q = A * Q_1 + Q_2;
18698 }, 25917 if((B - A) < 0.0000000005) break;
18699 25918 B = 1 / (B - A);
18700 /** 25919 P_2 = P_1; P_1 = P;
18701 * Add a directory to the zip file, or search. 25920 Q_2 = Q_1; Q_1 = Q;
18702 * @param {String|RegExp} arg The name of the directory to add, or a regex to search folders. 25921 }
18703 * @return {JSZip} an object with the new directory as the root, or an array containing matching folders. 25922 if(Q > D) { Q = Q_1; P = P_1; }
18704 */ 25923 if(Q > D) { Q = Q_2; P = P_2; }
18705 folder : function(arg) { 25924 if(!mixed) return [0, sgn * P, Q];
18706 if (!arg) { 25925 if(Q===0) throw "Unexpected state: "+P+" "+P_1+" "+P_2+" "+Q+" "+Q_1+" "+Q_2;
18707 return this; 25926 var q = Math.floor(sgn * P/Q);
18708 } 25927 return [q, sgn*P - q*Q, Q];
18709 25928 }
18710 if (arg instanceof RegExp) { 25929 function general_fmt_int(v, opts) { return ""+v; }
18711 return this.filter(function(relativePath, file) { 25930 SSF._general_int = general_fmt_int;
18712 return file.options.dir && arg.test(relativePath); 25931 var general_fmt_num = (function make_general_fmt_num() {
18713 }); 25932 var gnr1 = /\.(\d*[1-9])0+$/, gnr2 = /\.0*$/, gnr4 = /\.(\d*[1-9])0+/, gnr5 = /\.0*[Ee]/, gnr6 = /(E[+-])(\d)$/;
18714 } 25933 function gfn2(v) {
18715 25934 var w = (v<0?12:11);
18716 // else, name is a new folder 25935 var o = gfn5(v.toFixed(12)); if(o.length <= w) return o;
18717 var name = this.root + arg; 25936 o = v.toPrecision(10); if(o.length <= w) return o;
18718 var newFolder = folderAdd.call(this, name); 25937 return v.toExponential(5);
18719 25938 }
18720 // Allow chaining by returning a new object with this folder as the root 25939 function gfn3(v) {
18721 var ret = this.clone(); 25940 var o = v.toFixed(11).replace(gnr1,".$1");
18722 ret.root = newFolder.name; 25941 if(o.length > (v<0?12:11)) o = v.toPrecision(6);
18723 return ret; 25942 return o;
18724 }, 25943 }
18725 25944 function gfn4(o) {
18726 /** 25945 for(var i = 0; i != o.length; ++i) if((o.charCodeAt(i) | 0x20) === 101) return o.replace(gnr4,".$1").replace(gnr5,"E").replace("e","E").replace(gnr6,"$10$2");
18727 * Delete a file, or a directory and all sub-files, from the zip 25946 return o;
18728 * @param {string} name the name of the file to delete 25947 }
18729 * @return {JSZip} this JSZip object 25948 function gfn5(o) {
18730 */ 25949 //for(var i = 0; i != o.length; ++i) if(o.charCodeAt(i) === 46) return o.replace(gnr2,"").replace(gnr1,".$1");
18731 remove : function(name) { 25950 //return o;
18732 name = this.root + name; 25951 return o.indexOf(".") > -1 ? o.replace(gnr2,"").replace(gnr1,".$1") : o;
18733 var file = this.files[name]; 25952 }
18734 if (!file) { 25953 return function general_fmt_num(v, opts) {
18735 // Look for any folders 25954 var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o;
18736 if (name.slice(-1) != "/") { 25955 if(V >= -4 && V <= -1) o = v.toPrecision(10+V);
18737 name += "/"; 25956 else if(Math.abs(V) <= 9) o = gfn2(v);
18738 } 25957 else if(V === 10) o = v.toFixed(10).substr(0,12);
18739 file = this.files[name]; 25958 else o = gfn3(v);
18740 } 25959 return gfn5(gfn4(o));
18741 25960 };})();
18742 if (file) { 25961 SSF._general_num = general_fmt_num;
18743 if (!file.options.dir) { 25962 function general_fmt(v, opts) {
18744 // file 25963 switch(typeof v) {
18745 delete this.files[name]; 25964 case 'string': return v;
18746 } else { 25965 case 'boolean': return v ? "TRUE" : "FALSE";
18747 // folder 25966 case 'number': return (v|0) === v ? general_fmt_int(v, opts) : general_fmt_num(v, opts);
18748 var kids = this.filter(function (relativePath, file) { 25967 }
18749 return file.name.slice(0, name.length) === name; 25968 throw new Error("unsupported value in General format: " + v);
18750 }); 25969 }
18751 for (var i = 0; i < kids.length; i++) { 25970 SSF._general = general_fmt;
18752 delete this.files[kids[i].name]; 25971 function fix_hijri(date, o) { return 0; }
18753 } 25972 function parse_date_code(v,opts,b2) {
18754 } 25973 if(v > 2958465 || v < 0) return null;
18755 } 25974 var date = (v|0), time = Math.floor(86400 * (v - date)), dow=0;
18756 25975 var dout=[];
18757 return this; 25976 var out={D:date, T:time, u:86400*(v-date)-time,y:0,m:0,d:0,H:0,M:0,S:0,q:0};
18758 }, 25977 if(Math.abs(out.u) < 1e-6) out.u = 0;
18759 25978 fixopts(opts != null ? opts : (opts=[]));
18760 /** 25979 if(opts.date1904) date += 1462;
18761 * Generate the complete zip file 25980 if(out.u > 0.999) {
18762 * @param {Object} options the options to generate the zip file : 25981 out.u = 0;
18763 * - base64, (deprecated, use type instead) true to generate base64. 25982 if(++time == 86400) { time = 0; ++date; }
18764 * - compression, "STORE" by default. 25983 }
18765 * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob. 25984 if(date === 60) {dout = b2 ? [1317,10,29] : [1900,2,29]; dow=3;}
18766 * @return {String|Uint8Array|ArrayBuffer|Blob} the zip file 25985 else if(date === 0) {dout = b2 ? [1317,8,29] : [1900,1,0]; dow=6;}
18767 */ 25986 else {
18768 generate : function(options) { 25987 if(date > 60) --date;
18769 options = extend(options || {}, { 25988 /* 1 = Jan 1 1900 */
18770 base64 : true, 25989 var d = new Date(1900,0,1);
18771 compression : "STORE", 25990 d.setDate(d.getDate() + date - 1);
18772 type : "base64" 25991 dout = [d.getFullYear(), d.getMonth()+1,d.getDate()];
18773 }); 25992 dow = d.getDay();
18774 var compression = options.compression.toUpperCase(); 25993 if(date < 60) dow = (dow + 6) % 7;
18775 25994 if(b2) dow = fix_hijri(d, dout);
18776 // The central directory, and files data 25995 }
18777 var directory = [], files = [], fileOffset = 0; 25996 out.y = dout[0]; out.m = dout[1]; out.d = dout[2];
18778 25997 out.S = time % 60; time = Math.floor(time / 60);
18779 if (!JSZip.compressions[compression]) { 25998 out.M = time % 60; time = Math.floor(time / 60);
18780 throw compression + " is not a valid compression method !"; 25999 out.H = time;
18781 } 26000 out.q = dow;
18782 26001 return out;
18783 for (var name in this.files) { 26002 }
18784 if ( !this.files.hasOwnProperty(name) ) { continue; } 26003 SSF.parse_date_code = parse_date_code;
18785 26004 /*jshint -W086 */
18786 var file = this.files[name]; 26005 function write_date(type, fmt, val, ss0) {
18787 26006 var o="", ss=0, tt=0, y = val.y, out, outl = 0;
18788 var utfEncodedFileName = this.utf8encode(file.name); 26007 switch(type) {
18789 26008 case 98: /* 'b' buddhist year */
18790 var fileRecord = "", 26009 y = val.y + 543;
18791 dirRecord = "", 26010 /* falls through */
18792 data = prepareLocalHeaderData.call(this, file, utfEncodedFileName, compression); 26011 case 121: /* 'y' year */
18793 fileRecord = JSZip.signature.LOCAL_FILE_HEADER + data.header + utfEncodedFileName + data.compressedData; 26012 switch(fmt.length) {
18794 26013 case 1: case 2: out = y % 100; outl = 2; break;
18795 dirRecord = JSZip.signature.CENTRAL_FILE_HEADER + 26014 default: out = y % 10000; outl = 4; break;
18796 // version made by (00: DOS) 26015 } break;
18797 "\x14\x00" + 26016 case 109: /* 'm' month */
18798 // file header (common to file and central directory) 26017 switch(fmt.length) {
18799 data.header + 26018 case 1: case 2: out = val.m; outl = fmt.length; break;
18800 // file comment length 26019 case 3: return months[val.m-1][1];
18801 "\x00\x00" + 26020 case 5: return months[val.m-1][0];
18802 // disk number start 26021 default: return months[val.m-1][2];
18803 "\x00\x00" + 26022 } break;
18804 // internal file attributes TODO 26023 case 100: /* 'd' day */
18805 "\x00\x00" + 26024 switch(fmt.length) {
18806 // external file attributes 26025 case 1: case 2: out = val.d; outl = fmt.length; break;
18807 (this.files[name].options.dir===true?"\x10\x00\x00\x00":"\x00\x00\x00\x00")+ 26026 case 3: return days[val.q][0];
18808 // relative offset of local header 26027 default: return days[val.q][1];
18809 decToHex(fileOffset, 4) + 26028 } break;
18810 // file name 26029 case 104: /* 'h' 12-hour */
18811 utfEncodedFileName; 26030 switch(fmt.length) {
18812 26031 case 1: case 2: out = 1+(val.H+11)%12; outl = fmt.length; break;
18813 fileOffset += fileRecord.length; 26032 default: throw 'bad hour format: ' + fmt;
18814 26033 } break;
18815 files.push(fileRecord); 26034 case 72: /* 'H' 24-hour */
18816 directory.push(dirRecord); 26035 switch(fmt.length) {
18817 } 26036 case 1: case 2: out = val.H; outl = fmt.length; break;
18818 26037 default: throw 'bad hour format: ' + fmt;
18819 var fileData = files.join(""); 26038 } break;
18820 var dirData = directory.join(""); 26039 case 77: /* 'M' minutes */
18821 26040 switch(fmt.length) {
18822 var dirEnd = ""; 26041 case 1: case 2: out = val.M; outl = fmt.length; break;
18823 26042 default: throw 'bad minute format: ' + fmt;
18824 // end of central dir signature 26043 } break;
18825 dirEnd = JSZip.signature.CENTRAL_DIRECTORY_END + 26044 case 115: /* 's' seconds */
18826 // number of this disk 26045 if(val.u === 0) switch(fmt) {
18827 "\x00\x00" + 26046 case 's': case 'ss': return pad0(val.S, fmt.length);
18828 // number of the disk with the start of the central directory 26047 case '.0': case '.00': case '.000':
18829 "\x00\x00" + 26048 }
18830 // total number of entries in the central directory on this disk 26049 switch(fmt) {
18831 decToHex(files.length, 2) + 26050 case 's': case 'ss': case '.0': case '.00': case '.000':
18832 // total number of entries in the central directory 26051 if(ss0 >= 2) tt = ss0 === 3 ? 1000 : 100;
18833 decToHex(files.length, 2) + 26052 else tt = ss0 === 1 ? 10 : 1;
18834 // size of the central directory 4 bytes 26053 ss = Math.round((tt)*(val.S + val.u));
18835 decToHex(dirData.length, 4) + 26054 if(ss >= 60*tt) ss = 0;
18836 // offset of start of central directory with respect to the starting disk number 26055 if(fmt === 's') return ss === 0 ? "0" : ""+ss/tt;
18837 decToHex(fileData.length, 4) + 26056 o = pad0(ss,2 + ss0);
18838 // .ZIP file comment length 26057 if(fmt === 'ss') return o.substr(0,2);
18839 "\x00\x00"; 26058 return "." + o.substr(2,fmt.length-1);
18840 26059 default: throw 'bad second format: ' + fmt;
18841 var zip = fileData + dirData + dirEnd; 26060 }
18842 26061 case 90: /* 'Z' absolute time */
18843 26062 switch(fmt) {
18844 switch(options.type.toLowerCase()) { 26063 case '[h]': case '[hh]': out = val.D*24+val.H; break;
18845 case "uint8array" : 26064 case '[m]': case '[mm]': out = (val.D*24+val.H)*60+val.M; break;
18846 return JSZip.utils.string2Uint8Array(zip); 26065 case '[s]': case '[ss]': out = ((val.D*24+val.H)*60+val.M)*60+Math.round(val.S+val.u); break;
18847 case "arraybuffer" : 26066 default: throw 'bad abstime format: ' + fmt;
18848 return JSZip.utils.string2Uint8Array(zip).buffer; 26067 } outl = fmt.length === 3 ? 1 : 2; break;
18849 case "blob" : 26068 case 101: /* 'e' era */
18850 return JSZip.utils.string2Blob(zip); 26069 out = y; outl = 1;
18851 case "base64" : 26070 }
18852 return (options.base64) ? JSZipBase64.encode(zip) : zip; 26071 if(outl > 0) return pad0(out, outl); else return "";
18853 default : // case "string" : 26072 }
18854 return zip; 26073 /*jshint +W086 */
18855 } 26074 function commaify(s) {
18856 }, 26075 if(s.length <= 3) return s;
18857 26076 var j = (s.length % 3), o = s.substr(0,j);
18858 /** 26077 for(; j!=s.length; j+=3) o+=(o.length > 0 ? "," : "") + s.substr(j,3);
18859 * 26078 return o;
18860 * Javascript crc32 26079 }
18861 * http://www.webtoolkit.info/ 26080 var write_num = (function make_write_num(){
18862 * 26081 var pct1 = /%/g;
18863 */ 26082 function write_num_pct(type, fmt, val){
18864 crc32 : function(str, crc) { 26083 var sfmt = fmt.replace(pct1,""), mul = fmt.length - sfmt.length;
18865 26084 return write_num(type, sfmt, val * Math.pow(10,2*mul)) + fill("%",mul);
18866 if (str === "" || typeof str === "undefined") { 26085 }
18867 return 0; 26086 function write_num_cm(type, fmt, val){
18868 } 26087 var idx = fmt.length - 1;
18869 26088 while(fmt.charCodeAt(idx-1) === 44) --idx;
18870 var table = [ 26089 return write_num(type, fmt.substr(0,idx), val / Math.pow(10,3*(fmt.length-idx)));
18871 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 26090 }
18872 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 26091 function write_num_exp(fmt, val){
18873 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 26092 var o;
18874 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 26093 var idx = fmt.indexOf("E") - fmt.indexOf(".") - 1;
18875 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 26094 if(fmt.match(/^#+0.0E\+0$/)) {
18876 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 26095 var period = fmt.indexOf("."); if(period === -1) period=fmt.indexOf('E');
18877 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 26096 var ee = Math.floor(Math.log(Math.abs(val))*Math.LOG10E)%period;
18878 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 26097 if(ee < 0) ee += period;
18879 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 26098 o = (val/Math.pow(10,ee)).toPrecision(idx+1+(period+ee)%period);
18880 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 26099 if(o.indexOf("e") === -1) {
18881 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 26100 var fakee = Math.floor(Math.log(Math.abs(val))*Math.LOG10E);
18882 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 26101 if(o.indexOf(".") === -1) o = o[0] + "." + o.substr(1) + "E+" + (fakee - o.length+ee);
18883 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 26102 else o += "E+" + (fakee - ee);
18884 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 26103 while(o.substr(0,2) === "0.") {
18885 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 26104 o = o[0] + o.substr(2,period) + "." + o.substr(2+period);
18886 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 26105 o = o.replace(/^0+([1-9])/,"$1").replace(/^0+\./,"0.");
18887 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 26106 }
18888 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 26107 o = o.replace(/\+-/,"-");
18889 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 26108 }
18890 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 26109 o = o.replace(/^([+-]?)(\d*)\.(\d*)[Ee]/,function($$,$1,$2,$3) { return $1 + $2 + $3.substr(0,(period+ee)%period) + "." + $3.substr(ee) + "E"; });
18891 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 26110 } else o = val.toExponential(idx);
18892 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 26111 if(fmt.match(/E\+00$/) && o.match(/e[+-]\d$/)) o = o.substr(0,o.length-1) + "0" + o[o.length-1];
18893 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 26112 if(fmt.match(/E\-/) && o.match(/e\+/)) o = o.replace(/e\+/,"e");
18894 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 26113 return o.replace("e","E");
18895 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 26114 }
18896 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 26115 var frac1 = /# (\?+)( ?)\/( ?)(\d+)/;
18897 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 26116 function write_num_f1(r, aval, sign) {
18898 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 26117 var den = parseInt(r[4]), rr = Math.round(aval * den), base = Math.floor(rr/den);
18899 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 26118 var myn = (rr - base*den), myd = den;
18900 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 26119 return sign + (base === 0 ? "" : ""+base) + " " + (myn === 0 ? fill(" ", r[1].length + 1 + r[4].length) : pad_(myn,r[1].length) + r[2] + "/" + r[3] + pad0(myd,r[4].length));
18901 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 26120 }
18902 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 26121 function write_num_f2(r, aval, sign) {
18903 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 26122 return sign + (aval === 0 ? "" : ""+aval) + fill(" ", r[1].length + 2 + r[4].length);
18904 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 26123 }
18905 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 26124 var dec1 = /^#*0*\.(0+)/;
18906 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 26125 var closeparen = /\).*[0#]/;
18907 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 26126 var phone = /\(###\) ###\\?-####/;
18908 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 26127 function hashq(str) {
18909 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 26128 var o = "", cc;
18910 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 26129 for(var i = 0; i != str.length; ++i) switch((cc=str.charCodeAt(i))) {
18911 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 26130 case 35: break;
18912 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 26131 case 63: o+= " "; break;
18913 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 26132 case 48: o+= "0"; break;
18914 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 26133 default: o+= String.fromCharCode(cc);
18915 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 26134 }
18916 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 26135 return o;
18917 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 26136 }
18918 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 26137 function rnd(val, d) { var dd = Math.pow(10,d); return ""+(Math.round(val * dd)/dd); }
18919 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 26138 function dec(val, d) { return Math.round((val-Math.floor(val))*Math.pow(10,d)); }
18920 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 26139 function flr(val) { if(val < 2147483647 && val > -2147483648) return ""+(val >= 0 ? (val|0) : (val-1|0)); return ""+Math.floor(val); }
18921 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 26140 function write_num_flt(type, fmt, val) {
18922 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 26141 if(type.charCodeAt(0) === 40 && !fmt.match(closeparen)) {
18923 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 26142 var ffmt = fmt.replace(/\( */,"").replace(/ \)/,"").replace(/\)/,"");
18924 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 26143 if(val >= 0) return write_num_flt('n', ffmt, val);
18925 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 26144 return '(' + write_num_flt('n', ffmt, -val) + ')';
18926 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 26145 }
18927 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 26146 if(fmt.charCodeAt(fmt.length - 1) === 44) return write_num_cm(type, fmt, val);
18928 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 26147 if(fmt.indexOf('%') !== -1) return write_num_pct(type, fmt, val);
18929 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 26148 if(fmt.indexOf('E') !== -1) return write_num_exp(fmt, val);
18930 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 26149 if(fmt.charCodeAt(0) === 36) return "$"+write_num_flt(type,fmt.substr(fmt[1]==' '?2:1),val);
18931 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 26150 var o, oo;
18932 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 26151 var r, ri, ff, aval = Math.abs(val), sign = val < 0 ? "-" : "";
18933 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 26152 if(fmt.match(/^00+$/)) return sign + pad0r(aval,fmt.length);
18934 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D 26153 if(fmt.match(/^[#?]+$/)) {
18935 ]; 26154 o = pad0r(val,0); if(o === "0") o = "";
18936 26155 return o.length > fmt.length ? o : hashq(fmt.substr(0,fmt.length-o.length)) + o;
18937 if (typeof(crc) == "undefined") { crc = 0; } 26156 }
18938 var x = 0; 26157 if((r = fmt.match(frac1)) !== null) return write_num_f1(r, aval, sign);
18939 var y = 0; 26158 if(fmt.match(/^#+0+$/) !== null) return sign + pad0r(aval,fmt.length - fmt.indexOf("0"));
18940 26159 if((r = fmt.match(dec1)) !== null) {
18941 crc = crc ^ (-1); 26160 o = rnd(val, r[1].length).replace(/^([^\.]+)$/,"$1."+r[1]).replace(/\.$/,"."+r[1]).replace(/\.(\d*)$/,function($$, $1) { return "." + $1 + fill("0", r[1].length-$1.length); });
18942 for( var i = 0, iTop = str.length; i < iTop; i++ ) { 26161 return fmt.indexOf("0.") !== -1 ? o : o.replace(/^0\./,".");
18943 y = ( crc ^ str.charCodeAt( i ) ) & 0xFF; 26162 }
18944 x = table[y]; 26163 fmt = fmt.replace(/^#+([0.])/, "$1");
18945 crc = ( crc >>> 8 ) ^ x; 26164 if((r = fmt.match(/^(0*)\.(#*)$/)) !== null) {
18946 } 26165 return sign + rnd(aval, r[2].length).replace(/\.(\d*[1-9])0*$/,".$1").replace(/^(-?\d*)$/,"$1.").replace(/^0\./,r[1].length?"0.":".");
18947 26166 }
18948 return crc ^ (-1); 26167 if((r = fmt.match(/^#,##0(\.?)$/)) !== null) return sign + commaify(pad0r(aval,0));
18949 }, 26168 if((r = fmt.match(/^#,##0\.([#0]*0)$/)) !== null) {
18950 26169 return val < 0 ? "-" + write_num_flt(type, fmt, -val) : commaify(""+(Math.floor(val))) + "." + pad0(dec(val, r[1].length),r[1].length);
18951 // Inspired by http://my.opera.com/GreyWyvern/blog/show.dml/1725165 26170 }
18952 clone : function() { 26171 if((r = fmt.match(/^#,#*,#0/)) !== null) return write_num_flt(type,fmt.replace(/^#,#*,/,""),val);
18953 var newObj = new JSZip(); 26172 if((r = fmt.match(/^([0#]+)(\\?-([0#]+))+$/)) !== null) {
18954 for (var i in this) { 26173 o = _strrev(write_num_flt(type, fmt.replace(/[\\-]/g,""), val));
18955 if (typeof this[i] !== "function") { 26174 ri = 0;
18956 newObj[i] = this[i]; 26175 return _strrev(_strrev(fmt.replace(/\\/g,"")).replace(/[0#]/g,function(x){return ri<o.length?o[ri++]:x==='0'?'0':"";}));
18957 } 26176 }
18958 } 26177 if(fmt.match(phone) !== null) {
18959 return newObj; 26178 o = write_num_flt(type, "##########", val);
18960 }, 26179 return "(" + o.substr(0,3) + ") " + o.substr(3, 3) + "-" + o.substr(6);
18961 26180 }
18962 26181 var oa = "";
18963 /** 26182 if((r = fmt.match(/^([#0?]+)( ?)\/( ?)([#0?]+)/)) !== null) {
18964 * http://www.webtoolkit.info/javascript-utf8.html 26183 ri = Math.min(r[4].length,7);
18965 */ 26184 ff = frac(aval, Math.pow(10,ri)-1, false);
18966 utf8encode : function (string) { 26185 o = "" + sign;
18967 string = string.replace(/\r\n/g,"\n"); 26186 oa = write_num("n", r[1], ff[1]);
18968 var utftext = ""; 26187 if(oa[oa.length-1] == " ") oa = oa.substr(0,oa.length-1) + "0";
18969 26188 o += oa + r[2] + "/" + r[3];
18970 for (var n = 0; n < string.length; n++) { 26189 oa = rpad_(ff[2],ri);
18971 26190 if(oa.length < r[4].length) oa = hashq(r[4].substr(r[4].length-oa.length)) + oa;
18972 var c = string.charCodeAt(n); 26191 o += oa;
18973 26192 return o;
18974 if (c < 128) { 26193 }
18975 utftext += String.fromCharCode(c); 26194 if((r = fmt.match(/^# ([#0?]+)( ?)\/( ?)([#0?]+)/)) !== null) {
18976 } else if ((c > 127) && (c < 2048)) { 26195 ri = Math.min(Math.max(r[1].length, r[4].length),7);
18977 utftext += String.fromCharCode((c >> 6) | 192); 26196 ff = frac(aval, Math.pow(10,ri)-1, true);
18978 utftext += String.fromCharCode((c & 63) | 128); 26197 return sign + (ff[0]||(ff[1] ? "" : "0")) + " " + (ff[1] ? pad_(ff[1],ri) + r[2] + "/" + r[3] + rpad_(ff[2],ri): fill(" ", 2*ri+1 + r[2].length + r[3].length));
18979 } else { 26198 }
18980 utftext += String.fromCharCode((c >> 12) | 224); 26199 if((r = fmt.match(/^[#0?]+$/)) !== null) {
18981 utftext += String.fromCharCode(((c >> 6) & 63) | 128); 26200 o = pad0r(val, 0);
18982 utftext += String.fromCharCode((c & 63) | 128); 26201 if(fmt.length <= o.length) return o;
18983 } 26202 return hashq(fmt.substr(0,fmt.length-o.length)) + o;
18984 26203 }
18985 } 26204 if((r = fmt.match(/^([#0?]+)\.([#0]+)$/)) !== null) {
18986 26205 o = "" + val.toFixed(Math.min(r[2].length,10)).replace(/([^0])0+$/,"$1");
18987 return utftext; 26206 ri = o.indexOf(".");
18988 }, 26207 var lres = fmt.indexOf(".") - ri, rres = fmt.length - o.length - lres;
18989 26208 return hashq(fmt.substr(0,lres) + o + fmt.substr(fmt.length-rres));
18990 /** 26209 }
18991 * http://www.webtoolkit.info/javascript-utf8.html 26210 if((r = fmt.match(/^00,000\.([#0]*0)$/)) !== null) {
18992 */ 26211 ri = dec(val, r[1].length);
18993 utf8decode : function (utftext) { 26212 return val < 0 ? "-" + write_num_flt(type, fmt, -val) : commaify(flr(val)).replace(/^\d,\d{3}$/,"0$&").replace(/^\d*$/,function($$) { return "00," + ($$.length < 3 ? pad0(0,3-$$.length) : "") + $$; }) + "." + pad0(ri,r[1].length);
18994 var string = ""; 26213 }
18995 var i = 0; 26214 switch(fmt) {
18996 var c = 0, c1 = 0, c2 = 0, c3 = 0; 26215 case "#,###": var x = commaify(pad0r(aval,0)); return x !== "0" ? sign + x : "";
18997 26216 default:
18998 while ( i < utftext.length ) { 26217 }
18999 26218 throw new Error("unsupported format |" + fmt + "|");
19000 c = utftext.charCodeAt(i); 26219 }
19001 26220 function write_num_cm2(type, fmt, val){
19002 if (c < 128) { 26221 var idx = fmt.length - 1;
19003 string += String.fromCharCode(c); 26222 while(fmt.charCodeAt(idx-1) === 44) --idx;
19004 i++; 26223 return write_num(type, fmt.substr(0,idx), val / Math.pow(10,3*(fmt.length-idx)));
19005 } else if ((c > 191) && (c < 224)) { 26224 }
19006 c2 = utftext.charCodeAt(i+1); 26225 function write_num_pct2(type, fmt, val){
19007 string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); 26226 var sfmt = fmt.replace(pct1,""), mul = fmt.length - sfmt.length;
19008 i += 2; 26227 return write_num(type, sfmt, val * Math.pow(10,2*mul)) + fill("%",mul);
19009 } else { 26228 }
19010 c2 = utftext.charCodeAt(i+1); 26229 function write_num_exp2(fmt, val){
19011 c3 = utftext.charCodeAt(i+2); 26230 var o;
19012 string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); 26231 var idx = fmt.indexOf("E") - fmt.indexOf(".") - 1;
19013 i += 3; 26232 if(fmt.match(/^#+0.0E\+0$/)) {
19014 } 26233 var period = fmt.indexOf("."); if(period === -1) period=fmt.indexOf('E');
19015 26234 var ee = Math.floor(Math.log(Math.abs(val))*Math.LOG10E)%period;
19016 } 26235 if(ee < 0) ee += period;
19017 26236 o = (val/Math.pow(10,ee)).toPrecision(idx+1+(period+ee)%period);
19018 return string; 26237 if(!o.match(/[Ee]/)) {
19019 } 26238 var fakee = Math.floor(Math.log(Math.abs(val))*Math.LOG10E);
19020 }; 26239 if(o.indexOf(".") === -1) o = o[0] + "." + o.substr(1) + "E+" + (fakee - o.length+ee);
19021 }()); 26240 else o += "E+" + (fakee - ee);
19022 26241 o = o.replace(/\+-/,"-");
26242 }
26243 o = o.replace(/^([+-]?)(\d*)\.(\d*)[Ee]/,function($$,$1,$2,$3) { return $1 + $2 + $3.substr(0,(period+ee)%period) + "." + $3.substr(ee) + "E"; });
26244 } else o = val.toExponential(idx);
26245 if(fmt.match(/E\+00$/) && o.match(/e[+-]\d$/)) o = o.substr(0,o.length-1) + "0" + o[o.length-1];
26246 if(fmt.match(/E\-/) && o.match(/e\+/)) o = o.replace(/e\+/,"e");
26247 return o.replace("e","E");
26248 }
26249 function write_num_int(type, fmt, val) {
26250 if(type.charCodeAt(0) === 40 && !fmt.match(closeparen)) {
26251 var ffmt = fmt.replace(/\( */,"").replace(/ \)/,"").replace(/\)/,"");
26252 if(val >= 0) return write_num_int('n', ffmt, val);
26253 return '(' + write_num_int('n', ffmt, -val) + ')';
26254 }
26255 if(fmt.charCodeAt(fmt.length - 1) === 44) return write_num_cm2(type, fmt, val);
26256 if(fmt.indexOf('%') !== -1) return write_num_pct2(type, fmt, val);
26257 if(fmt.indexOf('E') !== -1) return write_num_exp2(fmt, val);
26258 if(fmt.charCodeAt(0) === 36) return "$"+write_num_int(type,fmt.substr(fmt[1]==' '?2:1),val);
26259 var o;
26260 var r, ri, ff, aval = Math.abs(val), sign = val < 0 ? "-" : "";
26261 if(fmt.match(/^00+$/)) return sign + pad0(aval,fmt.length);
26262 if(fmt.match(/^[#?]+$/)) {
26263 o = (""+val); if(val === 0) o = "";
26264 return o.length > fmt.length ? o : hashq(fmt.substr(0,fmt.length-o.length)) + o;
26265 }
26266 if((r = fmt.match(frac1)) !== null) return write_num_f2(r, aval, sign);
26267 if(fmt.match(/^#+0+$/) !== null) return sign + pad0(aval,fmt.length - fmt.indexOf("0"));
26268 if((r = fmt.match(dec1)) !== null) {
26269 o = (""+val).replace(/^([^\.]+)$/,"$1."+r[1]).replace(/\.$/,"."+r[1]).replace(/\.(\d*)$/,function($$, $1) { return "." + $1 + fill("0", r[1].length-$1.length); });
26270 return fmt.indexOf("0.") !== -1 ? o : o.replace(/^0\./,".");
26271 }
26272 fmt = fmt.replace(/^#+([0.])/, "$1");
26273 if((r = fmt.match(/^(0*)\.(#*)$/)) !== null) {
26274 return sign + (""+aval).replace(/\.(\d*[1-9])0*$/,".$1").replace(/^(-?\d*)$/,"$1.").replace(/^0\./,r[1].length?"0.":".");
26275 }
26276 if((r = fmt.match(/^#,##0(\.?)$/)) !== null) return sign + commaify((""+aval));
26277 if((r = fmt.match(/^#,##0\.([#0]*0)$/)) !== null) {
26278 return val < 0 ? "-" + write_num_int(type, fmt, -val) : commaify((""+val)) + "." + fill('0',r[1].length);
26279 }
26280 if((r = fmt.match(/^#,#*,#0/)) !== null) return write_num_int(type,fmt.replace(/^#,#*,/,""),val);
26281 if((r = fmt.match(/^([0#]+)(\\?-([0#]+))+$/)) !== null) {
26282 o = _strrev(write_num_int(type, fmt.replace(/[\\-]/g,""), val));
26283 ri = 0;
26284 return _strrev(_strrev(fmt.replace(/\\/g,"")).replace(/[0#]/g,function(x){return ri<o.length?o[ri++]:x==='0'?'0':"";}));
26285 }
26286 if(fmt.match(phone) !== null) {
26287 o = write_num_int(type, "##########", val);
26288 return "(" + o.substr(0,3) + ") " + o.substr(3, 3) + "-" + o.substr(6);
26289 }
26290 var oa = "";
26291 if((r = fmt.match(/^([#0?]+)( ?)\/( ?)([#0?]+)/)) !== null) {
26292 ri = Math.min(r[4].length,7);
26293 ff = frac(aval, Math.pow(10,ri)-1, false);
26294 o = "" + sign;
26295 oa = write_num("n", r[1], ff[1]);
26296 if(oa[oa.length-1] == " ") oa = oa.substr(0,oa.length-1) + "0";
26297 o += oa + r[2] + "/" + r[3];
26298 oa = rpad_(ff[2],ri);
26299 if(oa.length < r[4].length) oa = hashq(r[4].substr(r[4].length-oa.length)) + oa;
26300 o += oa;
26301 return o;
26302 }
26303 if((r = fmt.match(/^# ([#0?]+)( ?)\/( ?)([#0?]+)/)) !== null) {
26304 ri = Math.min(Math.max(r[1].length, r[4].length),7);
26305 ff = frac(aval, Math.pow(10,ri)-1, true);
26306 return sign + (ff[0]||(ff[1] ? "" : "0")) + " " + (ff[1] ? pad_(ff[1],ri) + r[2] + "/" + r[3] + rpad_(ff[2],ri): fill(" ", 2*ri+1 + r[2].length + r[3].length));
26307 }
26308 if((r = fmt.match(/^[#0?]+$/)) !== null) {
26309 o = "" + val;
26310 if(fmt.length <= o.length) return o;
26311 return hashq(fmt.substr(0,fmt.length-o.length)) + o;
26312 }
26313 if((r = fmt.match(/^([#0]+)\.([#0]+)$/)) !== null) {
26314 o = "" + val.toFixed(Math.min(r[2].length,10)).replace(/([^0])0+$/,"$1");
26315 ri = o.indexOf(".");
26316 var lres = fmt.indexOf(".") - ri, rres = fmt.length - o.length - lres;
26317 return hashq(fmt.substr(0,lres) + o + fmt.substr(fmt.length-rres));
26318 }
26319 if((r = fmt.match(/^00,000\.([#0]*0)$/)) !== null) {
26320 return val < 0 ? "-" + write_num_int(type, fmt, -val) : commaify(""+val).replace(/^\d,\d{3}$/,"0$&").replace(/^\d*$/,function($$) { return "00," + ($$.length < 3 ? pad0(0,3-$$.length) : "") + $$; }) + "." + pad0(0,r[1].length);
26321 }
26322 switch(fmt) {
26323 case "#,###": var x = commaify(""+aval); return x !== "0" ? sign + x : "";
26324 default:
26325 }
26326 throw new Error("unsupported format |" + fmt + "|");
26327 }
26328 return function write_num(type, fmt, val) {
26329 return (val|0) === val ? write_num_int(type, fmt, val) : write_num_flt(type, fmt, val);
26330 };})();
26331 function split_fmt(fmt) {
26332 var out = [];
26333 var in_str = false, cc;
26334 for(var i = 0, j = 0; i < fmt.length; ++i) switch((cc=fmt.charCodeAt(i))) {
26335 case 34: /* '"' */
26336 in_str = !in_str; break;
26337 case 95: case 42: case 92: /* '_' '*' '\\' */
26338 ++i; break;
26339 case 59: /* ';' */
26340 out[out.length] = fmt.substr(j,i-j);
26341 j = i+1;
26342 }
26343 out[out.length] = fmt.substr(j);
26344 if(in_str === true) throw new Error("Format |" + fmt + "| unterminated string ");
26345 return out;
26346 }
26347 SSF._split = split_fmt;
26348 var abstime = /\[[HhMmSs]*\]/;
26349 function eval_fmt(fmt, v, opts, flen) {
26350 var out = [], o = "", i = 0, c = "", lst='t', q, dt, j, cc;
26351 var hr='H';
26352 /* Tokenize */
26353 while(i < fmt.length) {
26354 switch((c = fmt[i])) {
26355 case 'G': /* General */
26356 if(!isgeneral(fmt, i)) throw new Error('unrecognized character ' + c + ' in ' +fmt);
26357 out[out.length] = {t:'G', v:'General'}; i+=7; break;
26358 case '"': /* Literal text */
26359 for(o="";(cc=fmt.charCodeAt(++i)) !== 34 && i < fmt.length;) o += String.fromCharCode(cc);
26360 out[out.length] = {t:'t', v:o}; ++i; break;
26361 case '\\': var w = fmt[++i], t = (w === "(" || w === ")") ? w : 't';
26362 out[out.length] = {t:t, v:w}; ++i; break;
26363 case '_': out[out.length] = {t:'t', v:" "}; i+=2; break;
26364 case '@': /* Text Placeholder */
26365 out[out.length] = {t:'T', v:v}; ++i; break;
26366 case 'B': case 'b':
26367 if(fmt[i+1] === "1" || fmt[i+1] === "2") {
26368 if(dt==null) { dt=parse_date_code(v, opts, fmt[i+1] === "2"); if(dt==null) return ""; }
26369 out[out.length] = {t:'X', v:fmt.substr(i,2)}; lst = c; i+=2; break;
26370 }
26371 /* falls through */
26372 case 'M': case 'D': case 'Y': case 'H': case 'S': case 'E':
26373 c = c.toLowerCase();
26374 /* falls through */
26375 case 'm': case 'd': case 'y': case 'h': case 's': case 'e': case 'g':
26376 if(v < 0) return "";
26377 if(dt==null) { dt=parse_date_code(v, opts); if(dt==null) return ""; }
26378 o = c; while(++i<fmt.length && fmt[i].toLowerCase() === c) o+=c;
26379 if(c === 'm' && lst.toLowerCase() === 'h') c = 'M'; /* m = minute */
26380 if(c === 'h') c = hr;
26381 out[out.length] = {t:c, v:o}; lst = c; break;
26382 case 'A':
26383 q={t:c, v:"A"};
26384 if(dt==null) dt=parse_date_code(v, opts);
26385 if(fmt.substr(i, 3) === "A/P") { if(dt!=null) q.v = dt.H >= 12 ? "P" : "A"; q.t = 'T'; hr='h';i+=3;}
26386 else if(fmt.substr(i,5) === "AM/PM") { if(dt!=null) q.v = dt.H >= 12 ? "PM" : "AM"; q.t = 'T'; i+=5; hr='h'; }
26387 else { q.t = "t"; ++i; }
26388 if(dt==null && q.t === 'T') return "";
26389 out[out.length] = q; lst = c; break;
26390 case '[':
26391 o = c;
26392 while(fmt[i++] !== ']' && i < fmt.length) o += fmt[i];
26393 if(o.substr(-1) !== ']') throw 'unterminated "[" block: |' + o + '|';
26394 if(o.match(abstime)) {
26395 if(dt==null) { dt=parse_date_code(v, opts); if(dt==null) return ""; }
26396 out[out.length] = {t:'Z', v:o.toLowerCase()};
26397 } else { o=""; }
26398 break;
26399 /* Numbers */
26400 case '.':
26401 if(dt != null) {
26402 o = c; while((c=fmt[++i]) === "0") o += c;
26403 out[out.length] = {t:'s', v:o}; break;
26404 }
26405 /* falls through */
26406 case '0': case '#':
26407 o = c; while("0#?.,E+-%".indexOf(c=fmt[++i]) > -1 || c=='\\' && fmt[i+1] == "-" && "0#".indexOf(fmt[i+2])>-1) o += c;
26408 out[out.length] = {t:'n', v:o}; break;
26409 case '?':
26410 o = c; while(fmt[++i] === c) o+=c;
26411 q={t:c, v:o}; out[out.length] = q; lst = c; break;
26412 case '*': ++i; if(fmt[i] == ' ' || fmt[i] == '*') ++i; break; // **
26413 case '(': case ')': out[out.length] = {t:(flen===1?'t':c), v:c}; ++i; break;
26414 case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
26415 o = c; while("0123456789".indexOf(fmt[++i]) > -1) o+=fmt[i];
26416 out[out.length] = {t:'D', v:o}; break;
26417 case ' ': out[out.length] = {t:c, v:c}; ++i; break;
26418 default:
26419 if(",$-+/():!^&'~{}<>=€acfijklopqrtuvwxz".indexOf(c) === -1) throw new Error('unrecognized character ' + c + ' in ' + fmt);
26420 out[out.length] = {t:'t', v:c}; ++i; break;
26421 }
26422 }
26423 var bt = 0, ss0 = 0, ssm;
26424 for(i=out.length-1, lst='t'; i >= 0; --i) {
26425 switch(out[i].t) {
26426 case 'h': case 'H': out[i].t = hr; lst='h'; if(bt < 1) bt = 1; break;
26427 case 's':
26428 if((ssm=out[i].v.match(/\.0+$/))) ss0=Math.max(ss0,ssm[0].length-1);
26429 if(bt < 3) bt = 3;
26430 /* falls through */
26431 case 'd': case 'y': case 'M': case 'e': lst=out[i].t; break;
26432 case 'm': if(lst === 's') { out[i].t = 'M'; if(bt < 2) bt = 2; } break;
26433 case 'X': if(out[i].v === "B2");
26434 break;
26435 case 'Z':
26436 if(bt < 1 && out[i].v.match(/[Hh]/)) bt = 1;
26437 if(bt < 2 && out[i].v.match(/[Mm]/)) bt = 2;
26438 if(bt < 3 && out[i].v.match(/[Ss]/)) bt = 3;
26439 }
26440 }
26441 switch(bt) {
26442 case 0: break;
26443 case 1:
26444 if(dt.u >= 0.5) { dt.u = 0; ++dt.S; }
26445 if(dt.S >= 60) { dt.S = 0; ++dt.M; }
26446 if(dt.M >= 60) { dt.M = 0; ++dt.H; }
26447 break;
26448 case 2:
26449 if(dt.u >= 0.5) { dt.u = 0; ++dt.S; }
26450 if(dt.S >= 60) { dt.S = 0; ++dt.M; }
26451 break;
26452 }
26453 /* replace fields */
26454 var nstr = "", jj;
26455 for(i=0; i < out.length; ++i) {
26456 switch(out[i].t) {
26457 case 't': case 'T': case ' ': case 'D': break;
26458 case 'X': out[i] = undefined; break;
26459 case 'd': case 'm': case 'y': case 'h': case 'H': case 'M': case 's': case 'e': case 'b': case 'Z':
26460 out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0);
26461 out[i].t = 't'; break;
26462 case 'n': case '(': case '?':
26463 jj = i+1;
26464 while(out[jj] != null && (
26465 (c=out[jj].t) === "?" || c === "D" ||
26466 (c === " " || c === "t") && out[jj+1] != null && (out[jj+1].t === '?' || out[jj+1].t === "t" && out[jj+1].v === '/') ||
26467 out[i].t === '(' && (c === ' ' || c === 'n' || c === ')') ||
26468 c === 't' && (out[jj].v === '/' || '$€'.indexOf(out[jj].v) > -1 || out[jj].v === ' ' && out[jj+1] != null && out[jj+1].t == '?')
26469 )) {
26470 out[i].v += out[jj].v;
26471 out[jj] = undefined; ++jj;
26472 }
26473 nstr += out[i].v;
26474 i = jj-1; break;
26475 case 'G': out[i].t = 't'; out[i].v = general_fmt(v,opts); break;
26476 }
26477 }
26478 var vv = "", myv, ostr;
26479 if(nstr.length > 0) {
26480 myv = (v<0&&nstr.charCodeAt(0) === 45 ? -v : v); /* '-' */
26481 ostr = write_num(nstr.charCodeAt(0) === 40 ? '(' : 'n', nstr, myv); /* '(' */
26482 jj=ostr.length-1;
26483 var decpt = out.length;
26484 for(i=0; i < out.length; ++i) if(out[i] != null && out[i].v.indexOf(".") > -1) { decpt = i; break; }
26485 var lasti=out.length;
26486 if(decpt === out.length && ostr.indexOf("E") === -1) {
26487 for(i=out.length-1; i>= 0;--i) {
26488 if(out[i] == null || 'n?('.indexOf(out[i].t) === -1) continue;
26489 if(jj>=out[i].v.length-1) { jj -= out[i].v.length; out[i].v = ostr.substr(jj+1, out[i].v.length); }
26490 else if(jj < 0) out[i].v = "";
26491 else { out[i].v = ostr.substr(0, jj+1); jj = -1; }
26492 out[i].t = 't';
26493 lasti = i;
26494 }
26495 if(jj>=0 && lasti<out.length) out[lasti].v = ostr.substr(0,jj+1) + out[lasti].v;
26496 }
26497 else if(decpt !== out.length && ostr.indexOf("E") === -1) {
26498 jj = ostr.indexOf(".")-1;
26499 for(i=decpt; i>= 0; --i) {
26500 if(out[i] == null || 'n?('.indexOf(out[i].t) === -1) continue;
26501 j=out[i].v.indexOf(".")>-1&&i===decpt?out[i].v.indexOf(".")-1:out[i].v.length-1;
26502 vv = out[i].v.substr(j+1);
26503 for(; j>=0; --j) {
26504 if(jj>=0 && (out[i].v[j] === "0" || out[i].v[j] === "#")) vv = ostr[jj--] + vv;
26505 }
26506 out[i].v = vv;
26507 out[i].t = 't';
26508 lasti = i;
26509 }
26510 if(jj>=0 && lasti<out.length) out[lasti].v = ostr.substr(0,jj+1) + out[lasti].v;
26511 jj = ostr.indexOf(".")+1;
26512 for(i=decpt; i<out.length; ++i) {
26513 if(out[i] == null || 'n?('.indexOf(out[i].t) === -1 && i !== decpt ) continue;
26514 j=out[i].v.indexOf(".")>-1&&i===decpt?out[i].v.indexOf(".")+1:0;
26515 vv = out[i].v.substr(0,j);
26516 for(; j<out[i].v.length; ++j) {
26517 if(jj<ostr.length) vv += ostr[jj++];
26518 }
26519 out[i].v = vv;
26520 out[i].t = 't';
26521 lasti = i;
26522 }
26523 }
26524 }
26525 for(i=0; i<out.length; ++i) if(out[i] != null && 'n(?'.indexOf(out[i].t)>-1) {
26526 myv = (flen >1 && v < 0 && i>0 && out[i-1].v === "-" ? -v:v);
26527 out[i].v = write_num(out[i].t, out[i].v, myv);
26528 out[i].t = 't';
26529 }
26530 var retval = "";
26531 for(i=0; i !== out.length; ++i) if(out[i] != null) retval += out[i].v;
26532 return retval;
26533 }
26534 SSF._eval = eval_fmt;
26535 var cfregex = /\[[=<>]/;
26536 var cfregex2 = /\[([=<>]*)(-?\d+\.?\d*)\]/;
26537 function chkcond(v, rr) {
26538 if(rr == null) return false;
26539 var thresh = parseFloat(rr[2]);
26540 switch(rr[1]) {
26541 case "=": if(v == thresh) return true; break;
26542 case ">": if(v > thresh) return true; break;
26543 case "<": if(v < thresh) return true; break;
26544 case "<>": if(v != thresh) return true; break;
26545 case ">=": if(v >= thresh) return true; break;
26546 case "<=": if(v <= thresh) return true; break;
26547 }
26548 return false;
26549 }
26550 function choose_fmt(f, v) {
26551 var fmt = split_fmt(f);
26552 var l = fmt.length, lat = fmt[l-1].indexOf("@");
26553 if(l<4 && lat>-1) --l;
26554 if(fmt.length > 4) throw "cannot find right format for |" + fmt + "|";
26555 if(typeof v !== "number") return [4, fmt.length === 4 || lat>-1?fmt[fmt.length-1]:"@"];
26556 switch(fmt.length) {
26557 case 1: fmt = lat>-1 ? ["General", "General", "General", fmt[0]] : [fmt[0], fmt[0], fmt[0], "@"]; break;
26558 case 2: fmt = lat>-1 ? [fmt[0], fmt[0], fmt[0], fmt[1]] : [fmt[0], fmt[1], fmt[0], "@"]; break;
26559 case 3: fmt = lat>-1 ? [fmt[0], fmt[1], fmt[0], fmt[2]] : [fmt[0], fmt[1], fmt[2], "@"]; break;
26560 case 4: break;
26561 }
26562 var ff = v > 0 ? fmt[0] : v < 0 ? fmt[1] : fmt[2];
26563 if(fmt[0].indexOf("[") === -1 && fmt[1].indexOf("[") === -1) return [l, ff];
26564 if(fmt[0].match(cfregex) != null || fmt[1].match(cfregex) != null) {
26565 var m1 = fmt[0].match(cfregex2);
26566 var m2 = fmt[1].match(cfregex2);
26567 return chkcond(v, m1) ? [l, fmt[0]] : chkcond(v, m2) ? [l, fmt[1]] : [l, fmt[m1 != null && m2 != null ? 2 : 1]];
26568 }
26569 return [l, ff];
26570 }
26571 function format(fmt,v,o) {
26572 fixopts(o != null ? o : (o=[]));
26573 var sfmt = "";
26574 switch(typeof fmt) {
26575 case "string": sfmt = fmt; break;
26576 case "number": sfmt = (o.table != null ? o.table : table_fmt)[fmt]; break;
26577 }
26578 if(isgeneral(sfmt,0)) return general_fmt(v, o);
26579 var f = choose_fmt(sfmt, v);
26580 if(isgeneral(f[1])) return general_fmt(v, o);
26581 if(v === true) v = "TRUE"; else if(v === false) v = "FALSE";
26582 else if(v === "" || v == null) return "";
26583 return eval_fmt(f[1], v, o, f[0]);
26584 }
26585 SSF._table = table_fmt;
26586 SSF.load = function load_entry(fmt, idx) { table_fmt[idx] = fmt; };
26587 SSF.format = format;
26588 SSF.get_table = function get_table() { return table_fmt; };
26589 SSF.load_table = function load_table(tbl) { for(var i=0; i!=0x0188; ++i) if(tbl[i] !== undefined) SSF.load(tbl[i], i); };
26590 };
26591 make_ssf(SSF);
26592 function isval(x) { return x !== undefined && x !== null; }
26593
26594 function keys(o) { return Object.keys(o); }
26595
26596 function evert_key(obj, key) {
26597 var o = [], K = keys(obj);
26598 for(var i = 0; i !== K.length; ++i) o[obj[K[i]][key]] = K[i];
26599 return o;
26600 }
26601
26602 function evert(obj) {
26603 var o = [], K = keys(obj);
26604 for(var i = 0; i !== K.length; ++i) o[obj[K[i]]] = K[i];
26605 return o;
26606 }
26607
26608 function evert_num(obj) {
26609 var o = [], K = keys(obj);
26610 for(var i = 0; i !== K.length; ++i) o[obj[K[i]]] = parseInt(K[i],10);
26611 return o;
26612 }
26613
26614 function evert_arr(obj) {
26615 var o = [], K = keys(obj);
26616 for(var i = 0; i !== K.length; ++i) {
26617 if(o[obj[K[i]]] == null) o[obj[K[i]]] = [];
26618 o[obj[K[i]]].push(K[i]);
26619 }
26620 return o;
26621 }
26622
26623 /* TODO: date1904 logic */
26624 function datenum(v, date1904) {
26625 if(date1904) v+=1462;
26626 var epoch = Date.parse(v);
26627 return (epoch + 2209161600000) / (24 * 60 * 60 * 1000);
26628 }
26629
26630 function cc2str(arr) {
26631 var o = "";
26632 for(var i = 0; i != arr.length; ++i) o += String.fromCharCode(arr[i]);
26633 return o;
26634 }
26635
26636 var has_buf = (typeof Buffer !== 'undefined');
26637 function getdata(data) {
26638 if(!data) return null;
26639 if(data.name.substr(-4) === ".bin") {
26640 if(data.data) return char_codes(data.data);
26641 if(data.asNodeBuffer && has_buf) return data.asNodeBuffer();
26642 if(data._data && data._data.getContent) return Array.prototype.slice.call(data._data.getContent());
26643 } else {
26644 if(data.data) return data.name.substr(-4) !== ".bin" ? debom_xml(data.data) : char_codes(data.data);
26645 if(data.asNodeBuffer && has_buf) return debom_xml(data.asNodeBuffer().toString('binary'));
26646 if(data.asBinary) return debom_xml(data.asBinary());
26647 if(data._data && data._data.getContent) return debom_xml(cc2str(Array.prototype.slice.call(data._data.getContent(),0)));
26648 }
26649 return null;
26650 }
26651
26652 function getzipfile(zip, file) {
26653 var f = file; if(zip.files[f]) return zip.files[f];
26654 f = file.toLowerCase(); if(zip.files[f]) return zip.files[f];
26655 f = f.replace(/\//g,'\\'); if(zip.files[f]) return zip.files[f];
26656 throw new Error("Cannot find file " + file + " in zip");
26657 }
26658
26659 function getzipdata(zip, file, safe) {
26660 if(!safe) return getdata(getzipfile(zip, file));
26661 if(!file) return null;
26662 try { return getzipdata(zip, file); } catch(e) { return null; }
26663 }
26664
26665 var _fs, jszip;
26666 if(typeof JSZip !== 'undefined') jszip = JSZip;
26667 if (typeof exports !== 'undefined') {
26668 if (typeof module !== 'undefined' && module.exports) {
26669 if(has_buf && typeof jszip === 'undefined') jszip = require('js'+'zip');
26670 if(typeof jszip === 'undefined') jszip = require('./js'+'zip').JSZip;
26671 _fs = require('f'+'s');
26672 }
26673 }
26674 var attregexg=/\b[\w:]+=["'][^"]*['"]/g;
26675 var tagregex=/<[^>]*>/g;
26676 var nsregex=/<\w*:/, nsregex2 = /<(\/?)\w+:/;
26677 function parsexmltag(tag, skip_root) {
26678 var z = [];
26679 var eq = 0, c = 0;
26680 for(; eq !== tag.length; ++eq) if((c = tag.charCodeAt(eq)) === 32 || c === 10 || c === 13) break;
26681 if(!skip_root) z[0] = tag.substr(0, eq);
26682 if(eq === tag.length) return z;
26683 var m = tag.match(attregexg), j=0, w="", v="", i=0, q="", cc="";
26684 if(m) for(i = 0; i != m.length; ++i) {
26685 cc = m[i];
26686 for(c=0; c != cc.length; ++c) if(cc.charCodeAt(c) === 61) break;
26687 q = cc.substr(0,c); v = cc.substring(c+2, cc.length-1);
26688 for(j=0;j!=q.length;++j) if(q.charCodeAt(j) === 58) break;
26689 if(j===q.length) z[q] = v;
26690 else z[(j===5 && q.substr(0,5)==="xmlns"?"xmlns":"")+q.substr(j+1)] = v;
26691 }
26692 return z;
26693 }
26694 function strip_ns(x) { return x.replace(nsregex2, "<$1"); }
26695
26696 var encodings = {
26697 '&quot;': '"',
26698 '&apos;': "'",
26699 '&gt;': '>',
26700 '&lt;': '<',
26701 '&amp;': '&'
26702 };
26703 var rencoding = evert(encodings);
26704 var rencstr = "&<>'\"".split("");
26705
26706 // TODO: CP remap (need to read file version to determine OS)
26707 var encregex = /&[a-z]*;/g, coderegex = /_x([\da-fA-F]+)_/g;
26708 function unescapexml(text){
26709 var s = text + '';
26710 return s.replace(encregex, function($$) { return encodings[$$]; }).replace(coderegex,function(m,c) {return String.fromCharCode(parseInt(c,16));});
26711 }
26712 var decregex=/[&<>'"]/g, charegex = /[\u0000-\u0008\u000b-\u001f]/g;
26713 function escapexml(text){
26714 var s = text + '';
26715 return s.replace(decregex, function(y) { return rencoding[y]; }).replace(charegex,function(s) { return "_x" + ("000"+s.charCodeAt(0).toString(16)).substr(-4) + "_";});
26716 }
26717
26718 function parsexmlbool(value, tag) {
26719 switch(value) {
26720 case '1': case 'true': case 'TRUE': return true;
26721 /* case '0': case 'false': case 'FALSE':*/
26722 default: return false;
26723 }
26724 }
26725
26726 var utf8read = function utf8reada(orig) {
26727 var out = "", i = 0, c = 0, d = 0, e = 0, f = 0, w = 0;
26728 while (i < orig.length) {
26729 c = orig.charCodeAt(i++);
26730 if (c < 128) { out += String.fromCharCode(c); continue; }
26731 d = orig.charCodeAt(i++);
26732 if (c>191 && c<224) { out += String.fromCharCode(((c & 31) << 6) | (d & 63)); continue; }
26733 e = orig.charCodeAt(i++);
26734 if (c < 240) { out += String.fromCharCode(((c & 15) << 12) | ((d & 63) << 6) | (e & 63)); continue; }
26735 f = orig.charCodeAt(i++);
26736 w = (((c & 7) << 18) | ((d & 63) << 12) | ((e & 63) << 6) | (f & 63))-65536;
26737 out += String.fromCharCode(0xD800 + ((w>>>10)&1023));
26738 out += String.fromCharCode(0xDC00 + (w&1023));
26739 }
26740 return out;
26741 };
26742
26743
26744 if(has_buf) {
26745 var utf8readb = function utf8readb(data) {
26746 var out = new Buffer(2*data.length), w, i, j = 1, k = 0, ww=0, c;
26747 for(i = 0; i < data.length; i+=j) {
26748 j = 1;
26749 if((c=data.charCodeAt(i)) < 128) w = c;
26750 else if(c < 224) { w = (c&31)*64+(data.charCodeAt(i+1)&63); j=2; }
26751 else if(c < 240) { w=(c&15)*4096+(data.charCodeAt(i+1)&63)*64+(data.charCodeAt(i+2)&63); j=3; }
26752 else { j = 4;
26753 w = (c & 7)*262144+(data.charCodeAt(i+1)&63)*4096+(data.charCodeAt(i+2)&63)*64+(data.charCodeAt(i+3)&63);
26754 w -= 65536; ww = 0xD800 + ((w>>>10)&1023); w = 0xDC00 + (w&1023);
26755 }
26756 if(ww !== 0) { out[k++] = ww&255; out[k++] = ww>>>8; ww = 0; }
26757 out[k++] = w%256; out[k++] = w>>>8;
26758 }
26759 out.length = k;
26760 return out.toString('ucs2');
26761 };
26762 var corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3";
26763 if(utf8read(corpus) == utf8readb(corpus)) utf8read = utf8readb;
26764 var utf8readc = function utf8readc(data) { return Buffer(data, 'binary').toString('utf8'); };
26765 if(utf8read(corpus) == utf8readc(corpus)) utf8read = utf8readc;
26766 }
26767
26768 // matches <foo>...</foo> extracts content
26769 var matchtag = (function() {
26770 var mtcache = {};
26771 return function matchtag(f,g) {
26772 var t = f+"|"+g;
26773 if(mtcache[t] !== undefined) return mtcache[t];
26774 return (mtcache[t] = new RegExp('<(?:\\w+:)?'+f+'(?: xml:space="preserve")?(?:[^>]*)>([^\u2603]*)</(?:\\w+:)?'+f+'>',(g||"")));
26775 };
26776 })();
26777
26778 var vtregex = (function(){ var vt_cache = {};
26779 return function vt_regex(bt) {
26780 if(vt_cache[bt] !== undefined) return vt_cache[bt];
26781 return (vt_cache[bt] = new RegExp("<vt:" + bt + ">(.*?)</vt:" + bt + ">", 'g') );
26782 };})();
26783 var vtvregex = /<\/?vt:variant>/g, vtmregex = /<vt:([^>]*)>(.*)</;
26784 function parseVector(data) {
26785 var h = parsexmltag(data);
26786
26787 var matches = data.match(vtregex(h.baseType))||[];
26788 if(matches.length != h.size) throw "unexpected vector length " + matches.length + " != " + h.size;
26789 var res = [];
26790 matches.forEach(function(x) {
26791 var v = x.replace(vtvregex,"").match(vtmregex);
26792 res.push({v:v[2], t:v[1]});
26793 });
26794 return res;
26795 }
26796
26797 var wtregex = /(^\s|\s$|\n)/;
26798 function writetag(f,g) {return '<' + f + (g.match(wtregex)?' xml:space="preserve"' : "") + '>' + g + '</' + f + '>';}
26799
26800 function wxt_helper(h) { return keys(h).map(function(k) { return " " + k + '="' + h[k] + '"';}).join(""); }
26801 function writextag(f,g,h) { return '<' + f + (isval(h) ? wxt_helper(h) : "") + (isval(g) ? (g.match(wtregex)?' xml:space="preserve"' : "") + '>' + g + '</' + f : "/") + '>';}
26802
26803 function write_w3cdtf(d, t) { try { return d.toISOString().replace(/\.\d*/,""); } catch(e) { if(t) throw e; } }
26804
26805 function write_vt(s) {
26806 switch(typeof s) {
26807 case 'string': return writextag('vt:lpwstr', s);
26808 case 'number': return writextag((s|0)==s?'vt:i4':'vt:r8', String(s));
26809 case 'boolean': return writextag('vt:bool',s?'true':'false');
26810 }
26811 if(s instanceof Date) return writextag('vt:filetime', write_w3cdtf(s));
26812 throw new Error("Unable to serialize " + s);
26813 }
26814
26815 var XML_HEADER = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n';
26816 var XMLNS = {
26817 'dc': 'http://purl.org/dc/elements/1.1/',
26818 'dcterms': 'http://purl.org/dc/terms/',
26819 'dcmitype': 'http://purl.org/dc/dcmitype/',
26820 'mx': 'http://schemas.microsoft.com/office/mac/excel/2008/main',
26821 'r': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships',
26822 'sjs': 'http://schemas.openxmlformats.org/package/2006/sheetjs/core-properties',
26823 'vt': 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes',
26824 'xsi': 'http://www.w3.org/2001/XMLSchema-instance',
26825 'xsd': 'http://www.w3.org/2001/XMLSchema'
26826 };
26827
26828 XMLNS.main = [
26829 'http://schemas.openxmlformats.org/spreadsheetml/2006/main',
26830 'http://purl.oclc.org/ooxml/spreadsheetml/main',
26831 'http://schemas.microsoft.com/office/excel/2006/main',
26832 'http://schemas.microsoft.com/office/excel/2006/2'
26833 ];
26834 function readIEEE754(buf, idx, isLE, nl, ml) {
26835 if(isLE === undefined) isLE = true;
26836 if(!nl) nl = 8;
26837 if(!ml && nl === 8) ml = 52;
26838 var e, m, el = nl * 8 - ml - 1, eMax = (1 << el) - 1, eBias = eMax >> 1;
26839 var bits = -7, d = isLE ? -1 : 1, i = isLE ? (nl - 1) : 0, s = buf[idx + i];
26840
26841 i += d;
26842 e = s & ((1 << (-bits)) - 1); s >>>= (-bits); bits += el;
26843 for (; bits > 0; e = e * 256 + buf[idx + i], i += d, bits -= 8);
26844 m = e & ((1 << (-bits)) - 1); e >>>= (-bits); bits += ml;
26845 for (; bits > 0; m = m * 256 + buf[idx + i], i += d, bits -= 8);
26846 if (e === eMax) return m ? NaN : ((s ? -1 : 1) * Infinity);
26847 else if (e === 0) e = 1 - eBias;
26848 else { m = m + Math.pow(2, ml); e = e - eBias; }
26849 return (s ? -1 : 1) * m * Math.pow(2, e - ml);
26850 }
26851
26852 var __toBuffer, ___toBuffer;
26853 __toBuffer = ___toBuffer = function toBuffer_(bufs) { var x = []; for(var i = 0; i < bufs[0].length; ++i) { x.push.apply(x, bufs[0][i]); } return x; };
26854 var __double, ___double;
26855 __double = ___double = function(b, idx) { return readIEEE754(b, idx);};
26856
26857 var is_buf = function is_buf_a(a) { return Array.isArray(a); };
26858 if(has_buf) {
26859 __toBuffer = function(bufs) { return (bufs[0].length > 0 && Buffer.isBuffer(bufs[0][0])) ? Buffer.concat(bufs[0]) : ___toBuffer(bufs);};
26860 __double = function double_(b,i) { if(Buffer.isBuffer(b)) return b.readDoubleLE(i); return ___double(b,i); };
26861 is_buf = function is_buf_b(a) { return Buffer.isBuffer(a) || Array.isArray(a); };
26862 }
26863
26864
26865 var __readUInt8 = function(b, idx) { return b[idx]; };
26866 var __readUInt16LE = function(b, idx) { return b[idx+1]*(1<<8)+b[idx]; };
26867 var __readInt16LE = function(b, idx) { var u = b[idx+1]*(1<<8)+b[idx]; return (u < 0x8000) ? u : (0xffff - u + 1) * -1; };
26868 var __readUInt32LE = function(b, idx) { return b[idx+3]*(1<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]; };
26869 var __readInt32LE = function(b, idx) { return (b[idx+3]<<24)|(b[idx+2]<<16)|(b[idx+1]<<8)|b[idx]; };
26870
26871
26872 function ReadShift(size, t) {
26873 var o="", oo=[], w, vv, i, loc;
26874 if(t === 'dbcs') {
26875 loc = this.l;
26876 if(has_buf && Buffer.isBuffer(this)) o = this.slice(this.l, this.l+2*size).toString("utf16le");
26877 else for(i = 0; i != size; ++i) { o+=String.fromCharCode(__readUInt16LE(this, loc)); loc+=2; }
26878 size *= 2;
26879 } else switch(size) {
26880 case 1: o = __readUInt8(this, this.l); break;
26881 case 2: o = (t === 'i' ? __readInt16LE : __readUInt16LE)(this, this.l); break;
26882 case 4: o = __readUInt32LE(this, this.l); break;
26883 case 8: if(t === 'f') { o = __double(this, this.l); break; }
26884 }
26885 this.l+=size; return o;
26886 }
26887
26888 function WriteShift(t, val, f) {
26889 var size, i;
26890 if(f === 'dbcs') {
26891 for(i = 0; i != val.length; ++i) this.writeUInt16LE(val.charCodeAt(i), this.l + 2 * i);
26892 size = 2 * val.length;
26893 } else switch(t) {
26894 case 1: size = 1; this[this.l] = val&255; break;
26895 case 3: size = 3; this[this.l+2] = val & 255; val >>>= 8; this[this.l+1] = val&255; val >>>= 8; this[this.l] = val&255; break;
26896 case 4: size = 4; this.writeUInt32LE(val, this.l); break;
26897 case 8: size = 8; if(f === 'f') { this.writeDoubleLE(val, this.l); break; }
26898 /* falls through */
26899 case 16: break;
26900 case -4: size = 4; this.writeInt32LE(val, this.l); break;
26901 }
26902 this.l += size; return this;
26903 }
26904
26905 function prep_blob(blob, pos) {
26906 blob.l = pos;
26907 blob.read_shift = ReadShift;
26908 blob.write_shift = WriteShift;
26909 }
26910
26911 function parsenoop(blob, length) { blob.l += length; }
26912
26913 function writenoop(blob, length) { blob.l += length; }
26914
26915 function new_buf(sz) {
26916 var o = has_buf ? new Buffer(sz) : new Array(sz);
26917 prep_blob(o, 0);
26918 return o;
26919 }
26920
26921 /* [MS-XLSB] 2.1.4 Record */
26922 function recordhopper(data, cb, opts) {
26923 var tmpbyte, cntbyte, length;
26924 prep_blob(data, data.l || 0);
26925 while(data.l < data.length) {
26926 var RT = data.read_shift(1);
26927 if(RT & 0x80) RT = (RT & 0x7F) + ((data.read_shift(1) & 0x7F)<<7);
26928 var R = RecordEnum[RT] || RecordEnum[0xFFFF];
26929 tmpbyte = data.read_shift(1);
26930 length = tmpbyte & 0x7F;
26931 for(cntbyte = 1; cntbyte <4 && (tmpbyte & 0x80); ++cntbyte) length += ((tmpbyte = data.read_shift(1)) & 0x7F)<<(7*cntbyte);
26932 var d = R.f(data, length, opts);
26933 if(cb(d, R, RT)) return;
26934 }
26935 }
26936
26937 /* control buffer usage for fixed-length buffers */
26938 function buf_array() {
26939 var bufs = [], blksz = 2048;
26940 var newblk = function ba_newblk(sz) {
26941 var o = new_buf(sz);
26942 prep_blob(o, 0);
26943 return o;
26944 };
26945
26946 var curbuf = newblk(blksz);
26947
26948 var endbuf = function ba_endbuf() {
26949 curbuf.length = curbuf.l;
26950 if(curbuf.length > 0) bufs.push(curbuf);
26951 curbuf = null;
26952 };
26953
26954 var next = function ba_next(sz) {
26955 if(sz < curbuf.length - curbuf.l) return curbuf;
26956 endbuf();
26957 return (curbuf = newblk(Math.max(sz+1, blksz)));
26958 };
26959
26960 var end = function ba_end() {
26961 endbuf();
26962 return __toBuffer([bufs]);
26963 };
26964
26965 var push = function ba_push(buf) { endbuf(); curbuf = buf; next(blksz); };
26966
26967 return { next:next, push:push, end:end, _bufs:bufs };
26968 }
26969
26970 function write_record(ba, type, payload, length) {
26971 var t = evert_RE[type], l;
26972 if(!length) length = RecordEnum[t].p || (payload||[]).length || 0;
26973 l = 1 + (t >= 0x80 ? 1 : 0) + 1 + length;
26974 if(length >= 0x80) ++l; if(length >= 0x4000) ++l; if(length >= 0x200000) ++l;
26975 var o = ba.next(l);
26976 if(t <= 0x7F) o.write_shift(1, t);
26977 else {
26978 o.write_shift(1, (t & 0x7F) + 0x80);
26979 o.write_shift(1, (t >> 7));
26980 }
26981 for(var i = 0; i != 4; ++i) {
26982 if(length >= 0x80) { o.write_shift(1, (length & 0x7F)+0x80); length >>= 7; }
26983 else { o.write_shift(1, length); break; }
26984 }
26985 if(length > 0 && is_buf(payload)) ba.push(payload);
26986 }
26987
26988 /* [MS-XLSB] 2.5.143 */
26989 function parse_StrRun(data, length) {
26990 return { ich: data.read_shift(2), ifnt: data.read_shift(2) };
26991 }
26992
26993 /* [MS-XLSB] 2.1.7.121 */
26994 function parse_RichStr(data, length) {
26995 var start = data.l;
26996 var flags = data.read_shift(1);
26997 var str = parse_XLWideString(data);
26998 var rgsStrRun = [];
26999 var z = { t: str, h: str };
27000 if((flags & 1) !== 0) { /* fRichStr */
27001 /* TODO: formatted string */
27002 var dwSizeStrRun = data.read_shift(4);
27003 for(var i = 0; i != dwSizeStrRun; ++i) rgsStrRun.push(parse_StrRun(data));
27004 z.r = rgsStrRun;
27005 }
27006 else z.r = "<t>" + escapexml(str) + "</t>";
27007 if((flags & 2) !== 0) { /* fExtStr */
27008 /* TODO: phonetic string */
27009 }
27010 data.l = start + length;
27011 return z;
27012 }
27013 function write_RichStr(str, o) {
27014 /* TODO: formatted string */
27015 if(o == null) o = new_buf(5+2*str.t.length);
27016 o.write_shift(1,0);
27017 write_XLWideString(str.t, o);
27018 return o;
27019 }
27020
27021 /* [MS-XLSB] 2.5.9 */
27022 function parse_Cell(data) {
27023 var col = data.read_shift(4);
27024 var iStyleRef = data.read_shift(2);
27025 iStyleRef += data.read_shift(1) <<16;
27026 var fPhShow = data.read_shift(1);
27027 return { c:col, iStyleRef: iStyleRef };
27028 }
27029 function write_Cell(cell, o) {
27030 if(o == null) o = new_buf(8);
27031 o.write_shift(-4, cell.c);
27032 o.write_shift(3, cell.iStyleRef === undefined ? cell.iStyleRef : cell.s);
27033 o.write_shift(1, 0); /* fPhShow */
27034 return o;
27035 }
27036
27037
27038 /* [MS-XLSB] 2.5.21 */
27039 function parse_CodeName (data, length) { return parse_XLWideString(data, length); }
27040
27041 /* [MS-XLSB] 2.5.166 */
27042 function parse_XLNullableWideString(data) {
27043 var cchCharacters = data.read_shift(4);
27044 return cchCharacters === 0 || cchCharacters === 0xFFFFFFFF ? "" : data.read_shift(cchCharacters, 'dbcs');
27045 }
27046 function write_XLNullableWideString(data, o) {
27047 if(!o) o = new_buf(127);
27048 o.write_shift(4, data.length > 0 ? data.length : 0xFFFFFFFF);
27049 if(data.length > 0) o.write_shift(0, data, 'dbcs');
27050 return o;
27051 }
27052
27053 /* [MS-XLSB] 2.5.168 */
27054 function parse_XLWideString(data) {
27055 var cchCharacters = data.read_shift(4);
27056 return cchCharacters === 0 ? "" : data.read_shift(cchCharacters, 'dbcs');
27057 }
27058 function write_XLWideString(data, o) {
27059 if(o == null) o = new_buf(4+2*data.length);
27060 o.write_shift(4, data.length);
27061 if(data.length > 0) o.write_shift(0, data, 'dbcs');
27062 return o;
27063 }
27064
27065 /* [MS-XLSB] 2.5.114 */
27066 var parse_RelID = parse_XLNullableWideString;
27067 var write_RelID = write_XLNullableWideString;
27068
27069
27070 /* [MS-XLSB] 2.5.122 */
27071 function parse_RkNumber(data) {
27072 var b = data.slice(data.l, data.l+4);
27073 var fX100 = b[0] & 1, fInt = b[0] & 2;
27074 data.l+=4;
27075 b[0] &= 0xFC;
27076 var RK = fInt === 0 ? __double([0,0,0,0,b[0],b[1],b[2],b[3]],0) : __readInt32LE(b,0)>>2;
27077 return fX100 ? RK/100 : RK;
27078 }
27079
27080 /* [MS-XLSB] 2.5.153 */
27081 function parse_UncheckedRfX(data) {
27082 var cell = {s: {}, e: {}};
27083 cell.s.r = data.read_shift(4);
27084 cell.e.r = data.read_shift(4);
27085 cell.s.c = data.read_shift(4);
27086 cell.e.c = data.read_shift(4);
27087 return cell;
27088 }
27089
27090 function write_UncheckedRfX(r, o) {
27091 if(!o) o = new_buf(16);
27092 o.write_shift(4, r.s.r);
27093 o.write_shift(4, r.e.r);
27094 o.write_shift(4, r.s.c);
27095 o.write_shift(4, r.e.c);
27096 return o;
27097 }
27098
27099 /* [MS-XLSB] 2.5.171 */
27100 function parse_Xnum(data, length) { return data.read_shift(8, 'f'); }
27101 function write_Xnum(data, o) { return (o || new_buf(8)).write_shift(8, 'f', data); }
27102
27103 /* [MS-XLSB] 2.5.198.2 */
27104 var BErr = {
27105 0x00: "#NULL!",
27106 0x07: "#DIV/0!",
27107 0x0F: "#VALUE!",
27108 0x17: "#REF!",
27109 0x1D: "#NAME?",
27110 0x24: "#NUM!",
27111 0x2A: "#N/A",
27112 0x2B: "#GETTING_DATA",
27113 0xFF: "#WTF?"
27114 };
27115 var RBErr = evert_num(BErr);
27116
27117 /* [MS-XLSB] 2.4.321 BrtColor */
27118 function parse_BrtColor(data, length) {
27119 var out = {};
27120 var d = data.read_shift(1);
27121 out.fValidRGB = d & 1;
27122 out.xColorType = d >>> 1;
27123 out.index = data.read_shift(1);
27124 out.nTintAndShade = data.read_shift(2, 'i');
27125 out.bRed = data.read_shift(1);
27126 out.bGreen = data.read_shift(1);
27127 out.bBlue = data.read_shift(1);
27128 out.bAlpha = data.read_shift(1);
27129 }
27130
27131 /* [MS-XLSB] 2.5.52 */
27132 function parse_FontFlags(data, length) {
27133 var d = data.read_shift(1);
27134 data.l++;
27135 var out = {
27136 fItalic: d & 0x2,
27137 fStrikeout: d & 0x8,
27138 fOutline: d & 0x10,
27139 fShadow: d & 0x20,
27140 fCondense: d & 0x40,
27141 fExtend: d & 0x80
27142 };
27143 return out;
27144 }
27145 /* Parts enumerated in OPC spec, MS-XLSB and MS-XLSX */
27146 /* 12.3 Part Summary <SpreadsheetML> */
27147 /* 14.2 Part Summary <DrawingML> */
27148 /* [MS-XLSX] 2.1 Part Enumerations */
27149 /* [MS-XLSB] 2.1.7 Part Enumeration */
27150 var ct2type = {
27151 /* Workbook */
27152 "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml": "workbooks",
27153
27154 /* Worksheet */
27155 "application/vnd.ms-excel.binIndexWs": "TODO", /* Binary Index */
27156
27157 /* Chartsheet */
27158 "application/vnd.ms-excel.chartsheet": "TODO",
27159 "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml": "TODO",
27160
27161 /* Dialogsheet */
27162 "application/vnd.ms-excel.dialogsheet": "TODO",
27163 "application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml": "TODO",
27164
27165 /* Macrosheet */
27166 "application/vnd.ms-excel.macrosheet": "TODO",
27167 "application/vnd.ms-excel.macrosheet+xml": "TODO",
27168 "application/vnd.ms-excel.intlmacrosheet": "TODO",
27169 "application/vnd.ms-excel.binIndexMs": "TODO", /* Binary Index */
27170
27171 /* File Properties */
27172 "application/vnd.openxmlformats-package.core-properties+xml": "coreprops",
27173 "application/vnd.openxmlformats-officedocument.custom-properties+xml": "custprops",
27174 "application/vnd.openxmlformats-officedocument.extended-properties+xml": "extprops",
27175
27176 /* Custom Data Properties */
27177 "application/vnd.openxmlformats-officedocument.customXmlProperties+xml": "TODO",
27178
27179 /* Comments */
27180 "application/vnd.ms-excel.comments": "comments",
27181 "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml": "comments",
27182
27183 /* PivotTable */
27184 "application/vnd.ms-excel.pivotTable": "TODO",
27185 "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml": "TODO",
27186
27187 /* Calculation Chain */
27188 "application/vnd.ms-excel.calcChain": "calcchains",
27189 "application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml": "calcchains",
27190
27191 /* Printer Settings */
27192 "application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings": "TODO",
27193
27194 /* ActiveX */
27195 "application/vnd.ms-office.activeX": "TODO",
27196 "application/vnd.ms-office.activeX+xml": "TODO",
27197
27198 /* Custom Toolbars */
27199 "application/vnd.ms-excel.attachedToolbars": "TODO",
27200
27201 /* External Data Connections */
27202 "application/vnd.ms-excel.connections": "TODO",
27203 "application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml": "TODO",
27204
27205 /* External Links */
27206 "application/vnd.ms-excel.externalLink": "TODO",
27207 "application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml": "TODO",
27208
27209 /* Metadata */
27210 "application/vnd.ms-excel.sheetMetadata": "TODO",
27211 "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml": "TODO",
27212
27213 /* PivotCache */
27214 "application/vnd.ms-excel.pivotCacheDefinition": "TODO",
27215 "application/vnd.ms-excel.pivotCacheRecords": "TODO",
27216 "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheDefinition+xml": "TODO",
27217 "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheRecords+xml": "TODO",
27218
27219 /* Query Table */
27220 "application/vnd.ms-excel.queryTable": "TODO",
27221 "application/vnd.openxmlformats-officedocument.spreadsheetml.queryTable+xml": "TODO",
27222
27223 /* Shared Workbook */
27224 "application/vnd.ms-excel.userNames": "TODO",
27225 "application/vnd.ms-excel.revisionHeaders": "TODO",
27226 "application/vnd.ms-excel.revisionLog": "TODO",
27227 "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionHeaders+xml": "TODO",
27228 "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionLog+xml": "TODO",
27229 "application/vnd.openxmlformats-officedocument.spreadsheetml.userNames+xml": "TODO",
27230
27231 /* Single Cell Table */
27232 "application/vnd.ms-excel.tableSingleCells": "TODO",
27233 "application/vnd.openxmlformats-officedocument.spreadsheetml.tableSingleCells+xml": "TODO",
27234
27235 /* Slicer */
27236 "application/vnd.ms-excel.slicer": "TODO",
27237 "application/vnd.ms-excel.slicerCache": "TODO",
27238 "application/vnd.ms-excel.slicer+xml": "TODO",
27239 "application/vnd.ms-excel.slicerCache+xml": "TODO",
27240
27241 /* Sort Map */
27242 "application/vnd.ms-excel.wsSortMap": "TODO",
27243
27244 /* Table */
27245 "application/vnd.ms-excel.table": "TODO",
27246 "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml": "TODO",
27247
27248 /* Themes */
27249 "application/vnd.openxmlformats-officedocument.theme+xml": "themes",
27250
27251 /* Timeline */
27252 "application/vnd.ms-excel.Timeline+xml": "TODO", /* verify */
27253 "application/vnd.ms-excel.TimelineCache+xml": "TODO", /* verify */
27254
27255 /* VBA */
27256 "application/vnd.ms-office.vbaProject": "vba",
27257 "application/vnd.ms-office.vbaProjectSignature": "vba",
27258
27259 /* Volatile Dependencies */
27260 "application/vnd.ms-office.volatileDependencies": "TODO",
27261 "application/vnd.openxmlformats-officedocument.spreadsheetml.volatileDependencies+xml": "TODO",
27262
27263 /* Control Properties */
27264 "application/vnd.ms-excel.controlproperties+xml": "TODO",
27265
27266 /* Data Model */
27267 "application/vnd.openxmlformats-officedocument.model+data": "TODO",
27268
27269 /* Survey */
27270 "application/vnd.ms-excel.Survey+xml": "TODO",
27271
27272 /* Drawing */
27273 "application/vnd.openxmlformats-officedocument.drawing+xml": "TODO",
27274 "application/vnd.openxmlformats-officedocument.drawingml.chart+xml": "TODO",
27275 "application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml": "TODO",
27276 "application/vnd.openxmlformats-officedocument.drawingml.diagramColors+xml": "TODO",
27277 "application/vnd.openxmlformats-officedocument.drawingml.diagramData+xml": "TODO",
27278 "application/vnd.openxmlformats-officedocument.drawingml.diagramLayout+xml": "TODO",
27279 "application/vnd.openxmlformats-officedocument.drawingml.diagramStyle+xml": "TODO",
27280
27281 /* VML */
27282 "application/vnd.openxmlformats-officedocument.vmlDrawing": "TODO",
27283
27284 "application/vnd.openxmlformats-package.relationships+xml": "rels",
27285 "application/vnd.openxmlformats-officedocument.oleObject": "TODO",
27286
27287 "sheet": "js"
27288 };
27289
27290 var CT_LIST = (function(){
27291 var o = {
27292 workbooks: {
27293 xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml",
27294 xlsm: "application/vnd.ms-excel.sheet.macroEnabled.main+xml",
27295 xlsb: "application/vnd.ms-excel.sheet.binary.macroEnabled.main",
27296 xltx: "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml"
27297 },
27298 strs: { /* Shared Strings */
27299 xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml",
27300 xlsb: "application/vnd.ms-excel.sharedStrings"
27301 },
27302 sheets: {
27303 xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml",
27304 xlsb: "application/vnd.ms-excel.worksheet"
27305 },
27306 styles: {/* Styles */
27307 xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
27308 xlsb: "application/vnd.ms-excel.styles"
27309 }
27310 };
27311 keys(o).forEach(function(k) { if(!o[k].xlsm) o[k].xlsm = o[k].xlsx; });
27312 keys(o).forEach(function(k){ keys(o[k]).forEach(function(v) { ct2type[o[k][v]] = k; }); });
27313 return o;
27314 })();
27315
27316 var type2ct = evert_arr(ct2type);
27317
27318 XMLNS.CT = 'http://schemas.openxmlformats.org/package/2006/content-types';
27319
27320 function parse_ct(data, opts) {
27321 var ctext = {};
27322 if(!data || !data.match) return data;
27323 var ct = { workbooks: [], sheets: [], calcchains: [], themes: [], styles: [],
27324 coreprops: [], extprops: [], custprops: [], strs:[], comments: [], vba: [],
27325 TODO:[], rels:[], xmlns: "" };
27326 (data.match(tagregex)||[]).forEach(function(x) {
27327 var y = parsexmltag(x);
27328 switch(y[0].replace(nsregex,"<")) {
27329 case '<?xml': break;
27330 case '<Types': ct.xmlns = y['xmlns' + (y[0].match(/<(\w+):/)||["",""])[1] ]; break;
27331 case '<Default': ctext[y.Extension] = y.ContentType; break;
27332 case '<Override':
27333 if(ct[ct2type[y.ContentType]] !== undefined) ct[ct2type[y.ContentType]].push(y.PartName);
27334 else if(opts.WTF) console.error(y);
27335 break;
27336 }
27337 });
27338 if(ct.xmlns !== XMLNS.CT) throw new Error("Unknown Namespace: " + ct.xmlns);
27339 ct.calcchain = ct.calcchains.length > 0 ? ct.calcchains[0] : "";
27340 ct.sst = ct.strs.length > 0 ? ct.strs[0] : "";
27341 ct.style = ct.styles.length > 0 ? ct.styles[0] : "";
27342 ct.defaults = ctext;
27343 delete ct.calcchains;
27344 return ct;
27345 }
27346
27347 var CTYPE_XML_ROOT = writextag('Types', null, {
27348 'xmlns': XMLNS.CT,
27349 'xmlns:xsd': XMLNS.xsd,
27350 'xmlns:xsi': XMLNS.xsi
27351 });
27352
27353 var CTYPE_DEFAULTS = [
27354 ['xml', 'application/xml'],
27355 ['bin', 'application/vnd.ms-excel.sheet.binary.macroEnabled.main'],
27356 ['rels', type2ct.rels[0]]
27357 ].map(function(x) {
27358 return writextag('Default', null, {'Extension':x[0], 'ContentType': x[1]});
27359 });
27360
27361 function write_ct(ct, opts) {
27362 var o = [], v;
27363 o[o.length] = (XML_HEADER);
27364 o[o.length] = (CTYPE_XML_ROOT);
27365 o = o.concat(CTYPE_DEFAULTS);
27366 var f1 = function(w) {
27367 if(ct[w] && ct[w].length > 0) {
27368 v = ct[w][0];
27369 o[o.length] = (writextag('Override', null, {
27370 'PartName': (v[0] == '/' ? "":"/") + v,
27371 'ContentType': CT_LIST[w][opts.bookType || 'xlsx']
27372 }));
27373 }
27374 };
27375 var f2 = function(w) {
27376 ct[w].forEach(function(v) {
27377 o[o.length] = (writextag('Override', null, {
27378 'PartName': (v[0] == '/' ? "":"/") + v,
27379 'ContentType': CT_LIST[w][opts.bookType || 'xlsx']
27380 }));
27381 });
27382 };
27383 var f3 = function(t) {
27384 (ct[t]||[]).forEach(function(v) {
27385 o[o.length] = (writextag('Override', null, {
27386 'PartName': (v[0] == '/' ? "":"/") + v,
27387 'ContentType': type2ct[t][0]
27388 }));
27389 });
27390 };
27391 f1('workbooks');
27392 f2('sheets');
27393 f3('themes');
27394 ['strs', 'styles'].forEach(f1);
27395 ['coreprops', 'extprops', 'custprops'].forEach(f3);
27396 if(o.length>2){ o[o.length] = ('</Types>'); o[1]=o[1].replace("/>",">"); }
27397 return o.join("");
27398 }
27399 /* 9.3.2 OPC Relationships Markup */
27400 var RELS = {
27401 WB: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
27402 SHEET: "http://sheetjs.openxmlformats.org/officeDocument/2006/relationships/officeDocument"
27403 };
27404
27405 function parse_rels(data, currentFilePath) {
27406 if (!data) return data;
27407 if (currentFilePath.charAt(0) !== '/') {
27408 currentFilePath = '/'+currentFilePath;
27409 }
27410 var rels = {};
27411 var hash = {};
27412 var resolveRelativePathIntoAbsolute = function (to) {
27413 var toksFrom = currentFilePath.split('/');
27414 toksFrom.pop(); // folder path
27415 var toksTo = to.split('/');
27416 var reversed = [];
27417 while (toksTo.length !== 0) {
27418 var tokTo = toksTo.shift();
27419 if (tokTo === '..') {
27420 toksFrom.pop();
27421 } else if (tokTo !== '.') {
27422 toksFrom.push(tokTo);
27423 }
27424 }
27425 return toksFrom.join('/');
27426 };
27427
27428 data.match(tagregex).forEach(function(x) {
27429 var y = parsexmltag(x);
27430 /* 9.3.2.2 OPC_Relationships */
27431 if (y[0] === '<Relationship') {
27432 var rel = {}; rel.Type = y.Type; rel.Target = y.Target; rel.Id = y.Id; rel.TargetMode = y.TargetMode;
27433 var canonictarget = y.TargetMode === 'External' ? y.Target : resolveRelativePathIntoAbsolute(y.Target);
27434 rels[canonictarget] = rel;
27435 hash[y.Id] = rel;
27436 }
27437 });
27438 rels["!id"] = hash;
27439 return rels;
27440 }
27441
27442 XMLNS.RELS = 'http://schemas.openxmlformats.org/package/2006/relationships';
27443
27444 var RELS_ROOT = writextag('Relationships', null, {
27445 //'xmlns:ns0': XMLNS.RELS,
27446 'xmlns': XMLNS.RELS
27447 });
27448
27449 /* TODO */
27450 function write_rels(rels) {
27451 var o = [];
27452 o[o.length] = (XML_HEADER);
27453 o[o.length] = (RELS_ROOT);
27454 keys(rels['!id']).forEach(function(rid) { var rel = rels['!id'][rid];
27455 o[o.length] = (writextag('Relationship', null, rel));
27456 });
27457 if(o.length>2){ o[o.length] = ('</Relationships>'); o[1]=o[1].replace("/>",">"); }
27458 return o.join("");
27459 }
27460 /* ECMA-376 Part II 11.1 Core Properties Part */
27461 /* [MS-OSHARED] 2.3.3.2.[1-2].1 (PIDSI/PIDDSI) */
27462 var CORE_PROPS = [
27463 ["cp:category", "Category"],
27464 ["cp:contentStatus", "ContentStatus"],
27465 ["cp:keywords", "Keywords"],
27466 ["cp:lastModifiedBy", "LastAuthor"],
27467 ["cp:lastPrinted", "LastPrinted"],
27468 ["cp:revision", "RevNumber"],
27469 ["cp:version", "Version"],
27470 ["dc:creator", "Author"],
27471 ["dc:description", "Comments"],
27472 ["dc:identifier", "Identifier"],
27473 ["dc:language", "Language"],
27474 ["dc:subject", "Subject"],
27475 ["dc:title", "Title"],
27476 ["dcterms:created", "CreatedDate", 'date'],
27477 ["dcterms:modified", "ModifiedDate", 'date']
27478 ];
27479
27480 XMLNS.CORE_PROPS = "http://schemas.openxmlformats.org/package/2006/metadata/core-properties";
27481 RELS.CORE_PROPS = 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties';
27482
27483 var CORE_PROPS_REGEX = (function() {
27484 var r = new Array(CORE_PROPS.length);
27485 for(var i = 0; i < CORE_PROPS.length; ++i) {
27486 var f = CORE_PROPS[i];
27487 var g = "(?:"+ f[0].substr(0,f[0].indexOf(":")) +":)"+ f[0].substr(f[0].indexOf(":")+1);
27488 r[i] = new RegExp("<" + g + "[^>]*>(.*)<\/" + g + ">");
27489 }
27490 return r;
27491 })();
27492
27493 function parse_core_props(data) {
27494 var p = {};
27495
27496 for(var i = 0; i < CORE_PROPS.length; ++i) {
27497 var f = CORE_PROPS[i], cur = data.match(CORE_PROPS_REGEX[i]);
27498 if(cur != null && cur.length > 0) p[f[1]] = cur[1];
27499 if(f[2] === 'date' && p[f[1]]) p[f[1]] = new Date(p[f[1]]);
27500 }
27501
27502 return p;
27503 }
27504
27505 var CORE_PROPS_XML_ROOT = writextag('cp:coreProperties', null, {
27506 //'xmlns': XMLNS.CORE_PROPS,
27507 'xmlns:cp': XMLNS.CORE_PROPS,
27508 'xmlns:dc': XMLNS.dc,
27509 'xmlns:dcterms': XMLNS.dcterms,
27510 'xmlns:dcmitype': XMLNS.dcmitype,
27511 'xmlns:xsi': XMLNS.xsi
27512 });
27513
27514 function cp_doit(f, g, h, o, p) {
27515 if(p[f] != null || g == null || g === "") return;
27516 p[f] = g;
27517 o[o.length] = (h ? writextag(f,g,h) : writetag(f,g));
27518 }
27519
27520 function write_core_props(cp, opts) {
27521 var o = [XML_HEADER, CORE_PROPS_XML_ROOT], p = {};
27522 if(!cp) return o.join("");
27523
27524
27525 if(cp.CreatedDate != null) cp_doit("dcterms:created", typeof cp.CreatedDate === "string" ? cp.CreatedDate : write_w3cdtf(cp.CreatedDate, opts.WTF), {"xsi:type":"dcterms:W3CDTF"}, o, p);
27526 if(cp.ModifiedDate != null) cp_doit("dcterms:modified", typeof cp.ModifiedDate === "string" ? cp.ModifiedDate : write_w3cdtf(cp.ModifiedDate, opts.WTF), {"xsi:type":"dcterms:W3CDTF"}, o, p);
27527
27528 for(var i = 0; i != CORE_PROPS.length; ++i) { var f = CORE_PROPS[i]; cp_doit(f[0], cp[f[1]], null, o, p); }
27529 if(o.length>2){ o[o.length] = ('</cp:coreProperties>'); o[1]=o[1].replace("/>",">"); }
27530 return o.join("");
27531 }
27532 /* 15.2.12.3 Extended File Properties Part */
27533 /* [MS-OSHARED] 2.3.3.2.[1-2].1 (PIDSI/PIDDSI) */
27534 var EXT_PROPS = [
27535 ["Application", "Application", "string"],
27536 ["AppVersion", "AppVersion", "string"],
27537 ["Company", "Company", "string"],
27538 ["DocSecurity", "DocSecurity", "string"],
27539 ["Manager", "Manager", "string"],
27540 ["HyperlinksChanged", "HyperlinksChanged", "bool"],
27541 ["SharedDoc", "SharedDoc", "bool"],
27542 ["LinksUpToDate", "LinksUpToDate", "bool"],
27543 ["ScaleCrop", "ScaleCrop", "bool"],
27544 ["HeadingPairs", "HeadingPairs", "raw"],
27545 ["TitlesOfParts", "TitlesOfParts", "raw"]
27546 ];
27547
27548 XMLNS.EXT_PROPS = "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties";
27549 RELS.EXT_PROPS = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties';
27550
27551 function parse_ext_props(data, p) {
27552 var q = {}; if(!p) p = {};
27553
27554 EXT_PROPS.forEach(function(f) {
27555 switch(f[2]) {
27556 case "string": p[f[1]] = (data.match(matchtag(f[0]))||[])[1]; break;
27557 case "bool": p[f[1]] = (data.match(matchtag(f[0]))||[])[1] === "true"; break;
27558 case "raw":
27559 var cur = data.match(new RegExp("<" + f[0] + "[^>]*>(.*)<\/" + f[0] + ">"));
27560 if(cur && cur.length > 0) q[f[1]] = cur[1];
27561 break;
27562 }
27563 });
27564
27565 if(q.HeadingPairs && q.TitlesOfParts) {
27566 var v = parseVector(q.HeadingPairs);
27567 var j = 0, widx = 0;
27568 for(var i = 0; i !== v.length; ++i) {
27569 switch(v[i].v) {
27570 case "Worksheets": widx = j; p.Worksheets = +(v[++i].v); break;
27571 case "Named Ranges": ++i; break; // TODO: Handle Named Ranges
27572 }
27573 }
27574 var parts = parseVector(q.TitlesOfParts).map(function(x) { return utf8read(x.v); });
27575 p.SheetNames = parts.slice(widx, widx + p.Worksheets);
27576 }
27577 return p;
27578 }
27579
27580 var EXT_PROPS_XML_ROOT = writextag('Properties', null, {
27581 'xmlns': XMLNS.EXT_PROPS,
27582 'xmlns:vt': XMLNS.vt
27583 });
27584
27585 function write_ext_props(cp, opts) {
27586 var o = [], p = {}, W = writextag;
27587 if(!cp) cp = {};
27588 cp.Application = "SheetJS";
27589 o[o.length] = (XML_HEADER);
27590 o[o.length] = (EXT_PROPS_XML_ROOT);
27591
27592 EXT_PROPS.forEach(function(f) {
27593 if(cp[f[1]] === undefined) return;
27594 var v;
27595 switch(f[2]) {
27596 case 'string': v = cp[f[1]]; break;
27597 case 'bool': v = cp[f[1]] ? 'true' : 'false'; break;
27598 }
27599 if(v !== undefined) o[o.length] = (W(f[0], v));
27600 });
27601
27602 /* TODO: HeadingPairs, TitlesOfParts */
27603 o[o.length] = (W('HeadingPairs', W('vt:vector', W('vt:variant', '<vt:lpstr>Worksheets</vt:lpstr>')+W('vt:variant', W('vt:i4', String(cp.Worksheets))), {size:2, baseType:"variant"})));
27604 o[o.length] = (W('TitlesOfParts', W('vt:vector', cp.SheetNames.map(function(s) { return "<vt:lpstr>" + s + "</vt:lpstr>"; }).join(""), {size: cp.Worksheets, baseType:"lpstr"})));
27605 if(o.length>2){ o[o.length] = ('</Properties>'); o[1]=o[1].replace("/>",">"); }
27606 return o.join("");
27607 }
27608 /* 15.2.12.2 Custom File Properties Part */
27609 XMLNS.CUST_PROPS = "http://schemas.openxmlformats.org/officeDocument/2006/custom-properties";
27610 RELS.CUST_PROPS = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties';
27611
27612 var custregex = /<[^>]+>[^<]*/g;
27613 function parse_cust_props(data, opts) {
27614 var p = {}, name;
27615 var m = data.match(custregex);
27616 if(m) for(var i = 0; i != m.length; ++i) {
27617 var x = m[i], y = parsexmltag(x);
27618 switch(y[0]) {
27619 case '<?xml': break;
27620 case '<Properties':
27621 if(y.xmlns !== XMLNS.CUST_PROPS) throw "unrecognized xmlns " + y.xmlns;
27622 if(y.xmlnsvt && y.xmlnsvt !== XMLNS.vt) throw "unrecognized vt " + y.xmlnsvt;
27623 break;
27624 case '<property': name = y.name; break;
27625 case '</property>': name = null; break;
27626 default: if (x.indexOf('<vt:') === 0) {
27627 var toks = x.split('>');
27628 var type = toks[0].substring(4), text = toks[1];
27629 /* 22.4.2.32 (CT_Variant). Omit the binary types from 22.4 (Variant Types) */
27630 switch(type) {
27631 case 'lpstr': case 'lpwstr': case 'bstr': case 'lpwstr':
27632 p[name] = unescapexml(text);
27633 break;
27634 case 'bool':
27635 p[name] = parsexmlbool(text, '<vt:bool>');
27636 break;
27637 case 'i1': case 'i2': case 'i4': case 'i8': case 'int': case 'uint':
27638 p[name] = parseInt(text, 10);
27639 break;
27640 case 'r4': case 'r8': case 'decimal':
27641 p[name] = parseFloat(text);
27642 break;
27643 case 'filetime': case 'date':
27644 p[name] = new Date(text);
27645 break;
27646 case 'cy': case 'error':
27647 p[name] = unescapexml(text);
27648 break;
27649 default:
27650 if(typeof console !== 'undefined') console.warn('Unexpected', x, type, toks);
27651 }
27652 } else if(x.substr(0,2) === "</") {
27653 } else if(opts.WTF) throw new Error(x);
27654 }
27655 }
27656 return p;
27657 }
27658
27659 var CUST_PROPS_XML_ROOT = writextag('Properties', null, {
27660 'xmlns': XMLNS.CUST_PROPS,
27661 'xmlns:vt': XMLNS.vt
27662 });
27663
27664 function write_cust_props(cp, opts) {
27665 var o = [XML_HEADER, CUST_PROPS_XML_ROOT];
27666 if(!cp) return o.join("");
27667 var pid = 1;
27668 keys(cp).forEach(function custprop(k) { ++pid;
27669 o[o.length] = (writextag('property', write_vt(cp[k]), {
27670 'fmtid': '{D5CDD505-2E9C-101B-9397-08002B2CF9AE}',
27671 'pid': pid,
27672 'name': k
27673 }));
27674 });
27675 if(o.length>2){ o[o.length] = '</Properties>'; o[1]=o[1].replace("/>",">"); }
27676 return o.join("");
27677 }
27678 /* 18.4.1 charset to codepage mapping */
27679 var CS2CP = {
27680 0: 1252, /* ANSI */
27681 1: 65001, /* DEFAULT */
27682 2: 65001, /* SYMBOL */
27683 77: 10000, /* MAC */
27684 128: 932, /* SHIFTJIS */
27685 129: 949, /* HANGUL */
27686 130: 1361, /* JOHAB */
27687 134: 936, /* GB2312 */
27688 136: 950, /* CHINESEBIG5 */
27689 161: 1253, /* GREEK */
27690 162: 1254, /* TURKISH */
27691 163: 1258, /* VIETNAMESE */
27692 177: 1255, /* HEBREW */
27693 178: 1256, /* ARABIC */
27694 186: 1257, /* BALTIC */
27695 204: 1251, /* RUSSIAN */
27696 222: 874, /* THAI */
27697 238: 1250, /* EASTEUROPE */
27698 255: 1252, /* OEM */
27699 69: 6969 /* MISC */
27700 };
27701
27702 /* Parse a list of <r> tags */
27703 var parse_rs = (function parse_rs_factory() {
27704 var tregex = matchtag("t"), rpregex = matchtag("rPr"), rregex = /<r>/g, rend = /<\/r>/, nlregex = /\r\n/g;
27705 /* 18.4.7 rPr CT_RPrElt */
27706 var parse_rpr = function parse_rpr(rpr, intro, outro) {
27707 var font = {}, cp = 65001;
27708 var m = rpr.match(tagregex), i = 0;
27709 if(m) for(;i!=m.length; ++i) {
27710 var y = parsexmltag(m[i]);
27711 switch(y[0]) {
27712 /* 18.8.12 condense CT_BooleanProperty */
27713 /* ** not required . */
27714 case '<condense': break;
27715 /* 18.8.17 extend CT_BooleanProperty */
27716 /* ** not required . */
27717 case '<extend': break;
27718 /* 18.8.36 shadow CT_BooleanProperty */
27719 /* ** not required . */
27720 case '<shadow':
27721 /* falls through */
27722 case '<shadow/>': break;
27723
27724 /* 18.4.1 charset CT_IntProperty TODO */
27725 case '<charset':
27726 if(y.val == '1') break;
27727 cp = CS2CP[parseInt(y.val, 10)];
27728 break;
27729
27730 /* 18.4.2 outline CT_BooleanProperty TODO */
27731 case '<outline':
27732 /* falls through */
27733 case '<outline/>': break;
27734
27735 /* 18.4.5 rFont CT_FontName */
27736 case '<rFont': font.name = y.val; break;
27737
27738 /* 18.4.11 sz CT_FontSize */
27739 case '<sz': font.sz = y.val; break;
27740
27741 /* 18.4.10 strike CT_BooleanProperty */
27742 case '<strike':
27743 if(!y.val) break;
27744 /* falls through */
27745 case '<strike/>': font.strike = 1; break;
27746 case '</strike>': break;
27747
27748 /* 18.4.13 u CT_UnderlineProperty */
27749 case '<u':
27750 if(!y.val) break;
27751 /* falls through */
27752 case '<u/>': font.u = 1; break;
27753 case '</u>': break;
27754
27755 /* 18.8.2 b */
27756 case '<b':
27757 if(!y.val) break;
27758 /* falls through */
27759 case '<b/>': font.b = 1; break;
27760 case '</b>': break;
27761
27762 /* 18.8.26 i */
27763 case '<i':
27764 if(!y.val) break;
27765 /* falls through */
27766 case '<i/>': font.i = 1; break;
27767 case '</i>': break;
27768
27769 /* 18.3.1.15 color CT_Color TODO: tint, theme, auto, indexed */
27770 case '<color':
27771 if(y.rgb) font.color = y.rgb.substr(2,6);
27772 break;
27773
27774 /* 18.8.18 family ST_FontFamily */
27775 case '<family': font.family = y.val; break;
27776
27777 /* 18.4.14 vertAlign CT_VerticalAlignFontProperty TODO */
27778 case '<vertAlign': break;
27779
27780 /* 18.8.35 scheme CT_FontScheme TODO */
27781 case '<scheme': break;
27782
27783 default:
27784 if(y[0].charCodeAt(1) !== 47) throw 'Unrecognized rich format ' + y[0];
27785 }
27786 }
27787 /* TODO: These should be generated styles, not inline */
27788 var style = [];
27789 if(font.b) style.push("font-weight: bold;");
27790 if(font.i) style.push("font-style: italic;");
27791 intro.push('<span style="' + style.join("") + '">');
27792 outro.push("</span>");
27793 return cp;
27794 };
27795
27796 /* 18.4.4 r CT_RElt */
27797 function parse_r(r) {
27798 var terms = [[],"",[]];
27799 /* 18.4.12 t ST_Xstring */
27800 var t = r.match(tregex), cp = 65001;
27801 if(!isval(t)) return "";
27802 terms[1] = t[1];
27803
27804 var rpr = r.match(rpregex);
27805 if(isval(rpr)) cp = parse_rpr(rpr[1], terms[0], terms[2]);
27806
27807 return terms[0].join("") + terms[1].replace(nlregex,'<br/>') + terms[2].join("");
27808 }
27809 return function parse_rs(rs) {
27810 return rs.replace(rregex,"").split(rend).map(parse_r).join("");
27811 };
27812 })();
27813
27814 /* 18.4.8 si CT_Rst */
27815 var sitregex = /<t[^>]*>([^<]*)<\/t>/g, sirregex = /<r>/;
27816 function parse_si(x, opts) {
27817 var html = opts ? opts.cellHTML : true;
27818 var z = {};
27819 if(!x) return null;
27820 var y;
27821 /* 18.4.12 t ST_Xstring (Plaintext String) */
27822 if(x.charCodeAt(1) === 116) {
27823 z.t = utf8read(unescapexml(x.substr(x.indexOf(">")+1).split(/<\/t>/)[0]));
27824 z.r = x;
27825 if(html) z.h = z.t;
27826 }
27827 /* 18.4.4 r CT_RElt (Rich Text Run) */
27828 else if((y = x.match(sirregex))) {
27829 z.r = x;
27830 z.t = utf8read(unescapexml(x.match(sitregex).join("").replace(tagregex,"")));
27831 if(html) z.h = parse_rs(x);
27832 }
27833 /* 18.4.3 phoneticPr CT_PhoneticPr (TODO: needed for Asian support) */
27834 /* 18.4.6 rPh CT_PhoneticRun (TODO: needed for Asian support) */
27835 return z;
27836 }
27837
27838 /* 18.4 Shared String Table */
27839 var sstr0 = /<sst([^>]*)>([\s\S]*)<\/sst>/;
27840 var sstr1 = /<(?:si|sstItem)>/g;
27841 var sstr2 = /<\/(?:si|sstItem)>/;
27842 function parse_sst_xml(data, opts) {
27843 var s = [], ss;
27844 /* 18.4.9 sst CT_Sst */
27845 var sst = data.match(sstr0);
27846 if(isval(sst)) {
27847 ss = sst[2].replace(sstr1,"").split(sstr2);
27848 for(var i = 0; i != ss.length; ++i) {
27849 var o = parse_si(ss[i], opts);
27850 if(o != null) s[s.length] = o;
27851 }
27852 sst = parsexmltag(sst[1]); s.Count = sst.count; s.Unique = sst.uniqueCount;
27853 }
27854 return s;
27855 }
27856
27857 RELS.SST = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings";
27858 var straywsregex = /^\s|\s$|[\t\n\r]/;
27859 function write_sst_xml(sst, opts) {
27860 if(!opts.bookSST) return "";
27861 var o = [XML_HEADER];
27862 o[o.length] = (writextag('sst', null, {
27863 xmlns: XMLNS.main[0],
27864 count: sst.Count,
27865 uniqueCount: sst.Unique
27866 }));
27867 for(var i = 0; i != sst.length; ++i) { if(sst[i] == null) continue;
27868 var s = sst[i];
27869 var sitag = "<si>";
27870 if(s.r) sitag += s.r;
27871 else {
27872 sitag += "<t";
27873 if(s.t.match(straywsregex)) sitag += ' xml:space="preserve"';
27874 sitag += ">" + escapexml(s.t) + "</t>";
27875 }
27876 sitag += "</si>";
27877 o[o.length] = (sitag);
27878 }
27879 if(o.length>2){ o[o.length] = ('</sst>'); o[1]=o[1].replace("/>",">"); }
27880 return o.join("");
27881 }
27882 /* [MS-XLSB] 2.4.219 BrtBeginSst */
27883 function parse_BrtBeginSst(data, length) {
27884 return [data.read_shift(4), data.read_shift(4)];
27885 }
27886
27887 /* [MS-XLSB] 2.1.7.45 Shared Strings */
27888 function parse_sst_bin(data, opts) {
27889 var s = [];
27890 var pass = false;
27891 recordhopper(data, function hopper_sst(val, R, RT) {
27892 switch(R.n) {
27893 case 'BrtBeginSst': s.Count = val[0]; s.Unique = val[1]; break;
27894 case 'BrtSSTItem': s.push(val); break;
27895 case 'BrtEndSst': return true;
27896 /* TODO: produce a test case with a future record */
27897 case 'BrtFRTBegin': pass = true; break;
27898 case 'BrtFRTEnd': pass = false; break;
27899 default: if(!pass || opts.WTF) throw new Error("Unexpected record " + RT + " " + R.n);
27900 }
27901 });
27902 return s;
27903 }
27904
27905 function write_BrtBeginSst(sst, o) {
27906 if(!o) o = new_buf(8);
27907 o.write_shift(4, sst.Count);
27908 o.write_shift(4, sst.Unique);
27909 return o;
27910 }
27911
27912 var write_BrtSSTItem = write_RichStr;
27913
27914 function write_sst_bin(sst, opts) {
27915 var ba = buf_array();
27916 write_record(ba, "BrtBeginSst", write_BrtBeginSst(sst));
27917 for(var i = 0; i < sst.length; ++i) write_record(ba, "BrtSSTItem", write_BrtSSTItem(sst[i]));
27918 write_record(ba, "BrtEndSst");
27919 return ba.end();
27920 }
27921 function hex2RGB(h) {
27922 var o = h.substr(h[0]==="#"?1:0,6);
27923 return [parseInt(o.substr(0,2),16),parseInt(o.substr(0,2),16),parseInt(o.substr(0,2),16)];
27924 }
27925 function rgb2Hex(rgb) {
27926 for(var i=0,o=1; i!=3; ++i) o = o*256 + (rgb[i]>255?255:rgb[i]<0?0:rgb[i]);
27927 return o.toString(16).toUpperCase().substr(1);
27928 }
27929
27930 function rgb2HSL(rgb) {
27931 var R = rgb[0]/255, G = rgb[1]/255, B=rgb[2]/255;
27932 var M = Math.max(R, G, B), m = Math.min(R, G, B), C = M - m;
27933 if(C === 0) return [0, 0, R];
27934
27935 var H6 = 0, S = 0, L2 = (M + m);
27936 S = C / (L2 > 1 ? 2 - L2 : L2);
27937 switch(M){
27938 case R: H6 = ((G - B) / C + 6)%6; break;
27939 case G: H6 = ((B - R) / C + 2); break;
27940 case B: H6 = ((R - G) / C + 4); break;
27941 }
27942 return [H6 / 6, S, L2 / 2];
27943 }
27944
27945 function hsl2RGB(hsl){
27946 var H = hsl[0], S = hsl[1], L = hsl[2];
27947 var C = S * 2 * (L < 0.5 ? L : 1 - L), m = L - C/2;
27948 var rgb = [m,m,m], h6 = 6*H;
27949
27950 var X;
27951 if(S !== 0) switch(h6|0) {
27952 case 0: case 6: X = C * h6; rgb[0] += C; rgb[1] += X; break;
27953 case 1: X = C * (2 - h6); rgb[0] += X; rgb[1] += C; break;
27954 case 2: X = C * (h6 - 2); rgb[1] += C; rgb[2] += X; break;
27955 case 3: X = C * (4 - h6); rgb[1] += X; rgb[2] += C; break;
27956 case 4: X = C * (h6 - 4); rgb[2] += C; rgb[0] += X; break;
27957 case 5: X = C * (6 - h6); rgb[2] += X; rgb[0] += C; break;
27958 }
27959 for(var i = 0; i != 3; ++i) rgb[i] = Math.round(rgb[i]*255);
27960 return rgb;
27961 }
27962
27963 /* 18.8.3 bgColor tint algorithm */
27964 function rgb_tint(hex, tint) {
27965 if(tint === 0) return hex;
27966 var hsl = rgb2HSL(hex2RGB(hex));
27967 if (tint < 0) hsl[2] = hsl[2] * (1 + tint);
27968 else hsl[2] = 1 - (1 - hsl[2]) * (1 - tint);
27969 return rgb2Hex(hsl2RGB(hsl));
27970 }
27971
27972 /* 18.3.1.13 width calculations */
27973 var DEF_MDW = 7, MAX_MDW = 15, MIN_MDW = 1, MDW = DEF_MDW;
27974 function width2px(width) { return (( width + ((128/MDW)|0)/256 )* MDW )|0; }
27975 function px2char(px) { return (((px - 5)/MDW * 100 + 0.5)|0)/100; }
27976 function char2width(chr) { return (((chr * MDW + 5)/MDW*256)|0)/256; }
27977 function cycle_width(collw) { return char2width(px2char(width2px(collw))); }
27978 function find_mdw(collw, coll) {
27979 if(cycle_width(collw) != collw) {
27980 for(MDW=DEF_MDW; MDW>MIN_MDW; --MDW) if(cycle_width(collw) === collw) break;
27981 if(MDW === MIN_MDW) for(MDW=DEF_MDW+1; MDW<MAX_MDW; ++MDW) if(cycle_width(collw) === collw) break;
27982 if(MDW === MAX_MDW) MDW = DEF_MDW;
27983 }
27984 }
27985 var styles = {}; // shared styles
27986
27987 var themes = {}; // shared themes
27988
27989 /* 18.8.21 fills CT_Fills */
27990 function parse_fills(t, opts) {
27991 styles.Fills = [];
27992 var fill = {};
27993 t[0].match(tagregex).forEach(function(x) {
27994 var y = parsexmltag(x);
27995 switch(y[0]) {
27996 case '<fills': case '<fills>': case '</fills>': break;
27997
27998 /* 18.8.20 fill CT_Fill */
27999 case '<fill>': break;
28000 case '</fill>': styles.Fills.push(fill); fill = {}; break;
28001
28002 /* 18.8.32 patternFill CT_PatternFill */
28003 case '<patternFill':
28004 if(y.patternType) fill.patternType = y.patternType;
28005 break;
28006 case '<patternFill/>': case '</patternFill>': break;
28007
28008 /* 18.8.3 bgColor CT_Color */
28009 case '<bgColor':
28010 if(!fill.bgColor) fill.bgColor = {};
28011 if(y.indexed) fill.bgColor.indexed = parseInt(y.indexed, 10);
28012 if(y.theme) fill.bgColor.theme = parseInt(y.theme, 10);
28013 if(y.tint) fill.bgColor.tint = parseFloat(y.tint);
28014 /* Excel uses ARGB strings */
28015 if(y.rgb) fill.bgColor.rgb = y.rgb.substring(y.rgb.length - 6);
28016 break;
28017 case '<bgColor/>': case '</bgColor>': break;
28018
28019 /* 18.8.19 fgColor CT_Color */
28020 case '<fgColor':
28021 if(!fill.fgColor) fill.fgColor = {};
28022 if(y.theme) fill.fgColor.theme = parseInt(y.theme, 10);
28023 if(y.tint) fill.fgColor.tint = parseFloat(y.tint);
28024 /* Excel uses ARGB strings */
28025 if(y.rgb) fill.fgColor.rgb = y.rgb.substring(y.rgb.length - 6);
28026 break;
28027 case '<bgColor/>': case '</fgColor>': break;
28028
28029 default: if(opts.WTF) throw 'unrecognized ' + y[0] + ' in fills';
28030 }
28031 });
28032 }
28033
28034 /* 18.8.31 numFmts CT_NumFmts */
28035 function parse_numFmts(t, opts) {
28036 styles.NumberFmt = [];
28037 var k = keys(SSF._table);
28038 for(var i=0; i < k.length; ++i) styles.NumberFmt[k[i]] = SSF._table[k[i]];
28039 var m = t[0].match(tagregex);
28040 for(i=0; i < m.length; ++i) {
28041 var y = parsexmltag(m[i]);
28042 switch(y[0]) {
28043 case '<numFmts': case '</numFmts>': case '<numFmts/>': case '<numFmts>': break;
28044 case '<numFmt': {
28045 var f=unescapexml(utf8read(y.formatCode)), j=parseInt(y.numFmtId,10);
28046 styles.NumberFmt[j] = f; if(j>0) SSF.load(f,j);
28047 } break;
28048 default: if(opts.WTF) throw 'unrecognized ' + y[0] + ' in numFmts';
28049 }
28050 }
28051 }
28052
28053 function write_numFmts(NF, opts) {
28054 var o = ["<numFmts>"];
28055 [[5,8],[23,26],[41,44],[63,66],[164,392]].forEach(function(r) {
28056 for(var i = r[0]; i <= r[1]; ++i) if(NF[i] !== undefined) o[o.length] = (writextag('numFmt',null,{numFmtId:i,formatCode:escapexml(NF[i])}));
28057 });
28058 if(o.length === 1) return "";
28059 o[o.length] = ("</numFmts>");
28060 o[0] = writextag('numFmts', null, { count:o.length-2 }).replace("/>", ">");
28061 return o.join("");
28062 }
28063
28064 /* 18.8.10 cellXfs CT_CellXfs */
28065 function parse_cellXfs(t, opts) {
28066 styles.CellXf = [];
28067 t[0].match(tagregex).forEach(function(x) {
28068 var y = parsexmltag(x);
28069 switch(y[0]) {
28070 case '<cellXfs': case '<cellXfs>': case '<cellXfs/>': case '</cellXfs>': break;
28071
28072 /* 18.8.45 xf CT_Xf */
28073 case '<xf': delete y[0];
28074 if(y.numFmtId) y.numFmtId = parseInt(y.numFmtId, 10);
28075 if(y.fillId) y.fillId = parseInt(y.fillId, 10);
28076 styles.CellXf.push(y); break;
28077 case '</xf>': break;
28078
28079 /* 18.8.1 alignment CT_CellAlignment */
28080 case '<alignment': case '<alignment/>': break;
28081
28082 /* 18.8.33 protection CT_CellProtection */
28083 case '<protection': case '</protection>': case '<protection/>': break;
28084
28085 case '<extLst': case '</extLst>': break;
28086 case '<ext': break;
28087 default: if(opts.WTF) throw 'unrecognized ' + y[0] + ' in cellXfs';
28088 }
28089 });
28090 }
28091
28092 function write_cellXfs(cellXfs) {
28093 var o = [];
28094 o[o.length] = (writextag('cellXfs',null));
28095 cellXfs.forEach(function(c) { o[o.length] = (writextag('xf', null, c)); });
28096 o[o.length] = ("</cellXfs>");
28097 if(o.length === 2) return "";
28098 o[0] = writextag('cellXfs',null, {count:o.length-2}).replace("/>",">");
28099 return o.join("");
28100 }
28101
28102 /* 18.8 Styles CT_Stylesheet*/
28103 var parse_sty_xml= (function make_pstyx() {
28104 var numFmtRegex = /<numFmts([^>]*)>.*<\/numFmts>/;
28105 var cellXfRegex = /<cellXfs([^>]*)>.*<\/cellXfs>/;
28106 var fillsRegex = /<fills([^>]*)>.*<\/fills>/;
28107
28108 return function parse_sty_xml(data, opts) {
28109 /* 18.8.39 styleSheet CT_Stylesheet */
28110 var t;
28111
28112 /* numFmts CT_NumFmts ? */
28113 if((t=data.match(numFmtRegex))) parse_numFmts(t, opts);
28114
28115 /* fonts CT_Fonts ? */
28116 // if((t=data.match(/<fonts([^>]*)>.*<\/fonts>/))) parse_fonts(t, opts);
28117
28118 /* fills CT_Fills */
28119 if((t=data.match(fillsRegex))) parse_fills(t, opts);
28120
28121 /* borders CT_Borders ? */
28122 /* cellStyleXfs CT_CellStyleXfs ? */
28123
28124 /* cellXfs CT_CellXfs ? */
28125 if((t=data.match(cellXfRegex))) parse_cellXfs(t, opts);
28126
28127 /* dxfs CT_Dxfs ? */
28128 /* tableStyles CT_TableStyles ? */
28129 /* colors CT_Colors ? */
28130 /* extLst CT_ExtensionList ? */
28131
28132 return styles;
28133 };
28134 })();
28135
28136 var STYLES_XML_ROOT = writextag('styleSheet', null, {
28137 'xmlns': XMLNS.main[0],
28138 'xmlns:vt': XMLNS.vt
28139 });
28140
28141 RELS.STY = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
28142
28143 function write_sty_xml(wb, opts) {
28144 var o = [XML_HEADER, STYLES_XML_ROOT], w;
28145 if((w = write_numFmts(wb.SSF)) != null) o[o.length] = w;
28146 o[o.length] = ('<fonts count="1"><font><sz val="12"/><color theme="1"/><name val="Calibri"/><family val="2"/><scheme val="minor"/></font></fonts>');
28147 o[o.length] = ('<fills count="2"><fill><patternFill patternType="none"/></fill><fill><patternFill patternType="gray125"/></fill></fills>');
28148 o[o.length] = ('<borders count="1"><border><left/><right/><top/><bottom/><diagonal/></border></borders>');
28149 o[o.length] = ('<cellStyleXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0"/></cellStyleXfs>');
28150 if((w = write_cellXfs(opts.cellXfs))) o[o.length] = (w);
28151 o[o.length] = ('<cellStyles count="1"><cellStyle name="Normal" xfId="0" builtinId="0"/></cellStyles>');
28152 o[o.length] = ('<dxfs count="0"/>');
28153 o[o.length] = ('<tableStyles count="0" defaultTableStyle="TableStyleMedium9" defaultPivotStyle="PivotStyleMedium4"/>');
28154
28155 if(o.length>2){ o[o.length] = ('</styleSheet>'); o[1]=o[1].replace("/>",">"); }
28156 return o.join("");
28157 }
28158 /* [MS-XLSB] 2.4.651 BrtFmt */
28159 function parse_BrtFmt(data, length) {
28160 var ifmt = data.read_shift(2);
28161 var stFmtCode = parse_XLWideString(data,length-2);
28162 return [ifmt, stFmtCode];
28163 }
28164
28165 /* [MS-XLSB] 2.4.653 BrtFont TODO */
28166 function parse_BrtFont(data, length) {
28167 var out = {flags:{}};
28168 out.dyHeight = data.read_shift(2);
28169 out.grbit = parse_FontFlags(data, 2);
28170 out.bls = data.read_shift(2);
28171 out.sss = data.read_shift(2);
28172 out.uls = data.read_shift(1);
28173 out.bFamily = data.read_shift(1);
28174 out.bCharSet = data.read_shift(1);
28175 data.l++;
28176 out.brtColor = parse_BrtColor(data, 8);
28177 out.bFontScheme = data.read_shift(1);
28178 out.name = parse_XLWideString(data, length - 21);
28179
28180 out.flags.Bold = out.bls === 0x02BC;
28181 out.flags.Italic = out.grbit.fItalic;
28182 out.flags.Strikeout = out.grbit.fStrikeout;
28183 out.flags.Outline = out.grbit.fOutline;
28184 out.flags.Shadow = out.grbit.fShadow;
28185 out.flags.Condense = out.grbit.fCondense;
28186 out.flags.Extend = out.grbit.fExtend;
28187 out.flags.Sub = out.sss & 0x2;
28188 out.flags.Sup = out.sss & 0x1;
28189 return out;
28190 }
28191
28192 /* [MS-XLSB] 2.4.816 BrtXF */
28193 function parse_BrtXF(data, length) {
28194 var ixfeParent = data.read_shift(2);
28195 var ifmt = data.read_shift(2);
28196 parsenoop(data, length-4);
28197 return {ixfe:ixfeParent, ifmt:ifmt };
28198 }
28199
28200 /* [MS-XLSB] 2.1.7.50 Styles */
28201 function parse_sty_bin(data, opts) {
28202 styles.NumberFmt = [];
28203 for(var y in SSF._table) styles.NumberFmt[y] = SSF._table[y];
28204
28205 styles.CellXf = [];
28206 var state = ""; /* TODO: this should be a stack */
28207 var pass = false;
28208 recordhopper(data, function hopper_sty(val, R, RT) {
28209 switch(R.n) {
28210 case 'BrtFmt':
28211 styles.NumberFmt[val[0]] = val[1]; SSF.load(val[1], val[0]);
28212 break;
28213 case 'BrtFont': break; /* TODO */
28214 case 'BrtKnownFonts': break; /* TODO */
28215 case 'BrtFill': break; /* TODO */
28216 case 'BrtBorder': break; /* TODO */
28217 case 'BrtXF':
28218 if(state === "CELLXFS") {
28219 styles.CellXf.push(val);
28220 }
28221 break; /* TODO */
28222 case 'BrtStyle': break; /* TODO */
28223 case 'BrtDXF': break; /* TODO */
28224 case 'BrtMRUColor': break; /* TODO */
28225 case 'BrtIndexedColor': break; /* TODO */
28226 case 'BrtBeginStyleSheet': break;
28227 case 'BrtEndStyleSheet': break;
28228 case 'BrtBeginTableStyle': break;
28229 case 'BrtTableStyleElement': break;
28230 case 'BrtEndTableStyle': break;
28231 case 'BrtBeginFmts': state = "FMTS"; break;
28232 case 'BrtEndFmts': state = ""; break;
28233 case 'BrtBeginFonts': state = "FONTS"; break;
28234 case 'BrtEndFonts': state = ""; break;
28235 case 'BrtACBegin': state = "ACFONTS"; break;
28236 case 'BrtACEnd': state = ""; break;
28237 case 'BrtBeginFills': state = "FILLS"; break;
28238 case 'BrtEndFills': state = ""; break;
28239 case 'BrtBeginBorders': state = "BORDERS"; break;
28240 case 'BrtEndBorders': state = ""; break;
28241 case 'BrtBeginCellStyleXFs': state = "CELLSTYLEXFS"; break;
28242 case 'BrtEndCellStyleXFs': state = ""; break;
28243 case 'BrtBeginCellXFs': state = "CELLXFS"; break;
28244 case 'BrtEndCellXFs': state = ""; break;
28245 case 'BrtBeginStyles': state = "STYLES"; break;
28246 case 'BrtEndStyles': state = ""; break;
28247 case 'BrtBeginDXFs': state = "DXFS"; break;
28248 case 'BrtEndDXFs': state = ""; break;
28249 case 'BrtBeginTableStyles': state = "TABLESTYLES"; break;
28250 case 'BrtEndTableStyles': state = ""; break;
28251 case 'BrtBeginColorPalette': state = "COLORPALETTE"; break;
28252 case 'BrtEndColorPalette': state = ""; break;
28253 case 'BrtBeginIndexedColors': state = "INDEXEDCOLORS"; break;
28254 case 'BrtEndIndexedColors': state = ""; break;
28255 case 'BrtBeginMRUColors': state = "MRUCOLORS"; break;
28256 case 'BrtEndMRUColors': state = ""; break;
28257 case 'BrtFRTBegin': pass = true; break;
28258 case 'BrtFRTEnd': pass = false; break;
28259 case 'BrtBeginStyleSheetExt14': break;
28260 case 'BrtBeginSlicerStyles': break;
28261 case 'BrtEndSlicerStyles': break;
28262 case 'BrtBeginTimelineStylesheetExt15': break;
28263 case 'BrtEndTimelineStylesheetExt15': break;
28264 case 'BrtBeginTimelineStyles': break;
28265 case 'BrtEndTimelineStyles': break;
28266 case 'BrtEndStyleSheetExt14': break;
28267 default: if(!pass || opts.WTF) throw new Error("Unexpected record " + RT + " " + R.n);
28268 }
28269 });
28270 return styles;
28271 }
28272
28273 /* [MS-XLSB] 2.1.7.50 Styles */
28274 function write_sty_bin(data, opts) {
28275 var ba = buf_array();
28276 write_record(ba, "BrtBeginStyleSheet");
28277 /* [FMTS] */
28278 /* [FONTS] */
28279 /* [FILLS] */
28280 /* [BORDERS] */
28281 /* CELLSTYLEXFS */
28282 /* CELLXFS*/
28283 /* STYLES */
28284 /* DXFS */
28285 /* TABLESTYLES */
28286 /* [COLORPALETTE] */
28287 /* FRTSTYLESHEET*/
28288 write_record(ba, "BrtEndStyleSheet");
28289 return ba.end();
28290 }
28291 RELS.THEME = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme";
28292
28293 /* 20.1.6.2 clrScheme CT_ColorScheme */
28294 function parse_clrScheme(t, opts) {
28295 themes.themeElements.clrScheme = [];
28296 var color = {};
28297 t[0].match(tagregex).forEach(function(x) {
28298 var y = parsexmltag(x);
28299 switch(y[0]) {
28300 case '<a:clrScheme': case '</a:clrScheme>': break;
28301
28302 /* 20.1.2.3.32 srgbClr CT_SRgbColor */
28303 case '<a:srgbClr': color.rgb = y.val; break;
28304
28305 /* 20.1.2.3.33 sysClr CT_SystemColor */
28306 case '<a:sysClr': color.rgb = y.lastClr; break;
28307
28308 /* 20.1.4.1.9 dk1 (Dark 1) */
28309 case '<a:dk1>':
28310 case '</a:dk1>':
28311 /* 20.1.4.1.10 dk2 (Dark 2) */
28312 case '<a:dk2>':
28313 case '</a:dk2>':
28314 /* 20.1.4.1.22 lt1 (Light 1) */
28315 case '<a:lt1>':
28316 case '</a:lt1>':
28317 /* 20.1.4.1.23 lt2 (Light 2) */
28318 case '<a:lt2>':
28319 case '</a:lt2>':
28320 /* 20.1.4.1.1 accent1 (Accent 1) */
28321 case '<a:accent1>':
28322 case '</a:accent1>':
28323 /* 20.1.4.1.2 accent2 (Accent 2) */
28324 case '<a:accent2>':
28325 case '</a:accent2>':
28326 /* 20.1.4.1.3 accent3 (Accent 3) */
28327 case '<a:accent3>':
28328 case '</a:accent3>':
28329 /* 20.1.4.1.4 accent4 (Accent 4) */
28330 case '<a:accent4>':
28331 case '</a:accent4>':
28332 /* 20.1.4.1.5 accent5 (Accent 5) */
28333 case '<a:accent5>':
28334 case '</a:accent5>':
28335 /* 20.1.4.1.6 accent6 (Accent 6) */
28336 case '<a:accent6>':
28337 case '</a:accent6>':
28338 /* 20.1.4.1.19 hlink (Hyperlink) */
28339 case '<a:hlink>':
28340 case '</a:hlink>':
28341 /* 20.1.4.1.15 folHlink (Followed Hyperlink) */
28342 case '<a:folHlink>':
28343 case '</a:folHlink>':
28344 if (y[0][1] === '/') {
28345 themes.themeElements.clrScheme.push(color);
28346 color = {};
28347 } else {
28348 color.name = y[0].substring(3, y[0].length - 1);
28349 }
28350 break;
28351
28352 default: if(opts.WTF) throw 'unrecognized ' + y[0] + ' in clrScheme';
28353 }
28354 });
28355 }
28356
28357 var clrsregex = /<a:clrScheme([^>]*)>.*<\/a:clrScheme>/;
28358 /* 14.2.7 Theme Part */
28359 function parse_theme_xml(data, opts) {
28360 if(!data || data.length === 0) return themes;
28361 themes.themeElements = {};
28362
28363 var t;
28364
28365 /* clrScheme CT_ColorScheme */
28366 if((t=data.match(clrsregex))) parse_clrScheme(t, opts);
28367
28368 return themes;
28369 }
28370
28371 function write_theme() { return '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="Office Theme"><a:themeElements><a:clrScheme name="Office"><a:dk1><a:sysClr val="windowText" lastClr="000000"/></a:dk1><a:lt1><a:sysClr val="window" lastClr="FFFFFF"/></a:lt1><a:dk2><a:srgbClr val="1F497D"/></a:dk2><a:lt2><a:srgbClr val="EEECE1"/></a:lt2><a:accent1><a:srgbClr val="4F81BD"/></a:accent1><a:accent2><a:srgbClr val="C0504D"/></a:accent2><a:accent3><a:srgbClr val="9BBB59"/></a:accent3><a:accent4><a:srgbClr val="8064A2"/></a:accent4><a:accent5><a:srgbClr val="4BACC6"/></a:accent5><a:accent6><a:srgbClr val="F79646"/></a:accent6><a:hlink><a:srgbClr val="0000FF"/></a:hlink><a:folHlink><a:srgbClr val="800080"/></a:folHlink></a:clrScheme><a:fontScheme name="Office"><a:majorFont><a:latin typeface="Cambria"/><a:ea typeface=""/><a:cs typeface=""/><a:font script="Jpan" typeface="MS Pゴシック"/><a:font script="Hang" typeface="맑은 고딕"/><a:font script="Hans" typeface="宋体"/><a:font script="Hant" typeface="新細明體"/><a:font script="Arab" typeface="Times New Roman"/><a:font script="Hebr" typeface="Times New Roman"/><a:font script="Thai" typeface="Tahoma"/><a:font script="Ethi" typeface="Nyala"/><a:font script="Beng" typeface="Vrinda"/><a:font script="Gujr" typeface="Shruti"/><a:font script="Khmr" typeface="MoolBoran"/><a:font script="Knda" typeface="Tunga"/><a:font script="Guru" typeface="Raavi"/><a:font script="Cans" typeface="Euphemia"/><a:font script="Cher" typeface="Plantagenet Cherokee"/><a:font script="Yiii" typeface="Microsoft Yi Baiti"/><a:font script="Tibt" typeface="Microsoft Himalaya"/><a:font script="Thaa" typeface="MV Boli"/><a:font script="Deva" typeface="Mangal"/><a:font script="Telu" typeface="Gautami"/><a:font script="Taml" typeface="Latha"/><a:font script="Syrc" typeface="Estrangelo Edessa"/><a:font script="Orya" typeface="Kalinga"/><a:font script="Mlym" typeface="Kartika"/><a:font script="Laoo" typeface="DokChampa"/><a:font script="Sinh" typeface="Iskoola Pota"/><a:font script="Mong" typeface="Mongolian Baiti"/><a:font script="Viet" typeface="Times New Roman"/><a:font script="Uigh" typeface="Microsoft Uighur"/><a:font script="Geor" typeface="Sylfaen"/></a:majorFont><a:minorFont><a:latin typeface="Calibri"/><a:ea typeface=""/><a:cs typeface=""/><a:font script="Jpan" typeface="MS Pゴシック"/><a:font script="Hang" typeface="맑은 고딕"/><a:font script="Hans" typeface="宋体"/><a:font script="Hant" typeface="新細明體"/><a:font script="Arab" typeface="Arial"/><a:font script="Hebr" typeface="Arial"/><a:font script="Thai" typeface="Tahoma"/><a:font script="Ethi" typeface="Nyala"/><a:font script="Beng" typeface="Vrinda"/><a:font script="Gujr" typeface="Shruti"/><a:font script="Khmr" typeface="DaunPenh"/><a:font script="Knda" typeface="Tunga"/><a:font script="Guru" typeface="Raavi"/><a:font script="Cans" typeface="Euphemia"/><a:font script="Cher" typeface="Plantagenet Cherokee"/><a:font script="Yiii" typeface="Microsoft Yi Baiti"/><a:font script="Tibt" typeface="Microsoft Himalaya"/><a:font script="Thaa" typeface="MV Boli"/><a:font script="Deva" typeface="Mangal"/><a:font script="Telu" typeface="Gautami"/><a:font script="Taml" typeface="Latha"/><a:font script="Syrc" typeface="Estrangelo Edessa"/><a:font script="Orya" typeface="Kalinga"/><a:font script="Mlym" typeface="Kartika"/><a:font script="Laoo" typeface="DokChampa"/><a:font script="Sinh" typeface="Iskoola Pota"/><a:font script="Mong" typeface="Mongolian Baiti"/><a:font script="Viet" typeface="Arial"/><a:font script="Uigh" typeface="Microsoft Uighur"/><a:font script="Geor" typeface="Sylfaen"/></a:minorFont></a:fontScheme><a:fmtScheme name="Office"><a:fillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="50000"/><a:satMod val="300000"/></a:schemeClr></a:gs><a:gs pos="35000"><a:schemeClr val="phClr"><a:tint val="37000"/><a:satMod val="300000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:tint val="15000"/><a:satMod val="350000"/></a:schemeClr></a:gs></a:gsLst><a:lin ang="16200000" scaled="1"/></a:gradFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="100000"/><a:shade val="100000"/><a:satMod val="130000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:tint val="50000"/><a:shade val="100000"/><a:satMod val="350000"/></a:schemeClr></a:gs></a:gsLst><a:lin ang="16200000" scaled="0"/></a:gradFill></a:fillStyleLst><a:lnStyleLst><a:ln w="9525" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"><a:shade val="95000"/><a:satMod val="105000"/></a:schemeClr></a:solidFill><a:prstDash val="solid"/></a:ln><a:ln w="25400" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/></a:ln><a:ln w="38100" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/></a:ln></a:lnStyleLst><a:effectStyleLst><a:effectStyle><a:effectLst><a:outerShdw blurRad="40000" dist="20000" dir="5400000" rotWithShape="0"><a:srgbClr val="000000"><a:alpha val="38000"/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle><a:effectStyle><a:effectLst><a:outerShdw blurRad="40000" dist="23000" dir="5400000" rotWithShape="0"><a:srgbClr val="000000"><a:alpha val="35000"/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle><a:effectStyle><a:effectLst><a:outerShdw blurRad="40000" dist="23000" dir="5400000" rotWithShape="0"><a:srgbClr val="000000"><a:alpha val="35000"/></a:srgbClr></a:outerShdw></a:effectLst><a:scene3d><a:camera prst="orthographicFront"><a:rot lat="0" lon="0" rev="0"/></a:camera><a:lightRig rig="threePt" dir="t"><a:rot lat="0" lon="0" rev="1200000"/></a:lightRig></a:scene3d><a:sp3d><a:bevelT w="63500" h="25400"/></a:sp3d></a:effectStyle></a:effectStyleLst><a:bgFillStyleLst><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="40000"/><a:satMod val="350000"/></a:schemeClr></a:gs><a:gs pos="40000"><a:schemeClr val="phClr"><a:tint val="45000"/><a:shade val="99000"/><a:satMod val="350000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:shade val="20000"/><a:satMod val="255000"/></a:schemeClr></a:gs></a:gsLst><a:path path="circle"><a:fillToRect l="50000" t="-80000" r="50000" b="180000"/></a:path></a:gradFill><a:gradFill rotWithShape="1"><a:gsLst><a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="80000"/><a:satMod val="300000"/></a:schemeClr></a:gs><a:gs pos="100000"><a:schemeClr val="phClr"><a:shade val="30000"/><a:satMod val="200000"/></a:schemeClr></a:gs></a:gsLst><a:path path="circle"><a:fillToRect l="50000" t="50000" r="50000" b="50000"/></a:path></a:gradFill></a:bgFillStyleLst></a:fmtScheme></a:themeElements><a:objectDefaults><a:spDef><a:spPr/><a:bodyPr/><a:lstStyle/><a:style><a:lnRef idx="1"><a:schemeClr val="accent1"/></a:lnRef><a:fillRef idx="3"><a:schemeClr val="accent1"/></a:fillRef><a:effectRef idx="2"><a:schemeClr val="accent1"/></a:effectRef><a:fontRef idx="minor"><a:schemeClr val="lt1"/></a:fontRef></a:style></a:spDef><a:lnDef><a:spPr/><a:bodyPr/><a:lstStyle/><a:style><a:lnRef idx="2"><a:schemeClr val="accent1"/></a:lnRef><a:fillRef idx="0"><a:schemeClr val="accent1"/></a:fillRef><a:effectRef idx="1"><a:schemeClr val="accent1"/></a:effectRef><a:fontRef idx="minor"><a:schemeClr val="tx1"/></a:fontRef></a:style></a:lnDef></a:objectDefaults><a:extraClrSchemeLst/></a:theme>'; }
28372 /* 18.6 Calculation Chain */
28373 function parse_cc_xml(data, opts) {
28374 var d = [];
28375 var l = 0, i = 1;
28376 (data.match(tagregex)||[]).forEach(function(x) {
28377 var y = parsexmltag(x);
28378 switch(y[0]) {
28379 case '<?xml': break;
28380 /* 18.6.2 calcChain CT_CalcChain 1 */
28381 case '<calcChain': case '<calcChain>': case '</calcChain>': break;
28382 /* 18.6.1 c CT_CalcCell 1 */
28383 case '<c': delete y[0]; if(y.i) i = y.i; else y.i = i; d.push(y); break;
28384 }
28385 });
28386 return d;
28387 }
28388
28389 function write_cc_xml(data, opts) { }
28390 /* [MS-XLSB] 2.6.4.1 */
28391 function parse_BrtCalcChainItem$(data, length) {
28392 var out = {};
28393 out.i = data.read_shift(4);
28394 var cell = {};
28395 cell.r = data.read_shift(4);
28396 cell.c = data.read_shift(4);
28397 out.r = encode_cell(cell);
28398 var flags = data.read_shift(1);
28399 if(flags & 0x2) out.l = '1';
28400 if(flags & 0x8) out.a = '1';
28401 return out;
28402 }
28403
28404 /* 18.6 Calculation Chain */
28405 function parse_cc_bin(data, opts) {
28406 var out = [];
28407 var pass = false;
28408 recordhopper(data, function hopper_cc(val, R, RT) {
28409 switch(R.n) {
28410 case 'BrtCalcChainItem$': out.push(val); break;
28411 case 'BrtBeginCalcChain$': break;
28412 case 'BrtEndCalcChain$': break;
28413 default: if(!pass || opts.WTF) throw new Error("Unexpected record " + RT + " " + R.n);
28414 }
28415 });
28416 return out;
28417 }
28418
28419 function write_cc_bin(data, opts) { }
28420
28421 function parse_comments(zip, dirComments, sheets, sheetRels, opts) {
28422 for(var i = 0; i != dirComments.length; ++i) {
28423 var canonicalpath=dirComments[i];
28424 var comments=parse_cmnt(getzipdata(zip, canonicalpath.replace(/^\//,''), true), canonicalpath, opts);
28425 if(!comments || !comments.length) continue;
28426 // find the sheets targeted by these comments
28427 var sheetNames = keys(sheets);
28428 for(var j = 0; j != sheetNames.length; ++j) {
28429 var sheetName = sheetNames[j];
28430 var rels = sheetRels[sheetName];
28431 if(rels) {
28432 var rel = rels[canonicalpath];
28433 if(rel) insertCommentsIntoSheet(sheetName, sheets[sheetName], comments);
28434 }
28435 }
28436 }
28437 }
28438
28439 function insertCommentsIntoSheet(sheetName, sheet, comments) {
28440 comments.forEach(function(comment) {
28441 var cell = sheet[comment.ref];
28442 if (!cell) {
28443 cell = {};
28444 sheet[comment.ref] = cell;
28445 var range = safe_decode_range(sheet["!ref"]||"BDWGO1000001:A1");
28446 var thisCell = decode_cell(comment.ref);
28447 if(range.s.r > thisCell.r) range.s.r = thisCell.r;
28448 if(range.e.r < thisCell.r) range.e.r = thisCell.r;
28449 if(range.s.c > thisCell.c) range.s.c = thisCell.c;
28450 if(range.e.c < thisCell.c) range.e.c = thisCell.c;
28451 var encoded = encode_range(range);
28452 if (encoded !== sheet["!ref"]) sheet["!ref"] = encoded;
28453 }
28454
28455 if (!cell.c) cell.c = [];
28456 var o = {a: comment.author, t: comment.t, r: comment.r};
28457 if(comment.h) o.h = comment.h;
28458 cell.c.push(o);
28459 });
28460 }
28461
28462 /* 18.7.3 CT_Comment */
28463 function parse_comments_xml(data, opts) {
28464 if(data.match(/<(?:\w+:)?comments *\/>/)) return [];
28465 var authors = [];
28466 var commentList = [];
28467 data.match(/<(?:\w+:)?authors>([^\u2603]*)<\/(?:\w+:)?authors>/)[1].split(/<\/\w*:?author>/).forEach(function(x) {
28468 if(x === "" || x.trim() === "") return;
28469 authors.push(x.match(/<(?:\w+:)?author[^>]*>(.*)/)[1]);
28470 });
28471 (data.match(/<(?:\w+:)?commentList>([^\u2603]*)<\/(?:\w+:)?commentList>/)||["",""])[1].split(/<\/\w*:?comment>/).forEach(function(x, index) {
28472 if(x === "" || x.trim() === "") return;
28473 var y = parsexmltag(x.match(/<(?:\w+:)?comment[^>]*>/)[0]);
28474 var comment = { author: y.authorId && authors[y.authorId] ? authors[y.authorId] : undefined, ref: y.ref, guid: y.guid };
28475 var cell = decode_cell(y.ref);
28476 if(opts.sheetRows && opts.sheetRows <= cell.r) return;
28477 var textMatch = x.match(/<text>([^\u2603]*)<\/text>/);
28478 if (!textMatch || !textMatch[1]) return; // a comment may contain an empty text tag.
28479 var rt = parse_si(textMatch[1]);
28480 comment.r = rt.r;
28481 comment.t = rt.t;
28482 if(opts.cellHTML) comment.h = rt.h;
28483 commentList.push(comment);
28484 });
28485 return commentList;
28486 }
28487
28488 function write_comments_xml(data, opts) { }
28489 /* [MS-XLSB] 2.4.28 BrtBeginComment */
28490 function parse_BrtBeginComment(data, length) {
28491 var out = {};
28492 out.iauthor = data.read_shift(4);
28493 var rfx = parse_UncheckedRfX(data, 16);
28494 out.rfx = rfx.s;
28495 out.ref = encode_cell(rfx.s);
28496 data.l += 16; /*var guid = parse_GUID(data); */
28497 return out;
28498 }
28499
28500 /* [MS-XLSB] 2.4.324 BrtCommentAuthor */
28501 var parse_BrtCommentAuthor = parse_XLWideString;
28502
28503 /* [MS-XLSB] 2.4.325 BrtCommentText */
28504 var parse_BrtCommentText = parse_RichStr;
28505
28506 /* [MS-XLSB] 2.1.7.8 Comments */
28507 function parse_comments_bin(data, opts) {
28508 var out = [];
28509 var authors = [];
28510 var c = {};
28511 var pass = false;
28512 recordhopper(data, function hopper_cmnt(val, R, RT) {
28513 switch(R.n) {
28514 case 'BrtCommentAuthor': authors.push(val); break;
28515 case 'BrtBeginComment': c = val; break;
28516 case 'BrtCommentText': c.t = val.t; c.h = val.h; c.r = val.r; break;
28517 case 'BrtEndComment':
28518 c.author = authors[c.iauthor];
28519 delete c.iauthor;
28520 if(opts.sheetRows && opts.sheetRows <= c.rfx.r) break;
28521 delete c.rfx; out.push(c); break;
28522 case 'BrtBeginComments': break;
28523 case 'BrtEndComments': break;
28524 case 'BrtBeginCommentAuthors': break;
28525 case 'BrtEndCommentAuthors': break;
28526 case 'BrtBeginCommentList': break;
28527 case 'BrtEndCommentList': break;
28528 default: if(!pass || opts.WTF) throw new Error("Unexpected record " + RT + " " + R.n);
28529 }
28530 });
28531 return out;
28532 }
28533
28534 function write_comments_bin(data, opts) { }
28535 /* [MS-XLSB] 2.5.97.4 CellParsedFormula TODO: use similar logic to js-xls */
28536 function parse_CellParsedFormula(data, length) {
28537 var cce = data.read_shift(4);
28538 return parsenoop(data, length-4);
28539 }
28540 var strs = {}; // shared strings
28541 var _ssfopts = {}; // spreadsheet formatting options
28542
28543 RELS.WS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet";
28544
28545 function get_sst_id(sst, str) {
28546 for(var i = 0, len = sst.length; i < len; ++i) if(sst[i].t === str) { sst.Count ++; return i; }
28547 sst[len] = {t:str}; sst.Count ++; sst.Unique ++; return len;
28548 }
28549
28550 function get_cell_style(styles, cell, opts) {
28551 var z = opts.revssf[cell.z != null ? cell.z : "General"];
28552 for(var i = 0, len = styles.length; i != len; ++i) if(styles[i].numFmtId === z) return i;
28553 styles[len] = {
28554 numFmtId:z,
28555 fontId:0,
28556 fillId:0,
28557 borderId:0,
28558 xfId:0,
28559 applyNumberFormat:1
28560 };
28561 return len;
28562 }
28563
28564 function safe_format(p, fmtid, fillid, opts) {
28565 try {
28566 if(fmtid === 0) {
28567 if(p.t === 'n') {
28568 if((p.v|0) === p.v) p.w = SSF._general_int(p.v,_ssfopts);
28569 else p.w = SSF._general_num(p.v,_ssfopts);
28570 }
28571 else if(p.v === undefined) return "";
28572 else p.w = SSF._general(p.v,_ssfopts);
28573 }
28574 else p.w = SSF.format(fmtid,p.v,_ssfopts);
28575 if(opts.cellNF) p.z = SSF._table[fmtid];
28576 } catch(e) { if(opts.WTF) throw e; }
28577 if(fillid) try {
28578 p.s = styles.Fills[fillid];
28579 if (p.s.fgColor && p.s.fgColor.theme) {
28580 p.s.fgColor.rgb = rgb_tint(themes.themeElements.clrScheme[p.s.fgColor.theme].rgb, p.s.fgColor.tint || 0);
28581 if(opts.WTF) p.s.fgColor.raw_rgb = themes.themeElements.clrScheme[p.s.fgColor.theme].rgb;
28582 }
28583 if (p.s.bgColor && p.s.bgColor.theme) {
28584 p.s.bgColor.rgb = rgb_tint(themes.themeElements.clrScheme[p.s.bgColor.theme].rgb, p.s.bgColor.tint || 0);
28585 if(opts.WTF) p.s.bgColor.raw_rgb = themes.themeElements.clrScheme[p.s.bgColor.theme].rgb;
28586 }
28587 } catch(e) { if(opts.WTF) throw e; }
28588 }
28589 function parse_ws_xml_dim(ws, s) {
28590 var d = safe_decode_range(s);
28591 if(d.s.r<=d.e.r && d.s.c<=d.e.c && d.s.r>=0 && d.s.c>=0) ws["!ref"] = encode_range(d);
28592 }
28593 var mergecregex = /<mergeCell ref="[A-Z0-9:]+"\s*\/>/g;
28594 var sheetdataregex = /<(?:\w+:)?sheetData>([^\u2603]*)<\/(?:\w+:)?sheetData>/;
28595 var hlinkregex = /<hyperlink[^>]*\/>/g;
28596 var dimregex = /"(\w*:\w*)"/;
28597 var colregex = /<col[^>]*\/>/g;
28598 /* 18.3 Worksheets */
28599 function parse_ws_xml(data, opts, rels) {
28600 if(!data) return data;
28601 /* 18.3.1.99 worksheet CT_Worksheet */
28602 var s = {};
28603
28604 /* 18.3.1.35 dimension CT_SheetDimension ? */
28605 var ridx = data.indexOf("<dimension");
28606 if(ridx > 0) {
28607 var ref = data.substr(ridx,50).match(dimregex);
28608 if(ref != null) parse_ws_xml_dim(s, ref[1]);
28609 }
28610
28611 /* 18.3.1.55 mergeCells CT_MergeCells */
28612 var mergecells = [];
28613 if(data.indexOf("</mergeCells>")!==-1) {
28614 var merges = data.match(mergecregex);
28615 for(ridx = 0; ridx != merges.length; ++ridx)
28616 mergecells[ridx] = safe_decode_range(merges[ridx].substr(merges[ridx].indexOf("\"")+1));
28617 }
28618
28619 /* 18.3.1.17 cols CT_Cols */
28620 var columns = [];
28621 if(opts.cellStyles && data.indexOf("</cols>")!==-1) {
28622 /* 18.3.1.13 col CT_Col */
28623 var cols = data.match(colregex);
28624 parse_ws_xml_cols(columns, cols);
28625 }
28626
28627 var refguess = {s: {r:1000000, c:1000000}, e: {r:0, c:0} };
28628
28629 /* 18.3.1.80 sheetData CT_SheetData ? */
28630 var mtch=data.match(sheetdataregex);
28631 if(mtch) parse_ws_xml_data(mtch[1], s, opts, refguess);
28632
28633 /* 18.3.1.48 hyperlinks CT_Hyperlinks */
28634 if(data.indexOf("</hyperlinks>")!==-1) parse_ws_xml_hlinks(s, data.match(hlinkregex), rels);
28635
28636 if(!s["!ref"] && refguess.e.c >= refguess.s.c && refguess.e.r >= refguess.s.r) s["!ref"] = encode_range(refguess);
28637 if(opts.sheetRows > 0 && s["!ref"]) {
28638 var tmpref = safe_decode_range(s["!ref"]);
28639 if(opts.sheetRows < +tmpref.e.r) {
28640 tmpref.e.r = opts.sheetRows - 1;
28641 if(tmpref.e.r > refguess.e.r) tmpref.e.r = refguess.e.r;
28642 if(tmpref.e.r < tmpref.s.r) tmpref.s.r = tmpref.e.r;
28643 if(tmpref.e.c > refguess.e.c) tmpref.e.c = refguess.e.c;
28644 if(tmpref.e.c < tmpref.s.c) tmpref.s.c = tmpref.e.c;
28645 s["!fullref"] = s["!ref"];
28646 s["!ref"] = encode_range(tmpref);
28647 }
28648 }
28649 if(mergecells.length > 0) s["!merges"] = mergecells;
28650 if(columns.length > 0) s["!cols"] = columns;
28651 return s;
28652 }
28653
28654
28655 function parse_ws_xml_hlinks(s, data, rels) {
28656 for(var i = 0; i != data.length; ++i) {
28657 var val = parsexmltag(data[i], true);
28658 if(!val.ref) return;
28659 var rel = rels['!id'][val.id];
28660 if(rel) {
28661 val.Target = rel.Target;
28662 if(val.location) val.Target += "#"+val.location;
28663 val.Rel = rel;
28664 }
28665 var rng = safe_decode_range(val.ref);
28666 for(var R=rng.s.r;R<=rng.e.r;++R) for(var C=rng.s.c;C<=rng.e.c;++C) {
28667 var addr = encode_cell({c:C,r:R});
28668 if(!s[addr]) s[addr] = {t:"str",v:undefined};
28669 s[addr].l = val;
28670 }
28671 }
28672 }
28673
28674 function parse_ws_xml_cols(columns, cols) {
28675 var seencol = false;
28676 for(var coli = 0; coli != cols.length; ++coli) {
28677 var coll = parsexmltag(cols[coli], true);
28678 var colm=parseInt(coll.min, 10)-1, colM=parseInt(coll.max,10)-1;
28679 delete coll.min; delete coll.max;
28680 if(!seencol && coll.width) { seencol = true; find_mdw(+coll.width, coll); }
28681 if(coll.width) {
28682 coll.wpx = width2px(+coll.width);
28683 coll.wch = px2char(coll.wpx);
28684 coll.MDW = MDW;
28685 }
28686 while(colm <= colM) columns[colm++] = coll;
28687 }
28688 }
28689
28690 function write_ws_xml_cols(ws, cols) {
28691 var o = ["<cols>"], col, width;
28692 for(var i = 0; i != cols.length; ++i) {
28693 if(!(col = cols[i])) continue;
28694 var p = {min:i+1,max:i+1};
28695 /* wch (chars), wpx (pixels) */
28696 width = -1;
28697 if(col.wpx) width = px2char(col.wpx);
28698 else if(col.wch) width = col.wch;
28699 if(width > -1) { p.width = char2width(width); p.customWidth= 1; }
28700 o[o.length] = (writextag('col', null, p));
28701 }
28702 o[o.length] = "</cols>";
28703 return o.join("");
28704 }
28705
28706 function write_ws_xml_cell(cell, ref, ws, opts, idx, wb) {
28707 if(cell.v === undefined) return "";
28708 var vv = "";
28709 switch(cell.t) {
28710 case 'b': vv = cell.v ? "1" : "0"; break;
28711 case 'n': case 'e': vv = ''+cell.v; break;
28712 default: vv = cell.v; break;
28713 }
28714 var v = writetag('v', escapexml(vv)), o = {r:ref};
28715 /* TODO: cell style */
28716 var os = get_cell_style(opts.cellXfs, cell, opts);
28717 if(os !== 0) o.s = os;
28718 switch(cell.t) {
28719 case 'n': break;
28720 case 'b': o.t = "b"; break;
28721 case 'e': o.t = "e"; break;
28722 default:
28723 if(opts.bookSST) {
28724 v = writetag('v', ''+get_sst_id(opts.Strings, cell.v));
28725 o.t = "s"; break;
28726 }
28727 o.t = "str"; break;
28728 }
28729 return writextag('c', v, o);
28730 }
28731
28732 var parse_ws_xml_data = (function parse_ws_xml_data_factory() {
28733 var cellregex = /<(?:\w+:)?c /, rowregex = /<\/(?:\w+:)?row>/;
28734 var rregex = /r=["']([^"']*)["']/, isregex = /<is>([\S\s]*?)<\/is>/;
28735 var match_v = matchtag("v"), match_f = matchtag("f");
28736
28737 return function parse_ws_xml_data(sdata, s, opts, guess) {
28738 var ri = 0, x = "", cells = [], cref = [], idx = 0, i=0, cc=0, d="", p;
28739 var tag;
28740 var sstr;
28741 var fmtid = 0, fillid = 0, do_format = Array.isArray(styles.CellXf), cf;
28742 for(var marr = sdata.split(rowregex), mt = 0, marrlen = marr.length; mt != marrlen; ++mt) {
28743 x = marr[mt].trim();
28744 var xlen = x.length;
28745 if(xlen === 0) continue;
28746
28747 /* 18.3.1.73 row CT_Row */
28748 for(ri = 0; ri < xlen; ++ri) if(x.charCodeAt(ri) === 62) break; ++ri;
28749 tag = parsexmltag(x.substr(0,ri), true);
28750 var tagr = parseInt(tag.r, 10);
28751 if(opts.sheetRows && opts.sheetRows < tagr) continue;
28752 if(guess.s.r > tagr - 1) guess.s.r = tagr - 1;
28753 if(guess.e.r < tagr - 1) guess.e.r = tagr - 1;
28754
28755 /* 18.3.1.4 c CT_Cell */
28756 cells = x.substr(ri).split(cellregex);
28757 for(ri = 1, cellen = cells.length; ri != cellen; ++ri) {
28758 x = cells[ri].trim();
28759 if(x.length === 0) continue;
28760 cref = x.match(rregex); idx = ri; i=0; cc=0;
28761 x = "<c " + x;
28762 if(cref !== null && cref.length === 2) {
28763 idx = 0; d=cref[1];
28764 for(i=0; i != d.length; ++i) {
28765 if((cc=d.charCodeAt(i)-64) < 1 || cc > 26) break;
28766 idx = 26*idx + cc;
28767 }
28768 --idx;
28769 }
28770
28771 for(i = 0; i != x.length; ++i) if(x.charCodeAt(i) === 62) break; ++i;
28772 tag = parsexmltag(x.substr(0,i), true);
28773 d = x.substr(i);
28774 p = {t:""};
28775
28776 if((cref=d.match(match_v))!== null) p.v=unescapexml(cref[1]);
28777 if(opts.cellFormula && (cref=d.match(match_f))!== null) p.f=unescapexml(cref[1]);
28778
28779 /* SCHEMA IS ACTUALLY INCORRECT HERE. IF A CELL HAS NO T, EMIT "" */
28780 if(tag.t === undefined && p.v === undefined) {
28781 if(!opts.sheetStubs) continue;
28782 p.t = "str";
28783 }
28784 else p.t = tag.t || "n";
28785 if(guess.s.c > idx) guess.s.c = idx;
28786 if(guess.e.c < idx) guess.e.c = idx;
28787 /* 18.18.11 t ST_CellType */
28788 switch(p.t) {
28789 case 'n': p.v = parseFloat(p.v); break;
28790 case 's':
28791 sstr = strs[parseInt(p.v, 10)];
28792 p.v = sstr.t;
28793 p.r = sstr.r;
28794 if(opts.cellHTML) p.h = sstr.h;
28795 break;
28796 case 'str': if(p.v != null) p.v = utf8read(p.v); else p.v = ""; break;
28797 case 'inlineStr':
28798 cref = d.match(isregex);
28799 p.t = 'str';
28800 if(cref !== null) { sstr = parse_si(cref[1]); p.v = sstr.t; } else p.v = "";
28801 break; // inline string
28802 case 'b': p.v = parsexmlbool(p.v); break;
28803 case 'd':
28804 p.v = datenum(p.v);
28805 p.t = 'n';
28806 break;
28807 /* in case of error, stick value in .raw */
28808 case 'e': p.raw = RBErr[p.v]; break;
28809 }
28810 /* formatting */
28811 fmtid = fillid = 0;
28812 if(do_format && tag.s !== undefined) {
28813 cf = styles.CellXf[tag.s];
28814 if(cf != null) {
28815 if(cf.numFmtId != null) fmtid = cf.numFmtId;
28816 if(opts.cellStyles && cf.fillId != null) fillid = cf.fillId;
28817 }
28818 }
28819 safe_format(p, fmtid, fillid, opts);
28820 s[tag.r] = p;
28821 }
28822 }
28823 }; })();
28824
28825 function write_ws_xml_data(ws, opts, idx, wb) {
28826 var o = [], r = [], range = safe_decode_range(ws['!ref']), cell, ref, rr = "", cols = [], R, C;
28827 for(C = range.s.c; C <= range.e.c; ++C) cols[C] = encode_col(C);
28828 for(R = range.s.r; R <= range.e.r; ++R) {
28829 r = [];
28830 rr = encode_row(R);
28831 for(C = range.s.c; C <= range.e.c; ++C) {
28832 ref = cols[C] + rr;
28833 if(ws[ref] === undefined) continue;
28834 if((cell = write_ws_xml_cell(ws[ref], ref, ws, opts, idx, wb)) != null) r.push(cell);
28835 }
28836 if(r.length > 0) o[o.length] = (writextag('row', r.join(""), {r:rr}));
28837 }
28838 return o.join("");
28839 }
28840
28841 var WS_XML_ROOT = writextag('worksheet', null, {
28842 'xmlns': XMLNS.main[0],
28843 'xmlns:r': XMLNS.r
28844 });
28845
28846 function write_ws_xml(idx, opts, wb) {
28847 var o = [XML_HEADER, WS_XML_ROOT];
28848 var s = wb.SheetNames[idx], sidx = 0, rdata = "";
28849 var ws = wb.Sheets[s];
28850 if(ws === undefined) ws = {};
28851 var ref = ws['!ref']; if(ref === undefined) ref = 'A1';
28852 o[o.length] = (writextag('dimension', null, {'ref': ref}));
28853
28854 if(ws['!cols'] !== undefined && ws['!cols'].length > 0) o[o.length] = (write_ws_xml_cols(ws, ws['!cols']));
28855 o[sidx = o.length] = '<sheetData/>';
28856 if(ws['!ref'] !== undefined) {
28857 rdata = write_ws_xml_data(ws, opts, idx, wb);
28858 if(rdata.length > 0) o[o.length] = (rdata);
28859 }
28860 if(o.length>sidx+1) { o[o.length] = ('</sheetData>'); o[sidx]=o[sidx].replace("/>",">"); }
28861
28862 if(o.length>2) { o[o.length] = ('</worksheet>'); o[1]=o[1].replace("/>",">"); }
28863 return o.join("");
28864 }
28865
28866 /* [MS-XLSB] 2.4.718 BrtRowHdr */
28867 function parse_BrtRowHdr(data, length) {
28868 var z = [];
28869 z.r = data.read_shift(4);
28870 data.l += length-4;
28871 return z;
28872 }
28873
28874 /* [MS-XLSB] 2.4.812 BrtWsDim */
28875 var parse_BrtWsDim = parse_UncheckedRfX;
28876 var write_BrtWsDim = write_UncheckedRfX;
28877
28878 /* [MS-XLSB] 2.4.815 BrtWsProp */
28879 function parse_BrtWsProp(data, length) {
28880 var z = {};
28881 /* TODO: pull flags */
28882 data.l += 19;
28883 z.name = parse_CodeName(data, length - 19);
28884 return z;
28885 }
28886
28887 /* [MS-XLSB] 2.4.303 BrtCellBlank */
28888 function parse_BrtCellBlank(data, length) {
28889 var cell = parse_Cell(data);
28890 return [cell];
28891 }
28892 function write_BrtCellBlank(cell, val, o) {
28893 if(o == null) o = new_buf(8);
28894 return write_Cell(val, o);
28895 }
28896
28897
28898 /* [MS-XLSB] 2.4.304 BrtCellBool */
28899 function parse_BrtCellBool(data, length) {
28900 var cell = parse_Cell(data);
28901 var fBool = data.read_shift(1);
28902 return [cell, fBool, 'b'];
28903 }
28904
28905 /* [MS-XLSB] 2.4.305 BrtCellError */
28906 function parse_BrtCellError(data, length) {
28907 var cell = parse_Cell(data);
28908 var fBool = data.read_shift(1);
28909 return [cell, fBool, 'e'];
28910 }
28911
28912 /* [MS-XLSB] 2.4.308 BrtCellIsst */
28913 function parse_BrtCellIsst(data, length) {
28914 var cell = parse_Cell(data);
28915 var isst = data.read_shift(4);
28916 return [cell, isst, 's'];
28917 }
28918
28919 /* [MS-XLSB] 2.4.310 BrtCellReal */
28920 function parse_BrtCellReal(data, length) {
28921 var cell = parse_Cell(data);
28922 var value = parse_Xnum(data);
28923 return [cell, value, 'n'];
28924 }
28925
28926 /* [MS-XLSB] 2.4.311 BrtCellRk */
28927 function parse_BrtCellRk(data, length) {
28928 var cell = parse_Cell(data);
28929 var value = parse_RkNumber(data);
28930 return [cell, value, 'n'];
28931 }
28932
28933 /* [MS-XLSB] 2.4.314 BrtCellSt */
28934 function parse_BrtCellSt(data, length) {
28935 var cell = parse_Cell(data);
28936 var value = parse_XLWideString(data);
28937 return [cell, value, 'str'];
28938 }
28939
28940 /* [MS-XLSB] 2.4.647 BrtFmlaBool */
28941 function parse_BrtFmlaBool(data, length, opts) {
28942 var cell = parse_Cell(data);
28943 var value = data.read_shift(1);
28944 var o = [cell, value, 'b'];
28945 if(opts.cellFormula) {
28946 var formula = parse_CellParsedFormula(data, length-9);
28947 o[3] = ""; /* TODO */
28948 }
28949 else data.l += length-9;
28950 return o;
28951 }
28952
28953 /* [MS-XLSB] 2.4.648 BrtFmlaError */
28954 function parse_BrtFmlaError(data, length, opts) {
28955 var cell = parse_Cell(data);
28956 var value = data.read_shift(1);
28957 var o = [cell, value, 'e'];
28958 if(opts.cellFormula) {
28959 var formula = parse_CellParsedFormula(data, length-9);
28960 o[3] = ""; /* TODO */
28961 }
28962 else data.l += length-9;
28963 return o;
28964 }
28965
28966 /* [MS-XLSB] 2.4.649 BrtFmlaNum */
28967 function parse_BrtFmlaNum(data, length, opts) {
28968 var cell = parse_Cell(data);
28969 var value = parse_Xnum(data);
28970 var o = [cell, value, 'n'];
28971 if(opts.cellFormula) {
28972 var formula = parse_CellParsedFormula(data, length - 16);
28973 o[3] = ""; /* TODO */
28974 }
28975 else data.l += length-16;
28976 return o;
28977 }
28978
28979 /* [MS-XLSB] 2.4.650 BrtFmlaString */
28980 function parse_BrtFmlaString(data, length, opts) {
28981 var start = data.l;
28982 var cell = parse_Cell(data);
28983 var value = parse_XLWideString(data);
28984 var o = [cell, value, 'str'];
28985 if(opts.cellFormula) {
28986 var formula = parse_CellParsedFormula(data, start + length - data.l);
28987 }
28988 else data.l = start + length;
28989 return o;
28990 }
28991
28992 /* [MS-XLSB] 2.4.676 BrtMergeCell */
28993 var parse_BrtMergeCell = parse_UncheckedRfX;
28994
28995 /* [MS-XLSB] 2.4.656 BrtHLink */
28996 function parse_BrtHLink(data, length, opts) {
28997 var end = data.l + length;
28998 var rfx = parse_UncheckedRfX(data, 16);
28999 var relId = parse_XLNullableWideString(data);
29000 var loc = parse_XLWideString(data);
29001 var tooltip = parse_XLWideString(data);
29002 var display = parse_XLWideString(data);
29003 data.l = end;
29004 return {rfx:rfx, relId:relId, loc:loc, tooltip:tooltip, display:display};
29005 }
29006
29007 /* [MS-XLSB] 2.1.7.61 Worksheet */
29008 function parse_ws_bin(data, opts, rels) {
29009 if(!data) return data;
29010 if(!rels) rels = {'!id':{}};
29011 var s = {};
29012
29013 var ref;
29014 var refguess = {s: {r:1000000, c:1000000}, e: {r:0, c:0} };
29015
29016 var pass = false, end = false;
29017 var row, p, cf, R, C, addr, sstr, rr;
29018 var mergecells = [];
29019 recordhopper(data, function ws_parse(val, R) {
29020 if(end) return;
29021 switch(R.n) {
29022 case 'BrtWsDim': ref = val; break;
29023 case 'BrtRowHdr':
29024 row = val;
29025 if(opts.sheetRows && opts.sheetRows <= row.r) end=true;
29026 rr = encode_row(row.r);
29027 break;
29028
29029 case 'BrtFmlaBool':
29030 case 'BrtFmlaError':
29031 case 'BrtFmlaNum':
29032 case 'BrtFmlaString':
29033 case 'BrtCellBool':
29034 case 'BrtCellError':
29035 case 'BrtCellIsst':
29036 case 'BrtCellReal':
29037 case 'BrtCellRk':
29038 case 'BrtCellSt':
29039 p = {t:val[2]};
29040 switch(val[2]) {
29041 case 'n': p.v = val[1]; break;
29042 case 's': sstr = strs[val[1]]; p.v = sstr.t; p.r = sstr.r; break;
29043 case 'b': p.v = val[1] ? true : false; break;
29044 case 'e': p.raw = val[1]; p.v = BErr[p.raw]; break;
29045 case 'str': p.v = utf8read(val[1]); break;
29046 }
29047 if(opts.cellFormula && val.length > 3) p.f = val[3];
29048 if((cf = styles.CellXf[val[0].iStyleRef])) safe_format(p,cf.ifmt,null,opts);
29049 s[encode_col(C=val[0].c) + rr] = p;
29050 if(refguess.s.r > row.r) refguess.s.r = row.r;
29051 if(refguess.s.c > C) refguess.s.c = C;
29052 if(refguess.e.r < row.r) refguess.e.r = row.r;
29053 if(refguess.e.c < C) refguess.e.c = C;
29054 break;
29055
29056 case 'BrtCellBlank': if(!opts.sheetStubs) break;
29057 p = {t:'str',v:undefined};
29058 s[encode_col(C=val[0].c) + rr] = p;
29059 if(refguess.s.r > row.r) refguess.s.r = row.r;
29060 if(refguess.s.c > C) refguess.s.c = C;
29061 if(refguess.e.r < row.r) refguess.e.r = row.r;
29062 if(refguess.e.c < C) refguess.e.c = C;
29063 break;
29064
29065 /* Merge Cells */
29066 case 'BrtBeginMergeCells': break;
29067 case 'BrtEndMergeCells': break;
29068 case 'BrtMergeCell': mergecells.push(val); break;
29069
29070 case 'BrtHLink':
29071 var rel = rels['!id'][val.relId];
29072 if(rel) {
29073 val.Target = rel.Target;
29074 if(val.loc) val.Target += "#"+val.loc;
29075 val.Rel = rel;
29076 }
29077 for(R=val.rfx.s.r;R<=val.rfx.e.r;++R) for(C=val.rfx.s.c;C<=val.rfx.e.c;++C) {
29078 addr = encode_cell({c:C,r:R});
29079 if(!s[addr]) s[addr] = {t:"str",v:undefined};
29080 s[addr].l = val;
29081 }
29082 break;
29083
29084 case 'BrtArrFmla': break; // TODO
29085 case 'BrtShrFmla': break; // TODO
29086 case 'BrtBeginSheet': break;
29087 case 'BrtWsProp': break; // TODO
29088 case 'BrtSheetCalcProp': break; // TODO
29089 case 'BrtBeginWsViews': break; // TODO
29090 case 'BrtBeginWsView': break; // TODO
29091 case 'BrtPane': break; // TODO
29092 case 'BrtSel': break; // TODO
29093 case 'BrtEndWsView': break; // TODO
29094 case 'BrtEndWsViews': break; // TODO
29095 case 'BrtACBegin': break; // TODO
29096 case 'BrtRwDescent': break; // TODO
29097 case 'BrtACEnd': break; // TODO
29098 case 'BrtWsFmtInfoEx14': break; // TODO
29099 case 'BrtWsFmtInfo': break; // TODO
29100 case 'BrtBeginColInfos': break; // TODO
29101 case 'BrtColInfo': break; // TODO
29102 case 'BrtEndColInfos': break; // TODO
29103 case 'BrtBeginSheetData': break; // TODO
29104 case 'BrtEndSheetData': break; // TODO
29105 case 'BrtSheetProtection': break; // TODO
29106 case 'BrtPrintOptions': break; // TODO
29107 case 'BrtMargins': break; // TODO
29108 case 'BrtPageSetup': break; // TODO
29109 case 'BrtFRTBegin': pass = true; break;
29110 case 'BrtFRTEnd': pass = false; break;
29111 case 'BrtEndSheet': break; // TODO
29112 case 'BrtDrawing': break; // TODO
29113 case 'BrtLegacyDrawing': break; // TODO
29114 case 'BrtLegacyDrawingHF': break; // TODO
29115 case 'BrtPhoneticInfo': break; // TODO
29116 case 'BrtBeginHeaderFooter': break; // TODO
29117 case 'BrtEndHeaderFooter': break; // TODO
29118 case 'BrtBrk': break; // TODO
29119 case 'BrtBeginRwBrk': break; // TODO
29120 case 'BrtEndRwBrk': break; // TODO
29121 case 'BrtBeginColBrk': break; // TODO
29122 case 'BrtEndColBrk': break; // TODO
29123 case 'BrtBeginUserShViews': break; // TODO
29124 case 'BrtBeginUserShView': break; // TODO
29125 case 'BrtEndUserShView': break; // TODO
29126 case 'BrtEndUserShViews': break; // TODO
29127 case 'BrtBkHim': break; // TODO
29128 case 'BrtBeginOleObjects': break; // TODO
29129 case 'BrtOleObject': break; // TODO
29130 case 'BrtEndOleObjects': break; // TODO
29131 case 'BrtBeginListParts': break; // TODO
29132 case 'BrtListPart': break; // TODO
29133 case 'BrtEndListParts': break; // TODO
29134 case 'BrtBeginSortState': break; // TODO
29135 case 'BrtBeginSortCond': break; // TODO
29136 case 'BrtEndSortCond': break; // TODO
29137 case 'BrtEndSortState': break; // TODO
29138 case 'BrtBeginConditionalFormatting': break; // TODO
29139 case 'BrtEndConditionalFormatting': break; // TODO
29140 case 'BrtBeginCFRule': break; // TODO
29141 case 'BrtEndCFRule': break; // TODO
29142 case 'BrtBeginDVals': break; // TODO
29143 case 'BrtDVal': break; // TODO
29144 case 'BrtEndDVals': break; // TODO
29145 case 'BrtRangeProtection': break; // TODO
29146 case 'BrtBeginDCon': break; // TODO
29147 case 'BrtEndDCon': break; // TODO
29148 case 'BrtBeginDRefs': break;
29149 case 'BrtDRef': break;
29150 case 'BrtEndDRefs': break;
29151
29152 /* ActiveX */
29153 case 'BrtBeginActiveXControls': break;
29154 case 'BrtActiveX': break;
29155 case 'BrtEndActiveXControls': break;
29156
29157 /* AutoFilter */
29158 case 'BrtBeginAFilter': break;
29159 case 'BrtEndAFilter': break;
29160 case 'BrtBeginFilterColumn': break;
29161 case 'BrtBeginFilters': break;
29162 case 'BrtFilter': break;
29163 case 'BrtEndFilters': break;
29164 case 'BrtEndFilterColumn': break;
29165 case 'BrtDynamicFilter': break;
29166 case 'BrtTop10Filter': break;
29167 case 'BrtBeginCustomFilters': break;
29168 case 'BrtCustomFilter': break;
29169 case 'BrtEndCustomFilters': break;
29170
29171 /* Smart Tags */
29172 case 'BrtBeginSmartTags': break;
29173 case 'BrtBeginCellSmartTags': break;
29174 case 'BrtBeginCellSmartTag': break;
29175 case 'BrtCellSmartTagProperty': break;
29176 case 'BrtEndCellSmartTag': break;
29177 case 'BrtEndCellSmartTags': break;
29178 case 'BrtEndSmartTags': break;
29179
29180 /* Cell Watch */
29181 case 'BrtBeginCellWatches': break;
29182 case 'BrtCellWatch': break;
29183 case 'BrtEndCellWatches': break;
29184
29185 /* Table */
29186 case 'BrtTable': break;
29187
29188 /* Ignore Cell Errors */
29189 case 'BrtBeginCellIgnoreECs': break;
29190 case 'BrtCellIgnoreEC': break;
29191 case 'BrtEndCellIgnoreECs': break;
29192
29193 default: if(!pass || opts.WTF) throw new Error("Unexpected record " + R.n);
29194 }
29195 }, opts);
29196 if(!s["!ref"] && (refguess.s.r < 1000000 || ref.e.r > 0 || ref.e.c > 0 || ref.s.r > 0 || ref.s.c > 0)) s["!ref"] = encode_range(ref);
29197 if(opts.sheetRows && s["!ref"]) {
29198 var tmpref = safe_decode_range(s["!ref"]);
29199 if(opts.sheetRows < +tmpref.e.r) {
29200 tmpref.e.r = opts.sheetRows - 1;
29201 if(tmpref.e.r > refguess.e.r) tmpref.e.r = refguess.e.r;
29202 if(tmpref.e.r < tmpref.s.r) tmpref.s.r = tmpref.e.r;
29203 if(tmpref.e.c > refguess.e.c) tmpref.e.c = refguess.e.c;
29204 if(tmpref.e.c < tmpref.s.c) tmpref.s.c = tmpref.e.c;
29205 s["!fullref"] = s["!ref"];
29206 s["!ref"] = encode_range(tmpref);
29207 }
29208 }
29209 if(mergecells.length > 0) s["!merges"] = mergecells;
29210 return s;
29211 }
29212
29213 /* TODO: something useful -- this is a stub */
29214 function write_ws_bin_cell(ba, cell, R, C, opts) {
29215 if(cell.v === undefined) return "";
29216 var vv = "";
29217 switch(cell.t) {
29218 case 'b': vv = cell.v ? "1" : "0"; break;
29219 case 'n': case 'e': vv = ''+cell.v; break;
29220 default: vv = cell.v; break;
29221 }
29222 var o = {r:R, c:C};
29223 /* TODO: cell style */
29224 o.s = get_cell_style(opts.cellXfs, cell, opts);
29225 switch(cell.t) {
29226 case 's': case 'str':
29227 if(opts.bookSST) {
29228 vv = get_sst_id(opts.Strings, cell.v);
29229 o.t = "s"; break;
29230 }
29231 o.t = "str"; break;
29232 case 'n': break;
29233 case 'b': o.t = "b"; break;
29234 case 'e': o.t = "e"; break;
29235 }
29236 write_record(ba, "BrtCellBlank", write_BrtCellBlank(cell, o));
29237 }
29238
29239 function write_CELLTABLE(ba, ws, idx, opts, wb) {
29240 var range = safe_decode_range(ws['!ref'] || "A1"), ref, rr = "", cols = [];
29241 write_record(ba, 'BrtBeginSheetData');
29242 for(var R = range.s.r; R <= range.e.r; ++R) {
29243 rr = encode_row(R);
29244 /* [ACCELLTABLE] */
29245 /* BrtRowHdr */
29246 for(var C = range.s.c; C <= range.e.c; ++C) {
29247 /* *16384CELL */
29248 if(R === range.s.r) cols[C] = encode_col(C);
29249 ref = cols[C] + rr;
29250 if(!ws[ref]) continue;
29251 /* write cell */
29252 write_ws_bin_cell(ba, ws[ref], R, C, opts);
29253 }
29254 }
29255 write_record(ba, 'BrtEndSheetData');
29256 }
29257
29258 function write_ws_bin(idx, opts, wb) {
29259 var ba = buf_array();
29260 var s = wb.SheetNames[idx], ws = wb.Sheets[s] || {};
29261 var r = safe_decode_range(ws['!ref'] || "A1");
29262 write_record(ba, "BrtBeginSheet");
29263 /* [BrtWsProp] */
29264 write_record(ba, "BrtWsDim", write_BrtWsDim(r));
29265 /* [WSVIEWS2] */
29266 /* [WSFMTINFO] */
29267 /* *COLINFOS */
29268 write_CELLTABLE(ba, ws, idx, opts, wb);
29269 /* [BrtSheetCalcProp] */
29270 /* [[BrtSheetProtectionIso] BrtSheetProtection] */
29271 /* *([BrtRangeProtectionIso] BrtRangeProtection) */
29272 /* [SCENMAN] */
29273 /* [AUTOFILTER] */
29274 /* [SORTSTATE] */
29275 /* [DCON] */
29276 /* [USERSHVIEWS] */
29277 /* [MERGECELLS] */
29278 /* [BrtPhoneticInfo] */
29279 /* *CONDITIONALFORMATTING */
29280 /* [DVALS] */
29281 /* *BrtHLink */
29282 /* [BrtPrintOptions] */
29283 /* [BrtMargins] */
29284 /* [BrtPageSetup] */
29285 /* [HEADERFOOTER] */
29286 /* [RWBRK] */
29287 /* [COLBRK] */
29288 /* *BrtBigName */
29289 /* [CELLWATCHES] */
29290 /* [IGNOREECS] */
29291 /* [SMARTTAGS] */
29292 /* [BrtDrawing] */
29293 /* [BrtLegacyDrawing] */
29294 /* [BrtLegacyDrawingHF] */
29295 /* [BrtBkHim] */
29296 /* [OLEOBJECTS] */
29297 /* [ACTIVEXCONTROLS] */
29298 /* [WEBPUBITEMS] */
29299 /* [LISTPARTS] */
29300 /* FRTWORKSHEET */
29301 write_record(ba, "BrtEndSheet");
29302 return ba.end();
29303 }
29304 /* 18.2.28 (CT_WorkbookProtection) Defaults */
29305 var WBPropsDef = [
29306 ['allowRefreshQuery', '0'],
29307 ['autoCompressPictures', '1'],
29308 ['backupFile', '0'],
29309 ['checkCompatibility', '0'],
29310 ['codeName', ''],
29311 ['date1904', '0'],
29312 ['dateCompatibility', '1'],
29313 //['defaultThemeVersion', '0'],
29314 ['filterPrivacy', '0'],
29315 ['hidePivotFieldList', '0'],
29316 ['promptedSolutions', '0'],
29317 ['publishItems', '0'],
29318 ['refreshAllConnections', false],
29319 ['saveExternalLinkValues', '1'],
29320 ['showBorderUnselectedTables', '1'],
29321 ['showInkAnnotation', '1'],
29322 ['showObjects', 'all'],
29323 ['showPivotChartFilter', '0']
29324 //['updateLinks', 'userSet']
29325 ];
29326
29327 /* 18.2.30 (CT_BookView) Defaults */
29328 var WBViewDef = [
29329 ['activeTab', '0'],
29330 ['autoFilterDateGrouping', '1'],
29331 ['firstSheet', '0'],
29332 ['minimized', '0'],
29333 ['showHorizontalScroll', '1'],
29334 ['showSheetTabs', '1'],
29335 ['showVerticalScroll', '1'],
29336 ['tabRatio', '600'],
29337 ['visibility', 'visible']
29338 //window{Height,Width}, {x,y}Window
29339 ];
29340
29341 /* 18.2.19 (CT_Sheet) Defaults */
29342 var SheetDef = [
29343 ['state', 'visible']
29344 ];
29345
29346 /* 18.2.2 (CT_CalcPr) Defaults */
29347 var CalcPrDef = [
29348 ['calcCompleted', 'true'],
29349 ['calcMode', 'auto'],
29350 ['calcOnSave', 'true'],
29351 ['concurrentCalc', 'true'],
29352 ['fullCalcOnLoad', 'false'],
29353 ['fullPrecision', 'true'],
29354 ['iterate', 'false'],
29355 ['iterateCount', '100'],
29356 ['iterateDelta', '0.001'],
29357 ['refMode', 'A1']
29358 ];
29359
29360 /* 18.2.3 (CT_CustomWorkbookView) Defaults */
29361 var CustomWBViewDef = [
29362 ['autoUpdate', 'false'],
29363 ['changesSavedWin', 'false'],
29364 ['includeHiddenRowCol', 'true'],
29365 ['includePrintSettings', 'true'],
29366 ['maximized', 'false'],
29367 ['minimized', 'false'],
29368 ['onlySync', 'false'],
29369 ['personalView', 'false'],
29370 ['showComments', 'commIndicator'],
29371 ['showFormulaBar', 'true'],
29372 ['showHorizontalScroll', 'true'],
29373 ['showObjects', 'all'],
29374 ['showSheetTabs', 'true'],
29375 ['showStatusbar', 'true'],
29376 ['showVerticalScroll', 'true'],
29377 ['tabRatio', '600'],
29378 ['xWindow', '0'],
29379 ['yWindow', '0']
29380 ];
29381
29382 function push_defaults_array(target, defaults) {
29383 for(var j = 0; j != target.length; ++j) { var w = target[j];
29384 for(var i=0; i != defaults.length; ++i) { var z = defaults[i];
29385 if(w[z[0]] == null) w[z[0]] = z[1];
29386 }
29387 }
29388 }
29389 function push_defaults(target, defaults) {
29390 for(var i = 0; i != defaults.length; ++i) { var z = defaults[i];
29391 if(target[z[0]] == null) target[z[0]] = z[1];
29392 }
29393 }
29394
29395 function parse_wb_defaults(wb) {
29396 push_defaults(wb.WBProps, WBPropsDef);
29397 push_defaults(wb.CalcPr, CalcPrDef);
29398
29399 push_defaults_array(wb.WBView, WBViewDef);
29400 push_defaults_array(wb.Sheets, SheetDef);
29401
29402 _ssfopts.date1904 = parsexmlbool(wb.WBProps.date1904, 'date1904');
29403 }
29404 /* 18.2 Workbook */
29405 var wbnsregex = /<\w+:workbook/;
29406 function parse_wb_xml(data, opts) {
29407 var wb = { AppVersion:{}, WBProps:{}, WBView:[], Sheets:[], CalcPr:{}, xmlns: "" };
29408 var pass = false, xmlns = "xmlns";
29409 data.match(tagregex).forEach(function xml_wb(x) {
29410 var y = parsexmltag(x);
29411 switch(strip_ns(y[0])) {
29412 case '<?xml': break;
29413
29414 /* 18.2.27 workbook CT_Workbook 1 */
29415 case '<workbook':
29416 if(x.match(wbnsregex)) xmlns = "xmlns" + x.match(/<(\w+):/)[1];
29417 wb.xmlns = y[xmlns];
29418 break;
29419 case '</workbook>': break;
29420
29421 /* 18.2.13 fileVersion CT_FileVersion ? */
29422 case '<fileVersion': delete y[0]; wb.AppVersion = y; break;
29423 case '<fileVersion/>': break;
29424
29425 /* 18.2.12 fileSharing CT_FileSharing ? */
29426 case '<fileSharing': case '<fileSharing/>': break;
29427
29428 /* 18.2.28 workbookPr CT_WorkbookPr ? */
29429 case '<workbookPr': delete y[0]; wb.WBProps = y; break;
29430 case '<workbookPr/>': delete y[0]; wb.WBProps = y; break;
29431
29432 /* 18.2.29 workbookProtection CT_WorkbookProtection ? */
29433 case '<workbookProtection': break;
29434 case '<workbookProtection/>': break;
29435
29436 /* 18.2.1 bookViews CT_BookViews ? */
29437 case '<bookViews>': case '</bookViews>': break;
29438 /* 18.2.30 workbookView CT_BookView + */
29439 case '<workbookView': delete y[0]; wb.WBView.push(y); break;
29440
29441 /* 18.2.20 sheets CT_Sheets 1 */
29442 case '<sheets>': case '</sheets>': break; // aggregate sheet
29443 /* 18.2.19 sheet CT_Sheet + */
29444 case '<sheet': delete y[0]; y.name = utf8read(y.name); wb.Sheets.push(y); break;
29445
29446 /* 18.2.15 functionGroups CT_FunctionGroups ? */
29447 case '<functionGroups': case '<functionGroups/>': break;
29448 /* 18.2.14 functionGroup CT_FunctionGroup + */
29449 case '<functionGroup': break;
29450
29451 /* 18.2.9 externalReferences CT_ExternalReferences ? */
29452 case '<externalReferences': case '</externalReferences>': case '<externalReferences>': break;
29453 /* 18.2.8 externalReference CT_ExternalReference + */
29454 case '<externalReference': break;
29455
29456 /* 18.2.6 definedNames CT_DefinedNames ? */
29457 case '<definedNames/>': break;
29458 case '<definedNames>': case '<definedNames': pass=true; break;
29459 case '</definedNames>': pass=false; break;
29460 /* 18.2.5 definedName CT_DefinedName + */
29461 case '<definedName': case '<definedName/>': case '</definedName>': break;
29462
29463 /* 18.2.2 calcPr CT_CalcPr ? */
29464 case '<calcPr': delete y[0]; wb.CalcPr = y; break;
29465 case '<calcPr/>': delete y[0]; wb.CalcPr = y; break;
29466
29467 /* 18.2.16 oleSize CT_OleSize ? (ref required) */
29468 case '<oleSize': break;
29469
29470 /* 18.2.4 customWorkbookViews CT_CustomWorkbookViews ? */
29471 case '<customWorkbookViews>': case '</customWorkbookViews>': case '<customWorkbookViews': break;
29472 /* 18.2.3 customWorkbookView CT_CustomWorkbookView + */
29473 case '<customWorkbookView': case '</customWorkbookView>': break;
29474
29475 /* 18.2.18 pivotCaches CT_PivotCaches ? */
29476 case '<pivotCaches>': case '</pivotCaches>': case '<pivotCaches': break;
29477 /* 18.2.17 pivotCache CT_PivotCache ? */
29478 case '<pivotCache': break;
29479
29480 /* 18.2.21 smartTagPr CT_SmartTagPr ? */
29481 case '<smartTagPr': case '<smartTagPr/>': break;
29482
29483 /* 18.2.23 smartTagTypes CT_SmartTagTypes ? */
29484 case '<smartTagTypes': case '<smartTagTypes>': case '</smartTagTypes>': break;
29485 /* 18.2.22 smartTagType CT_SmartTagType ? */
29486 case '<smartTagType': break;
29487
29488 /* 18.2.24 webPublishing CT_WebPublishing ? */
29489 case '<webPublishing': case '<webPublishing/>': break;
29490
29491 /* 18.2.11 fileRecoveryPr CT_FileRecoveryPr ? */
29492 case '<fileRecoveryPr': case '<fileRecoveryPr/>': break;
29493
29494 /* 18.2.26 webPublishObjects CT_WebPublishObjects ? */
29495 case '<webPublishObjects>': case '<webPublishObjects': case '</webPublishObjects>': break;
29496 /* 18.2.25 webPublishObject CT_WebPublishObject ? */
29497 case '<webPublishObject': break;
29498
29499 /* 18.2.10 extLst CT_ExtensionList ? */
29500 case '<extLst>': case '</extLst>': case '<extLst/>': break;
29501 /* 18.2.7 ext CT_Extension + */
29502 case '<ext': pass=true; break; //TODO: check with versions of excel
29503 case '</ext>': pass=false; break;
29504
29505 /* Others */
29506 case '<ArchID': break;
29507 case '<AlternateContent': pass=true; break;
29508 case '</AlternateContent>': pass=false; break;
29509
29510 default: if(!pass && opts.WTF) throw 'unrecognized ' + y[0] + ' in workbook';
29511 }
29512 });
29513 if(XMLNS.main.indexOf(wb.xmlns) === -1) throw new Error("Unknown Namespace: " + wb.xmlns);
29514
29515 parse_wb_defaults(wb);
29516
29517 return wb;
29518 }
29519
29520 var WB_XML_ROOT = writextag('workbook', null, {
29521 'xmlns': XMLNS.main[0],
29522 //'xmlns:mx': XMLNS.mx,
29523 //'xmlns:s': XMLNS.main[0],
29524 'xmlns:r': XMLNS.r
29525 });
29526
29527 function safe1904(wb) {
29528 /* TODO: store date1904 somewhere else */
29529 try { return parsexmlbool(wb.Workbook.WBProps.date1904) ? "true" : "false"; } catch(e) { return "false"; }
29530 }
29531
29532 function write_wb_xml(wb, opts) {
29533 var o = [XML_HEADER];
29534 o[o.length] = WB_XML_ROOT;
29535 o[o.length] = (writextag('workbookPr', null, {date1904:safe1904(wb)}));
29536 o[o.length] = "<sheets>";
29537 for(var i = 0; i != wb.SheetNames.length; ++i)
29538 o[o.length] = (writextag('sheet',null,{name:wb.SheetNames[i].substr(0,31), sheetId:""+(i+1), "r:id":"rId"+(i+1)}));
29539 o[o.length] = "</sheets>";
29540 if(o.length>2){ o[o.length] = '</workbook>'; o[1]=o[1].replace("/>",">"); }
29541 return o.join("");
29542 }
29543 /* [MS-XLSB] 2.4.301 BrtBundleSh */
29544 function parse_BrtBundleSh(data, length) {
29545 var z = {};
29546 z.hsState = data.read_shift(4); //ST_SheetState
29547 z.iTabID = data.read_shift(4);
29548 z.strRelID = parse_RelID(data,length-8);
29549 z.name = parse_XLWideString(data);
29550 return z;
29551 }
29552 function write_BrtBundleSh(data, o) {
29553 if(!o) o = new_buf(127);
29554 o.write_shift(4, data.hsState);
29555 o.write_shift(4, data.iTabID);
29556 write_RelID(data.strRelID, o);
29557 write_XLWideString(data.name.substr(0,31), o);
29558 return o;
29559 }
29560
29561 /* [MS-XLSB] 2.4.807 BrtWbProp */
29562 function parse_BrtWbProp(data, length) {
29563 data.read_shift(4);
29564 var dwThemeVersion = data.read_shift(4);
29565 var strName = (length > 8) ? parse_XLWideString(data) : "";
29566 return [dwThemeVersion, strName];
29567 }
29568 function write_BrtWbProp(data, o) {
29569 if(!o) o = new_buf(8);
29570 o.write_shift(4, 0);
29571 o.write_shift(4, 0);
29572 return o;
29573 }
29574
29575 function parse_BrtFRTArchID$(data, length) {
29576 var o = {};
29577 data.read_shift(4);
29578 o.ArchID = data.read_shift(4);
29579 data.l += length - 8;
29580 return o;
29581 }
29582
29583 /* [MS-XLSB] 2.1.7.60 Workbook */
29584 function parse_wb_bin(data, opts) {
29585 var wb = { AppVersion:{}, WBProps:{}, WBView:[], Sheets:[], CalcPr:{}, xmlns: "" };
29586 var pass = false, z;
29587
29588 recordhopper(data, function hopper_wb(val, R) {
29589 switch(R.n) {
29590 case 'BrtBundleSh': wb.Sheets.push(val); break;
29591
29592 case 'BrtBeginBook': break;
29593 case 'BrtFileVersion': break;
29594 case 'BrtWbProp': break;
29595 case 'BrtACBegin': break;
29596 case 'BrtAbsPath15': break;
29597 case 'BrtACEnd': break;
29598 case 'BrtWbFactoid': break;
29599 /*case 'BrtBookProtectionIso': break;*/
29600 case 'BrtBookProtection': break;
29601 case 'BrtBeginBookViews': break;
29602 case 'BrtBookView': break;
29603 case 'BrtEndBookViews': break;
29604 case 'BrtBeginBundleShs': break;
29605 case 'BrtEndBundleShs': break;
29606 case 'BrtBeginFnGroup': break;
29607 case 'BrtEndFnGroup': break;
29608 case 'BrtBeginExternals': break;
29609 case 'BrtSupSelf': break;
29610 case 'BrtSupBookSrc': break;
29611 case 'BrtExternSheet': break;
29612 case 'BrtEndExternals': break;
29613 case 'BrtName': break;
29614 case 'BrtCalcProp': break;
29615 case 'BrtUserBookView': break;
29616 case 'BrtBeginPivotCacheIDs': break;
29617 case 'BrtBeginPivotCacheID': break;
29618 case 'BrtEndPivotCacheID': break;
29619 case 'BrtEndPivotCacheIDs': break;
29620 case 'BrtWebOpt': break;
29621 case 'BrtFileRecover': break;
29622 case 'BrtFileSharing': break;
29623 /*case 'BrtBeginWebPubItems': break;
29624 case 'BrtBeginWebPubItem': break;
29625 case 'BrtEndWebPubItem': break;
29626 case 'BrtEndWebPubItems': break;*/
29627
29628 /* Smart Tags */
29629 case 'BrtBeginSmartTagTypes': break;
29630 case 'BrtSmartTagType': break;
29631 case 'BrtEndSmartTagTypes': break;
29632
29633 case 'BrtFRTBegin': pass = true; break;
29634 case 'BrtFRTArchID$': break;
29635 case 'BrtWorkBookPr15': break;
29636 case 'BrtFRTEnd': pass = false; break;
29637 case 'BrtEndBook': break;
29638 default: if(!pass || opts.WTF) throw new Error("Unexpected record " + R.n);
29639 }
29640 });
29641
29642 parse_wb_defaults(wb);
29643
29644 return wb;
29645 }
29646
29647 /* [MS-XLSB] 2.1.7.60 Workbook */
29648 function write_BUNDLESHS(ba, wb, opts) {
29649 write_record(ba, "BrtBeginBundleShs");
29650 for(var idx = 0; idx != wb.SheetNames.length; ++idx) {
29651 var d = { hsState: 0, iTabID: idx+1, strRelID: 'rId' + (idx+1), name: wb.SheetNames[idx] };
29652 write_record(ba, "BrtBundleSh", write_BrtBundleSh(d));
29653 }
29654 write_record(ba, "BrtEndBundleShs");
29655 }
29656
29657 /* [MS-XLSB] 2.4.643 BrtFileVersion */
29658 function write_BrtFileVersion(data, o) {
29659 if(!o) o = new_buf(127);
29660 for(var i = 0; i != 4; ++i) o.write_shift(4, 0);
29661 write_XLWideString("SheetJS", o);
29662 write_XLWideString(XLSX.version, o);
29663 write_XLWideString(XLSX.version, o);
29664 write_XLWideString("7262", o);
29665 o.length = o.l;
29666 return o;
29667 }
29668
29669 /* [MS-XLSB] 2.1.7.60 Workbook */
29670 function write_BOOKVIEWS(ba, wb, opts) {
29671 write_record(ba, "BrtBeginBookViews");
29672 /* 1*(BrtBookView *FRT) */
29673 write_record(ba, "BrtEndBookViews");
29674 }
29675
29676 /* [MS-XLSB] 2.4.302 BrtCalcProp */
29677 function write_BrtCalcProp(data, o) {
29678 if(!o) o = new_buf(26);
29679 o.write_shift(4,0); /* force recalc */
29680 o.write_shift(4,1);
29681 o.write_shift(4,0);
29682 write_Xnum(0, o);
29683 o.write_shift(-4, 1023);
29684 o.write_shift(1, 0x33);
29685 o.write_shift(1, 0x00);
29686 return o;
29687 }
29688
29689 function write_BrtFileRecover(data, o) {
29690 if(!o) o = new_buf(1);
29691 o.write_shift(1,0);
29692 return o;
29693 }
29694
29695 /* [MS-XLSB] 2.1.7.60 Workbook */
29696 function write_wb_bin(wb, opts) {
29697 var ba = buf_array();
29698 write_record(ba, "BrtBeginBook");
29699 write_record(ba, "BrtFileVersion", write_BrtFileVersion());
29700 /* [[BrtFileSharingIso] BrtFileSharing] */
29701 write_record(ba, "BrtWbProp", write_BrtWbProp());
29702 /* [ACABSPATH] */
29703 /* [[BrtBookProtectionIso] BrtBookProtection] */
29704 write_BOOKVIEWS(ba, wb, opts);
29705 write_BUNDLESHS(ba, wb, opts);
29706 /* [FNGROUP] */
29707 /* [EXTERNALS] */
29708 /* *BrtName */
29709 write_record(ba, "BrtCalcProp", write_BrtCalcProp());
29710 /* [BrtOleSize] */
29711 /* *(BrtUserBookView *FRT) */
29712 /* [PIVOTCACHEIDS] */
29713 /* [BrtWbFactoid] */
29714 /* [SMARTTAGTYPES] */
29715 /* [BrtWebOpt] */
29716 write_record(ba, "BrtFileRecover", write_BrtFileRecover());
29717 /* [WEBPUBITEMS] */
29718 /* [CRERRS] */
29719 /* FRTWORKBOOK */
29720 write_record(ba, "BrtEndBook");
29721
29722 return ba.end();
29723 }
29724 function parse_wb(data, name, opts) {
29725 return (name.substr(-4)===".bin" ? parse_wb_bin : parse_wb_xml)(data, opts);
29726 }
29727
29728 function parse_ws(data, name, opts, rels) {
29729 return (name.substr(-4)===".bin" ? parse_ws_bin : parse_ws_xml)(data, opts, rels);
29730 }
29731
29732 function parse_sty(data, name, opts) {
29733 return (name.substr(-4)===".bin" ? parse_sty_bin : parse_sty_xml)(data, opts);
29734 }
29735
29736 function parse_theme(data, name, opts) {
29737 return parse_theme_xml(data, opts);
29738 }
29739
29740 function parse_sst(data, name, opts) {
29741 return (name.substr(-4)===".bin" ? parse_sst_bin : parse_sst_xml)(data, opts);
29742 }
29743
29744 function parse_cmnt(data, name, opts) {
29745 return (name.substr(-4)===".bin" ? parse_comments_bin : parse_comments_xml)(data, opts);
29746 }
29747
29748 function parse_cc(data, name, opts) {
29749 return (name.substr(-4)===".bin" ? parse_cc_bin : parse_cc_xml)(data, opts);
29750 }
29751
29752 function write_wb(wb, name, opts) {
29753 return (name.substr(-4)===".bin" ? write_wb_bin : write_wb_xml)(wb, opts);
29754 }
29755
29756 function write_ws(data, name, opts, wb) {
29757 return (name.substr(-4)===".bin" ? write_ws_bin : write_ws_xml)(data, opts, wb);
29758 }
29759
29760 function write_sty(data, name, opts) {
29761 return (name.substr(-4)===".bin" ? write_sty_bin : write_sty_xml)(data, opts);
29762 }
29763
29764 function write_sst(data, name, opts) {
29765 return (name.substr(-4)===".bin" ? write_sst_bin : write_sst_xml)(data, opts);
29766 }
19023 /* 29767 /*
19024 * Compression methods 29768 function write_cmnt(data, name, opts) {
19025 * This object is filled in as follow : 29769 return (name.substr(-4)===".bin" ? write_comments_bin : write_comments_xml)(data, opts);
19026 * name : { 29770 }
19027 * magic // the 2 bytes indentifying the compression method 29771
19028 * compress // function, take the uncompressed content and return it compressed. 29772 function write_cc(data, name, opts) {
19029 * uncompress // function, take the compressed content and return it uncompressed. 29773 return (name.substr(-4)===".bin" ? write_cc_bin : write_cc_xml)(data, opts);
19030 * } 29774 }
19031 * 29775 */
19032 * STORE is the default compression method, so it's included in this file. 29776 /* [MS-XLSB] 2.3 Record Enumeration */
19033 * Other methods should go to separated files : the user wants modularity. 29777 var RecordEnum = {
19034 */ 29778 0x0000: { n:"BrtRowHdr", f:parse_BrtRowHdr },
19035 JSZip.compressions = { 29779 0x0001: { n:"BrtCellBlank", f:parse_BrtCellBlank },
19036 "STORE" : { 29780 0x0002: { n:"BrtCellRk", f:parse_BrtCellRk },
19037 magic : "\x00\x00", 29781 0x0003: { n:"BrtCellError", f:parse_BrtCellError },
19038 compress : function (content) { 29782 0x0004: { n:"BrtCellBool", f:parse_BrtCellBool },
19039 return content; // no compression 29783 0x0005: { n:"BrtCellReal", f:parse_BrtCellReal },
19040 }, 29784 0x0006: { n:"BrtCellSt", f:parse_BrtCellSt },
19041 uncompress : function (content) { 29785 0x0007: { n:"BrtCellIsst", f:parse_BrtCellIsst },
19042 return content; // no compression 29786 0x0008: { n:"BrtFmlaString", f:parse_BrtFmlaString },
19043 } 29787 0x0009: { n:"BrtFmlaNum", f:parse_BrtFmlaNum },
19044 } 29788 0x000A: { n:"BrtFmlaBool", f:parse_BrtFmlaBool },
29789 0x000B: { n:"BrtFmlaError", f:parse_BrtFmlaError },
29790 0x0010: { n:"BrtFRTArchID$", f:parse_BrtFRTArchID$ },
29791 0x0013: { n:"BrtSSTItem", f:parse_RichStr },
29792 0x0014: { n:"BrtPCDIMissing", f:parsenoop },
29793 0x0015: { n:"BrtPCDINumber", f:parsenoop },
29794 0x0016: { n:"BrtPCDIBoolean", f:parsenoop },
29795 0x0017: { n:"BrtPCDIError", f:parsenoop },
29796 0x0018: { n:"BrtPCDIString", f:parsenoop },
29797 0x0019: { n:"BrtPCDIDatetime", f:parsenoop },
29798 0x001A: { n:"BrtPCDIIndex", f:parsenoop },
29799 0x001B: { n:"BrtPCDIAMissing", f:parsenoop },
29800 0x001C: { n:"BrtPCDIANumber", f:parsenoop },
29801 0x001D: { n:"BrtPCDIABoolean", f:parsenoop },
29802 0x001E: { n:"BrtPCDIAError", f:parsenoop },
29803 0x001F: { n:"BrtPCDIAString", f:parsenoop },
29804 0x0020: { n:"BrtPCDIADatetime", f:parsenoop },
29805 0x0021: { n:"BrtPCRRecord", f:parsenoop },
29806 0x0022: { n:"BrtPCRRecordDt", f:parsenoop },
29807 0x0023: { n:"BrtFRTBegin", f:parsenoop },
29808 0x0024: { n:"BrtFRTEnd", f:parsenoop },
29809 0x0025: { n:"BrtACBegin", f:parsenoop },
29810 0x0026: { n:"BrtACEnd", f:parsenoop },
29811 0x0027: { n:"BrtName", f:parsenoop },
29812 0x0028: { n:"BrtIndexRowBlock", f:parsenoop },
29813 0x002A: { n:"BrtIndexBlock", f:parsenoop },
29814 0x002B: { n:"BrtFont", f:parse_BrtFont },
29815 0x002C: { n:"BrtFmt", f:parse_BrtFmt },
29816 0x002D: { n:"BrtFill", f:parsenoop },
29817 0x002E: { n:"BrtBorder", f:parsenoop },
29818 0x002F: { n:"BrtXF", f:parse_BrtXF },
29819 0x0030: { n:"BrtStyle", f:parsenoop },
29820 0x0031: { n:"BrtCellMeta", f:parsenoop },
29821 0x0032: { n:"BrtValueMeta", f:parsenoop },
29822 0x0033: { n:"BrtMdb", f:parsenoop },
29823 0x0034: { n:"BrtBeginFmd", f:parsenoop },
29824 0x0035: { n:"BrtEndFmd", f:parsenoop },
29825 0x0036: { n:"BrtBeginMdx", f:parsenoop },
29826 0x0037: { n:"BrtEndMdx", f:parsenoop },
29827 0x0038: { n:"BrtBeginMdxTuple", f:parsenoop },
29828 0x0039: { n:"BrtEndMdxTuple", f:parsenoop },
29829 0x003A: { n:"BrtMdxMbrIstr", f:parsenoop },
29830 0x003B: { n:"BrtStr", f:parsenoop },
29831 0x003C: { n:"BrtColInfo", f:parsenoop },
29832 0x003E: { n:"BrtCellRString", f:parsenoop },
29833 0x003F: { n:"BrtCalcChainItem$", f:parse_BrtCalcChainItem$ },
29834 0x0040: { n:"BrtDVal", f:parsenoop },
29835 0x0041: { n:"BrtSxvcellNum", f:parsenoop },
29836 0x0042: { n:"BrtSxvcellStr", f:parsenoop },
29837 0x0043: { n:"BrtSxvcellBool", f:parsenoop },
29838 0x0044: { n:"BrtSxvcellErr", f:parsenoop },
29839 0x0045: { n:"BrtSxvcellDate", f:parsenoop },
29840 0x0046: { n:"BrtSxvcellNil", f:parsenoop },
29841 0x0080: { n:"BrtFileVersion", f:parsenoop },
29842 0x0081: { n:"BrtBeginSheet", f:parsenoop },
29843 0x0082: { n:"BrtEndSheet", f:parsenoop },
29844 0x0083: { n:"BrtBeginBook", f:parsenoop, p:0 },
29845 0x0084: { n:"BrtEndBook", f:parsenoop },
29846 0x0085: { n:"BrtBeginWsViews", f:parsenoop },
29847 0x0086: { n:"BrtEndWsViews", f:parsenoop },
29848 0x0087: { n:"BrtBeginBookViews", f:parsenoop },
29849 0x0088: { n:"BrtEndBookViews", f:parsenoop },
29850 0x0089: { n:"BrtBeginWsView", f:parsenoop },
29851 0x008A: { n:"BrtEndWsView", f:parsenoop },
29852 0x008B: { n:"BrtBeginCsViews", f:parsenoop },
29853 0x008C: { n:"BrtEndCsViews", f:parsenoop },
29854 0x008D: { n:"BrtBeginCsView", f:parsenoop },
29855 0x008E: { n:"BrtEndCsView", f:parsenoop },
29856 0x008F: { n:"BrtBeginBundleShs", f:parsenoop },
29857 0x0090: { n:"BrtEndBundleShs", f:parsenoop },
29858 0x0091: { n:"BrtBeginSheetData", f:parsenoop },
29859 0x0092: { n:"BrtEndSheetData", f:parsenoop },
29860 0x0093: { n:"BrtWsProp", f:parse_BrtWsProp },
29861 0x0094: { n:"BrtWsDim", f:parse_BrtWsDim, p:16 },
29862 0x0097: { n:"BrtPane", f:parsenoop },
29863 0x0098: { n:"BrtSel", f:parsenoop },
29864 0x0099: { n:"BrtWbProp", f:parse_BrtWbProp },
29865 0x009A: { n:"BrtWbFactoid", f:parsenoop },
29866 0x009B: { n:"BrtFileRecover", f:parsenoop },
29867 0x009C: { n:"BrtBundleSh", f:parse_BrtBundleSh },
29868 0x009D: { n:"BrtCalcProp", f:parsenoop },
29869 0x009E: { n:"BrtBookView", f:parsenoop },
29870 0x009F: { n:"BrtBeginSst", f:parse_BrtBeginSst },
29871 0x00A0: { n:"BrtEndSst", f:parsenoop },
29872 0x00A1: { n:"BrtBeginAFilter", f:parsenoop },
29873 0x00A2: { n:"BrtEndAFilter", f:parsenoop },
29874 0x00A3: { n:"BrtBeginFilterColumn", f:parsenoop },
29875 0x00A4: { n:"BrtEndFilterColumn", f:parsenoop },
29876 0x00A5: { n:"BrtBeginFilters", f:parsenoop },
29877 0x00A6: { n:"BrtEndFilters", f:parsenoop },
29878 0x00A7: { n:"BrtFilter", f:parsenoop },
29879 0x00A8: { n:"BrtColorFilter", f:parsenoop },
29880 0x00A9: { n:"BrtIconFilter", f:parsenoop },
29881 0x00AA: { n:"BrtTop10Filter", f:parsenoop },
29882 0x00AB: { n:"BrtDynamicFilter", f:parsenoop },
29883 0x00AC: { n:"BrtBeginCustomFilters", f:parsenoop },
29884 0x00AD: { n:"BrtEndCustomFilters", f:parsenoop },
29885 0x00AE: { n:"BrtCustomFilter", f:parsenoop },
29886 0x00AF: { n:"BrtAFilterDateGroupItem", f:parsenoop },
29887 0x00B0: { n:"BrtMergeCell", f:parse_BrtMergeCell },
29888 0x00B1: { n:"BrtBeginMergeCells", f:parsenoop },
29889 0x00B2: { n:"BrtEndMergeCells", f:parsenoop },
29890 0x00B3: { n:"BrtBeginPivotCacheDef", f:parsenoop },
29891 0x00B4: { n:"BrtEndPivotCacheDef", f:parsenoop },
29892 0x00B5: { n:"BrtBeginPCDFields", f:parsenoop },
29893 0x00B6: { n:"BrtEndPCDFields", f:parsenoop },
29894 0x00B7: { n:"BrtBeginPCDField", f:parsenoop },
29895 0x00B8: { n:"BrtEndPCDField", f:parsenoop },
29896 0x00B9: { n:"BrtBeginPCDSource", f:parsenoop },
29897 0x00BA: { n:"BrtEndPCDSource", f:parsenoop },
29898 0x00BB: { n:"BrtBeginPCDSRange", f:parsenoop },
29899 0x00BC: { n:"BrtEndPCDSRange", f:parsenoop },
29900 0x00BD: { n:"BrtBeginPCDFAtbl", f:parsenoop },
29901 0x00BE: { n:"BrtEndPCDFAtbl", f:parsenoop },
29902 0x00BF: { n:"BrtBeginPCDIRun", f:parsenoop },
29903 0x00C0: { n:"BrtEndPCDIRun", f:parsenoop },
29904 0x00C1: { n:"BrtBeginPivotCacheRecords", f:parsenoop },
29905 0x00C2: { n:"BrtEndPivotCacheRecords", f:parsenoop },
29906 0x00C3: { n:"BrtBeginPCDHierarchies", f:parsenoop },
29907 0x00C4: { n:"BrtEndPCDHierarchies", f:parsenoop },
29908 0x00C5: { n:"BrtBeginPCDHierarchy", f:parsenoop },
29909 0x00C6: { n:"BrtEndPCDHierarchy", f:parsenoop },
29910 0x00C7: { n:"BrtBeginPCDHFieldsUsage", f:parsenoop },
29911 0x00C8: { n:"BrtEndPCDHFieldsUsage", f:parsenoop },
29912 0x00C9: { n:"BrtBeginExtConnection", f:parsenoop },
29913 0x00CA: { n:"BrtEndExtConnection", f:parsenoop },
29914 0x00CB: { n:"BrtBeginECDbProps", f:parsenoop },
29915 0x00CC: { n:"BrtEndECDbProps", f:parsenoop },
29916 0x00CD: { n:"BrtBeginECOlapProps", f:parsenoop },
29917 0x00CE: { n:"BrtEndECOlapProps", f:parsenoop },
29918 0x00CF: { n:"BrtBeginPCDSConsol", f:parsenoop },
29919 0x00D0: { n:"BrtEndPCDSConsol", f:parsenoop },
29920 0x00D1: { n:"BrtBeginPCDSCPages", f:parsenoop },
29921 0x00D2: { n:"BrtEndPCDSCPages", f:parsenoop },
29922 0x00D3: { n:"BrtBeginPCDSCPage", f:parsenoop },
29923 0x00D4: { n:"BrtEndPCDSCPage", f:parsenoop },
29924 0x00D5: { n:"BrtBeginPCDSCPItem", f:parsenoop },
29925 0x00D6: { n:"BrtEndPCDSCPItem", f:parsenoop },
29926 0x00D7: { n:"BrtBeginPCDSCSets", f:parsenoop },
29927 0x00D8: { n:"BrtEndPCDSCSets", f:parsenoop },
29928 0x00D9: { n:"BrtBeginPCDSCSet", f:parsenoop },
29929 0x00DA: { n:"BrtEndPCDSCSet", f:parsenoop },
29930 0x00DB: { n:"BrtBeginPCDFGroup", f:parsenoop },
29931 0x00DC: { n:"BrtEndPCDFGroup", f:parsenoop },
29932 0x00DD: { n:"BrtBeginPCDFGItems", f:parsenoop },
29933 0x00DE: { n:"BrtEndPCDFGItems", f:parsenoop },
29934 0x00DF: { n:"BrtBeginPCDFGRange", f:parsenoop },
29935 0x00E0: { n:"BrtEndPCDFGRange", f:parsenoop },
29936 0x00E1: { n:"BrtBeginPCDFGDiscrete", f:parsenoop },
29937 0x00E2: { n:"BrtEndPCDFGDiscrete", f:parsenoop },
29938 0x00E3: { n:"BrtBeginPCDSDTupleCache", f:parsenoop },
29939 0x00E4: { n:"BrtEndPCDSDTupleCache", f:parsenoop },
29940 0x00E5: { n:"BrtBeginPCDSDTCEntries", f:parsenoop },
29941 0x00E6: { n:"BrtEndPCDSDTCEntries", f:parsenoop },
29942 0x00E7: { n:"BrtBeginPCDSDTCEMembers", f:parsenoop },
29943 0x00E8: { n:"BrtEndPCDSDTCEMembers", f:parsenoop },
29944 0x00E9: { n:"BrtBeginPCDSDTCEMember", f:parsenoop },
29945 0x00EA: { n:"BrtEndPCDSDTCEMember", f:parsenoop },
29946 0x00EB: { n:"BrtBeginPCDSDTCQueries", f:parsenoop },
29947 0x00EC: { n:"BrtEndPCDSDTCQueries", f:parsenoop },
29948 0x00ED: { n:"BrtBeginPCDSDTCQuery", f:parsenoop },
29949 0x00EE: { n:"BrtEndPCDSDTCQuery", f:parsenoop },
29950 0x00EF: { n:"BrtBeginPCDSDTCSets", f:parsenoop },
29951 0x00F0: { n:"BrtEndPCDSDTCSets", f:parsenoop },
29952 0x00F1: { n:"BrtBeginPCDSDTCSet", f:parsenoop },
29953 0x00F2: { n:"BrtEndPCDSDTCSet", f:parsenoop },
29954 0x00F3: { n:"BrtBeginPCDCalcItems", f:parsenoop },
29955 0x00F4: { n:"BrtEndPCDCalcItems", f:parsenoop },
29956 0x00F5: { n:"BrtBeginPCDCalcItem", f:parsenoop },
29957 0x00F6: { n:"BrtEndPCDCalcItem", f:parsenoop },
29958 0x00F7: { n:"BrtBeginPRule", f:parsenoop },
29959 0x00F8: { n:"BrtEndPRule", f:parsenoop },
29960 0x00F9: { n:"BrtBeginPRFilters", f:parsenoop },
29961 0x00FA: { n:"BrtEndPRFilters", f:parsenoop },
29962 0x00FB: { n:"BrtBeginPRFilter", f:parsenoop },
29963 0x00FC: { n:"BrtEndPRFilter", f:parsenoop },
29964 0x00FD: { n:"BrtBeginPNames", f:parsenoop },
29965 0x00FE: { n:"BrtEndPNames", f:parsenoop },
29966 0x00FF: { n:"BrtBeginPName", f:parsenoop },
29967 0x0100: { n:"BrtEndPName", f:parsenoop },
29968 0x0101: { n:"BrtBeginPNPairs", f:parsenoop },
29969 0x0102: { n:"BrtEndPNPairs", f:parsenoop },
29970 0x0103: { n:"BrtBeginPNPair", f:parsenoop },
29971 0x0104: { n:"BrtEndPNPair", f:parsenoop },
29972 0x0105: { n:"BrtBeginECWebProps", f:parsenoop },
29973 0x0106: { n:"BrtEndECWebProps", f:parsenoop },
29974 0x0107: { n:"BrtBeginEcWpTables", f:parsenoop },
29975 0x0108: { n:"BrtEndECWPTables", f:parsenoop },
29976 0x0109: { n:"BrtBeginECParams", f:parsenoop },
29977 0x010A: { n:"BrtEndECParams", f:parsenoop },
29978 0x010B: { n:"BrtBeginECParam", f:parsenoop },
29979 0x010C: { n:"BrtEndECParam", f:parsenoop },
29980 0x010D: { n:"BrtBeginPCDKPIs", f:parsenoop },
29981 0x010E: { n:"BrtEndPCDKPIs", f:parsenoop },
29982 0x010F: { n:"BrtBeginPCDKPI", f:parsenoop },
29983 0x0110: { n:"BrtEndPCDKPI", f:parsenoop },
29984 0x0111: { n:"BrtBeginDims", f:parsenoop },
29985 0x0112: { n:"BrtEndDims", f:parsenoop },
29986 0x0113: { n:"BrtBeginDim", f:parsenoop },
29987 0x0114: { n:"BrtEndDim", f:parsenoop },
29988 0x0115: { n:"BrtIndexPartEnd", f:parsenoop },
29989 0x0116: { n:"BrtBeginStyleSheet", f:parsenoop },
29990 0x0117: { n:"BrtEndStyleSheet", f:parsenoop },
29991 0x0118: { n:"BrtBeginSXView", f:parsenoop },
29992 0x0119: { n:"BrtEndSXVI", f:parsenoop },
29993 0x011A: { n:"BrtBeginSXVI", f:parsenoop },
29994 0x011B: { n:"BrtBeginSXVIs", f:parsenoop },
29995 0x011C: { n:"BrtEndSXVIs", f:parsenoop },
29996 0x011D: { n:"BrtBeginSXVD", f:parsenoop },
29997 0x011E: { n:"BrtEndSXVD", f:parsenoop },
29998 0x011F: { n:"BrtBeginSXVDs", f:parsenoop },
29999 0x0120: { n:"BrtEndSXVDs", f:parsenoop },
30000 0x0121: { n:"BrtBeginSXPI", f:parsenoop },
30001 0x0122: { n:"BrtEndSXPI", f:parsenoop },
30002 0x0123: { n:"BrtBeginSXPIs", f:parsenoop },
30003 0x0124: { n:"BrtEndSXPIs", f:parsenoop },
30004 0x0125: { n:"BrtBeginSXDI", f:parsenoop },
30005 0x0126: { n:"BrtEndSXDI", f:parsenoop },
30006 0x0127: { n:"BrtBeginSXDIs", f:parsenoop },
30007 0x0128: { n:"BrtEndSXDIs", f:parsenoop },
30008 0x0129: { n:"BrtBeginSXLI", f:parsenoop },
30009 0x012A: { n:"BrtEndSXLI", f:parsenoop },
30010 0x012B: { n:"BrtBeginSXLIRws", f:parsenoop },
30011 0x012C: { n:"BrtEndSXLIRws", f:parsenoop },
30012 0x012D: { n:"BrtBeginSXLICols", f:parsenoop },
30013 0x012E: { n:"BrtEndSXLICols", f:parsenoop },
30014 0x012F: { n:"BrtBeginSXFormat", f:parsenoop },
30015 0x0130: { n:"BrtEndSXFormat", f:parsenoop },
30016 0x0131: { n:"BrtBeginSXFormats", f:parsenoop },
30017 0x0132: { n:"BrtEndSxFormats", f:parsenoop },
30018 0x0133: { n:"BrtBeginSxSelect", f:parsenoop },
30019 0x0134: { n:"BrtEndSxSelect", f:parsenoop },
30020 0x0135: { n:"BrtBeginISXVDRws", f:parsenoop },
30021 0x0136: { n:"BrtEndISXVDRws", f:parsenoop },
30022 0x0137: { n:"BrtBeginISXVDCols", f:parsenoop },
30023 0x0138: { n:"BrtEndISXVDCols", f:parsenoop },
30024 0x0139: { n:"BrtEndSXLocation", f:parsenoop },
30025 0x013A: { n:"BrtBeginSXLocation", f:parsenoop },
30026 0x013B: { n:"BrtEndSXView", f:parsenoop },
30027 0x013C: { n:"BrtBeginSXTHs", f:parsenoop },
30028 0x013D: { n:"BrtEndSXTHs", f:parsenoop },
30029 0x013E: { n:"BrtBeginSXTH", f:parsenoop },
30030 0x013F: { n:"BrtEndSXTH", f:parsenoop },
30031 0x0140: { n:"BrtBeginISXTHRws", f:parsenoop },
30032 0x0141: { n:"BrtEndISXTHRws", f:parsenoop },
30033 0x0142: { n:"BrtBeginISXTHCols", f:parsenoop },
30034 0x0143: { n:"BrtEndISXTHCols", f:parsenoop },
30035 0x0144: { n:"BrtBeginSXTDMPS", f:parsenoop },
30036 0x0145: { n:"BrtEndSXTDMPs", f:parsenoop },
30037 0x0146: { n:"BrtBeginSXTDMP", f:parsenoop },
30038 0x0147: { n:"BrtEndSXTDMP", f:parsenoop },
30039 0x0148: { n:"BrtBeginSXTHItems", f:parsenoop },
30040 0x0149: { n:"BrtEndSXTHItems", f:parsenoop },
30041 0x014A: { n:"BrtBeginSXTHItem", f:parsenoop },
30042 0x014B: { n:"BrtEndSXTHItem", f:parsenoop },
30043 0x014C: { n:"BrtBeginMetadata", f:parsenoop },
30044 0x014D: { n:"BrtEndMetadata", f:parsenoop },
30045 0x014E: { n:"BrtBeginEsmdtinfo", f:parsenoop },
30046 0x014F: { n:"BrtMdtinfo", f:parsenoop },
30047 0x0150: { n:"BrtEndEsmdtinfo", f:parsenoop },
30048 0x0151: { n:"BrtBeginEsmdb", f:parsenoop },
30049 0x0152: { n:"BrtEndEsmdb", f:parsenoop },
30050 0x0153: { n:"BrtBeginEsfmd", f:parsenoop },
30051 0x0154: { n:"BrtEndEsfmd", f:parsenoop },
30052 0x0155: { n:"BrtBeginSingleCells", f:parsenoop },
30053 0x0156: { n:"BrtEndSingleCells", f:parsenoop },
30054 0x0157: { n:"BrtBeginList", f:parsenoop },
30055 0x0158: { n:"BrtEndList", f:parsenoop },
30056 0x0159: { n:"BrtBeginListCols", f:parsenoop },
30057 0x015A: { n:"BrtEndListCols", f:parsenoop },
30058 0x015B: { n:"BrtBeginListCol", f:parsenoop },
30059 0x015C: { n:"BrtEndListCol", f:parsenoop },
30060 0x015D: { n:"BrtBeginListXmlCPr", f:parsenoop },
30061 0x015E: { n:"BrtEndListXmlCPr", f:parsenoop },
30062 0x015F: { n:"BrtListCCFmla", f:parsenoop },
30063 0x0160: { n:"BrtListTrFmla", f:parsenoop },
30064 0x0161: { n:"BrtBeginExternals", f:parsenoop },
30065 0x0162: { n:"BrtEndExternals", f:parsenoop },
30066 0x0163: { n:"BrtSupBookSrc", f:parsenoop },
30067 0x0165: { n:"BrtSupSelf", f:parsenoop },
30068 0x0166: { n:"BrtSupSame", f:parsenoop },
30069 0x0167: { n:"BrtSupTabs", f:parsenoop },
30070 0x0168: { n:"BrtBeginSupBook", f:parsenoop },
30071 0x0169: { n:"BrtPlaceholderName", f:parsenoop },
30072 0x016A: { n:"BrtExternSheet", f:parsenoop },
30073 0x016B: { n:"BrtExternTableStart", f:parsenoop },
30074 0x016C: { n:"BrtExternTableEnd", f:parsenoop },
30075 0x016E: { n:"BrtExternRowHdr", f:parsenoop },
30076 0x016F: { n:"BrtExternCellBlank", f:parsenoop },
30077 0x0170: { n:"BrtExternCellReal", f:parsenoop },
30078 0x0171: { n:"BrtExternCellBool", f:parsenoop },
30079 0x0172: { n:"BrtExternCellError", f:parsenoop },
30080 0x0173: { n:"BrtExternCellString", f:parsenoop },
30081 0x0174: { n:"BrtBeginEsmdx", f:parsenoop },
30082 0x0175: { n:"BrtEndEsmdx", f:parsenoop },
30083 0x0176: { n:"BrtBeginMdxSet", f:parsenoop },
30084 0x0177: { n:"BrtEndMdxSet", f:parsenoop },
30085 0x0178: { n:"BrtBeginMdxMbrProp", f:parsenoop },
30086 0x0179: { n:"BrtEndMdxMbrProp", f:parsenoop },
30087 0x017A: { n:"BrtBeginMdxKPI", f:parsenoop },
30088 0x017B: { n:"BrtEndMdxKPI", f:parsenoop },
30089 0x017C: { n:"BrtBeginEsstr", f:parsenoop },
30090 0x017D: { n:"BrtEndEsstr", f:parsenoop },
30091 0x017E: { n:"BrtBeginPRFItem", f:parsenoop },
30092 0x017F: { n:"BrtEndPRFItem", f:parsenoop },
30093 0x0180: { n:"BrtBeginPivotCacheIDs", f:parsenoop },
30094 0x0181: { n:"BrtEndPivotCacheIDs", f:parsenoop },
30095 0x0182: { n:"BrtBeginPivotCacheID", f:parsenoop },
30096 0x0183: { n:"BrtEndPivotCacheID", f:parsenoop },
30097 0x0184: { n:"BrtBeginISXVIs", f:parsenoop },
30098 0x0185: { n:"BrtEndISXVIs", f:parsenoop },
30099 0x0186: { n:"BrtBeginColInfos", f:parsenoop },
30100 0x0187: { n:"BrtEndColInfos", f:parsenoop },
30101 0x0188: { n:"BrtBeginRwBrk", f:parsenoop },
30102 0x0189: { n:"BrtEndRwBrk", f:parsenoop },
30103 0x018A: { n:"BrtBeginColBrk", f:parsenoop },
30104 0x018B: { n:"BrtEndColBrk", f:parsenoop },
30105 0x018C: { n:"BrtBrk", f:parsenoop },
30106 0x018D: { n:"BrtUserBookView", f:parsenoop },
30107 0x018E: { n:"BrtInfo", f:parsenoop },
30108 0x018F: { n:"BrtCUsr", f:parsenoop },
30109 0x0190: { n:"BrtUsr", f:parsenoop },
30110 0x0191: { n:"BrtBeginUsers", f:parsenoop },
30111 0x0193: { n:"BrtEOF", f:parsenoop },
30112 0x0194: { n:"BrtUCR", f:parsenoop },
30113 0x0195: { n:"BrtRRInsDel", f:parsenoop },
30114 0x0196: { n:"BrtRREndInsDel", f:parsenoop },
30115 0x0197: { n:"BrtRRMove", f:parsenoop },
30116 0x0198: { n:"BrtRREndMove", f:parsenoop },
30117 0x0199: { n:"BrtRRChgCell", f:parsenoop },
30118 0x019A: { n:"BrtRREndChgCell", f:parsenoop },
30119 0x019B: { n:"BrtRRHeader", f:parsenoop },
30120 0x019C: { n:"BrtRRUserView", f:parsenoop },
30121 0x019D: { n:"BrtRRRenSheet", f:parsenoop },
30122 0x019E: { n:"BrtRRInsertSh", f:parsenoop },
30123 0x019F: { n:"BrtRRDefName", f:parsenoop },
30124 0x01A0: { n:"BrtRRNote", f:parsenoop },
30125 0x01A1: { n:"BrtRRConflict", f:parsenoop },
30126 0x01A2: { n:"BrtRRTQSIF", f:parsenoop },
30127 0x01A3: { n:"BrtRRFormat", f:parsenoop },
30128 0x01A4: { n:"BrtRREndFormat", f:parsenoop },
30129 0x01A5: { n:"BrtRRAutoFmt", f:parsenoop },
30130 0x01A6: { n:"BrtBeginUserShViews", f:parsenoop },
30131 0x01A7: { n:"BrtBeginUserShView", f:parsenoop },
30132 0x01A8: { n:"BrtEndUserShView", f:parsenoop },
30133 0x01A9: { n:"BrtEndUserShViews", f:parsenoop },
30134 0x01AA: { n:"BrtArrFmla", f:parsenoop },
30135 0x01AB: { n:"BrtShrFmla", f:parsenoop },
30136 0x01AC: { n:"BrtTable", f:parsenoop },
30137 0x01AD: { n:"BrtBeginExtConnections", f:parsenoop },
30138 0x01AE: { n:"BrtEndExtConnections", f:parsenoop },
30139 0x01AF: { n:"BrtBeginPCDCalcMems", f:parsenoop },
30140 0x01B0: { n:"BrtEndPCDCalcMems", f:parsenoop },
30141 0x01B1: { n:"BrtBeginPCDCalcMem", f:parsenoop },
30142 0x01B2: { n:"BrtEndPCDCalcMem", f:parsenoop },
30143 0x01B3: { n:"BrtBeginPCDHGLevels", f:parsenoop },
30144 0x01B4: { n:"BrtEndPCDHGLevels", f:parsenoop },
30145 0x01B5: { n:"BrtBeginPCDHGLevel", f:parsenoop },
30146 0x01B6: { n:"BrtEndPCDHGLevel", f:parsenoop },
30147 0x01B7: { n:"BrtBeginPCDHGLGroups", f:parsenoop },
30148 0x01B8: { n:"BrtEndPCDHGLGroups", f:parsenoop },
30149 0x01B9: { n:"BrtBeginPCDHGLGroup", f:parsenoop },
30150 0x01BA: { n:"BrtEndPCDHGLGroup", f:parsenoop },
30151 0x01BB: { n:"BrtBeginPCDHGLGMembers", f:parsenoop },
30152 0x01BC: { n:"BrtEndPCDHGLGMembers", f:parsenoop },
30153 0x01BD: { n:"BrtBeginPCDHGLGMember", f:parsenoop },
30154 0x01BE: { n:"BrtEndPCDHGLGMember", f:parsenoop },
30155 0x01BF: { n:"BrtBeginQSI", f:parsenoop },
30156 0x01C0: { n:"BrtEndQSI", f:parsenoop },
30157 0x01C1: { n:"BrtBeginQSIR", f:parsenoop },
30158 0x01C2: { n:"BrtEndQSIR", f:parsenoop },
30159 0x01C3: { n:"BrtBeginDeletedNames", f:parsenoop },
30160 0x01C4: { n:"BrtEndDeletedNames", f:parsenoop },
30161 0x01C5: { n:"BrtBeginDeletedName", f:parsenoop },
30162 0x01C6: { n:"BrtEndDeletedName", f:parsenoop },
30163 0x01C7: { n:"BrtBeginQSIFs", f:parsenoop },
30164 0x01C8: { n:"BrtEndQSIFs", f:parsenoop },
30165 0x01C9: { n:"BrtBeginQSIF", f:parsenoop },
30166 0x01CA: { n:"BrtEndQSIF", f:parsenoop },
30167 0x01CB: { n:"BrtBeginAutoSortScope", f:parsenoop },
30168 0x01CC: { n:"BrtEndAutoSortScope", f:parsenoop },
30169 0x01CD: { n:"BrtBeginConditionalFormatting", f:parsenoop },
30170 0x01CE: { n:"BrtEndConditionalFormatting", f:parsenoop },
30171 0x01CF: { n:"BrtBeginCFRule", f:parsenoop },
30172 0x01D0: { n:"BrtEndCFRule", f:parsenoop },
30173 0x01D1: { n:"BrtBeginIconSet", f:parsenoop },
30174 0x01D2: { n:"BrtEndIconSet", f:parsenoop },
30175 0x01D3: { n:"BrtBeginDatabar", f:parsenoop },
30176 0x01D4: { n:"BrtEndDatabar", f:parsenoop },
30177 0x01D5: { n:"BrtBeginColorScale", f:parsenoop },
30178 0x01D6: { n:"BrtEndColorScale", f:parsenoop },
30179 0x01D7: { n:"BrtCFVO", f:parsenoop },
30180 0x01D8: { n:"BrtExternValueMeta", f:parsenoop },
30181 0x01D9: { n:"BrtBeginColorPalette", f:parsenoop },
30182 0x01DA: { n:"BrtEndColorPalette", f:parsenoop },
30183 0x01DB: { n:"BrtIndexedColor", f:parsenoop },
30184 0x01DC: { n:"BrtMargins", f:parsenoop },
30185 0x01DD: { n:"BrtPrintOptions", f:parsenoop },
30186 0x01DE: { n:"BrtPageSetup", f:parsenoop },
30187 0x01DF: { n:"BrtBeginHeaderFooter", f:parsenoop },
30188 0x01E0: { n:"BrtEndHeaderFooter", f:parsenoop },
30189 0x01E1: { n:"BrtBeginSXCrtFormat", f:parsenoop },
30190 0x01E2: { n:"BrtEndSXCrtFormat", f:parsenoop },
30191 0x01E3: { n:"BrtBeginSXCrtFormats", f:parsenoop },
30192 0x01E4: { n:"BrtEndSXCrtFormats", f:parsenoop },
30193 0x01E5: { n:"BrtWsFmtInfo", f:parsenoop },
30194 0x01E6: { n:"BrtBeginMgs", f:parsenoop },
30195 0x01E7: { n:"BrtEndMGs", f:parsenoop },
30196 0x01E8: { n:"BrtBeginMGMaps", f:parsenoop },
30197 0x01E9: { n:"BrtEndMGMaps", f:parsenoop },
30198 0x01EA: { n:"BrtBeginMG", f:parsenoop },
30199 0x01EB: { n:"BrtEndMG", f:parsenoop },
30200 0x01EC: { n:"BrtBeginMap", f:parsenoop },
30201 0x01ED: { n:"BrtEndMap", f:parsenoop },
30202 0x01EE: { n:"BrtHLink", f:parse_BrtHLink },
30203 0x01EF: { n:"BrtBeginDCon", f:parsenoop },
30204 0x01F0: { n:"BrtEndDCon", f:parsenoop },
30205 0x01F1: { n:"BrtBeginDRefs", f:parsenoop },
30206 0x01F2: { n:"BrtEndDRefs", f:parsenoop },
30207 0x01F3: { n:"BrtDRef", f:parsenoop },
30208 0x01F4: { n:"BrtBeginScenMan", f:parsenoop },
30209 0x01F5: { n:"BrtEndScenMan", f:parsenoop },
30210 0x01F6: { n:"BrtBeginSct", f:parsenoop },
30211 0x01F7: { n:"BrtEndSct", f:parsenoop },
30212 0x01F8: { n:"BrtSlc", f:parsenoop },
30213 0x01F9: { n:"BrtBeginDXFs", f:parsenoop },
30214 0x01FA: { n:"BrtEndDXFs", f:parsenoop },
30215 0x01FB: { n:"BrtDXF", f:parsenoop },
30216 0x01FC: { n:"BrtBeginTableStyles", f:parsenoop },
30217 0x01FD: { n:"BrtEndTableStyles", f:parsenoop },
30218 0x01FE: { n:"BrtBeginTableStyle", f:parsenoop },
30219 0x01FF: { n:"BrtEndTableStyle", f:parsenoop },
30220 0x0200: { n:"BrtTableStyleElement", f:parsenoop },
30221 0x0201: { n:"BrtTableStyleClient", f:parsenoop },
30222 0x0202: { n:"BrtBeginVolDeps", f:parsenoop },
30223 0x0203: { n:"BrtEndVolDeps", f:parsenoop },
30224 0x0204: { n:"BrtBeginVolType", f:parsenoop },
30225 0x0205: { n:"BrtEndVolType", f:parsenoop },
30226 0x0206: { n:"BrtBeginVolMain", f:parsenoop },
30227 0x0207: { n:"BrtEndVolMain", f:parsenoop },
30228 0x0208: { n:"BrtBeginVolTopic", f:parsenoop },
30229 0x0209: { n:"BrtEndVolTopic", f:parsenoop },
30230 0x020A: { n:"BrtVolSubtopic", f:parsenoop },
30231 0x020B: { n:"BrtVolRef", f:parsenoop },
30232 0x020C: { n:"BrtVolNum", f:parsenoop },
30233 0x020D: { n:"BrtVolErr", f:parsenoop },
30234 0x020E: { n:"BrtVolStr", f:parsenoop },
30235 0x020F: { n:"BrtVolBool", f:parsenoop },
30236 0x0210: { n:"BrtBeginCalcChain$", f:parsenoop },
30237 0x0211: { n:"BrtEndCalcChain$", f:parsenoop },
30238 0x0212: { n:"BrtBeginSortState", f:parsenoop },
30239 0x0213: { n:"BrtEndSortState", f:parsenoop },
30240 0x0214: { n:"BrtBeginSortCond", f:parsenoop },
30241 0x0215: { n:"BrtEndSortCond", f:parsenoop },
30242 0x0216: { n:"BrtBookProtection", f:parsenoop },
30243 0x0217: { n:"BrtSheetProtection", f:parsenoop },
30244 0x0218: { n:"BrtRangeProtection", f:parsenoop },
30245 0x0219: { n:"BrtPhoneticInfo", f:parsenoop },
30246 0x021A: { n:"BrtBeginECTxtWiz", f:parsenoop },
30247 0x021B: { n:"BrtEndECTxtWiz", f:parsenoop },
30248 0x021C: { n:"BrtBeginECTWFldInfoLst", f:parsenoop },
30249 0x021D: { n:"BrtEndECTWFldInfoLst", f:parsenoop },
30250 0x021E: { n:"BrtBeginECTwFldInfo", f:parsenoop },
30251 0x0224: { n:"BrtFileSharing", f:parsenoop },
30252 0x0225: { n:"BrtOleSize", f:parsenoop },
30253 0x0226: { n:"BrtDrawing", f:parsenoop },
30254 0x0227: { n:"BrtLegacyDrawing", f:parsenoop },
30255 0x0228: { n:"BrtLegacyDrawingHF", f:parsenoop },
30256 0x0229: { n:"BrtWebOpt", f:parsenoop },
30257 0x022A: { n:"BrtBeginWebPubItems", f:parsenoop },
30258 0x022B: { n:"BrtEndWebPubItems", f:parsenoop },
30259 0x022C: { n:"BrtBeginWebPubItem", f:parsenoop },
30260 0x022D: { n:"BrtEndWebPubItem", f:parsenoop },
30261 0x022E: { n:"BrtBeginSXCondFmt", f:parsenoop },
30262 0x022F: { n:"BrtEndSXCondFmt", f:parsenoop },
30263 0x0230: { n:"BrtBeginSXCondFmts", f:parsenoop },
30264 0x0231: { n:"BrtEndSXCondFmts", f:parsenoop },
30265 0x0232: { n:"BrtBkHim", f:parsenoop },
30266 0x0234: { n:"BrtColor", f:parsenoop },
30267 0x0235: { n:"BrtBeginIndexedColors", f:parsenoop },
30268 0x0236: { n:"BrtEndIndexedColors", f:parsenoop },
30269 0x0239: { n:"BrtBeginMRUColors", f:parsenoop },
30270 0x023A: { n:"BrtEndMRUColors", f:parsenoop },
30271 0x023C: { n:"BrtMRUColor", f:parsenoop },
30272 0x023D: { n:"BrtBeginDVals", f:parsenoop },
30273 0x023E: { n:"BrtEndDVals", f:parsenoop },
30274 0x0241: { n:"BrtSupNameStart", f:parsenoop },
30275 0x0242: { n:"BrtSupNameValueStart", f:parsenoop },
30276 0x0243: { n:"BrtSupNameValueEnd", f:parsenoop },
30277 0x0244: { n:"BrtSupNameNum", f:parsenoop },
30278 0x0245: { n:"BrtSupNameErr", f:parsenoop },
30279 0x0246: { n:"BrtSupNameSt", f:parsenoop },
30280 0x0247: { n:"BrtSupNameNil", f:parsenoop },
30281 0x0248: { n:"BrtSupNameBool", f:parsenoop },
30282 0x0249: { n:"BrtSupNameFmla", f:parsenoop },
30283 0x024A: { n:"BrtSupNameBits", f:parsenoop },
30284 0x024B: { n:"BrtSupNameEnd", f:parsenoop },
30285 0x024C: { n:"BrtEndSupBook", f:parsenoop },
30286 0x024D: { n:"BrtCellSmartTagProperty", f:parsenoop },
30287 0x024E: { n:"BrtBeginCellSmartTag", f:parsenoop },
30288 0x024F: { n:"BrtEndCellSmartTag", f:parsenoop },
30289 0x0250: { n:"BrtBeginCellSmartTags", f:parsenoop },
30290 0x0251: { n:"BrtEndCellSmartTags", f:parsenoop },
30291 0x0252: { n:"BrtBeginSmartTags", f:parsenoop },
30292 0x0253: { n:"BrtEndSmartTags", f:parsenoop },
30293 0x0254: { n:"BrtSmartTagType", f:parsenoop },
30294 0x0255: { n:"BrtBeginSmartTagTypes", f:parsenoop },
30295 0x0256: { n:"BrtEndSmartTagTypes", f:parsenoop },
30296 0x0257: { n:"BrtBeginSXFilters", f:parsenoop },
30297 0x0258: { n:"BrtEndSXFilters", f:parsenoop },
30298 0x0259: { n:"BrtBeginSXFILTER", f:parsenoop },
30299 0x025A: { n:"BrtEndSXFilter", f:parsenoop },
30300 0x025B: { n:"BrtBeginFills", f:parsenoop },
30301 0x025C: { n:"BrtEndFills", f:parsenoop },
30302 0x025D: { n:"BrtBeginCellWatches", f:parsenoop },
30303 0x025E: { n:"BrtEndCellWatches", f:parsenoop },
30304 0x025F: { n:"BrtCellWatch", f:parsenoop },
30305 0x0260: { n:"BrtBeginCRErrs", f:parsenoop },
30306 0x0261: { n:"BrtEndCRErrs", f:parsenoop },
30307 0x0262: { n:"BrtCrashRecErr", f:parsenoop },
30308 0x0263: { n:"BrtBeginFonts", f:parsenoop },
30309 0x0264: { n:"BrtEndFonts", f:parsenoop },
30310 0x0265: { n:"BrtBeginBorders", f:parsenoop },
30311 0x0266: { n:"BrtEndBorders", f:parsenoop },
30312 0x0267: { n:"BrtBeginFmts", f:parsenoop },
30313 0x0268: { n:"BrtEndFmts", f:parsenoop },
30314 0x0269: { n:"BrtBeginCellXFs", f:parsenoop },
30315 0x026A: { n:"BrtEndCellXFs", f:parsenoop },
30316 0x026B: { n:"BrtBeginStyles", f:parsenoop },
30317 0x026C: { n:"BrtEndStyles", f:parsenoop },
30318 0x0271: { n:"BrtBigName", f:parsenoop },
30319 0x0272: { n:"BrtBeginCellStyleXFs", f:parsenoop },
30320 0x0273: { n:"BrtEndCellStyleXFs", f:parsenoop },
30321 0x0274: { n:"BrtBeginComments", f:parsenoop },
30322 0x0275: { n:"BrtEndComments", f:parsenoop },
30323 0x0276: { n:"BrtBeginCommentAuthors", f:parsenoop },
30324 0x0277: { n:"BrtEndCommentAuthors", f:parsenoop },
30325 0x0278: { n:"BrtCommentAuthor", f:parse_BrtCommentAuthor },
30326 0x0279: { n:"BrtBeginCommentList", f:parsenoop },
30327 0x027A: { n:"BrtEndCommentList", f:parsenoop },
30328 0x027B: { n:"BrtBeginComment", f:parse_BrtBeginComment},
30329 0x027C: { n:"BrtEndComment", f:parsenoop },
30330 0x027D: { n:"BrtCommentText", f:parse_BrtCommentText },
30331 0x027E: { n:"BrtBeginOleObjects", f:parsenoop },
30332 0x027F: { n:"BrtOleObject", f:parsenoop },
30333 0x0280: { n:"BrtEndOleObjects", f:parsenoop },
30334 0x0281: { n:"BrtBeginSxrules", f:parsenoop },
30335 0x0282: { n:"BrtEndSxRules", f:parsenoop },
30336 0x0283: { n:"BrtBeginActiveXControls", f:parsenoop },
30337 0x0284: { n:"BrtActiveX", f:parsenoop },
30338 0x0285: { n:"BrtEndActiveXControls", f:parsenoop },
30339 0x0286: { n:"BrtBeginPCDSDTCEMembersSortBy", f:parsenoop },
30340 0x0288: { n:"BrtBeginCellIgnoreECs", f:parsenoop },
30341 0x0289: { n:"BrtCellIgnoreEC", f:parsenoop },
30342 0x028A: { n:"BrtEndCellIgnoreECs", f:parsenoop },
30343 0x028B: { n:"BrtCsProp", f:parsenoop },
30344 0x028C: { n:"BrtCsPageSetup", f:parsenoop },
30345 0x028D: { n:"BrtBeginUserCsViews", f:parsenoop },
30346 0x028E: { n:"BrtEndUserCsViews", f:parsenoop },
30347 0x028F: { n:"BrtBeginUserCsView", f:parsenoop },
30348 0x0290: { n:"BrtEndUserCsView", f:parsenoop },
30349 0x0291: { n:"BrtBeginPcdSFCIEntries", f:parsenoop },
30350 0x0292: { n:"BrtEndPCDSFCIEntries", f:parsenoop },
30351 0x0293: { n:"BrtPCDSFCIEntry", f:parsenoop },
30352 0x0294: { n:"BrtBeginListParts", f:parsenoop },
30353 0x0295: { n:"BrtListPart", f:parsenoop },
30354 0x0296: { n:"BrtEndListParts", f:parsenoop },
30355 0x0297: { n:"BrtSheetCalcProp", f:parsenoop },
30356 0x0298: { n:"BrtBeginFnGroup", f:parsenoop },
30357 0x0299: { n:"BrtFnGroup", f:parsenoop },
30358 0x029A: { n:"BrtEndFnGroup", f:parsenoop },
30359 0x029B: { n:"BrtSupAddin", f:parsenoop },
30360 0x029C: { n:"BrtSXTDMPOrder", f:parsenoop },
30361 0x029D: { n:"BrtCsProtection", f:parsenoop },
30362 0x029F: { n:"BrtBeginWsSortMap", f:parsenoop },
30363 0x02A0: { n:"BrtEndWsSortMap", f:parsenoop },
30364 0x02A1: { n:"BrtBeginRRSort", f:parsenoop },
30365 0x02A2: { n:"BrtEndRRSort", f:parsenoop },
30366 0x02A3: { n:"BrtRRSortItem", f:parsenoop },
30367 0x02A4: { n:"BrtFileSharingIso", f:parsenoop },
30368 0x02A5: { n:"BrtBookProtectionIso", f:parsenoop },
30369 0x02A6: { n:"BrtSheetProtectionIso", f:parsenoop },
30370 0x02A7: { n:"BrtCsProtectionIso", f:parsenoop },
30371 0x02A8: { n:"BrtRangeProtectionIso", f:parsenoop },
30372 0x0400: { n:"BrtRwDescent", f:parsenoop },
30373 0x0401: { n:"BrtKnownFonts", f:parsenoop },
30374 0x0402: { n:"BrtBeginSXTupleSet", f:parsenoop },
30375 0x0403: { n:"BrtEndSXTupleSet", f:parsenoop },
30376 0x0404: { n:"BrtBeginSXTupleSetHeader", f:parsenoop },
30377 0x0405: { n:"BrtEndSXTupleSetHeader", f:parsenoop },
30378 0x0406: { n:"BrtSXTupleSetHeaderItem", f:parsenoop },
30379 0x0407: { n:"BrtBeginSXTupleSetData", f:parsenoop },
30380 0x0408: { n:"BrtEndSXTupleSetData", f:parsenoop },
30381 0x0409: { n:"BrtBeginSXTupleSetRow", f:parsenoop },
30382 0x040A: { n:"BrtEndSXTupleSetRow", f:parsenoop },
30383 0x040B: { n:"BrtSXTupleSetRowItem", f:parsenoop },
30384 0x040C: { n:"BrtNameExt", f:parsenoop },
30385 0x040D: { n:"BrtPCDH14", f:parsenoop },
30386 0x040E: { n:"BrtBeginPCDCalcMem14", f:parsenoop },
30387 0x040F: { n:"BrtEndPCDCalcMem14", f:parsenoop },
30388 0x0410: { n:"BrtSXTH14", f:parsenoop },
30389 0x0411: { n:"BrtBeginSparklineGroup", f:parsenoop },
30390 0x0412: { n:"BrtEndSparklineGroup", f:parsenoop },
30391 0x0413: { n:"BrtSparkline", f:parsenoop },
30392 0x0414: { n:"BrtSXDI14", f:parsenoop },
30393 0x0415: { n:"BrtWsFmtInfoEx14", f:parsenoop },
30394 0x0416: { n:"BrtBeginConditionalFormatting14", f:parsenoop },
30395 0x0417: { n:"BrtEndConditionalFormatting14", f:parsenoop },
30396 0x0418: { n:"BrtBeginCFRule14", f:parsenoop },
30397 0x0419: { n:"BrtEndCFRule14", f:parsenoop },
30398 0x041A: { n:"BrtCFVO14", f:parsenoop },
30399 0x041B: { n:"BrtBeginDatabar14", f:parsenoop },
30400 0x041C: { n:"BrtBeginIconSet14", f:parsenoop },
30401 0x041D: { n:"BrtDVal14", f:parsenoop },
30402 0x041E: { n:"BrtBeginDVals14", f:parsenoop },
30403 0x041F: { n:"BrtColor14", f:parsenoop },
30404 0x0420: { n:"BrtBeginSparklines", f:parsenoop },
30405 0x0421: { n:"BrtEndSparklines", f:parsenoop },
30406 0x0422: { n:"BrtBeginSparklineGroups", f:parsenoop },
30407 0x0423: { n:"BrtEndSparklineGroups", f:parsenoop },
30408 0x0425: { n:"BrtSXVD14", f:parsenoop },
30409 0x0426: { n:"BrtBeginSxview14", f:parsenoop },
30410 0x0427: { n:"BrtEndSxview14", f:parsenoop },
30411 0x042A: { n:"BrtBeginPCD14", f:parsenoop },
30412 0x042B: { n:"BrtEndPCD14", f:parsenoop },
30413 0x042C: { n:"BrtBeginExtConn14", f:parsenoop },
30414 0x042D: { n:"BrtEndExtConn14", f:parsenoop },
30415 0x042E: { n:"BrtBeginSlicerCacheIDs", f:parsenoop },
30416 0x042F: { n:"BrtEndSlicerCacheIDs", f:parsenoop },
30417 0x0430: { n:"BrtBeginSlicerCacheID", f:parsenoop },
30418 0x0431: { n:"BrtEndSlicerCacheID", f:parsenoop },
30419 0x0433: { n:"BrtBeginSlicerCache", f:parsenoop },
30420 0x0434: { n:"BrtEndSlicerCache", f:parsenoop },
30421 0x0435: { n:"BrtBeginSlicerCacheDef", f:parsenoop },
30422 0x0436: { n:"BrtEndSlicerCacheDef", f:parsenoop },
30423 0x0437: { n:"BrtBeginSlicersEx", f:parsenoop },
30424 0x0438: { n:"BrtEndSlicersEx", f:parsenoop },
30425 0x0439: { n:"BrtBeginSlicerEx", f:parsenoop },
30426 0x043A: { n:"BrtEndSlicerEx", f:parsenoop },
30427 0x043B: { n:"BrtBeginSlicer", f:parsenoop },
30428 0x043C: { n:"BrtEndSlicer", f:parsenoop },
30429 0x043D: { n:"BrtSlicerCachePivotTables", f:parsenoop },
30430 0x043E: { n:"BrtBeginSlicerCacheOlapImpl", f:parsenoop },
30431 0x043F: { n:"BrtEndSlicerCacheOlapImpl", f:parsenoop },
30432 0x0440: { n:"BrtBeginSlicerCacheLevelsData", f:parsenoop },
30433 0x0441: { n:"BrtEndSlicerCacheLevelsData", f:parsenoop },
30434 0x0442: { n:"BrtBeginSlicerCacheLevelData", f:parsenoop },
30435 0x0443: { n:"BrtEndSlicerCacheLevelData", f:parsenoop },
30436 0x0444: { n:"BrtBeginSlicerCacheSiRanges", f:parsenoop },
30437 0x0445: { n:"BrtEndSlicerCacheSiRanges", f:parsenoop },
30438 0x0446: { n:"BrtBeginSlicerCacheSiRange", f:parsenoop },
30439 0x0447: { n:"BrtEndSlicerCacheSiRange", f:parsenoop },
30440 0x0448: { n:"BrtSlicerCacheOlapItem", f:parsenoop },
30441 0x0449: { n:"BrtBeginSlicerCacheSelections", f:parsenoop },
30442 0x044A: { n:"BrtSlicerCacheSelection", f:parsenoop },
30443 0x044B: { n:"BrtEndSlicerCacheSelections", f:parsenoop },
30444 0x044C: { n:"BrtBeginSlicerCacheNative", f:parsenoop },
30445 0x044D: { n:"BrtEndSlicerCacheNative", f:parsenoop },
30446 0x044E: { n:"BrtSlicerCacheNativeItem", f:parsenoop },
30447 0x044F: { n:"BrtRangeProtection14", f:parsenoop },
30448 0x0450: { n:"BrtRangeProtectionIso14", f:parsenoop },
30449 0x0451: { n:"BrtCellIgnoreEC14", f:parsenoop },
30450 0x0457: { n:"BrtList14", f:parsenoop },
30451 0x0458: { n:"BrtCFIcon", f:parsenoop },
30452 0x0459: { n:"BrtBeginSlicerCachesPivotCacheIDs", f:parsenoop },
30453 0x045A: { n:"BrtEndSlicerCachesPivotCacheIDs", f:parsenoop },
30454 0x045B: { n:"BrtBeginSlicers", f:parsenoop },
30455 0x045C: { n:"BrtEndSlicers", f:parsenoop },
30456 0x045D: { n:"BrtWbProp14", f:parsenoop },
30457 0x045E: { n:"BrtBeginSXEdit", f:parsenoop },
30458 0x045F: { n:"BrtEndSXEdit", f:parsenoop },
30459 0x0460: { n:"BrtBeginSXEdits", f:parsenoop },
30460 0x0461: { n:"BrtEndSXEdits", f:parsenoop },
30461 0x0462: { n:"BrtBeginSXChange", f:parsenoop },
30462 0x0463: { n:"BrtEndSXChange", f:parsenoop },
30463 0x0464: { n:"BrtBeginSXChanges", f:parsenoop },
30464 0x0465: { n:"BrtEndSXChanges", f:parsenoop },
30465 0x0466: { n:"BrtSXTupleItems", f:parsenoop },
30466 0x0468: { n:"BrtBeginSlicerStyle", f:parsenoop },
30467 0x0469: { n:"BrtEndSlicerStyle", f:parsenoop },
30468 0x046A: { n:"BrtSlicerStyleElement", f:parsenoop },
30469 0x046B: { n:"BrtBeginStyleSheetExt14", f:parsenoop },
30470 0x046C: { n:"BrtEndStyleSheetExt14", f:parsenoop },
30471 0x046D: { n:"BrtBeginSlicerCachesPivotCacheID", f:parsenoop },
30472 0x046E: { n:"BrtEndSlicerCachesPivotCacheID", f:parsenoop },
30473 0x046F: { n:"BrtBeginConditionalFormattings", f:parsenoop },
30474 0x0470: { n:"BrtEndConditionalFormattings", f:parsenoop },
30475 0x0471: { n:"BrtBeginPCDCalcMemExt", f:parsenoop },
30476 0x0472: { n:"BrtEndPCDCalcMemExt", f:parsenoop },
30477 0x0473: { n:"BrtBeginPCDCalcMemsExt", f:parsenoop },
30478 0x0474: { n:"BrtEndPCDCalcMemsExt", f:parsenoop },
30479 0x0475: { n:"BrtPCDField14", f:parsenoop },
30480 0x0476: { n:"BrtBeginSlicerStyles", f:parsenoop },
30481 0x0477: { n:"BrtEndSlicerStyles", f:parsenoop },
30482 0x0478: { n:"BrtBeginSlicerStyleElements", f:parsenoop },
30483 0x0479: { n:"BrtEndSlicerStyleElements", f:parsenoop },
30484 0x047A: { n:"BrtCFRuleExt", f:parsenoop },
30485 0x047B: { n:"BrtBeginSXCondFmt14", f:parsenoop },
30486 0x047C: { n:"BrtEndSXCondFmt14", f:parsenoop },
30487 0x047D: { n:"BrtBeginSXCondFmts14", f:parsenoop },
30488 0x047E: { n:"BrtEndSXCondFmts14", f:parsenoop },
30489 0x0480: { n:"BrtBeginSortCond14", f:parsenoop },
30490 0x0481: { n:"BrtEndSortCond14", f:parsenoop },
30491 0x0482: { n:"BrtEndDVals14", f:parsenoop },
30492 0x0483: { n:"BrtEndIconSet14", f:parsenoop },
30493 0x0484: { n:"BrtEndDatabar14", f:parsenoop },
30494 0x0485: { n:"BrtBeginColorScale14", f:parsenoop },
30495 0x0486: { n:"BrtEndColorScale14", f:parsenoop },
30496 0x0487: { n:"BrtBeginSxrules14", f:parsenoop },
30497 0x0488: { n:"BrtEndSxrules14", f:parsenoop },
30498 0x0489: { n:"BrtBeginPRule14", f:parsenoop },
30499 0x048A: { n:"BrtEndPRule14", f:parsenoop },
30500 0x048B: { n:"BrtBeginPRFilters14", f:parsenoop },
30501 0x048C: { n:"BrtEndPRFilters14", f:parsenoop },
30502 0x048D: { n:"BrtBeginPRFilter14", f:parsenoop },
30503 0x048E: { n:"BrtEndPRFilter14", f:parsenoop },
30504 0x048F: { n:"BrtBeginPRFItem14", f:parsenoop },
30505 0x0490: { n:"BrtEndPRFItem14", f:parsenoop },
30506 0x0491: { n:"BrtBeginCellIgnoreECs14", f:parsenoop },
30507 0x0492: { n:"BrtEndCellIgnoreECs14", f:parsenoop },
30508 0x0493: { n:"BrtDxf14", f:parsenoop },
30509 0x0494: { n:"BrtBeginDxF14s", f:parsenoop },
30510 0x0495: { n:"BrtEndDxf14s", f:parsenoop },
30511 0x0499: { n:"BrtFilter14", f:parsenoop },
30512 0x049A: { n:"BrtBeginCustomFilters14", f:parsenoop },
30513 0x049C: { n:"BrtCustomFilter14", f:parsenoop },
30514 0x049D: { n:"BrtIconFilter14", f:parsenoop },
30515 0x049E: { n:"BrtPivotCacheConnectionName", f:parsenoop },
30516 0x0800: { n:"BrtBeginDecoupledPivotCacheIDs", f:parsenoop },
30517 0x0801: { n:"BrtEndDecoupledPivotCacheIDs", f:parsenoop },
30518 0x0802: { n:"BrtDecoupledPivotCacheID", f:parsenoop },
30519 0x0803: { n:"BrtBeginPivotTableRefs", f:parsenoop },
30520 0x0804: { n:"BrtEndPivotTableRefs", f:parsenoop },
30521 0x0805: { n:"BrtPivotTableRef", f:parsenoop },
30522 0x0806: { n:"BrtSlicerCacheBookPivotTables", f:parsenoop },
30523 0x0807: { n:"BrtBeginSxvcells", f:parsenoop },
30524 0x0808: { n:"BrtEndSxvcells", f:parsenoop },
30525 0x0809: { n:"BrtBeginSxRow", f:parsenoop },
30526 0x080A: { n:"BrtEndSxRow", f:parsenoop },
30527 0x080C: { n:"BrtPcdCalcMem15", f:parsenoop },
30528 0x0813: { n:"BrtQsi15", f:parsenoop },
30529 0x0814: { n:"BrtBeginWebExtensions", f:parsenoop },
30530 0x0815: { n:"BrtEndWebExtensions", f:parsenoop },
30531 0x0816: { n:"BrtWebExtension", f:parsenoop },
30532 0x0817: { n:"BrtAbsPath15", f:parsenoop },
30533 0x0818: { n:"BrtBeginPivotTableUISettings", f:parsenoop },
30534 0x0819: { n:"BrtEndPivotTableUISettings", f:parsenoop },
30535 0x081B: { n:"BrtTableSlicerCacheIDs", f:parsenoop },
30536 0x081C: { n:"BrtTableSlicerCacheID", f:parsenoop },
30537 0x081D: { n:"BrtBeginTableSlicerCache", f:parsenoop },
30538 0x081E: { n:"BrtEndTableSlicerCache", f:parsenoop },
30539 0x081F: { n:"BrtSxFilter15", f:parsenoop },
30540 0x0820: { n:"BrtBeginTimelineCachePivotCacheIDs", f:parsenoop },
30541 0x0821: { n:"BrtEndTimelineCachePivotCacheIDs", f:parsenoop },
30542 0x0822: { n:"BrtTimelineCachePivotCacheID", f:parsenoop },
30543 0x0823: { n:"BrtBeginTimelineCacheIDs", f:parsenoop },
30544 0x0824: { n:"BrtEndTimelineCacheIDs", f:parsenoop },
30545 0x0825: { n:"BrtBeginTimelineCacheID", f:parsenoop },
30546 0x0826: { n:"BrtEndTimelineCacheID", f:parsenoop },
30547 0x0827: { n:"BrtBeginTimelinesEx", f:parsenoop },
30548 0x0828: { n:"BrtEndTimelinesEx", f:parsenoop },
30549 0x0829: { n:"BrtBeginTimelineEx", f:parsenoop },
30550 0x082A: { n:"BrtEndTimelineEx", f:parsenoop },
30551 0x082B: { n:"BrtWorkBookPr15", f:parsenoop },
30552 0x082C: { n:"BrtPCDH15", f:parsenoop },
30553 0x082D: { n:"BrtBeginTimelineStyle", f:parsenoop },
30554 0x082E: { n:"BrtEndTimelineStyle", f:parsenoop },
30555 0x082F: { n:"BrtTimelineStyleElement", f:parsenoop },
30556 0x0830: { n:"BrtBeginTimelineStylesheetExt15", f:parsenoop },
30557 0x0831: { n:"BrtEndTimelineStylesheetExt15", f:parsenoop },
30558 0x0832: { n:"BrtBeginTimelineStyles", f:parsenoop },
30559 0x0833: { n:"BrtEndTimelineStyles", f:parsenoop },
30560 0x0834: { n:"BrtBeginTimelineStyleElements", f:parsenoop },
30561 0x0835: { n:"BrtEndTimelineStyleElements", f:parsenoop },
30562 0x0836: { n:"BrtDxf15", f:parsenoop },
30563 0x0837: { n:"BrtBeginDxfs15", f:parsenoop },
30564 0x0838: { n:"brtEndDxfs15", f:parsenoop },
30565 0x0839: { n:"BrtSlicerCacheHideItemsWithNoData", f:parsenoop },
30566 0x083A: { n:"BrtBeginItemUniqueNames", f:parsenoop },
30567 0x083B: { n:"BrtEndItemUniqueNames", f:parsenoop },
30568 0x083C: { n:"BrtItemUniqueName", f:parsenoop },
30569 0x083D: { n:"BrtBeginExtConn15", f:parsenoop },
30570 0x083E: { n:"BrtEndExtConn15", f:parsenoop },
30571 0x083F: { n:"BrtBeginOledbPr15", f:parsenoop },
30572 0x0840: { n:"BrtEndOledbPr15", f:parsenoop },
30573 0x0841: { n:"BrtBeginDataFeedPr15", f:parsenoop },
30574 0x0842: { n:"BrtEndDataFeedPr15", f:parsenoop },
30575 0x0843: { n:"BrtTextPr15", f:parsenoop },
30576 0x0844: { n:"BrtRangePr15", f:parsenoop },
30577 0x0845: { n:"BrtDbCommand15", f:parsenoop },
30578 0x0846: { n:"BrtBeginDbTables15", f:parsenoop },
30579 0x0847: { n:"BrtEndDbTables15", f:parsenoop },
30580 0x0848: { n:"BrtDbTable15", f:parsenoop },
30581 0x0849: { n:"BrtBeginDataModel", f:parsenoop },
30582 0x084A: { n:"BrtEndDataModel", f:parsenoop },
30583 0x084B: { n:"BrtBeginModelTables", f:parsenoop },
30584 0x084C: { n:"BrtEndModelTables", f:parsenoop },
30585 0x084D: { n:"BrtModelTable", f:parsenoop },
30586 0x084E: { n:"BrtBeginModelRelationships", f:parsenoop },
30587 0x084F: { n:"BrtEndModelRelationships", f:parsenoop },
30588 0x0850: { n:"BrtModelRelationship", f:parsenoop },
30589 0x0851: { n:"BrtBeginECTxtWiz15", f:parsenoop },
30590 0x0852: { n:"BrtEndECTxtWiz15", f:parsenoop },
30591 0x0853: { n:"BrtBeginECTWFldInfoLst15", f:parsenoop },
30592 0x0854: { n:"BrtEndECTWFldInfoLst15", f:parsenoop },
30593 0x0855: { n:"BrtBeginECTWFldInfo15", f:parsenoop },
30594 0x0856: { n:"BrtFieldListActiveItem", f:parsenoop },
30595 0x0857: { n:"BrtPivotCacheIdVersion", f:parsenoop },
30596 0x0858: { n:"BrtSXDI15", f:parsenoop },
30597 0xFFFF: { n:"", f:parsenoop }
19045 }; 30598 };
19046 30599
19047 /* 30600 var evert_RE = evert_key(RecordEnum, 'n');
19048 * List features that require a modern browser, and if the current browser support them. 30601 function fix_opts_func(defaults) {
19049 */ 30602 return function fix_opts(opts) {
19050 JSZip.support = { 30603 for(var i = 0; i != defaults.length; ++i) {
19051 // contains true if JSZip can read/generate ArrayBuffer, false otherwise. 30604 var d = defaults[i];
19052 arraybuffer : (function(){ 30605 if(opts[d[0]] === undefined) opts[d[0]] = d[1];
19053 return typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined"; 30606 if(d[2] === 'n') opts[d[0]] = Number(opts[d[0]]);
19054 })(), 30607 }
19055 // contains true if JSZip can read/generate Uint8Array, false otherwise. 30608 };
19056 uint8array : (function(){ 30609 }
19057 return typeof Uint8Array !== "undefined"; 30610
19058 })(), 30611 var fix_read_opts = fix_opts_func([
19059 // contains true if JSZip can read/generate Blob, false otherwise. 30612 ['cellNF', false], /* emit cell number format string as .z */
19060 blob : (function(){ 30613 ['cellHTML', true], /* emit html string as .h */
19061 // the spec started with BlobBuilder then replaced it with a construtor for Blob. 30614 ['cellFormula', true], /* emit formulae as .f */
19062 // Result : we have browsers that : 30615 ['cellStyles', false], /* emits style/theme as .s */
19063 // * know the BlobBuilder (but with prefix) 30616
19064 // * know the Blob constructor 30617 ['sheetStubs', false], /* emit empty cells */
19065 // * know about Blob but not about how to build them 30618 ['sheetRows', 0, 'n'], /* read n rows (0 = read all rows) */
19066 // About the "=== 0" test : if given the wrong type, it may be converted to a string. 30619
19067 // Instead of an empty content, we will get "[object Uint8Array]" for example. 30620 ['bookDeps', false], /* parse calculation chains */
19068 if (typeof ArrayBuffer === "undefined") { 30621 ['bookSheets', false], /* only try to get sheet names (no Sheets) */
19069 return false; 30622 ['bookProps', false], /* only try to get properties (no Sheets) */
19070 } 30623 ['bookFiles', false], /* include raw file structure (keys, files) */
19071 var buffer = new ArrayBuffer(0); 30624 ['bookVBA', false], /* include vba raw data (vbaraw) */
19072 try { 30625
19073 return new Blob([buffer], { type: "application/zip" }).size === 0; 30626 ['WTF', false] /* WTF mode (throws errors) */
19074 } 30627 ]);
19075 catch(e) {} 30628
19076 30629
19077 try { 30630 var fix_write_opts = fix_opts_func([
19078 var builder = new (window.BlobBuilder || window.WebKitBlobBuilder || 30631 ['bookSST', false], /* Generate Shared String Table */
19079 window.MozBlobBuilder || window.MSBlobBuilder)(); 30632
19080 builder.append(buffer); 30633 ['bookType', 'xlsx'], /* Type of workbook (xlsx/m/b) */
19081 return builder.getBlob('application/zip').size === 0; 30634
19082 } 30635 ['WTF', false] /* WTF mode (throws errors) */
19083 catch(e) {} 30636 ]);
19084 30637 function safe_parse_wbrels(wbrels, sheets) {
19085 return false; 30638 if(!wbrels) return 0;
19086 })() 30639 try {
30640 wbrels = sheets.map(function pwbr(w) { return [w.name, wbrels['!id'][w.id].Target]; });
30641 } catch(e) { return null; }
30642 return !wbrels || wbrels.length === 0 ? null : wbrels;
30643 }
30644
30645 function safe_parse_ws(zip, path, relsPath, sheet, sheetRels, sheets, opts) {
30646 try {
30647 sheetRels[sheet]=parse_rels(getzipdata(zip, relsPath, true), path);
30648 sheets[sheet]=parse_ws(getzipdata(zip, path),path,opts,sheetRels[sheet]);
30649 } catch(e) { if(opts.WTF) throw e; }
30650 }
30651
30652 var nodirs = function nodirs(x){return x.substr(-1) != '/';};
30653 function parse_zip(zip, opts) {
30654 make_ssf(SSF);
30655 opts = opts || {};
30656 fix_read_opts(opts);
30657 reset_cp();
30658 var entries = keys(zip.files).filter(nodirs).sort();
30659 var dir = parse_ct(getzipdata(zip, '[Content_Types].xml'), opts);
30660 var xlsb = false;
30661 var sheets, binname;
30662 if(dir.workbooks.length === 0) {
30663 binname = "xl/workbook.xml";
30664 if(getzipdata(zip,binname, true)) dir.workbooks.push(binname);
30665 }
30666 if(dir.workbooks.length === 0) {
30667 binname = "xl/workbook.bin";
30668 if(!getzipfile(zip,binname,true)) throw new Error("Could not find workbook");
30669 dir.workbooks.push(binname);
30670 xlsb = true;
30671 }
30672 if(dir.workbooks[0].substr(-3) == "bin") xlsb = true;
30673 if(xlsb) set_cp(1200);
30674
30675 if(!opts.bookSheets && !opts.bookProps) {
30676 strs = [];
30677 if(dir.sst) strs=parse_sst(getzipdata(zip, dir.sst.replace(/^\//,'')), dir.sst, opts);
30678
30679 styles = {};
30680 if(dir.style) styles = parse_sty(getzipdata(zip, dir.style.replace(/^\//,'')),dir.style, opts);
30681
30682 themes = {};
30683 if(opts.cellStyles && dir.themes.length) themes = parse_theme(getzipdata(zip, dir.themes[0].replace(/^\//,''), true),dir.themes[0], opts);
30684 }
30685
30686 var wb = parse_wb(getzipdata(zip, dir.workbooks[0].replace(/^\//,'')), dir.workbooks[0], opts);
30687
30688 var props = {}, propdata = "";
30689
30690 if(dir.coreprops.length !== 0) {
30691 propdata = getzipdata(zip, dir.coreprops[0].replace(/^\//,''), true);
30692 if(propdata) props = parse_core_props(propdata);
30693 if(dir.extprops.length !== 0) {
30694 propdata = getzipdata(zip, dir.extprops[0].replace(/^\//,''), true);
30695 if(propdata) parse_ext_props(propdata, props);
30696 }
30697 }
30698
30699 var custprops = {};
30700 if(!opts.bookSheets || opts.bookProps) {
30701 if (dir.custprops.length !== 0) {
30702 propdata = getzipdata(zip, dir.custprops[0].replace(/^\//,''), true);
30703 if(propdata) custprops = parse_cust_props(propdata, opts);
30704 }
30705 }
30706
30707 var out = {};
30708 if(opts.bookSheets || opts.bookProps) {
30709 if(props.Worksheets && props.SheetNames.length > 0) sheets=props.SheetNames;
30710 else if(wb.Sheets) sheets = wb.Sheets.map(function pluck(x){ return x.name; });
30711 if(opts.bookProps) { out.Props = props; out.Custprops = custprops; }
30712 if(typeof sheets !== 'undefined') out.SheetNames = sheets;
30713 if(opts.bookSheets ? out.SheetNames : opts.bookProps) return out;
30714 }
30715 sheets = {};
30716
30717 var deps = {};
30718 if(opts.bookDeps && dir.calcchain) deps=parse_cc(getzipdata(zip, dir.calcchain.replace(/^\//,'')),dir.calcchain,opts);
30719
30720 var i=0;
30721 var sheetRels = {};
30722 var path, relsPath;
30723 if(!props.Worksheets) {
30724 var wbsheets = wb.Sheets;
30725 props.Worksheets = wbsheets.length;
30726 props.SheetNames = [];
30727 for(var j = 0; j != wbsheets.length; ++j) {
30728 props.SheetNames[j] = wbsheets[j].name;
30729 }
30730 }
30731
30732 var wbext = xlsb ? "bin" : "xml";
30733 var wbrelsfile = 'xl/_rels/workbook.' + wbext + '.rels';
30734 var wbrels = parse_rels(getzipdata(zip, wbrelsfile, true), wbrelsfile);
30735 if(wbrels) wbrels = safe_parse_wbrels(wbrels, wb.Sheets);
30736 /* Numbers iOS hack */
30737 var nmode = (getzipdata(zip,"xl/worksheets/sheet.xml",true))?1:0;
30738 for(i = 0; i != props.Worksheets; ++i) {
30739 if(wbrels) path = 'xl/' + (wbrels[i][1]).replace(/[\/]?xl\//, "");
30740 else {
30741 path = 'xl/worksheets/sheet'+(i+1-nmode)+"." + wbext;
30742 path = path.replace(/sheet0\./,"sheet.");
30743 }
30744 relsPath = path.replace(/^(.*)(\/)([^\/]*)$/, "$1/_rels/$3.rels");
30745 safe_parse_ws(zip, path, relsPath, props.SheetNames[i], sheetRels, sheets, opts);
30746 }
30747
30748 if(dir.comments) parse_comments(zip, dir.comments, sheets, sheetRels, opts);
30749
30750 out = {
30751 Directory: dir,
30752 Workbook: wb,
30753 Props: props,
30754 Custprops: custprops,
30755 Deps: deps,
30756 Sheets: sheets,
30757 SheetNames: props.SheetNames,
30758 Strings: strs,
30759 Styles: styles,
30760 Themes: themes,
30761 SSF: SSF.get_table()
30762 };
30763 if(opts.bookFiles) {
30764 out.keys = entries;
30765 out.files = zip.files;
30766 }
30767 if(opts.bookVBA) {
30768 if(dir.vba.length > 0) out.vbaraw = getzipdata(zip,dir.vba[0],true);
30769 else if(dir.defaults.bin === 'application/vnd.ms-office.vbaProject') out.vbaraw = getzipdata(zip,'xl/vbaProject.bin',true);
30770 }
30771 return out;
30772 }
30773 function add_rels(rels, rId, f, type, relobj) {
30774 if(!relobj) relobj = {};
30775 if(!rels['!id']) rels['!id'] = {};
30776 relobj.Id = 'rId' + rId;
30777 relobj.Type = type;
30778 relobj.Target = f;
30779 if(rels['!id'][relobj.Id]) throw new Error("Cannot rewrite rId " + rId);
30780 rels['!id'][relobj.Id] = relobj;
30781 rels[('/' + relobj.Target).replace("//","/")] = relobj;
30782 }
30783
30784 function write_zip(wb, opts) {
30785 if(wb && !wb.SSF) {
30786 wb.SSF = SSF.get_table();
30787 }
30788 if(wb && wb.SSF) {
30789 make_ssf(SSF); SSF.load_table(wb.SSF);
30790 opts.revssf = evert_num(wb.SSF); opts.revssf[wb.SSF[65535]] = 0;
30791 }
30792 opts.rels = {}; opts.wbrels = {};
30793 opts.Strings = []; opts.Strings.Count = 0; opts.Strings.Unique = 0;
30794 var wbext = opts.bookType == "xlsb" ? "bin" : "xml";
30795 var ct = { workbooks: [], sheets: [], calcchains: [], themes: [], styles: [],
30796 coreprops: [], extprops: [], custprops: [], strs:[], comments: [], vba: [],
30797 TODO:[], rels:[], xmlns: "" };
30798 fix_write_opts(opts = opts || {});
30799 var zip = new jszip();
30800 var f = "", rId = 0;
30801
30802 opts.cellXfs = [];
30803 get_cell_style(opts.cellXfs, {}, {revssf:{"General":0}});
30804
30805 f = "docProps/core.xml";
30806 zip.file(f, write_core_props(wb.Props, opts));
30807 ct.coreprops.push(f);
30808 add_rels(opts.rels, 2, f, RELS.CORE_PROPS);
30809
30810 f = "docProps/app.xml";
30811 if(!wb.Props) wb.Props = {};
30812 wb.Props.SheetNames = wb.SheetNames;
30813 wb.Props.Worksheets = wb.SheetNames.length;
30814 zip.file(f, write_ext_props(wb.Props, opts));
30815 ct.extprops.push(f);
30816 add_rels(opts.rels, 3, f, RELS.EXT_PROPS);
30817
30818 if(wb.Custprops !== wb.Props && keys(wb.Custprops||{}).length > 0) {
30819 f = "docProps/custom.xml";
30820 zip.file(f, write_cust_props(wb.Custprops, opts));
30821 ct.custprops.push(f);
30822 add_rels(opts.rels, 4, f, RELS.CUST_PROPS);
30823 }
30824
30825 f = "xl/workbook." + wbext;
30826 zip.file(f, write_wb(wb, f, opts));
30827 ct.workbooks.push(f);
30828 add_rels(opts.rels, 1, f, RELS.WB);
30829
30830 for(rId=1;rId <= wb.SheetNames.length; ++rId) {
30831 f = "xl/worksheets/sheet" + rId + "." + wbext;
30832 zip.file(f, write_ws(rId-1, f, opts, wb));
30833 ct.sheets.push(f);
30834 add_rels(opts.wbrels, rId, "worksheets/sheet" + rId + "." + wbext, RELS.WS);
30835 }
30836
30837 if(opts.Strings != null && opts.Strings.length > 0) {
30838 f = "xl/sharedStrings." + wbext;
30839 zip.file(f, write_sst(opts.Strings, f, opts));
30840 ct.strs.push(f);
30841 add_rels(opts.wbrels, ++rId, "sharedStrings." + wbext, RELS.SST);
30842 }
30843
30844 /* TODO: something more intelligent with themes */
30845
30846 f = "xl/theme/theme1.xml";
30847 zip.file(f, write_theme());
30848 ct.themes.push(f);
30849 add_rels(opts.wbrels, ++rId, "theme/theme1.xml", RELS.THEME);
30850
30851 /* TODO: something more intelligent with styles */
30852
30853 f = "xl/styles." + wbext;
30854 zip.file(f, write_sty(wb, f, opts));
30855 ct.styles.push(f);
30856 add_rels(opts.wbrels, ++rId, "styles." + wbext, RELS.STY);
30857
30858 zip.file("[Content_Types].xml", write_ct(ct, opts));
30859 zip.file('_rels/.rels', write_rels(opts.rels));
30860 zip.file('xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels));
30861 return zip;
30862 }
30863 function readSync(data, opts) {
30864 var zip, d = data;
30865 var o = opts||{};
30866 if(!o.type) o.type = (has_buf && Buffer.isBuffer(data)) ? "buffer" : "base64";
30867 switch(o.type) {
30868 case "base64": zip = new jszip(d, { base64:true }); break;
30869 case "binary": zip = new jszip(d, { base64:false }); break;
30870 case "buffer": zip = new jszip(d); break;
30871 case "file": zip=new jszip(d=_fs.readFileSync(data)); break;
30872 default: throw new Error("Unrecognized type " + o.type);
30873 }
30874 return parse_zip(zip, o);
30875 }
30876
30877 function readFileSync(data, opts) {
30878 var o = opts||{}; o.type = 'file';
30879 return readSync(data, o);
30880 }
30881
30882 function writeSync(wb, opts) {
30883 var o = opts||{};
30884 var z = write_zip(wb, o);
30885 switch(o.type) {
30886 case "base64": return z.generate({type:"base64"});
30887 case "binary": return z.generate({type:"string"});
30888 case "buffer": return z.generate({type:"nodebuffer"});
30889 case "file": return _fs.writeFileSync(o.file, z.generate({type:"nodebuffer"}));
30890 default: throw new Error("Unrecognized type " + o.type);
30891 }
30892 }
30893
30894 function writeFileSync(wb, filename, opts) {
30895 var o = opts||{}; o.type = 'file';
30896 o.file = filename;
30897 switch(o.file.substr(-5).toLowerCase()) {
30898 case '.xlsm': o.bookType = 'xlsm'; break;
30899 case '.xlsb': o.bookType = 'xlsb'; break;
30900 }
30901 return writeSync(wb, o);
30902 }
30903
30904 function decode_row(rowstr) { return parseInt(unfix_row(rowstr),10) - 1; }
30905 function encode_row(row) { return "" + (row + 1); }
30906 function fix_row(cstr) { return cstr.replace(/([A-Z]|^)(\d+)$/,"$1$$$2"); }
30907 function unfix_row(cstr) { return cstr.replace(/\$(\d+)$/,"$1"); }
30908
30909 function decode_col(colstr) { var c = unfix_col(colstr), d = 0, i = 0; for(; i !== c.length; ++i) d = 26*d + c.charCodeAt(i) - 64; return d - 1; }
30910 function encode_col(col) { var s=""; for(++col; col; col=Math.floor((col-1)/26)) s = String.fromCharCode(((col-1)%26) + 65) + s; return s; }
30911 function fix_col(cstr) { return cstr.replace(/^([A-Z])/,"$$$1"); }
30912 function unfix_col(cstr) { return cstr.replace(/^\$([A-Z])/,"$1"); }
30913
30914 function split_cell(cstr) { return cstr.replace(/(\$?[A-Z]*)(\$?\d*)/,"$1,$2").split(","); }
30915 function decode_cell(cstr) { var splt = split_cell(cstr); return { c:decode_col(splt[0]), r:decode_row(splt[1]) }; }
30916 function encode_cell(cell) { return encode_col(cell.c) + encode_row(cell.r); }
30917 function fix_cell(cstr) { return fix_col(fix_row(cstr)); }
30918 function unfix_cell(cstr) { return unfix_col(unfix_row(cstr)); }
30919 function decode_range(range) { var x =range.split(":").map(decode_cell); return {s:x[0],e:x[x.length-1]}; }
30920 function encode_range(cs,ce) {
30921 if(ce === undefined || typeof ce === 'number') return encode_range(cs.s, cs.e);
30922 if(typeof cs !== 'string') cs = encode_cell(cs); if(typeof ce !== 'string') ce = encode_cell(ce);
30923 return cs == ce ? cs : cs + ":" + ce;
30924 }
30925
30926 function safe_decode_range(range) {
30927 var o = {s:{c:0,r:0},e:{c:0,r:0}};
30928 var idx = 0, i = 0, cc = 0;
30929 var len = range.length;
30930 for(idx = 0; i < len; ++i) {
30931 if((cc=range.charCodeAt(i)-64) < 1 || cc > 26) break;
30932 idx = 26*idx + cc;
30933 }
30934 o.s.c = --idx;
30935
30936 for(idx = 0; i < len; ++i) {
30937 if((cc=range.charCodeAt(i)-48) < 0 || cc > 9) break;
30938 idx = 10*idx + cc;
30939 }
30940 o.s.r = --idx;
30941
30942 if(i === len || range.charCodeAt(++i) === 58) { o.e.c=o.s.c; o.e.r=o.s.r; return o; }
30943
30944 for(idx = 0; i != len; ++i) {
30945 if((cc=range.charCodeAt(i)-64) < 1 || cc > 26) break;
30946 idx = 26*idx + cc;
30947 }
30948 o.e.c = --idx;
30949
30950 for(idx = 0; i != len; ++i) {
30951 if((cc=range.charCodeAt(i)-48) < 0 || cc > 9) break;
30952 idx = 10*idx + cc;
30953 }
30954 o.e.r = --idx;
30955 return o;
30956 }
30957
30958 function safe_format_cell(cell, v) {
30959 if(cell.z !== undefined) try { return (cell.w = SSF.format(cell.z, v)); } catch(e) { }
30960 if(!cell.XF) return v;
30961 try { return (cell.w = SSF.format(cell.XF.ifmt||0, v)); } catch(e) { return ''+v; }
30962 }
30963
30964 function format_cell(cell, v) {
30965 if(cell == null || cell.t == null) return "";
30966 if(cell.w !== undefined) return cell.w;
30967 if(v === undefined) return safe_format_cell(cell, cell.v);
30968 return safe_format_cell(cell, v);
30969 }
30970
30971 function sheet_to_json(sheet, opts){
30972 var val, row, range, header = 0, offset = 1, r, hdr = [], isempty, R, C, v;
30973 var o = opts != null ? opts : {};
30974 var raw = o.raw;
30975 if(sheet == null || sheet["!ref"] == null) return [];
30976 range = o.range !== undefined ? o.range : sheet["!ref"];
30977 if(o.header === 1) header = 1;
30978 else if(o.header === "A") header = 2;
30979 else if(Array.isArray(o.header)) header = 3;
30980 switch(typeof range) {
30981 case 'string': r = safe_decode_range(range); break;
30982 case 'number': r = safe_decode_range(sheet["!ref"]); r.s.r = range; break;
30983 default: r = range;
30984 }
30985 if(header > 0) offset = 0;
30986 var rr = encode_row(r.s.r);
30987 var cols = new Array(r.e.c-r.s.c+1);
30988 var out = new Array(r.e.r-r.s.r-offset+1);
30989 var outi = 0;
30990 for(C = r.s.c; C <= r.e.c; ++C) {
30991 cols[C] = encode_col(C);
30992 val = sheet[cols[C] + rr];
30993 switch(header) {
30994 case 1: hdr[C] = C; break;
30995 case 2: hdr[C] = cols[C]; break;
30996 case 3: hdr[C] = o.header[C - r.s.c]; break;
30997 default:
30998 if(val === undefined) continue;
30999 hdr[C] = format_cell(val);
31000 }
31001 }
31002
31003 for (R = r.s.r + offset; R <= r.e.r; ++R) {
31004 rr = encode_row(R);
31005 isempty = true;
31006 row = header === 1 ? [] : Object.create({ __rowNum__ : R });
31007 for (C = r.s.c; C <= r.e.c; ++C) {
31008 val = sheet[cols[C] + rr];
31009 if(val === undefined || val.t === undefined) continue;
31010 v = val.v;
31011 switch(val.t){
31012 case 'e': continue;
31013 case 's': case 'str': break;
31014 case 'b': case 'n': break;
31015 default: throw 'unrecognized type ' + val.t;
31016 }
31017 if(v !== undefined) {
31018 row[hdr[C]] = raw ? v : format_cell(val,v);
31019 isempty = false;
31020 }
31021 }
31022 if(isempty === false) out[outi++] = row;
31023 }
31024 out.length = outi;
31025 return out;
31026 }
31027
31028 function sheet_to_row_object_array(sheet, opts) { return sheet_to_json(sheet, opts != null ? opts : {}); }
31029
31030 function sheet_to_csv(sheet, opts) {
31031 var out = "", txt = "", qreg = /"/g;
31032 var o = opts == null ? {} : opts;
31033 if(sheet == null || sheet["!ref"] == null) return "";
31034 var r = safe_decode_range(sheet["!ref"]);
31035 var FS = o.FS !== undefined ? o.FS : ",", fs = FS.charCodeAt(0);
31036 var RS = o.RS !== undefined ? o.RS : "\n", rs = RS.charCodeAt(0);
31037 var row = "", rr = "", cols = [];
31038 var i = 0, cc = 0, val;
31039 var R = 0, C = 0;
31040 for(C = r.s.c; C <= r.e.c; ++C) cols[C] = encode_col(C);
31041 for(R = r.s.r; R <= r.e.r; ++R) {
31042 row = "";
31043 rr = encode_row(R);
31044 for(C = r.s.c; C <= r.e.c; ++C) {
31045 val = sheet[cols[C] + rr];
31046 txt = val !== undefined ? ''+format_cell(val) : "";
31047 for(i = 0, cc = 0; i !== txt.length; ++i) if((cc = txt.charCodeAt(i)) === fs || cc === rs || cc === 34) {
31048 txt = "\"" + txt.replace(qreg, '""') + "\""; break; }
31049 row += (C === r.s.c ? "" : FS) + txt;
31050 }
31051 out += row + RS;
31052 }
31053 return out;
31054 }
31055 var make_csv = sheet_to_csv;
31056
31057 function sheet_to_formulae(sheet) {
31058 var cmds, y = "", x, val="";
31059 if(sheet == null || sheet["!ref"] == null) return "";
31060 var r = safe_decode_range(sheet['!ref']), rr = "", cols = [], C;
31061 cmds = new Array((r.e.r-r.s.r+1)*(r.e.c-r.s.c+1));
31062 var i = 0;
31063 for(C = r.s.c; C <= r.e.c; ++C) cols[C] = encode_col(C);
31064 for(var R = r.s.r; R <= r.e.r; ++R) {
31065 rr = encode_row(R);
31066 for(C = r.s.c; C <= r.e.c; ++C) {
31067 y = cols[C] + rr;
31068 x = sheet[y];
31069 val = "";
31070 if(x === undefined) continue;
31071 if(x.f != null) val = x.f;
31072 else if(x.w !== undefined) val = "'" + x.w;
31073 else if(x.v === undefined) continue;
31074 else val = ""+x.v;
31075 cmds[i++] = y + "=" + val;
31076 }
31077 }
31078 cmds.length = i;
31079 return cmds;
31080 }
31081
31082 var utils = {
31083 encode_col: encode_col,
31084 encode_row: encode_row,
31085 encode_cell: encode_cell,
31086 encode_range: encode_range,
31087 decode_col: decode_col,
31088 decode_row: decode_row,
31089 split_cell: split_cell,
31090 decode_cell: decode_cell,
31091 decode_range: decode_range,
31092 format_cell: format_cell,
31093 get_formulae: sheet_to_formulae,
31094 make_csv: sheet_to_csv,
31095 make_json: sheet_to_json,
31096 make_formulae: sheet_to_formulae,
31097 sheet_to_csv: sheet_to_csv,
31098 sheet_to_json: sheet_to_json,
31099 sheet_to_formulae: sheet_to_formulae,
31100 sheet_to_row_object_array: sheet_to_row_object_array
19087 }; 31101 };
19088 31102 XLSX.parseZip = parse_zip;
19089 JSZip.utils = { 31103 XLSX.read = readSync;
19090 /** 31104 XLSX.readFile = readFileSync;
19091 * Convert a string to a "binary string" : a string containing only char codes between 0 and 255. 31105 XLSX.write = writeSync;
19092 * @param {string} str the string to transform. 31106 XLSX.writeFile = writeFileSync;
19093 * @return {String} the binary string. 31107 XLSX.utils = utils;
19094 */ 31108 XLSX.SSF = SSF;
19095 string2binary : function (str) { 31109 })(typeof exports !== 'undefined' ? exports : XLSX);
19096 var result = "";
19097 for (var i = 0; i < str.length; i++) {
19098 result += String.fromCharCode(str.charCodeAt(i) & 0xff);
19099 }
19100 return result;
19101 },
19102 /**
19103 * Create a Uint8Array from the string.
19104 * @param {string} str the string to transform.
19105 * @return {Uint8Array} the typed array.
19106 * @throws {Error} an Error if the browser doesn't support the requested feature.
19107 */
19108 string2Uint8Array : function (str) {
19109 if (!JSZip.support.uint8array) {
19110 throw new Error("Uint8Array is not supported by this browser");
19111 }
19112 var buffer = new ArrayBuffer(str.length);
19113 var bufferView = new Uint8Array(buffer);
19114 for(var i = 0; i < str.length; i++) {
19115 bufferView[i] = str.charCodeAt(i);
19116 }
19117
19118 return bufferView;
19119 },
19120
19121 /**
19122 * Create a string from the Uint8Array.
19123 * @param {Uint8Array} array the array to transform.
19124 * @return {string} the string.
19125 * @throws {Error} an Error if the browser doesn't support the requested feature.
19126 */
19127 uint8Array2String : function (array) {
19128 if (!JSZip.support.uint8array) {
19129 throw new Error("Uint8Array is not supported by this browser");
19130 }
19131 var result = "";
19132 for(var i = 0; i < array.length; i++) {
19133 result += String.fromCharCode(array[i]);
19134 }
19135
19136 return result;
19137 },
19138 /**
19139 * Create a blob from the given string.
19140 * @param {string} str the string to transform.
19141 * @return {Blob} the string.
19142 * @throws {Error} an Error if the browser doesn't support the requested feature.
19143 */
19144 string2Blob : function (str) {
19145 if (!JSZip.support.blob) {
19146 throw new Error("Blob is not supported by this browser");
19147 }
19148
19149 var buffer = JSZip.utils.string2Uint8Array(str).buffer;
19150 try {
19151 // Blob constructor
19152 return new Blob([buffer], { type: "application/zip" });
19153 }
19154 catch(e) {}
19155
19156 try {
19157 // deprecated, browser only, old way
19158 var builder = new (window.BlobBuilder || window.WebKitBlobBuilder ||
19159 window.MozBlobBuilder || window.MSBlobBuilder)();
19160 builder.append(buffer);
19161 return builder.getBlob('application/zip');
19162 }
19163 catch(e) {}
19164
19165 // well, fuck ?!
19166 throw new Error("Bug : can't construct the Blob.");
19167 }
19168 };
19169
19170 /**
19171 *
19172 * Base64 encode / decode
19173 * http://www.webtoolkit.info/
19174 *
19175 * Hacked so that it doesn't utf8 en/decode everything
19176 **/
19177 var JSZipBase64 = (function() {
19178 // private property
19179 var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
19180
19181 return {
19182 // public method for encoding
19183 encode : function(input, utf8) {
19184 var output = "";
19185 var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
19186 var i = 0;
19187
19188 while (i < input.length) {
19189
19190 chr1 = input.charCodeAt(i++);
19191 chr2 = input.charCodeAt(i++);
19192 chr3 = input.charCodeAt(i++);
19193
19194 enc1 = chr1 >> 2;
19195 enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
19196 enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
19197 enc4 = chr3 & 63;
19198
19199 if (isNaN(chr2)) {
19200 enc3 = enc4 = 64;
19201 } else if (isNaN(chr3)) {
19202 enc4 = 64;
19203 }
19204
19205 output = output +
19206 _keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
19207 _keyStr.charAt(enc3) + _keyStr.charAt(enc4);
19208
19209 }
19210
19211 return output;
19212 },
19213
19214 // public method for decoding
19215 decode : function(input, utf8) {
19216 var output = "";
19217 var chr1, chr2, chr3;
19218 var enc1, enc2, enc3, enc4;
19219 var i = 0;
19220
19221 input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
19222
19223 while (i < input.length) {
19224
19225 enc1 = _keyStr.indexOf(input.charAt(i++));
19226 enc2 = _keyStr.indexOf(input.charAt(i++));
19227 enc3 = _keyStr.indexOf(input.charAt(i++));
19228 enc4 = _keyStr.indexOf(input.charAt(i++));
19229
19230 chr1 = (enc1 << 2) | (enc2 >> 4);
19231 chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
19232 chr3 = ((enc3 & 3) << 6) | enc4;
19233
19234 output = output + String.fromCharCode(chr1);
19235
19236 if (enc3 != 64) {
19237 output = output + String.fromCharCode(chr2);
19238 }
19239 if (enc4 != 64) {
19240 output = output + String.fromCharCode(chr3);
19241 }
19242
19243 }
19244
19245 return output;
19246
19247 }
19248 };
19249 }());
19250
19251 // enforcing Stuk's coding style
19252 // vim: set shiftwidth=3 softtabstop=3:
19253 /*
19254 * Port of a script by Masanao Izumo.
19255 *
19256 * Only changes : wrap all the variables in a function and add the
19257 * main function to JSZip (DEFLATE compression method).
19258 * Everything else was written by M. Izumo.
19259 *
19260 * Original code can be found here: http://www.onicos.com/staff/iz/amuse/javascript/expert/deflate.txt
19261 */
19262
19263 if(!JSZip) {
19264 throw "JSZip not defined";
19265 }
19266
19267 /*
19268 * Original:
19269 * http://www.onicos.com/staff/iz/amuse/javascript/expert/deflate.txt
19270 */
19271
19272 (function(){
19273
19274 /* Copyright (C) 1999 Masanao Izumo <iz@onicos.co.jp>
19275 * Version: 1.0.1
19276 * LastModified: Dec 25 1999
19277 */
19278
19279 /* Interface:
19280 * data = zip_deflate(src);
19281 */
19282
19283 /* constant parameters */
19284 var zip_WSIZE = 32768; // Sliding Window size
19285 var zip_STORED_BLOCK = 0;
19286 var zip_STATIC_TREES = 1;
19287 var zip_DYN_TREES = 2;
19288
19289 /* for deflate */
19290 var zip_DEFAULT_LEVEL = 6;
19291 var zip_FULL_SEARCH = true;
19292 var zip_INBUFSIZ = 32768; // Input buffer size
19293 var zip_INBUF_EXTRA = 64; // Extra buffer
19294 var zip_OUTBUFSIZ = 1024 * 8;
19295 var zip_window_size = 2 * zip_WSIZE;
19296 var zip_MIN_MATCH = 3;
19297 var zip_MAX_MATCH = 258;
19298 var zip_BITS = 16;
19299 // for SMALL_MEM
19300 var zip_LIT_BUFSIZE = 0x2000;
19301 var zip_HASH_BITS = 13;
19302 // for MEDIUM_MEM
19303 // var zip_LIT_BUFSIZE = 0x4000;
19304 // var zip_HASH_BITS = 14;
19305 // for BIG_MEM
19306 // var zip_LIT_BUFSIZE = 0x8000;
19307 // var zip_HASH_BITS = 15;
19308 if(zip_LIT_BUFSIZE > zip_INBUFSIZ)
19309 alert("error: zip_INBUFSIZ is too small");
19310 if((zip_WSIZE<<1) > (1<<zip_BITS))
19311 alert("error: zip_WSIZE is too large");
19312 if(zip_HASH_BITS > zip_BITS-1)
19313 alert("error: zip_HASH_BITS is too large");
19314 if(zip_HASH_BITS < 8 || zip_MAX_MATCH != 258)
19315 alert("error: Code too clever");
19316 var zip_DIST_BUFSIZE = zip_LIT_BUFSIZE;
19317 var zip_HASH_SIZE = 1 << zip_HASH_BITS;
19318 var zip_HASH_MASK = zip_HASH_SIZE - 1;
19319 var zip_WMASK = zip_WSIZE - 1;
19320 var zip_NIL = 0; // Tail of hash chains
19321 var zip_TOO_FAR = 4096;
19322 var zip_MIN_LOOKAHEAD = zip_MAX_MATCH + zip_MIN_MATCH + 1;
19323 var zip_MAX_DIST = zip_WSIZE - zip_MIN_LOOKAHEAD;
19324 var zip_SMALLEST = 1;
19325 var zip_MAX_BITS = 15;
19326 var zip_MAX_BL_BITS = 7;
19327 var zip_LENGTH_CODES = 29;
19328 var zip_LITERALS =256;
19329 var zip_END_BLOCK = 256;
19330 var zip_L_CODES = zip_LITERALS + 1 + zip_LENGTH_CODES;
19331 var zip_D_CODES = 30;
19332 var zip_BL_CODES = 19;
19333 var zip_REP_3_6 = 16;
19334 var zip_REPZ_3_10 = 17;
19335 var zip_REPZ_11_138 = 18;
19336 var zip_HEAP_SIZE = 2 * zip_L_CODES + 1;
19337 var zip_H_SHIFT = parseInt((zip_HASH_BITS + zip_MIN_MATCH - 1) /
19338 zip_MIN_MATCH);
19339
19340 /* variables */
19341 var zip_free_queue;
19342 var zip_qhead, zip_qtail;
19343 var zip_initflag;
19344 var zip_outbuf = null;
19345 var zip_outcnt, zip_outoff;
19346 var zip_complete;
19347 var zip_window;
19348 var zip_d_buf;
19349 var zip_l_buf;
19350 var zip_prev;
19351 var zip_bi_buf;
19352 var zip_bi_valid;
19353 var zip_block_start;
19354 var zip_ins_h;
19355 var zip_hash_head;
19356 var zip_prev_match;
19357 var zip_match_available;
19358 var zip_match_length;
19359 var zip_prev_length;
19360 var zip_strstart;
19361 var zip_match_start;
19362 var zip_eofile;
19363 var zip_lookahead;
19364 var zip_max_chain_length;
19365 var zip_max_lazy_match;
19366 var zip_compr_level;
19367 var zip_good_match;
19368 var zip_nice_match;
19369 var zip_dyn_ltree;
19370 var zip_dyn_dtree;
19371 var zip_static_ltree;
19372 var zip_static_dtree;
19373 var zip_bl_tree;
19374 var zip_l_desc;
19375 var zip_d_desc;
19376 var zip_bl_desc;
19377 var zip_bl_count;
19378 var zip_heap;
19379 var zip_heap_len;
19380 var zip_heap_max;
19381 var zip_depth;
19382 var zip_length_code;
19383 var zip_dist_code;
19384 var zip_base_length;
19385 var zip_base_dist;
19386 var zip_flag_buf;
19387 var zip_last_lit;
19388 var zip_last_dist;
19389 var zip_last_flags;
19390 var zip_flags;
19391 var zip_flag_bit;
19392 var zip_opt_len;
19393 var zip_static_len;
19394 var zip_deflate_data;
19395 var zip_deflate_pos;
19396
19397 /* objects (deflate) */
19398
19399 var zip_DeflateCT = function() {
19400 this.fc = 0; // frequency count or bit string
19401 this.dl = 0; // father node in Huffman tree or length of bit string
19402 }
19403
19404 var zip_DeflateTreeDesc = function() {
19405 this.dyn_tree = null; // the dynamic tree
19406 this.static_tree = null; // corresponding static tree or NULL
19407 this.extra_bits = null; // extra bits for each code or NULL
19408 this.extra_base = 0; // base index for extra_bits
19409 this.elems = 0; // max number of elements in the tree
19410 this.max_length = 0; // max bit length for the codes
19411 this.max_code = 0; // largest code with non zero frequency
19412 }
19413
19414 /* Values for max_lazy_match, good_match and max_chain_length, depending on
19415 * the desired pack level (0..9). The values given below have been tuned to
19416 * exclude worst case performance for pathological files. Better values may be
19417 * found for specific files.
19418 */
19419 var zip_DeflateConfiguration = function(a, b, c, d) {
19420 this.good_length = a; // reduce lazy search above this match length
19421 this.max_lazy = b; // do not perform lazy search above this match length
19422 this.nice_length = c; // quit search above this match length
19423 this.max_chain = d;
19424 }
19425
19426 var zip_DeflateBuffer = function() {
19427 this.next = null;
19428 this.len = 0;
19429 this.ptr = new Array(zip_OUTBUFSIZ);
19430 this.off = 0;
19431 }
19432
19433 /* constant tables */
19434 var zip_extra_lbits = new Array(
19435 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0);
19436 var zip_extra_dbits = new Array(
19437 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13);
19438 var zip_extra_blbits = new Array(
19439 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7);
19440 var zip_bl_order = new Array(
19441 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15);
19442 var zip_configuration_table = new Array(
19443 new zip_DeflateConfiguration(0, 0, 0, 0),
19444 new zip_DeflateConfiguration(4, 4, 8, 4),
19445 new zip_DeflateConfiguration(4, 5, 16, 8),
19446 new zip_DeflateConfiguration(4, 6, 32, 32),
19447 new zip_DeflateConfiguration(4, 4, 16, 16),
19448 new zip_DeflateConfiguration(8, 16, 32, 32),
19449 new zip_DeflateConfiguration(8, 16, 128, 128),
19450 new zip_DeflateConfiguration(8, 32, 128, 256),
19451 new zip_DeflateConfiguration(32, 128, 258, 1024),
19452 new zip_DeflateConfiguration(32, 258, 258, 4096));
19453
19454
19455 /* routines (deflate) */
19456
19457 var zip_deflate_start = function(level) {
19458 var i;
19459
19460 if(!level)
19461 level = zip_DEFAULT_LEVEL;
19462 else if(level < 1)
19463 level = 1;
19464 else if(level > 9)
19465 level = 9;
19466
19467 zip_compr_level = level;
19468 zip_initflag = false;
19469 zip_eofile = false;
19470 if(zip_outbuf != null)
19471 return;
19472
19473 zip_free_queue = zip_qhead = zip_qtail = null;
19474 zip_outbuf = new Array(zip_OUTBUFSIZ);
19475 zip_window = new Array(zip_window_size);
19476 zip_d_buf = new Array(zip_DIST_BUFSIZE);
19477 zip_l_buf = new Array(zip_INBUFSIZ + zip_INBUF_EXTRA);
19478 zip_prev = new Array(1 << zip_BITS);
19479 zip_dyn_ltree = new Array(zip_HEAP_SIZE);
19480 for(i = 0; i < zip_HEAP_SIZE; i++)
19481 zip_dyn_ltree[i] = new zip_DeflateCT();
19482 zip_dyn_dtree = new Array(2*zip_D_CODES+1);
19483 for(i = 0; i < 2*zip_D_CODES+1; i++)
19484 zip_dyn_dtree[i] = new zip_DeflateCT();
19485 zip_static_ltree = new Array(zip_L_CODES+2);
19486 for(i = 0; i < zip_L_CODES+2; i++)
19487 zip_static_ltree[i] = new zip_DeflateCT();
19488 zip_static_dtree = new Array(zip_D_CODES);
19489 for(i = 0; i < zip_D_CODES; i++)
19490 zip_static_dtree[i] = new zip_DeflateCT();
19491 zip_bl_tree = new Array(2*zip_BL_CODES+1);
19492 for(i = 0; i < 2*zip_BL_CODES+1; i++)
19493 zip_bl_tree[i] = new zip_DeflateCT();
19494 zip_l_desc = new zip_DeflateTreeDesc();
19495 zip_d_desc = new zip_DeflateTreeDesc();
19496 zip_bl_desc = new zip_DeflateTreeDesc();
19497 zip_bl_count = new Array(zip_MAX_BITS+1);
19498 zip_heap = new Array(2*zip_L_CODES+1);
19499 zip_depth = new Array(2*zip_L_CODES+1);
19500 zip_length_code = new Array(zip_MAX_MATCH-zip_MIN_MATCH+1);
19501 zip_dist_code = new Array(512);
19502 zip_base_length = new Array(zip_LENGTH_CODES);
19503 zip_base_dist = new Array(zip_D_CODES);
19504 zip_flag_buf = new Array(parseInt(zip_LIT_BUFSIZE / 8));
19505 }
19506
19507 var zip_deflate_end = function() {
19508 zip_free_queue = zip_qhead = zip_qtail = null;
19509 zip_outbuf = null;
19510 zip_window = null;
19511 zip_d_buf = null;
19512 zip_l_buf = null;
19513 zip_prev = null;
19514 zip_dyn_ltree = null;
19515 zip_dyn_dtree = null;
19516 zip_static_ltree = null;
19517 zip_static_dtree = null;
19518 zip_bl_tree = null;
19519 zip_l_desc = null;
19520 zip_d_desc = null;
19521 zip_bl_desc = null;
19522 zip_bl_count = null;
19523 zip_heap = null;
19524 zip_depth = null;
19525 zip_length_code = null;
19526 zip_dist_code = null;
19527 zip_base_length = null;
19528 zip_base_dist = null;
19529 zip_flag_buf = null;
19530 }
19531
19532 var zip_reuse_queue = function(p) {
19533 p.next = zip_free_queue;
19534 zip_free_queue = p;
19535 }
19536
19537 var zip_new_queue = function() {
19538 var p;
19539
19540 if(zip_free_queue != null)
19541 {
19542 p = zip_free_queue;
19543 zip_free_queue = zip_free_queue.next;
19544 }
19545 else
19546 p = new zip_DeflateBuffer();
19547 p.next = null;
19548 p.len = p.off = 0;
19549
19550 return p;
19551 }
19552
19553 var zip_head1 = function(i) {
19554 return zip_prev[zip_WSIZE + i];
19555 }
19556
19557 var zip_head2 = function(i, val) {
19558 return zip_prev[zip_WSIZE + i] = val;
19559 }
19560
19561 /* put_byte is used for the compressed output, put_ubyte for the
19562 * uncompressed output. However unlzw() uses window for its
19563 * suffix table instead of its output buffer, so it does not use put_ubyte
19564 * (to be cleaned up).
19565 */
19566 var zip_put_byte = function(c) {
19567 zip_outbuf[zip_outoff + zip_outcnt++] = c;
19568 if(zip_outoff + zip_outcnt == zip_OUTBUFSIZ)
19569 zip_qoutbuf();
19570 }
19571
19572 /* Output a 16 bit value, lsb first */
19573 var zip_put_short = function(w) {
19574 w &= 0xffff;
19575 if(zip_outoff + zip_outcnt < zip_OUTBUFSIZ - 2) {
19576 zip_outbuf[zip_outoff + zip_outcnt++] = (w & 0xff);
19577 zip_outbuf[zip_outoff + zip_outcnt++] = (w >>> 8);
19578 } else {
19579 zip_put_byte(w & 0xff);
19580 zip_put_byte(w >>> 8);
19581 }
19582 }
19583
19584 /* ==========================================================================
19585 * Insert string s in the dictionary and set match_head to the previous head
19586 * of the hash chain (the most recent string with same hash key). Return
19587 * the previous length of the hash chain.
19588 * IN assertion: all calls to to INSERT_STRING are made with consecutive
19589 * input characters and the first MIN_MATCH bytes of s are valid
19590 * (except for the last MIN_MATCH-1 bytes of the input file).
19591 */
19592 var zip_INSERT_STRING = function() {
19593 zip_ins_h = ((zip_ins_h << zip_H_SHIFT)
19594 ^ (zip_window[zip_strstart + zip_MIN_MATCH - 1] & 0xff))
19595 & zip_HASH_MASK;
19596 zip_hash_head = zip_head1(zip_ins_h);
19597 zip_prev[zip_strstart & zip_WMASK] = zip_hash_head;
19598 zip_head2(zip_ins_h, zip_strstart);
19599 }
19600
19601 /* Send a code of the given tree. c and tree must not have side effects */
19602 var zip_SEND_CODE = function(c, tree) {
19603 zip_send_bits(tree[c].fc, tree[c].dl);
19604 }
19605
19606 /* Mapping from a distance to a distance code. dist is the distance - 1 and
19607 * must not have side effects. dist_code[256] and dist_code[257] are never
19608 * used.
19609 */
19610 var zip_D_CODE = function(dist) {
19611 return (dist < 256 ? zip_dist_code[dist]
19612 : zip_dist_code[256 + (dist>>7)]) & 0xff;
19613 }
19614
19615 /* ==========================================================================
19616 * Compares to subtrees, using the tree depth as tie breaker when
19617 * the subtrees have equal frequency. This minimizes the worst case length.
19618 */
19619 var zip_SMALLER = function(tree, n, m) {
19620 return tree[n].fc < tree[m].fc ||
19621 (tree[n].fc == tree[m].fc && zip_depth[n] <= zip_depth[m]);
19622 }
19623
19624 /* ==========================================================================
19625 * read string data
19626 */
19627 var zip_read_buff = function(buff, offset, n) {
19628 var i;
19629 for(i = 0; i < n && zip_deflate_pos < zip_deflate_data.length; i++)
19630 buff[offset + i] =
19631 zip_deflate_data.charCodeAt(zip_deflate_pos++) & 0xff;
19632 return i;
19633 }
19634
19635 /* ==========================================================================
19636 * Initialize the "longest match" routines for a new file
19637 */
19638 var zip_lm_init = function() {
19639 var j;
19640
19641 /* Initialize the hash table. */
19642 for(j = 0; j < zip_HASH_SIZE; j++)
19643 // zip_head2(j, zip_NIL);
19644 zip_prev[zip_WSIZE + j] = 0;
19645 /* prev will be initialized on the fly */
19646
19647 /* Set the default configuration parameters:
19648 */
19649 zip_max_lazy_match = zip_configuration_table[zip_compr_level].max_lazy;
19650 zip_good_match = zip_configuration_table[zip_compr_level].good_length;
19651 if(!zip_FULL_SEARCH)
19652 zip_nice_match = zip_configuration_table[zip_compr_level].nice_length;
19653 zip_max_chain_length = zip_configuration_table[zip_compr_level].max_chain;
19654
19655 zip_strstart = 0;
19656 zip_block_start = 0;
19657
19658 zip_lookahead = zip_read_buff(zip_window, 0, 2 * zip_WSIZE);
19659 if(zip_lookahead <= 0) {
19660 zip_eofile = true;
19661 zip_lookahead = 0;
19662 return;
19663 }
19664 zip_eofile = false;
19665 /* Make sure that we always have enough lookahead. This is important
19666 * if input comes from a device such as a tty.
19667 */
19668 while(zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile)
19669 zip_fill_window();
19670
19671 /* If lookahead < MIN_MATCH, ins_h is garbage, but this is
19672 * not important since only literal bytes will be emitted.
19673 */
19674 zip_ins_h = 0;
19675 for(j = 0; j < zip_MIN_MATCH - 1; j++) {
19676 // UPDATE_HASH(ins_h, window[j]);
19677 zip_ins_h = ((zip_ins_h << zip_H_SHIFT) ^ (zip_window[j] & 0xff)) & zip_HASH_MASK;
19678 }
19679 }
19680
19681 /* ==========================================================================
19682 * Set match_start to the longest match starting at the given string and
19683 * return its length. Matches shorter or equal to prev_length are discarded,
19684 * in which case the result is equal to prev_length and match_start is
19685 * garbage.
19686 * IN assertions: cur_match is the head of the hash chain for the current
19687 * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
19688 */
19689 var zip_longest_match = function(cur_match) {
19690 var chain_length = zip_max_chain_length; // max hash chain length
19691 var scanp = zip_strstart; // current string
19692 var matchp; // matched string
19693 var len; // length of current match
19694 var best_len = zip_prev_length; // best match length so far
19695
19696 /* Stop when cur_match becomes <= limit. To simplify the code,
19697 * we prevent matches with the string of window index 0.
19698 */
19699 var limit = (zip_strstart > zip_MAX_DIST ? zip_strstart - zip_MAX_DIST : zip_NIL);
19700
19701 var strendp = zip_strstart + zip_MAX_MATCH;
19702 var scan_end1 = zip_window[scanp + best_len - 1];
19703 var scan_end = zip_window[scanp + best_len];
19704
19705 /* Do not waste too much time if we already have a good match: */
19706 if(zip_prev_length >= zip_good_match)
19707 chain_length >>= 2;
19708
19709 // Assert(encoder->strstart <= window_size-MIN_LOOKAHEAD, "insufficient lookahead");
19710
19711 do {
19712 // Assert(cur_match < encoder->strstart, "no future");
19713 matchp = cur_match;
19714
19715 /* Skip to next match if the match length cannot increase
19716 * or if the match length is less than 2:
19717 */
19718 if(zip_window[matchp + best_len] != scan_end ||
19719 zip_window[matchp + best_len - 1] != scan_end1 ||
19720 zip_window[matchp] != zip_window[scanp] ||
19721 zip_window[++matchp] != zip_window[scanp + 1]) {
19722 continue;
19723 }
19724
19725 /* The check at best_len-1 can be removed because it will be made
19726 * again later. (This heuristic is not always a win.)
19727 * It is not necessary to compare scan[2] and match[2] since they
19728 * are always equal when the other bytes match, given that
19729 * the hash keys are equal and that HASH_BITS >= 8.
19730 */
19731 scanp += 2;
19732 matchp++;
19733
19734 /* We check for insufficient lookahead only every 8th comparison;
19735 * the 256th check will be made at strstart+258.
19736 */
19737 do {
19738 } while(zip_window[++scanp] == zip_window[++matchp] &&
19739 zip_window[++scanp] == zip_window[++matchp] &&
19740 zip_window[++scanp] == zip_window[++matchp] &&
19741 zip_window[++scanp] == zip_window[++matchp] &&
19742 zip_window[++scanp] == zip_window[++matchp] &&
19743 zip_window[++scanp] == zip_window[++matchp] &&
19744 zip_window[++scanp] == zip_window[++matchp] &&
19745 zip_window[++scanp] == zip_window[++matchp] &&
19746 scanp < strendp);
19747
19748 len = zip_MAX_MATCH - (strendp - scanp);
19749 scanp = strendp - zip_MAX_MATCH;
19750
19751 if(len > best_len) {
19752 zip_match_start = cur_match;
19753 best_len = len;
19754 if(zip_FULL_SEARCH) {
19755 if(len >= zip_MAX_MATCH) break;
19756 } else {
19757 if(len >= zip_nice_match) break;
19758 }
19759
19760 scan_end1 = zip_window[scanp + best_len-1];
19761 scan_end = zip_window[scanp + best_len];
19762 }
19763 } while((cur_match = zip_prev[cur_match & zip_WMASK]) > limit
19764 && --chain_length != 0);
19765
19766 return best_len;
19767 }
19768
19769 /* ==========================================================================
19770 * Fill the window when the lookahead becomes insufficient.
19771 * Updates strstart and lookahead, and sets eofile if end of input file.
19772 * IN assertion: lookahead < MIN_LOOKAHEAD && strstart + lookahead > 0
19773 * OUT assertions: at least one byte has been read, or eofile is set;
19774 * file reads are performed for at least two bytes (required for the
19775 * translate_eol option).
19776 */
19777 var zip_fill_window = function() {
19778 var n, m;
19779
19780 // Amount of free space at the end of the window.
19781 var more = zip_window_size - zip_lookahead - zip_strstart;
19782
19783 /* If the window is almost full and there is insufficient lookahead,
19784 * move the upper half to the lower one to make room in the upper half.
19785 */
19786 if(more == -1) {
19787 /* Very unlikely, but possible on 16 bit machine if strstart == 0
19788 * and lookahead == 1 (input done one byte at time)
19789 */
19790 more--;
19791 } else if(zip_strstart >= zip_WSIZE + zip_MAX_DIST) {
19792 /* By the IN assertion, the window is not empty so we can't confuse
19793 * more == 0 with more == 64K on a 16 bit machine.
19794 */
19795 // Assert(window_size == (ulg)2*WSIZE, "no sliding with BIG_MEM");
19796
19797 // System.arraycopy(window, WSIZE, window, 0, WSIZE);
19798 for(n = 0; n < zip_WSIZE; n++)
19799 zip_window[n] = zip_window[n + zip_WSIZE];
19800
19801 zip_match_start -= zip_WSIZE;
19802 zip_strstart -= zip_WSIZE; /* we now have strstart >= MAX_DIST: */
19803 zip_block_start -= zip_WSIZE;
19804
19805 for(n = 0; n < zip_HASH_SIZE; n++) {
19806 m = zip_head1(n);
19807 zip_head2(n, m >= zip_WSIZE ? m - zip_WSIZE : zip_NIL);
19808 }
19809 for(n = 0; n < zip_WSIZE; n++) {
19810 /* If n is not on any hash chain, prev[n] is garbage but
19811 * its value will never be used.
19812 */
19813 m = zip_prev[n];
19814 zip_prev[n] = (m >= zip_WSIZE ? m - zip_WSIZE : zip_NIL);
19815 }
19816 more += zip_WSIZE;
19817 }
19818 // At this point, more >= 2
19819 if(!zip_eofile) {
19820 n = zip_read_buff(zip_window, zip_strstart + zip_lookahead, more);
19821 if(n <= 0)
19822 zip_eofile = true;
19823 else
19824 zip_lookahead += n;
19825 }
19826 }
19827
19828 /* ==========================================================================
19829 * Processes a new input file and return its compressed length. This
19830 * function does not perform lazy evaluationof matches and inserts
19831 * new strings in the dictionary only for unmatched strings or for short
19832 * matches. It is used only for the fast compression options.
19833 */
19834 var zip_deflate_fast = function() {
19835 while(zip_lookahead != 0 && zip_qhead == null) {
19836 var flush; // set if current block must be flushed
19837
19838 /* Insert the string window[strstart .. strstart+2] in the
19839 * dictionary, and set hash_head to the head of the hash chain:
19840 */
19841 zip_INSERT_STRING();
19842
19843 /* Find the longest match, discarding those <= prev_length.
19844 * At this point we have always match_length < MIN_MATCH
19845 */
19846 if(zip_hash_head != zip_NIL &&
19847 zip_strstart - zip_hash_head <= zip_MAX_DIST) {
19848 /* To simplify the code, we prevent matches with the string
19849 * of window index 0 (in particular we have to avoid a match
19850 * of the string with itself at the start of the input file).
19851 */
19852 zip_match_length = zip_longest_match(zip_hash_head);
19853 /* longest_match() sets match_start */
19854 if(zip_match_length > zip_lookahead)
19855 zip_match_length = zip_lookahead;
19856 }
19857 if(zip_match_length >= zip_MIN_MATCH) {
19858 // check_match(strstart, match_start, match_length);
19859
19860 flush = zip_ct_tally(zip_strstart - zip_match_start,
19861 zip_match_length - zip_MIN_MATCH);
19862 zip_lookahead -= zip_match_length;
19863
19864 /* Insert new strings in the hash table only if the match length
19865 * is not too large. This saves time but degrades compression.
19866 */
19867 if(zip_match_length <= zip_max_lazy_match) {
19868 zip_match_length--; // string at strstart already in hash table
19869 do {
19870 zip_strstart++;
19871 zip_INSERT_STRING();
19872 /* strstart never exceeds WSIZE-MAX_MATCH, so there are
19873 * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH
19874 * these bytes are garbage, but it does not matter since
19875 * the next lookahead bytes will be emitted as literals.
19876 */
19877 } while(--zip_match_length != 0);
19878 zip_strstart++;
19879 } else {
19880 zip_strstart += zip_match_length;
19881 zip_match_length = 0;
19882 zip_ins_h = zip_window[zip_strstart] & 0xff;
19883 // UPDATE_HASH(ins_h, window[strstart + 1]);
19884 zip_ins_h = ((zip_ins_h<<zip_H_SHIFT) ^ (zip_window[zip_strstart + 1] & 0xff)) & zip_HASH_MASK;
19885
19886 //#if MIN_MATCH != 3
19887 // Call UPDATE_HASH() MIN_MATCH-3 more times
19888 //#endif
19889
19890 }
19891 } else {
19892 /* No match, output a literal byte */
19893 flush = zip_ct_tally(0, zip_window[zip_strstart] & 0xff);
19894 zip_lookahead--;
19895 zip_strstart++;
19896 }
19897 if(flush) {
19898 zip_flush_block(0);
19899 zip_block_start = zip_strstart;
19900 }
19901
19902 /* Make sure that we always have enough lookahead, except
19903 * at the end of the input file. We need MAX_MATCH bytes
19904 * for the next match, plus MIN_MATCH bytes to insert the
19905 * string following the next match.
19906 */
19907 while(zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile)
19908 zip_fill_window();
19909 }
19910 }
19911
19912 var zip_deflate_better = function() {
19913 /* Process the input block. */
19914 while(zip_lookahead != 0 && zip_qhead == null) {
19915 /* Insert the string window[strstart .. strstart+2] in the
19916 * dictionary, and set hash_head to the head of the hash chain:
19917 */
19918 zip_INSERT_STRING();
19919
19920 /* Find the longest match, discarding those <= prev_length.
19921 */
19922 zip_prev_length = zip_match_length;
19923 zip_prev_match = zip_match_start;
19924 zip_match_length = zip_MIN_MATCH - 1;
19925
19926 if(zip_hash_head != zip_NIL &&
19927 zip_prev_length < zip_max_lazy_match &&
19928 zip_strstart - zip_hash_head <= zip_MAX_DIST) {
19929 /* To simplify the code, we prevent matches with the string
19930 * of window index 0 (in particular we have to avoid a match
19931 * of the string with itself at the start of the input file).
19932 */
19933 zip_match_length = zip_longest_match(zip_hash_head);
19934 /* longest_match() sets match_start */
19935 if(zip_match_length > zip_lookahead)
19936 zip_match_length = zip_lookahead;
19937
19938 /* Ignore a length 3 match if it is too distant: */
19939 if(zip_match_length == zip_MIN_MATCH &&
19940 zip_strstart - zip_match_start > zip_TOO_FAR) {
19941 /* If prev_match is also MIN_MATCH, match_start is garbage
19942 * but we will ignore the current match anyway.
19943 */
19944 zip_match_length--;
19945 }
19946 }
19947 /* If there was a match at the previous step and the current
19948 * match is not better, output the previous match:
19949 */
19950 if(zip_prev_length >= zip_MIN_MATCH &&
19951 zip_match_length <= zip_prev_length) {
19952 var flush; // set if current block must be flushed
19953
19954 // check_match(strstart - 1, prev_match, prev_length);
19955 flush = zip_ct_tally(zip_strstart - 1 - zip_prev_match,
19956 zip_prev_length - zip_MIN_MATCH);
19957
19958 /* Insert in hash table all strings up to the end of the match.
19959 * strstart-1 and strstart are already inserted.
19960 */
19961 zip_lookahead -= zip_prev_length - 1;
19962 zip_prev_length -= 2;
19963 do {
19964 zip_strstart++;
19965 zip_INSERT_STRING();
19966 /* strstart never exceeds WSIZE-MAX_MATCH, so there are
19967 * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH
19968 * these bytes are garbage, but it does not matter since the
19969 * next lookahead bytes will always be emitted as literals.
19970 */
19971 } while(--zip_prev_length != 0);
19972 zip_match_available = 0;
19973 zip_match_length = zip_MIN_MATCH - 1;
19974 zip_strstart++;
19975 if(flush) {
19976 zip_flush_block(0);
19977 zip_block_start = zip_strstart;
19978 }
19979 } else if(zip_match_available != 0) {
19980 /* If there was no match at the previous position, output a
19981 * single literal. If there was a match but the current match
19982 * is longer, truncate the previous match to a single literal.
19983 */
19984 if(zip_ct_tally(0, zip_window[zip_strstart - 1] & 0xff)) {
19985 zip_flush_block(0);
19986 zip_block_start = zip_strstart;
19987 }
19988 zip_strstart++;
19989 zip_lookahead--;
19990 } else {
19991 /* There is no previous match to compare with, wait for
19992 * the next step to decide.
19993 */
19994 zip_match_available = 1;
19995 zip_strstart++;
19996 zip_lookahead--;
19997 }
19998
19999 /* Make sure that we always have enough lookahead, except
20000 * at the end of the input file. We need MAX_MATCH bytes
20001 * for the next match, plus MIN_MATCH bytes to insert the
20002 * string following the next match.
20003 */
20004 while(zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile)
20005 zip_fill_window();
20006 }
20007 }
20008
20009 var zip_init_deflate = function() {
20010 if(zip_eofile)
20011 return;
20012 zip_bi_buf = 0;
20013 zip_bi_valid = 0;
20014 zip_ct_init();
20015 zip_lm_init();
20016
20017 zip_qhead = null;
20018 zip_outcnt = 0;
20019 zip_outoff = 0;
20020
20021 if(zip_compr_level <= 3)
20022 {
20023 zip_prev_length = zip_MIN_MATCH - 1;
20024 zip_match_length = 0;
20025 }
20026 else
20027 {
20028 zip_match_length = zip_MIN_MATCH - 1;
20029 zip_match_available = 0;
20030 }
20031
20032 zip_complete = false;
20033 }
20034
20035 /* ==========================================================================
20036 * Same as above, but achieves better compression. We use a lazy
20037 * evaluation for matches: a match is finally adopted only if there is
20038 * no better match at the next window position.
20039 */
20040 var zip_deflate_internal = function(buff, off, buff_size) {
20041 var n;
20042
20043 if(!zip_initflag)
20044 {
20045 zip_init_deflate();
20046 zip_initflag = true;
20047 if(zip_lookahead == 0) { // empty
20048 zip_complete = true;
20049 return 0;
20050 }
20051 }
20052
20053 if((n = zip_qcopy(buff, off, buff_size)) == buff_size)
20054 return buff_size;
20055
20056 if(zip_complete)
20057 return n;
20058
20059 if(zip_compr_level <= 3) // optimized for speed
20060 zip_deflate_fast();
20061 else
20062 zip_deflate_better();
20063 if(zip_lookahead == 0) {
20064 if(zip_match_available != 0)
20065 zip_ct_tally(0, zip_window[zip_strstart - 1] & 0xff);
20066 zip_flush_block(1);
20067 zip_complete = true;
20068 }
20069 return n + zip_qcopy(buff, n + off, buff_size - n);
20070 }
20071
20072 var zip_qcopy = function(buff, off, buff_size) {
20073 var n, i, j;
20074
20075 n = 0;
20076 while(zip_qhead != null && n < buff_size)
20077 {
20078 i = buff_size - n;
20079 if(i > zip_qhead.len)
20080 i = zip_qhead.len;
20081 // System.arraycopy(qhead.ptr, qhead.off, buff, off + n, i);
20082 for(j = 0; j < i; j++)
20083 buff[off + n + j] = zip_qhead.ptr[zip_qhead.off + j];
20084
20085 zip_qhead.off += i;
20086 zip_qhead.len -= i;
20087 n += i;
20088 if(zip_qhead.len == 0) {
20089 var p;
20090 p = zip_qhead;
20091 zip_qhead = zip_qhead.next;
20092 zip_reuse_queue(p);
20093 }
20094 }
20095
20096 if(n == buff_size)
20097 return n;
20098
20099 if(zip_outoff < zip_outcnt) {
20100 i = buff_size - n;
20101 if(i > zip_outcnt - zip_outoff)
20102 i = zip_outcnt - zip_outoff;
20103 // System.arraycopy(outbuf, outoff, buff, off + n, i);
20104 for(j = 0; j < i; j++)
20105 buff[off + n + j] = zip_outbuf[zip_outoff + j];
20106 zip_outoff += i;
20107 n += i;
20108 if(zip_outcnt == zip_outoff)
20109 zip_outcnt = zip_outoff = 0;
20110 }
20111 return n;
20112 }
20113
20114 /* ==========================================================================
20115 * Allocate the match buffer, initialize the various tables and save the
20116 * location of the internal file attribute (ascii/binary) and method
20117 * (DEFLATE/STORE).
20118 */
20119 var zip_ct_init = function() {
20120 var n; // iterates over tree elements
20121 var bits; // bit counter
20122 var length; // length value
20123 var code; // code value
20124 var dist; // distance index
20125
20126 if(zip_static_dtree[0].dl != 0) return; // ct_init already called
20127
20128 zip_l_desc.dyn_tree = zip_dyn_ltree;
20129 zip_l_desc.static_tree = zip_static_ltree;
20130 zip_l_desc.extra_bits = zip_extra_lbits;
20131 zip_l_desc.extra_base = zip_LITERALS + 1;
20132 zip_l_desc.elems = zip_L_CODES;
20133 zip_l_desc.max_length = zip_MAX_BITS;
20134 zip_l_desc.max_code = 0;
20135
20136 zip_d_desc.dyn_tree = zip_dyn_dtree;
20137 zip_d_desc.static_tree = zip_static_dtree;
20138 zip_d_desc.extra_bits = zip_extra_dbits;
20139 zip_d_desc.extra_base = 0;
20140 zip_d_desc.elems = zip_D_CODES;
20141 zip_d_desc.max_length = zip_MAX_BITS;
20142 zip_d_desc.max_code = 0;
20143
20144 zip_bl_desc.dyn_tree = zip_bl_tree;
20145 zip_bl_desc.static_tree = null;
20146 zip_bl_desc.extra_bits = zip_extra_blbits;
20147 zip_bl_desc.extra_base = 0;
20148 zip_bl_desc.elems = zip_BL_CODES;
20149 zip_bl_desc.max_length = zip_MAX_BL_BITS;
20150 zip_bl_desc.max_code = 0;
20151
20152 // Initialize the mapping length (0..255) -> length code (0..28)
20153 length = 0;
20154 for(code = 0; code < zip_LENGTH_CODES-1; code++) {
20155 zip_base_length[code] = length;
20156 for(n = 0; n < (1<<zip_extra_lbits[code]); n++)
20157 zip_length_code[length++] = code;
20158 }
20159 // Assert (length == 256, "ct_init: length != 256");
20160
20161 /* Note that the length 255 (match length 258) can be represented
20162 * in two different ways: code 284 + 5 bits or code 285, so we
20163 * overwrite length_code[255] to use the best encoding:
20164 */
20165 zip_length_code[length-1] = code;
20166
20167 /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
20168 dist = 0;
20169 for(code = 0 ; code < 16; code++) {
20170 zip_base_dist[code] = dist;
20171 for(n = 0; n < (1<<zip_extra_dbits[code]); n++) {
20172 zip_dist_code[dist++] = code;
20173 }
20174 }
20175 // Assert (dist == 256, "ct_init: dist != 256");
20176 dist >>= 7; // from now on, all distances are divided by 128
20177 for( ; code < zip_D_CODES; code++) {
20178 zip_base_dist[code] = dist << 7;
20179 for(n = 0; n < (1<<(zip_extra_dbits[code]-7)); n++)
20180 zip_dist_code[256 + dist++] = code;
20181 }
20182 // Assert (dist == 256, "ct_init: 256+dist != 512");
20183
20184 // Construct the codes of the static literal tree
20185 for(bits = 0; bits <= zip_MAX_BITS; bits++)
20186 zip_bl_count[bits] = 0;
20187 n = 0;
20188 while(n <= 143) { zip_static_ltree[n++].dl = 8; zip_bl_count[8]++; }
20189 while(n <= 255) { zip_static_ltree[n++].dl = 9; zip_bl_count[9]++; }
20190 while(n <= 279) { zip_static_ltree[n++].dl = 7; zip_bl_count[7]++; }
20191 while(n <= 287) { zip_static_ltree[n++].dl = 8; zip_bl_count[8]++; }
20192 /* Codes 286 and 287 do not exist, but we must include them in the
20193 * tree construction to get a canonical Huffman tree (longest code
20194 * all ones)
20195 */
20196 zip_gen_codes(zip_static_ltree, zip_L_CODES + 1);
20197
20198 /* The static distance tree is trivial: */
20199 for(n = 0; n < zip_D_CODES; n++) {
20200 zip_static_dtree[n].dl = 5;
20201 zip_static_dtree[n].fc = zip_bi_reverse(n, 5);
20202 }
20203
20204 // Initialize the first block of the first file:
20205 zip_init_block();
20206 }
20207
20208 /* ==========================================================================
20209 * Initialize a new block.
20210 */
20211 var zip_init_block = function() {
20212 var n; // iterates over tree elements
20213
20214 // Initialize the trees.
20215 for(n = 0; n < zip_L_CODES; n++) zip_dyn_ltree[n].fc = 0;
20216 for(n = 0; n < zip_D_CODES; n++) zip_dyn_dtree[n].fc = 0;
20217 for(n = 0; n < zip_BL_CODES; n++) zip_bl_tree[n].fc = 0;
20218
20219 zip_dyn_ltree[zip_END_BLOCK].fc = 1;
20220 zip_opt_len = zip_static_len = 0;
20221 zip_last_lit = zip_last_dist = zip_last_flags = 0;
20222 zip_flags = 0;
20223 zip_flag_bit = 1;
20224 }
20225
20226 /* ==========================================================================
20227 * Restore the heap property by moving down the tree starting at node k,
20228 * exchanging a node with the smallest of its two sons if necessary, stopping
20229 * when the heap property is re-established (each father smaller than its
20230 * two sons).
20231 */
20232 var zip_pqdownheap = function(
20233 tree, // the tree to restore
20234 k) { // node to move down
20235 var v = zip_heap[k];
20236 var j = k << 1; // left son of k
20237
20238 while(j <= zip_heap_len) {
20239 // Set j to the smallest of the two sons:
20240 if(j < zip_heap_len &&
20241 zip_SMALLER(tree, zip_heap[j + 1], zip_heap[j]))
20242 j++;
20243
20244 // Exit if v is smaller than both sons
20245 if(zip_SMALLER(tree, v, zip_heap[j]))
20246 break;
20247
20248 // Exchange v with the smallest son
20249 zip_heap[k] = zip_heap[j];
20250 k = j;
20251
20252 // And continue down the tree, setting j to the left son of k
20253 j <<= 1;
20254 }
20255 zip_heap[k] = v;
20256 }
20257
20258 /* ==========================================================================
20259 * Compute the optimal bit lengths for a tree and update the total bit length
20260 * for the current block.
20261 * IN assertion: the fields freq and dad are set, heap[heap_max] and
20262 * above are the tree nodes sorted by increasing frequency.
20263 * OUT assertions: the field len is set to the optimal bit length, the
20264 * array bl_count contains the frequencies for each bit length.
20265 * The length opt_len is updated; static_len is also updated if stree is
20266 * not null.
20267 */
20268 var zip_gen_bitlen = function(desc) { // the tree descriptor
20269 var tree = desc.dyn_tree;
20270 var extra = desc.extra_bits;
20271 var base = desc.extra_base;
20272 var max_code = desc.max_code;
20273 var max_length = desc.max_length;
20274 var stree = desc.static_tree;
20275 var h; // heap index
20276 var n, m; // iterate over the tree elements
20277 var bits; // bit length
20278 var xbits; // extra bits
20279 var f; // frequency
20280 var overflow = 0; // number of elements with bit length too large
20281
20282 for(bits = 0; bits <= zip_MAX_BITS; bits++)
20283 zip_bl_count[bits] = 0;
20284
20285 /* In a first pass, compute the optimal bit lengths (which may
20286 * overflow in the case of the bit length tree).
20287 */
20288 tree[zip_heap[zip_heap_max]].dl = 0; // root of the heap
20289
20290 for(h = zip_heap_max + 1; h < zip_HEAP_SIZE; h++) {
20291 n = zip_heap[h];
20292 bits = tree[tree[n].dl].dl + 1;
20293 if(bits > max_length) {
20294 bits = max_length;
20295 overflow++;
20296 }
20297 tree[n].dl = bits;
20298 // We overwrite tree[n].dl which is no longer needed
20299
20300 if(n > max_code)
20301 continue; // not a leaf node
20302
20303 zip_bl_count[bits]++;
20304 xbits = 0;
20305 if(n >= base)
20306 xbits = extra[n - base];
20307 f = tree[n].fc;
20308 zip_opt_len += f * (bits + xbits);
20309 if(stree != null)
20310 zip_static_len += f * (stree[n].dl + xbits);
20311 }
20312 if(overflow == 0)
20313 return;
20314
20315 // This happens for example on obj2 and pic of the Calgary corpus
20316
20317 // Find the first bit length which could increase:
20318 do {
20319 bits = max_length - 1;
20320 while(zip_bl_count[bits] == 0)
20321 bits--;
20322 zip_bl_count[bits]--; // move one leaf down the tree
20323 zip_bl_count[bits + 1] += 2; // move one overflow item as its brother
20324 zip_bl_count[max_length]--;
20325 /* The brother of the overflow item also moves one step up,
20326 * but this does not affect bl_count[max_length]
20327 */
20328 overflow -= 2;
20329 } while(overflow > 0);
20330
20331 /* Now recompute all bit lengths, scanning in increasing frequency.
20332 * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
20333 * lengths instead of fixing only the wrong ones. This idea is taken
20334 * from 'ar' written by Haruhiko Okumura.)
20335 */
20336 for(bits = max_length; bits != 0; bits--) {
20337 n = zip_bl_count[bits];
20338 while(n != 0) {
20339 m = zip_heap[--h];
20340 if(m > max_code)
20341 continue;
20342 if(tree[m].dl != bits) {
20343 zip_opt_len += (bits - tree[m].dl) * tree[m].fc;
20344 tree[m].fc = bits;
20345 }
20346 n--;
20347 }
20348 }
20349 }
20350
20351 /* ==========================================================================
20352 * Generate the codes for a given tree and bit counts (which need not be
20353 * optimal).
20354 * IN assertion: the array bl_count contains the bit length statistics for
20355 * the given tree and the field len is set for all tree elements.
20356 * OUT assertion: the field code is set for all tree elements of non
20357 * zero code length.
20358 */
20359 var zip_gen_codes = function(tree, // the tree to decorate
20360 max_code) { // largest code with non zero frequency
20361 var next_code = new Array(zip_MAX_BITS+1); // next code value for each bit length
20362 var code = 0; // running code value
20363 var bits; // bit index
20364 var n; // code index
20365
20366 /* The distribution counts are first used to generate the code values
20367 * without bit reversal.
20368 */
20369 for(bits = 1; bits <= zip_MAX_BITS; bits++) {
20370 code = ((code + zip_bl_count[bits-1]) << 1);
20371 next_code[bits] = code;
20372 }
20373
20374 /* Check that the bit counts in bl_count are consistent. The last code
20375 * must be all ones.
20376 */
20377 // Assert (code + encoder->bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
20378 // "inconsistent bit counts");
20379 // Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
20380
20381 for(n = 0; n <= max_code; n++) {
20382 var len = tree[n].dl;
20383 if(len == 0)
20384 continue;
20385 // Now reverse the bits
20386 tree[n].fc = zip_bi_reverse(next_code[len]++, len);
20387
20388 // Tracec(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
20389 // n, (isgraph(n) ? n : ' '), len, tree[n].fc, next_code[len]-1));
20390 }
20391 }
20392
20393 /* ==========================================================================
20394 * Construct one Huffman tree and assigns the code bit strings and lengths.
20395 * Update the total bit length for the current block.
20396 * IN assertion: the field freq is set for all tree elements.
20397 * OUT assertions: the fields len and code are set to the optimal bit length
20398 * and corresponding code. The length opt_len is updated; static_len is
20399 * also updated if stree is not null. The field max_code is set.
20400 */
20401 var zip_build_tree = function(desc) { // the tree descriptor
20402 var tree = desc.dyn_tree;
20403 var stree = desc.static_tree;
20404 var elems = desc.elems;
20405 var n, m; // iterate over heap elements
20406 var max_code = -1; // largest code with non zero frequency
20407 var node = elems; // next internal node of the tree
20408
20409 /* Construct the initial heap, with least frequent element in
20410 * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
20411 * heap[0] is not used.
20412 */
20413 zip_heap_len = 0;
20414 zip_heap_max = zip_HEAP_SIZE;
20415
20416 for(n = 0; n < elems; n++) {
20417 if(tree[n].fc != 0) {
20418 zip_heap[++zip_heap_len] = max_code = n;
20419 zip_depth[n] = 0;
20420 } else
20421 tree[n].dl = 0;
20422 }
20423
20424 /* The pkzip format requires that at least one distance code exists,
20425 * and that at least one bit should be sent even if there is only one
20426 * possible code. So to avoid special checks later on we force at least
20427 * two codes of non zero frequency.
20428 */
20429 while(zip_heap_len < 2) {
20430 var xnew = zip_heap[++zip_heap_len] = (max_code < 2 ? ++max_code : 0);
20431 tree[xnew].fc = 1;
20432 zip_depth[xnew] = 0;
20433 zip_opt_len--;
20434 if(stree != null)
20435 zip_static_len -= stree[xnew].dl;
20436 // new is 0 or 1 so it does not have extra bits
20437 }
20438 desc.max_code = max_code;
20439
20440 /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
20441 * establish sub-heaps of increasing lengths:
20442 */
20443 for(n = zip_heap_len >> 1; n >= 1; n--)
20444 zip_pqdownheap(tree, n);
20445
20446 /* Construct the Huffman tree by repeatedly combining the least two
20447 * frequent nodes.
20448 */
20449 do {
20450 n = zip_heap[zip_SMALLEST];
20451 zip_heap[zip_SMALLEST] = zip_heap[zip_heap_len--];
20452 zip_pqdownheap(tree, zip_SMALLEST);
20453
20454 m = zip_heap[zip_SMALLEST]; // m = node of next least frequency
20455
20456 // keep the nodes sorted by frequency
20457 zip_heap[--zip_heap_max] = n;
20458 zip_heap[--zip_heap_max] = m;
20459
20460 // Create a new node father of n and m
20461 tree[node].fc = tree[n].fc + tree[m].fc;
20462 // depth[node] = (char)(MAX(depth[n], depth[m]) + 1);
20463 if(zip_depth[n] > zip_depth[m] + 1)
20464 zip_depth[node] = zip_depth[n];
20465 else
20466 zip_depth[node] = zip_depth[m] + 1;
20467 tree[n].dl = tree[m].dl = node;
20468
20469 // and insert the new node in the heap
20470 zip_heap[zip_SMALLEST] = node++;
20471 zip_pqdownheap(tree, zip_SMALLEST);
20472
20473 } while(zip_heap_len >= 2);
20474
20475 zip_heap[--zip_heap_max] = zip_heap[zip_SMALLEST];
20476
20477 /* At this point, the fields freq and dad are set. We can now
20478 * generate the bit lengths.
20479 */
20480 zip_gen_bitlen(desc);
20481
20482 // The field len is now set, we can generate the bit codes
20483 zip_gen_codes(tree, max_code);
20484 }
20485
20486 /* ==========================================================================
20487 * Scan a literal or distance tree to determine the frequencies of the codes
20488 * in the bit length tree. Updates opt_len to take into account the repeat
20489 * counts. (The contribution of the bit length codes will be added later
20490 * during the construction of bl_tree.)
20491 */
20492 var zip_scan_tree = function(tree,// the tree to be scanned
20493 max_code) { // and its largest code of non zero frequency
20494 var n; // iterates over all tree elements
20495 var prevlen = -1; // last emitted length
20496 var curlen; // length of current code
20497 var nextlen = tree[0].dl; // length of next code
20498 var count = 0; // repeat count of the current code
20499 var max_count = 7; // max repeat count
20500 var min_count = 4; // min repeat count
20501
20502 if(nextlen == 0) {
20503 max_count = 138;
20504 min_count = 3;
20505 }
20506 tree[max_code + 1].dl = 0xffff; // guard
20507
20508 for(n = 0; n <= max_code; n++) {
20509 curlen = nextlen;
20510 nextlen = tree[n + 1].dl;
20511 if(++count < max_count && curlen == nextlen)
20512 continue;
20513 else if(count < min_count)
20514 zip_bl_tree[curlen].fc += count;
20515 else if(curlen != 0) {
20516 if(curlen != prevlen)
20517 zip_bl_tree[curlen].fc++;
20518 zip_bl_tree[zip_REP_3_6].fc++;
20519 } else if(count <= 10)
20520 zip_bl_tree[zip_REPZ_3_10].fc++;
20521 else
20522 zip_bl_tree[zip_REPZ_11_138].fc++;
20523 count = 0; prevlen = curlen;
20524 if(nextlen == 0) {
20525 max_count = 138;
20526 min_count = 3;
20527 } else if(curlen == nextlen) {
20528 max_count = 6;
20529 min_count = 3;
20530 } else {
20531 max_count = 7;
20532 min_count = 4;
20533 }
20534 }
20535 }
20536
20537 /* ==========================================================================
20538 * Send a literal or distance tree in compressed form, using the codes in
20539 * bl_tree.
20540 */
20541 var zip_send_tree = function(tree, // the tree to be scanned
20542 max_code) { // and its largest code of non zero frequency
20543 var n; // iterates over all tree elements
20544 var prevlen = -1; // last emitted length
20545 var curlen; // length of current code
20546 var nextlen = tree[0].dl; // length of next code
20547 var count = 0; // repeat count of the current code
20548 var max_count = 7; // max repeat count
20549 var min_count = 4; // min repeat count
20550
20551 /* tree[max_code+1].dl = -1; */ /* guard already set */
20552 if(nextlen == 0) {
20553 max_count = 138;
20554 min_count = 3;
20555 }
20556
20557 for(n = 0; n <= max_code; n++) {
20558 curlen = nextlen;
20559 nextlen = tree[n+1].dl;
20560 if(++count < max_count && curlen == nextlen) {
20561 continue;
20562 } else if(count < min_count) {
20563 do { zip_SEND_CODE(curlen, zip_bl_tree); } while(--count != 0);
20564 } else if(curlen != 0) {
20565 if(curlen != prevlen) {
20566 zip_SEND_CODE(curlen, zip_bl_tree);
20567 count--;
20568 }
20569 // Assert(count >= 3 && count <= 6, " 3_6?");
20570 zip_SEND_CODE(zip_REP_3_6, zip_bl_tree);
20571 zip_send_bits(count - 3, 2);
20572 } else if(count <= 10) {
20573 zip_SEND_CODE(zip_REPZ_3_10, zip_bl_tree);
20574 zip_send_bits(count-3, 3);
20575 } else {
20576 zip_SEND_CODE(zip_REPZ_11_138, zip_bl_tree);
20577 zip_send_bits(count-11, 7);
20578 }
20579 count = 0;
20580 prevlen = curlen;
20581 if(nextlen == 0) {
20582 max_count = 138;
20583 min_count = 3;
20584 } else if(curlen == nextlen) {
20585 max_count = 6;
20586 min_count = 3;
20587 } else {
20588 max_count = 7;
20589 min_count = 4;
20590 }
20591 }
20592 }
20593
20594 /* ==========================================================================
20595 * Construct the Huffman tree for the bit lengths and return the index in
20596 * bl_order of the last bit length code to send.
20597 */
20598 var zip_build_bl_tree = function() {
20599 var max_blindex; // index of last bit length code of non zero freq
20600
20601 // Determine the bit length frequencies for literal and distance trees
20602 zip_scan_tree(zip_dyn_ltree, zip_l_desc.max_code);
20603 zip_scan_tree(zip_dyn_dtree, zip_d_desc.max_code);
20604
20605 // Build the bit length tree:
20606 zip_build_tree(zip_bl_desc);
20607 /* opt_len now includes the length of the tree representations, except
20608 * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
20609 */
20610
20611 /* Determine the number of bit length codes to send. The pkzip format
20612 * requires that at least 4 bit length codes be sent. (appnote.txt says
20613 * 3 but the actual value used is 4.)
20614 */
20615 for(max_blindex = zip_BL_CODES-1; max_blindex >= 3; max_blindex--) {
20616 if(zip_bl_tree[zip_bl_order[max_blindex]].dl != 0) break;
20617 }
20618 /* Update opt_len to include the bit length tree and counts */
20619 zip_opt_len += 3*(max_blindex+1) + 5+5+4;
20620 // Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
20621 // encoder->opt_len, encoder->static_len));
20622
20623 return max_blindex;
20624 }
20625
20626 /* ==========================================================================
20627 * Send the header for a block using dynamic Huffman trees: the counts, the
20628 * lengths of the bit length codes, the literal tree and the distance tree.
20629 * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
20630 */
20631 var zip_send_all_trees = function(lcodes, dcodes, blcodes) { // number of codes for each tree
20632 var rank; // index in bl_order
20633
20634 // Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
20635 // Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
20636 // "too many codes");
20637 // Tracev((stderr, "\nbl counts: "));
20638 zip_send_bits(lcodes-257, 5); // not +255 as stated in appnote.txt
20639 zip_send_bits(dcodes-1, 5);
20640 zip_send_bits(blcodes-4, 4); // not -3 as stated in appnote.txt
20641 for(rank = 0; rank < blcodes; rank++) {
20642 // Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
20643 zip_send_bits(zip_bl_tree[zip_bl_order[rank]].dl, 3);
20644 }
20645
20646 // send the literal tree
20647 zip_send_tree(zip_dyn_ltree,lcodes-1);
20648
20649 // send the distance tree
20650 zip_send_tree(zip_dyn_dtree,dcodes-1);
20651 }
20652
20653 /* ==========================================================================
20654 * Determine the best encoding for the current block: dynamic trees, static
20655 * trees or store, and output the encoded block to the zip file.
20656 */
20657 var zip_flush_block = function(eof) { // true if this is the last block for a file
20658 var opt_lenb, static_lenb; // opt_len and static_len in bytes
20659 var max_blindex; // index of last bit length code of non zero freq
20660 var stored_len; // length of input block
20661
20662 stored_len = zip_strstart - zip_block_start;
20663 zip_flag_buf[zip_last_flags] = zip_flags; // Save the flags for the last 8 items
20664
20665 // Construct the literal and distance trees
20666 zip_build_tree(zip_l_desc);
20667 // Tracev((stderr, "\nlit data: dyn %ld, stat %ld",
20668 // encoder->opt_len, encoder->static_len));
20669
20670 zip_build_tree(zip_d_desc);
20671 // Tracev((stderr, "\ndist data: dyn %ld, stat %ld",
20672 // encoder->opt_len, encoder->static_len));
20673 /* At this point, opt_len and static_len are the total bit lengths of
20674 * the compressed block data, excluding the tree representations.
20675 */
20676
20677 /* Build the bit length tree for the above two trees, and get the index
20678 * in bl_order of the last bit length code to send.
20679 */
20680 max_blindex = zip_build_bl_tree();
20681
20682 // Determine the best encoding. Compute first the block length in bytes
20683 opt_lenb = (zip_opt_len +3+7)>>3;
20684 static_lenb = (zip_static_len+3+7)>>3;
20685
20686 // Trace((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ",
20687 // opt_lenb, encoder->opt_len,
20688 // static_lenb, encoder->static_len, stored_len,
20689 // encoder->last_lit, encoder->last_dist));
20690
20691 if(static_lenb <= opt_lenb)
20692 opt_lenb = static_lenb;
20693 if(stored_len + 4 <= opt_lenb // 4: two words for the lengths
20694 && zip_block_start >= 0) {
20695 var i;
20696
20697 /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
20698 * Otherwise we can't have processed more than WSIZE input bytes since
20699 * the last block flush, because compression would have been
20700 * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
20701 * transform a block into a stored block.
20702 */
20703 zip_send_bits((zip_STORED_BLOCK<<1)+eof, 3); /* send block type */
20704 zip_bi_windup(); /* align on byte boundary */
20705 zip_put_short(stored_len);
20706 zip_put_short(~stored_len);
20707
20708 // copy block
20709 /*
20710 p = &window[block_start];
20711 for(i = 0; i < stored_len; i++)
20712 put_byte(p[i]);
20713 */
20714 for(i = 0; i < stored_len; i++)
20715 zip_put_byte(zip_window[zip_block_start + i]);
20716
20717 } else if(static_lenb == opt_lenb) {
20718 zip_send_bits((zip_STATIC_TREES<<1)+eof, 3);
20719 zip_compress_block(zip_static_ltree, zip_static_dtree);
20720 } else {
20721 zip_send_bits((zip_DYN_TREES<<1)+eof, 3);
20722 zip_send_all_trees(zip_l_desc.max_code+1,
20723 zip_d_desc.max_code+1,
20724 max_blindex+1);
20725 zip_compress_block(zip_dyn_ltree, zip_dyn_dtree);
20726 }
20727
20728 zip_init_block();
20729
20730 if(eof != 0)
20731 zip_bi_windup();
20732 }
20733
20734 /* ==========================================================================
20735 * Save the match info and tally the frequency counts. Return true if
20736 * the current block must be flushed.
20737 */
20738 var zip_ct_tally = function(
20739 dist, // distance of matched string
20740 lc) { // match length-MIN_MATCH or unmatched char (if dist==0)
20741 zip_l_buf[zip_last_lit++] = lc;
20742 if(dist == 0) {
20743 // lc is the unmatched char
20744 zip_dyn_ltree[lc].fc++;
20745 } else {
20746 // Here, lc is the match length - MIN_MATCH
20747 dist--; // dist = match distance - 1
20748 // Assert((ush)dist < (ush)MAX_DIST &&
20749 // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
20750 // (ush)D_CODE(dist) < (ush)D_CODES, "ct_tally: bad match");
20751
20752 zip_dyn_ltree[zip_length_code[lc]+zip_LITERALS+1].fc++;
20753 zip_dyn_dtree[zip_D_CODE(dist)].fc++;
20754
20755 zip_d_buf[zip_last_dist++] = dist;
20756 zip_flags |= zip_flag_bit;
20757 }
20758 zip_flag_bit <<= 1;
20759
20760 // Output the flags if they fill a byte
20761 if((zip_last_lit & 7) == 0) {
20762 zip_flag_buf[zip_last_flags++] = zip_flags;
20763 zip_flags = 0;
20764 zip_flag_bit = 1;
20765 }
20766 // Try to guess if it is profitable to stop the current block here
20767 if(zip_compr_level > 2 && (zip_last_lit & 0xfff) == 0) {
20768 // Compute an upper bound for the compressed length
20769 var out_length = zip_last_lit * 8;
20770 var in_length = zip_strstart - zip_block_start;
20771 var dcode;
20772
20773 for(dcode = 0; dcode < zip_D_CODES; dcode++) {
20774 out_length += zip_dyn_dtree[dcode].fc * (5 + zip_extra_dbits[dcode]);
20775 }
20776 out_length >>= 3;
20777 // Trace((stderr,"\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ",
20778 // encoder->last_lit, encoder->last_dist, in_length, out_length,
20779 // 100L - out_length*100L/in_length));
20780 if(zip_last_dist < parseInt(zip_last_lit/2) &&
20781 out_length < parseInt(in_length/2))
20782 return true;
20783 }
20784 return (zip_last_lit == zip_LIT_BUFSIZE-1 ||
20785 zip_last_dist == zip_DIST_BUFSIZE);
20786 /* We avoid equality with LIT_BUFSIZE because of wraparound at 64K
20787 * on 16 bit machines and because stored blocks are restricted to
20788 * 64K-1 bytes.
20789 */
20790 }
20791
20792 /* ==========================================================================
20793 * Send the block data compressed using the given Huffman trees
20794 */
20795 var zip_compress_block = function(
20796 ltree, // literal tree
20797 dtree) { // distance tree
20798 var dist; // distance of matched string
20799 var lc; // match length or unmatched char (if dist == 0)
20800 var lx = 0; // running index in l_buf
20801 var dx = 0; // running index in d_buf
20802 var fx = 0; // running index in flag_buf
20803 var flag = 0; // current flags
20804 var code; // the code to send
20805 var extra; // number of extra bits to send
20806
20807 if(zip_last_lit != 0) do {
20808 if((lx & 7) == 0)
20809 flag = zip_flag_buf[fx++];
20810 lc = zip_l_buf[lx++] & 0xff;
20811 if((flag & 1) == 0) {
20812 zip_SEND_CODE(lc, ltree); /* send a literal byte */
20813 // Tracecv(isgraph(lc), (stderr," '%c' ", lc));
20814 } else {
20815 // Here, lc is the match length - MIN_MATCH
20816 code = zip_length_code[lc];
20817 zip_SEND_CODE(code+zip_LITERALS+1, ltree); // send the length code
20818 extra = zip_extra_lbits[code];
20819 if(extra != 0) {
20820 lc -= zip_base_length[code];
20821 zip_send_bits(lc, extra); // send the extra length bits
20822 }
20823 dist = zip_d_buf[dx++];
20824 // Here, dist is the match distance - 1
20825 code = zip_D_CODE(dist);
20826 // Assert (code < D_CODES, "bad d_code");
20827
20828 zip_SEND_CODE(code, dtree); // send the distance code
20829 extra = zip_extra_dbits[code];
20830 if(extra != 0) {
20831 dist -= zip_base_dist[code];
20832 zip_send_bits(dist, extra); // send the extra distance bits
20833 }
20834 } // literal or match pair ?
20835 flag >>= 1;
20836 } while(lx < zip_last_lit);
20837
20838 zip_SEND_CODE(zip_END_BLOCK, ltree);
20839 }
20840
20841 /* ==========================================================================
20842 * Send a value on a given number of bits.
20843 * IN assertion: length <= 16 and value fits in length bits.
20844 */
20845 var zip_Buf_size = 16; // bit size of bi_buf
20846 var zip_send_bits = function(
20847 value, // value to send
20848 length) { // number of bits
20849 /* If not enough room in bi_buf, use (valid) bits from bi_buf and
20850 * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
20851 * unused bits in value.
20852 */
20853 if(zip_bi_valid > zip_Buf_size - length) {
20854 zip_bi_buf |= (value << zip_bi_valid);
20855 zip_put_short(zip_bi_buf);
20856 zip_bi_buf = (value >> (zip_Buf_size - zip_bi_valid));
20857 zip_bi_valid += length - zip_Buf_size;
20858 } else {
20859 zip_bi_buf |= value << zip_bi_valid;
20860 zip_bi_valid += length;
20861 }
20862 }
20863
20864 /* ==========================================================================
20865 * Reverse the first len bits of a code, using straightforward code (a faster
20866 * method would use a table)
20867 * IN assertion: 1 <= len <= 15
20868 */
20869 var zip_bi_reverse = function(
20870 code, // the value to invert
20871 len) { // its bit length
20872 var res = 0;
20873 do {
20874 res |= code & 1;
20875 code >>= 1;
20876 res <<= 1;
20877 } while(--len > 0);
20878 return res >> 1;
20879 }
20880
20881 /* ==========================================================================
20882 * Write out any remaining bits in an incomplete byte.
20883 */
20884 var zip_bi_windup = function() {
20885 if(zip_bi_valid > 8) {
20886 zip_put_short(zip_bi_buf);
20887 } else if(zip_bi_valid > 0) {
20888 zip_put_byte(zip_bi_buf);
20889 }
20890 zip_bi_buf = 0;
20891 zip_bi_valid = 0;
20892 }
20893
20894 var zip_qoutbuf = function() {
20895 if(zip_outcnt != 0) {
20896 var q, i;
20897 q = zip_new_queue();
20898 if(zip_qhead == null)
20899 zip_qhead = zip_qtail = q;
20900 else
20901 zip_qtail = zip_qtail.next = q;
20902 q.len = zip_outcnt - zip_outoff;
20903 // System.arraycopy(zip_outbuf, zip_outoff, q.ptr, 0, q.len);
20904 for(i = 0; i < q.len; i++)
20905 q.ptr[i] = zip_outbuf[zip_outoff + i];
20906 zip_outcnt = zip_outoff = 0;
20907 }
20908 }
20909
20910 var zip_deflate = function(str, level) {
20911 var i, j;
20912
20913 zip_deflate_data = str;
20914 zip_deflate_pos = 0;
20915 if(typeof level == "undefined")
20916 level = zip_DEFAULT_LEVEL;
20917 zip_deflate_start(level);
20918
20919 var buff = new Array(1024);
20920 var aout = [];
20921 while((i = zip_deflate_internal(buff, 0, buff.length)) > 0) {
20922 var cbuf = new Array(i);
20923 for(j = 0; j < i; j++){
20924 cbuf[j] = String.fromCharCode(buff[j]);
20925 }
20926 aout[aout.length] = cbuf.join("");
20927 }
20928 zip_deflate_data = null; // G.C.
20929 return aout.join("");
20930 }
20931
20932 //
20933 // end of the script of Masanao Izumo.
20934 //
20935
20936 // we add the compression method for JSZip
20937 if(!JSZip.compressions["DEFLATE"]) {
20938 JSZip.compressions["DEFLATE"] = {
20939 magic : "\x08\x00",
20940 compress : zip_deflate
20941 }
20942 } else {
20943 JSZip.compressions["DEFLATE"].compress = zip_deflate;
20944 }
20945
20946 })();
20947
20948 // enforcing Stuk's coding style
20949 // vim: set shiftwidth=3 softtabstop=3:
20950 /*
20951 * Port of a script by Masanao Izumo.
20952 *
20953 * Only changes : wrap all the variables in a function and add the
20954 * main function to JSZip (DEFLATE compression method).
20955 * Everything else was written by M. Izumo.
20956 *
20957 * Original code can be found here: http://www.onicos.com/staff/iz/amuse/javascript/expert/inflate.txt
20958 */
20959
20960 if(!JSZip) {
20961 throw "JSZip not defined";
20962 }
20963
20964 /*
20965 * Original:
20966 * http://www.onicos.com/staff/iz/amuse/javascript/expert/inflate.txt
20967 */
20968
20969 (function(){
20970 // the original implementation leaks a global variable.
20971 // Defining the variable here doesn't break anything.
20972 var zip_fixed_bd;
20973
20974 /* Copyright (C) 1999 Masanao Izumo <iz@onicos.co.jp>
20975 * Version: 1.0.0.1
20976 * LastModified: Dec 25 1999
20977 */
20978
20979 /* Interface:
20980 * data = zip_inflate(src);
20981 */
20982
20983 /* constant parameters */
20984 var zip_WSIZE = 32768; // Sliding Window size
20985 var zip_STORED_BLOCK = 0;
20986 var zip_STATIC_TREES = 1;
20987 var zip_DYN_TREES = 2;
20988
20989 /* for inflate */
20990 var zip_lbits = 9; // bits in base literal/length lookup table
20991 var zip_dbits = 6; // bits in base distance lookup table
20992 var zip_INBUFSIZ = 32768; // Input buffer size
20993 var zip_INBUF_EXTRA = 64; // Extra buffer
20994
20995 /* variables (inflate) */
20996 var zip_slide;
20997 var zip_wp; // current position in slide
20998 var zip_fixed_tl = null; // inflate static
20999 var zip_fixed_td; // inflate static
21000 var zip_fixed_bl, fixed_bd; // inflate static
21001 var zip_bit_buf; // bit buffer
21002 var zip_bit_len; // bits in bit buffer
21003 var zip_method;
21004 var zip_eof;
21005 var zip_copy_leng;
21006 var zip_copy_dist;
21007 var zip_tl, zip_td; // literal/length and distance decoder tables
21008 var zip_bl, zip_bd; // number of bits decoded by tl and td
21009
21010 var zip_inflate_data;
21011 var zip_inflate_pos;
21012
21013
21014 /* constant tables (inflate) */
21015 var zip_MASK_BITS = new Array(
21016 0x0000,
21017 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
21018 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff);
21019 // Tables for deflate from PKZIP's appnote.txt.
21020 var zip_cplens = new Array( // Copy lengths for literal codes 257..285
21021 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
21022 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0);
21023 /* note: see note #13 above about the 258 in this list. */
21024 var zip_cplext = new Array( // Extra bits for literal codes 257..285
21025 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
21026 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99); // 99==invalid
21027 var zip_cpdist = new Array( // Copy offsets for distance codes 0..29
21028 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
21029 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
21030 8193, 12289, 16385, 24577);
21031 var zip_cpdext = new Array( // Extra bits for distance codes
21032 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
21033 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
21034 12, 12, 13, 13);
21035 var zip_border = new Array( // Order of the bit length code lengths
21036 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15);
21037 /* objects (inflate) */
21038
21039 function zip_HuftList() {
21040 this.next = null;
21041 this.list = null;
21042 }
21043
21044 function zip_HuftNode() {
21045 this.e = 0; // number of extra bits or operation
21046 this.b = 0; // number of bits in this code or subcode
21047
21048 // union
21049 this.n = 0; // literal, length base, or distance base
21050 this.t = null; // (zip_HuftNode) pointer to next level of table
21051 }
21052
21053 function zip_HuftBuild(b, // code lengths in bits (all assumed <= BMAX)
21054 n, // number of codes (assumed <= N_MAX)
21055 s, // number of simple-valued codes (0..s-1)
21056 d, // list of base values for non-simple codes
21057 e, // list of extra bits for non-simple codes
21058 mm // maximum lookup bits
21059 ) {
21060 this.BMAX = 16; // maximum bit length of any code
21061 this.N_MAX = 288; // maximum number of codes in any set
21062 this.status = 0; // 0: success, 1: incomplete table, 2: bad input
21063 this.root = null; // (zip_HuftList) starting table
21064 this.m = 0; // maximum lookup bits, returns actual
21065
21066 /* Given a list of code lengths and a maximum table size, make a set of
21067 tables to decode that set of codes. Return zero on success, one if
21068 the given code set is incomplete (the tables are still built in this
21069 case), two if the input is invalid (all zero length codes or an
21070 oversubscribed set of lengths), and three if not enough memory.
21071 The code with value 256 is special, and the tables are constructed
21072 so that no bits beyond that code are fetched when that code is
21073 decoded. */
21074 {
21075 var a; // counter for codes of length k
21076 var c = new Array(this.BMAX+1); // bit length count table
21077 var el; // length of EOB code (value 256)
21078 var f; // i repeats in table every f entries
21079 var g; // maximum code length
21080 var h; // table level
21081 var i; // counter, current code
21082 var j; // counter
21083 var k; // number of bits in current code
21084 var lx = new Array(this.BMAX+1); // stack of bits per table
21085 var p; // pointer into c[], b[], or v[]
21086 var pidx; // index of p
21087 var q; // (zip_HuftNode) points to current table
21088 var r = new zip_HuftNode(); // table entry for structure assignment
21089 var u = new Array(this.BMAX); // zip_HuftNode[BMAX][] table stack
21090 var v = new Array(this.N_MAX); // values in order of bit length
21091 var w;
21092 var x = new Array(this.BMAX+1);// bit offsets, then code stack
21093 var xp; // pointer into x or c
21094 var y; // number of dummy codes added
21095 var z; // number of entries in current table
21096 var o;
21097 var tail; // (zip_HuftList)
21098
21099 tail = this.root = null;
21100 for(i = 0; i < c.length; i++)
21101 c[i] = 0;
21102 for(i = 0; i < lx.length; i++)
21103 lx[i] = 0;
21104 for(i = 0; i < u.length; i++)
21105 u[i] = null;
21106 for(i = 0; i < v.length; i++)
21107 v[i] = 0;
21108 for(i = 0; i < x.length; i++)
21109 x[i] = 0;
21110
21111 // Generate counts for each bit length
21112 el = n > 256 ? b[256] : this.BMAX; // set length of EOB code, if any
21113 p = b; pidx = 0;
21114 i = n;
21115 do {
21116 c[p[pidx]]++; // assume all entries <= BMAX
21117 pidx++;
21118 } while(--i > 0);
21119 if(c[0] == n) { // null input--all zero length codes
21120 this.root = null;
21121 this.m = 0;
21122 this.status = 0;
21123 return;
21124 }
21125
21126 // Find minimum and maximum length, bound *m by those
21127 for(j = 1; j <= this.BMAX; j++)
21128 if(c[j] != 0)
21129 break;
21130 k = j; // minimum code length
21131 if(mm < j)
21132 mm = j;
21133 for(i = this.BMAX; i != 0; i--)
21134 if(c[i] != 0)
21135 break;
21136 g = i; // maximum code length
21137 if(mm > i)
21138 mm = i;
21139
21140 // Adjust last length count to fill out codes, if needed
21141 for(y = 1 << j; j < i; j++, y <<= 1)
21142 if((y -= c[j]) < 0) {
21143 this.status = 2; // bad input: more codes than bits
21144 this.m = mm;
21145 return;
21146 }
21147 if((y -= c[i]) < 0) {
21148 this.status = 2;
21149 this.m = mm;
21150 return;
21151 }
21152 c[i] += y;
21153
21154 // Generate starting offsets into the value table for each length
21155 x[1] = j = 0;
21156 p = c;
21157 pidx = 1;
21158 xp = 2;
21159 while(--i > 0) // note that i == g from above
21160 x[xp++] = (j += p[pidx++]);
21161
21162 // Make a table of values in order of bit lengths
21163 p = b; pidx = 0;
21164 i = 0;
21165 do {
21166 if((j = p[pidx++]) != 0)
21167 v[x[j]++] = i;
21168 } while(++i < n);
21169 n = x[g]; // set n to length of v
21170
21171 // Generate the Huffman codes and for each, make the table entries
21172 x[0] = i = 0; // first Huffman code is zero
21173 p = v; pidx = 0; // grab values in bit order
21174 h = -1; // no tables yet--level -1
21175 w = lx[0] = 0; // no bits decoded yet
21176 q = null; // ditto
21177 z = 0; // ditto
21178
21179 // go through the bit lengths (k already is bits in shortest code)
21180 for(; k <= g; k++) {
21181 a = c[k];
21182 while(a-- > 0) {
21183 // here i is the Huffman code of length k bits for value p[pidx]
21184 // make tables up to required level
21185 while(k > w + lx[1 + h]) {
21186 w += lx[1 + h]; // add bits already decoded
21187 h++;
21188
21189 // compute minimum size table less than or equal to *m bits
21190 z = (z = g - w) > mm ? mm : z; // upper limit
21191 if((f = 1 << (j = k - w)) > a + 1) { // try a k-w bit table
21192 // too few codes for k-w bit table
21193 f -= a + 1; // deduct codes from patterns left
21194 xp = k;
21195 while(++j < z) { // try smaller tables up to z bits
21196 if((f <<= 1) <= c[++xp])
21197 break; // enough codes to use up j bits
21198 f -= c[xp]; // else deduct codes from patterns
21199 }
21200 }
21201 if(w + j > el && w < el)
21202 j = el - w; // make EOB code end at table
21203 z = 1 << j; // table entries for j-bit table
21204 lx[1 + h] = j; // set table size in stack
21205
21206 // allocate and link in new table
21207 q = new Array(z);
21208 for(o = 0; o < z; o++) {
21209 q[o] = new zip_HuftNode();
21210 }
21211
21212 if(tail == null)
21213 tail = this.root = new zip_HuftList();
21214 else
21215 tail = tail.next = new zip_HuftList();
21216 tail.next = null;
21217 tail.list = q;
21218 u[h] = q; // table starts after link
21219
21220 /* connect to last table, if there is one */
21221 if(h > 0) {
21222 x[h] = i; // save pattern for backing up
21223 r.b = lx[h]; // bits to dump before this table
21224 r.e = 16 + j; // bits in this table
21225 r.t = q; // pointer to this table
21226 j = (i & ((1 << w) - 1)) >> (w - lx[h]);
21227 u[h-1][j].e = r.e;
21228 u[h-1][j].b = r.b;
21229 u[h-1][j].n = r.n;
21230 u[h-1][j].t = r.t;
21231 }
21232 }
21233
21234 // set up table entry in r
21235 r.b = k - w;
21236 if(pidx >= n)
21237 r.e = 99; // out of values--invalid code
21238 else if(p[pidx] < s) {
21239 r.e = (p[pidx] < 256 ? 16 : 15); // 256 is end-of-block code
21240 r.n = p[pidx++]; // simple code is just the value
21241 } else {
21242 r.e = e[p[pidx] - s]; // non-simple--look up in lists
21243 r.n = d[p[pidx++] - s];
21244 }
21245
21246 // fill code-like entries with r //
21247 f = 1 << (k - w);
21248 for(j = i >> w; j < z; j += f) {
21249 q[j].e = r.e;
21250 q[j].b = r.b;
21251 q[j].n = r.n;
21252 q[j].t = r.t;
21253 }
21254
21255 // backwards increment the k-bit code i
21256 for(j = 1 << (k - 1); (i & j) != 0; j >>= 1)
21257 i ^= j;
21258 i ^= j;
21259
21260 // backup over finished tables
21261 while((i & ((1 << w) - 1)) != x[h]) {
21262 w -= lx[h]; // don't need to update q
21263 h--;
21264 }
21265 }
21266 }
21267
21268 /* return actual size of base table */
21269 this.m = lx[1];
21270
21271 /* Return true (1) if we were given an incomplete table */
21272 this.status = ((y != 0 && g != 1) ? 1 : 0);
21273 } /* end of constructor */
21274 }
21275
21276
21277 /* routines (inflate) */
21278
21279 function zip_GET_BYTE() {
21280 if(zip_inflate_data.length == zip_inflate_pos)
21281 return -1;
21282 return zip_inflate_data.charCodeAt(zip_inflate_pos++) & 0xff;
21283 }
21284
21285 function zip_NEEDBITS(n) {
21286 while(zip_bit_len < n) {
21287 zip_bit_buf |= zip_GET_BYTE() << zip_bit_len;
21288 zip_bit_len += 8;
21289 }
21290 }
21291
21292 function zip_GETBITS(n) {
21293 return zip_bit_buf & zip_MASK_BITS[n];
21294 }
21295
21296 function zip_DUMPBITS(n) {
21297 zip_bit_buf >>= n;
21298 zip_bit_len -= n;
21299 }
21300
21301 function zip_inflate_codes(buff, off, size) {
21302 /* inflate (decompress) the codes in a deflated (compressed) block.
21303 Return an error code or zero if it all goes ok. */
21304 var e; // table entry flag/number of extra bits
21305 var t; // (zip_HuftNode) pointer to table entry
21306 var n;
21307
21308 if(size == 0)
21309 return 0;
21310
21311 // inflate the coded data
21312 n = 0;
21313 for(;;) { // do until end of block
21314 zip_NEEDBITS(zip_bl);
21315 t = zip_tl.list[zip_GETBITS(zip_bl)];
21316 e = t.e;
21317 while(e > 16) {
21318 if(e == 99)
21319 return -1;
21320 zip_DUMPBITS(t.b);
21321 e -= 16;
21322 zip_NEEDBITS(e);
21323 t = t.t[zip_GETBITS(e)];
21324 e = t.e;
21325 }
21326 zip_DUMPBITS(t.b);
21327
21328 if(e == 16) { // then it's a literal
21329 zip_wp &= zip_WSIZE - 1;
21330 buff[off + n++] = zip_slide[zip_wp++] = t.n;
21331 if(n == size)
21332 return size;
21333 continue;
21334 }
21335
21336 // exit if end of block
21337 if(e == 15)
21338 break;
21339
21340 // it's an EOB or a length
21341
21342 // get length of block to copy
21343 zip_NEEDBITS(e);
21344 zip_copy_leng = t.n + zip_GETBITS(e);
21345 zip_DUMPBITS(e);
21346
21347 // decode distance of block to copy
21348 zip_NEEDBITS(zip_bd);
21349 t = zip_td.list[zip_GETBITS(zip_bd)];
21350 e = t.e;
21351
21352 while(e > 16) {
21353 if(e == 99)
21354 return -1;
21355 zip_DUMPBITS(t.b);
21356 e -= 16;
21357 zip_NEEDBITS(e);
21358 t = t.t[zip_GETBITS(e)];
21359 e = t.e;
21360 }
21361 zip_DUMPBITS(t.b);
21362 zip_NEEDBITS(e);
21363 zip_copy_dist = zip_wp - t.n - zip_GETBITS(e);
21364 zip_DUMPBITS(e);
21365
21366 // do the copy
21367 while(zip_copy_leng > 0 && n < size) {
21368 zip_copy_leng--;
21369 zip_copy_dist &= zip_WSIZE - 1;
21370 zip_wp &= zip_WSIZE - 1;
21371 buff[off + n++] = zip_slide[zip_wp++]
21372 = zip_slide[zip_copy_dist++];
21373 }
21374
21375 if(n == size)
21376 return size;
21377 }
21378
21379 zip_method = -1; // done
21380 return n;
21381 }
21382
21383 function zip_inflate_stored(buff, off, size) {
21384 /* "decompress" an inflated type 0 (stored) block. */
21385 var n;
21386
21387 // go to byte boundary
21388 n = zip_bit_len & 7;
21389 zip_DUMPBITS(n);
21390
21391 // get the length and its complement
21392 zip_NEEDBITS(16);
21393 n = zip_GETBITS(16);
21394 zip_DUMPBITS(16);
21395 zip_NEEDBITS(16);
21396 if(n != ((~zip_bit_buf) & 0xffff))
21397 return -1; // error in compressed data
21398 zip_DUMPBITS(16);
21399
21400 // read and output the compressed data
21401 zip_copy_leng = n;
21402
21403 n = 0;
21404 while(zip_copy_leng > 0 && n < size) {
21405 zip_copy_leng--;
21406 zip_wp &= zip_WSIZE - 1;
21407 zip_NEEDBITS(8);
21408 buff[off + n++] = zip_slide[zip_wp++] =
21409 zip_GETBITS(8);
21410 zip_DUMPBITS(8);
21411 }
21412
21413 if(zip_copy_leng == 0)
21414 zip_method = -1; // done
21415 return n;
21416 }
21417
21418 function zip_inflate_fixed(buff, off, size) {
21419 /* decompress an inflated type 1 (fixed Huffman codes) block. We should
21420 either replace this with a custom decoder, or at least precompute the
21421 Huffman tables. */
21422
21423 // if first time, set up tables for fixed blocks
21424 if(zip_fixed_tl == null) {
21425 var i; // temporary variable
21426 var l = new Array(288); // length list for huft_build
21427 var h; // zip_HuftBuild
21428
21429 // literal table
21430 for(i = 0; i < 144; i++)
21431 l[i] = 8;
21432 for(; i < 256; i++)
21433 l[i] = 9;
21434 for(; i < 280; i++)
21435 l[i] = 7;
21436 for(; i < 288; i++) // make a complete, but wrong code set
21437 l[i] = 8;
21438 zip_fixed_bl = 7;
21439
21440 h = new zip_HuftBuild(l, 288, 257, zip_cplens, zip_cplext,
21441 zip_fixed_bl);
21442 if(h.status != 0) {
21443 alert("HufBuild error: "+h.status);
21444 return -1;
21445 }
21446 zip_fixed_tl = h.root;
21447 zip_fixed_bl = h.m;
21448
21449 // distance table
21450 for(i = 0; i < 30; i++) // make an incomplete code set
21451 l[i] = 5;
21452 zip_fixed_bd = 5;
21453
21454 h = new zip_HuftBuild(l, 30, 0, zip_cpdist, zip_cpdext, zip_fixed_bd);
21455 if(h.status > 1) {
21456 zip_fixed_tl = null;
21457 alert("HufBuild error: "+h.status);
21458 return -1;
21459 }
21460 zip_fixed_td = h.root;
21461 zip_fixed_bd = h.m;
21462 }
21463
21464 zip_tl = zip_fixed_tl;
21465 zip_td = zip_fixed_td;
21466 zip_bl = zip_fixed_bl;
21467 zip_bd = zip_fixed_bd;
21468 return zip_inflate_codes(buff, off, size);
21469 }
21470
21471 function zip_inflate_dynamic(buff, off, size) {
21472 // decompress an inflated type 2 (dynamic Huffman codes) block.
21473 var i; // temporary variables
21474 var j;
21475 var l; // last length
21476 var n; // number of lengths to get
21477 var t; // (zip_HuftNode) literal/length code table
21478 var nb; // number of bit length codes
21479 var nl; // number of literal/length codes
21480 var nd; // number of distance codes
21481 var ll = new Array(286+30); // literal/length and distance code lengths
21482 var h; // (zip_HuftBuild)
21483
21484 for(i = 0; i < ll.length; i++)
21485 ll[i] = 0;
21486
21487 // read in table lengths
21488 zip_NEEDBITS(5);
21489 nl = 257 + zip_GETBITS(5); // number of literal/length codes
21490 zip_DUMPBITS(5);
21491 zip_NEEDBITS(5);
21492 nd = 1 + zip_GETBITS(5); // number of distance codes
21493 zip_DUMPBITS(5);
21494 zip_NEEDBITS(4);
21495 nb = 4 + zip_GETBITS(4); // number of bit length codes
21496 zip_DUMPBITS(4);
21497 if(nl > 286 || nd > 30)
21498 return -1; // bad lengths
21499
21500 // read in bit-length-code lengths
21501 for(j = 0; j < nb; j++)
21502 {
21503 zip_NEEDBITS(3);
21504 ll[zip_border[j]] = zip_GETBITS(3);
21505 zip_DUMPBITS(3);
21506 }
21507 for(; j < 19; j++)
21508 ll[zip_border[j]] = 0;
21509
21510 // build decoding table for trees--single level, 7 bit lookup
21511 zip_bl = 7;
21512 h = new zip_HuftBuild(ll, 19, 19, null, null, zip_bl);
21513 if(h.status != 0)
21514 return -1; // incomplete code set
21515
21516 zip_tl = h.root;
21517 zip_bl = h.m;
21518
21519 // read in literal and distance code lengths
21520 n = nl + nd;
21521 i = l = 0;
21522 while(i < n) {
21523 zip_NEEDBITS(zip_bl);
21524 t = zip_tl.list[zip_GETBITS(zip_bl)];
21525 j = t.b;
21526 zip_DUMPBITS(j);
21527 j = t.n;
21528 if(j < 16) // length of code in bits (0..15)
21529 ll[i++] = l = j; // save last length in l
21530 else if(j == 16) { // repeat last length 3 to 6 times
21531 zip_NEEDBITS(2);
21532 j = 3 + zip_GETBITS(2);
21533 zip_DUMPBITS(2);
21534 if(i + j > n)
21535 return -1;
21536 while(j-- > 0)
21537 ll[i++] = l;
21538 } else if(j == 17) { // 3 to 10 zero length codes
21539 zip_NEEDBITS(3);
21540 j = 3 + zip_GETBITS(3);
21541 zip_DUMPBITS(3);
21542 if(i + j > n)
21543 return -1;
21544 while(j-- > 0)
21545 ll[i++] = 0;
21546 l = 0;
21547 } else { // j == 18: 11 to 138 zero length codes
21548 zip_NEEDBITS(7);
21549 j = 11 + zip_GETBITS(7);
21550 zip_DUMPBITS(7);
21551 if(i + j > n)
21552 return -1;
21553 while(j-- > 0)
21554 ll[i++] = 0;
21555 l = 0;
21556 }
21557 }
21558
21559 // build the decoding tables for literal/length and distance codes
21560 zip_bl = zip_lbits;
21561 h = new zip_HuftBuild(ll, nl, 257, zip_cplens, zip_cplext, zip_bl);
21562 if(zip_bl == 0) // no literals or lengths
21563 h.status = 1;
21564 if(h.status != 0) {
21565 if(h.status == 1)
21566 ;// **incomplete literal tree**
21567 return -1; // incomplete code set
21568 }
21569 zip_tl = h.root;
21570 zip_bl = h.m;
21571
21572 for(i = 0; i < nd; i++)
21573 ll[i] = ll[i + nl];
21574 zip_bd = zip_dbits;
21575 h = new zip_HuftBuild(ll, nd, 0, zip_cpdist, zip_cpdext, zip_bd);
21576 zip_td = h.root;
21577 zip_bd = h.m;
21578
21579 if(zip_bd == 0 && nl > 257) { // lengths but no distances
21580 // **incomplete distance tree**
21581 return -1;
21582 }
21583
21584 if(h.status == 1) {
21585 ;// **incomplete distance tree**
21586 }
21587 if(h.status != 0)
21588 return -1;
21589
21590 // decompress until an end-of-block code
21591 return zip_inflate_codes(buff, off, size);
21592 }
21593
21594 function zip_inflate_start() {
21595 var i;
21596
21597 if(zip_slide == null)
21598 zip_slide = new Array(2 * zip_WSIZE);
21599 zip_wp = 0;
21600 zip_bit_buf = 0;
21601 zip_bit_len = 0;
21602 zip_method = -1;
21603 zip_eof = false;
21604 zip_copy_leng = zip_copy_dist = 0;
21605 zip_tl = null;
21606 }
21607
21608 function zip_inflate_internal(buff, off, size) {
21609 // decompress an inflated entry
21610 var n, i;
21611
21612 n = 0;
21613 while(n < size) {
21614 if(zip_eof && zip_method == -1)
21615 return n;
21616
21617 if(zip_copy_leng > 0) {
21618 if(zip_method != zip_STORED_BLOCK) {
21619 // STATIC_TREES or DYN_TREES
21620 while(zip_copy_leng > 0 && n < size) {
21621 zip_copy_leng--;
21622 zip_copy_dist &= zip_WSIZE - 1;
21623 zip_wp &= zip_WSIZE - 1;
21624 buff[off + n++] = zip_slide[zip_wp++] =
21625 zip_slide[zip_copy_dist++];
21626 }
21627 } else {
21628 while(zip_copy_leng > 0 && n < size) {
21629 zip_copy_leng--;
21630 zip_wp &= zip_WSIZE - 1;
21631 zip_NEEDBITS(8);
21632 buff[off + n++] = zip_slide[zip_wp++] = zip_GETBITS(8);
21633 zip_DUMPBITS(8);
21634 }
21635 if(zip_copy_leng == 0)
21636 zip_method = -1; // done
21637 }
21638 if(n == size)
21639 return n;
21640 }
21641
21642 if(zip_method == -1) {
21643 if(zip_eof)
21644 break;
21645
21646 // read in last block bit
21647 zip_NEEDBITS(1);
21648 if(zip_GETBITS(1) != 0)
21649 zip_eof = true;
21650 zip_DUMPBITS(1);
21651
21652 // read in block type
21653 zip_NEEDBITS(2);
21654 zip_method = zip_GETBITS(2);
21655 zip_DUMPBITS(2);
21656 zip_tl = null;
21657 zip_copy_leng = 0;
21658 }
21659
21660 switch(zip_method) {
21661 case 0: // zip_STORED_BLOCK
21662 i = zip_inflate_stored(buff, off + n, size - n);
21663 break;
21664
21665 case 1: // zip_STATIC_TREES
21666 if(zip_tl != null)
21667 i = zip_inflate_codes(buff, off + n, size - n);
21668 else
21669 i = zip_inflate_fixed(buff, off + n, size - n);
21670 break;
21671
21672 case 2: // zip_DYN_TREES
21673 if(zip_tl != null)
21674 i = zip_inflate_codes(buff, off + n, size - n);
21675 else
21676 i = zip_inflate_dynamic(buff, off + n, size - n);
21677 break;
21678
21679 default: // error
21680 i = -1;
21681 break;
21682 }
21683
21684 if(i == -1) {
21685 if(zip_eof)
21686 return 0;
21687 return -1;
21688 }
21689 n += i;
21690 }
21691 return n;
21692 }
21693
21694 function zip_inflate(str) {
21695 var out, buff;
21696 var i, j;
21697
21698 zip_inflate_start();
21699 zip_inflate_data = str;
21700 zip_inflate_pos = 0;
21701
21702 buff = new Array(1024);
21703 out = "";
21704 while((i = zip_inflate_internal(buff, 0, buff.length)) > 0) {
21705 for(j = 0; j < i; j++)
21706 out += String.fromCharCode(buff[j]);
21707 }
21708 zip_inflate_data = null; // G.C.
21709 return out;
21710 }
21711
21712 //
21713 // end of the script of Masanao Izumo.
21714 //
21715
21716 // we add the compression method for JSZip
21717 if(!JSZip.compressions["DEFLATE"]) {
21718 JSZip.compressions["DEFLATE"] = {
21719 magic : "\x08\x00",
21720 uncompress : zip_inflate
21721 }
21722 } else {
21723 JSZip.compressions["DEFLATE"].uncompress = zip_inflate;
21724 }
21725
21726 })();
21727
21728 // enforcing Stuk's coding style
21729 // vim: set shiftwidth=3 softtabstop=3:
21730 /**
21731
21732 JSZip - A Javascript class for generating and reading zip files
21733 <http://stuartk.com/jszip>
21734
21735 (c) 2011 David Duponchel <d.duponchel@gmail.com>
21736 Dual licenced under the MIT license or GPLv3. See LICENSE.markdown.
21737
21738 **/
21739 /*global JSZip,JSZipBase64 */
21740 (function () {
21741
21742 var MAX_VALUE_16BITS = 65535;
21743 var MAX_VALUE_32BITS = -1; // well, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" is parsed as -1
21744
21745 /**
21746 * Prettify a string read as binary.
21747 * @param {string} str the string to prettify.
21748 * @return {string} a pretty string.
21749 */
21750 var pretty = function (str) {
21751 var res = '', code, i;
21752 for (i = 0; i < (str||"").length; i++) {
21753 code = str.charCodeAt(i);
21754 res += '\\x' + (code < 16 ? "0" : "") + code.toString(16).toUpperCase();
21755 }
21756 return res;
21757 };
21758
21759 /**
21760 * Find a compression registered in JSZip.
21761 * @param {string} compressionMethod the method magic to find.
21762 * @return {Object|null} the JSZip compression object, null if none found.
21763 */
21764 var findCompression = function (compressionMethod) {
21765 for (var method in JSZip.compressions) {
21766 if( !JSZip.compressions.hasOwnProperty(method) ) { continue; }
21767 if (JSZip.compressions[method].magic === compressionMethod) {
21768 return JSZip.compressions[method];
21769 }
21770 }
21771 return null;
21772 };
21773
21774 // class StreamReader {{{
21775 /**
21776 * Read bytes from a stream.
21777 * Developer tip : when debugging, a watch on pretty(this.reader.stream.slice(this.reader.index))
21778 * is very useful :)
21779 * @constructor
21780 * @param {String|ArrayBuffer|Uint8Array} stream the stream to read.
21781 */
21782 function StreamReader(stream) {
21783 this.stream = "";
21784 if (JSZip.support.uint8array && stream instanceof Uint8Array) {
21785 this.stream = JSZip.utils.uint8Array2String(stream);
21786 } else if (JSZip.support.arraybuffer && stream instanceof ArrayBuffer) {
21787 var bufferView = new Uint8Array(stream);
21788 this.stream = JSZip.utils.uint8Array2String(bufferView);
21789 } else {
21790 this.stream = JSZip.utils.string2binary(stream);
21791 }
21792 this.index = 0;
21793 }
21794 StreamReader.prototype = {
21795 /**
21796 * Check that the offset will not go too far.
21797 * @param {string} offset the additional offset to check.
21798 * @throws {Error} an Error if the offset is out of bounds.
21799 */
21800 checkOffset : function (offset) {
21801 this.checkIndex(this.index + offset);
21802 },
21803 /**
21804 * Check that the specifed index will not be too far.
21805 * @param {string} newIndex the index to check.
21806 * @throws {Error} an Error if the index is out of bounds.
21807 */
21808 checkIndex : function (newIndex) {
21809 if (this.stream.length < newIndex || newIndex < 0) {
21810 throw new Error("End of stream reached (stream length = " +
21811 this.stream.length + ", asked index = " +
21812 (newIndex) + "). Corrupted zip ?");
21813 }
21814 },
21815 /**
21816 * Change the index.
21817 * @param {number} newIndex The new index.
21818 * @throws {Error} if the new index is out of the stream.
21819 */
21820 setIndex : function (newIndex) {
21821 this.checkIndex(newIndex);
21822 this.index = newIndex;
21823 },
21824 /**
21825 * Skip the next n bytes.
21826 * @param {number} n the number of bytes to skip.
21827 * @throws {Error} if the new index is out of the stream.
21828 */
21829 skip : function (n) {
21830 this.setIndex(this.index + n);
21831 },
21832 /**
21833 * Get the byte at the specified index.
21834 * @param {number} i the index to use.
21835 * @return {number} a byte.
21836 */
21837 byteAt : function(i) {
21838 return this.stream.charCodeAt(i);
21839 },
21840 /**
21841 * Get the next number with a given byte size.
21842 * @param {number} size the number of bytes to read.
21843 * @return {number} the corresponding number.
21844 */
21845 readInt : function (size) {
21846 var result = 0, i;
21847 this.checkOffset(size);
21848 for(i = this.index + size - 1; i >= this.index; i--) {
21849 result = (result << 8) + this.byteAt(i);
21850 }
21851 this.index += size;
21852 return result;
21853 },
21854 /**
21855 * Get the next string with a given byte size.
21856 * @param {number} size the number of bytes to read.
21857 * @return {string} the corresponding string.
21858 */
21859 readString : function (size) {
21860 this.checkOffset(size);
21861 // this will work because the constructor applied the "& 0xff" mask.
21862 var result = this.stream.slice(this.index, this.index + size);
21863 this.index += size;
21864 return result;
21865 },
21866 /**
21867 * Get the next date.
21868 * @return {Date} the date.
21869 */
21870 readDate : function () {
21871 var dostime = this.readInt(4);
21872 return new Date(
21873 ((dostime >> 25) & 0x7f) + 1980, // year
21874 ((dostime >> 21) & 0x0f) - 1, // month
21875 (dostime >> 16) & 0x1f, // day
21876 (dostime >> 11) & 0x1f, // hour
21877 (dostime >> 5) & 0x3f, // minute
21878 (dostime & 0x1f) << 1); // second
21879 }
21880 };
21881 // }}} end of StreamReader
21882
21883 // class ZipEntry {{{
21884 /**
21885 * An entry in the zip file.
21886 * @constructor
21887 * @param {Object} options Options of the current file.
21888 * @param {Object} loadOptions Options for loading the stream.
21889 */
21890 function ZipEntry(options, loadOptions) {
21891 this.options = options;
21892 this.loadOptions = loadOptions;
21893 }
21894 ZipEntry.prototype = {
21895 /**
21896 * say if the file is encrypted.
21897 * @return {boolean} true if the file is encrypted, false otherwise.
21898 */
21899 isEncrypted : function () {
21900 // bit 1 is set
21901 return (this.bitFlag & 0x0001) === 0x0001;
21902 },
21903 /**
21904 * say if the file has utf-8 filename/comment.
21905 * @return {boolean} true if the filename/comment is in utf-8, false otherwise.
21906 */
21907 useUTF8 : function () {
21908 // bit 11 is set
21909 return (this.bitFlag & 0x0800) === 0x0800;
21910 },
21911 /**
21912 * Read the local part of a zip file and add the info in this object.
21913 * @param {StreamReader} reader the reader to use.
21914 */
21915 readLocalPart : function(reader) {
21916 var compression, localExtraFieldsLength;
21917
21918 // we already know everything from the central dir !
21919 // If the central dir data are false, we are doomed.
21920 // On the bright side, the local part is scary : zip64, data descriptors, both, etc.
21921 // The less data we get here, the more reliable this should be.
21922 // Let's skip the whole header and dash to the data !
21923 reader.skip(22);
21924 // in some zip created on windows, the filename stored in the central dir contains \ instead of /.
21925 // Strangely, the filename here is OK.
21926 // I would love to treat these zip files as corrupted (see http://www.info-zip.org/FAQ.html#backslashes
21927 // or APPNOTE#4.4.17.1, "All slashes MUST be forward slashes '/'") but there are a lot of bad zip generators...
21928 // Search "unzip mismatching "local" filename continuing with "central" filename version" on
21929 // the internet.
21930 //
21931 // I think I see the logic here : the central directory is used to display
21932 // content and the local directory is used to extract the files. Mixing / and \
21933 // may be used to display \ to windows users and use / when extracting the files.
21934 // Unfortunately, this lead also to some issues : http://seclists.org/fulldisclosure/2009/Sep/394
21935 this.fileNameLength = reader.readInt(2);
21936 localExtraFieldsLength = reader.readInt(2); // can't be sure this will be the same as the central dir
21937 this.fileName = reader.readString(this.fileNameLength);
21938 reader.skip(localExtraFieldsLength);
21939
21940 if (this.compressedSize == -1 || this.uncompressedSize == -1) {
21941 throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory " +
21942 "(compressedSize == -1 || uncompressedSize == -1)");
21943 }
21944 this.compressedFileData = reader.readString(this.compressedSize);
21945
21946 compression = findCompression(this.compressionMethod);
21947 if (compression === null) { // no compression found
21948 throw new Error("Corrupted zip : compression " + pretty(this.compressionMethod) +
21949 " unknown (inner file : " + this.fileName + ")");
21950 }
21951 this.uncompressedFileData = compression.uncompress(this.compressedFileData);
21952
21953 if (this.uncompressedFileData.length !== this.uncompressedSize) {
21954 throw new Error("Bug : uncompressed data size mismatch");
21955 }
21956
21957 if (this.loadOptions.checkCRC32 && JSZip.prototype.crc32(this.uncompressedFileData) !== this.crc32) {
21958 throw new Error("Corrupted zip : CRC32 mismatch");
21959 }
21960 },
21961
21962 /**
21963 * Read the central part of a zip file and add the info in this object.
21964 * @param {StreamReader} reader the reader to use.
21965 */
21966 readCentralPart : function(reader) {
21967 this.versionMadeBy = reader.readString(2);
21968 this.versionNeeded = reader.readInt(2);
21969 this.bitFlag = reader.readInt(2);
21970 this.compressionMethod = reader.readString(2);
21971 this.date = reader.readDate();
21972 this.crc32 = reader.readInt(4);
21973 this.compressedSize = reader.readInt(4);
21974 this.uncompressedSize = reader.readInt(4);
21975 this.fileNameLength = reader.readInt(2);
21976 this.extraFieldsLength = reader.readInt(2);
21977 this.fileCommentLength = reader.readInt(2);
21978 this.diskNumberStart = reader.readInt(2);
21979 this.internalFileAttributes = reader.readInt(2);
21980 this.externalFileAttributes = reader.readInt(4);
21981 this.localHeaderOffset = reader.readInt(4);
21982
21983 if (this.isEncrypted()) {
21984 throw new Error("Encrypted zip are not supported");
21985 }
21986
21987 this.fileName = reader.readString(this.fileNameLength);
21988 this.readExtraFields(reader);
21989 this.parseZIP64ExtraField(reader);
21990 this.fileComment = reader.readString(this.fileCommentLength);
21991
21992 // warning, this is true only for zip with madeBy == DOS (plateform dependent feature)
21993 this.dir = this.externalFileAttributes & 0x00000010 ? true : false;
21994 },
21995 /**
21996 * Parse the ZIP64 extra field and merge the info in the current ZipEntry.
21997 * @param {StreamReader} reader the reader to use.
21998 */
21999 parseZIP64ExtraField : function(reader) {
22000
22001 if(!this.extraFields[0x0001]) {
22002 return;
22003 }
22004
22005 // should be something, preparing the extra reader
22006 var extraReader = new StreamReader(this.extraFields[0x0001].value);
22007
22008 // I really hope that these 64bits integer can fit in 32 bits integer, because js
22009 // won't let us have more.
22010 if(this.uncompressedSize === MAX_VALUE_32BITS) {
22011 this.uncompressedSize = extraReader.readInt(8);
22012 }
22013 if(this.compressedSize === MAX_VALUE_32BITS) {
22014 this.compressedSize = extraReader.readInt(8);
22015 }
22016 if(this.localHeaderOffset === MAX_VALUE_32BITS) {
22017 this.localHeaderOffset = extraReader.readInt(8);
22018 }
22019 if(this.diskNumberStart === MAX_VALUE_32BITS) {
22020 this.diskNumberStart = extraReader.readInt(4);
22021 }
22022 },
22023 /**
22024 * Read the central part of a zip file and add the info in this object.
22025 * @param {StreamReader} reader the reader to use.
22026 */
22027 readExtraFields : function(reader) {
22028 var start = reader.index,
22029 extraFieldId,
22030 extraFieldLength,
22031 extraFieldValue;
22032
22033 this.extraFields = this.extraFields || {};
22034
22035 while (reader.index < start + this.extraFieldsLength) {
22036 extraFieldId = reader.readInt(2);
22037 extraFieldLength = reader.readInt(2);
22038 extraFieldValue = reader.readString(extraFieldLength);
22039
22040 this.extraFields[extraFieldId] = {
22041 id: extraFieldId,
22042 length: extraFieldLength,
22043 value: extraFieldValue
22044 };
22045 }
22046 },
22047 /**
22048 * Apply an UTF8 transformation if needed.
22049 */
22050 handleUTF8 : function() {
22051 if (this.useUTF8()) {
22052 this.fileName = JSZip.prototype.utf8decode(this.fileName);
22053 this.fileComment = JSZip.prototype.utf8decode(this.fileComment);
22054 }
22055 }
22056 };
22057 // }}} end of ZipEntry
22058
22059 // class ZipEntries {{{
22060 /**
22061 * All the entries in the zip file.
22062 * @constructor
22063 * @param {String|ArrayBuffer|Uint8Array} data the binary stream to load.
22064 * @param {Object} loadOptions Options for loading the stream.
22065 */
22066 function ZipEntries(data, loadOptions) {
22067 this.files = [];
22068 this.loadOptions = loadOptions;
22069 if (data) {
22070 this.load(data);
22071 }
22072 }
22073 ZipEntries.prototype = {
22074 /**
22075 * Check that the reader is on the speficied signature.
22076 * @param {string} expectedSignature the expected signature.
22077 * @throws {Error} if it is an other signature.
22078 */
22079 checkSignature : function(expectedSignature) {
22080 var signature = this.reader.readString(4);
22081 if (signature !== expectedSignature) {
22082 throw new Error("Corrupted zip or bug : unexpected signature " +
22083 "(" + pretty(signature) + ", expected " + pretty(expectedSignature) + ")");
22084 }
22085 },
22086 /**
22087 * Read the end of the central directory.
22088 */
22089 readBlockEndOfCentral : function () {
22090 this.diskNumber = this.reader.readInt(2);
22091 this.diskWithCentralDirStart = this.reader.readInt(2);
22092 this.centralDirRecordsOnThisDisk = this.reader.readInt(2);
22093 this.centralDirRecords = this.reader.readInt(2);
22094 this.centralDirSize = this.reader.readInt(4);
22095 this.centralDirOffset = this.reader.readInt(4);
22096
22097 this.zipCommentLength = this.reader.readInt(2);
22098 this.zipComment = this.reader.readString(this.zipCommentLength);
22099 },
22100 /**
22101 * Read the end of the Zip 64 central directory.
22102 * Not merged with the method readEndOfCentral :
22103 * The end of central can coexist with its Zip64 brother,
22104 * I don't want to read the wrong number of bytes !
22105 */
22106 readBlockZip64EndOfCentral : function () {
22107 this.zip64EndOfCentralSize = this.reader.readInt(8);
22108 this.versionMadeBy = this.reader.readString(2);
22109 this.versionNeeded = this.reader.readInt(2);
22110 this.diskNumber = this.reader.readInt(4);
22111 this.diskWithCentralDirStart = this.reader.readInt(4);
22112 this.centralDirRecordsOnThisDisk = this.reader.readInt(8);
22113 this.centralDirRecords = this.reader.readInt(8);
22114 this.centralDirSize = this.reader.readInt(8);
22115 this.centralDirOffset = this.reader.readInt(8);
22116
22117 this.zip64ExtensibleData = {};
22118 var extraDataSize = this.zip64EndOfCentralSize - 44,
22119 index = 0,
22120 extraFieldId,
22121 extraFieldLength,
22122 extraFieldValue;
22123 while(index < extraDataSize) {
22124 extraFieldId = this.reader.readInt(2);
22125 extraFieldLength = this.reader.readInt(4);
22126 extraFieldValue = this.reader.readString(extraFieldLength);
22127 this.zip64ExtensibleData[extraFieldId] = {
22128 id: extraFieldId,
22129 length: extraFieldLength,
22130 value: extraFieldValue
22131 };
22132 }
22133 },
22134 /**
22135 * Read the end of the Zip 64 central directory locator.
22136 */
22137 readBlockZip64EndOfCentralLocator : function () {
22138 this.diskWithZip64CentralDirStart = this.reader.readInt(4);
22139 this.relativeOffsetEndOfZip64CentralDir = this.reader.readInt(8);
22140 this.disksCount = this.reader.readInt(4);
22141 if (this.disksCount > 1) {
22142 throw new Error("Multi-volumes zip are not supported");
22143 }
22144 },
22145 /**
22146 * Read the local files, based on the offset read in the central part.
22147 */
22148 readLocalFiles : function() {
22149 var i, file;
22150 for(i = 0; i < this.files.length; i++) {
22151 file = this.files[i];
22152 this.reader.setIndex(file.localHeaderOffset);
22153 this.checkSignature(JSZip.signature.LOCAL_FILE_HEADER);
22154 file.readLocalPart(this.reader);
22155 file.handleUTF8();
22156 }
22157 },
22158 /**
22159 * Read the central directory.
22160 */
22161 readCentralDir : function() {
22162 var file;
22163
22164 this.reader.setIndex(this.centralDirOffset);
22165 while(this.reader.readString(4) === JSZip.signature.CENTRAL_FILE_HEADER) {
22166 file = new ZipEntry({
22167 zip64: this.zip64
22168 }, this.loadOptions);
22169 file.readCentralPart(this.reader);
22170 this.files.push(file);
22171 }
22172 },
22173 /**
22174 * Read the end of central directory.
22175 */
22176 readEndOfCentral : function() {
22177 var offset = this.reader.stream.lastIndexOf(JSZip.signature.CENTRAL_DIRECTORY_END);
22178 if (offset === -1) {
22179 throw new Error("Corrupted zip : can't find end of central directory");
22180 }
22181 this.reader.setIndex(offset);
22182 this.checkSignature(JSZip.signature.CENTRAL_DIRECTORY_END);
22183 this.readBlockEndOfCentral();
22184
22185
22186 /* extract from the zip spec :
22187 4) If one of the fields in the end of central directory
22188 record is too small to hold required data, the field
22189 should be set to -1 (0xFFFF or 0xFFFFFFFF) and the
22190 ZIP64 format record should be created.
22191 5) The end of central directory record and the
22192 Zip64 end of central directory locator record must
22193 reside on the same disk when splitting or spanning
22194 an archive.
22195 */
22196 if ( this.diskNumber === MAX_VALUE_16BITS
22197 || this.diskWithCentralDirStart === MAX_VALUE_16BITS
22198 || this.centralDirRecordsOnThisDisk === MAX_VALUE_16BITS
22199 || this.centralDirRecords === MAX_VALUE_16BITS
22200 || this.centralDirSize === MAX_VALUE_32BITS
22201 || this.centralDirOffset === MAX_VALUE_32BITS
22202 ) {
22203 this.zip64 = true;
22204
22205 /*
22206 Warning : the zip64 extension is supported, but ONLY if the 64bits integer read from
22207 the zip file can fit into a 32bits integer. This cannot be solved : Javascript represents
22208 all numbers as 64-bit double precision IEEE 754 floating point numbers.
22209 So, we have 53bits for integers and bitwise operations treat everything as 32bits.
22210 see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Bitwise_Operators
22211 and http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf section 8.5
22212 */
22213
22214 // should look for a zip64 EOCD locator
22215 offset = this.reader.stream.lastIndexOf(JSZip.signature.ZIP64_CENTRAL_DIRECTORY_LOCATOR);
22216 if (offset === -1) {
22217 throw new Error("Corrupted zip : can't find the ZIP64 end of central directory locator");
22218 }
22219 this.reader.setIndex(offset);
22220 this.checkSignature(JSZip.signature.ZIP64_CENTRAL_DIRECTORY_LOCATOR);
22221 this.readBlockZip64EndOfCentralLocator();
22222
22223 // now the zip64 EOCD record
22224 this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir);
22225 this.checkSignature(JSZip.signature.ZIP64_CENTRAL_DIRECTORY_END);
22226 this.readBlockZip64EndOfCentral();
22227 }
22228 },
22229 /**
22230 * Read a zip file and create ZipEntries.
22231 * @param {String|ArrayBuffer|Uint8Array} data the binary string representing a zip file.
22232 */
22233 load : function(data) {
22234 this.reader = new StreamReader(data);
22235
22236 this.readEndOfCentral();
22237 this.readCentralDir();
22238 this.readLocalFiles();
22239 }
22240 };
22241 // }}} end of ZipEntries
22242
22243 /**
22244 * Implementation of the load method of JSZip.
22245 * It uses the above classes to decode a zip file, and load every files.
22246 * @param {String|ArrayBuffer|Uint8Array} data the data to load.
22247 * @param {Object} options Options for loading the stream.
22248 * options.base64 : is the stream in base64 ? default : false
22249 */
22250 JSZip.prototype.load = function(data, options) {
22251 var files, zipEntries, i, input;
22252 options = options || {};
22253 if(options.base64) {
22254 data = JSZipBase64.decode(data);
22255 }
22256
22257 zipEntries = new ZipEntries(data, options);
22258 files = zipEntries.files;
22259 for (i = 0; i < files.length; i++) {
22260 input = files[i];
22261 this.file(input.fileName, input.uncompressedFileData, {
22262 binary:true,
22263 optimizedBinaryString:true,
22264 date:input.date,
22265 dir:input.dir
22266 });
22267 }
22268
22269 return this;
22270 };
22271
22272 }());
22273 // enforcing Stuk's coding style
22274 // vim: set shiftwidth=3 softtabstop=3 foldmethod=marker:
22275 //! moment.js 31110 //! moment.js
22276 //! version : 2.5.1 31111 //! version : 2.5.1
22277 //! authors : Tim Wood, Iskren Chernev, Moment.js contributors 31112 //! authors : Tim Wood, Iskren Chernev, Moment.js contributors
22278 //! license : MIT 31113 //! license : MIT
22279 //! momentjs.com 31114 //! momentjs.com
30260 if (ieversion == 8) { 39095 if (ieversion == 8) {
30261 GeoTemConfig.ie8 = true; 39096 GeoTemConfig.ie8 = true;
30262 } 39097 }
30263 } 39098 }
30264 39099
39100 GeoTemConfig.quoteVal = function(val){
39101 return val.replace(new RegExp('"', 'g'), '%22');
39102
39103 }
39104
30265 GeoTemConfig.getIndependentId = function(target){ 39105 GeoTemConfig.getIndependentId = function(target){
30266 if( target == 'map' ){ 39106 if( target == 'map' ){
30267 return ++GeoTemConfig.independentMapId; 39107 return ++GeoTemConfig.independentMapId;
30268 } 39108 }
30269 if( target == 'time' ){ 39109 if( target == 'time' ){
30434 /** 39274 /**
30435 * returns the json object of the file from the given url 39275 * returns the json object of the file from the given url
30436 * @param {String} url the url of the file to load 39276 * @param {String} url the url of the file to load
30437 * @return json object of given file 39277 * @return json object of given file
30438 */ 39278 */
30439 GeoTemConfig.getJson = function(url) { 39279 GeoTemConfig.getJson = function(url,asyncFunc) {
39280 var async = false;
39281 if( asyncFunc ){
39282 async = true;
39283 }
39284
30440 var data; 39285 var data;
30441 $.ajax({ 39286 $.ajax({
30442 url : url, 39287 url : url,
30443 async : false, 39288 async : async,
30444 dataType : 'json', 39289 dataType : 'json',
30445 success : function(json) { 39290 success : function(json) {
30446 data = json; 39291 data = json;
39292 if (async){
39293 asyncFunc(data);
39294 }
30447 } 39295 }
30448 }); 39296 });
30449 return data; 39297
39298 if (async){
39299 return data;
39300 }
30450 } 39301 }
30451 39302
30452 GeoTemConfig.mergeObjects = function(set1, set2) { 39303 GeoTemConfig.mergeObjects = function(set1, set2) {
30453 var inside = []; 39304 var inside = [];
30454 var newSet = []; 39305 var newSet = [];
30487 }; 39338 };
30488 39339
30489 GeoTemConfig.removeDataset = function(index){ 39340 GeoTemConfig.removeDataset = function(index){
30490 GeoTemConfig.datasets.splice(index,1); 39341 GeoTemConfig.datasets.splice(index,1);
30491 Publisher.Publish('filterData', GeoTemConfig.datasets, null); 39342 Publisher.Publish('filterData', GeoTemConfig.datasets, null);
39343 };
39344
39345 GeoTemConfig.removeAllDatasets = function() {
39346
39347 if (GeoTemConfig.datasets.length > 0) {
39348 GeoTemConfig.datasets.splice(0, GeoTemConfig.datasets.length);
39349 Publisher.Publish('filterData', GeoTemConfig.datasets, null);
39350 }
30492 }; 39351 };
30493 39352
30494 /** 39353 /**
30495 * converts the csv-file into json-format 39354 * converts the csv-file into json-format
30496 * 39355 *
30682 req.send(); 39541 req.send();
30683 39542
30684 if( !async ){ 39543 if( !async ){
30685 return json; 39544 return json;
30686 } 39545 }
39546 };
39547
39548 /**
39549 * loads a binary file
39550 * @param {String} url of the file to load
39551 * @return binary data
39552 */
39553 GeoTemConfig.getBinary = function(url,asyncFunc) {
39554 var async = true;
39555
39556 var req = new XMLHttpRequest();
39557 req.open("GET",url,async);
39558 req.responseType = "arraybuffer";
39559
39560 var binaryData;
39561 req.onload = function() {
39562 var arrayBuffer = req.response;
39563 asyncFunc(arrayBuffer);
39564 };
39565 req.send();
30687 }; 39566 };
30688 39567
30689 /** 39568 /**
30690 * returns a Date and a SimileAjax.DateTime granularity value for a given XML time 39569 * returns a Date and a SimileAjax.DateTime granularity value for a given XML time
30691 * @param {String} xmlTime the XML time as String 39570 * @param {String} xmlTime the XML time as String
31160 csvContent += ","; 40039 csvContent += ",";
31161 } 40040 }
31162 csvContent += "\""+val+"\""; 40041 csvContent += "\""+val+"\"";
31163 }); 40042 });
31164 //Names according to CSV import definition 40043 //Names according to CSV import definition
31165 csvContent += ",\"Address\",\"Latitude\",\"Longitude\",\"TimeStamp\""; 40044 csvContent += ",\"Address\",\"Latitude\",\"Longitude\",\"TimeStamp\",\"TimeSpan:begin\",\"TimeSpan:end\"";
31166 csvContent += "\n"; 40045 csvContent += "\n";
31167 40046
31168 var isFirstRow = true; 40047 var isFirstRow = true;
31169 $(GeoTemConfig.datasets[index].objects).each(function(){ 40048 $(GeoTemConfig.datasets[index].objects).each(function(){
31170 var elem = this; 40049 var elem = this;
31188 if (isFirst){ 40067 if (isFirst){
31189 isFirst = false; 40068 isFirst = false;
31190 } else { 40069 } else {
31191 csvContent += ","; 40070 csvContent += ",";
31192 } 40071 }
31193 csvContent += "\""+elem.tableContent[val]+"\""; 40072 csvContent += "\""+GeoTemConfig.quoteVal(elem.tableContent[val])+"\"";
31194 }); 40073 });
31195 40074
31196 csvContent += ","; 40075 csvContent += ",";
31197 csvContent += "\""; 40076 csvContent += "\"";
31198 if (elem.isGeospatial){ 40077 if (elem.isGeospatial){
31219 if ( (elem.isTemporal) && (typeof elem.getDate(0) !== "undefined") ){ 40098 if ( (elem.isTemporal) && (typeof elem.getDate(0) !== "undefined") ){
31220 //TODO: not supported in IE8 switch to moment.js 40099 //TODO: not supported in IE8 switch to moment.js
31221 csvContent += elem.getDate(0).toISOString(); 40100 csvContent += elem.getDate(0).toISOString();
31222 } 40101 }
31223 csvContent += "\""; 40102 csvContent += "\"";
40103
40104 csvContent += ",";
40105 if (elem.isFuzzyTemporal){
40106 //TODO: not supported in IE8 switch to moment.js
40107 csvContent += "\""+elem.TimeSpanBegin.format()+"\",\""+elem.TimeSpanEnd.format()+"\"";
40108 } else {
40109 csvContent += "\"\",\"\"";
40110 }
31224 }); 40111 });
31225 40112
31226 return(csvContent); 40113 return(csvContent);
31227 }; 40114 };
31228 /** 40115 /**
32678 binningSelection : false, // show/hide binning algorithms dropdown 41565 binningSelection : false, // show/hide binning algorithms dropdown
32679 mapSelectionTools : true, // show/hide map selector tools 41566 mapSelectionTools : true, // show/hide map selector tools
32680 dataInformation : true, // show/hide data information 41567 dataInformation : true, // show/hide data information
32681 overlayVisibility : false, // initial visibility of additional overlays 41568 overlayVisibility : false, // initial visibility of additional overlays
32682 //proxyHost : 'php/proxy.php?address=', //required for selectCountry feature, if the requested GeoServer and GeoTemCo are NOT on the same server 41569 //proxyHost : 'php/proxy.php?address=', //required for selectCountry feature, if the requested GeoServer and GeoTemCo are NOT on the same server
32683 placenameTagsStyle : 'value' // the style of the placenames "surrounding" a circle on hover. 'zoom' for tags based on zoom level (old behaviour), 'value' for new value-based 41570 placenameTagsStyle : 'value', // the style of the placenames "surrounding" a circle on hover. 'zoom' for tags based on zoom level (old behaviour), 'value' for new value-based
41571 hideUnselected : false //hide unselected circles (features) on highlight/selection
32684 41572
32685 }; 41573 };
32686 if ( typeof options != 'undefined') { 41574 if ( typeof options != 'undefined') {
32687 $.extend(this.options, options); 41575 $.extend(this.options, options);
32688 } 41576 }
34206 43094
34207 /** 43095 /**
34208 * updates the the object layer of the map after selections had been executed in timeplot or table or zoom level has changed 43096 * updates the the object layer of the map after selections had been executed in timeplot or table or zoom level has changed
34209 */ 43097 */
34210 highlightChanged : function(mapObjects) { 43098 highlightChanged : function(mapObjects) {
43099 var hideEmptyCircles = false;
43100
43101 if (this.config.options.hideUnselected){
43102 var overallCnt = 0;
43103 for (var i in mapObjects){
43104 overallCnt += mapObjects[i].length;
43105 }
43106 if (overallCnt > 0){
43107 hideEmptyCircles = true;
43108 }
43109 }
43110
34211 if( !GeoTemConfig.highlightEvents ){ 43111 if( !GeoTemConfig.highlightEvents ){
34212 return; 43112 return;
34213 } 43113 }
34214 this.mds.clearOverlay(); 43114 this.mds.clearOverlay();
34215 if (this.selection.valid()) { 43115 if (this.selection.valid()) {
34219 } 43119 }
34220 var points = this.mds.getObjectsByZoom(); 43120 var points = this.mds.getObjectsByZoom();
34221 var polygon = this.openlayersMap.getExtent().toGeometry(); 43121 var polygon = this.openlayersMap.getExtent().toGeometry();
34222 for (var i in points ) { 43122 for (var i in points ) {
34223 for (var j in points[i] ) { 43123 for (var j in points[i] ) {
43124 var point = points[i][j];
43125
43126 if (hideEmptyCircles){
43127 point.feature.style.display = 'none';
43128 } else {
43129 point.feature.style.display = '';
43130 }
43131
34224 this.updatePoint(points[i][j], polygon); 43132 this.updatePoint(points[i][j], polygon);
34225 } 43133 }
34226 } 43134 }
34227 this.displayConnections(); 43135 this.displayConnections();
43136 this.objectLayer.redraw();
34228 }, 43137 },
34229 43138
34230 selectionChanged : function(selection) { 43139 selectionChanged : function(selection) {
34231 if( !GeoTemConfig.selectionEvents ){ 43140 if( !GeoTemConfig.selectionEvents ){
34232 return; 43141 return;
34643 } else if (zoom <= 8) { 43552 } else if (zoom <= 8) {
34644 return 2; 43553 return 2;
34645 } else { 43554 } else {
34646 return 3; 43555 return 3;
34647 } 43556 }
34648 } 43557 },
43558
43559
43560 getConfig : function(inquiringWidget){
43561 var mapWidget = this;
43562 var config = {};
43563
43564 //save widget specific configurations here into the config object
43565 config.mapIndex = this.baselayerIndex;
43566 config.mapCenter = this.openlayersMap.center;
43567 config.mapZoom = this.openlayersMap.zoom;
43568 //send config to iquiring widget
43569 if (typeof inquiringWidget.sendConfig !== "undefined"){
43570 inquiringWidget.sendConfig({widgetName: "map", 'config': config});
43571 }
43572 },
43573
43574 setConfig : function(configObj){
43575 var mapWidget = this;
43576
43577 if (configObj.widgetName === "map"){
43578 var config = configObj.config;
43579
43580 //set widgets configuration provided by config
43581 this.setMap(config.mapIndex);
43582 this.gui.mapTypeDropdown.setEntry(config.mapIndex);
43583
43584 this.openlayersMap.setCenter(config.mapCenter);
43585 this.openlayersMap.zoomTo(config.mapZoom);
43586 }
43587 },
43588
34649 } 43589 }
34650 /* 43590 /*
34651 * TimeConfig.js 43591 * TimeConfig.js
34652 * 43592 *
34653 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. 43593 * Copyright (c) 2012, Stefan Jänicke. All rights reserved.
36483 tableTab.onclick = function() { 45423 tableTab.onclick = function() {
36484 tableWidget.selectTable(index); 45424 tableWidget.selectTable(index);
36485 } 45425 }
36486 var tableNameDiv = document.createElement('div'); 45426 var tableNameDiv = document.createElement('div');
36487 $(tableNameDiv).append(name); 45427 $(tableNameDiv).append(name);
45428 $(tableNameDiv).dblclick(function() {
45429 var n = $(tableNameDiv).text();
45430 $(tableNameDiv).empty();
45431 var nameInput = $('<input type="text" name="nameinput" value="'+n+'" />');
45432 $(tableNameDiv).append(nameInput);
45433 $(nameInput).focus();
45434 $(nameInput).focusout(function() {
45435 var newname = $(nameInput).val();
45436 $(tableNameDiv).empty();
45437 $(tableNameDiv).append(newname);
45438 dataSet.label = newname;
45439 });
45440 $(nameInput).keypress(function(event) {
45441 if (event.which == 13) {
45442 var newname = $(nameInput).val();
45443 $(tableNameDiv).empty();
45444 $(tableNameDiv).append(newname);
45445 dataSet.label = newname;
45446 }
45447 });
45448 });
36488 45449
36489 if (typeof dataSet.url !== "undefined"){ 45450 if (typeof dataSet.url !== "undefined"){
36490 var tableLinkDiv = document.createElement('a'); 45451 var tableLinkDiv = document.createElement('a');
36491 tableLinkDiv.title = dataSet.url; 45452 tableLinkDiv.title = dataSet.url;
36492 tableLinkDiv.href = dataSet.url; 45453 tableLinkDiv.href = dataSet.url;
36832 if( this.tables.length > 0 ){ 45793 if( this.tables.length > 0 ){
36833 this.tables[this.activeTable].resetElements(); 45794 this.tables[this.activeTable].resetElements();
36834 this.tables[this.activeTable].reset(); 45795 this.tables[this.activeTable].reset();
36835 this.tables[this.activeTable].update(); 45796 this.tables[this.activeTable].update();
36836 } 45797 }
36837 } 45798 },
45799
45800
45801 getConfig : function(inquiringWidget){
45802 var tableWidget = this;
45803 var config = {};
45804
45805 //save widget specific configurations here into the config object
45806
45807 //send config to iquiring widget
45808 if (typeof inquiringWidget.sendConfig !== "undefined"){
45809 inquiringWidget.sendConfig({widgetName: "table", 'config': config});
45810 }
45811 },
45812
45813 setConfig : function(configObj){
45814 var tableWidget = this;
45815
45816 if (configObj.widgetName === "table"){
45817 var config = configObj.config;
45818
45819 //set widgets configuration provided by config
45820
45821 }
45822 },
45823
36838 } 45824 }
36839 /* 45825 /*
36840 * Table.js 45826 * Table.js
36841 * 45827 *
36842 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. 45828 * Copyright (c) 2012, Stefan Jänicke. All rights reserved.
37648 this.addKMLLoader(); 46634 this.addKMLLoader();
37649 this.addKMZLoader(); 46635 this.addKMZLoader();
37650 this.addCSVLoader(); 46636 this.addCSVLoader();
37651 this.addLocalKMLLoader(); 46637 this.addLocalKMLLoader();
37652 this.addLocalCSVLoader(); 46638 this.addLocalCSVLoader();
46639 this.addLocalXLSXLoader();
37653 46640
37654 // trigger change event on the select so 46641 // trigger change event on the select so
37655 // that only the first loader div will be shown 46642 // that only the first loader div will be shown
37656 $(this.parent.gui.loaderTypeSelect).change(); 46643 $(this.parent.gui.loaderTypeSelect).change();
37657 }, 46644 },
37960 if (dataSet != null) 46947 if (dataSet != null)
37961 dataLoader.distributeDataset(dataSet); 46948 dataLoader.distributeDataset(dataSet);
37962 },this)); 46949 },this));
37963 46950
37964 $(this.parent.gui.loaders).append(this.localStorageLoaderTab); 46951 $(this.parent.gui.loaders).append(this.localStorageLoaderTab);
37965 } 46952 },
46953
46954 addLocalXLSXLoader : function() {
46955 //taken from http://oss.sheetjs.com/js-xlsx/
46956 var fixdata = function(data) {
46957 var o = "", l = 0, w = 10240;
46958 for(; l<data.byteLength/w; ++l) o+=String.fromCharCode.apply(null,new Uint8Array(data.slice(l*w,l*w+w)));
46959 o+=String.fromCharCode.apply(null, new Uint8Array(data.slice(o.length)));
46960 return o;
46961 }
46962
46963 $(this.parent.gui.loaderTypeSelect).append("<option value='LocalXLSXLoader'>local XLS/XLSX File</option>");
46964
46965 this.LocalXLSXLoader = document.createElement("div");
46966 $(this.LocalXLSXLoader).attr("id","LocalXLSXLoader");
46967
46968 this.xlsxFile = document.createElement("input");
46969 $(this.xlsxFile).attr("type","file");
46970 $(this.LocalXLSXLoader).append(this.xlsxFile);
46971
46972 this.loadLocalXLSXButton = document.createElement("button");
46973 $(this.loadLocalXLSXButton).text("load XLS/XLSX");
46974 $(this.LocalXLSXLoader).append(this.loadLocalXLSXButton);
46975
46976 $(this.loadLocalXLSXButton).click($.proxy(function(){
46977 var filelist = $(this.xlsxFile).get(0).files;
46978 if (filelist.length > 0){
46979 var file = filelist[0];
46980 var fileName = file.name;
46981 var reader = new FileReader();
46982
46983 reader.onloadend = ($.proxy(function(theFile) {
46984 return function(e) {
46985 var workbook;
46986 var json;
46987 if (fileName.toLowerCase().indexOf("xlsx")!=-1){
46988 workbook = XLSX.read(btoa(fixdata(reader.result)), {type: 'base64'});
46989 var csv = XLSX.utils.sheet_to_csv(workbook.Sheets[workbook.SheetNames[0]]);
46990 var json = GeoTemConfig.convertCsv(csv);
46991 } else {
46992 workbook = XLS.read(btoa(fixdata(reader.result)), {type: 'base64'});
46993 var csv = XLS.utils.sheet_to_csv(workbook.Sheets[workbook.SheetNames[0]]);
46994 var json = GeoTemConfig.convertCsv(csv);
46995 }
46996
46997 var dataSet = new Dataset(GeoTemConfig.loadJson(json), fileName);
46998 if (dataSet != null)
46999 this.distributeDataset(dataSet);
47000 };
47001 }(file),this));
47002
47003 reader.readAsArrayBuffer(file);
47004 }
47005 },this));
47006
47007 $(this.parent.gui.loaders).append(this.LocalXLSXLoader);
47008 },
37966 }; 47009 };
37967 /* 47010 /*
37968 * DataloaderConfig.js 47011 * DataloaderConfig.js
37969 * 47012 *
37970 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. 47013 * Copyright (c) 2013, Sebastian Kruse. All rights reserved.
38093 47136
38094 this.options = (new DataloaderConfig(options)).options; 47137 this.options = (new DataloaderConfig(options)).options;
38095 this.gui = new DataloaderGui(this, div, this.options); 47138 this.gui = new DataloaderGui(this, div, this.options);
38096 47139
38097 this.dataLoader = new Dataloader(this); 47140 this.dataLoader = new Dataloader(this);
47141
47142 this.datasets = [];
38098 } 47143 }
38099 47144
38100 DataloaderWidget.prototype = { 47145 DataloaderWidget.prototype = {
38101 47146
38102 initWidget : function() { 47147 initWidget : function() {
38135 }, 47180 },
38136 47181
38137 reset : function() { 47182 reset : function() {
38138 }, 47183 },
38139 47184
38140 loadFromURL : function() { 47185 loadRenames : function(){
38141 var dataLoaderWidget = this;
38142 //using jQuery-URL-Parser (https://github.com/skruse/jQuery-URL-Parser)
38143 var datasets = [];
38144 $.each($.url().param(),function(paramName, paramValue){
38145 //startsWith and endsWith defined in SIMILE Ajax (string.js)
38146 var fileName = dataLoaderWidget.dataLoader.getFileName(paramValue);
38147 var origURL = paramValue;
38148 if (typeof GeoTemConfig.proxy != 'undefined')
38149 paramValue = GeoTemConfig.proxy + paramValue;
38150 if (paramName.toLowerCase().startsWith("kml")){
38151 var kmlDoc = GeoTemConfig.getKml(paramValue);
38152 var dataSet = new Dataset(GeoTemConfig.loadKml(kmlDoc), fileName, origURL);
38153 if (dataSet != null){
38154 var datasetID = parseInt(paramName.substr(3));
38155 if (!isNaN(datasetID)){
38156 datasets[datasetID] = dataSet;
38157 } else {
38158 datasets.push(dataSet);
38159 }
38160 }
38161 }
38162 else if (paramName.toLowerCase().startsWith("csv")){
38163 var json = GeoTemConfig.getCsv(paramValue);
38164 var dataSet = new Dataset(GeoTemConfig.loadJson(json), fileName, origURL);
38165 if (dataSet != null){
38166 var datasetID = parseInt(paramName.substr(3));
38167 if (!isNaN(datasetID)){
38168 datasets[datasetID] = dataSet;
38169 } else {
38170 datasets.push(dataSet);
38171 }
38172 }
38173 }
38174 else if (paramName.toLowerCase().startsWith("json")){
38175 var json = GeoTemConfig.getJson(paramValue);
38176 var dataSet = new Dataset(GeoTemConfig.loadJson(json), fileName, origURL);
38177 if (dataSet != null){
38178 var datasetID = parseInt(paramName.substr(4));
38179 if (!isNaN(datasetID)){
38180 datasets[datasetID] = dataSet;
38181 } else {
38182 datasets.push(dataSet);
38183 }
38184 }
38185 }
38186 else if (paramName.toLowerCase().startsWith("local")){
38187 var csv = $.remember({name:encodeURIComponent(origURL)});
38188 //TODO: this is a bad idea and will be changed upon having a better
38189 //usage model for local stored data
38190 var fileName = origURL.substring("GeoBrowser_dataset_".length);
38191 var json = GeoTemConfig.convertCsv(csv);
38192 var dataSet = new Dataset(GeoTemConfig.loadJson(json), fileName, origURL, "local");
38193 if (dataSet != null){
38194 var datasetID = parseInt(paramName.substr(5));
38195 if (!isNaN(datasetID)){
38196 datasets[datasetID] = dataSet;
38197 } else {
38198 datasets.push(dataSet);
38199 }
38200 }
38201 }
38202 });
38203 //load (optional!) attribute renames 47186 //load (optional!) attribute renames
38204 //each rename param is {latitude:..,longitude:..,place:..,date:..,timeSpanBegin:..,timeSpanEnd:..} 47187 //each rename param is {latitude:..,longitude:..,place:..,date:..,timeSpanBegin:..,timeSpanEnd:..}
38205 //examples: 47188 //examples:
38206 // &rename1={"latitude":"lat1","longitude":"lon1"} 47189 // &rename1={"latitude":"lat1","longitude":"lon1"}
38207 // &rename2=[{"latitude":"lat1","longitude":"lon1"},{"latitude":"lat2","longitude":"lon2"}] 47190 // &rename2=[{"latitude":"lat1","longitude":"lon1"},{"latitude":"lat2","longitude":"lon2"}]
47191 var dataLoaderWidget = this;
47192 var datasets = dataLoaderWidget.datasets;
38208 $.each($.url().param(),function(paramName, paramValue){ 47193 $.each($.url().param(),function(paramName, paramValue){
38209 if (paramName.toLowerCase().startsWith("rename")){ 47194 if (paramName.toLowerCase().startsWith("rename")){
38210 var datasetID = parseInt(paramName.substr(6)); 47195 var datasetID = parseInt(paramName.replace(/\D/g,''));
38211 var dataset; 47196 var dataset;
38212 if (isNaN(datasetID)){ 47197 if (isNaN(datasetID)){
38213 var dataset; 47198 var dataset;
38214 for (datasetID in datasets){ 47199 for (datasetID in datasets){
38215 break; 47200 break;
38286 renameFunc(0,renames.latitude,renames.longitude,renames.place,renames.date, 47271 renameFunc(0,renames.latitude,renames.longitude,renames.place,renames.date,
38287 renames.timeSpanBegin,renames.timeSpanEnd,renames.index); 47272 renames.timeSpanBegin,renames.timeSpanEnd,renames.index);
38288 } 47273 }
38289 } 47274 }
38290 }); 47275 });
47276 },
47277
47278 loadFilters : function(){
38291 //load (optional!) filters 47279 //load (optional!) filters
38292 //those will create a new(!) dataset, that only contains the filtered IDs 47280 //those will create a new(!) dataset, that only contains the filtered IDs
47281 var dataLoaderWidget = this;
47282 var datasets = dataLoaderWidget.datasets;
38293 $.each($.url().param(),function(paramName, paramValue){ 47283 $.each($.url().param(),function(paramName, paramValue){
38294 //startsWith and endsWith defined in SIMILE Ajax (string.js) 47284 //startsWith and endsWith defined in SIMILE Ajax (string.js)
38295 if (paramName.toLowerCase().startsWith("filter")){ 47285 if (paramName.toLowerCase().startsWith("filter")){
38296 var datasetID = parseInt(paramName.substr(6)); 47286 var datasetID = parseInt(paramName.replace(/\D/g,''));
38297 var dataset; 47287 var dataset;
38298 if (isNaN(datasetID)){ 47288 if (isNaN(datasetID)){
38299 var dataset; 47289 var dataset;
38300 for (datasetID in datasets){ 47290 for (datasetID in datasets){
38301 break; 47291 break;
38326 } else { 47316 } else {
38327 filterValues(paramValue); 47317 filterValues(paramValue);
38328 } 47318 }
38329 47319
38330 } 47320 }
38331 }); 47321 });
47322 },
47323
47324 loadColors : function(){
38332 //Load the (optional!) dataset colors 47325 //Load the (optional!) dataset colors
47326 var dataLoaderWidget = this;
47327 var datasets = dataLoaderWidget.datasets;
38333 $.each($.url().param(),function(paramName, paramValue){ 47328 $.each($.url().param(),function(paramName, paramValue){
38334 if (paramName.toLowerCase().startsWith("color")){ 47329 if (paramName.toLowerCase().startsWith("color")){
38335 //color is 1-based, index is 0-based! 47330 //color is 1-based, index is 0-based!
38336 var datasetID = parseInt(paramName.substring("color".length))-1; 47331 var datasetID = parseInt(paramName.replace(/\D/g,''));
38337 if (datasets.length > datasetID){ 47332 if (datasets.length > datasetID){
38338 if (typeof datasets[datasetID].color === "undefined"){ 47333 if (typeof datasets[datasetID].color === "undefined"){
38339 var color = new Object(); 47334 var color = new Object();
38340 var colorsSelectedUnselected = paramValue.split(","); 47335 var colorsSelectedUnselected = paramValue.split(",");
38341 if (colorsSelectedUnselected.length > 2) 47336 if (colorsSelectedUnselected.length > 2)
38367 47362
38368 datasets[datasetID].color = color; 47363 datasets[datasetID].color = color;
38369 } 47364 }
38370 } 47365 }
38371 } 47366 }
47367 });
47368 },
47369
47370 loadFromURL : function() {
47371 var dataLoaderWidget = this;
47372 dataLoaderWidget.datasets = [];
47373 //using jQuery-URL-Parser (https://github.com/skruse/jQuery-URL-Parser)
47374 var datasets = dataLoaderWidget.datasets;
47375 var parametersHash = $.url().param();
47376 var parametersArray = [];
47377 $.each(parametersHash,function(paramName, paramValue){
47378 parametersArray.push({paramName:paramName, paramValue:paramValue});
38372 }); 47379 });
38373 //delete undefined entries in the array
38374 //(can happen if the sequence given in the URL is not complete
38375 // e.g. kml0=..,kml2=..)
38376 //this also reorders the array, starting with 0
38377 var tempDatasets = [];
38378 for(var index in datasets){
38379 if (datasets[index] instanceof Dataset){
38380 tempDatasets.push(datasets[index]);
38381 }
38382 }
38383 datasets = tempDatasets;
38384 47380
38385 if (datasets.length > 0) 47381 var parseParam = function(paramNr){
38386 dataLoaderWidget.dataLoader.distributeDatasets(datasets); 47382
47383 if (paramNr==parametersArray.length){
47384 dataLoaderWidget.loadRenames();
47385 dataLoaderWidget.loadFilters();
47386 dataLoaderWidget.loadColors();
47387
47388 //delete undefined entries in the array
47389 //(can happen if the sequence given in the URL is not complete
47390 // e.g. kml0=..,kml2=..)
47391 //this also reorders the array, starting with 0
47392 var tempDatasets = [];
47393 for(var index in datasets){
47394 if (datasets[index] instanceof Dataset){
47395 tempDatasets.push(datasets[index]);
47396 }
47397 }
47398 datasets = tempDatasets;
47399
47400 if (datasets.length > 0){
47401 dataLoaderWidget.dataLoader.distributeDatasets(datasets);
47402 }
47403 return;
47404 }
47405
47406 var paramName = parametersArray[paramNr].paramName;
47407 var paramValue = parametersArray[paramNr].paramValue;
47408
47409 var datasetID = parseInt(paramName.replace(/\D/g,''));
47410
47411 //startsWith and endsWith defined in SIMILE Ajax (string.js)
47412 var fileName = dataLoaderWidget.dataLoader.getFileName(paramValue);
47413 var origURL = paramValue;
47414 if (typeof GeoTemConfig.proxy != 'undefined')
47415 paramValue = GeoTemConfig.proxy + paramValue;
47416 if (paramName.toLowerCase().startsWith("kml")){
47417 GeoTemConfig.getKml(paramValue, function(kmlDoc){
47418 var dataSet = new Dataset(GeoTemConfig.loadKml(kmlDoc), fileName, origURL);
47419 if (dataSet != null){
47420 if (!isNaN(datasetID)){
47421 datasets[datasetID] = dataSet;
47422 } else {
47423 datasets.push(dataSet);
47424 }
47425 }
47426 setTimeout(function(){parseParam(paramNr+1)},1);
47427 });
47428 }
47429 else if (paramName.toLowerCase().startsWith("csv")){
47430 GeoTemConfig.getCsv(paramValue,function(json){
47431 var dataSet = new Dataset(GeoTemConfig.loadJson(json), fileName, origURL);
47432 if (dataSet != null){
47433 if (!isNaN(datasetID)){
47434 datasets[datasetID] = dataSet;
47435 } else {
47436 datasets.push(dataSet);
47437 }
47438 }
47439 setTimeout(function(){parseParam(paramNr+1)},1);
47440 });
47441 }
47442 else if (paramName.toLowerCase().startsWith("json")){
47443 GeoTemConfig.getJson(paramValue,function(json ){
47444 var dataSet = new Dataset(GeoTemConfig.loadJson(json), fileName, origURL);
47445 if (dataSet != null){
47446 if (!isNaN(datasetID)){
47447 datasets[datasetID] = dataSet;
47448 } else {
47449 datasets.push(dataSet);
47450 }
47451 }
47452 setTimeout(function(){parseParam(paramNr+1)},1);
47453 });
47454 }
47455 else if (paramName.toLowerCase().startsWith("local")){
47456 var csv = $.remember({name:encodeURIComponent(origURL)});
47457 //TODO: this is a bad idea and will be changed upon having a better
47458 //usage model for local stored data
47459 var fileName = origURL.substring("GeoBrowser_dataset_".length);
47460 var json = GeoTemConfig.convertCsv(csv);
47461 var dataSet = new Dataset(GeoTemConfig.loadJson(json), fileName, origURL, "local");
47462 if (dataSet != null){
47463 if (!isNaN(datasetID)){
47464 datasets[datasetID] = dataSet;
47465 } else {
47466 datasets.push(dataSet);
47467 }
47468 }
47469 setTimeout(function(){parseParam(paramNr+1)},1);
47470 } else if (paramName.toLowerCase().startsWith("xls")){
47471 GeoTemConfig.getBinary(paramValue,function(binaryData){
47472 var data = new Uint8Array(binaryData);
47473 var arr = new Array();
47474 for(var i = 0; i != data.length; ++i){
47475 arr[i] = String.fromCharCode(data[i]);
47476 }
47477
47478 var workbook;
47479 var json;
47480 if (paramName.toLowerCase().startsWith("xlsx")){
47481 workbook = XLSX.read(arr.join(""), {type:"binary"});
47482 var csv = XLSX.utils.sheet_to_csv(workbook.Sheets[workbook.SheetNames[0]]);
47483 var json = GeoTemConfig.convertCsv(csv);
47484 } else {
47485 workbook = XLS.read(arr.join(""), {type:"binary"});
47486 var csv = XLS.utils.sheet_to_csv(workbook.Sheets[workbook.SheetNames[0]]);
47487 var json = GeoTemConfig.convertCsv(csv);
47488 }
47489
47490 var dataSet = new Dataset(GeoTemConfig.loadJson(json), fileName, origURL);
47491 if (dataSet != null){
47492 if (!isNaN(datasetID)){
47493 datasets[datasetID] = dataSet;
47494 } else {
47495 datasets.push(dataSet);
47496 }
47497 }
47498 setTimeout(function(){parseParam(paramNr+1)},1);
47499 });
47500 } else {
47501 setTimeout(function(){parseParam(paramNr+1)},1);
47502 }
47503 };
47504
47505 if (parametersArray.length>0){
47506 parseParam(0)
47507 }
38387 } 47508 }
38388 }; 47509 };
38389 /* 47510 /*
38390 * FuzzyTimelineConfig.js 47511 * FuzzyTimelineConfig.js
38391 * 47512 *
39152 weight = this.weight * ticks.firstTickPercentage; 48273 weight = this.weight * ticks.firstTickPercentage;
39153 else if (i == ticks.lastTick) 48274 else if (i == ticks.lastTick)
39154 weight = this.weight * ticks.lastTickPercentage; 48275 weight = this.weight * ticks.lastTickPercentage;
39155 else 48276 else
39156 weight = this.weight; 48277 weight = this.weight;
39157
39158 weight = this.weight;
39159 } 48278 }
39160 48279
39161 chartDataCounter[i] += weight; 48280 chartDataCounter[i] += weight;
39162 //add this object to the hash 48281 //add this object to the hash
39163 if (typeof objectHash[i] === "undefined") 48282 if (typeof objectHash[i] === "undefined")
39928 moment.duration(10000, 'years'), 49047 moment.duration(10000, 'years'),
39929 ]; 49048 ];
39930 var overallSpan = rangeSlider.parent.overallMax-rangeSlider.parent.overallMin; 49049 var overallSpan = rangeSlider.parent.overallMax-rangeSlider.parent.overallMin;
39931 //only add spans that are not too small for the data 49050 //only add spans that are not too small for the data
39932 for (var i = 0; i < fixedSpans.length; i++){ 49051 for (var i = 0; i < fixedSpans.length; i++){
39933 if ( (fixedSpans[i].asMilliseconds() > (smallestSpan.asMilliseconds() * 0.5)) && 49052 if ( (fixedSpans[i].asMilliseconds() > (smallestSpan.asMilliseconds() * 0.25)) &&
39934 (fixedSpans[i].asMilliseconds() < overallSpan) 49053 (fixedSpans[i].asMilliseconds() < overallSpan)
39935 && 49054 &&
39936 ( 49055 (
39937 rangeSlider.parent.options.showAllPossibleSpans || 49056 rangeSlider.parent.options.showAllPossibleSpans ||
39938 ((rangeSlider.parent.overallMax-rangeSlider.parent.overallMin)/fixedSpans[i]<rangeSlider.options.maxBars) 49057 ((rangeSlider.parent.overallMax-rangeSlider.parent.overallMin)/fixedSpans[i]<rangeSlider.options.maxBars)
40716 $(fuzzyTimeline.handles).each(function(){ 49835 $(fuzzyTimeline.handles).each(function(){
40717 var handle = this; 49836 var handle = this;
40718 handle.x1 = handle.x1 * (zoomFactor/oldZoomFactor); 49837 handle.x1 = handle.x1 * (zoomFactor/oldZoomFactor);
40719 handle.x2 = handle.x2 * (zoomFactor/oldZoomFactor); 49838 handle.x2 = handle.x2 * (zoomFactor/oldZoomFactor);
40720 }); 49839 });
40721 } 49840 },
49841
49842 getConfig : function(inquiringWidget){
49843 var fuzzyTimeline = this;
49844 var config = {};
49845
49846 //create handle copy
49847 var handleCopy = JSON.parse( JSON.stringify( fuzzyTimeline.handles ) );
49848 config.handles = handleCopy;
49849
49850 config.viewMode = fuzzyTimeline.viewMode;
49851
49852 config.rangeDropdownVal = $(fuzzyTimeline.rangeSlider.rangeDropdown).val();
49853 config.rangeStartVal = $(fuzzyTimeline.rangeSlider.rangeStart).val();
49854
49855 //send config to iquiring widget
49856 if (typeof inquiringWidget.sendConfig !== "undefined"){
49857 inquiringWidget.sendConfig({widgetName: "fuzzyTimeline", 'config': config});
49858 }
49859 },
49860
49861 setConfig : function(configObj){
49862 var fuzzyTimeline = this;
49863
49864 if (configObj.widgetName === "fuzzyTimeline"){
49865 var config = configObj.config;
49866
49867 $(fuzzyTimeline.rangeSlider.rangeDropdown).val(config.rangeDropdownVal);
49868 $(fuzzyTimeline.rangeSlider.rangeDropdown).change();
49869 fuzzyTimeline.switchViewMode(config.viewMode);
49870
49871 $(fuzzyTimeline.rangeSlider.rangeStart).val(config.rangeStartVal);
49872 $(fuzzyTimeline.rangeSlider.rangeStart).change();
49873
49874 //clear handles
49875 fuzzyTimeline.clearHandles();
49876
49877 //create handle copy
49878 var handleCopy = JSON.parse( JSON.stringify( config.handles ) );
49879 fuzzyTimeline.handles = handleCopy;
49880
49881 // redraw handles
49882 fuzzyTimeline.drawHandles();
49883
49884 // select elements
49885 $(fuzzyTimeline.handles).each(function(){
49886 var handle = this;
49887 fuzzyTimeline.selectByX(handle.x1, handle.x2)
49888 });
49889 }
49890 },
40722 }; 49891 };
40723 /* 49892 /*
40724 * Overlayloader.js 49893 * Overlayloader.js
40725 * 49894 *
40726 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. 49895 * Copyright (c) 2013, Sebastian Kruse. All rights reserved.
42819 elements.push(this); 51988 elements.push(this);
42820 }); 51989 });
42821 51990
42822 return elements; 51991 return elements;
42823 }, 51992 },
51993
51994 getConfig : function(inquiringWidget){
51995 var pieChartWidget = this;
51996 var config = {};
51997
51998 //save widget specific configurations here into the config object
51999 var pieCharts = [];
52000 for (var i=0; i < pieChartWidget.pieCharts.length; i++){
52001 pieChart = pieChartWidget.pieCharts[i];
52002
52003 if (!pieChart){
52004 continue;
52005 }
52006
52007 if (pieChart.selectionFunction.categories){
52008 pieCharts.push({
52009 watchColumn:pieChart.watchColumn,
52010 watchedDataset:pieChart.watchedDataset,
52011 type:pieChart.selectionFunction.type,
52012 categories:pieChart.selectionFunction.categories
52013 });
52014 } else {
52015 pieCharts.push({
52016 watchColumn:pieChart.watchColumn,
52017 watchedDataset:pieChart.watchedDataset
52018 });
52019 }
52020 }
52021
52022 config.pieCharts = pieCharts;
52023
52024 //send config to iquiring widget
52025 if (typeof inquiringWidget.sendConfig !== "undefined"){
52026 inquiringWidget.sendConfig({widgetName: "pieChart", 'config': config});
52027 }
52028 },
52029
52030 setConfig : function(configObj){
52031 var pieChartWidget = this;
52032
52033 if (configObj.widgetName === "pieChart"){
52034 var config = configObj.config;
52035
52036 //remove old piecharts
52037 pieChartWidget.pieCharts = [];
52038 //set widgets configuration provided by config
52039 for (var i=0; i < config.pieCharts.length; i++){
52040 pieChart = config.pieCharts[i];
52041
52042 if (pieChart.type){
52043 pieChartWidget.addCategorizedPieChart(
52044 pieChart.watchedDataset,
52045 pieChart.watchColumn,
52046 pieChart.type,
52047 pieChart.categories
52048 );
52049 } else {
52050 pieChartWidget.addPieChart(
52051 pieChart.watchedDataset,
52052 pieChart.watchColumn
52053 );
52054 }
52055 }
52056 }
52057 },
52058
42824 }; 52059 };
42825 /* 52060 /*
42826 * Storytelling.js 52061 * Storytelling.js
42827 * 52062 *
42828 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. 52063 * Copyright (c) 2013, Sebastian Kruse. All rights reserved.
43170 highlightChanged : function(objects) { 52405 highlightChanged : function(objects) {
43171 }, 52406 },
43172 52407
43173 selectionChanged : function(selection) { 52408 selectionChanged : function(selection) {
43174 }, 52409 },
52410 };
52411 /*
52412 * Storytellingv2.js
52413 *
52414 * Copyright (c) 2013, Sebastian Kruse. All rights reserved.
52415 *
52416 * This library is free software; you can redistribute it and/or
52417 * modify it under the terms of the GNU Lesser General Public
52418 * License as published by the Free Software Foundation; either
52419 * version 3 of the License, or (at your option) any later version.
52420 *
52421 * This library is distributed in the hope that it will be useful,
52422 * but WITHOUT ANY WARRANTY; without even the implied warranty of
52423 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
52424 * Lesser General Public License for more details.
52425 *
52426 * You should have received a copy of the GNU Lesser General Public
52427 * License along with this library; if not, write to the Free Software
52428 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
52429 * MA 02110-1301 USA
52430 */
52431
52432 /**
52433 * @class Storytellingv2
52434 * Storytelling Version 2
52435 * @author Mike Bretschneider (mike.bretschneider@gmx.de)
52436 *
52437 * @param {HTML object} parent div to append the Storytellingv2 widget
52438 */
52439 function Storytellingv2(parent) {
52440
52441 this.index;
52442 this.storytellingv2 = this;
52443
52444 this.parent = parent;
52445 this.options = parent.options;
52446
52447 this.initialize();
52448 }
52449
52450 Storytellingv2.prototype = {
52451
52452
52453 deleteAllNodes : function(tree) {
52454 var nodes = tree.jstree().get_children_dom('#');
52455 nodes.each(function() {
52456 tree.jstree().delete_node(this);
52457 });
52458 },
52459
52460 findNodesByType : function(tree,type, parent) {
52461 if (parent != undefined) {
52462 parent = tree.jstree().get_node(parent);
52463 } else {
52464 parent = tree.jstree().get_node('#');
52465 }
52466 var nodes = new Array();
52467
52468 if (parent.type == type) {
52469 nodes.push(parent);
52470 }
52471 for (var i = 0; i < parent.children_d.length; i++) {
52472 var n = tree.jstree().get_node(parent.children_d[i]);
52473 if (n.type == type) {
52474 nodes.push(n);
52475 }
52476 }
52477
52478 return nodes;
52479 },
52480
52481
52482 handleFileSelect : function(evt) {
52483
52484 // var storytellingv2 = this;
52485
52486 var file = evt.target.files[0];
52487 var tree = $('#storytellingv2jstree');
52488
52489 var reader = new FileReader();
52490
52491 var deleteAllNodes = function(tree) {
52492 var nodes = tree.jstree().get_children_dom('#');
52493 nodes.each(function() {
52494 tree.jstree().delete_node(this);
52495 });
52496 }
52497
52498 reader.onload = (function(f) {
52499 return function(e) {
52500
52501 var treedata = JSON.parse(e.target.result);
52502 deleteAllNodes(tree);
52503 for (var i = 0; i < treedata.length; i++) {
52504 if (treedata[i].type == 'dataset') {
52505 tree.jstree().create_node(treedata[i].parent,treedata[i]);
52506 var n = tree.jstree().get_node(treedata[i].id);
52507 tree.jstree().set_type(n, 'snapshot');
52508 $('#storytellingv2expert').show();
52509 $('#storytellingv2simple').hide();
52510 } else if (treedata[i].type == 'snapshot') {
52511 treedata[i].type = 'dataset';
52512 tree.jstree().create_node(treedata[i].parent,treedata[i]);
52513 var n = tree.jstree().get_node(treedata[i].id);
52514 tree.jstree().set_type(n, 'snapshot');
52515 $('#storytellingv2expert').show();
52516 $('#storytellingv2simple').hide();
52517 } else {
52518 tree.jstree().create_node(treedata[i].parent,treedata[i]);
52519 }
52520 };
52521
52522 }
52523 })(file);
52524 reader.readAsText(file);
52525 },
52526
52527
52528 makeSimple : function(tree) {
52529 var configs = this.findNodesByType(tree,'config');
52530 var datasets = this.findNodesByType(tree,'dataset');
52531 for (var i = 0; i < datasets.length; i++) {
52532 tree.jstree().set_type(datasets[i], 'snapshot');
52533 datasets[i].li_attr.dataset_text = datasets[i].text;
52534 datasets[i].text = datasets[i].li_attr.snapshot_text || datasets[i].text;
52535 }
52536 for (var i = 0; i < configs.length; i++) {
52537 var c = tree.jstree().get_node(configs[i], true);
52538 $(c).hide();
52539 }
52540 },
52541
52542
52543
52544
52545
52546
52547
52548
52549 defaultSession : function(tree) {
52550 if (tree.jstree().is_leaf('#')) {
52551 tree.jstree().create_node('#', {
52552 'text' : 'Default Session',
52553 'type' : 'session',
52554 'li_attr' : {
52555 'timestamp' : Date.now(),
52556 'description' : 'Default Session'
52557 }
52558 })
52559 };
52560
52561 },
52562
52563 remove : function() {
52564 },
52565
52566 initialize : function() {
52567 },
52568
52569 triggerHighlight : function(columnElement) {
52570 },
52571
52572 triggerSelection : function(columnElement) {
52573 },
52574
52575 deselection : function() {
52576 },
52577
52578 filtering : function() {
52579 },
52580
52581 inverseFiltering : function() {
52582 },
52583
52584 triggerRefining : function() {
52585 },
52586
52587 reset : function() {
52588 },
52589
52590 show : function() {
52591 },
52592
52593 hide : function() {
52594 }
52595 };
52596 /*
52597 * Storytellingv2Config.js
52598 *
52599 * Copyright (c) 2013, Sebastian Kruse. All rights reserved.
52600 *
52601 * This library is free software; you can redistribute it and/or
52602 * modify it under the terms of the GNU Lesser General Public
52603 * License as published by the Free Software Foundation; either
52604 * version 3 of the License, or (at your option) any later version.
52605 *
52606 * This library is distributed in the hope that it will be useful,
52607 * but WITHOUT ANY WARRANTY; without even the implied warranty of
52608 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
52609 * Lesser General Public License for more details.
52610 *
52611 * You should have received a copy of the GNU Lesser General Public
52612 * License along with this library; if not, write to the Free Software
52613 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
52614 * MA 02110-1301 USA
52615 */
52616
52617 /**
52618 * @class Storytellingv2Config
52619 * Storytellingv2 Configuration File
52620 * @author Mike Bretschneider (mike.bretschneider@gmx.de)
52621 */
52622 function Storytellingv2Config(options) {
52623
52624 this.options = {
52625 dariahStorage : false,
52626 localStorage : true
52627 };
52628 if ( typeof options != 'undefined') {
52629 $.extend(this.options, options);
52630 }
52631
52632 };
52633 /*
52634 * Storytellingv2Gui.js
52635 *
52636 * Copyright (c) 2013, Sebastian Kruse. All rights reserved.
52637 *
52638 * This library is free software; you can redistribute it and/or
52639 * modify it under the terms of the GNU Lesser General Public
52640 * License as published by the Free Software Foundation; either
52641 * version 3 of the License, or (at your option) any later version.
52642 *
52643 * This library is distributed in the hope that it will be useful,
52644 * but WITHOUT ANY WARRANTY; without even the implied warranty of
52645 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
52646 * Lesser General Public License for more details.
52647 *
52648 * You should have received a copy of the GNU Lesser General Public
52649 * License along with this library; if not, write to the Free Software
52650 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
52651 * MA 02110-1301 USA
52652 */
52653
52654 /**
52655 * @class StorytellingGui
52656 * Storytellingv2 GUI Implementation
52657 * @author Mike Bretschneider (mike.bretschneider@gmx.de)
52658 *
52659 * @param {Storytellingv2Widget} parent Storytellingv2 widget object
52660 * @param {HTML object} div parent div to append the Storytellingv2 gui
52661 * @param {JSON} options Storytellingv2 configuration
52662 */
52663 function Storytellingv2Gui(storytellingv2, div, options) {
52664
52665 this.parent = storytellingv2;
52666 var storytellingv2Gui = this;
52667
52668 storytellingv2Gui.storytellingv2Container = document.createElement('div');
52669 $(div).append(storytellingv2Gui.storytellingv2Container);
52670 storytellingv2Gui.storytellingv2Container.style.position = 'relative';
52671 };
52672
52673 Storytellingv2Gui.prototype = {
52674
52675 initGui : function() {
52676
52677 var storytellingv2Gui = this;
52678 var storytellingv2Widget = storytellingv2Gui.parent;
52679 var storytellingv2 = storytellingv2Widget.storytellingv2;
52680
52681 if (storytellingv2Gui.tree == undefined) {
52682 storytellingv2Gui.initTree();
52683 }
52684 },
52685
52686 initTree : function() {
52687
52688 var storytellingv2Gui = this;
52689 var storytellingv2Widget = storytellingv2Gui.parent;
52690 var storytellingv2 = storytellingv2Widget.storytellingv2;
52691
52692 $(storytellingv2Gui.storytellingv2Container).empty();
52693
52694 storytellingv2Gui.tree = $('<div style="border: 2px solid; padding: 5px; float: left;" id="storytellingv2jstree"><ul></ul></div>');
52695 storytellingv2Gui.tree.jstree({
52696 'core' : {
52697 'check_callback' : true,
52698 },
52699 'plugins' : [ 'dnd', 'types' ],
52700 'types' : {
52701 '#' : {
52702 valid_children : ['session']
52703 },
52704 'session' : {
52705 valid_children : ['dataset', 'config']
52706 },
52707 'dataset' : {
52708 'valid_children' : ['config'],
52709 'icon' : 'lib/jstree/themes/default/dataset.png'
52710 },
52711 'snapshot' : {
52712 'valid_children' : ['config'],
52713 'icon' : 'lib/jstree/themes/default/snapshot.png'
52714 },
52715 'config' : {
52716 'valid_children' : ['config'],
52717 'icon' : 'lib/jstree/themes/default/filter.png'
52718 }
52719 }
52720 });
52721
52722 storytellingv2Gui.tree.on('open_node.jstree', function(e, data) {
52723 var node = data.node;
52724 if (node.type == 'snapshot') {
52725 storytellingv2Gui.tree.jstree().close_node(node, false);
52726 }
52727
52728 });
52729
52730 storytellingv2Gui.menu = $('<div style="float: left;"></div>');
52731 storytellingv2Gui.importexportsubmenu = $('<div style="border: 2px solid; margin: 2px; padding: 5px;"></div>');
52732
52733 storytellingv2Gui.addImportButton();
52734 storytellingv2Gui.addExportButton();
52735 storytellingv2Gui.addResetButton();
52736 storytellingv2Gui.addExpertButton();
52737 storytellingv2Gui.addSimpleButton();
52738
52739 storytellingv2Gui.simplebutton.hide();
52740 $(storytellingv2Gui.importexportsubmenu).append(storytellingv2Gui.importbutton);
52741 $(storytellingv2Gui.importexportsubmenu).append(storytellingv2Gui.exportbutton);
52742 $(storytellingv2Gui.importexportsubmenu).append(storytellingv2Gui.resetbutton);
52743 $(storytellingv2Gui.importexportsubmenu).append(storytellingv2Gui.expertbutton);
52744 $(storytellingv2Gui.importexportsubmenu).append(storytellingv2Gui.simplebutton);
52745 $(storytellingv2Gui.importexportsubmenu).append(storytellingv2Gui.importfile);
52746
52747 storytellingv2Gui.treemanipulationsubmenu = $('<div style="border: 2px solid; margin: 2px; padding: 5px;"></div>');
52748
52749 storytellingv2Gui.addNewButton();
52750 storytellingv2Gui.addSnapshotButton();
52751 storytellingv2Gui.addRestoreButton();
52752 storytellingv2Gui.addDeleteButton();
52753 storytellingv2Gui.addEditButton();
52754 storytellingv2Gui.addBackwardButton();
52755 storytellingv2Gui.addForwardButton();
52756
52757 $(storytellingv2Gui.treemanipulationsubmenu).append(storytellingv2Gui.newbutton);
52758 $(storytellingv2Gui.treemanipulationsubmenu).append(storytellingv2Gui.snapshotbutton);
52759 $(storytellingv2Gui.treemanipulationsubmenu).append(storytellingv2Gui.restorebutton);
52760 $(storytellingv2Gui.treemanipulationsubmenu).append(storytellingv2Gui.deletebutton);
52761 $(storytellingv2Gui.treemanipulationsubmenu).append(storytellingv2Gui.editbutton);
52762 $(storytellingv2Gui.treemanipulationsubmenu).append(storytellingv2Gui.backwardbutton);
52763 $(storytellingv2Gui.treemanipulationsubmenu).append(storytellingv2Gui.forwardbutton);
52764
52765 storytellingv2Gui.addMetadata();
52766
52767 storytellingv2Gui.newbutton.hide();
52768 $(storytellingv2Gui.storytellingv2Container).append(storytellingv2Gui.tree);
52769 $(storytellingv2Gui.menu).append(storytellingv2Gui.importexportsubmenu);
52770 $(storytellingv2Gui.menu).append(storytellingv2Gui.treemanipulationsubmenu);
52771 $(storytellingv2Gui.menu).append(storytellingv2Gui.metadata);
52772 $(storytellingv2Gui.storytellingv2Container).append(storytellingv2Gui.menu);
52773
52774 storytellingv2Gui.tree.hide();
52775 storytellingv2Gui.metadata.hide();
52776
52777 storytellingv2Gui.tree.on('create_node.jstree delete_node.jstree', function(e, data) {
52778 var root = storytellingv2Gui.tree.jstree().get_node('#');
52779 if (root.children.length > 0) {
52780 storytellingv2Gui.tree.show();
52781 storytellingv2Gui.metadata.show();
52782 if (e.type == "create_node") {
52783 storytellingv2Gui.tree.jstree().deselect_all();
52784 storytellingv2Gui.tree.jstree().select_node(data.node);
52785 } if (e.type == "delete_node") {
52786 storytellingv2Gui.tree.jstree().deselect_all();
52787 var prev_node = storytellingv2Gui.tree.jstree().get_prev_dom(data.node);
52788 storytellingv2Gui.tree.jstree().select_node(prev_node);
52789 }
52790 } else {
52791 storytellingv2Gui.tree.hide();
52792 storytellingv2Gui.metadata.hide();
52793 }
52794
52795 });
52796
52797 if (localStorage.getItem('PLATIN.storytellingv2.last_snapshot')) {
52798 var lastSession = storytellingv2Gui.tree.jstree().create_node('#', {
52799 'text' : 'Last Session',
52800 'type' : 'session',
52801 'li_attr' : {
52802 'timestamp' : Date.now(),
52803 'description' : 'Default Session'
52804 }
52805 });
52806 var nodes = JSON.parse(localStorage.getItem('PLATIN.storytellingv2.last_snapshot'));
52807 var last = storytellingv2Gui.tree.jstree().create_node(lastSession, nodes);
52808 storytellingv2.makeSimple(storytellingv2Gui.tree);
52809
52810 }
52811
52812 },
52813
52814 addImportButton : function() {
52815
52816 var storytellingv2Gui = this;
52817 var storytellingv2Widget = storytellingv2Gui.parent;
52818 var storytellingv2 = storytellingv2Widget.storytellingv2;
52819
52820 storytellingv2Gui.importbutton = $('<input type="button" id="storytellingv2import" name="import" value="import" />');
52821 storytellingv2Gui.importfile = $('<input type="file" id="storytellingv2importfile" accept="application/json" style="display: block; visibility:hidden; width: 0; height: 0" />');
52822 storytellingv2Gui.importfile.change(storytellingv2.handleFileSelect);
52823
52824 storytellingv2Gui.importbutton.click($.proxy(function() {
52825 storytellingv2Gui.importfile.click();
52826 }));
52827
52828 },
52829
52830 addExportButton : function() {
52831
52832 var storytellingv2Gui = this;
52833 var storytellingv2Widget = storytellingv2Gui.parent;
52834 var storytellingv2 = storytellingv2Widget.storytellingv2;
52835
52836 storytellingv2Gui.exportbutton = $('<input type="button" id="storytellingv2export" name="export" value="export" />');
52837 var dialog = $('<div id="tree-export-filename" title="Save File As?"><p><input type="text" size="25" /></p></div>');
52838 storytellingv2Gui.exportbutton.append(dialog);
52839 dialog.dialog({
52840 resizable: false,
52841 autoOpen: false,
52842 height: 220,
52843 modal: true,
52844 buttons: {
52845 'Ok': function() {
52846 $(this).dialog("close");
52847 },
52848 Cancel: function() {
52849 $(this).dialog("close");
52850 }
52851 }
52852 });
52853 storytellingv2Gui.exportbutton.click($.proxy(function() {
52854 var tree_as_json = JSON.stringify($('#storytellingv2jstree').jstree(true).get_json('#', { 'flat': true }));
52855 var exportdate = new Date().toUTCString();
52856
52857 dialog.dialog('open');
52858 $(dialog).find(':input').val("Storytelling State(" + exportdate + ").json");
52859 dialog.dialog('option', 'buttons', {
52860 'Ok': function() {
52861 var blob = new Blob([tree_as_json], {type: "text/plain;charset=utf-8"});
52862 saveAs(blob, dialog.find(':input').val());
52863 $(this).dialog("close");
52864 },
52865 Cancel: function() {
52866 $(this).dialog("close");
52867 }
52868 })
52869 // var blob = new Blob([tree_as_json], {type: "text/plain;charset=utf-8"});
52870 // saveAs(blob, "Storytelling State(" + exportdate + ").json");
52871
52872 /*
52873 var pom = document.createElement('a');
52874 pom.setAttribute('href','data:application/json;charset=UTF-8, ' + encodeURIComponent(tree_as_json));
52875 pom.setAttribute('download','Storytelling State(' + exportdate + ').json');
52876 pom.click();
52877 */
52878 }));
52879
52880 },
52881
52882 addResetButton : function() {
52883
52884 var storytellingv2Gui = this;
52885 var storytellingv2Widget = storytellingv2Gui.parent;
52886 var storytellingv2 = storytellingv2Widget.storytellingv2;
52887
52888 storytellingv2Gui.resetbutton = $('<input type="button" id="storytellingv2reset" name="reset" value="reset" />');
52889 var dialog = $('<div id="tree-reset-dialog-confirm" title="Erase all tree content?"><p><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0;"></span>Tree items will be permanently deleted and cannot be recovered. Are you sure?</p></div>');
52890 storytellingv2Gui.resetbutton.append(dialog)
52891 dialog.dialog({
52892 resizable: false,
52893 autoOpen: false,
52894 height: 260,
52895 modal: true,
52896 buttons: {
52897 'Yes': function() {
52898 storytellingv2.deleteAllNodes(storytellingv2Gui.tree);
52899 $(this).dialog("close");
52900 },
52901 Cancel: function() {
52902 $(this).dialog("close");
52903 }
52904 }
52905 });
52906
52907 storytellingv2Gui.resetbutton.click($.proxy(function() {
52908 dialog.dialog('open');
52909 }));
52910 },
52911
52912 addExpertButton : function() {
52913
52914 var storytellingv2Gui = this;
52915 var storytellingv2Widget = storytellingv2Gui.parent;
52916 var storytellingv2 = storytellingv2Widget.storytellingv2;
52917
52918 storytellingv2Gui.expertbutton = $('<input type="button" id="storytellingv2expert" name="expert" value="expert" />');
52919 storytellingv2Gui.expertbutton.click($.proxy(function() {
52920 storytellingv2Gui.expertbutton.hide();
52921 storytellingv2Gui.simplebutton.show();
52922 storytellingv2Gui.snapshotbutton.hide();
52923 storytellingv2Gui.newbutton.show();
52924 storytellingv2Gui.parent.simplemode = false;
52925 var configs = storytellingv2.findNodesByType(storytellingv2Gui.tree,'config');
52926 for (var i = 0; i < configs.length; i++) {
52927 storytellingv2Gui.tree.jstree().get_node(configs[i], true).show();
52928 }
52929 var snapshots = storytellingv2.findNodesByType(storytellingv2Gui.tree,'snapshot');
52930 for (var i = 0; i < snapshots.length; i++) {
52931 storytellingv2Gui.tree.jstree().set_type(snapshots[i], 'dataset');
52932 snapshots[i].li_attr.snapshot_text = snapshots[i].text;
52933 snapshots[i].text = snapshots[i].li_attr.dataset_text || snapshots[i].text;
52934 }
52935
52936 }));
52937
52938 },
52939
52940 addSimpleButton : function() {
52941
52942 var storytellingv2Gui = this;
52943 var storytellingv2Widget = storytellingv2Gui.parent;
52944 var storytellingv2 = storytellingv2Widget.storytellingv2;
52945
52946 storytellingv2Gui.simplebutton = $('<input type="button" id="storytellingv2simple" name="simple" value="simple" />');
52947 storytellingv2Gui.simplebutton.click($.proxy(function() {
52948 storytellingv2Gui.simplebutton.hide();
52949 storytellingv2Gui.expertbutton.show();
52950 storytellingv2Gui.newbutton.hide();
52951 storytellingv2Gui.snapshotbutton.show();
52952 storytellingv2Gui.parent.simplemode = true;
52953 storytellingv2.makeSimple(storytellingv2Gui.tree);
52954 }));
52955
52956 },
52957
52958 addNewButton : function() {
52959
52960 var storytellingv2Gui = this;
52961 var storytellingv2Widget = storytellingv2Gui.parent;
52962 var storytellingv2 = storytellingv2Widget.storytellingv2;
52963
52964 storytellingv2Gui.newbutton = $('<input type="button" id="storytellingv2new" name="new" value="new" />');
52965 storytellingv2Gui.newbutton.click($.proxy(function() {
52966 storytellingv2.defaultSession(storytellingv2Gui.tree);
52967 var newform = $('<div></div>');
52968 var nameinput = $('<p>Name: <input type="text" /></p>');
52969 var typeinput = $('<p>Type: <select name="type"><option value="session">Session</option><option value="dataset">Dataset</option><option value="config">Config</option></select></p>');
52970 var descriptioninput = $('<p>Description: <textarea name="description"></textarea></p>');
52971 var addbutton = $('<p><input type="button" name="add" value="add" /></p>');
52972 newform.focusout(function() {
52973 var elem = $(this);
52974 setTimeout(function() {
52975 var hasFocus = !!(elem.find(':focus').length > 0);
52976 if (! hasFocus) {
52977 newform.empty();
52978 }
52979 }, 10);
52980 });
52981 addbutton.click($.proxy(function() {
52982 var sel = storytellingv2Gui.tree.jstree().get_selected()[0] || '#' ;
52983 if ($(typeinput).find('option:selected').val() == 'session') {
52984 sel = '#';
52985 }
52986 sel = storytellingv2Gui.tree.jstree().create_node(sel, {
52987 "text" : $(nameinput).find(':text').first().val(),
52988 "type" : $(typeinput).find('option:selected').val(),
52989 "li_attr" : {
52990 "timestamp" : Date.now(),
52991 "description" : $(descriptioninput).find('textarea').first().val()
52992 }
52993 });
52994 var newNode = storytellingv2Gui.tree.jstree().get_node(sel);
52995
52996 if (newNode.type == 'config') {
52997 Publisher.Publish('getConfig',storytellingv2Widget);
52998 newNode.li_attr.configs = storytellingv2Widget.configArray.slice();
52999 } else if (newNode.type == 'dataset') {
53000 var datasets = [];
53001 if (storytellingv2Widget.datasets != undefined) {
53002 for (var i = 0; i < storytellingv2Widget.datasets.length; i++) {
53003 var ds = {};
53004 ds.label = storytellingv2Widget.datasets[i].label;
53005 ds.objects = GeoTemConfig.convertCsv(GeoTemConfig.createCSVfromDataset(i));
53006 datasets.push(ds);
53007 }
53008 }
53009 newNode.li_attr.selected = storytellingv2Widget.selected;
53010 newNode.li_attr.datasets = datasets;
53011 }
53012 // tree.jstree().set_type(sel, 'session');
53013 $(newform).empty();
53014 }));
53015 $(newform).append(nameinput);
53016 $(newform).append(typeinput);
53017 $(newform).append(descriptioninput);
53018 $(newform).append(addbutton);
53019 $(storytellingv2Gui.treemanipulationsubmenu).append(newform);
53020 $(nameinput).find(':input').focus();
53021 }));
53022
53023 },
53024
53025 addSnapshotButton : function() {
53026
53027 var storytellingv2Gui = this;
53028 var storytellingv2Widget = storytellingv2Gui.parent;
53029 var storytellingv2 = storytellingv2Widget.storytellingv2;
53030
53031 storytellingv2Gui.snapshotbutton = $('<input type="button" id="storytellingv2snapshot" name="snapshot" value="snapshot" />');
53032 storytellingv2Gui.snapshotbutton.click($.proxy(function() {
53033 storytellingv2.defaultSession(storytellingv2Gui.tree);
53034 var root = storytellingv2Gui.tree.jstree().get_node('#');
53035 var session = storytellingv2Gui.tree.jstree().get_node(root.children[0]);
53036 var countSnapshots = session.children.length + 1;
53037 var datasets = [];
53038
53039 if (storytellingv2Widget.datasets != undefined) {
53040 for (var i = 0; i < storytellingv2Widget.datasets.length; i++) {
53041 var ds = {};
53042 ds.label = storytellingv2Widget.datasets[i].label;
53043 ds.objects = GeoTemConfig.convertCsv(GeoTemConfig.createCSVfromDataset(i));
53044 datasets.push(ds);
53045 }
53046 }
53047 var newDataset = storytellingv2Gui.tree.jstree().create_node(session, {
53048 'text' : 'Snapshot #'+countSnapshots,
53049 'type' : 'dataset',
53050 'li_attr' : {
53051 'timestamp' : Date.now(),
53052 'description' : 'Snapshot #'+countSnapshots+' Dataset',
53053 'datasets' : datasets,
53054 'selected' : storytellingv2Widget.selected
53055 }
53056 });
53057 Publisher.Publish('getConfig',storytellingv2Widget);
53058 var newConfig = storytellingv2Gui.tree.jstree().create_node(newDataset, {
53059 'text' : 'Snapshot #'+countSnapshots,
53060 'type' : 'config',
53061 'li_attr' : {
53062 'timestamp' : Date.now(),
53063 'description' : 'Snapshot #'+countSnapshots+' Config',
53064 'configs' : storytellingv2Widget.configArray.slice()
53065 }
53066 });
53067 snapshot_as_json = JSON.stringify(storytellingv2Gui.tree.jstree(true).get_json(newDataset));
53068 localStorage.setItem("PLATIN.storytellingv2.last_snapshot",snapshot_as_json);
53069 storytellingv2.makeSimple(storytellingv2Gui.tree);
53070
53071 }));
53072
53073 },
53074
53075 addRestoreButton : function() {
53076
53077 var storytellingv2Gui = this;
53078 var storytellingv2Widget = storytellingv2Gui.parent;
53079 var storytellingv2 = storytellingv2Widget.storytellingv2;
53080
53081 storytellingv2Gui.restorebutton = $('<input type="button" id="storytellingv2restore" name="restore" value="restore" />');
53082 var loadDataset = function(node) {
53083 var datasets = node.li_attr.datasets;
53084 if (datasets != undefined) {
53085 GeoTemConfig.removeAllDatasets();
53086 for (var i = 0; i < datasets.length; i++) {
53087 var dataset = new Dataset(GeoTemConfig.loadJson(datasets[i].objects), datasets[i].label);
53088 GeoTemConfig.addDataset(dataset);
53089 }
53090 }
53091
53092 }
53093
53094 var loadFilter = function(node) {
53095 var configArray = node.li_attr.configs;
53096 for (var i = 0; i < configArray.length; i++) {
53097 Publisher.Publish('setConfig', configArray[i]);
53098 }
53099 }
53100
53101 var loadSnapshot = function(node) {
53102 loadDataset(node);
53103 var childNode = node;
53104 while (storytellingv2Gui.tree.jstree().is_parent(childNode)) {
53105 childNode = storytellingv2Gui.tree.jstree().get_node(childNode.children[0]);
53106 if (childNode.type == 'config') {
53107 loadFilter(childNode);
53108 }
53109 }
53110 }
53111
53112 storytellingv2Gui.restorebutton.click($.proxy(function() {
53113 var selectedNode = storytellingv2Gui.tree.jstree().get_node(storytellingv2Gui.tree.jstree().get_selected()[0]);
53114 if (selectedNode == 'undefined' || selectedNode.type == 'session') {
53115 return;
53116 }
53117 if (selectedNode.type == 'snapshot') {
53118 loadSnapshot(selectedNode);
53119 return;
53120 }
53121 for (var i = selectedNode.parents.length - 1; i >= 0; i--) {
53122 var curNode = storytellingv2Gui.tree.jstree().get_node(selectedNode.parents[i]);
53123 if (curNode.type == 'dataset') {
53124 loadDataset(curNode);
53125 } else if (curNode.type == 'config') {
53126 loadFilter(curNode);
53127 }
53128 }
53129 if (selectedNode.type == 'dataset') {
53130 loadDataset(selectedNode);
53131 } else if (selectedNode.type == 'config') {
53132 loadFilter(selectedNode);
53133 }
53134 }));
53135
53136 },
53137
53138 addDeleteButton : function() {
53139
53140 var storytellingv2Gui = this;
53141 var storytellingv2Widget = storytellingv2Gui.parent;
53142 var storytellingv2 = storytellingv2Widget.storytellingv2;
53143
53144 storytellingv2Gui.deletebutton = $('<input type="button" id="storytellingv2delete" name="delete" value="delete" />');
53145 storytellingv2Gui.deletebutton.click($.proxy(function() {
53146 var selectedNode = storytellingv2Gui.tree.jstree().get_node(storytellingv2Gui.tree.jstree().get_selected()[0]);
53147 storytellingv2Gui.tree.jstree().delete_node(selectedNode);
53148 }))
53149
53150 },
53151
53152 addEditButton : function() {
53153
53154 var storytellingv2Gui = this;
53155 var storytellingv2Widget = storytellingv2Gui.parent;
53156 var storytellingv2 = storytellingv2Widget.storytellingv2;
53157
53158 storytellingv2Gui.editbutton = $('<input type="button" id="storytellingv2edit" name="edit" value="edit" />');
53159 storytellingv2Gui.editbutton.click($.proxy(function() {
53160 var sel = storytellingv2Gui.tree.jstree().get_selected()[0];
53161 if (sel != undefined ) {
53162 sel = storytellingv2Gui.tree.jstree().get_node(sel);
53163 var editform = $('<div></div>');
53164 var nameinput = $('<p>Name: <input type="text" value="'+sel.text+'" /></p>');
53165 var descriptioninput = $('<p>Description: <textarea name="description">'+sel.li_attr.description+'</textarea></p>');
53166 var savebutton = $('<p><input type="button" name="save" value="save" /></p>');
53167 editform.focusout(function() {
53168 var elem = $(this);
53169 setTimeout(function() {
53170 var hasFocus = !!(elem.find(':focus').length > 0);
53171 if (! hasFocus) {
53172 editform.empty();
53173 }
53174 }, 10);
53175 });
53176 savebutton.click($.proxy(function() {
53177 storytellingv2Gui.tree.jstree().rename_node(sel, $(nameinput).find(':text').first().val());
53178 sel.li_attr.description = $(descriptioninput).find('textarea').first().val();
53179 storytellingv2Gui.tree.jstree().redraw();
53180 $(editform).empty();
53181 }));
53182 // $(editform).focusout(function() {
53183 // $(editform).empty();
53184 // });
53185 $(editform).append(nameinput);
53186 $(editform).append(descriptioninput);
53187 $(editform).append(savebutton);
53188 storytellingv2Gui.treemanipulationsubmenu.append(editform);
53189 nameinput.find(':input').focus();
53190 }
53191
53192
53193 }));
53194
53195 },
53196
53197 addForwardButton : function() {
53198
53199 var storytellingv2Gui = this;
53200 var storytellingv2Widget = storytellingv2Gui.parent;
53201 var storytellingv2 = storytellingv2Widget.storytellingv2;
53202
53203 storytellingv2Gui.forwardbutton = $('<input type="button" id="storytellingv2forward" name="forward" value=">>" />');
53204 storytellingv2Gui.forwardbutton.click($.proxy(function() {
53205 var sel = storytellingv2Gui.tree.jstree().get_selected()[0];
53206 if (storytellingv2Gui.tree.jstree().get_next_dom(sel, true)) {
53207 storytellingv2Gui.tree.jstree().deselect_node(sel);
53208 storytellingv2Gui.tree.jstree().select_node(storytellingv2Gui.tree.jstree().get_next_dom(sel, true));
53209 }
53210
53211 }));
53212
53213 },
53214
53215 addBackwardButton : function() {
53216
53217 var storytellingv2Gui = this;
53218 var storytellingv2Widget = storytellingv2Gui.parent;
53219 var storytellingv2 = storytellingv2Widget.storytellingv2;
53220
53221 storytellingv2Gui.backwardbutton = $('<input type="button" id="storytellingv2backward" name="backward" value="<<" />');
53222 storytellingv2Gui.backwardbutton.click($.proxy(function() {
53223 var sel = storytellingv2Gui.tree.jstree().get_selected()[0];
53224 if (storytellingv2Gui.tree.jstree().get_prev_dom(sel, true)) {
53225 storytellingv2Gui.tree.jstree().deselect_node(sel);
53226 storytellingv2Gui.tree.jstree().select_node(storytellingv2Gui.tree.jstree().get_prev_dom(sel, true));
53227 }
53228
53229 }));
53230
53231
53232 },
53233
53234 addMetadata : function() {
53235
53236 var storytellingv2Gui = this;
53237 var storytellingv2Widget = storytellingv2Gui.parent;
53238 var storytellingv2 = storytellingv2Widget.storytellingv2;
53239
53240 storytellingv2Gui.metadata = $('<div></div>');
53241 var metadatafieldset = $('<fieldset style="border: 2px solid; margin: 2px; padding: 5px;"><legend>Metadata</legend></fieldset>');
53242 var metadataname = $('<p>Name:</p>');
53243 var metadatatype = $('<p>Type:</p>');
53244 var metadatatimestamp = $('<p>Timestamp:</p>');
53245 var metadatadescription = $('<p>Description:</p>');
53246 var metadataselected = $('<p></p>');
53247 $(metadatafieldset).append(metadataname);
53248 $(metadatafieldset).append(metadatatype);
53249 $(metadatafieldset).append(metadatatimestamp);
53250 $(metadatafieldset).append(metadatadescription);
53251 $(metadatafieldset).append(metadataselected);
53252 $(storytellingv2Gui.metadata).append(metadatafieldset);
53253 storytellingv2Gui.tree.on('changed.jstree rename_node.jstree', function(e, data) {
53254 if (data.node == undefined) {
53255 return;
53256 }
53257 $(metadataname).empty().append($('<p>Name: '+data.node.text+'</p>'));
53258 $(metadatatype).empty().append($('<p>Type: '+data.node.type+'</p>'));
53259 var tstamp = new Date(data.node.li_attr.timestamp);
53260 $(metadatatimestamp).empty().append($('<p>Timestamp: '+tstamp.toUTCString()+'</p>'));
53261 $(metadatadescription).empty().append($('<p>Description: '+data.node.li_attr.description+'</p>'));
53262 var objectcount = 0;
53263 var datasetcount = 0;
53264 if ($.isArray(data.node.li_attr.selected)) {
53265 datasetcount = data.node.li_attr.selected.length;
53266 $(data.node.li_attr.selected).each(function() {
53267 objectcount += this.length;
53268 });
53269 }
53270 // $(metadataselected).empty().append($('<p>'+objectcount+' Selected Objects in '+datasetcount+' Datasets</p>'));
53271 });
53272
53273 }
53274
53275
53276 };
53277 /*
53278 * StorytellingWidget.js
53279 *
53280 * Copyright (c) 2013, Sebastian Kruse. All rights reserved.
53281 *
53282 * This library is free software; you can redistribute it and/or
53283 * modify it under the terms of the GNU Lesser General Public
53284 * License as published by the Free Software Foundation; either
53285 * version 3 of the License, or (at your option) any later version.
53286 *
53287 * This library is distributed in the hope that it will be useful,
53288 * but WITHOUT ANY WARRANTY; without even the implied warranty of
53289 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
53290 * Lesser General Public License for more details.
53291 *
53292 * You should have received a copy of the GNU Lesser General Public
53293 * License along with this library; if not, write to the Free Software
53294 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
53295 * MA 02110-1301 USA
53296 */
53297
53298 /**
53299 * @class Storytellingv2Widget
53300 * Storytellingv2Widget Implementation
53301 * @author Mike Bretschneider (mike.bretschneider@gmx.de)
53302 *
53303 * @param {WidgetWrapper} core wrapper for interaction to other widgets
53304 * @param {HTML object} div parent div to append the Storytellingv2 widget div
53305 * @param {JSON} options user specified configuration that overwrites options in Storytellingv2Config.js
53306 */
53307 Storytellingv2Widget = function(core, div, options) {
53308 /* HACK DW: stelle sicher, dass das nicht zweimal aufgerufen wird! */
53309 if (typeof Storytellingv2Widget_cont == "undefined"){
53310 Storytellingv2Widget_cont="Done";
53311
53312 this.datasets;
53313 this.core = core;
53314 this.core.setWidget(this);
53315 this.currentStatus = new Object();
53316
53317 this.options = (new Storytellingv2Config(options)).options;
53318 this.gui = new Storytellingv2Gui(this, div, this.options);
53319 this.storytellingv2 = new Storytellingv2(this);
53320
53321 this.datasetLink;
53322
53323 this.selected;
53324 this.configArray = [];
53325
53326 this.simplemode = true;
53327
53328 this.initWidget();
53329
53330 }
53331 }
53332
53333 Storytellingv2Widget.prototype = {
53334
53335 initWidget : function(data) {
53336
53337
53338 var storytellingv2Widget = this;
53339 var gui = storytellingv2Widget.gui;
53340
53341 storytellingv2Widget.datasets = data;
53342
53343 gui.initGui();
53344
53345 },
53346
53347 createLink : function() {
53348 },
53349
53350 highlightChanged : function(objects) {
53351 },
53352
53353 selectionChanged : function(selection) {
53354 if (!selection.valid()) {
53355 selection.loadAllObjects();
53356 }
53357 this.selected = selection.objects;
53358 },
53359
53360 sendConfig : function(widgetConfig){
53361 for (var i = 0; i < this.configArray.length; i++) {
53362 if (this.configArray[i].widgetName == widgetConfig.widgetName) {
53363 this.configArray.splice(i,1);
53364 }
53365 }
53366 this.configArray.push(widgetConfig);
53367 },
53368
43175 }; 53369 };
43176 /* 53370 /*
43177 * LineOverlay.js 53371 * LineOverlay.js
43178 * 53372 *
43179 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. 53373 * Copyright (c) 2013, Sebastian Kruse. All rights reserved.
47007 Publisher.Subscribe('resizeWidget', this, function() { 57201 Publisher.Subscribe('resizeWidget', this, function() {
47008 if ( typeof wrapper.widget != 'undefined' && typeof wrapper.widget.gui != 'undefined' && typeof wrapper.widget.gui.resize != 'undefined' ) { 57202 if ( typeof wrapper.widget != 'undefined' && typeof wrapper.widget.gui != 'undefined' && typeof wrapper.widget.gui.resize != 'undefined' ) {
47009 wrapper.widget.gui.resize(); 57203 wrapper.widget.gui.resize();
47010 } 57204 }
47011 }); 57205 });
57206
57207 Publisher.Subscribe('getConfig', this, function(inquiringWidget) {
57208 if (inquiringWidget == undefined) {
57209 return;
57210 }
57211 if ( typeof wrapper.widget != 'undefined') {
57212 if ( typeof wrapper.widget.getConfig != 'undefined') {
57213 wrapper.widget.getConfig(inquiringWidget);
57214 }
57215 }
57216 });
57217
57218 Publisher.Subscribe('setConfig', this, function(config) {
57219 if (config == undefined) {
57220 return;
57221 }
57222 if ( typeof wrapper.widget != 'undefined') {
57223 if ( typeof wrapper.widget.setConfig != 'undefined') {
57224 wrapper.widget.setConfig(config);
57225 }
57226 }
57227 });
57228
47012 57229
47013 this.triggerRefining = function(datasets) { 57230 this.triggerRefining = function(datasets) {
47014 Publisher.Publish('filterData', datasets, null); 57231 Publisher.Publish('filterData', datasets, null);
47015 }; 57232 };
47016 57233