/*!
 * Copyright (c) 2012 - 2019, Anaconda, Inc., and Bokeh Contributors
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 * 
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * 
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 * 
 * Neither the name of Anaconda nor the names of any contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
*/
(function(root, factory) {
  root["Bokeh"] = factory();
})(this, function() {
  var define;
  var parent_require = typeof require === "function" && require
  return (function(modules, entry, aliases, externals) {
    if (aliases === undefined) aliases = {};
    if (externals === undefined) externals = {};

    var cache = {};

    var normalize = function(name) {
      if (typeof name === "number")
        return name;

      if (name === "bokehjs")
        return entry;

      var prefix = "@bokehjs/"
      if (name.slice(0, prefix.length) === prefix)
        name = name.slice(prefix.length)

      var alias = aliases[name]
      if (alias != null)
        return alias;

      var trailing = name.length > 0 && name[name.lenght-1] === "/";
      var index = aliases[name + (trailing ? "" : "/") + "index"];
      if (index != null)
        return index;

      return name;
    }

    var require = function(name) {
      var mod = cache[name];
      if (!mod) {
        var id = normalize(name);

        mod = cache[id];
        if (!mod) {
          if (!modules[id]) {
            if (parent_require && externals[id]) {
              try {
                mod = {exports: parent_require(id)};
                cache[id] = cache[name] = mod;
                return mod.exports;
              } catch (e) {}
            }

            var err = new Error("Cannot find module '" + name + "'");
            err.code = 'MODULE_NOT_FOUND';
            throw err;
          }

          mod = {exports: {}};
          cache[id] = cache[name] = mod;
          modules[id].call(mod.exports, require, mod, mod.exports);
        } else
          cache[name] = mod;
      }

      return mod.exports;
    }

    var main = require(entry);
    main.require = require;

    main.register_plugin = function(plugin_modules, plugin_entry, plugin_aliases, plugin_externals) {
      if (plugin_aliases === undefined) plugin_aliases = {};
      if (plugin_externals === undefined) plugin_externals = {};

      for (var name in plugin_modules) {
        modules[name] = plugin_modules[name];
      }

      for (var name in plugin_aliases) {
        aliases[name] = plugin_aliases[name];
      }

      for (var name in plugin_externals) {
        externals[name] = plugin_externals[name];
      }

      var plugin = require(plugin_entry);

      for (var name in plugin) {
        main[name] = plugin[name];
      }

      return plugin;
    }

    return main;
  })
([
/* main.js */ function _(require, module, exports) {
    function __export(m) {
        for (var p in m)
            if (!exports.hasOwnProperty(p))
                exports[p] = m[p];
    }
    __export(require(1) /* ./index */);
},
/* index.js */ function _(require, module, exports) {
    var version_1 = require(2) /* ./version */;
    exports.version = version_1.version;
    const embed = require(3) /* ./embed */;
    exports.embed = embed;
    var embed_1 = require(3) /* ./embed */;
    exports.index = embed_1.index;
    const protocol = require(348) /* ./protocol */;
    exports.protocol = protocol;
    const _testing = require(349) /* ./testing */;
    exports._testing = _testing;
    var logging_1 = require(65) /* ./core/logging */;
    exports.logger = logging_1.logger;
    exports.set_log_level = logging_1.set_log_level;
    var settings_1 = require(26) /* ./core/settings */;
    exports.settings = settings_1.settings;
    var base_1 = require(6) /* ./base */;
    exports.Models = base_1.Models;
    var document_1 = require(4) /* ./document */;
    exports.documents = document_1.documents;
    var safely_1 = require(350) /* ./safely */;
    exports.safely = safely_1.safely;
},
/* version.js */ function _(require, module, exports) {
    exports.version = '1.4.0';
},
/* embed/index.js */ function _(require, module, exports) {
    const document_1 = require(4) /* ../document */;
    const logging_1 = require(65) /* ../core/logging */;
    const callback_1 = require(16) /* ../core/util/callback */;
    const string_1 = require(25) /* ../core/util/string */;
    const types_1 = require(7) /* ../core/util/types */;
    const standalone_1 = require(339) /* ./standalone */;
    const server_1 = require(341) /* ./server */;
    const dom_1 = require(340) /* ./dom */;
    var standalone_2 = require(339) /* ./standalone */;
    exports.add_document_standalone = standalone_2.add_document_standalone;
    exports.index = standalone_2.index;
    var server_2 = require(341) /* ./server */;
    exports.add_document_from_session = server_2.add_document_from_session;
    var notebook_1 = require(346) /* ./notebook */;
    exports.embed_items_notebook = notebook_1.embed_items_notebook;
    exports.kernels = notebook_1.kernels;
    var dom_2 = require(340) /* ./dom */;
    exports.BOKEH_ROOT = dom_2.BOKEH_ROOT;
    function embed_item(item, target_id) {
        const docs_json = {};
        const doc_id = string_1.uuid4();
        docs_json[doc_id] = item.doc;
        if (target_id == null)
            target_id = item.target_id;
        const element = document.getElementById(target_id);
        if (element != null)
            element.classList.add(dom_1.BOKEH_ROOT);
        const roots = { [item.root_id]: target_id };
        const render_item = { roots, docid: doc_id };
        callback_1.defer(() => _embed_items(docs_json, [render_item]));
    }
    exports.embed_item = embed_item;
    // TODO (bev) this is currently clunky. Standalone embeds only provide
    // the first two args, whereas server provide the app_app, and *may* prove and
    // absolute_url as well if non-relative links are needed for resources. This function
    // should probably be split in to two pieces to reflect the different usage patterns
    function embed_items(docs_json, render_items, app_path, absolute_url) {
        callback_1.defer(() => _embed_items(docs_json, render_items, app_path, absolute_url));
    }
    exports.embed_items = embed_items;
    function _embed_items(docs_json, render_items, app_path, absolute_url) {
        if (types_1.isString(docs_json))
            docs_json = JSON.parse(string_1.unescape(docs_json));
        const docs = {};
        for (const docid in docs_json) {
            const doc_json = docs_json[docid];
            docs[docid] = document_1.Document.from_json(doc_json);
        }
        for (const item of render_items) {
            const element = dom_1._resolve_element(item);
            const roots = dom_1._resolve_root_elements(item);
            if (item.docid != null) {
                standalone_1.add_document_standalone(docs[item.docid], element, roots, item.use_for_title);
            }
            else if (item.sessionid != null) {
                const websocket_url = server_1._get_ws_url(app_path, absolute_url);
                logging_1.logger.debug(`embed: computed ws url: ${websocket_url}`);
                const promise = server_1.add_document_from_session(websocket_url, item.sessionid, element, roots, item.use_for_title);
                promise.then(() => {
                    console.log("Bokeh items were rendered successfully");
                }, (error) => {
                    console.log("Error rendering Bokeh items:", error);
                });
            }
            else
                throw new Error(`Error rendering Bokeh items: either 'docid' or 'sessionid' was expected.`);
        }
    }
},
/* document/index.js */ function _(require, module, exports) {
    function __export(m) {
        for (var p in m)
            if (!exports.hasOwnProperty(p))
                exports[p] = m[p];
    }
    __export(require(5) /* ./document */);
    __export(require(97) /* ./events */);
},
/* document/document.js */ function _(require, module, exports) {
    const base_1 = require(6) /* ../base */;
    const version_1 = require(2) /* ../version */;
    const logging_1 = require(65) /* ../core/logging */;
    const bokeh_events_1 = require(274) /* ../core/bokeh_events */;
    const has_props_1 = require(12) /* ../core/has_props */;
    const signaling_1 = require(13) /* ../core/signaling */;
    const refs_1 = require(24) /* ../core/util/refs */;
    const serialization_1 = require(94) /* ../core/util/serialization */;
    const data_structures_1 = require(14) /* ../core/util/data_structures */;
    const array_1 = require(8) /* ../core/util/array */;
    const object_1 = require(22) /* ../core/util/object */;
    const eq_1 = require(15) /* ../core/util/eq */;
    const types_1 = require(7) /* ../core/util/types */;
    const layout_dom_1 = require(237) /* ../models/layouts/layout_dom */;
    const column_data_source_1 = require(68) /* ../models/sources/column_data_source */;
    const model_1 = require(64) /* ../model */;
    const events_1 = require(97) /* ./events */;
    class EventManager {
        constructor(document) {
            this.document = document;
            // Dispatches events to the subscribed models
            this.session = null;
            this.subscribed_models = new data_structures_1.Set();
        }
        send_event(event) {
            if (this.session != null)
                this.session.send_event(event);
        }
        trigger(event) {
            for (const id of this.subscribed_models.values) {
                if (event.origin != null && event.origin.id !== id)
                    continue;
                const model = this.document._all_models[id];
                if (model != null && model instanceof model_1.Model)
                    model._process_event(event);
            }
        }
    }
    exports.EventManager = EventManager;
    EventManager.__name__ = "EventManager";
    exports.documents = [];
    exports.DEFAULT_TITLE = "Bokeh Application";
    // This class should match the API of the Python Document class
    // as much as possible.
    class Document {
        constructor() {
            exports.documents.push(this);
            this._init_timestamp = Date.now();
            this._title = exports.DEFAULT_TITLE;
            this._roots = [];
            this._all_models = {};
            this._all_models_by_name = new data_structures_1.MultiDict();
            this._all_models_freeze_count = 0;
            this._callbacks = [];
            this.event_manager = new EventManager(this);
            this.idle = new signaling_1.Signal0(this, "idle");
            this._idle_roots = new WeakMap(); // TODO: WeakSet would be better
            this._interactive_timestamp = null;
            this._interactive_plot = null;
        }
        get layoutables() {
            return this._roots.filter((root) => root instanceof layout_dom_1.LayoutDOM);
        }
        get is_idle() {
            for (const root of this.layoutables) {
                if (!this._idle_roots.has(root))
                    return false;
            }
            return true;
        }
        notify_idle(model) {
            this._idle_roots.set(model, true);
            if (this.is_idle) {
                logging_1.logger.info(`document idle at ${Date.now() - this._init_timestamp} ms`);
                this.idle.emit();
            }
        }
        clear() {
            this._push_all_models_freeze();
            try {
                while (this._roots.length > 0) {
                    this.remove_root(this._roots[0]);
                }
            }
            finally {
                this._pop_all_models_freeze();
            }
        }
        interactive_start(plot) {
            if (this._interactive_plot == null) {
                this._interactive_plot = plot;
                this._interactive_plot.trigger_event(new bokeh_events_1.LODStart());
            }
            this._interactive_timestamp = Date.now();
        }
        interactive_stop(plot) {
            if (this._interactive_plot != null && this._interactive_plot.id === plot.id) {
                this._interactive_plot.trigger_event(new bokeh_events_1.LODEnd());
            }
            this._interactive_plot = null;
            this._interactive_timestamp = null;
        }
        interactive_duration() {
            if (this._interactive_timestamp == null)
                return -1;
            else
                return Date.now() - this._interactive_timestamp;
        }
        destructively_move(dest_doc) {
            if (dest_doc === this) {
                throw new Error("Attempted to overwrite a document with itself");
            }
            dest_doc.clear();
            // we have to remove ALL roots before adding any
            // to the new doc or else models referenced from multiple
            // roots could be in both docs at once, which isn't allowed.
            const roots = array_1.copy(this._roots);
            this.clear();
            for (const root of roots) {
                if (root.document != null)
                    throw new Error(`Somehow we didn't detach ${root}`);
            }
            if (Object.keys(this._all_models).length !== 0) {
                throw new Error(`this._all_models still had stuff in it: ${this._all_models}`);
            }
            for (const root of roots) {
                dest_doc.add_root(root);
            }
            dest_doc.set_title(this._title);
        }
        // TODO other fields of doc
        _push_all_models_freeze() {
            this._all_models_freeze_count += 1;
        }
        _pop_all_models_freeze() {
            this._all_models_freeze_count -= 1;
            if (this._all_models_freeze_count === 0) {
                this._recompute_all_models();
            }
        }
        /*protected*/ _invalidate_all_models() {
            logging_1.logger.debug("invalidating document models");
            // if freeze count is > 0, we'll recompute on unfreeze
            if (this._all_models_freeze_count === 0) {
                this._recompute_all_models();
            }
        }
        _recompute_all_models() {
            let new_all_models_set = new data_structures_1.Set();
            for (const r of this._roots) {
                new_all_models_set = new_all_models_set.union(r.references());
            }
            const old_all_models_set = new data_structures_1.Set(object_1.values(this._all_models));
            const to_detach = old_all_models_set.diff(new_all_models_set);
            const to_attach = new_all_models_set.diff(old_all_models_set);
            const recomputed = {};
            for (const m of new_all_models_set.values) {
                recomputed[m.id] = m;
            }
            for (const d of to_detach.values) {
                d.detach_document();
                if (d instanceof model_1.Model && d.name != null)
                    this._all_models_by_name.remove_value(d.name, d);
            }
            for (const a of to_attach.values) {
                a.attach_document(this);
                if (a instanceof model_1.Model && a.name != null)
                    this._all_models_by_name.add_value(a.name, a);
            }
            this._all_models = recomputed;
        }
        roots() {
            return this._roots;
        }
        add_root(model, setter_id) {
            logging_1.logger.debug(`Adding root: ${model}`);
            if (array_1.includes(this._roots, model))
                return;
            this._push_all_models_freeze();
            try {
                this._roots.push(model);
            }
            finally {
                this._pop_all_models_freeze();
            }
            this._trigger_on_change(new events_1.RootAddedEvent(this, model, setter_id));
        }
        remove_root(model, setter_id) {
            const i = this._roots.indexOf(model);
            if (i < 0)
                return;
            this._push_all_models_freeze();
            try {
                this._roots.splice(i, 1);
            }
            finally {
                this._pop_all_models_freeze();
            }
            this._trigger_on_change(new events_1.RootRemovedEvent(this, model, setter_id));
        }
        title() {
            return this._title;
        }
        set_title(title, setter_id) {
            if (title !== this._title) {
                this._title = title;
                this._trigger_on_change(new events_1.TitleChangedEvent(this, title, setter_id));
            }
        }
        get_model_by_id(model_id) {
            if (model_id in this._all_models) {
                return this._all_models[model_id];
            }
            else {
                return null;
            }
        }
        get_model_by_name(name) {
            return this._all_models_by_name.get_one(name, `Multiple models are named '${name}'`);
        }
        on_change(callback) {
            if (!array_1.includes(this._callbacks, callback))
                this._callbacks.push(callback);
        }
        remove_on_change(callback) {
            const i = this._callbacks.indexOf(callback);
            if (i >= 0)
                this._callbacks.splice(i, 1);
        }
        _trigger_on_change(event) {
            for (const cb of this._callbacks) {
                cb(event);
            }
        }
        // called by the model
        _notify_change(model, attr, old, new_, options) {
            if (attr === 'name') {
                this._all_models_by_name.remove_value(old, model);
                if (new_ != null)
                    this._all_models_by_name.add_value(new_, model);
            }
            const setter_id = options != null ? options.setter_id : void 0;
            const hint = options != null ? options.hint : void 0;
            this._trigger_on_change(new events_1.ModelChangedEvent(this, model, attr, old, new_, setter_id, hint));
        }
        static _references_json(references, include_defaults = true) {
            const references_json = [];
            for (const r of references) {
                const ref = r.ref();
                ref.attributes = r.attributes_as_json(include_defaults);
                // server doesn't want id in here since it's already in ref above
                delete ref.attributes.id;
                references_json.push(ref);
            }
            return references_json;
        }
        static _instantiate_object(obj_id, obj_type, obj_attrs) {
            const full_attrs = Object.assign(Object.assign({}, obj_attrs), { id: obj_id, __deferred__: true });
            const model = base_1.Models(obj_type);
            return new model(full_attrs);
        }
        // given a JSON representation of all models in a graph, return a
        // dict of new model objects
        static _instantiate_references_json(references_json, existing_models) {
            // Create all instances, but without setting their props
            const references = {};
            for (const obj of references_json) {
                const obj_id = obj.id;
                const obj_type = obj.type;
                const obj_attrs = obj.attributes || {};
                let instance;
                if (obj_id in existing_models)
                    instance = existing_models[obj_id];
                else {
                    instance = Document._instantiate_object(obj_id, obj_type, obj_attrs);
                    if (obj.subtype != null)
                        instance.set_subtype(obj.subtype);
                }
                references[instance.id] = instance;
            }
            return references;
        }
        // if v looks like a ref, or a collection, resolve it, otherwise return it unchanged
        // recurse into collections but not into HasProps
        static _resolve_refs(value, old_references, new_references) {
            function resolve_ref(v) {
                if (refs_1.is_ref(v)) {
                    if (v.id in old_references)
                        return old_references[v.id];
                    else if (v.id in new_references)
                        return new_references[v.id];
                    else
                        throw new Error(`reference ${JSON.stringify(v)} isn't known (not in Document?)`);
                }
                else if (types_1.isArray(v))
                    return resolve_array(v);
                else if (types_1.isPlainObject(v))
                    return resolve_dict(v);
                else
                    return v;
            }
            function resolve_array(array) {
                const results = [];
                for (const v of array) {
                    results.push(resolve_ref(v));
                }
                return results;
            }
            function resolve_dict(dict) {
                const resolved = {};
                for (const k in dict) {
                    const v = dict[k];
                    resolved[k] = resolve_ref(v);
                }
                return resolved;
            }
            return resolve_ref(value);
        }
        // given a JSON representation of all models in a graph and new
        // model instances, set the properties on the models from the
        // JSON
        static _initialize_references_json(references_json, old_references, new_references) {
            const to_update = {};
            for (const obj of references_json) {
                const obj_id = obj.id;
                const obj_attrs = obj.attributes;
                const was_new = !(obj_id in old_references);
                const instance = !was_new ? old_references[obj_id] : new_references[obj_id];
                // replace references with actual instances in obj_attrs
                const resolved_attrs = Document._resolve_refs(obj_attrs, old_references, new_references);
                to_update[instance.id] = [instance, resolved_attrs, was_new];
            }
            function foreach_depth_first(items, f) {
                const already_started = {};
                function foreach_value(v) {
                    if (v instanceof has_props_1.HasProps) {
                        // note that we ignore instances that aren't updated (not in to_update)
                        if (!(v.id in already_started) && v.id in items) {
                            already_started[v.id] = true;
                            const [, attrs, was_new] = items[v.id];
                            for (const a in attrs) {
                                const e = attrs[a];
                                foreach_value(e);
                            }
                            f(v, attrs, was_new);
                        }
                    }
                    else if (types_1.isArray(v)) {
                        for (const e of v)
                            foreach_value(e);
                    }
                    else if (types_1.isPlainObject(v)) {
                        for (const k in v) {
                            const e = v[k];
                            foreach_value(e);
                        }
                    }
                }
                for (const k in items) {
                    const [instance, ,] = items[k];
                    foreach_value(instance);
                }
            }
            // this first pass removes all 'refs' replacing them with real instances
            foreach_depth_first(to_update, function (instance, attrs, was_new) {
                if (was_new)
                    instance.setv(attrs, { silent: true });
            });
            // after removing all the refs, we can run the initialize code safely
            foreach_depth_first(to_update, function (instance, _attrs, was_new) {
                if (was_new)
                    instance.finalize();
            });
        }
        static _event_for_attribute_change(changed_obj, key, new_value, doc, value_refs) {
            const changed_model = doc.get_model_by_id(changed_obj.id); // XXX!
            if (!changed_model.attribute_is_serializable(key))
                return null;
            else {
                const event = {
                    kind: "ModelChanged",
                    model: {
                        id: changed_obj.id,
                        type: changed_obj.type,
                    },
                    attr: key,
                    new: new_value,
                };
                has_props_1.HasProps._json_record_references(doc, new_value, value_refs, true); // true = recurse
                return event;
            }
        }
        static _events_to_sync_objects(from_obj, to_obj, to_doc, value_refs) {
            const from_keys = Object.keys(from_obj.attributes); //XXX!
            const to_keys = Object.keys(to_obj.attributes); //XXX!
            const removed = array_1.difference(from_keys, to_keys);
            const added = array_1.difference(to_keys, from_keys);
            const shared = array_1.intersection(from_keys, to_keys);
            const events = [];
            for (const key of removed) {
                // we don't really have a "remove" event - not sure this ever
                // happens even. One way this could happen is if the server
                // does include_defaults=True and we do
                // include_defaults=false ... in that case it'd be best to
                // just ignore this probably. Warn about it, could mean
                // there's a bug if we don't have a key that the server sent.
                logging_1.logger.warn(`Server sent key ${key} but we don't seem to have it in our JSON`);
            }
            for (const key of added) {
                const new_value = to_obj.attributes[key]; // XXX!
                events.push(Document._event_for_attribute_change(from_obj, key, new_value, to_doc, value_refs));
            }
            for (const key of shared) {
                const old_value = from_obj.attributes[key]; // XXX!
                const new_value = to_obj.attributes[key]; // XXX!
                if (old_value == null && new_value == null) {
                }
                else if (old_value == null || new_value == null) {
                    events.push(Document._event_for_attribute_change(from_obj, key, new_value, to_doc, value_refs));
                }
                else {
                    if (!eq_1.isEqual(old_value, new_value))
                        events.push(Document._event_for_attribute_change(from_obj, key, new_value, to_doc, value_refs));
                }
            }
            return events.filter((e) => e != null);
        }
        // we use this to detect changes during document deserialization
        // (in model constructors and initializers)
        static _compute_patch_since_json(from_json, to_doc) {
            const to_json = to_doc.to_json(false); // include_defaults=false
            function refs(json) {
                const result = {};
                for (const obj of json.roots.references)
                    result[obj.id] = obj;
                return result;
            }
            const from_references = refs(from_json);
            const from_roots = {};
            const from_root_ids = [];
            for (const r of from_json.roots.root_ids) {
                from_roots[r] = from_references[r];
                from_root_ids.push(r);
            }
            const to_references = refs(to_json);
            const to_roots = {};
            const to_root_ids = [];
            for (const r of to_json.roots.root_ids) {
                to_roots[r] = to_references[r];
                to_root_ids.push(r);
            }
            from_root_ids.sort();
            to_root_ids.sort();
            if (array_1.difference(from_root_ids, to_root_ids).length > 0 ||
                array_1.difference(to_root_ids, from_root_ids).length > 0) {
                // this would arise if someone does add_root/remove_root during
                // document deserialization, hopefully they won't ever do so.
                throw new Error("Not implemented: computing add/remove of document roots");
            }
            const value_refs = {};
            let events = [];
            for (const id in to_doc._all_models) {
                if (id in from_references) {
                    const update_model_events = Document._events_to_sync_objects(from_references[id], to_references[id], to_doc, value_refs);
                    events = events.concat(update_model_events);
                }
            }
            return {
                references: Document._references_json(object_1.values(value_refs), false),
                events,
            };
        }
        to_json_string(include_defaults = true) {
            return JSON.stringify(this.to_json(include_defaults));
        }
        to_json(include_defaults = true) {
            const root_ids = this._roots.map((r) => r.id);
            const root_references = object_1.values(this._all_models);
            return {
                version: version_1.version,
                title: this._title,
                roots: {
                    root_ids,
                    references: Document._references_json(root_references, include_defaults),
                },
            };
        }
        static from_json_string(s) {
            const json = JSON.parse(s);
            return Document.from_json(json);
        }
        static from_json(json) {
            logging_1.logger.debug("Creating Document from JSON");
            const py_version = json.version; // XXX!
            const is_dev = py_version.indexOf('+') !== -1 || py_version.indexOf('-') !== -1;
            const versions_string = `Library versions: JS (${version_1.version}) / Python (${py_version})`;
            if (!is_dev && version_1.version !== py_version) {
                logging_1.logger.warn("JS/Python version mismatch");
                logging_1.logger.warn(versions_string);
            }
            else
                logging_1.logger.debug(versions_string);
            const roots_json = json.roots;
            const root_ids = roots_json.root_ids;
            const references_json = roots_json.references;
            const references = Document._instantiate_references_json(references_json, {});
            Document._initialize_references_json(references_json, {}, references);
            const doc = new Document();
            for (const r of root_ids)
                doc.add_root(references[r]); // XXX: HasProps
            doc.set_title(json.title); // XXX!
            return doc;
        }
        replace_with_json(json) {
            const replacement = Document.from_json(json);
            replacement.destructively_move(this);
        }
        create_json_patch_string(events) {
            return JSON.stringify(this.create_json_patch(events));
        }
        create_json_patch(events) {
            const references = {};
            const json_events = [];
            for (const event of events) {
                if (event.document !== this) {
                    logging_1.logger.warn("Cannot create a patch using events from a different document, event had ", event.document, " we are ", this);
                    throw new Error("Cannot create a patch using events from a different document");
                }
                json_events.push(event.json(references));
            }
            return {
                events: json_events,
                references: Document._references_json(object_1.values(references)),
            };
        }
        apply_json_patch(patch, buffers = [], setter_id) {
            const references_json = patch.references;
            const events_json = patch.events;
            const references = Document._instantiate_references_json(references_json, this._all_models);
            // The model being changed isn't always in references so add it in
            for (const event_json of events_json) {
                switch (event_json.kind) {
                    case "RootAdded":
                    case "RootRemoved":
                    case "ModelChanged": {
                        const model_id = event_json.model.id;
                        if (model_id in this._all_models) {
                            references[model_id] = this._all_models[model_id];
                        }
                        else {
                            if (!(model_id in references)) {
                                logging_1.logger.warn("Got an event for unknown model ", event_json.model);
                                throw new Error("event model wasn't known");
                            }
                        }
                        break;
                    }
                }
            }
            // split references into old and new so we know whether to initialize or update
            const old_references = {};
            const new_references = {};
            for (const id in references) {
                const value = references[id];
                if (id in this._all_models)
                    old_references[id] = value;
                else
                    new_references[id] = value;
            }
            Document._initialize_references_json(references_json, old_references, new_references);
            for (const event_json of events_json) {
                switch (event_json.kind) {
                    case 'ModelChanged': {
                        const patched_id = event_json.model.id;
                        if (!(patched_id in this._all_models)) {
                            throw new Error(`Cannot apply patch to ${patched_id} which is not in the document`);
                        }
                        const patched_obj = this._all_models[patched_id];
                        const attr = event_json.attr;
                        const model_type = event_json.model.type;
                        // XXXX currently still need this first branch, some updates (initial?) go through here
                        if (attr === 'data' && model_type === 'ColumnDataSource') {
                            const [data, shapes] = serialization_1.decode_column_data(event_json.new, buffers);
                            patched_obj.setv({ _shapes: shapes, data }, { setter_id });
                        }
                        else {
                            const value = Document._resolve_refs(event_json.new, old_references, new_references);
                            patched_obj.setv({ [attr]: value }, { setter_id });
                        }
                        break;
                    }
                    case 'ColumnDataChanged': {
                        const column_source_id = event_json.column_source.id;
                        if (!(column_source_id in this._all_models)) {
                            throw new Error(`Cannot stream to ${column_source_id} which is not in the document`);
                        }
                        const column_source = this._all_models[column_source_id];
                        const [data, shapes] = serialization_1.decode_column_data(event_json.new, buffers);
                        if (event_json.cols != null) {
                            for (const k in column_source.data) {
                                if (!(k in data)) {
                                    data[k] = column_source.data[k];
                                }
                            }
                            for (const k in column_source._shapes) {
                                if (!(k in shapes)) {
                                    shapes[k] = column_source._shapes[k];
                                }
                            }
                        }
                        column_source.setv({
                            _shapes: shapes,
                            data,
                        }, {
                            setter_id,
                            check_eq: false,
                        });
                        break;
                    }
                    case 'ColumnsStreamed': {
                        const column_source_id = event_json.column_source.id;
                        if (!(column_source_id in this._all_models)) {
                            throw new Error(`Cannot stream to ${column_source_id} which is not in the document`);
                        }
                        const column_source = this._all_models[column_source_id];
                        if (!(column_source instanceof column_data_source_1.ColumnDataSource)) {
                            throw new Error("Cannot stream to non-ColumnDataSource");
                        }
                        const data = event_json.data;
                        const rollover = event_json.rollover;
                        column_source.stream(data, rollover, setter_id);
                        break;
                    }
                    case 'ColumnsPatched': {
                        const column_source_id = event_json.column_source.id;
                        if (!(column_source_id in this._all_models)) {
                            throw new Error(`Cannot patch ${column_source_id} which is not in the document`);
                        }
                        const column_source = this._all_models[column_source_id];
                        if (!(column_source instanceof column_data_source_1.ColumnDataSource)) {
                            throw new Error("Cannot patch non-ColumnDataSource");
                        }
                        const patches = event_json.patches;
                        column_source.patch(patches, setter_id);
                        break;
                    }
                    case 'RootAdded': {
                        const root_id = event_json.model.id;
                        const root_obj = references[root_id];
                        this.add_root(root_obj, setter_id); // XXX: HasProps
                        break;
                    }
                    case 'RootRemoved': {
                        const root_id = event_json.model.id;
                        const root_obj = references[root_id];
                        this.remove_root(root_obj, setter_id); // XXX: HasProps
                        break;
                    }
                    case 'TitleChanged': {
                        this.set_title(event_json.title, setter_id);
                        break;
                    }
                    default:
                        throw new Error("Unknown patch event " + JSON.stringify(event_json));
                }
            }
        }
    }
    exports.Document = Document;
    Document.__name__ = "Document";
},
/* base.js */ function _(require, module, exports) {
    const types_1 = require(7) /* ./core/util/types */;
    const has_props_1 = require(12) /* ./core/has_props */;
    exports.overrides = {};
    const _all_models = new Map();
    exports.Models = ((name) => {
        const model = exports.overrides[name] || _all_models.get(name);
        if (model == null) {
            throw new Error(`Model '${name}' does not exist. This could be due to a widget or a custom model not being registered before first usage.`);
        }
        return model;
    });
    exports.Models.register = (name, model) => {
        exports.overrides[name] = model;
    };
    exports.Models.unregister = (name) => {
        delete exports.overrides[name];
    };
    function is_HasProps(obj) {
        return types_1.isObject(obj) && obj.prototype instanceof has_props_1.HasProps;
    }
    exports.Models.register_models = (models, force = false, errorFn) => {
        if (models == null)
            return;
        for (const name in models) {
            const model = models[name];
            if (is_HasProps(model)) {
                const qualified = model.__qualified__;
                if (force || !_all_models.has(qualified))
                    _all_models.set(qualified, model);
                else if (errorFn != null)
                    errorFn(qualified);
                else
                    console.warn(`Model '${qualified}' was already registered`);
            }
        }
    };
    exports.register_models = exports.Models.register_models;
    exports.Models.registered_names = () => Array.from(_all_models.keys());
    // TODO: this doesn't belong here, but it's easier this way for backwards compatibility
    const AllModels = require(27) /* ./models */;
    exports.register_models(AllModels);
},
/* core/util/types.js */ function _(require, module, exports) {
    const array_1 = require(8) /* ./array */;
    const toString = Object.prototype.toString;
    function isBoolean(obj) {
        return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
    }
    exports.isBoolean = isBoolean;
    function isNumber(obj) {
        return toString.call(obj) === "[object Number]";
    }
    exports.isNumber = isNumber;
    function isInteger(obj) {
        return isNumber(obj) && isFinite(obj) && Math.floor(obj) === obj;
    }
    exports.isInteger = isInteger;
    function isString(obj) {
        return toString.call(obj) === "[object String]";
    }
    exports.isString = isString;
    function isStrictNaN(obj) {
        return isNumber(obj) && obj !== +obj;
    }
    exports.isStrictNaN = isStrictNaN;
    function isFunction(obj) {
        return toString.call(obj) === "[object Function]";
    }
    exports.isFunction = isFunction;
    function isArray(obj) {
        return Array.isArray(obj);
    }
    exports.isArray = isArray;
    function isArrayOf(arr, predicate) {
        return array_1.every(arr, predicate);
    }
    exports.isArrayOf = isArrayOf;
    function isArrayableOf(arr, predicate) {
        for (let i = 0, end = arr.length; i < end; i++) {
            if (!predicate(arr[i]))
                return false;
        }
        return true;
    }
    exports.isArrayableOf = isArrayableOf;
    function isTypedArray(obj) {
        return obj != null && obj.buffer instanceof ArrayBuffer;
    }
    exports.isTypedArray = isTypedArray;
    function isObject(obj) {
        const tp = typeof obj;
        return tp === 'function' || tp === 'object' && !!obj;
    }
    exports.isObject = isObject;
    function isPlainObject(obj) {
        return isObject(obj) && (obj.constructor == null || obj.constructor === Object);
    }
    exports.isPlainObject = isPlainObject;
},
/* core/util/array.js */ function _(require, module, exports) {
    const math_1 = require(9) /* ./math */;
    const assert_1 = require(10) /* ./assert */;
    const arrayable_1 = require(11) /* ./arrayable */;
    exports.map = arrayable_1.map;
    exports.reduce = arrayable_1.reduce;
    exports.min = arrayable_1.min;
    exports.min_by = arrayable_1.min_by;
    exports.max = arrayable_1.max;
    exports.max_by = arrayable_1.max_by;
    exports.sum = arrayable_1.sum;
    exports.cumsum = arrayable_1.cumsum;
    exports.every = arrayable_1.every;
    exports.some = arrayable_1.some;
    exports.find = arrayable_1.find;
    exports.find_last = arrayable_1.find_last;
    exports.find_index = arrayable_1.find_index;
    exports.find_last_index = arrayable_1.find_last_index;
    exports.sorted_index = arrayable_1.sorted_index;
    const slice = Array.prototype.slice;
    function head(array) {
        return array[0];
    }
    exports.head = head;
    function tail(array) {
        return array[array.length - 1];
    }
    exports.tail = tail;
    function last(array) {
        return array[array.length - 1];
    }
    exports.last = last;
    function copy(array) {
        return slice.call(array);
    }
    exports.copy = copy;
    function concat(arrays) {
        return [].concat(...arrays);
    }
    exports.concat = concat;
    function includes(array, value) {
        return array.indexOf(value) !== -1;
    }
    exports.includes = includes;
    exports.contains = includes;
    function nth(array, index) {
        return array[index >= 0 ? index : array.length + index];
    }
    exports.nth = nth;
    function zip(...arrays) {
        if (arrays.length == 0)
            return [];
        const n = arrayable_1.min(arrays.map((a) => a.length));
        const k = arrays.length;
        const result = new Array(n);
        for (let i = 0; i < n; i++) {
            result[i] = new Array(k);
            for (let j = 0; j < k; j++)
                result[i][j] = arrays[j][i];
        }
        return result;
    }
    exports.zip = zip;
    function unzip(array) {
        const n = array.length;
        const k = arrayable_1.min(array.map((a) => a.length));
        const results = Array(k);
        for (let j = 0; j < k; j++)
            results[j] = new Array(n);
        for (let i = 0; i < n; i++) {
            for (let j = 0; j < k; j++)
                results[j][i] = array[i][j];
        }
        return results;
    }
    exports.unzip = unzip;
    function range(start, stop, step = 1) {
        assert_1.assert(step > 0, "'step' must be a positive number");
        if (stop == null) {
            stop = start;
            start = 0;
        }
        const { max, ceil, abs } = Math;
        const delta = start <= stop ? step : -step;
        const length = max(ceil(abs(stop - start) / step), 0);
        const range = Array(length);
        for (let i = 0; i < length; i++, start += delta) {
            range[i] = start;
        }
        return range;
    }
    exports.range = range;
    function linspace(start, stop, num = 100) {
        const step = (stop - start) / (num - 1);
        const array = new Array(num);
        for (let i = 0; i < num; i++) {
            array[i] = start + step * i;
        }
        return array;
    }
    exports.linspace = linspace;
    function transpose(array) {
        const rows = array.length;
        const cols = array[0].length;
        const transposed = [];
        for (let j = 0; j < cols; j++) {
            transposed[j] = [];
            for (let i = 0; i < rows; i++) {
                transposed[j][i] = array[i][j];
            }
        }
        return transposed;
    }
    exports.transpose = transpose;
    function argmin(array) {
        return arrayable_1.min_by(range(array.length), (i) => array[i]);
    }
    exports.argmin = argmin;
    function argmax(array) {
        return arrayable_1.max_by(range(array.length), (i) => array[i]);
    }
    exports.argmax = argmax;
    function sort_by(array, key) {
        const tmp = array.map((value, index) => {
            return { value, index, key: key(value) };
        });
        tmp.sort((left, right) => {
            const a = left.key;
            const b = right.key;
            if (a !== b) {
                if (a > b || a === undefined)
                    return 1;
                if (a < b || b === undefined)
                    return -1;
            }
            return left.index - right.index;
        });
        return tmp.map((item) => item.value);
    }
    exports.sort_by = sort_by;
    function uniq(array) {
        const result = [];
        for (const value of array) {
            if (!includes(result, value)) {
                result.push(value);
            }
        }
        return result;
    }
    exports.uniq = uniq;
    function uniq_by(array, key) {
        const result = [];
        const seen = [];
        for (const value of array) {
            const computed = key(value);
            if (!includes(seen, computed)) {
                seen.push(computed);
                result.push(value);
            }
        }
        return result;
    }
    exports.uniq_by = uniq_by;
    function union(...arrays) {
        return uniq(concat(arrays));
    }
    exports.union = union;
    function intersection(array, ...arrays) {
        const result = [];
        top: for (const item of array) {
            if (includes(result, item))
                continue;
            for (const other of arrays) {
                if (!includes(other, item))
                    continue top;
            }
            result.push(item);
        }
        return result;
    }
    exports.intersection = intersection;
    function difference(array, ...arrays) {
        const rest = concat(arrays);
        return array.filter((value) => !includes(rest, value));
    }
    exports.difference = difference;
    function remove_at(array, i) {
        const result = copy(array);
        result.splice(i, 1);
        return result;
    }
    exports.remove_at = remove_at;
    function remove_by(array, key) {
        for (let i = 0; i < array.length;) {
            if (key(array[i]))
                array.splice(i, 1);
            else
                i++;
        }
    }
    exports.remove_by = remove_by;
    // Shuffle a collection, using the modern version of the
    // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
    function shuffle(array) {
        const length = array.length;
        const shuffled = new Array(length);
        for (let i = 0; i < length; i++) {
            const rand = math_1.randomIn(0, i);
            if (rand !== i)
                shuffled[i] = shuffled[rand];
            shuffled[rand] = array[i];
        }
        return shuffled;
    }
    exports.shuffle = shuffle;
    function pairwise(array, fn) {
        const n = array.length;
        const result = new Array(n - 1);
        for (let i = 0; i < n - 1; i++) {
            result[i] = fn(array[i], array[i + 1]);
        }
        return result;
    }
    exports.pairwise = pairwise;
    function reversed(array) {
        const n = array.length;
        const result = new Array(n);
        for (let i = 0; i < n; i++) {
            result[n - i - 1] = array[i];
        }
        return result;
    }
    exports.reversed = reversed;
    function repeat(value, n) {
        const result = new Array(n);
        for (let i = 0; i < n; i++) {
            result[i] = value;
        }
        return result;
    }
    exports.repeat = repeat;
},
/* core/util/math.js */ function _(require, module, exports) {
    function angle_norm(angle) {
        if (angle == 0) {
            return 0;
        }
        while (angle <= 0) {
            angle += 2 * Math.PI;
        }
        while (angle > 2 * Math.PI) {
            angle -= 2 * Math.PI;
        }
        return angle;
    }
    exports.angle_norm = angle_norm;
    function angle_dist(lhs, rhs) {
        return angle_norm(lhs - rhs);
    }
    exports.angle_dist = angle_dist;
    function angle_between(mid, lhs, rhs, direction) {
        const d = angle_dist(lhs, rhs);
        if (d == 0)
            return false;
        if (d == 2 * Math.PI)
            return true;
        const norm_mid = angle_norm(mid);
        const cond = angle_dist(lhs, norm_mid) <= d && angle_dist(norm_mid, rhs) <= d;
        return (direction == 0 /* clock */) ? cond : !cond;
    }
    exports.angle_between = angle_between;
    function random() {
        return Math.random();
    }
    exports.random = random;
    function randomIn(min, max) {
        if (max == null) {
            max = min;
            min = 0;
        }
        return min + Math.floor(Math.random() * (max - min + 1));
    }
    exports.randomIn = randomIn;
    function atan2(start, end) {
        /*
         * Calculate the angle between a line containing start and end points (composed
         * of [x, y] arrays) and the positive x-axis.
         */
        return Math.atan2(end[1] - start[1], end[0] - start[0]);
    }
    exports.atan2 = atan2;
    // http://www2.econ.osaka-u.ac.jp/~tanizaki/class/2013/econome3/13.pdf (Page 432)
    function rnorm(mu, sigma) {
        // Generate a random normal with a mean of 0 and a sigma of 1
        let r1;
        let r2;
        while (true) {
            r1 = random();
            r2 = random();
            r2 = (2 * r2 - 1) * Math.sqrt(2 * (1 / Math.E));
            if (-4 * r1 * r1 * Math.log(r1) >= r2 * r2)
                break;
        }
        let rn = r2 / r1;
        // Transform the standard normal to meet the characteristics that we want (mu, sigma)
        rn = mu + sigma * rn;
        return rn;
    }
    exports.rnorm = rnorm;
    function clamp(val, min, max) {
        if (val > max)
            return max;
        if (val < min)
            return min;
        return val;
    }
    exports.clamp = clamp;
},
/* core/util/assert.js */ function _(require, module, exports) {
    class AssertionError extends Error {
    }
    exports.AssertionError = AssertionError;
    AssertionError.__name__ = "AssertionError";
    function assert(condition, message) {
        if (condition === true || (condition !== false && condition()))
            return;
        throw new AssertionError(message || "Assertion failed");
    }
    exports.assert = assert;
},
/* core/util/arrayable.js */ function _(require, module, exports) {
    function splice(array, start, k, ...items) {
        const len = array.length;
        if (start < 0)
            start += len;
        if (start < 0)
            start = 0;
        else if (start > len)
            start = len;
        if (k == null || k > len - start)
            k = len - start;
        else if (k < 0)
            k = 0;
        const n = len - k + items.length;
        const result = new array.constructor(n);
        let i = 0;
        for (; i < start; i++) {
            result[i] = array[i];
        }
        for (const item of items) {
            result[i++] = item;
        }
        for (let j = start + k; j < len; j++) {
            result[i++] = array[j];
        }
        return result;
    }
    exports.splice = splice;
    function head(array, n) {
        return splice(array, n, array.length - n);
    }
    exports.head = head;
    function insert(array, item, i) {
        return splice(array, i, 0, item);
    }
    exports.insert = insert;
    function append(array, item) {
        return splice(array, array.length, 0, item);
    }
    exports.append = append;
    function prepend(array, item) {
        return splice(array, 0, 0, item);
    }
    exports.prepend = prepend;
    function indexOf(array, item) {
        for (let i = 0, n = array.length; i < n; i++) {
            if (array[i] === item)
                return i;
        }
        return -1;
    }
    exports.indexOf = indexOf;
    function map(array, fn) {
        const n = array.length;
        const result = new array.constructor(n);
        for (let i = 0; i < n; i++) {
            result[i] = fn(array[i], i, array);
        }
        return result;
    }
    exports.map = map;
    function filter(array, pred) {
        const n = array.length;
        const result = new array.constructor(n);
        let k = 0;
        for (let i = 0; i < n; i++) {
            const value = array[i];
            if (pred(value, i, array))
                result[k++] = value;
        }
        return head(result, k);
    }
    exports.filter = filter;
    function reduce(array, fn, initial) {
        const n = array.length;
        if (initial === undefined && n == 0)
            throw new Error("can't reduce an empty array without an initial value");
        let value;
        let i;
        if (initial === undefined) {
            value = array[0];
            i = 1;
        }
        else {
            value = initial;
            i = 0;
        }
        for (; i < n; i++) {
            value = fn(value, array[i], i, array);
        }
        return value;
    }
    exports.reduce = reduce;
    function min(array) {
        let value;
        let result = Infinity;
        for (let i = 0, length = array.length; i < length; i++) {
            value = array[i];
            if (value < result) {
                result = value;
            }
        }
        return result;
    }
    exports.min = min;
    function min_by(array, key) {
        if (array.length == 0)
            throw new Error("min_by() called with an empty array");
        let result = array[0];
        let resultComputed = key(result);
        for (let i = 1, length = array.length; i < length; i++) {
            const value = array[i];
            const computed = key(value);
            if (computed < resultComputed) {
                result = value;
                resultComputed = computed;
            }
        }
        return result;
    }
    exports.min_by = min_by;
    function max(array) {
        let value;
        let result = -Infinity;
        for (let i = 0, length = array.length; i < length; i++) {
            value = array[i];
            if (value > result) {
                result = value;
            }
        }
        return result;
    }
    exports.max = max;
    function max_by(array, key) {
        if (array.length == 0)
            throw new Error("max_by() called with an empty array");
        let result = array[0];
        let resultComputed = key(result);
        for (let i = 1, length = array.length; i < length; i++) {
            const value = array[i];
            const computed = key(value);
            if (computed > resultComputed) {
                result = value;
                resultComputed = computed;
            }
        }
        return result;
    }
    exports.max_by = max_by;
    function sum(array) {
        let result = 0;
        for (let i = 0, n = array.length; i < n; i++) {
            result += array[i];
        }
        return result;
    }
    exports.sum = sum;
    function cumsum(array) {
        const result = new array.constructor(array.length);
        reduce(array, (a, b, i) => result[i] = a + b, 0);
        return result;
    }
    exports.cumsum = cumsum;
    function every(array, predicate) {
        for (let i = 0, length = array.length; i < length; i++) {
            if (!predicate(array[i]))
                return false;
        }
        return true;
    }
    exports.every = every;
    function some(array, predicate) {
        for (let i = 0, length = array.length; i < length; i++) {
            if (predicate(array[i]))
                return true;
        }
        return false;
    }
    exports.some = some;
    function index_of(array, value) {
        for (let i = 0, length = array.length; i < length; i++) {
            if (array[i] === value)
                return i;
        }
        return -1;
    }
    exports.index_of = index_of;
    function _find_index(dir) {
        return function (array, predicate) {
            const length = array.length;
            let index = dir > 0 ? 0 : length - 1;
            for (; index >= 0 && index < length; index += dir) {
                if (predicate(array[index]))
                    return index;
            }
            return -1;
        };
    }
    exports.find_index = _find_index(1);
    exports.find_last_index = _find_index(-1);
    function find(array, predicate) {
        const index = exports.find_index(array, predicate);
        return index == -1 ? undefined : array[index];
    }
    exports.find = find;
    function find_last(array, predicate) {
        const index = exports.find_last_index(array, predicate);
        return index == -1 ? undefined : array[index];
    }
    exports.find_last = find_last;
    function sorted_index(array, value) {
        let low = 0;
        let high = array.length;
        while (low < high) {
            const mid = Math.floor((low + high) / 2);
            if (array[mid] < value)
                low = mid + 1;
            else
                high = mid;
        }
        return low;
    }
    exports.sorted_index = sorted_index;
},
/* core/has_props.js */ function _(require, module, exports) {
    const signaling_1 = require(13) /* ./signaling */;
    const property_mixins = require(17) /* ./property_mixins */;
    const refs_1 = require(24) /* ./util/refs */;
    const p = require(18) /* ./properties */;
    const string_1 = require(25) /* ./util/string */;
    const array_1 = require(8) /* ./util/array */;
    const object_1 = require(22) /* ./util/object */;
    const types_1 = require(7) /* ./util/types */;
    const eq_1 = require(15) /* ./util/eq */;
    class HasProps extends signaling_1.Signalable() {
        constructor(attrs = {}) {
            super();
            this._subtype = undefined;
            this.document = null;
            this.destroyed = new signaling_1.Signal0(this, "destroyed");
            this.change = new signaling_1.Signal0(this, "change");
            this.transformchange = new signaling_1.Signal0(this, "transformchange");
            this.attributes = {};
            this.properties = {};
            this._set_after_defaults = {};
            this._pending = false;
            this._changing = false;
            for (const name in this.props) {
                const { type, default_value } = this.props[name];
                if (type != null)
                    this.properties[name] = new type(this, name, default_value);
                else
                    throw new Error(`undefined property type for ${this.type}.${name}`);
            }
            // auto generating ID
            if (attrs.id == null)
                this.setv({ id: string_1.uniqueId() }, { silent: true });
            const deferred = attrs.__deferred__ || false;
            if (deferred) {
                attrs = object_1.clone(attrs);
                delete attrs.__deferred__;
            }
            this.setv(attrs, { silent: true });
            // allowing us to defer initialization when loading many models
            // when loading a bunch of models, we want to do initialization as a second pass
            // because other objects that this one depends on might not be loaded yet
            if (!deferred)
                this.finalize();
        }
        // XXX: setter is only required for backwards compatibility
        set type(name) {
            console.warn("prototype.type = 'ModelName' is deprecated, use static __name__ instead");
            this.constructor.__name__ = name;
        }
        get type() {
            return this.constructor.__qualified__;
        }
        static get __qualified__() {
            const { __module__, __name__ } = this;
            return __module__ != null ? `${__module__}.${__name__}` : __name__;
        }
        static init_HasProps() {
            this.prototype.props = {};
            this.prototype.mixins = [];
            this.define({
                id: [p.Any],
            });
        }
        // }}}
        static _fix_default(default_value, _attr) {
            if (default_value === undefined)
                return undefined;
            else if (types_1.isFunction(default_value))
                return default_value;
            else if (!types_1.isObject(default_value))
                return () => default_value;
            else {
                //logger.warn(`${this.prototype.type}.${attr} uses unwrapped non-primitive default value`)
                if (types_1.isArray(default_value))
                    return () => array_1.copy(default_value);
                else
                    return () => object_1.clone(default_value);
            }
        }
        // TODO: don't use Partial<>, but exclude inherited properties
        static define(obj) {
            for (const name in obj) {
                const prop = obj[name];
                if (this.prototype.props[name] != null)
                    throw new Error(`attempted to redefine property '${this.prototype.type}.${name}'`);
                if (this.prototype[name] != null)
                    throw new Error(`attempted to redefine attribute '${this.prototype.type}.${name}'`);
                Object.defineProperty(this.prototype, name, {
                    // XXX: don't use tail calls in getters/setters due to https://bugs.webkit.org/show_bug.cgi?id=164306
                    get() {
                        const value = this.getv(name);
                        return value;
                    },
                    set(value) {
                        this.setv({ [name]: value });
                        return this;
                    },
                    configurable: false,
                    enumerable: true,
                });
                const [type, default_value, internal] = prop;
                const refined_prop = {
                    type,
                    default_value: this._fix_default(default_value, name),
                    internal: internal || false,
                };
                const props = object_1.clone(this.prototype.props);
                props[name] = refined_prop;
                this.prototype.props = props;
            }
        }
        static internal(obj) {
            const _object = {};
            for (const name in obj) {
                const prop = obj[name];
                const [type, default_value] = prop;
                _object[name] = [type, default_value, true];
            }
            this.define(_object);
        }
        static mixin(...names) {
            this.define(property_mixins.create(names));
            const mixins = this.prototype.mixins.concat(names);
            this.prototype.mixins = mixins;
        }
        static mixins(names) {
            this.mixin(...names);
        }
        static override(obj) {
            for (const name in obj) {
                const default_value = this._fix_default(obj[name], name);
                const value = this.prototype.props[name];
                if (value == null)
                    throw new Error(`attempted to override nonexistent '${this.prototype.type}.${name}'`);
                const props = object_1.clone(this.prototype.props);
                props[name] = Object.assign(Object.assign({}, value), { default_value });
                this.prototype.props = props;
            }
        }
        toString() {
            return `${this.type}(${this.id})`;
        }
        finalize() {
            // This is necessary because the initial creation of properties relies on
            // model.get which is not usable at that point yet in the constructor. This
            // initializer is called when deferred initialization happens for all models
            // and insures that the Bokeh properties are initialized from Backbone
            // attributes in a consistent way.
            //
            // TODO (bev) split property creation up into two parts so that only the
            // portion of init that can be done happens in HasProps constructor and so
            // that subsequent updates do not duplicate that setup work.
            for (const name in this.properties) {
                const prop = this.properties[name];
                prop.update();
                if (prop.spec.transform != null)
                    this.connect(prop.spec.transform.change, () => this.transformchange.emit());
            }
            this.initialize();
            this.connect_signals();
        }
        initialize() { }
        connect_signals() { }
        disconnect_signals() {
            signaling_1.Signal.disconnectReceiver(this);
        }
        destroy() {
            this.disconnect_signals();
            this.destroyed.emit();
        }
        // Create a new model with identical attributes to this one.
        clone() {
            return new this.constructor(this.attributes);
        }
        // Set a hash of model attributes on the object, firing `"change"`. This is
        // the core primitive operation of a model, updating the data and notifying
        // anyone who needs to know about the change in state. The heart of the beast.
        _setv(attrs, options) {
            // Extract attributes and options.
            const check_eq = options.check_eq;
            const silent = options.silent;
            const changes = [];
            const changing = this._changing;
            this._changing = true;
            const current = this.attributes;
            // For each `set` attribute, update or delete the current value.
            for (const attr in attrs) {
                const val = attrs[attr];
                if (check_eq !== false) {
                    if (!eq_1.isEqual(current[attr], val))
                        changes.push(attr);
                }
                else
                    changes.push(attr);
                current[attr] = val;
            }
            // Trigger all relevant attribute changes.
            if (!silent) {
                if (changes.length > 0)
                    this._pending = true;
                for (let i = 0; i < changes.length; i++)
                    this.properties[changes[i]].change.emit();
            }
            // You might be wondering why there's a `while` loop here. Changes can
            // be recursively nested within `"change"` events.
            if (changing)
                return;
            if (!silent && !options.no_change) {
                while (this._pending) {
                    this._pending = false;
                    this.change.emit();
                }
            }
            this._pending = false;
            this._changing = false;
        }
        setv(attrs, options = {}) {
            for (const key in attrs) {
                if (!attrs.hasOwnProperty(key))
                    continue;
                const prop_name = key;
                if (this.props[prop_name] == null)
                    throw new Error(`property ${this.type}.${prop_name} wasn't declared`);
                if (!(options != null && options.defaults))
                    this._set_after_defaults[key] = true;
            }
            if (!object_1.isEmpty(attrs)) {
                const old = {};
                for (const key in attrs)
                    old[key] = this.getv(key);
                this._setv(attrs, options);
                const silent = options.silent;
                if (silent == null || !silent) {
                    for (const key in attrs)
                        this._tell_document_about_change(key, old[key], this.getv(key), options);
                }
            }
        }
        getv(prop_name) {
            if (this.props[prop_name] == null)
                throw new Error(`property ${this.type}.${prop_name} wasn't declared`);
            else
                return this.attributes[prop_name];
        }
        ref() {
            return refs_1.create_ref(this);
        }
        // we only keep the subtype so we match Python;
        // only Python cares about this
        set_subtype(subtype) {
            this._subtype = subtype;
        }
        attribute_is_serializable(attr) {
            const prop = this.props[attr];
            if (prop == null)
                throw new Error(`${this.type}.attribute_is_serializable('${attr}'): ${attr} wasn't declared`);
            else
                return !prop.internal;
        }
        // dict of attributes that should be serialized to the server. We
        // sometimes stick things in attributes that aren't part of the
        // Document's models, subtypes that do that have to remove their
        // extra attributes here.
        serializable_attributes() {
            const attrs = {};
            for (const name in this.attributes) {
                const value = this.attributes[name];
                if (this.attribute_is_serializable(name))
                    attrs[name] = value;
            }
            return attrs;
        }
        static _value_to_json(_key, value, _optional_parent_object) {
            if (value instanceof HasProps)
                return value.ref();
            else if (types_1.isArray(value)) {
                const ref_array = [];
                for (let i = 0; i < value.length; i++) {
                    const v = value[i];
                    ref_array.push(HasProps._value_to_json(i.toString(), v, value));
                }
                return ref_array;
            }
            else if (types_1.isPlainObject(value)) {
                const ref_obj = {};
                for (const subkey in value) {
                    if (value.hasOwnProperty(subkey))
                        ref_obj[subkey] = HasProps._value_to_json(subkey, value[subkey], value);
                }
                return ref_obj;
            }
            else
                return value;
        }
        // Convert attributes to "shallow" JSON (values which are themselves models
        // are included as just references)
        attributes_as_json(include_defaults = true, value_to_json = HasProps._value_to_json) {
            const serializable = this.serializable_attributes();
            const attrs = {};
            for (const key in serializable) {
                if (serializable.hasOwnProperty(key)) {
                    const value = serializable[key];
                    if (include_defaults)
                        attrs[key] = value;
                    else if (key in this._set_after_defaults)
                        attrs[key] = value;
                }
            }
            return value_to_json("attributes", attrs, this);
        }
        // this is like _value_record_references but expects to find refs
        // instead of models, and takes a doc to look up the refs in
        static _json_record_references(doc, v, result, recurse) {
            if (v == null) {
            }
            else if (refs_1.is_ref(v)) {
                if (!(v.id in result)) {
                    const model = doc.get_model_by_id(v.id);
                    HasProps._value_record_references(model, result, recurse);
                }
            }
            else if (types_1.isArray(v)) {
                for (const elem of v)
                    HasProps._json_record_references(doc, elem, result, recurse);
            }
            else if (types_1.isPlainObject(v)) {
                for (const k in v) {
                    if (v.hasOwnProperty(k)) {
                        const elem = v[k];
                        HasProps._json_record_references(doc, elem, result, recurse);
                    }
                }
            }
        }
        // add all references from 'v' to 'result', if recurse
        // is true then descend into refs, if false only
        // descend into non-refs
        static _value_record_references(v, result, recurse) {
            if (v == null) {
            }
            else if (v instanceof HasProps) {
                if (!(v.id in result)) {
                    result[v.id] = v;
                    if (recurse) {
                        const immediate = v._immediate_references();
                        for (const obj of immediate)
                            HasProps._value_record_references(obj, result, true); // true=recurse
                    }
                }
            }
            else if (v.buffer instanceof ArrayBuffer) {
            }
            else if (types_1.isArray(v)) {
                for (const elem of v)
                    HasProps._value_record_references(elem, result, recurse);
            }
            else if (types_1.isPlainObject(v)) {
                for (const k in v) {
                    if (v.hasOwnProperty(k)) {
                        const elem = v[k];
                        HasProps._value_record_references(elem, result, recurse);
                    }
                }
            }
        }
        // Get models that are immediately referenced by our properties
        // (do not recurse, do not include ourselves)
        _immediate_references() {
            const result = {};
            const attrs = this.serializable_attributes();
            for (const key in attrs) {
                const value = attrs[key];
                HasProps._value_record_references(value, result, false); // false = no recurse
            }
            return object_1.values(result);
        }
        references() {
            const references = {};
            HasProps._value_record_references(this, references, true);
            return object_1.values(references);
        }
        _doc_attached() { }
        attach_document(doc) {
            // This should only be called by the Document implementation to set the document field
            if (this.document != null && this.document != doc)
                throw new Error("models must be owned by only a single document");
            this.document = doc;
            this._doc_attached();
        }
        detach_document() {
            // This should only be called by the Document implementation to unset the document field
            this.document = null;
        }
        _tell_document_about_change(attr, old, new_, options) {
            if (!this.attribute_is_serializable(attr))
                return;
            if (this.document != null) {
                const new_refs = {};
                HasProps._value_record_references(new_, new_refs, false);
                const old_refs = {};
                HasProps._value_record_references(old, old_refs, false);
                let need_invalidate = false;
                for (const new_id in new_refs) {
                    if (!(new_id in old_refs)) {
                        need_invalidate = true;
                        break;
                    }
                }
                if (!need_invalidate) {
                    for (const old_id in old_refs) {
                        if (!(old_id in new_refs)) {
                            need_invalidate = true;
                            break;
                        }
                    }
                }
                if (need_invalidate)
                    this.document._invalidate_all_models();
                this.document._notify_change(this, attr, old, new_, options);
            }
        }
        materialize_dataspecs(source) {
            // Note: this should be moved to a function separate from HasProps
            const data = {};
            for (const name in this.properties) {
                const prop = this.properties[name];
                if (!(prop instanceof p.VectorSpec))
                    continue;
                // this skips optional properties like radius for circles
                if (prop.optional && prop.spec.value == null && !(name in this._set_after_defaults))
                    continue;
                const array = prop.array(source);
                data[`_${name}`] = array;
                // the shapes are indexed by the column name, but when we materialize the dataspec, we should
                // store under the canonical field name, e.g. _image_shape, even if the column name is "foo"
                if (prop.spec.field != null && prop.spec.field in source._shapes)
                    data[`_${name}_shape`] = source._shapes[prop.spec.field];
                if (prop instanceof p.DistanceSpec)
                    data[`max_${name}`] = array_1.max(array);
            }
            return data;
        }
    }
    exports.HasProps = HasProps;
    HasProps.init_HasProps();
},
/* core/signaling.js */ function _(require, module, exports) {
    const data_structures_1 = require(14) /* ./util/data_structures */;
    const callback_1 = require(16) /* ./util/callback */;
    const array_1 = require(8) /* ./util/array */;
    class Signal {
        constructor(sender, name) {
            this.sender = sender;
            this.name = name;
        }
        connect(slot, context = null) {
            if (!receiversForSender.has(this.sender)) {
                receiversForSender.set(this.sender, []);
            }
            const receivers = receiversForSender.get(this.sender);
            if (findConnection(receivers, this, slot, context) != null) {
                return false;
            }
            const receiver = context || slot;
            if (!sendersForReceiver.has(receiver)) {
                sendersForReceiver.set(receiver, []);
            }
            const senders = sendersForReceiver.get(receiver);
            const connection = { signal: this, slot, context };
            receivers.push(connection);
            senders.push(connection);
            return true;
        }
        disconnect(slot, context = null) {
            const receivers = receiversForSender.get(this.sender);
            if (receivers == null || receivers.length === 0) {
                return false;
            }
            const connection = findConnection(receivers, this, slot, context);
            if (connection == null) {
                return false;
            }
            const receiver = context || slot;
            const senders = sendersForReceiver.get(receiver);
            connection.signal = null;
            scheduleCleanup(receivers);
            scheduleCleanup(senders);
            return true;
        }
        emit(args) {
            const receivers = receiversForSender.get(this.sender) || [];
            for (const { signal, slot, context } of receivers) {
                if (signal === this) {
                    slot.call(context, args, this.sender);
                }
            }
        }
    }
    exports.Signal = Signal;
    Signal.__name__ = "Signal";
    class Signal0 extends Signal {
        emit() {
            super.emit(undefined);
        }
    }
    exports.Signal0 = Signal0;
    Signal0.__name__ = "Signal0";
    (function (Signal) {
        function disconnectBetween(sender, receiver) {
            const receivers = receiversForSender.get(sender);
            if (receivers == null || receivers.length === 0)
                return;
            const senders = sendersForReceiver.get(receiver);
            if (senders == null || senders.length === 0)
                return;
            for (const connection of senders) {
                if (connection.signal == null)
                    return;
                if (connection.signal.sender === sender)
                    connection.signal = null;
            }
            scheduleCleanup(receivers);
            scheduleCleanup(senders);
        }
        Signal.disconnectBetween = disconnectBetween;
        function disconnectSender(sender) {
            const receivers = receiversForSender.get(sender);
            if (receivers == null || receivers.length === 0)
                return;
            for (const connection of receivers) {
                if (connection.signal == null)
                    return;
                const receiver = connection.context || connection.slot;
                connection.signal = null;
                scheduleCleanup(sendersForReceiver.get(receiver));
            }
            scheduleCleanup(receivers);
        }
        Signal.disconnectSender = disconnectSender;
        function disconnectReceiver(receiver) {
            const senders = sendersForReceiver.get(receiver);
            if (senders == null || senders.length === 0)
                return;
            for (const connection of senders) {
                if (connection.signal == null)
                    return;
                const sender = connection.signal.sender;
                connection.signal = null;
                scheduleCleanup(receiversForSender.get(sender));
            }
            scheduleCleanup(senders);
        }
        Signal.disconnectReceiver = disconnectReceiver;
        function disconnectAll(obj) {
            const receivers = receiversForSender.get(obj);
            if (receivers != null && receivers.length !== 0) {
                for (const connection of receivers) {
                    connection.signal = null;
                }
                scheduleCleanup(receivers);
            }
            const senders = sendersForReceiver.get(obj);
            if (senders != null && senders.length !== 0) {
                for (const connection of senders) {
                    connection.signal = null;
                }
                scheduleCleanup(senders);
            }
        }
        Signal.disconnectAll = disconnectAll;
    })(Signal = exports.Signal || (exports.Signal = {}));
    function Signalable(Base) {
        // XXX: `class Foo extends Signalable(Object)` doesn't work (compiles, but fails at runtime), so
        // we have to do this to allow signalable classes without an explict base class.
        if (Base != null) {
            return class extends Base {
                connect(signal, slot) {
                    return signal.connect(slot, this);
                }
                disconnect(signal, slot) {
                    return signal.disconnect(slot, this);
                }
            };
        }
        else {
            return class {
                connect(signal, slot) {
                    return signal.connect(slot, this);
                }
                disconnect(signal, slot) {
                    return signal.disconnect(slot, this);
                }
            };
        }
    }
    exports.Signalable = Signalable;
    var _Signalable;
    (function (_Signalable) {
        function connect(signal, slot) {
            return signal.connect(slot, this);
        }
        _Signalable.connect = connect;
        function disconnect(signal, slot) {
            return signal.disconnect(slot, this);
        }
        _Signalable.disconnect = disconnect;
    })(_Signalable = exports._Signalable || (exports._Signalable = {}));
    const receiversForSender = new WeakMap();
    const sendersForReceiver = new WeakMap();
    function findConnection(conns, signal, slot, context) {
        return array_1.find(conns, conn => conn.signal === signal && conn.slot === slot && conn.context === context);
    }
    const dirtySet = new data_structures_1.Set();
    function scheduleCleanup(connections) {
        if (dirtySet.size === 0) {
            callback_1.defer(cleanupDirtySet);
        }
        dirtySet.add(connections);
    }
    function cleanupDirtySet() {
        dirtySet.forEach((connections) => {
            array_1.remove_by(connections, (connection) => connection.signal == null);
        });
        dirtySet.clear();
    }
},
/* core/util/data_structures.js */ function _(require, module, exports) {
    const array_1 = require(8) /* ./array */;
    const eq_1 = require(15) /* ./eq */;
    const types_1 = require(7) /* ./types */;
    class MultiDict {
        constructor() {
            this._dict = {};
        }
        _existing(key) {
            if (key in this._dict)
                return this._dict[key];
            else
                return null;
        }
        add_value(key, value) {
            /*
            if value == null
              throw new Error("Can't put null in this dict")
            if isArray(value)
              throw new Error("Can't put arrays in this dict")
            */
            const existing = this._existing(key);
            if (existing == null) {
                this._dict[key] = value;
            }
            else if (types_1.isArray(existing)) {
                existing.push(value);
            }
            else {
                this._dict[key] = [existing, value];
            }
        }
        remove_value(key, value) {
            const existing = this._existing(key);
            if (types_1.isArray(existing)) {
                const new_array = array_1.difference(existing, [value]);
                if (new_array.length > 0)
                    this._dict[key] = new_array;
                else
                    delete this._dict[key];
            }
            else if (eq_1.isEqual(existing, value)) {
                delete this._dict[key];
            }
        }
        get_one(key, duplicate_error) {
            const existing = this._existing(key);
            if (types_1.isArray(existing)) {
                if (existing.length === 1)
                    return existing[0];
                else
                    throw new Error(duplicate_error);
            }
            else
                return existing;
        }
    }
    exports.MultiDict = MultiDict;
    MultiDict.__name__ = "MultiDict";
    class Set {
        constructor(obj) {
            if (obj == null)
                this._values = [];
            else if (obj instanceof Set)
                this._values = array_1.copy(obj._values);
            else {
                this._values = [];
                for (const item of obj)
                    this.add(item);
            }
        }
        get values() {
            return array_1.copy(this._values).sort();
        }
        toString() {
            return `Set([${this.values.join(",")}])`;
        }
        get size() {
            return this._values.length;
        }
        has(item) {
            return this._values.indexOf(item) !== -1;
        }
        add(item) {
            if (!this.has(item))
                this._values.push(item);
        }
        remove(item) {
            const i = this._values.indexOf(item);
            if (i !== -1)
                this._values.splice(i, 1);
        }
        toggle(item) {
            const i = this._values.indexOf(item);
            if (i === -1)
                this._values.push(item);
            else
                this._values.splice(i, 1);
        }
        clear() {
            this._values = [];
        }
        union(input) {
            input = new Set(input);
            return new Set(this._values.concat(input._values));
        }
        intersect(input) {
            input = new Set(input);
            const output = new Set();
            for (const item of input._values) {
                if (this.has(item) && input.has(item))
                    output.add(item);
            }
            return output;
        }
        diff(input) {
            input = new Set(input);
            const output = new Set();
            for (const item of this._values) {
                if (!input.has(item))
                    output.add(item);
            }
            return output;
        }
        forEach(fn, thisArg) {
            for (const value of this._values) {
                fn.call(thisArg || this, value, value, this);
            }
        }
    }
    exports.Set = Set;
    Set.__name__ = "Set";
    class Matrix {
        constructor(nrows, ncols, init) {
            this.nrows = nrows;
            this.ncols = ncols;
            this._matrix = new Array(nrows);
            for (let y = 0; y < nrows; y++) {
                this._matrix[y] = new Array(ncols);
                for (let x = 0; x < ncols; x++) {
                    this._matrix[y][x] = init(y, x);
                }
            }
        }
        at(row, col) {
            return this._matrix[row][col];
        }
        map(fn) {
            return new Matrix(this.nrows, this.ncols, (row, col) => fn(this.at(row, col), row, col));
        }
        apply(obj) {
            const fn = Matrix.from(obj);
            const { nrows, ncols } = this;
            if (nrows == fn.nrows && ncols == fn.ncols)
                return new Matrix(nrows, ncols, (row, col) => fn.at(row, col)(this.at(row, col), row, col));
            else
                throw new Error("dimensions don't match");
        }
        to_sparse() {
            const items = [];
            for (let y = 0; y < this.nrows; y++) {
                for (let x = 0; x < this.ncols; x++) {
                    const value = this._matrix[y][x];
                    items.push([value, y, x]);
                }
            }
            return items;
        }
        static from(obj) {
            if (obj instanceof Matrix)
                return obj;
            else {
                const nrows = obj.length;
                const ncols = array_1.min(obj.map((row) => row.length));
                return new Matrix(nrows, ncols, (row, col) => obj[row][col]);
            }
        }
    }
    exports.Matrix = Matrix;
    Matrix.__name__ = "Matrix";
},
/* core/util/eq.js */ function _(require, module, exports) {
    const types_1 = require(7) /* ./types */;
    const toString = Object.prototype.toString;
    // Internal recursive comparison function for `isEqual`.
    function eq(a, b, aStack, bStack) {
        // Identical objects are equal. `0 === -0`, but they aren't identical.
        // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
        if (a === b)
            return a !== 0 || 1 / a === 1 / b;
        // A strict comparison is necessary because `null == undefined`.
        if (a == null || b == null)
            return a === b;
        // Compare `[[Class]]` names.
        const className = toString.call(a);
        if (className !== toString.call(b))
            return false;
        switch (className) {
            // Strings, numbers, regular expressions, dates, and booleans are compared by value.
            case '[object RegExp]':
            // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
            case '[object String]':
                // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
                // equivalent to `new String("5")`.
                return '' + a === '' + b;
            case '[object Number]':
                // `NaN`s are equivalent, but non-reflexive.
                // Object(NaN) is equivalent to NaN
                if (+a !== +a)
                    return +b !== +b;
                // An `egal` comparison is performed for other numeric values.
                return +a === 0 ? 1 / +a === 1 / b : +a === +b;
            case '[object Date]':
            case '[object Boolean]':
                // Coerce dates and booleans to numeric primitive values. Dates are compared by their
                // millisecond representations. Note that invalid dates with millisecond representations
                // of `NaN` are not equivalent.
                return +a === +b;
        }
        const areArrays = className === '[object Array]';
        if (!areArrays) {
            if (typeof a != 'object' || typeof b != 'object')
                return false;
            // Objects with different constructors are not equivalent, but `Object`s or `Array`s
            // from different frames are.
            const aCtor = a.constructor, bCtor = b.constructor;
            if (aCtor !== bCtor && !(types_1.isFunction(aCtor) && aCtor instanceof aCtor &&
                types_1.isFunction(bCtor) && bCtor instanceof bCtor)
                && ('constructor' in a && 'constructor' in b)) {
                return false;
            }
        }
        // Assume equality for cyclic structures. The algorithm for detecting cyclic
        // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
        // Initializing stack of traversed objects.
        // It's done here since we only need them for objects and arrays comparison.
        aStack = aStack || [];
        bStack = bStack || [];
        let length = aStack.length;
        while (length--) {
            // Linear search. Performance is inversely proportional to the number of
            // unique nested structures.
            if (aStack[length] === a)
                return bStack[length] === b;
        }
        // Add the first object to the stack of traversed objects.
        aStack.push(a);
        bStack.push(b);
        // Recursively compare objects and arrays.
        if (areArrays) {
            // Compare array lengths to determine if a deep comparison is necessary.
            length = a.length;
            if (length !== b.length)
                return false;
            // Deep compare the contents, ignoring non-numeric properties.
            while (length--) {
                if (!eq(a[length], b[length], aStack, bStack))
                    return false;
            }
        }
        else {
            // Deep compare objects.
            const keys = Object.keys(a);
            let key;
            length = keys.length;
            // Ensure that both objects contain the same number of properties before comparing deep equality.
            if (Object.keys(b).length !== length)
                return false;
            while (length--) {
                // Deep compare each member
                key = keys[length];
                if (!(b.hasOwnProperty(key) && eq(a[key], b[key], aStack, bStack)))
                    return false;
            }
        }
        // Remove the first object from the stack of traversed objects.
        aStack.pop();
        bStack.pop();
        return true;
    }
    // Perform a deep comparison to check if two objects are equal.
    function isEqual(a, b) {
        return eq(a, b);
    }
    exports.isEqual = isEqual;
},
/* core/util/callback.js */ function _(require, module, exports) {
    function delay(func, wait) {
        return setTimeout(func, wait);
    }
    exports.delay = delay;
    const _defer = typeof requestAnimationFrame === "function" ? requestAnimationFrame : setImmediate;
    function defer(func) {
        return _defer(func);
    }
    exports.defer = defer;
    function throttle(func, wait, options = {}) {
        let context, args, result;
        let timeout = null;
        let previous = 0;
        const later = function () {
            previous = options.leading === false ? 0 : Date.now();
            timeout = null;
            result = func.apply(context, args);
            if (!timeout)
                context = args = null;
        };
        return function () {
            const now = Date.now();
            if (!previous && options.leading === false)
                previous = now;
            const remaining = wait - (now - previous);
            context = this;
            args = arguments;
            if (remaining <= 0 || remaining > wait) {
                if (timeout) {
                    clearTimeout(timeout);
                    timeout = null;
                }
                previous = now;
                result = func.apply(context, args);
                if (!timeout)
                    context = args = null;
            }
            else if (!timeout && options.trailing !== false) {
                timeout = setTimeout(later, remaining);
            }
            return result;
        };
    }
    exports.throttle = throttle;
    function once(func) {
        let done = false;
        let memo;
        return function () {
            if (!done) {
                done = true;
                memo = func();
            }
            return memo;
        };
    }
    exports.once = once;
},
/* core/property_mixins.js */ function _(require, module, exports) {
    const p = require(18) /* ./properties */;
    const object_1 = require(22) /* ./util/object */;
    function _gen_mixin(mixin, prefix) {
        const result = {};
        for (const name in mixin) {
            const prop = mixin[name];
            result[prefix + name] = prop;
        }
        return result;
    }
    const _line_mixin = {
        line_color: [p.ColorSpec, 'black'],
        line_width: [p.NumberSpec, 1],
        line_alpha: [p.NumberSpec, 1.0],
        line_join: [p.LineJoin, 'bevel'],
        line_cap: [p.LineCap, 'butt'],
        line_dash: [p.Array, []],
        line_dash_offset: [p.Number, 0],
    };
    exports.line = (prefix = "") => _gen_mixin(_line_mixin, prefix);
    const _fill_mixin = {
        fill_color: [p.ColorSpec, 'gray'],
        fill_alpha: [p.NumberSpec, 1.0],
    };
    exports.fill = (prefix = "") => _gen_mixin(_fill_mixin, prefix);
    const _hatch_mixin = {
        hatch_color: [p.ColorSpec, 'black'],
        hatch_alpha: [p.NumberSpec, 1.0],
        hatch_scale: [p.NumberSpec, 12.0],
        hatch_pattern: [p.StringSpec, null],
        hatch_weight: [p.NumberSpec, 1.0],
        hatch_extra: [p.Any, {}],
    };
    exports.hatch = (prefix = "") => _gen_mixin(_hatch_mixin, prefix);
    const _text_mixin = {
        text_font: [p.Font, 'helvetica'],
        text_font_size: [p.FontSizeSpec, '12pt'],
        text_font_style: [p.FontStyle, 'normal'],
        text_color: [p.ColorSpec, '#444444'],
        text_alpha: [p.NumberSpec, 1.0],
        text_align: [p.TextAlign, 'left'],
        text_baseline: [p.TextBaseline, 'bottom'],
        text_line_height: [p.Number, 1.2],
    };
    exports.text = (prefix = "") => _gen_mixin(_text_mixin, prefix);
    function create(configs) {
        const result = {};
        for (const config of configs) {
            const [kind, prefix] = config.split(":");
            let mixin;
            switch (kind) {
                case "line":
                    mixin = exports.line;
                    break;
                case "fill":
                    mixin = exports.fill;
                    break;
                case "hatch":
                    mixin = exports.hatch;
                    break;
                case "text":
                    mixin = exports.text;
                    break;
                default:
                    throw new Error(`Unknown property mixin kind '${kind}'`);
            }
            object_1.extend(result, mixin(prefix));
        }
        return result;
    }
    exports.create = create;
},
/* core/properties.js */ function _(require, module, exports) {
    const signaling_1 = require(13) /* ./signaling */;
    const enums = require(19) /* ./enums */;
    const array_1 = require(8) /* ./util/array */;
    const arrayable_1 = require(11) /* ./util/arrayable */;
    const color_1 = require(20) /* ./util/color */;
    const types_1 = require(7) /* ./util/types */;
    signaling_1.Signal; // XXX: silence TS, because `Signal` appears in declarations due to Signalable
    function valueToString(value) {
        try {
            return JSON.stringify(value);
        }
        catch (_a) {
            return value.toString();
        }
    }
    function isSpec(obj) {
        return types_1.isPlainObject(obj) &&
            ((obj.value === undefined ? 0 : 1) +
                (obj.field === undefined ? 0 : 1) +
                (obj.expr === undefined ? 0 : 1) == 1); // garbage JS XOR
    }
    exports.isSpec = isSpec;
    class Property extends signaling_1.Signalable() {
        constructor(obj, attr, default_value) {
            super();
            this.obj = obj;
            this.attr = attr;
            this.default_value = default_value;
            this.optional = false;
            this.change = new signaling_1.Signal0(this.obj, "change");
            this._init();
            this.connect(this.change, () => this._init());
        }
        update() {
            this._init();
        }
        // ----- customizable policies
        init() { }
        transform(values) {
            return values;
        }
        validate(value) {
            if (!this.valid(value))
                throw new Error(`${this.obj.type}.${this.attr} given invalid value: ${valueToString(value)}`);
        }
        valid(_value) {
            return true;
        }
        // ----- property accessors
        value(do_spec_transform = true) {
            if (this.spec.value === undefined)
                throw new Error("attempted to retrieve property value for property without value specification");
            let ret = this.transform([this.spec.value])[0];
            if (this.spec.transform != null && do_spec_transform)
                ret = this.spec.transform.compute(ret);
            return ret;
        }
        // ----- private methods
        /*protected*/ _init() {
            const obj = this.obj;
            const attr = this.attr;
            let attr_value = obj.getv(attr);
            if (attr_value === undefined) {
                const default_value = this.default_value;
                if (default_value !== undefined)
                    attr_value = default_value(obj);
                else
                    attr_value = null;
                obj.setv({ [attr]: attr_value }, { silent: true, defaults: true });
            }
            if (types_1.isArray(attr_value))
                this.spec = { value: attr_value };
            else if (isSpec(attr_value))
                this.spec = attr_value;
            else
                this.spec = { value: attr_value };
            //if (this.dataspec && this.spec.field != null && !isString(this.spec.field))
            //  throw new Error(`field value for property '${attr}' is not a string`)
            if (this.spec.value != null)
                this.validate(this.spec.value);
            this.init();
        }
        toString() {
            /*${this.name}*/
            return `Prop(${this.obj}.${this.attr}, spec: ${valueToString(this.spec)})`;
        }
    }
    exports.Property = Property;
    Property.__name__ = "Property";
    //
    // Primitive Properties
    //
    class Any extends Property {
    }
    exports.Any = Any;
    Any.__name__ = "Any";
    class Array extends Property {
        valid(value) {
            return types_1.isArray(value) || value instanceof Float64Array;
        }
    }
    exports.Array = Array;
    Array.__name__ = "Array";
    class Boolean extends Property {
        valid(value) {
            return types_1.isBoolean(value);
        }
    }
    exports.Boolean = Boolean;
    Boolean.__name__ = "Boolean";
    class Color extends Property {
        valid(value) {
            return types_1.isString(value) && color_1.is_color(value);
        }
    }
    exports.Color = Color;
    Color.__name__ = "Color";
    class Instance extends Property {
    }
    exports.Instance = Instance;
    Instance.__name__ = "Instance";
    class Number extends Property {
        valid(value) {
            return types_1.isNumber(value);
        }
    }
    exports.Number = Number;
    Number.__name__ = "Number";
    class Int extends Number {
        valid(value) {
            return types_1.isNumber(value) && (value | 0) == value;
        }
    }
    exports.Int = Int;
    Int.__name__ = "Int";
    class Angle extends Number {
    }
    exports.Angle = Angle;
    Angle.__name__ = "Angle";
    class Percent extends Number {
        valid(value) {
            return types_1.isNumber(value) && 0 <= value && value <= 1.0;
        }
    }
    exports.Percent = Percent;
    Percent.__name__ = "Percent";
    class String extends Property {
        valid(value) {
            return types_1.isString(value);
        }
    }
    exports.String = String;
    String.__name__ = "String";
    class FontSize extends String {
    }
    exports.FontSize = FontSize;
    FontSize.__name__ = "FontSize";
    class Font extends String {
    } // TODO (bev) don't think this exists python side
    exports.Font = Font;
    Font.__name__ = "Font";
    //
    // Enum properties
    //
    class EnumProperty extends Property {
        valid(value) {
            return types_1.isString(value) && array_1.includes(this.enum_values, value);
        }
    }
    exports.EnumProperty = EnumProperty;
    EnumProperty.__name__ = "EnumProperty";
    function Enum(values) {
        return class extends EnumProperty {
            get enum_values() {
                return values;
            }
        };
    }
    exports.Enum = Enum;
    class Direction extends EnumProperty {
        get enum_values() {
            return enums.Direction;
        }
        transform(values) {
            const result = new Uint8Array(values.length);
            for (let i = 0; i < values.length; i++) {
                switch (values[i]) {
                    case "clock":
                        result[i] = 0;
                        break;
                    case "anticlock":
                        result[i] = 1;
                        break;
                }
            }
            return result;
        }
    }
    exports.Direction = Direction;
    Direction.__name__ = "Direction";
    exports.Anchor = Enum(enums.Anchor);
    exports.AngleUnits = Enum(enums.AngleUnits);
    exports.BoxOrigin = Enum(enums.BoxOrigin);
    exports.ButtonType = Enum(enums.ButtonType);
    exports.Dimension = Enum(enums.Dimension);
    exports.Dimensions = Enum(enums.Dimensions);
    exports.Distribution = Enum(enums.Distribution);
    exports.FontStyle = Enum(enums.FontStyle);
    exports.HatchPatternType = Enum(enums.HatchPatternType);
    exports.HTTPMethod = Enum(enums.HTTPMethod);
    exports.HexTileOrientation = Enum(enums.HexTileOrientation);
    exports.HoverMode = Enum(enums.HoverMode);
    exports.LatLon = Enum(enums.LatLon);
    exports.LegendClickPolicy = Enum(enums.LegendClickPolicy);
    exports.LegendLocation = Enum(enums.LegendLocation);
    exports.LineCap = Enum(enums.LineCap);
    exports.LineJoin = Enum(enums.LineJoin);
    exports.LinePolicy = Enum(enums.LinePolicy);
    exports.Location = Enum(enums.Location);
    exports.Logo = Enum(enums.Logo);
    exports.MarkerType = Enum(enums.MarkerType);
    exports.Orientation = Enum(enums.Orientation);
    exports.OutputBackend = Enum(enums.OutputBackend);
    exports.PaddingUnits = Enum(enums.PaddingUnits);
    exports.Place = Enum(enums.Place);
    exports.PointPolicy = Enum(enums.PointPolicy);
    exports.RadiusDimension = Enum(enums.RadiusDimension);
    exports.RenderLevel = Enum(enums.RenderLevel);
    exports.RenderMode = Enum(enums.RenderMode);
    exports.ResetPolicy = Enum(enums.ResetPolicy);
    exports.RoundingFunction = Enum(enums.RoundingFunction);
    exports.Side = Enum(enums.Side);
    exports.SizingMode = Enum(enums.SizingMode);
    exports.SliderCallbackPolicy = Enum(enums.SliderCallbackPolicy);
    exports.Sort = Enum(enums.Sort);
    exports.SpatialUnits = Enum(enums.SpatialUnits);
    exports.StartEnd = Enum(enums.StartEnd);
    exports.StepMode = Enum(enums.StepMode);
    exports.TapBehavior = Enum(enums.TapBehavior);
    exports.TextAlign = Enum(enums.TextAlign);
    exports.TextBaseline = Enum(enums.TextBaseline);
    exports.TextureRepetition = Enum(enums.TextureRepetition);
    exports.TickLabelOrientation = Enum(enums.TickLabelOrientation);
    exports.TooltipAttachment = Enum(enums.TooltipAttachment);
    exports.UpdateMode = Enum(enums.UpdateMode);
    exports.VerticalAlign = Enum(enums.VerticalAlign);
    //
    // DataSpec properties
    //
    class ScalarSpec extends Property {
    }
    exports.ScalarSpec = ScalarSpec;
    ScalarSpec.__name__ = "ScalarSpec";
    class VectorSpec extends Property {
        array(source) {
            let ret;
            if (this.spec.field != null) {
                ret = this.transform(source.get_column(this.spec.field));
                if (ret == null)
                    throw new Error(`attempted to retrieve property array for nonexistent field '${this.spec.field}'`);
            }
            else if (this.spec.expr != null) {
                ret = this.transform(this.spec.expr.v_compute(source));
            }
            else {
                let length = source.get_length();
                if (length == null)
                    length = 1;
                const value = this.value(false); // don't apply any spec transform
                ret = array_1.repeat(value, length);
            }
            if (this.spec.transform != null)
                ret = this.spec.transform.v_compute(ret);
            return ret;
        }
    }
    exports.VectorSpec = VectorSpec;
    VectorSpec.__name__ = "VectorSpec";
    class DataSpec extends VectorSpec {
    }
    exports.DataSpec = DataSpec;
    DataSpec.__name__ = "DataSpec";
    class UnitsSpec extends VectorSpec {
        init() {
            if (this.spec.units == null)
                this.spec.units = this.default_units;
            const units = this.spec.units;
            if (!array_1.includes(this.valid_units, units))
                throw new Error(`units must be one of ${this.valid_units.join(", ")}; got: ${units}`);
        }
        get units() {
            return this.spec.units;
        }
        set units(units) {
            this.spec.units = units;
        }
    }
    exports.UnitsSpec = UnitsSpec;
    UnitsSpec.__name__ = "UnitsSpec";
    class AngleSpec extends UnitsSpec {
        get default_units() { return "rad"; }
        get valid_units() { return enums.AngleUnits; }
        transform(values) {
            if (this.spec.units == "deg")
                values = arrayable_1.map(values, (x) => x * Math.PI / 180.0);
            values = arrayable_1.map(values, (x) => -x);
            return super.transform(values);
        }
    }
    exports.AngleSpec = AngleSpec;
    AngleSpec.__name__ = "AngleSpec";
    class BooleanSpec extends DataSpec {
    }
    exports.BooleanSpec = BooleanSpec;
    BooleanSpec.__name__ = "BooleanSpec";
    class ColorSpec extends DataSpec {
    }
    exports.ColorSpec = ColorSpec;
    ColorSpec.__name__ = "ColorSpec";
    class CoordinateSpec extends DataSpec {
    }
    exports.CoordinateSpec = CoordinateSpec;
    CoordinateSpec.__name__ = "CoordinateSpec";
    class CoordinateSeqSpec extends DataSpec {
    }
    exports.CoordinateSeqSpec = CoordinateSeqSpec;
    CoordinateSeqSpec.__name__ = "CoordinateSeqSpec";
    class DistanceSpec extends UnitsSpec {
        get default_units() { return "data"; }
        get valid_units() { return enums.SpatialUnits; }
    }
    exports.DistanceSpec = DistanceSpec;
    DistanceSpec.__name__ = "DistanceSpec";
    class FontSizeSpec extends DataSpec {
    }
    exports.FontSizeSpec = FontSizeSpec;
    FontSizeSpec.__name__ = "FontSizeSpec";
    class MarkerSpec extends DataSpec {
    }
    exports.MarkerSpec = MarkerSpec;
    MarkerSpec.__name__ = "MarkerSpec";
    class NumberSpec extends DataSpec {
    }
    exports.NumberSpec = NumberSpec;
    NumberSpec.__name__ = "NumberSpec";
    class StringSpec extends DataSpec {
    }
    exports.StringSpec = StringSpec;
    StringSpec.__name__ = "StringSpec";
    class NullStringSpec extends DataSpec {
    }
    exports.NullStringSpec = NullStringSpec;
    NullStringSpec.__name__ = "NullStringSpec";
},
/* core/enums.js */ function _(require, module, exports) {
    exports.Align = ["start", "center", "end"];
    exports.Anchor = [
        "top_left", "top_center", "top_right",
        "center_left", "center", "center_right",
        "bottom_left", "bottom_center", "bottom_right",
    ];
    exports.AngleUnits = ["deg", "rad"];
    exports.BoxOrigin = ["corner", "center"];
    exports.ButtonType = ["default", "primary", "success", "warning", "danger"];
    exports.Dimension = ["width", "height"];
    exports.Dimensions = ["width", "height", "both"];
    exports.Direction = ["clock", "anticlock"];
    exports.Distribution = ["uniform", "normal"];
    exports.FontStyle = ["normal", "italic", "bold", "bold italic"];
    exports.HatchPatternType = [
        'blank', 'dot', 'ring', 'horizontal_line', 'vertical_line', 'cross', 'horizontal_dash',
        'vertical_dash', 'spiral', 'right_diagonal_line', 'left_diagonal_line', 'diagonal_cross',
        'right_diagonal_dash', 'left_diagonal_dash', 'horizontal_wave', 'vertical_wave', 'criss_cross',
        ' ', '.', 'o', '-', '|', '+', '"', ':', '@', '/', '\\', 'x', ',', '`', 'v', '>', '*',
    ];
    exports.HTTPMethod = ["POST", "GET"];
    exports.HexTileOrientation = ["pointytop", "flattop"];
    exports.HoverMode = ["mouse", "hline", "vline"];
    exports.LatLon = ["lat", "lon"];
    exports.LegendClickPolicy = ["none", "hide", "mute"];
    exports.LegendLocation = exports.Anchor;
    exports.LineCap = ["butt", "round", "square"];
    exports.LineJoin = ["miter", "round", "bevel"];
    exports.LinePolicy = ["prev", "next", "nearest", "interp", "none"];
    exports.Location = ["above", "below", "left", "right"];
    exports.Logo = ["normal", "grey"];
    exports.MarkerType = [
        "asterisk", "circle", "circle_cross", "circle_x", "cross",
        "dash", "diamond", "diamond_cross", "hex", "inverted_triangle",
        "square", "square_cross", "square_x", "triangle", "x",
    ];
    exports.Orientation = ["vertical", "horizontal"];
    exports.OutputBackend = ["canvas", "svg", "webgl"];
    exports.PaddingUnits = ["percent", "absolute"];
    exports.Place = ["above", "below", "left", "right", "center"];
    exports.PointPolicy = ["snap_to_data", "follow_mouse", "none"];
    exports.RadiusDimension = ["x", "y", "max", "min"];
    exports.RenderLevel = ["image", "underlay", "glyph", "annotation", "overlay"];
    exports.RenderMode = ["canvas", "css"];
    exports.ResetPolicy = ["standard", "event_only"];
    exports.RoundingFunction = ["round", "nearest", "floor", "rounddown", "ceil", "roundup"];
    exports.Side = ["above", "below", "left", "right"];
    exports.SizingMode = ["stretch_width", "stretch_height", "stretch_both", "scale_width", "scale_height", "scale_both", "fixed"];
    exports.SliderCallbackPolicy = ["continuous", "throttle", "mouseup"];
    exports.Sort = ["ascending", "descending"];
    exports.SpatialUnits = ["screen", "data"];
    exports.StartEnd = ["start", "end"];
    exports.StepMode = ["after", "before", "center"];
    exports.TapBehavior = ["select", "inspect"];
    exports.TextAlign = ["left", "right", "center"];
    exports.TextBaseline = ["top", "middle", "bottom", "alphabetic", "hanging", "ideographic"];
    exports.TextureRepetition = ["repeat", "repeat_x", "repeat_y", "no_repeat"];
    exports.TickLabelOrientation = ["vertical", "horizontal", "parallel", "normal"];
    exports.TooltipAttachment = ["horizontal", "vertical", "left", "right", "above", "below"];
    exports.UpdateMode = ["replace", "append"];
    exports.VerticalAlign = ["top", "middle", "bottom"];
},
/* core/util/color.js */ function _(require, module, exports) {
    const svg_colors_1 = require(21) /* ./svg_colors */;
    const array_1 = require(8) /* ./array */;
    function is_color(value) {
        return svg_colors_1.is_svg_color(value.toLowerCase()) || value.substring(0, 1) == "#" || valid_rgb(value);
    }
    exports.is_color = is_color;
    function _component2hex(v) {
        const h = Number(v).toString(16);
        return h.length == 1 ? `0${h}` : h;
    }
    function rgb2hex(r, g, b) {
        const R = _component2hex(r & 0xFF);
        const G = _component2hex(g & 0xFF);
        const B = _component2hex(b & 0xFF);
        return `#${R}${G}${B}`;
    }
    exports.rgb2hex = rgb2hex;
    function color2hex(color) {
        color = color + '';
        if (color.indexOf('#') == 0)
            return color;
        else if (svg_colors_1.is_svg_color(color))
            return svg_colors_1.svg_colors[color];
        else if (color.indexOf('rgb') == 0) {
            const rgb = color.replace(/^rgba?\(|\s+|\)$/g, '').split(',');
            let hex = rgb.slice(0, 3).map(_component2hex).join('');
            if (rgb.length == 4)
                hex += _component2hex(Math.floor(parseFloat(rgb[3]) * 255));
            return `#${hex.slice(0, 8)}`; // can also be rgba
        }
        else
            return color;
    }
    exports.color2hex = color2hex;
    function color2rgba(color, alpha = 1.0) {
        if (!color) // NaN, null, '', etc.
            return [0, 0, 0, 0]; // transparent
        // Convert to hex and then to clean version of 6 or 8 chars
        let hex = color2hex(color);
        hex = hex.replace(/ |#/g, '');
        if (hex.length <= 4) {
            hex = hex.replace(/(.)/g, '$1$1');
        }
        // Convert pairs to numbers
        const rgba = hex.match(/../g).map((i) => parseInt(i, 16) / 255);
        // Ensure correct length, add alpha if necessary
        while (rgba.length < 3)
            rgba.push(0);
        if (rgba.length < 4)
            rgba.push(alpha);
        return rgba.slice(0, 4);
    }
    exports.color2rgba = color2rgba;
    function valid_rgb(value) {
        let params;
        switch (value.substring(0, 4)) {
            case "rgba": {
                params = { start: "rgba(", len: 4, alpha: true };
                break;
            }
            case "rgb(": {
                params = { start: "rgb(", len: 3, alpha: false };
                break;
            }
            default:
                return false;
        }
        // if '.' and then ',' found, we know decimals are used on rgb
        if (new RegExp(".*?(\\.).*(,)").test(value))
            throw new Error(`color expects integers for rgb in rgb/rgba tuple, received ${value}`);
        // extract the numerical values from inside parens
        const contents = value.replace(params.start, "").replace(")", "").split(',').map(parseFloat);
        // check length of array based on rgb/rgba
        if (contents.length != params.len)
            throw new Error(`color expects rgba ${params.len}-tuple, received ${value}`);
        // check for valid numerical values for rgba
        if (params.alpha && !(0 <= contents[3] && contents[3] <= 1))
            throw new Error("color expects rgba 4-tuple to have alpha value between 0 and 1");
        if (array_1.includes(contents.slice(0, 3).map((rgb) => 0 <= rgb && rgb <= 255), false))
            throw new Error("color expects rgb to have value between 0 and 255");
        return true;
    }
    exports.valid_rgb = valid_rgb;
},
/* core/util/svg_colors.js */ function _(require, module, exports) {
    exports.svg_colors = {
        indianred: "#CD5C5C",
        lightcoral: "#F08080",
        salmon: "#FA8072",
        darksalmon: "#E9967A",
        lightsalmon: "#FFA07A",
        crimson: "#DC143C",
        red: "#FF0000",
        firebrick: "#B22222",
        darkred: "#8B0000",
        pink: "#FFC0CB",
        lightpink: "#FFB6C1",
        hotpink: "#FF69B4",
        deeppink: "#FF1493",
        mediumvioletred: "#C71585",
        palevioletred: "#DB7093",
        coral: "#FF7F50",
        tomato: "#FF6347",
        orangered: "#FF4500",
        darkorange: "#FF8C00",
        orange: "#FFA500",
        gold: "#FFD700",
        yellow: "#FFFF00",
        lightyellow: "#FFFFE0",
        lemonchiffon: "#FFFACD",
        lightgoldenrodyellow: "#FAFAD2",
        papayawhip: "#FFEFD5",
        moccasin: "#FFE4B5",
        peachpuff: "#FFDAB9",
        palegoldenrod: "#EEE8AA",
        khaki: "#F0E68C",
        darkkhaki: "#BDB76B",
        lavender: "#E6E6FA",
        thistle: "#D8BFD8",
        plum: "#DDA0DD",
        violet: "#EE82EE",
        orchid: "#DA70D6",
        fuchsia: "#FF00FF",
        magenta: "#FF00FF",
        mediumorchid: "#BA55D3",
        mediumpurple: "#9370DB",
        blueviolet: "#8A2BE2",
        darkviolet: "#9400D3",
        darkorchid: "#9932CC",
        darkmagenta: "#8B008B",
        purple: "#800080",
        indigo: "#4B0082",
        slateblue: "#6A5ACD",
        darkslateblue: "#483D8B",
        mediumslateblue: "#7B68EE",
        greenyellow: "#ADFF2F",
        chartreuse: "#7FFF00",
        lawngreen: "#7CFC00",
        lime: "#00FF00",
        limegreen: "#32CD32",
        palegreen: "#98FB98",
        lightgreen: "#90EE90",
        mediumspringgreen: "#00FA9A",
        springgreen: "#00FF7F",
        mediumseagreen: "#3CB371",
        seagreen: "#2E8B57",
        forestgreen: "#228B22",
        green: "#008000",
        darkgreen: "#006400",
        yellowgreen: "#9ACD32",
        olivedrab: "#6B8E23",
        olive: "#808000",
        darkolivegreen: "#556B2F",
        mediumaquamarine: "#66CDAA",
        darkseagreen: "#8FBC8F",
        lightseagreen: "#20B2AA",
        darkcyan: "#008B8B",
        teal: "#008080",
        aqua: "#00FFFF",
        cyan: "#00FFFF",
        lightcyan: "#E0FFFF",
        paleturquoise: "#AFEEEE",
        aquamarine: "#7FFFD4",
        turquoise: "#40E0D0",
        mediumturquoise: "#48D1CC",
        darkturquoise: "#00CED1",
        cadetblue: "#5F9EA0",
        steelblue: "#4682B4",
        lightsteelblue: "#B0C4DE",
        powderblue: "#B0E0E6",
        lightblue: "#ADD8E6",
        skyblue: "#87CEEB",
        lightskyblue: "#87CEFA",
        deepskyblue: "#00BFFF",
        dodgerblue: "#1E90FF",
        cornflowerblue: "#6495ED",
        royalblue: "#4169E1",
        blue: "#0000FF",
        mediumblue: "#0000CD",
        darkblue: "#00008B",
        navy: "#000080",
        midnightblue: "#191970",
        cornsilk: "#FFF8DC",
        blanchedalmond: "#FFEBCD",
        bisque: "#FFE4C4",
        navajowhite: "#FFDEAD",
        wheat: "#F5DEB3",
        burlywood: "#DEB887",
        tan: "#D2B48C",
        rosybrown: "#BC8F8F",
        sandybrown: "#F4A460",
        goldenrod: "#DAA520",
        darkgoldenrod: "#B8860B",
        peru: "#CD853F",
        chocolate: "#D2691E",
        saddlebrown: "#8B4513",
        sienna: "#A0522D",
        brown: "#A52A2A",
        maroon: "#800000",
        white: "#FFFFFF",
        snow: "#FFFAFA",
        honeydew: "#F0FFF0",
        mintcream: "#F5FFFA",
        azure: "#F0FFFF",
        aliceblue: "#F0F8FF",
        ghostwhite: "#F8F8FF",
        whitesmoke: "#F5F5F5",
        seashell: "#FFF5EE",
        beige: "#F5F5DC",
        oldlace: "#FDF5E6",
        floralwhite: "#FFFAF0",
        ivory: "#FFFFF0",
        antiquewhite: "#FAEBD7",
        linen: "#FAF0E6",
        lavenderblush: "#FFF0F5",
        mistyrose: "#FFE4E1",
        gainsboro: "#DCDCDC",
        lightgray: "#D3D3D3",
        lightgrey: "#D3D3D3",
        silver: "#C0C0C0",
        darkgray: "#A9A9A9",
        darkgrey: "#A9A9A9",
        gray: "#808080",
        grey: "#808080",
        dimgray: "#696969",
        dimgrey: "#696969",
        lightslategray: "#778899",
        lightslategrey: "#778899",
        slategray: "#708090",
        slategrey: "#708090",
        darkslategray: "#2F4F4F",
        darkslategrey: "#2F4F4F",
        black: "#000000",
    };
    function is_svg_color(color) {
        return color in exports.svg_colors;
    }
    exports.is_svg_color = is_svg_color;
},
/* core/util/object.js */ function _(require, module, exports) {
    const tslib_1 = require(23) /* tslib */;
    const array_1 = require(8) /* ./array */;
    exports.keys = Object.keys;
    function values(object) {
        const keys = Object.keys(object);
        const length = keys.length;
        const values = new Array(length);
        for (let i = 0; i < length; i++) {
            values[i] = object[keys[i]];
        }
        return values;
    }
    exports.values = values;
    function extend(dest, src) {
        return tslib_1.__assign(dest, src);
    }
    exports.extend = extend;
    function clone(obj) {
        return extend({}, obj); // XXX: can't use {...obj} due to https://github.com/Microsoft/TypeScript/issues/14409
    }
    exports.clone = clone;
    function merge(obj1, obj2) {
        /*
         * Returns an object with the array values for obj1 and obj2 unioned by key.
         */
        const result = Object.create(Object.prototype);
        const keys = array_1.concat([Object.keys(obj1), Object.keys(obj2)]);
        for (const key of keys) {
            const arr1 = obj1.hasOwnProperty(key) ? obj1[key] : [];
            const arr2 = obj2.hasOwnProperty(key) ? obj2[key] : [];
            result[key] = array_1.union(arr1, arr2);
        }
        return result;
    }
    exports.merge = merge;
    function size(obj) {
        return Object.keys(obj).length;
    }
    exports.size = size;
    function isEmpty(obj) {
        return size(obj) === 0;
    }
    exports.isEmpty = isEmpty;
},
/* tslib/tslib.js */ function _(require, module, exports) {
    /*! *****************************************************************************
    Copyright (c) Microsoft Corporation. All rights reserved.
    Licensed under the Apache License, Version 2.0 (the "License"); you may not use
    this file except in compliance with the License. You may obtain a copy of the
    License at http://www.apache.org/licenses/LICENSE-2.0
    
    THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
    WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
    MERCHANTABLITY OR NON-INFRINGEMENT.
    
    See the Apache Version 2.0 License for specific language governing permissions
    and limitations under the License.
    ***************************************************************************** */
    /* global global, define, System, Reflect, Promise */
    var __extends;
    var __assign;
    var __rest;
    var __decorate;
    var __param;
    var __metadata;
    var __awaiter;
    var __generator;
    var __exportStar;
    var __values;
    var __read;
    var __spread;
    var __spreadArrays;
    var __await;
    var __asyncGenerator;
    var __asyncDelegator;
    var __asyncValues;
    var __makeTemplateObject;
    var __importStar;
    var __importDefault;
    (function (factory) {
        var root = typeof global === "object" ? global : typeof self === "object" ? self : typeof this === "object" ? this : {};
        if (typeof define === "function" && define.amd) {
            define("tslib", ["exports"], function (exports) { factory(createExporter(root, createExporter(exports))); });
        }
        else if (typeof module === "object" && typeof module.exports === "object") {
            factory(createExporter(root, createExporter(module.exports)));
        }
        else {
            factory(createExporter(root));
        }
        function createExporter(exports, previous) {
            if (exports !== root) {
                if (typeof Object.create === "function") {
                    Object.defineProperty(exports, "__esModule", { value: true });
                }
                else {
                    exports.__esModule = true;
                }
            }
            return function (id, v) { return exports[id] = previous ? previous(id, v) : v; };
        }
    })(function (exporter) {
        var extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b)
                if (b.hasOwnProperty(p))
                    d[p] = b[p]; };
        __extends = function (d, b) {
            extendStatics(d, b);
            function __() { this.constructor = d; }
            d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
        };
        __assign = Object.assign || function (t) {
            for (var s, i = 1, n = arguments.length; i < n; i++) {
                s = arguments[i];
                for (var p in s)
                    if (Object.prototype.hasOwnProperty.call(s, p))
                        t[p] = s[p];
            }
            return t;
        };
        __rest = function (s, e) {
            var t = {};
            for (var p in s)
                if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
                    t[p] = s[p];
            if (s != null && typeof Object.getOwnPropertySymbols === "function")
                for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
                    if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                        t[p[i]] = s[p[i]];
                }
            return t;
        };
        __decorate = function (decorators, target, key, desc) {
            var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
            if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
                r = Reflect.decorate(decorators, target, key, desc);
            else
                for (var i = decorators.length - 1; i >= 0; i--)
                    if (d = decorators[i])
                        r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
            return c > 3 && r && Object.defineProperty(target, key, r), r;
        };
        __param = function (paramIndex, decorator) {
            return function (target, key) { decorator(target, key, paramIndex); };
        };
        __metadata = function (metadataKey, metadataValue) {
            if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
                return Reflect.metadata(metadataKey, metadataValue);
        };
        __awaiter = function (thisArg, _arguments, P, generator) {
            return new (P || (P = Promise))(function (resolve, reject) {
                function fulfilled(value) { try {
                    step(generator.next(value));
                }
                catch (e) {
                    reject(e);
                } }
                function rejected(value) { try {
                    step(generator["throw"](value));
                }
                catch (e) {
                    reject(e);
                } }
                function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
                step((generator = generator.apply(thisArg, _arguments || [])).next());
            });
        };
        __generator = function (thisArg, body) {
            var _ = { label: 0, sent: function () { if (t[0] & 1)
                    throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
            return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { return this; }), g;
            function verb(n) { return function (v) { return step([n, v]); }; }
            function step(op) {
                if (f)
                    throw new TypeError("Generator is already executing.");
                while (_)
                    try {
                        if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done)
                            return t;
                        if (y = 0, t)
                            op = [op[0] & 2, t.value];
                        switch (op[0]) {
                            case 0:
                            case 1:
                                t = op;
                                break;
                            case 4:
                                _.label++;
                                return { value: op[1], done: false };
                            case 5:
                                _.label++;
                                y = op[1];
                                op = [0];
                                continue;
                            case 7:
                                op = _.ops.pop();
                                _.trys.pop();
                                continue;
                            default:
                                if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
                                    _ = 0;
                                    continue;
                                }
                                if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) {
                                    _.label = op[1];
                                    break;
                                }
                                if (op[0] === 6 && _.label < t[1]) {
                                    _.label = t[1];
                                    t = op;
                                    break;
                                }
                                if (t && _.label < t[2]) {
                                    _.label = t[2];
                                    _.ops.push(op);
                                    break;
                                }
                                if (t[2])
                                    _.ops.pop();
                                _.trys.pop();
                                continue;
                        }
                        op = body.call(thisArg, _);
                    }
                    catch (e) {
                        op = [6, e];
                        y = 0;
                    }
                    finally {
                        f = t = 0;
                    }
                if (op[0] & 5)
                    throw op[1];
                return { value: op[0] ? op[1] : void 0, done: true };
            }
        };
        __exportStar = function (m, exports) {
            for (var p in m)
                if (!exports.hasOwnProperty(p))
                    exports[p] = m[p];
        };
        __values = function (o) {
            var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
            if (m)
                return m.call(o);
            return {
                next: function () {
                    if (o && i >= o.length)
                        o = void 0;
                    return { value: o && o[i++], done: !o };
                }
            };
        };
        __read = function (o, n) {
            var m = typeof Symbol === "function" && o[Symbol.iterator];
            if (!m)
                return o;
            var i = m.call(o), r, ar = [], e;
            try {
                while ((n === void 0 || n-- > 0) && !(r = i.next()).done)
                    ar.push(r.value);
            }
            catch (error) {
                e = { error: error };
            }
            finally {
                try {
                    if (r && !r.done && (m = i["return"]))
                        m.call(i);
                }
                finally {
                    if (e)
                        throw e.error;
                }
            }
            return ar;
        };
        __spread = function () {
            for (var ar = [], i = 0; i < arguments.length; i++)
                ar = ar.concat(__read(arguments[i]));
            return ar;
        };
        __spreadArrays = function () {
            for (var s = 0, i = 0, il = arguments.length; i < il; i++)
                s += arguments[i].length;
            for (var r = Array(s), k = 0, i = 0; i < il; i++)
                for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
                    r[k] = a[j];
            return r;
        };
        __await = function (v) {
            return this instanceof __await ? (this.v = v, this) : new __await(v);
        };
        __asyncGenerator = function (thisArg, _arguments, generator) {
            if (!Symbol.asyncIterator)
                throw new TypeError("Symbol.asyncIterator is not defined.");
            var g = generator.apply(thisArg, _arguments || []), i, q = [];
            return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
            function verb(n) { if (g[n])
                i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
            function resume(n, v) { try {
                step(g[n](v));
            }
            catch (e) {
                settle(q[0][3], e);
            } }
            function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
            function fulfill(value) { resume("next", value); }
            function reject(value) { resume("throw", value); }
            function settle(f, v) { if (f(v), q.shift(), q.length)
                resume(q[0][0], q[0][1]); }
        };
        __asyncDelegator = function (o) {
            var i, p;
            return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
            function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
        };
        __asyncValues = function (o) {
            if (!Symbol.asyncIterator)
                throw new TypeError("Symbol.asyncIterator is not defined.");
            var m = o[Symbol.asyncIterator], i;
            return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
            function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
            function settle(resolve, reject, d, v) { Promise.resolve(v).then(function (v) { resolve({ value: v, done: d }); }, reject); }
        };
        __makeTemplateObject = function (cooked, raw) {
            if (Object.defineProperty) {
                Object.defineProperty(cooked, "raw", { value: raw });
            }
            else {
                cooked.raw = raw;
            }
            return cooked;
        };
        __importStar = function (mod) {
            if (mod && mod.__esModule)
                return mod;
            var result = {};
            if (mod != null)
                for (var k in mod)
                    if (Object.hasOwnProperty.call(mod, k))
                        result[k] = mod[k];
            result["default"] = mod;
            return result;
        };
        __importDefault = function (mod) {
            return (mod && mod.__esModule) ? mod : { "default": mod };
        };
        exporter("__extends", __extends);
        exporter("__assign", __assign);
        exporter("__rest", __rest);
        exporter("__decorate", __decorate);
        exporter("__param", __param);
        exporter("__metadata", __metadata);
        exporter("__awaiter", __awaiter);
        exporter("__generator", __generator);
        exporter("__exportStar", __exportStar);
        exporter("__values", __values);
        exporter("__read", __read);
        exporter("__spread", __spread);
        exporter("__spreadArrays", __spreadArrays);
        exporter("__await", __await);
        exporter("__asyncGenerator", __asyncGenerator);
        exporter("__asyncDelegator", __asyncDelegator);
        exporter("__asyncValues", __asyncValues);
        exporter("__makeTemplateObject", __makeTemplateObject);
        exporter("__importStar", __importStar);
        exporter("__importDefault", __importDefault);
    });
},
/* core/util/refs.js */ function _(require, module, exports) {
    const types_1 = require(7) /* ./types */;
    // Create a Bokeh reference from a HasProps subclass
    //
    // @param obj [HasProps] the object to create a reference for
    // @return [Object] a Bokeh reference for `obj`
    // @throw Error if `obj` is not a HasProps
    //
    function create_ref(obj) {
        const ref = {
            type: obj.type,
            id: obj.id,
        };
        if (obj._subtype != null) {
            ref.subtype = obj._subtype;
        }
        return ref;
    }
    exports.create_ref = create_ref;
    // Determine whether an object has the proper format of a Bokeh reference
    //
    // @param arg [Object] the object to test
    // @return [bool] whether the object is a reference
    //
    // @note this function does not check that the id and types are valid,
    //   only that the format is correct (all required keys are present)
    //
    function is_ref(arg) {
        if (types_1.isObject(arg)) {
            const keys = Object.keys(arg).sort();
            if (keys.length == 2)
                return keys[0] == 'id' && keys[1] == 'type';
            if (keys.length == 3)
                return keys[0] == 'id' && keys[1] == 'subtype' && keys[2] == 'type';
        }
        return false;
    }
    exports.is_ref = is_ref;
},
/* core/util/string.js */ function _(require, module, exports) {
    const settings_1 = require(26) /* ../settings */;
    function startsWith(str, searchString, position = 0) {
        return str.substr(position, searchString.length) == searchString;
    }
    exports.startsWith = startsWith;
    function uuid4() {
        // from ipython project
        // http://www.ietf.org/rfc/rfc4122.txt
        const s = new Array(32);
        const hexDigits = "0123456789ABCDEF";
        for (let i = 0; i < 32; i++) {
            s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
        }
        s[12] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
        s[16] = hexDigits.substr((s[16].charCodeAt(0) & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
        return s.join("");
    }
    exports.uuid4 = uuid4;
    let counter = 1000;
    function uniqueId(prefix) {
        const id = settings_1.settings.dev ? `j${counter++}` : uuid4();
        if (prefix != null)
            return `${prefix}-${id}`;
        else
            return id;
    }
    exports.uniqueId = uniqueId;
    function escape(s) {
        return s.replace(/(?:[&<>"'`])/g, (ch) => {
            switch (ch) {
                case '&': return '&amp;';
                case '<': return '&lt;';
                case '>': return '&gt;';
                case '"': return '&quot;';
                case "'": return '&#x27;';
                case '`': return '&#x60;';
                default: return ch;
            }
        });
    }
    exports.escape = escape;
    function unescape(s) {
        return s.replace(/&(amp|lt|gt|quot|#x27|#x60);/g, (_, entity) => {
            switch (entity) {
                case 'amp': return '&';
                case 'lt': return '<';
                case 'gt': return '>';
                case 'quot': return '"';
                case '#x27': return "'";
                case '#x60': return '`';
                default: return entity;
            }
        });
    }
    exports.unescape = unescape;
    function use_strict(code) {
        return `'use strict';\n${code}`;
    }
    exports.use_strict = use_strict;
},
/* core/settings.js */ function _(require, module, exports) {
    class Settings {
        constructor() {
            this._dev = false;
        }
        set dev(dev) {
            this._dev = dev;
        }
        get dev() {
            return this._dev;
        }
    }
    exports.Settings = Settings;
    Settings.__name__ = "Settings";
    exports.settings = new Settings();
},
/* models/index.js */ function _(require, module, exports) {
    function __export(m) {
        for (var p in m)
            if (!exports.hasOwnProperty(p))
                exports[p] = m[p];
    }
    __export(require(28) /* ./annotations */);
    __export(require(140) /* ./axes */);
    __export(require(167) /* ./callbacks */);
    __export(require(171) /* ./canvas */);
    __export(require(186) /* ./expressions */);
    __export(require(190) /* ./filters */);
    __export(require(196) /* ./formatters */);
    __export(require(200) /* ./glyphs */);
    __export(require(230) /* ./graphs */);
    __export(require(233) /* ./grids */);
    __export(require(235) /* ./layouts */);
    __export(require(248) /* ./mappers */);
    __export(require(115) /* ./transforms */);
    __export(require(254) /* ./markers */);
    __export(require(258) /* ./plots */);
    __export(require(281) /* ./ranges */);
    __export(require(282) /* ./renderers */);
    __export(require(283) /* ./scales */);
    __export(require(284) /* ./selections */);
    __export(require(285) /* ./sources */);
    __export(require(291) /* ./tickers */);
    __export(require(293) /* ./tiles */);
    __export(require(303) /* ./textures */);
    __export(require(307) /* ./tools */);
},
/* models/annotations/index.js */ function _(require, module, exports) {
    var annotation_1 = require(29) /* ./annotation */;
    exports.Annotation = annotation_1.Annotation;
    var arrow_1 = require(66) /* ./arrow */;
    exports.Arrow = arrow_1.Arrow;
    var arrow_head_1 = require(67) /* ./arrow_head */;
    exports.ArrowHead = arrow_head_1.ArrowHead;
    var arrow_head_2 = require(67) /* ./arrow_head */;
    exports.OpenHead = arrow_head_2.OpenHead;
    var arrow_head_3 = require(67) /* ./arrow_head */;
    exports.NormalHead = arrow_head_3.NormalHead;
    var arrow_head_4 = require(67) /* ./arrow_head */;
    exports.TeeHead = arrow_head_4.TeeHead;
    var arrow_head_5 = require(67) /* ./arrow_head */;
    exports.VeeHead = arrow_head_5.VeeHead;
    var band_1 = require(98) /* ./band */;
    exports.Band = band_1.Band;
    var box_annotation_1 = require(99) /* ./box_annotation */;
    exports.BoxAnnotation = box_annotation_1.BoxAnnotation;
    var color_bar_1 = require(101) /* ./color_bar */;
    exports.ColorBar = color_bar_1.ColorBar;
    var label_1 = require(125) /* ./label */;
    exports.Label = label_1.Label;
    var label_set_1 = require(127) /* ./label_set */;
    exports.LabelSet = label_set_1.LabelSet;
    var legend_1 = require(128) /* ./legend */;
    exports.Legend = legend_1.Legend;
    var legend_item_1 = require(129) /* ./legend_item */;
    exports.LegendItem = legend_item_1.LegendItem;
    var poly_annotation_1 = require(131) /* ./poly_annotation */;
    exports.PolyAnnotation = poly_annotation_1.PolyAnnotation;
    var slope_1 = require(132) /* ./slope */;
    exports.Slope = slope_1.Slope;
    var span_1 = require(133) /* ./span */;
    exports.Span = span_1.Span;
    var text_annotation_1 = require(126) /* ./text_annotation */;
    exports.TextAnnotation = text_annotation_1.TextAnnotation;
    var title_1 = require(134) /* ./title */;
    exports.Title = title_1.Title;
    var toolbar_panel_1 = require(135) /* ./toolbar_panel */;
    exports.ToolbarPanel = toolbar_panel_1.ToolbarPanel;
    var tooltip_1 = require(136) /* ./tooltip */;
    exports.Tooltip = tooltip_1.Tooltip;
    var whisker_1 = require(139) /* ./whisker */;
    exports.Whisker = whisker_1.Whisker;
},
/* models/annotations/annotation.js */ function _(require, module, exports) {
    const proj = require(30) /* ../../core/util/projections */;
    const object_1 = require(22) /* ../../core/util/object */;
    const renderer_1 = require(58) /* ../renderers/renderer */;
    class AnnotationView extends renderer_1.RendererView {
        get panel() {
            return this.layout;
        }
        get_size() {
            if (this.model.visible) {
                const { width, height } = this._get_size();
                return { width: Math.round(width), height: Math.round(height) };
            }
            else
                return { width: 0, height: 0 };
        }
        connect_signals() {
            super.connect_signals();
            const p = this.model.properties;
            this.on_change(p.visible, () => this.plot_view.request_layout());
        }
        _get_size() {
            throw new Error("not implemented");
        }
        get ctx() {
            return this.plot_view.canvas_view.ctx;
        }
        set_data(source) {
            const data = this.model.materialize_dataspecs(source);
            object_1.extend(this, data);
            if (this.plot_model.use_map) {
                const self = this;
                if (self._x != null)
                    [self._x, self._y] = proj.project_xy(self._x, self._y);
                if (self._xs != null)
                    [self._xs, self._ys] = proj.project_xsys(self._xs, self._ys);
            }
        }
        get needs_clip() {
            return this.layout == null; // TODO: change this, when center layout is fully implemented
        }
        serializable_state() {
            const state = super.serializable_state();
            return this.layout == null ? state : Object.assign(Object.assign({}, state), { bbox: this.layout.bbox.box });
        }
    }
    exports.AnnotationView = AnnotationView;
    AnnotationView.__name__ = "AnnotationView";
    class Annotation extends renderer_1.Renderer {
        constructor(attrs) {
            super(attrs);
        }
        static init_Annotation() {
            this.override({
                level: 'annotation',
            });
        }
    }
    exports.Annotation = Annotation;
    Annotation.__name__ = "Annotation";
    Annotation.init_Annotation();
},
/* core/util/projections.js */ function _(require, module, exports) {
    const proj4 = require(31) /* proj4/lib/core */;
    const Projection = require(32) /* proj4/lib/Proj */;
    const mercator = new Projection('GOOGLE');
    const wgs84 = new Projection('WGS84');
    exports.wgs84_mercator = proj4(wgs84, mercator);
    const mercator_bounds = {
        lon: [-20026376.39, 20026376.39],
        lat: [-20048966.10, 20048966.10],
    };
    const latlon_bounds = {
        lon: [-180, 180],
        lat: [-85.06, 85.06],
    };
    function clip_mercator(low, high, dimension) {
        const [min, max] = mercator_bounds[dimension];
        return [Math.max(low, min), Math.min(high, max)];
    }
    exports.clip_mercator = clip_mercator;
    function in_bounds(value, dimension) {
        return value > latlon_bounds[dimension][0] && value < latlon_bounds[dimension][1];
    }
    exports.in_bounds = in_bounds;
    function project_xy(x, y) {
        const n = Math.min(x.length, y.length);
        const merc_x_s = new Array(n);
        const merc_y_s = new Array(n);
        for (let i = 0; i < n; i++) {
            const [merc_x, merc_y] = exports.wgs84_mercator.forward([x[i], y[i]]);
            merc_x_s[i] = merc_x;
            merc_y_s[i] = merc_y;
        }
        return [merc_x_s, merc_y_s];
    }
    exports.project_xy = project_xy;
    function project_xsys(xs, ys) {
        const n = Math.min(xs.length, ys.length);
        const merc_xs_s = new Array(n);
        const merc_ys_s = new Array(n);
        for (let i = 0; i < n; i++) {
            const [merc_x_s, merc_y_s] = project_xy(xs[i], ys[i]);
            merc_xs_s[i] = merc_x_s;
            merc_ys_s[i] = merc_y_s;
        }
        return [merc_xs_s, merc_ys_s];
    }
    exports.project_xsys = project_xsys;
},
/* proj4/lib/core.js */ function _(require, module, exports) {
    var proj = require(32) /* ./Proj */;
    var transform = require(53) /* ./transform */;
    var wgs84 = proj('WGS84');
    function transformer(from, to, coords) {
        var transformedArray;
        if (Array.isArray(coords)) {
            transformedArray = transform(from, to, coords);
            if (coords.length === 3) {
                return [transformedArray.x, transformedArray.y, transformedArray.z];
            }
            else {
                return [transformedArray.x, transformedArray.y];
            }
        }
        else {
            return transform(from, to, coords);
        }
    }
    function checkProj(item) {
        if (item instanceof proj) {
            return item;
        }
        if (item.oProj) {
            return item.oProj;
        }
        return proj(item);
    }
    function proj4(fromProj, toProj, coord) {
        fromProj = checkProj(fromProj);
        var single = false;
        var obj;
        if (typeof toProj === 'undefined') {
            toProj = fromProj;
            fromProj = wgs84;
            single = true;
        }
        else if (typeof toProj.x !== 'undefined' || Array.isArray(toProj)) {
            coord = toProj;
            toProj = fromProj;
            fromProj = wgs84;
            single = true;
        }
        toProj = checkProj(toProj);
        if (coord) {
            return transformer(fromProj, toProj, coord);
        }
        else {
            obj = {
                forward: function (coords) {
                    return transformer(fromProj, toProj, coords);
                },
                inverse: function (coords) {
                    return transformer(toProj, fromProj, coords);
                }
            };
            if (single) {
                obj.oProj = toProj;
            }
            return obj;
        }
    }
    module.exports = proj4;
},
/* proj4/lib/Proj.js */ function _(require, module, exports) {
    var parseCode = require(33) /* ./parseCode */;
    var extend = require(40) /* ./extend */;
    var projections = require(41) /* ./projections */;
    var deriveConstants = require(49) /* ./deriveConstants */;
    var Datum = require(51) /* ./constants/Datum */;
    var datum = require(52) /* ./datum */;
    function Projection(srsCode, callback) {
        if (!(this instanceof Projection)) {
            return new Projection(srsCode);
        }
        callback = callback || function (error) {
            if (error) {
                throw error;
            }
        };
        var json = parseCode(srsCode);
        if (typeof json !== 'object') {
            callback(srsCode);
            return;
        }
        var ourProj = Projection.projections.get(json.projName);
        if (!ourProj) {
            callback(srsCode);
            return;
        }
        if (json.datumCode && json.datumCode !== 'none') {
            var datumDef = Datum[json.datumCode];
            if (datumDef) {
                json.datum_params = datumDef.towgs84 ? datumDef.towgs84.split(',') : null;
                json.ellps = datumDef.ellipse;
                json.datumName = datumDef.datumName ? datumDef.datumName : json.datumCode;
            }
        }
        json.k0 = json.k0 || 1.0;
        json.axis = json.axis || 'enu';
        var sphere = deriveConstants.sphere(json.a, json.b, json.rf, json.ellps, json.sphere);
        var ecc = deriveConstants.eccentricity(sphere.a, sphere.b, sphere.rf, json.R_A);
        var datumObj = json.datum || datum(json.datumCode, json.datum_params, sphere.a, sphere.b, ecc.es, ecc.ep2);
        extend(this, json); // transfer everything over from the projection because we don't know what we'll need
        extend(this, ourProj); // transfer all the methods from the projection
        // copy the 4 things over we calulated in deriveConstants.sphere
        this.a = sphere.a;
        this.b = sphere.b;
        this.rf = sphere.rf;
        this.sphere = sphere.sphere;
        // copy the 3 things we calculated in deriveConstants.eccentricity
        this.es = ecc.es;
        this.e = ecc.e;
        this.ep2 = ecc.ep2;
        // add in the datum object
        this.datum = datumObj;
        // init the projection
        this.init();
        // legecy callback from back in the day when it went to spatialreference.org
        callback(null, this);
    }
    Projection.projections = projections;
    Projection.projections.start();
    module.exports = Projection;
},
/* proj4/lib/parseCode.js */ function _(require, module, exports) {
    var defs = require(34) /* ./defs */;
    var wkt = require(39) /* ./wkt */;
    var projStr = require(36) /* ./projString */;
    function testObj(code) {
        return typeof code === 'string';
    }
    function testDef(code) {
        return code in defs;
    }
    var codeWords = ['GEOGCS', 'GEOCCS', 'PROJCS', 'LOCAL_CS'];
    function testWKT(code) {
        return codeWords.some(function (word) {
            return code.indexOf(word) > -1;
        });
    }
    function testProj(code) {
        return code[0] === '+';
    }
    function parse(code) {
        if (testObj(code)) {
            //check to see if this is a WKT string
            if (testDef(code)) {
                return defs[code];
            }
            if (testWKT(code)) {
                return wkt(code);
            }
            if (testProj(code)) {
                return projStr(code);
            }
        }
        else {
            return code;
        }
    }
    module.exports = parse;
},
/* proj4/lib/defs.js */ function _(require, module, exports) {
    var globals = require(35) /* ./global */;
    var parseProj = require(36) /* ./projString */;
    var wkt = require(39) /* ./wkt */;
    function defs(name) {
        /*global console*/
        var that = this;
        if (arguments.length === 2) {
            var def = arguments[1];
            if (typeof def === 'string') {
                if (def.charAt(0) === '+') {
                    defs[name] = parseProj(arguments[1]);
                }
                else {
                    defs[name] = wkt(arguments[1]);
                }
            }
            else {
                defs[name] = def;
            }
        }
        else if (arguments.length === 1) {
            if (Array.isArray(name)) {
                return name.map(function (v) {
                    if (Array.isArray(v)) {
                        defs.apply(that, v);
                    }
                    else {
                        defs(v);
                    }
                });
            }
            else if (typeof name === 'string') {
                if (name in defs) {
                    return defs[name];
                }
            }
            else if ('EPSG' in name) {
                defs['EPSG:' + name.EPSG] = name;
            }
            else if ('ESRI' in name) {
                defs['ESRI:' + name.ESRI] = name;
            }
            else if ('IAU2000' in name) {
                defs['IAU2000:' + name.IAU2000] = name;
            }
            else {
                console.log(name);
            }
            return;
        }
    }
    globals(defs);
    module.exports = defs;
},
/* proj4/lib/global.js */ function _(require, module, exports) {
    module.exports = function (defs) {
        defs('EPSG:4326', "+title=WGS 84 (long/lat) +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees");
        defs('EPSG:4269', "+title=NAD83 (long/lat) +proj=longlat +a=6378137.0 +b=6356752.31414036 +ellps=GRS80 +datum=NAD83 +units=degrees");
        defs('EPSG:3857', "+title=WGS 84 / Pseudo-Mercator +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs");
        defs.WGS84 = defs['EPSG:4326'];
        defs['EPSG:3785'] = defs['EPSG:3857']; // maintain backward compat, official code is 3857
        defs.GOOGLE = defs['EPSG:3857'];
        defs['EPSG:900913'] = defs['EPSG:3857'];
        defs['EPSG:102113'] = defs['EPSG:3857'];
    };
},
/* proj4/lib/projString.js */ function _(require, module, exports) {
    var D2R = 0.01745329251994329577;
    var PrimeMeridian = require(37) /* ./constants/PrimeMeridian */;
    var units = require(38) /* ./constants/units */;
    module.exports = function (defData) {
        var self = {};
        var paramObj = defData.split('+').map(function (v) {
            return v.trim();
        }).filter(function (a) {
            return a;
        }).reduce(function (p, a) {
            var split = a.split('=');
            split.push(true);
            p[split[0].toLowerCase()] = split[1];
            return p;
        }, {});
        var paramName, paramVal, paramOutname;
        var params = {
            proj: 'projName',
            datum: 'datumCode',
            rf: function (v) {
                self.rf = parseFloat(v);
            },
            lat_0: function (v) {
                self.lat0 = v * D2R;
            },
            lat_1: function (v) {
                self.lat1 = v * D2R;
            },
            lat_2: function (v) {
                self.lat2 = v * D2R;
            },
            lat_ts: function (v) {
                self.lat_ts = v * D2R;
            },
            lon_0: function (v) {
                self.long0 = v * D2R;
            },
            lon_1: function (v) {
                self.long1 = v * D2R;
            },
            lon_2: function (v) {
                self.long2 = v * D2R;
            },
            alpha: function (v) {
                self.alpha = parseFloat(v) * D2R;
            },
            lonc: function (v) {
                self.longc = v * D2R;
            },
            x_0: function (v) {
                self.x0 = parseFloat(v);
            },
            y_0: function (v) {
                self.y0 = parseFloat(v);
            },
            k_0: function (v) {
                self.k0 = parseFloat(v);
            },
            k: function (v) {
                self.k0 = parseFloat(v);
            },
            a: function (v) {
                self.a = parseFloat(v);
            },
            b: function (v) {
                self.b = parseFloat(v);
            },
            r_a: function () {
                self.R_A = true;
            },
            zone: function (v) {
                self.zone = parseInt(v, 10);
            },
            south: function () {
                self.utmSouth = true;
            },
            towgs84: function (v) {
                self.datum_params = v.split(",").map(function (a) {
                    return parseFloat(a);
                });
            },
            to_meter: function (v) {
                self.to_meter = parseFloat(v);
            },
            units: function (v) {
                self.units = v;
                if (units[v]) {
                    self.to_meter = units[v].to_meter;
                }
            },
            from_greenwich: function (v) {
                self.from_greenwich = v * D2R;
            },
            pm: function (v) {
                self.from_greenwich = (PrimeMeridian[v] ? PrimeMeridian[v] : parseFloat(v)) * D2R;
            },
            nadgrids: function (v) {
                if (v === '@null') {
                    self.datumCode = 'none';
                }
                else {
                    self.nadgrids = v;
                }
            },
            axis: function (v) {
                var legalAxis = "ewnsud";
                if (v.length === 3 && legalAxis.indexOf(v.substr(0, 1)) !== -1 && legalAxis.indexOf(v.substr(1, 1)) !== -1 && legalAxis.indexOf(v.substr(2, 1)) !== -1) {
                    self.axis = v;
                }
            }
        };
        for (paramName in paramObj) {
            paramVal = paramObj[paramName];
            if (paramName in params) {
                paramOutname = params[paramName];
                if (typeof paramOutname === 'function') {
                    paramOutname(paramVal);
                }
                else {
                    self[paramOutname] = paramVal;
                }
            }
            else {
                self[paramName] = paramVal;
            }
        }
        if (typeof self.datumCode === 'string' && self.datumCode !== "WGS84") {
            self.datumCode = self.datumCode.toLowerCase();
        }
        return self;
    };
},
/* proj4/lib/constants/PrimeMeridian.js */ function _(require, module, exports) {
    exports.greenwich = 0.0; //"0dE",
    exports.lisbon = -9.131906111111; //"9d07'54.862\"W",
    exports.paris = 2.337229166667; //"2d20'14.025\"E",
    exports.bogota = -74.080916666667; //"74d04'51.3\"W",
    exports.madrid = -3.687938888889; //"3d41'16.58\"W",
    exports.rome = 12.452333333333; //"12d27'8.4\"E",
    exports.bern = 7.439583333333; //"7d26'22.5\"E",
    exports.jakarta = 106.807719444444; //"106d48'27.79\"E",
    exports.ferro = -17.666666666667; //"17d40'W",
    exports.brussels = 4.367975; //"4d22'4.71\"E",
    exports.stockholm = 18.058277777778; //"18d3'29.8\"E",
    exports.athens = 23.7163375; //"23d42'58.815\"E",
    exports.oslo = 10.722916666667; //"10d43'22.5\"E"
},
/* proj4/lib/constants/units.js */ function _(require, module, exports) {
    exports.ft = { to_meter: 0.3048 };
    exports['us-ft'] = { to_meter: 1200 / 3937 };
},
/* proj4/lib/wkt.js */ function _(require, module, exports) {
    var D2R = 0.01745329251994329577;
    var extend = require(40) /* ./extend */;
    function mapit(obj, key, v) {
        obj[key] = v.map(function (aa) {
            var o = {};
            sExpr(aa, o);
            return o;
        }).reduce(function (a, b) {
            return extend(a, b);
        }, {});
    }
    function sExpr(v, obj) {
        var key;
        if (!Array.isArray(v)) {
            obj[v] = true;
            return;
        }
        else {
            key = v.shift();
            if (key === 'PARAMETER') {
                key = v.shift();
            }
            if (v.length === 1) {
                if (Array.isArray(v[0])) {
                    obj[key] = {};
                    sExpr(v[0], obj[key]);
                }
                else {
                    obj[key] = v[0];
                }
            }
            else if (!v.length) {
                obj[key] = true;
            }
            else if (key === 'TOWGS84') {
                obj[key] = v;
            }
            else {
                obj[key] = {};
                if (['UNIT', 'PRIMEM', 'VERT_DATUM'].indexOf(key) > -1) {
                    obj[key] = {
                        name: v[0].toLowerCase(),
                        convert: v[1]
                    };
                    if (v.length === 3) {
                        obj[key].auth = v[2];
                    }
                }
                else if (key === 'SPHEROID') {
                    obj[key] = {
                        name: v[0],
                        a: v[1],
                        rf: v[2]
                    };
                    if (v.length === 4) {
                        obj[key].auth = v[3];
                    }
                }
                else if (['GEOGCS', 'GEOCCS', 'DATUM', 'VERT_CS', 'COMPD_CS', 'LOCAL_CS', 'FITTED_CS', 'LOCAL_DATUM'].indexOf(key) > -1) {
                    v[0] = ['name', v[0]];
                    mapit(obj, key, v);
                }
                else if (v.every(function (aa) {
                    return Array.isArray(aa);
                })) {
                    mapit(obj, key, v);
                }
                else {
                    sExpr(v, obj[key]);
                }
            }
        }
    }
    function rename(obj, params) {
        var outName = params[0];
        var inName = params[1];
        if (!(outName in obj) && (inName in obj)) {
            obj[outName] = obj[inName];
            if (params.length === 3) {
                obj[outName] = params[2](obj[outName]);
            }
        }
    }
    function d2r(input) {
        return input * D2R;
    }
    function cleanWKT(wkt) {
        if (wkt.type === 'GEOGCS') {
            wkt.projName = 'longlat';
        }
        else if (wkt.type === 'LOCAL_CS') {
            wkt.projName = 'identity';
            wkt.local = true;
        }
        else {
            if (typeof wkt.PROJECTION === "object") {
                wkt.projName = Object.keys(wkt.PROJECTION)[0];
            }
            else {
                wkt.projName = wkt.PROJECTION;
            }
        }
        if (wkt.UNIT) {
            wkt.units = wkt.UNIT.name.toLowerCase();
            if (wkt.units === 'metre') {
                wkt.units = 'meter';
            }
            if (wkt.UNIT.convert) {
                if (wkt.type === 'GEOGCS') {
                    if (wkt.DATUM && wkt.DATUM.SPHEROID) {
                        wkt.to_meter = parseFloat(wkt.UNIT.convert, 10) * wkt.DATUM.SPHEROID.a;
                    }
                }
                else {
                    wkt.to_meter = parseFloat(wkt.UNIT.convert, 10);
                }
            }
        }
        if (wkt.GEOGCS) {
            //if(wkt.GEOGCS.PRIMEM&&wkt.GEOGCS.PRIMEM.convert){
            //  wkt.from_greenwich=wkt.GEOGCS.PRIMEM.convert*D2R;
            //}
            if (wkt.GEOGCS.DATUM) {
                wkt.datumCode = wkt.GEOGCS.DATUM.name.toLowerCase();
            }
            else {
                wkt.datumCode = wkt.GEOGCS.name.toLowerCase();
            }
            if (wkt.datumCode.slice(0, 2) === 'd_') {
                wkt.datumCode = wkt.datumCode.slice(2);
            }
            if (wkt.datumCode === 'new_zealand_geodetic_datum_1949' || wkt.datumCode === 'new_zealand_1949') {
                wkt.datumCode = 'nzgd49';
            }
            if (wkt.datumCode === "wgs_1984") {
                if (wkt.PROJECTION === 'Mercator_Auxiliary_Sphere') {
                    wkt.sphere = true;
                }
                wkt.datumCode = 'wgs84';
            }
            if (wkt.datumCode.slice(-6) === '_ferro') {
                wkt.datumCode = wkt.datumCode.slice(0, -6);
            }
            if (wkt.datumCode.slice(-8) === '_jakarta') {
                wkt.datumCode = wkt.datumCode.slice(0, -8);
            }
            if (~wkt.datumCode.indexOf('belge')) {
                wkt.datumCode = "rnb72";
            }
            if (wkt.GEOGCS.DATUM && wkt.GEOGCS.DATUM.SPHEROID) {
                wkt.ellps = wkt.GEOGCS.DATUM.SPHEROID.name.replace('_19', '').replace(/[Cc]larke\_18/, 'clrk');
                if (wkt.ellps.toLowerCase().slice(0, 13) === "international") {
                    wkt.ellps = 'intl';
                }
                wkt.a = wkt.GEOGCS.DATUM.SPHEROID.a;
                wkt.rf = parseFloat(wkt.GEOGCS.DATUM.SPHEROID.rf, 10);
            }
            if (~wkt.datumCode.indexOf('osgb_1936')) {
                wkt.datumCode = "osgb36";
            }
        }
        if (wkt.b && !isFinite(wkt.b)) {
            wkt.b = wkt.a;
        }
        function toMeter(input) {
            var ratio = wkt.to_meter || 1;
            return parseFloat(input, 10) * ratio;
        }
        var renamer = function (a) {
            return rename(wkt, a);
        };
        var list = [
            ['standard_parallel_1', 'Standard_Parallel_1'],
            ['standard_parallel_2', 'Standard_Parallel_2'],
            ['false_easting', 'False_Easting'],
            ['false_northing', 'False_Northing'],
            ['central_meridian', 'Central_Meridian'],
            ['latitude_of_origin', 'Latitude_Of_Origin'],
            ['latitude_of_origin', 'Central_Parallel'],
            ['scale_factor', 'Scale_Factor'],
            ['k0', 'scale_factor'],
            ['latitude_of_center', 'Latitude_of_center'],
            ['lat0', 'latitude_of_center', d2r],
            ['longitude_of_center', 'Longitude_Of_Center'],
            ['longc', 'longitude_of_center', d2r],
            ['x0', 'false_easting', toMeter],
            ['y0', 'false_northing', toMeter],
            ['long0', 'central_meridian', d2r],
            ['lat0', 'latitude_of_origin', d2r],
            ['lat0', 'standard_parallel_1', d2r],
            ['lat1', 'standard_parallel_1', d2r],
            ['lat2', 'standard_parallel_2', d2r],
            ['alpha', 'azimuth', d2r],
            ['srsCode', 'name']
        ];
        list.forEach(renamer);
        if (!wkt.long0 && wkt.longc && (wkt.projName === 'Albers_Conic_Equal_Area' || wkt.projName === "Lambert_Azimuthal_Equal_Area")) {
            wkt.long0 = wkt.longc;
        }
        if (!wkt.lat_ts && wkt.lat1 && (wkt.projName === 'Stereographic_South_Pole' || wkt.projName === 'Polar Stereographic (variant B)')) {
            wkt.lat0 = d2r(wkt.lat1 > 0 ? 90 : -90);
            wkt.lat_ts = wkt.lat1;
        }
    }
    module.exports = function (wkt, self) {
        var lisp = JSON.parse(("," + wkt).replace(/\s*\,\s*([A-Z_0-9]+?)(\[)/g, ',["$1",').slice(1).replace(/\s*\,\s*([A-Z_0-9]+?)\]/g, ',"$1"]').replace(/,\["VERTCS".+/, ''));
        var type = lisp.shift();
        var name = lisp.shift();
        lisp.unshift(['name', name]);
        lisp.unshift(['type', type]);
        lisp.unshift('output');
        var obj = {};
        sExpr(lisp, obj);
        cleanWKT(obj.output);
        return extend(self, obj.output);
    };
},
/* proj4/lib/extend.js */ function _(require, module, exports) {
    module.exports = function (destination, source) {
        destination = destination || {};
        var value, property;
        if (!source) {
            return destination;
        }
        for (property in source) {
            value = source[property];
            if (value !== undefined) {
                destination[property] = value;
            }
        }
        return destination;
    };
},
/* proj4/lib/projections.js */ function _(require, module, exports) {
    var projs = [
        require(42) /* ./projections/merc */,
        require(48) /* ./projections/longlat */
    ];
    var names = {};
    var projStore = [];
    function add(proj, i) {
        var len = projStore.length;
        if (!proj.names) {
            console.log(i);
            return true;
        }
        projStore[len] = proj;
        proj.names.forEach(function (n) {
            names[n.toLowerCase()] = len;
        });
        return this;
    }
    exports.add = add;
    exports.get = function (name) {
        if (!name) {
            return false;
        }
        var n = name.toLowerCase();
        if (typeof names[n] !== 'undefined' && projStore[names[n]]) {
            return projStore[names[n]];
        }
    };
    exports.start = function () {
        projs.forEach(add);
    };
},
/* proj4/lib/projections/merc.js */ function _(require, module, exports) {
    var msfnz = require(43) /* ../common/msfnz */;
    var HALF_PI = Math.PI / 2;
    var EPSLN = 1.0e-10;
    var R2D = 57.29577951308232088;
    var adjust_lon = require(44) /* ../common/adjust_lon */;
    var FORTPI = Math.PI / 4;
    var tsfnz = require(46) /* ../common/tsfnz */;
    var phi2z = require(47) /* ../common/phi2z */;
    exports.init = function () {
        var con = this.b / this.a;
        this.es = 1 - con * con;
        if (!('x0' in this)) {
            this.x0 = 0;
        }
        if (!('y0' in this)) {
            this.y0 = 0;
        }
        this.e = Math.sqrt(this.es);
        if (this.lat_ts) {
            if (this.sphere) {
                this.k0 = Math.cos(this.lat_ts);
            }
            else {
                this.k0 = msfnz(this.e, Math.sin(this.lat_ts), Math.cos(this.lat_ts));
            }
        }
        else {
            if (!this.k0) {
                if (this.k) {
                    this.k0 = this.k;
                }
                else {
                    this.k0 = 1;
                }
            }
        }
    };
    /* Mercator forward equations--mapping lat,long to x,y
      --------------------------------------------------*/
    exports.forward = function (p) {
        var lon = p.x;
        var lat = p.y;
        // convert to radians
        if (lat * R2D > 90 && lat * R2D < -90 && lon * R2D > 180 && lon * R2D < -180) {
            return null;
        }
        var x, y;
        if (Math.abs(Math.abs(lat) - HALF_PI) <= EPSLN) {
            return null;
        }
        else {
            if (this.sphere) {
                x = this.x0 + this.a * this.k0 * adjust_lon(lon - this.long0);
                y = this.y0 + this.a * this.k0 * Math.log(Math.tan(FORTPI + 0.5 * lat));
            }
            else {
                var sinphi = Math.sin(lat);
                var ts = tsfnz(this.e, lat, sinphi);
                x = this.x0 + this.a * this.k0 * adjust_lon(lon - this.long0);
                y = this.y0 - this.a * this.k0 * Math.log(ts);
            }
            p.x = x;
            p.y = y;
            return p;
        }
    };
    /* Mercator inverse equations--mapping x,y to lat/long
      --------------------------------------------------*/
    exports.inverse = function (p) {
        var x = p.x - this.x0;
        var y = p.y - this.y0;
        var lon, lat;
        if (this.sphere) {
            lat = HALF_PI - 2 * Math.atan(Math.exp(-y / (this.a * this.k0)));
        }
        else {
            var ts = Math.exp(-y / (this.a * this.k0));
            lat = phi2z(this.e, ts);
            if (lat === -9999) {
                return null;
            }
        }
        lon = adjust_lon(this.long0 + x / (this.a * this.k0));
        p.x = lon;
        p.y = lat;
        return p;
    };
    exports.names = ["Mercator", "Popular Visualisation Pseudo Mercator", "Mercator_1SP", "Mercator_Auxiliary_Sphere", "merc"];
},
/* proj4/lib/common/msfnz.js */ function _(require, module, exports) {
    module.exports = function (eccent, sinphi, cosphi) {
        var con = eccent * sinphi;
        return cosphi / (Math.sqrt(1 - con * con));
    };
},
/* proj4/lib/common/adjust_lon.js */ function _(require, module, exports) {
    var TWO_PI = Math.PI * 2;
    // SPI is slightly greater than Math.PI, so values that exceed the -180..180
    // degree range by a tiny amount don't get wrapped. This prevents points that
    // have drifted from their original location along the 180th meridian (due to
    // floating point error) from changing their sign.
    var SPI = 3.14159265359;
    var sign = require(45) /* ./sign */;
    module.exports = function (x) {
        return (Math.abs(x) <= SPI) ? x : (x - (sign(x) * TWO_PI));
    };
},
/* proj4/lib/common/sign.js */ function _(require, module, exports) {
    module.exports = function (x) {
        return x < 0 ? -1 : 1;
    };
},
/* proj4/lib/common/tsfnz.js */ function _(require, module, exports) {
    var HALF_PI = Math.PI / 2;
    module.exports = function (eccent, phi, sinphi) {
        var con = eccent * sinphi;
        var com = 0.5 * eccent;
        con = Math.pow(((1 - con) / (1 + con)), com);
        return (Math.tan(0.5 * (HALF_PI - phi)) / con);
    };
},
/* proj4/lib/common/phi2z.js */ function _(require, module, exports) {
    var HALF_PI = Math.PI / 2;
    module.exports = function (eccent, ts) {
        var eccnth = 0.5 * eccent;
        var con, dphi;
        var phi = HALF_PI - 2 * Math.atan(ts);
        for (var i = 0; i <= 15; i++) {
            con = eccent * Math.sin(phi);
            dphi = HALF_PI - 2 * Math.atan(ts * (Math.pow(((1 - con) / (1 + con)), eccnth))) - phi;
            phi += dphi;
            if (Math.abs(dphi) <= 0.0000000001) {
                return phi;
            }
        }
        //console.log("phi2z has NoConvergence");
        return -9999;
    };
},
/* proj4/lib/projections/longlat.js */ function _(require, module, exports) {
    exports.init = function () {
        //no-op for longlat
    };
    function identity(pt) {
        return pt;
    }
    exports.forward = identity;
    exports.inverse = identity;
    exports.names = ["longlat", "identity"];
},
/* proj4/lib/deriveConstants.js */ function _(require, module, exports) {
    // ellipoid pj_set_ell.c
    var SIXTH = 0.1666666666666666667;
    /* 1/6 */
    var RA4 = 0.04722222222222222222;
    /* 17/360 */
    var RA6 = 0.02215608465608465608;
    var EPSLN = 1.0e-10;
    var Ellipsoid = require(50) /* ./constants/Ellipsoid */;
    exports.eccentricity = function (a, b, rf, R_A) {
        var a2 = a * a; // used in geocentric
        var b2 = b * b; // used in geocentric
        var es = (a2 - b2) / a2; // e ^ 2
        var e = 0;
        if (R_A) {
            a *= 1 - es * (SIXTH + es * (RA4 + es * RA6));
            a2 = a * a;
            es = 0;
        }
        else {
            e = Math.sqrt(es); // eccentricity
        }
        var ep2 = (a2 - b2) / b2; // used in geocentric
        return {
            es: es,
            e: e,
            ep2: ep2
        };
    };
    exports.sphere = function (a, b, rf, ellps, sphere) {
        if (!a) { // do we have an ellipsoid?
            var ellipse = Ellipsoid[ellps];
            if (!ellipse) {
                ellipse = Ellipsoid.WGS84;
            }
            a = ellipse.a;
            b = ellipse.b;
            rf = ellipse.rf;
        }
        if (rf && !b) {
            b = (1.0 - 1.0 / rf) * a;
        }
        if (rf === 0 || Math.abs(a - b) < EPSLN) {
            sphere = true;
            b = a;
        }
        return {
            a: a,
            b: b,
            rf: rf,
            sphere: sphere
        };
    };
},
/* proj4/lib/constants/Ellipsoid.js */ function _(require, module, exports) {
    exports.MERIT = {
        a: 6378137.0,
        rf: 298.257,
        ellipseName: "MERIT 1983"
    };
    exports.SGS85 = {
        a: 6378136.0,
        rf: 298.257,
        ellipseName: "Soviet Geodetic System 85"
    };
    exports.GRS80 = {
        a: 6378137.0,
        rf: 298.257222101,
        ellipseName: "GRS 1980(IUGG, 1980)"
    };
    exports.IAU76 = {
        a: 6378140.0,
        rf: 298.257,
        ellipseName: "IAU 1976"
    };
    exports.airy = {
        a: 6377563.396,
        b: 6356256.910,
        ellipseName: "Airy 1830"
    };
    exports.APL4 = {
        a: 6378137,
        rf: 298.25,
        ellipseName: "Appl. Physics. 1965"
    };
    exports.NWL9D = {
        a: 6378145.0,
        rf: 298.25,
        ellipseName: "Naval Weapons Lab., 1965"
    };
    exports.mod_airy = {
        a: 6377340.189,
        b: 6356034.446,
        ellipseName: "Modified Airy"
    };
    exports.andrae = {
        a: 6377104.43,
        rf: 300.0,
        ellipseName: "Andrae 1876 (Den., Iclnd.)"
    };
    exports.aust_SA = {
        a: 6378160.0,
        rf: 298.25,
        ellipseName: "Australian Natl & S. Amer. 1969"
    };
    exports.GRS67 = {
        a: 6378160.0,
        rf: 298.2471674270,
        ellipseName: "GRS 67(IUGG 1967)"
    };
    exports.bessel = {
        a: 6377397.155,
        rf: 299.1528128,
        ellipseName: "Bessel 1841"
    };
    exports.bess_nam = {
        a: 6377483.865,
        rf: 299.1528128,
        ellipseName: "Bessel 1841 (Namibia)"
    };
    exports.clrk66 = {
        a: 6378206.4,
        b: 6356583.8,
        ellipseName: "Clarke 1866"
    };
    exports.clrk80 = {
        a: 6378249.145,
        rf: 293.4663,
        ellipseName: "Clarke 1880 mod."
    };
    exports.clrk58 = {
        a: 6378293.645208759,
        rf: 294.2606763692654,
        ellipseName: "Clarke 1858"
    };
    exports.CPM = {
        a: 6375738.7,
        rf: 334.29,
        ellipseName: "Comm. des Poids et Mesures 1799"
    };
    exports.delmbr = {
        a: 6376428.0,
        rf: 311.5,
        ellipseName: "Delambre 1810 (Belgium)"
    };
    exports.engelis = {
        a: 6378136.05,
        rf: 298.2566,
        ellipseName: "Engelis 1985"
    };
    exports.evrst30 = {
        a: 6377276.345,
        rf: 300.8017,
        ellipseName: "Everest 1830"
    };
    exports.evrst48 = {
        a: 6377304.063,
        rf: 300.8017,
        ellipseName: "Everest 1948"
    };
    exports.evrst56 = {
        a: 6377301.243,
        rf: 300.8017,
        ellipseName: "Everest 1956"
    };
    exports.evrst69 = {
        a: 6377295.664,
        rf: 300.8017,
        ellipseName: "Everest 1969"
    };
    exports.evrstSS = {
        a: 6377298.556,
        rf: 300.8017,
        ellipseName: "Everest (Sabah & Sarawak)"
    };
    exports.fschr60 = {
        a: 6378166.0,
        rf: 298.3,
        ellipseName: "Fischer (Mercury Datum) 1960"
    };
    exports.fschr60m = {
        a: 6378155.0,
        rf: 298.3,
        ellipseName: "Fischer 1960"
    };
    exports.fschr68 = {
        a: 6378150.0,
        rf: 298.3,
        ellipseName: "Fischer 1968"
    };
    exports.helmert = {
        a: 6378200.0,
        rf: 298.3,
        ellipseName: "Helmert 1906"
    };
    exports.hough = {
        a: 6378270.0,
        rf: 297.0,
        ellipseName: "Hough"
    };
    exports.intl = {
        a: 6378388.0,
        rf: 297.0,
        ellipseName: "International 1909 (Hayford)"
    };
    exports.kaula = {
        a: 6378163.0,
        rf: 298.24,
        ellipseName: "Kaula 1961"
    };
    exports.lerch = {
        a: 6378139.0,
        rf: 298.257,
        ellipseName: "Lerch 1979"
    };
    exports.mprts = {
        a: 6397300.0,
        rf: 191.0,
        ellipseName: "Maupertius 1738"
    };
    exports.new_intl = {
        a: 6378157.5,
        b: 6356772.2,
        ellipseName: "New International 1967"
    };
    exports.plessis = {
        a: 6376523.0,
        rf: 6355863.0,
        ellipseName: "Plessis 1817 (France)"
    };
    exports.krass = {
        a: 6378245.0,
        rf: 298.3,
        ellipseName: "Krassovsky, 1942"
    };
    exports.SEasia = {
        a: 6378155.0,
        b: 6356773.3205,
        ellipseName: "Southeast Asia"
    };
    exports.walbeck = {
        a: 6376896.0,
        b: 6355834.8467,
        ellipseName: "Walbeck"
    };
    exports.WGS60 = {
        a: 6378165.0,
        rf: 298.3,
        ellipseName: "WGS 60"
    };
    exports.WGS66 = {
        a: 6378145.0,
        rf: 298.25,
        ellipseName: "WGS 66"
    };
    exports.WGS7 = {
        a: 6378135.0,
        rf: 298.26,
        ellipseName: "WGS 72"
    };
    exports.WGS84 = {
        a: 6378137.0,
        rf: 298.257223563,
        ellipseName: "WGS 84"
    };
    exports.sphere = {
        a: 6370997.0,
        b: 6370997.0,
        ellipseName: "Normal Sphere (r=6370997)"
    };
},
/* proj4/lib/constants/Datum.js */ function _(require, module, exports) {
    exports.wgs84 = {
        towgs84: "0,0,0",
        ellipse: "WGS84",
        datumName: "WGS84"
    };
    exports.ch1903 = {
        towgs84: "674.374,15.056,405.346",
        ellipse: "bessel",
        datumName: "swiss"
    };
    exports.ggrs87 = {
        towgs84: "-199.87,74.79,246.62",
        ellipse: "GRS80",
        datumName: "Greek_Geodetic_Reference_System_1987"
    };
    exports.nad83 = {
        towgs84: "0,0,0",
        ellipse: "GRS80",
        datumName: "North_American_Datum_1983"
    };
    exports.nad27 = {
        nadgrids: "@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat",
        ellipse: "clrk66",
        datumName: "North_American_Datum_1927"
    };
    exports.potsdam = {
        towgs84: "606.0,23.0,413.0",
        ellipse: "bessel",
        datumName: "Potsdam Rauenberg 1950 DHDN"
    };
    exports.carthage = {
        towgs84: "-263.0,6.0,431.0",
        ellipse: "clark80",
        datumName: "Carthage 1934 Tunisia"
    };
    exports.hermannskogel = {
        towgs84: "653.0,-212.0,449.0",
        ellipse: "bessel",
        datumName: "Hermannskogel"
    };
    exports.ire65 = {
        towgs84: "482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15",
        ellipse: "mod_airy",
        datumName: "Ireland 1965"
    };
    exports.rassadiran = {
        towgs84: "-133.63,-157.5,-158.62",
        ellipse: "intl",
        datumName: "Rassadiran"
    };
    exports.nzgd49 = {
        towgs84: "59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993",
        ellipse: "intl",
        datumName: "New Zealand Geodetic Datum 1949"
    };
    exports.osgb36 = {
        towgs84: "446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894",
        ellipse: "airy",
        datumName: "Airy 1830"
    };
    exports.s_jtsk = {
        towgs84: "589,76,480",
        ellipse: 'bessel',
        datumName: 'S-JTSK (Ferro)'
    };
    exports.beduaram = {
        towgs84: '-106,-87,188',
        ellipse: 'clrk80',
        datumName: 'Beduaram'
    };
    exports.gunung_segara = {
        towgs84: '-403,684,41',
        ellipse: 'bessel',
        datumName: 'Gunung Segara Jakarta'
    };
    exports.rnb72 = {
        towgs84: "106.869,-52.2978,103.724,-0.33657,0.456955,-1.84218,1",
        ellipse: "intl",
        datumName: "Reseau National Belge 1972"
    };
},
/* proj4/lib/datum.js */ function _(require, module, exports) {
    var PJD_3PARAM = 1;
    var PJD_7PARAM = 2;
    var PJD_WGS84 = 4; // WGS84 or equivalent
    var PJD_NODATUM = 5; // WGS84 or equivalent
    var SEC_TO_RAD = 4.84813681109535993589914102357e-6;
    function datum(datumCode, datum_params, a, b, es, ep2) {
        var out = {};
        out.datum_type = PJD_WGS84; //default setting
        if (datumCode && datumCode === 'none') {
            out.datum_type = PJD_NODATUM;
        }
        if (datum_params) {
            out.datum_params = datum_params.map(parseFloat);
            if (out.datum_params[0] !== 0 || out.datum_params[1] !== 0 || out.datum_params[2] !== 0) {
                out.datum_type = PJD_3PARAM;
            }
            if (out.datum_params.length > 3) {
                if (out.datum_params[3] !== 0 || out.datum_params[4] !== 0 || out.datum_params[5] !== 0 || out.datum_params[6] !== 0) {
                    out.datum_type = PJD_7PARAM;
                    out.datum_params[3] *= SEC_TO_RAD;
                    out.datum_params[4] *= SEC_TO_RAD;
                    out.datum_params[5] *= SEC_TO_RAD;
                    out.datum_params[6] = (out.datum_params[6] / 1000000.0) + 1.0;
                }
            }
        }
        out.a = a; //datum object also uses these values
        out.b = b;
        out.es = es;
        out.ep2 = ep2;
        return out;
    }
    module.exports = datum;
},
/* proj4/lib/transform.js */ function _(require, module, exports) {
    var D2R = 0.01745329251994329577;
    var R2D = 57.29577951308232088;
    var PJD_3PARAM = 1;
    var PJD_7PARAM = 2;
    var datum_transform = require(54) /* ./datum_transform */;
    var adjust_axis = require(56) /* ./adjust_axis */;
    var proj = require(32) /* ./Proj */;
    var toPoint = require(57) /* ./common/toPoint */;
    function checkNotWGS(source, dest) {
        return ((source.datum.datum_type === PJD_3PARAM || source.datum.datum_type === PJD_7PARAM) && dest.datumCode !== 'WGS84') || ((dest.datum.datum_type === PJD_3PARAM || dest.datum.datum_type === PJD_7PARAM) && source.datumCode !== 'WGS84');
    }
    module.exports = function transform(source, dest, point) {
        var wgs84;
        if (Array.isArray(point)) {
            point = toPoint(point);
        }
        // Workaround for datum shifts towgs84, if either source or destination projection is not wgs84
        if (source.datum && dest.datum && checkNotWGS(source, dest)) {
            wgs84 = new proj('WGS84');
            point = transform(source, wgs84, point);
            source = wgs84;
        }
        // DGR, 2010/11/12
        if (source.axis !== 'enu') {
            point = adjust_axis(source, false, point);
        }
        // Transform source points to long/lat, if they aren't already.
        if (source.projName === 'longlat') {
            point = {
                x: point.x * D2R,
                y: point.y * D2R
            };
        }
        else {
            if (source.to_meter) {
                point = {
                    x: point.x * source.to_meter,
                    y: point.y * source.to_meter
                };
            }
            point = source.inverse(point); // Convert Cartesian to longlat
        }
        // Adjust for the prime meridian if necessary
        if (source.from_greenwich) {
            point.x += source.from_greenwich;
        }
        // Convert datums if needed, and if possible.
        point = datum_transform(source.datum, dest.datum, point);
        // Adjust for the prime meridian if necessary
        if (dest.from_greenwich) {
            point = {
                x: point.x - dest.grom_greenwich,
                y: point.y
            };
        }
        if (dest.projName === 'longlat') {
            // convert radians to decimal degrees
            point = {
                x: point.x * R2D,
                y: point.y * R2D
            };
        }
        else { // else project
            point = dest.forward(point);
            if (dest.to_meter) {
                point = {
                    x: point.x / dest.to_meter,
                    y: point.y / dest.to_meter
                };
            }
        }
        // DGR, 2010/11/12
        if (dest.axis !== 'enu') {
            return adjust_axis(dest, true, point);
        }
        return point;
    };
},
/* proj4/lib/datum_transform.js */ function _(require, module, exports) {
    var PJD_3PARAM = 1;
    var PJD_7PARAM = 2;
    var PJD_NODATUM = 5; // WGS84 or equivalent
    var datum = require(55) /* ./datumUtils */;
    function checkParams(type) {
        return (type === PJD_3PARAM || type === PJD_7PARAM);
    }
    module.exports = function (source, dest, point) {
        // Short cut if the datums are identical.
        if (datum.compareDatums(source, dest)) {
            return point; // in this case, zero is sucess,
            // whereas cs_compare_datums returns 1 to indicate TRUE
            // confusing, should fix this
        }
        // Explicitly skip datum transform by setting 'datum=none' as parameter for either source or dest
        if (source.datum_type === PJD_NODATUM || dest.datum_type === PJD_NODATUM) {
            return point;
        }
        // If this datum requires grid shifts, then apply it to geodetic coordinates.
        // Do we need to go through geocentric coordinates?
        if (source.es === dest.es && source.a === dest.a && !checkParams(source.datum_type) && !checkParams(dest.datum_type)) {
            return point;
        }
        // Convert to geocentric coordinates.
        point = datum.geodeticToGeocentric(point, source.es, source.a);
        // Convert between datums
        if (checkParams(source.datum_type)) {
            point = datum.geocentricToWgs84(point, source.datum_type, source.datum_params);
        }
        if (checkParams(dest.datum_type)) {
            point = datum.geocentricFromWgs84(point, dest.datum_type, dest.datum_params);
        }
        return datum.geocentricToGeodetic(point, dest.es, dest.a, dest.b);
    };
},
/* proj4/lib/datumUtils.js */ function _(require, module, exports) {
    var PJD_3PARAM = 1;
    var PJD_7PARAM = 2;
    var HALF_PI = Math.PI / 2;
    exports.compareDatums = function (source, dest) {
        if (source.datum_type !== dest.datum_type) {
            return false; // false, datums are not equal
        }
        else if (source.a !== dest.a || Math.abs(this.es - dest.es) > 0.000000000050) {
            // the tolerence for es is to ensure that GRS80 and WGS84
            // are considered identical
            return false;
        }
        else if (source.datum_type === PJD_3PARAM) {
            return (this.datum_params[0] === dest.datum_params[0] && source.datum_params[1] === dest.datum_params[1] && source.datum_params[2] === dest.datum_params[2]);
        }
        else if (source.datum_type === PJD_7PARAM) {
            return (source.datum_params[0] === dest.datum_params[0] && source.datum_params[1] === dest.datum_params[1] && source.datum_params[2] === dest.datum_params[2] && source.datum_params[3] === dest.datum_params[3] && source.datum_params[4] === dest.datum_params[4] && source.datum_params[5] === dest.datum_params[5] && source.datum_params[6] === dest.datum_params[6]);
        }
        else {
            return true; // datums are equal
        }
    }; // cs_compare_datums()
    /*
     * The function Convert_Geodetic_To_Geocentric converts geodetic coordinates
     * (latitude, longitude, and height) to geocentric coordinates (X, Y, Z),
     * according to the current ellipsoid parameters.
     *
     *    Latitude  : Geodetic latitude in radians                     (input)
     *    Longitude : Geodetic longitude in radians                    (input)
     *    Height    : Geodetic height, in meters                       (input)
     *    X         : Calculated Geocentric X coordinate, in meters    (output)
     *    Y         : Calculated Geocentric Y coordinate, in meters    (output)
     *    Z         : Calculated Geocentric Z coordinate, in meters    (output)
     *
     */
    exports.geodeticToGeocentric = function (p, es, a) {
        var Longitude = p.x;
        var Latitude = p.y;
        var Height = p.z ? p.z : 0; //Z value not always supplied
        var Rn; /*  Earth radius at location  */
        var Sin_Lat; /*  Math.sin(Latitude)  */
        var Sin2_Lat; /*  Square of Math.sin(Latitude)  */
        var Cos_Lat; /*  Math.cos(Latitude)  */
        /*
         ** Don't blow up if Latitude is just a little out of the value
         ** range as it may just be a rounding issue.  Also removed longitude
         ** test, it should be wrapped by Math.cos() and Math.sin().  NFW for PROJ.4, Sep/2001.
         */
        if (Latitude < -HALF_PI && Latitude > -1.001 * HALF_PI) {
            Latitude = -HALF_PI;
        }
        else if (Latitude > HALF_PI && Latitude < 1.001 * HALF_PI) {
            Latitude = HALF_PI;
        }
        else if ((Latitude < -HALF_PI) || (Latitude > HALF_PI)) {
            /* Latitude out of range */
            //..reportError('geocent:lat out of range:' + Latitude);
            return null;
        }
        if (Longitude > Math.PI) {
            Longitude -= (2 * Math.PI);
        }
        Sin_Lat = Math.sin(Latitude);
        Cos_Lat = Math.cos(Latitude);
        Sin2_Lat = Sin_Lat * Sin_Lat;
        Rn = a / (Math.sqrt(1.0e0 - es * Sin2_Lat));
        return {
            x: (Rn + Height) * Cos_Lat * Math.cos(Longitude),
            y: (Rn + Height) * Cos_Lat * Math.sin(Longitude),
            z: ((Rn * (1 - es)) + Height) * Sin_Lat
        };
    }; // cs_geodetic_to_geocentric()
    exports.geocentricToGeodetic = function (p, es, a, b) {
        /* local defintions and variables */
        /* end-criterium of loop, accuracy of sin(Latitude) */
        var genau = 1e-12;
        var genau2 = (genau * genau);
        var maxiter = 30;
        var P; /* distance between semi-minor axis and location */
        var RR; /* distance between center and location */
        var CT; /* sin of geocentric latitude */
        var ST; /* cos of geocentric latitude */
        var RX;
        var RK;
        var RN; /* Earth radius at location */
        var CPHI0; /* cos of start or old geodetic latitude in iterations */
        var SPHI0; /* sin of start or old geodetic latitude in iterations */
        var CPHI; /* cos of searched geodetic latitude */
        var SPHI; /* sin of searched geodetic latitude */
        var SDPHI; /* end-criterium: addition-theorem of sin(Latitude(iter)-Latitude(iter-1)) */
        var iter; /* # of continous iteration, max. 30 is always enough (s.a.) */
        var X = p.x;
        var Y = p.y;
        var Z = p.z ? p.z : 0.0; //Z value not always supplied
        var Longitude;
        var Latitude;
        var Height;
        P = Math.sqrt(X * X + Y * Y);
        RR = Math.sqrt(X * X + Y * Y + Z * Z);
        /*      special cases for latitude and longitude */
        if (P / a < genau) {
            /*  special case, if P=0. (X=0., Y=0.) */
            Longitude = 0.0;
            /*  if (X,Y,Z)=(0.,0.,0.) then Height becomes semi-minor axis
             *  of ellipsoid (=center of mass), Latitude becomes PI/2 */
            if (RR / a < genau) {
                Latitude = HALF_PI;
                Height = -b;
                return {
                    x: p.x,
                    y: p.y,
                    z: p.z
                };
            }
        }
        else {
            /*  ellipsoidal (geodetic) longitude
             *  interval: -PI < Longitude <= +PI */
            Longitude = Math.atan2(Y, X);
        }
        /* --------------------------------------------------------------
         * Following iterative algorithm was developped by
         * "Institut for Erdmessung", University of Hannover, July 1988.
         * Internet: www.ife.uni-hannover.de
         * Iterative computation of CPHI,SPHI and Height.
         * Iteration of CPHI and SPHI to 10**-12 radian resp.
         * 2*10**-7 arcsec.
         * --------------------------------------------------------------
         */
        CT = Z / RR;
        ST = P / RR;
        RX = 1.0 / Math.sqrt(1.0 - es * (2.0 - es) * ST * ST);
        CPHI0 = ST * (1.0 - es) * RX;
        SPHI0 = CT * RX;
        iter = 0;
        /* loop to find sin(Latitude) resp. Latitude
         * until |sin(Latitude(iter)-Latitude(iter-1))| < genau */
        do {
            iter++;
            RN = a / Math.sqrt(1.0 - es * SPHI0 * SPHI0);
            /*  ellipsoidal (geodetic) height */
            Height = P * CPHI0 + Z * SPHI0 - RN * (1.0 - es * SPHI0 * SPHI0);
            RK = es * RN / (RN + Height);
            RX = 1.0 / Math.sqrt(1.0 - RK * (2.0 - RK) * ST * ST);
            CPHI = ST * (1.0 - RK) * RX;
            SPHI = CT * RX;
            SDPHI = SPHI * CPHI0 - CPHI * SPHI0;
            CPHI0 = CPHI;
            SPHI0 = SPHI;
        } while (SDPHI * SDPHI > genau2 && iter < maxiter);
        /*      ellipsoidal (geodetic) latitude */
        Latitude = Math.atan(SPHI / Math.abs(CPHI));
        return {
            x: Longitude,
            y: Latitude,
            z: Height
        };
    }; // cs_geocentric_to_geodetic()
    /****************************************************************/
    // pj_geocentic_to_wgs84( p )
    //  p = point to transform in geocentric coordinates (x,y,z)
    /** point object, nothing fancy, just allows values to be
        passed back and forth by reference rather than by value.
        Other point classes may be used as long as they have
        x and y properties, which will get modified in the transform method.
    */
    exports.geocentricToWgs84 = function (p, datum_type, datum_params) {
        if (datum_type === PJD_3PARAM) {
            // if( x[io] === HUGE_VAL )
            //    continue;
            return {
                x: p.x + datum_params[0],
                y: p.y + datum_params[1],
                z: p.z + datum_params[2],
            };
        }
        else if (datum_type === PJD_7PARAM) {
            var Dx_BF = datum_params[0];
            var Dy_BF = datum_params[1];
            var Dz_BF = datum_params[2];
            var Rx_BF = datum_params[3];
            var Ry_BF = datum_params[4];
            var Rz_BF = datum_params[5];
            var M_BF = datum_params[6];
            // if( x[io] === HUGE_VAL )
            //    continue;
            return {
                x: M_BF * (p.x - Rz_BF * p.y + Ry_BF * p.z) + Dx_BF,
                y: M_BF * (Rz_BF * p.x + p.y - Rx_BF * p.z) + Dy_BF,
                z: M_BF * (-Ry_BF * p.x + Rx_BF * p.y + p.z) + Dz_BF
            };
        }
    }; // cs_geocentric_to_wgs84
    /****************************************************************/
    // pj_geocentic_from_wgs84()
    //  coordinate system definition,
    //  point to transform in geocentric coordinates (x,y,z)
    exports.geocentricFromWgs84 = function (p, datum_type, datum_params) {
        if (datum_type === PJD_3PARAM) {
            //if( x[io] === HUGE_VAL )
            //    continue;
            return {
                x: p.x - datum_params[0],
                y: p.y - datum_params[1],
                z: p.z - datum_params[2],
            };
        }
        else if (datum_type === PJD_7PARAM) {
            var Dx_BF = datum_params[0];
            var Dy_BF = datum_params[1];
            var Dz_BF = datum_params[2];
            var Rx_BF = datum_params[3];
            var Ry_BF = datum_params[4];
            var Rz_BF = datum_params[5];
            var M_BF = datum_params[6];
            var x_tmp = (p.x - Dx_BF) / M_BF;
            var y_tmp = (p.y - Dy_BF) / M_BF;
            var z_tmp = (p.z - Dz_BF) / M_BF;
            //if( x[io] === HUGE_VAL )
            //    continue;
            return {
                x: x_tmp + Rz_BF * y_tmp - Ry_BF * z_tmp,
                y: -Rz_BF * x_tmp + y_tmp + Rx_BF * z_tmp,
                z: Ry_BF * x_tmp - Rx_BF * y_tmp + z_tmp
            };
        } //cs_geocentric_from_wgs84()
    };
},
/* proj4/lib/adjust_axis.js */ function _(require, module, exports) {
    module.exports = function (crs, denorm, point) {
        var xin = point.x, yin = point.y, zin = point.z || 0.0;
        var v, t, i;
        var out = {};
        for (i = 0; i < 3; i++) {
            if (denorm && i === 2 && point.z === undefined) {
                continue;
            }
            if (i === 0) {
                v = xin;
                t = 'x';
            }
            else if (i === 1) {
                v = yin;
                t = 'y';
            }
            else {
                v = zin;
                t = 'z';
            }
            switch (crs.axis[i]) {
                case 'e':
                    out[t] = v;
                    break;
                case 'w':
                    out[t] = -v;
                    break;
                case 'n':
                    out[t] = v;
                    break;
                case 's':
                    out[t] = -v;
                    break;
                case 'u':
                    if (point[t] !== undefined) {
                        out.z = v;
                    }
                    break;
                case 'd':
                    if (point[t] !== undefined) {
                        out.z = -v;
                    }
                    break;
                default:
                    //console.log("ERROR: unknow axis ("+crs.axis[i]+") - check definition of "+crs.projName);
                    return null;
            }
        }
        return out;
    };
},
/* proj4/lib/common/toPoint.js */ function _(require, module, exports) {
    module.exports = function (array) {
        var out = {
            x: array[0],
            y: array[1]
        };
        if (array.length > 2) {
            out.z = array[2];
        }
        if (array.length > 3) {
            out.m = array[3];
        }
        return out;
    };
},
/* models/renderers/renderer.js */ function _(require, module, exports) {
    const dom_view_1 = require(59) /* ../../core/dom_view */;
    const visuals = require(63) /* ../../core/visuals */;
    const p = require(18) /* ../../core/properties */;
    const model_1 = require(64) /* ../../model */;
    // This shouldn't be a DOMView, but annotations create a mess.
    class RendererView extends dom_view_1.DOMView {
        initialize() {
            super.initialize();
            this.visuals = new visuals.Visuals(this.model);
            this._has_finished = true; // XXX: should be in render() but subclasses don't respect super()
        }
        get plot_view() {
            return this.parent;
        }
        get plot_model() {
            return this.parent.model;
        }
        request_render() {
            this.plot_view.request_render();
        }
        map_to_screen(x, y) {
            return this.plot_view.map_to_screen(x, y, this.model.x_range_name, this.model.y_range_name);
        }
        get needs_clip() {
            return false;
        }
        notify_finished() {
            this.plot_view.notify_finished();
        }
        get has_webgl() {
            return false;
        }
    }
    exports.RendererView = RendererView;
    RendererView.__name__ = "RendererView";
    class Renderer extends model_1.Model {
        constructor(attrs) {
            super(attrs);
        }
        static init_Renderer() {
            this.define({
                level: [p.RenderLevel],
                visible: [p.Boolean, true],
            });
        }
    }
    exports.Renderer = Renderer;
    Renderer.__name__ = "Renderer";
    Renderer.init_Renderer();
},
/* core/dom_view.js */ function _(require, module, exports) {
    const view_1 = require(60) /* ./view */;
    const DOM = require(61) /* ./dom */;
    const root_1 = require(62) /* ../styles/root */;
    class DOMView extends view_1.View {
        initialize() {
            super.initialize();
            this._has_finished = false;
            this.el = this._createElement();
        }
        remove() {
            DOM.removeElement(this.el);
            super.remove();
        }
        css_classes() {
            return [];
        }
        cursor(_sx, _sy) {
            return null;
        }
        render() { }
        renderTo(element) {
            element.appendChild(this.el);
            this.render();
        }
        has_finished() {
            return this._has_finished;
        }
        get _root_element() {
            return DOM.parent(this.el, `.${root_1.bk_root}`) || document.body;
        }
        get is_idle() {
            return this.has_finished();
        }
        _createElement() {
            return DOM.createElement(this.tagName, { class: this.css_classes() });
        }
    }
    exports.DOMView = DOMView;
    DOMView.__name__ = "DOMView";
    DOMView.prototype.tagName = "div";
},
/* core/view.js */ function _(require, module, exports) {
    const signaling_1 = require(13) /* ./signaling */;
    const types_1 = require(7) /* ./util/types */;
    const string_1 = require(25) /* ./util/string */;
    class View extends signaling_1.Signalable() {
        constructor(options) {
            super();
            this.removed = new signaling_1.Signal0(this, "removed");
            if (options.model != null)
                this.model = options.model;
            else
                throw new Error("model of a view wasn't configured");
            this._parent = options.parent;
            this.id = options.id || string_1.uniqueId();
            this.initialize();
            if (options.connect_signals !== false)
                this.connect_signals();
        }
        initialize() { }
        remove() {
            this._parent = undefined;
            this.disconnect_signals();
            this.removed.emit();
        }
        toString() {
            return `${this.model.type}View(${this.id})`;
        }
        serializable_state() {
            return { type: this.model.type };
        }
        get parent() {
            if (this._parent !== undefined)
                return this._parent;
            else
                throw new Error("parent of a view wasn't configured");
        }
        get is_root() {
            return this.parent === null;
        }
        get root() {
            return this.is_root ? this : this.parent.root;
        }
        assert_root() {
            if (!this.is_root)
                throw new Error(`${this.toString()} is not a root layout`);
        }
        connect_signals() { }
        disconnect_signals() {
            signaling_1.Signal.disconnectReceiver(this);
        }
        on_change(properties, fn) {
            for (const property of types_1.isArray(properties) ? properties : [properties])
                this.connect(property.change, fn);
        }
    }
    exports.View = View;
    View.__name__ = "View";
},
/* core/dom.js */ function _(require, module, exports) {
    const types_1 = require(7) /* ./util/types */;
    const _createElement = (tag) => {
        return (attrs = {}, ...children) => {
            const element = document.createElement(tag);
            element.classList.add("bk");
            for (const attr in attrs) {
                let value = attrs[attr];
                if (value == null || types_1.isBoolean(value) && !value)
                    continue;
                if (attr === "class") {
                    if (types_1.isString(value))
                        value = value.split(/\s+/);
                    if (types_1.isArray(value)) {
                        for (const cls of value) {
                            if (cls != null)
                                element.classList.add(cls);
                        }
                        continue;
                    }
                }
                if (attr === "style" && types_1.isPlainObject(value)) {
                    for (const prop in value) {
                        element.style[prop] = value[prop];
                    }
                    continue;
                }
                if (attr === "data" && types_1.isPlainObject(value)) {
                    for (const key in value) {
                        element.dataset[key] = value[key]; // XXX: attrs needs a better type
                    }
                    continue;
                }
                element.setAttribute(attr, value);
            }
            function append(child) {
                if (child instanceof HTMLElement)
                    element.appendChild(child);
                else if (types_1.isString(child))
                    element.appendChild(document.createTextNode(child));
                else if (child != null && child !== false)
                    throw new Error(`expected an HTMLElement, string, false or null, got ${JSON.stringify(child)}`);
            }
            for (const child of children) {
                if (types_1.isArray(child)) {
                    for (const _child of child)
                        append(_child);
                }
                else
                    append(child);
            }
            return element;
        };
    };
    function createElement(tag, attrs, ...children) {
        return _createElement(tag)(attrs, ...children);
    }
    exports.createElement = createElement;
    exports.div = _createElement("div"), exports.span = _createElement("span"), exports.canvas = _createElement("canvas"), exports.link = _createElement("link"), exports.style = _createElement("style"), exports.a = _createElement("a"), exports.p = _createElement("p"), exports.i = _createElement("i"), exports.pre = _createElement("pre"), exports.button = _createElement("button"), exports.label = _createElement("label"), exports.input = _createElement("input"), exports.select = _createElement("select"), exports.option = _createElement("option"), exports.optgroup = _createElement("optgroup"), exports.textarea = _createElement("textarea");
    function nbsp() {
        return document.createTextNode("\u00a0");
    }
    exports.nbsp = nbsp;
    function removeElement(element) {
        const parent = element.parentNode;
        if (parent != null) {
            parent.removeChild(element);
        }
    }
    exports.removeElement = removeElement;
    function replaceWith(element, replacement) {
        const parent = element.parentNode;
        if (parent != null) {
            parent.replaceChild(replacement, element);
        }
    }
    exports.replaceWith = replaceWith;
    function prepend(element, ...nodes) {
        const first = element.firstChild;
        for (const node of nodes) {
            element.insertBefore(node, first);
        }
    }
    exports.prepend = prepend;
    function empty(element) {
        let child;
        while (child = element.firstChild) {
            element.removeChild(child);
        }
    }
    exports.empty = empty;
    function display(element) {
        element.style.display = "";
    }
    exports.display = display;
    function undisplay(element) {
        element.style.display = "none";
    }
    exports.undisplay = undisplay;
    function show(element) {
        element.style.visibility = "";
    }
    exports.show = show;
    function hide(element) {
        element.style.visibility = "hidden";
    }
    exports.hide = hide;
    function offset(element) {
        const rect = element.getBoundingClientRect();
        return {
            top: rect.top + window.pageYOffset - document.documentElement.clientTop,
            left: rect.left + window.pageXOffset - document.documentElement.clientLeft,
        };
    }
    exports.offset = offset;
    function matches(el, selector) {
        const p = Element.prototype;
        const f = p.matches || p.webkitMatchesSelector || p.mozMatchesSelector || p.msMatchesSelector;
        return f.call(el, selector);
    }
    exports.matches = matches;
    function parent(el, selector) {
        let node = el;
        while (node = node.parentElement) {
            if (matches(node, selector))
                return node;
        }
        return null;
    }
    exports.parent = parent;
    function num(value) {
        return parseFloat(value) || 0;
    }
    function extents(el) {
        const style = getComputedStyle(el);
        return {
            border: {
                top: num(style.borderTopWidth),
                bottom: num(style.borderBottomWidth),
                left: num(style.borderLeftWidth),
                right: num(style.borderRightWidth),
            },
            margin: {
                top: num(style.marginTop),
                bottom: num(style.marginBottom),
                left: num(style.marginLeft),
                right: num(style.marginRight),
            },
            padding: {
                top: num(style.paddingTop),
                bottom: num(style.paddingBottom),
                left: num(style.paddingLeft),
                right: num(style.paddingRight),
            },
        };
    }
    exports.extents = extents;
    function size(el) {
        const rect = el.getBoundingClientRect();
        return {
            width: Math.ceil(rect.width),
            height: Math.ceil(rect.height),
        };
    }
    exports.size = size;
    function scroll_size(el) {
        return {
            width: Math.ceil(el.scrollWidth),
            height: Math.ceil(el.scrollHeight),
        };
    }
    exports.scroll_size = scroll_size;
    function outer_size(el) {
        const { margin: { left, right, top, bottom } } = extents(el);
        const { width, height } = size(el);
        return {
            width: Math.ceil(width + left + right),
            height: Math.ceil(height + top + bottom),
        };
    }
    exports.outer_size = outer_size;
    function content_size(el) {
        const { left, top } = el.getBoundingClientRect();
        const { padding } = extents(el);
        let width = 0;
        let height = 0;
        for (const child of children(el)) {
            const rect = child.getBoundingClientRect();
            width = Math.max(width, Math.ceil(rect.left - left - padding.left + rect.width));
            height = Math.max(height, Math.ceil(rect.top - top - padding.top + rect.height));
        }
        return { width, height };
    }
    exports.content_size = content_size;
    function position(el, box, margin) {
        const { style } = el;
        style.left = `${box.x}px`;
        style.top = `${box.y}px`;
        style.width = `${box.width}px`;
        style.height = `${box.height}px`;
        if (margin == null)
            style.margin = "";
        else {
            const { top, right, bottom, left } = margin;
            style.margin = `${top}px ${right}px ${bottom}px ${left}px`;
        }
    }
    exports.position = position;
    function children(el) {
        return Array.from(el.children);
    }
    exports.children = children;
    class ClassList {
        constructor(el) {
            this.el = el;
            this.classList = el.classList;
        }
        get values() {
            const values = [];
            for (let i = 0; i < this.classList.length; i++) {
                const item = this.classList.item(i);
                if (item != null)
                    values.push(item);
            }
            return values;
        }
        has(cls) {
            return this.classList.contains(cls);
        }
        add(...classes) {
            for (const cls of classes)
                this.classList.add(cls);
            return this;
        }
        remove(...classes) {
            for (const cls of classes)
                this.classList.remove(cls);
            return this;
        }
        clear() {
            for (const cls of this.values) {
                if (cls != "bk")
                    this.classList.remove(cls);
            }
            return this;
        }
        toggle(cls, activate) {
            const add = activate != null ? activate : !this.has(cls);
            if (add)
                this.add(cls);
            else
                this.remove(cls);
            return this;
        }
    }
    exports.ClassList = ClassList;
    ClassList.__name__ = "ClassList";
    function classes(el) {
        return new ClassList(el);
    }
    exports.classes = classes;
    var Keys;
    (function (Keys) {
        Keys[Keys["Backspace"] = 8] = "Backspace";
        Keys[Keys["Tab"] = 9] = "Tab";
        Keys[Keys["Enter"] = 13] = "Enter";
        Keys[Keys["Esc"] = 27] = "Esc";
        Keys[Keys["PageUp"] = 33] = "PageUp";
        Keys[Keys["PageDown"] = 34] = "PageDown";
        Keys[Keys["Left"] = 37] = "Left";
        Keys[Keys["Up"] = 38] = "Up";
        Keys[Keys["Right"] = 39] = "Right";
        Keys[Keys["Down"] = 40] = "Down";
        Keys[Keys["Delete"] = 46] = "Delete";
    })(Keys = exports.Keys || (exports.Keys = {}));
    function undisplayed(el, fn) {
        const { display } = el.style;
        el.style.display = "none";
        try {
            return fn();
        }
        finally {
            el.style.display = display;
        }
    }
    exports.undisplayed = undisplayed;
    function unsized(el, fn) {
        return sized(el, {}, fn);
    }
    exports.unsized = unsized;
    function sized(el, size, fn) {
        const { width, height, position, display } = el.style;
        el.style.position = "absolute";
        el.style.display = "";
        el.style.width = size.width != null && size.width != Infinity ? `${size.width}px` : "auto";
        el.style.height = size.height != null && size.height != Infinity ? `${size.height}px` : "auto";
        try {
            return fn();
        }
        finally {
            el.style.position = position;
            el.style.display = display;
            el.style.width = width;
            el.style.height = height;
        }
    }
    exports.sized = sized;
    class StyleSheet {
        constructor() {
            this.style = exports.style({ type: "text/css" });
            prepend(document.head, this.style);
        }
        append(css) {
            this.style.appendChild(document.createTextNode(css));
        }
    }
    exports.StyleSheet = StyleSheet;
    StyleSheet.__name__ = "StyleSheet";
    exports.styles = new StyleSheet();
},
/* styles/root.js */ function _(require, module, exports) {
    const _a = require(61) /* ../core/dom */;
    _a.styles.append(".bk-root {\n  position: relative;\n  width: auto;\n  height: auto;\n  z-index: 0;\n  box-sizing: border-box;\n  font-family: Helvetica, Arial, sans-serif;\n  font-size: 10pt;\n}\n.bk-root .bk,\n.bk-root .bk:before,\n.bk-root .bk:after {\n  box-sizing: inherit;\n  margin: 0;\n  border: 0;\n  padding: 0;\n  background-image: none;\n  font-family: inherit;\n  font-size: 100%;\n  line-height: 1.42857143;\n}\n.bk-root pre.bk {\n  font-family: Courier, monospace;\n}\n");
    exports.bk_root = "bk-root";
},
/* core/visuals.js */ function _(require, module, exports) {
    const mixins = require(17) /* ./property_mixins */;
    const color_1 = require(20) /* ./util/color */;
    function _horz(ctx, h, h2) {
        ctx.moveTo(0, h2 + 0.5);
        ctx.lineTo(h, h2 + 0.5);
        ctx.stroke();
    }
    function _vert(ctx, h, h2) {
        ctx.moveTo(h2 + 0.5, 0);
        ctx.lineTo(h2 + 0.5, h);
        ctx.stroke();
    }
    function _x(ctx, h) {
        ctx.moveTo(0, h);
        ctx.lineTo(h, 0);
        ctx.stroke();
        ctx.moveTo(0, 0);
        ctx.lineTo(h, h);
        ctx.stroke();
    }
    function _get_canvas(size) {
        const canvas = document.createElement('canvas');
        canvas.width = size;
        canvas.height = size;
        return canvas;
    }
    function create_hatch_canvas(hatch_pattern, hatch_color, hatch_scale, hatch_weight) {
        const h = hatch_scale;
        const h2 = h / 2;
        const h4 = h2 / 2;
        const canvas = _get_canvas(hatch_scale);
        const ctx = canvas.getContext("2d");
        ctx.strokeStyle = hatch_color;
        ctx.lineCap = "square";
        ctx.fillStyle = hatch_color;
        ctx.lineWidth = hatch_weight;
        switch (hatch_pattern) {
            // we should not need these if code conditions on hatch.doit, but
            // include them here just for completeness
            case " ":
            case "blank":
                break;
            case ".":
            case "dot":
                ctx.arc(h2, h2, h2 / 2, 0, 2 * Math.PI, true);
                ctx.fill();
                break;
            case "o":
            case "ring":
                ctx.arc(h2, h2, h2 / 2, 0, 2 * Math.PI, true);
                ctx.stroke();
                break;
            case "-":
            case "horizontal_line":
                _horz(ctx, h, h2);
                break;
            case "|":
            case "vertical_line":
                _vert(ctx, h, h2);
                break;
            case "+":
            case "cross":
                _horz(ctx, h, h2);
                _vert(ctx, h, h2);
                break;
            case "\"":
            case "horizontal_dash":
                _horz(ctx, h2, h2);
                break;
            case ":":
            case "vertical_dash":
                _vert(ctx, h2, h2);
                break;
            case "@":
            case "spiral":
                const h30 = h / 30;
                ctx.moveTo(h2, h2);
                for (let i = 0; i < 360; i++) {
                    const angle = 0.1 * i;
                    const x = h2 + (h30 * angle) * Math.cos(angle);
                    const y = h2 + (h30 * angle) * Math.sin(angle);
                    ctx.lineTo(x, y);
                }
                ctx.stroke();
                break;
            case "/":
            case "right_diagonal_line":
                ctx.moveTo(-h4 + 0.5, h);
                ctx.lineTo(h4 + 0.5, 0);
                ctx.stroke();
                ctx.moveTo(h4 + 0.5, h);
                ctx.lineTo(3 * h4 + 0.5, 0);
                ctx.stroke();
                ctx.moveTo(3 * h4 + 0.5, h);
                ctx.lineTo(5 * h4 + 0.5, 0);
                ctx.stroke();
                ctx.stroke();
                break;
            case "\\":
            case "left_diagonal_line":
                ctx.moveTo(h4 + 0.5, h);
                ctx.lineTo(-h4 + 0.5, 0);
                ctx.stroke();
                ctx.moveTo(3 * h4 + 0.5, h);
                ctx.lineTo(h4 + 0.5, 0);
                ctx.stroke();
                ctx.moveTo(5 * h4 + 0.5, h);
                ctx.lineTo(3 * h4 + 0.5, 0);
                ctx.stroke();
                ctx.stroke();
                break;
            case "x":
            case "diagonal_cross":
                _x(ctx, h);
                break;
            case ",":
            case "right_diagonal_dash":
                ctx.moveTo(h4 + 0.5, 3 * h4 + 0.5);
                ctx.lineTo(3 * h4 + 0.5, h4 + 0.5);
                ctx.stroke();
                break;
            case "`":
            case "left_diagonal_dash":
                ctx.moveTo(h4 + 0.5, h4 + 0.5);
                ctx.lineTo(3 * h4 + 0.5, 3 * h4 + 0.5);
                ctx.stroke();
                break;
            case "v":
            case "horizontal_wave":
                ctx.moveTo(0, h4);
                ctx.lineTo(h2, 3 * h4);
                ctx.lineTo(h, h4);
                ctx.stroke();
                break;
            case ">":
            case "vertical_wave":
                ctx.moveTo(h4, 0);
                ctx.lineTo(3 * h4, h2);
                ctx.lineTo(h4, h);
                ctx.stroke();
                break;
            case "*":
            case "criss_cross":
                _x(ctx, h);
                _horz(ctx, h, h2);
                _vert(ctx, h, h2);
                break;
        }
        return canvas;
    }
    class ContextProperties {
        constructor(obj, prefix = "") {
            this.obj = obj;
            this.prefix = prefix;
            // }
            this.cache = {};
            for (const attr of this.attrs)
                this[attr] = obj.properties[prefix + attr];
        }
        warm_cache(source) {
            for (const attr of this.attrs) {
                const prop = this.obj.properties[this.prefix + attr];
                if (prop.spec.value !== undefined) // TODO (bev) better test?
                    this.cache[attr] = prop.spec.value;
                else if (source != null)
                    this.cache[attr + "_array"] = prop.array(source);
                else
                    throw new Error("source is required with a vectorized visual property");
            }
        }
        cache_select(attr, i) {
            const prop = this.obj.properties[this.prefix + attr];
            let value;
            if (prop.spec.value !== undefined) // TODO (bev) better test?
                this.cache[attr] = value = prop.spec.value;
            else
                this.cache[attr] = value = this.cache[attr + "_array"][i];
            return value;
        }
        set_vectorize(ctx, i) {
            if (this.all_indices != null) // all_indices is set by a Visuals instance associated with a CDSView
                this._set_vectorize(ctx, this.all_indices[i]);
            else // all_indices is not set for annotations which may have vectorized visual props
                this._set_vectorize(ctx, i);
        }
    }
    exports.ContextProperties = ContextProperties;
    ContextProperties.__name__ = "ContextProperties";
    class Line extends ContextProperties {
        set_value(ctx) {
            ctx.strokeStyle = this.line_color.value();
            ctx.globalAlpha = this.line_alpha.value();
            ctx.lineWidth = this.line_width.value();
            ctx.lineJoin = this.line_join.value();
            ctx.lineCap = this.line_cap.value();
            ctx.setLineDash(this.line_dash.value());
            ctx.setLineDashOffset(this.line_dash_offset.value());
        }
        get doit() {
            return !(this.line_color.spec.value === null ||
                this.line_alpha.spec.value == 0 ||
                this.line_width.spec.value == 0);
        }
        _set_vectorize(ctx, i) {
            this.cache_select("line_color", i);
            if (ctx.strokeStyle !== this.cache.line_color)
                ctx.strokeStyle = this.cache.line_color;
            this.cache_select("line_alpha", i);
            if (ctx.globalAlpha !== this.cache.line_alpha)
                ctx.globalAlpha = this.cache.line_alpha;
            this.cache_select("line_width", i);
            if (ctx.lineWidth !== this.cache.line_width)
                ctx.lineWidth = this.cache.line_width;
            this.cache_select("line_join", i);
            if (ctx.lineJoin !== this.cache.line_join)
                ctx.lineJoin = this.cache.line_join;
            this.cache_select("line_cap", i);
            if (ctx.lineCap !== this.cache.line_cap)
                ctx.lineCap = this.cache.line_cap;
            this.cache_select("line_dash", i);
            if (ctx.getLineDash() !== this.cache.line_dash)
                ctx.setLineDash(this.cache.line_dash);
            this.cache_select("line_dash_offset", i);
            if (ctx.getLineDashOffset() !== this.cache.line_dash_offset)
                ctx.setLineDashOffset(this.cache.line_dash_offset);
        }
        color_value() {
            const [r, g, b, a] = color_1.color2rgba(this.line_color.value(), this.line_alpha.value());
            return `rgba(${r * 255},${g * 255},${b * 255},${a})`;
        }
    }
    exports.Line = Line;
    Line.__name__ = "Line";
    Line.prototype.attrs = Object.keys(mixins.line());
    class Fill extends ContextProperties {
        set_value(ctx) {
            ctx.fillStyle = this.fill_color.value();
            ctx.globalAlpha = this.fill_alpha.value();
        }
        get doit() {
            return !(this.fill_color.spec.value === null ||
                this.fill_alpha.spec.value == 0);
        }
        _set_vectorize(ctx, i) {
            this.cache_select("fill_color", i);
            if (ctx.fillStyle !== this.cache.fill_color)
                ctx.fillStyle = this.cache.fill_color;
            this.cache_select("fill_alpha", i);
            if (ctx.globalAlpha !== this.cache.fill_alpha)
                ctx.globalAlpha = this.cache.fill_alpha;
        }
        color_value() {
            const [r, g, b, a] = color_1.color2rgba(this.fill_color.value(), this.fill_alpha.value());
            return `rgba(${r * 255},${g * 255},${b * 255},${a})`;
        }
    }
    exports.Fill = Fill;
    Fill.__name__ = "Fill";
    Fill.prototype.attrs = Object.keys(mixins.fill());
    class Hatch extends ContextProperties {
        cache_select(name, i) {
            let value;
            if (name == "pattern") {
                this.cache_select("hatch_color", i);
                this.cache_select("hatch_scale", i);
                this.cache_select("hatch_pattern", i);
                this.cache_select("hatch_weight", i);
                const { hatch_color, hatch_scale, hatch_pattern, hatch_weight, hatch_extra } = this.cache;
                if (hatch_extra != null && hatch_extra.hasOwnProperty(hatch_pattern)) {
                    const custom = hatch_extra[hatch_pattern];
                    this.cache.pattern = custom.get_pattern(hatch_color, hatch_scale, hatch_weight);
                }
                else {
                    this.cache.pattern = (ctx) => {
                        const canvas = create_hatch_canvas(hatch_pattern, hatch_color, hatch_scale, hatch_weight);
                        return ctx.createPattern(canvas, 'repeat');
                    };
                }
            }
            else
                value = super.cache_select(name, i);
            return value;
        }
        _try_defer(defer_func) {
            const { hatch_pattern, hatch_extra } = this.cache;
            if (hatch_extra != null && hatch_extra.hasOwnProperty(hatch_pattern)) {
                const custom = hatch_extra[hatch_pattern];
                custom.onload(defer_func);
            }
        }
        get doit() {
            return !(this.hatch_color.spec.value === null ||
                this.hatch_alpha.spec.value == 0 ||
                this.hatch_pattern.spec.value == " " ||
                this.hatch_pattern.spec.value == "blank" ||
                this.hatch_pattern.spec.value === null);
        }
        doit2(ctx, i, ready_func, defer_func) {
            if (!this.doit) {
                return;
            }
            this.cache_select("pattern", i);
            const pattern = this.cache.pattern(ctx);
            if (pattern == null) {
                this._try_defer(defer_func);
            }
            else {
                this.set_vectorize(ctx, i);
                ready_func();
            }
        }
        _set_vectorize(ctx, i) {
            this.cache_select("pattern", i);
            ctx.fillStyle = this.cache.pattern(ctx);
            this.cache_select("hatch_alpha", i);
            if (ctx.globalAlpha !== this.cache.hatch_alpha)
                ctx.globalAlpha = this.cache.hatch_alpha;
        }
        color_value() {
            const [r, g, b, a] = color_1.color2rgba(this.hatch_color.value(), this.hatch_alpha.value());
            return `rgba(${r * 255},${g * 255},${b * 255},${a})`;
        }
    }
    exports.Hatch = Hatch;
    Hatch.__name__ = "Hatch";
    Hatch.prototype.attrs = Object.keys(mixins.hatch());
    class Text extends ContextProperties {
        cache_select(name, i) {
            let value;
            if (name == "font") {
                super.cache_select("text_font_style", i);
                super.cache_select("text_font_size", i);
                super.cache_select("text_font", i);
                const { text_font_style, text_font_size, text_font } = this.cache;
                this.cache.font = value = `${text_font_style} ${text_font_size} ${text_font}`;
            }
            else
                value = super.cache_select(name, i);
            return value;
        }
        font_value() {
            const font = this.text_font.value();
            const font_size = this.text_font_size.value();
            const font_style = this.text_font_style.value();
            return font_style + " " + font_size + " " + font;
        }
        color_value() {
            const [r, g, b, a] = color_1.color2rgba(this.text_color.value(), this.text_alpha.value());
            return `rgba(${r * 255},${g * 255},${b * 255},${a})`;
        }
        set_value(ctx) {
            ctx.font = this.font_value();
            ctx.fillStyle = this.text_color.value();
            ctx.globalAlpha = this.text_alpha.value();
            ctx.textAlign = this.text_align.value();
            ctx.textBaseline = this.text_baseline.value();
        }
        get doit() {
            return !(this.text_color.spec.value === null ||
                this.text_alpha.spec.value == 0);
        }
        _set_vectorize(ctx, i) {
            this.cache_select("font", i);
            if (ctx.font !== this.cache.font)
                ctx.font = this.cache.font;
            this.cache_select("text_color", i);
            if (ctx.fillStyle !== this.cache.text_color)
                ctx.fillStyle = this.cache.text_color;
            this.cache_select("text_alpha", i);
            if (ctx.globalAlpha !== this.cache.text_alpha)
                ctx.globalAlpha = this.cache.text_alpha;
            this.cache_select("text_align", i);
            if (ctx.textAlign !== this.cache.text_align)
                ctx.textAlign = this.cache.text_align;
            this.cache_select("text_baseline", i);
            if (ctx.textBaseline !== this.cache.text_baseline)
                ctx.textBaseline = this.cache.text_baseline;
        }
    }
    exports.Text = Text;
    Text.__name__ = "Text";
    Text.prototype.attrs = Object.keys(mixins.text());
    class Visuals {
        constructor(model) {
            for (const mixin of model.mixins) {
                const [name, prefix = ""] = mixin.split(":");
                let cls;
                switch (name) {
                    case "line":
                        cls = Line;
                        break;
                    case "fill":
                        cls = Fill;
                        break;
                    case "hatch":
                        cls = Hatch;
                        break;
                    case "text":
                        cls = Text;
                        break;
                    default:
                        throw new Error(`unknown visual: ${name}`);
                }
                this[prefix + name] = new cls(model, prefix);
            }
        }
        warm_cache(source) {
            for (const name in this) {
                if (this.hasOwnProperty(name)) {
                    const prop = this[name];
                    if (prop instanceof ContextProperties)
                        prop.warm_cache(source);
                }
            }
        }
        set_all_indices(all_indices) {
            for (const name in this) {
                if (this.hasOwnProperty(name)) {
                    const prop = this[name];
                    if (prop instanceof ContextProperties)
                        prop.all_indices = all_indices;
                }
            }
        }
    }
    exports.Visuals = Visuals;
    Visuals.__name__ = "Visuals";
},
/* model.js */ function _(require, module, exports) {
    const has_props_1 = require(12) /* ./core/has_props */;
    const p = require(18) /* ./core/properties */;
    const types_1 = require(7) /* ./core/util/types */;
    const object_1 = require(22) /* ./core/util/object */;
    const logging_1 = require(65) /* ./core/logging */;
    class Model extends has_props_1.HasProps {
        constructor(attrs) {
            super(attrs);
        }
        static init_Model() {
            this.define({
                tags: [p.Array, []],
                name: [p.String],
                js_property_callbacks: [p.Any, {}],
                js_event_callbacks: [p.Any, {}],
                subscribed_events: [p.Array, []],
            });
        }
        connect_signals() {
            super.connect_signals();
            this._update_property_callbacks();
            this.connect(this.properties.js_property_callbacks.change, () => this._update_property_callbacks());
            this.connect(this.properties.js_event_callbacks.change, () => this._update_event_callbacks());
            this.connect(this.properties.subscribed_events.change, () => this._update_event_callbacks());
        }
        /*protected*/ _process_event(event) {
            for (const callback of this.js_event_callbacks[event.event_name] || [])
                callback.execute(event);
            if (this.document != null && this.subscribed_events.some((m) => m == event.event_name))
                this.document.event_manager.send_event(event);
        }
        trigger_event(event) {
            if (this.document != null) {
                event.origin = this;
                this.document.event_manager.trigger(event);
            }
        }
        _update_event_callbacks() {
            if (this.document == null) {
                // File an issue: SidePanel in particular seems to have this issue
                logging_1.logger.warn('WARNING: Document not defined for updating event callbacks');
                return;
            }
            this.document.event_manager.subscribed_models.add(this.id);
        }
        _update_property_callbacks() {
            const signal_for = (event) => {
                const [evt, attr = null] = event.split(":");
                return attr != null ? this.properties[attr][evt] : this[evt];
            };
            for (const event in this._js_callbacks) {
                const callbacks = this._js_callbacks[event];
                const signal = signal_for(event);
                for (const cb of callbacks)
                    this.disconnect(signal, cb);
            }
            this._js_callbacks = {};
            for (const event in this.js_property_callbacks) {
                const callbacks = this.js_property_callbacks[event];
                const wrappers = callbacks.map((cb) => () => cb.execute(this));
                this._js_callbacks[event] = wrappers;
                const signal = signal_for(event);
                for (const cb of wrappers)
                    this.connect(signal, cb);
            }
        }
        _doc_attached() {
            if (!object_1.isEmpty(this.js_event_callbacks) || !object_1.isEmpty(this.subscribed_events))
                this._update_event_callbacks();
        }
        select(selector) {
            if (types_1.isString(selector))
                return this.references().filter((ref) => ref instanceof Model && ref.name === selector);
            else if (selector.prototype instanceof has_props_1.HasProps)
                return this.references().filter((ref) => ref instanceof selector);
            else
                throw new Error("invalid selector");
        }
        select_one(selector) {
            const result = this.select(selector);
            switch (result.length) {
                case 0:
                    return null;
                case 1:
                    return result[0];
                default:
                    throw new Error("found more than one object matching given selector");
            }
        }
    }
    exports.Model = Model;
    Model.__name__ = "Model";
    Model.init_Model();
},
/* core/logging.js */ function _(require, module, exports) {
    const types_1 = require(7) /* ./util/types */;
    const _loggers = {};
    class LogLevel {
        constructor(name, level) {
            this.name = name;
            this.level = level;
        }
    }
    exports.LogLevel = LogLevel;
    LogLevel.__name__ = "LogLevel";
    class Logger {
        constructor(name, level = Logger.INFO) {
            this._name = name;
            this.set_level(level);
        }
        static get levels() {
            return Object.keys(Logger.log_levels);
        }
        static get(name, level = Logger.INFO) {
            if (name.length > 0) {
                let logger = _loggers[name];
                if (logger == null)
                    _loggers[name] = logger = new Logger(name, level);
                return logger;
            }
            else
                throw new TypeError("Logger.get() expects a non-empty string name and an optional log-level");
        }
        get level() {
            return this.get_level();
        }
        get_level() {
            return this._log_level;
        }
        set_level(log_level) {
            if (log_level instanceof LogLevel)
                this._log_level = log_level;
            else if (types_1.isString(log_level) && Logger.log_levels[log_level] != null)
                this._log_level = Logger.log_levels[log_level];
            else
                throw new Error("Logger.set_level() expects a log-level object or a string name of a log-level");
            const logger_name = `[${this._name}]`;
            for (const name in Logger.log_levels) {
                const log_level = Logger.log_levels[name];
                if (log_level.level < this._log_level.level || this._log_level.level === Logger.OFF.level)
                    this[name] = function () { };
                else
                    this[name] = _method_factory(name, logger_name);
            }
        }
        trace(..._args) { }
        debug(..._args) { }
        info(..._args) { }
        warn(..._args) { }
        error(..._args) { }
    }
    exports.Logger = Logger;
    Logger.__name__ = "Logger";
    Logger.TRACE = new LogLevel("trace", 0);
    Logger.DEBUG = new LogLevel("debug", 1);
    Logger.INFO = new LogLevel("info", 2);
    Logger.WARN = new LogLevel("warn", 6);
    Logger.ERROR = new LogLevel("error", 7);
    Logger.FATAL = new LogLevel("fatal", 8);
    Logger.OFF = new LogLevel("off", 9);
    Logger.log_levels = {
        trace: Logger.TRACE,
        debug: Logger.DEBUG,
        info: Logger.INFO,
        warn: Logger.WARN,
        error: Logger.ERROR,
        fatal: Logger.FATAL,
        off: Logger.OFF,
    };
    function _method_factory(method_name, logger_name) {
        if (console[method_name] != null)
            return console[method_name].bind(console, logger_name);
        else if (console.log != null)
            return console.log.bind(console, logger_name);
        else
            return function () { };
    }
    exports.logger = Logger.get("bokeh");
    function set_log_level(level) {
        if (Logger.log_levels[level] == null) {
            console.log(`[bokeh] unrecognized logging level '${level}' passed to Bokeh.set_log_level(), ignoring`);
            console.log(`[bokeh] valid log levels are: ${Logger.levels.join(', ')}`);
        }
        else {
            console.log(`[bokeh] setting log level to: '${level}'`);
            exports.logger.set_level(level);
        }
    }
    exports.set_log_level = set_log_level;
},
/* models/annotations/arrow.js */ function _(require, module, exports) {
    const annotation_1 = require(29) /* ./annotation */;
    const arrow_head_1 = require(67) /* ./arrow_head */;
    const column_data_source_1 = require(68) /* ../sources/column_data_source */;
    const p = require(18) /* ../../core/properties */;
    const math_1 = require(9) /* ../../core/util/math */;
    class ArrowView extends annotation_1.AnnotationView {
        initialize() {
            super.initialize();
            if (this.model.source == null)
                this.model.source = new column_data_source_1.ColumnDataSource();
            this.set_data(this.model.source);
        }
        connect_signals() {
            super.connect_signals();
            this.connect(this.model.change, () => this.set_data(this.model.source));
            this.connect(this.model.source.streaming, () => this.set_data(this.model.source));
            this.connect(this.model.source.patching, () => this.set_data(this.model.source));
        }
        set_data(source) {
            super.set_data(source);
            this.visuals.warm_cache(source);
            this.plot_view.request_render();
        }
        _map_data() {
            const { frame } = this.plot_view;
            let sx_start, sy_start;
            if (this.model.start_units == 'data') {
                sx_start = frame.xscales[this.model.x_range_name].v_compute(this._x_start);
                sy_start = frame.yscales[this.model.y_range_name].v_compute(this._y_start);
            }
            else {
                sx_start = frame.xview.v_compute(this._x_start);
                sy_start = frame.yview.v_compute(this._y_start);
            }
            let sx_end, sy_end;
            if (this.model.end_units == 'data') {
                sx_end = frame.xscales[this.model.x_range_name].v_compute(this._x_end);
                sy_end = frame.yscales[this.model.y_range_name].v_compute(this._y_end);
            }
            else {
                sx_end = frame.xview.v_compute(this._x_end);
                sy_end = frame.yview.v_compute(this._y_end);
            }
            return [[sx_start, sy_start], [sx_end, sy_end]];
        }
        render() {
            if (!this.model.visible)
                return;
            const { ctx } = this.plot_view.canvas_view;
            ctx.save();
            // Order in this function is important. First we draw all the arrow heads.
            const [start, end] = this._map_data();
            if (this.model.end != null)
                this._arrow_head(ctx, "render", this.model.end, start, end);
            if (this.model.start != null)
                this._arrow_head(ctx, "render", this.model.start, end, start);
            // Next we call .clip on all the arrow heads, inside an initial canvas sized
            // rect, to create an "inverted" clip region for the arrow heads
            ctx.beginPath();
            const { x, y, width, height } = this.plot_view.layout.bbox;
            ctx.rect(x, y, width, height);
            if (this.model.end != null)
                this._arrow_head(ctx, "clip", this.model.end, start, end);
            if (this.model.start != null)
                this._arrow_head(ctx, "clip", this.model.start, end, start);
            ctx.closePath();
            ctx.clip();
            // Finally we draw the arrow body, with the clipping regions set up. This prevents
            // "fat" arrows from overlapping the arrow head in a bad way.
            this._arrow_body(ctx, start, end);
            ctx.restore();
        }
        _arrow_head(ctx, action, head, start, end) {
            for (let i = 0, _end = this._x_start.length; i < _end; i++) {
                // arrow head runs orthogonal to arrow body
                const angle = Math.PI / 2 + math_1.atan2([start[0][i], start[1][i]], [end[0][i], end[1][i]]);
                ctx.save();
                ctx.translate(end[0][i], end[1][i]);
                ctx.rotate(angle);
                if (action == "render")
                    head.render(ctx, i);
                else if (action == "clip")
                    head.clip(ctx, i);
                ctx.restore();
            }
        }
        _arrow_body(ctx, start, end) {
            if (!this.visuals.line.doit)
                return;
            for (let i = 0, n = this._x_start.length; i < n; i++) {
                this.visuals.line.set_vectorize(ctx, i);
                ctx.beginPath();
                ctx.moveTo(start[0][i], start[1][i]);
                ctx.lineTo(end[0][i], end[1][i]);
                ctx.stroke();
            }
        }
    }
    exports.ArrowView = ArrowView;
    ArrowView.__name__ = "ArrowView";
    class Arrow extends annotation_1.Annotation {
        constructor(attrs) {
            super(attrs);
        }
        static init_Arrow() {
            this.prototype.default_view = ArrowView;
            this.mixins(['line']);
            this.define({
                x_start: [p.NumberSpec],
                y_start: [p.NumberSpec],
                start_units: [p.SpatialUnits, 'data'],
                start: [p.Instance, null],
                x_end: [p.NumberSpec],
                y_end: [p.NumberSpec],
                end_units: [p.SpatialUnits, 'data'],
                end: [p.Instance, () => new arrow_head_1.OpenHead({})],
                source: [p.Instance],
                x_range_name: [p.String, 'default'],
                y_range_name: [p.String, 'default'],
            });
        }
    }
    exports.Arrow = Arrow;
    Arrow.__name__ = "Arrow";
    Arrow.init_Arrow();
},
/* models/annotations/arrow_head.js */ function _(require, module, exports) {
    const annotation_1 = require(29) /* ./annotation */;
    const visuals_1 = require(63) /* ../../core/visuals */;
    const p = require(18) /* ../../core/properties */;
    class ArrowHead extends annotation_1.Annotation {
        constructor(attrs) {
            super(attrs);
        }
        static init_ArrowHead() {
            this.define({
                size: [p.Number, 25],
            });
        }
        initialize() {
            super.initialize();
            this.visuals = new visuals_1.Visuals(this);
        }
    }
    exports.ArrowHead = ArrowHead;
    ArrowHead.__name__ = "ArrowHead";
    ArrowHead.init_ArrowHead();
    class OpenHead extends ArrowHead {
        constructor(attrs) {
            super(attrs);
        }
        static init_OpenHead() {
            this.mixins(['line']);
        }
        clip(ctx, i) {
            // This method should not begin or close a path
            this.visuals.line.set_vectorize(ctx, i);
            ctx.moveTo(0.5 * this.size, this.size);
            ctx.lineTo(0.5 * this.size, -2);
            ctx.lineTo(-0.5 * this.size, -2);
            ctx.lineTo(-0.5 * this.size, this.size);
            ctx.lineTo(0, 0);
            ctx.lineTo(0.5 * this.size, this.size);
        }
        render(ctx, i) {
            if (this.visuals.line.doit) {
                this.visuals.line.set_vectorize(ctx, i);
                ctx.beginPath();
                ctx.moveTo(0.5 * this.size, this.size);
                ctx.lineTo(0, 0);
                ctx.lineTo(-0.5 * this.size, this.size);
                ctx.stroke();
            }
        }
    }
    exports.OpenHead = OpenHead;
    OpenHead.__name__ = "OpenHead";
    OpenHead.init_OpenHead();
    class NormalHead extends ArrowHead {
        constructor(attrs) {
            super(attrs);
        }
        static init_NormalHead() {
            this.mixins(['line', 'fill']);
            this.override({
                fill_color: 'black',
            });
        }
        clip(ctx, i) {
            // This method should not begin or close a path
            this.visuals.line.set_vectorize(ctx, i);
            ctx.moveTo(0.5 * this.size, this.size);
            ctx.lineTo(0.5 * this.size, -2);
            ctx.lineTo(-0.5 * this.size, -2);
            ctx.lineTo(-0.5 * this.size, this.size);
            ctx.lineTo(0.5 * this.size, this.size);
        }
        render(ctx, i) {
            if (this.visuals.fill.doit) {
                this.visuals.fill.set_vectorize(ctx, i);
                this._normal(ctx, i);
                ctx.fill();
            }
            if (this.visuals.line.doit) {
                this.visuals.line.set_vectorize(ctx, i);
                this._normal(ctx, i);
                ctx.stroke();
            }
        }
        _normal(ctx, _i) {
            ctx.beginPath();
            ctx.moveTo(0.5 * this.size, this.size);
            ctx.lineTo(0, 0);
            ctx.lineTo(-0.5 * this.size, this.size);
            ctx.closePath();
        }
    }
    exports.NormalHead = NormalHead;
    NormalHead.__name__ = "NormalHead";
    NormalHead.init_NormalHead();
    class VeeHead extends ArrowHead {
        constructor(attrs) {
            super(attrs);
        }
        static init_VeeHead() {
            this.mixins(['line', 'fill']);
            this.override({
                fill_color: 'black',
            });
        }
        clip(ctx, i) {
            // This method should not begin or close a path
            this.visuals.line.set_vectorize(ctx, i);
            ctx.moveTo(0.5 * this.size, this.size);
            ctx.lineTo(0.5 * this.size, -2);
            ctx.lineTo(-0.5 * this.size, -2);
            ctx.lineTo(-0.5 * this.size, this.size);
            ctx.lineTo(0, 0.5 * this.size);
            ctx.lineTo(0.5 * this.size, this.size);
        }
        render(ctx, i) {
            if (this.visuals.fill.doit) {
                this.visuals.fill.set_vectorize(ctx, i);
                this._vee(ctx, i);
                ctx.fill();
            }
            if (this.visuals.line.doit) {
                this.visuals.line.set_vectorize(ctx, i);
                this._vee(ctx, i);
                ctx.stroke();
            }
        }
        _vee(ctx, _i) {
            ctx.beginPath();
            ctx.moveTo(0.5 * this.size, this.size);
            ctx.lineTo(0, 0);
            ctx.lineTo(-0.5 * this.size, this.size);
            ctx.lineTo(0, 0.5 * this.size);
            ctx.closePath();
        }
    }
    exports.VeeHead = VeeHead;
    VeeHead.__name__ = "VeeHead";
    VeeHead.init_VeeHead();
    class TeeHead extends ArrowHead {
        constructor(attrs) {
            super(attrs);
        }
        static init_TeeHead() {
            this.mixins(['line']);
        }
        render(ctx, i) {
            if (this.visuals.line.doit) {
                this.visuals.line.set_vectorize(ctx, i);
                ctx.beginPath();
                ctx.moveTo(0.5 * this.size, 0);
                ctx.lineTo(-0.5 * this.size, 0);
                ctx.stroke();
            }
        }
        clip(_ctx, _i) { }
    }
    exports.TeeHead = TeeHead;
    TeeHead.__name__ = "TeeHead";
    TeeHead.init_TeeHead();
},
/* models/sources/column_data_source.js */ function _(require, module, exports) {
    const columnar_data_source_1 = require(69) /* ./columnar_data_source */;
    const has_props_1 = require(12) /* ../../core/has_props */;
    const p = require(18) /* ../../core/properties */;
    const data_structures_1 = require(14) /* ../../core/util/data_structures */;
    const serialization_1 = require(94) /* ../../core/util/serialization */;
    const types_1 = require(7) /* ../../core/util/types */;
    const typed_array = require(96) /* ../../core/util/typed_array */;
    const object_1 = require(22) /* ../../core/util/object */;
    const events_1 = require(97) /* ../../document/events */;
    //exported for testing
    function stream_to_column(col, new_col, rollover) {
        if (types_1.isArray(col)) {
            const result = col.concat(new_col);
            if (rollover != null && result.length > rollover)
                return result.slice(-rollover);
            else
                return result;
        }
        else if (types_1.isTypedArray(col)) {
            const total_len = col.length + new_col.length;
            // handle rollover case for typed arrays
            if (rollover != null && total_len > rollover) {
                const start = total_len - rollover;
                const end = col.length;
                // resize col if it is shorter than the rollover length
                let result;
                if (col.length < rollover) {
                    result = new col.constructor(rollover);
                    result.set(col, 0);
                }
                else
                    result = col;
                // shift values in original col to accommodate new_col
                for (let i = start, endi = end; i < endi; i++) {
                    result[i - start] = result[i];
                }
                // update end values in col with new_col
                for (let i = 0, endi = new_col.length; i < endi; i++) {
                    result[i + (end - start)] = new_col[i];
                }
                return result;
            }
            else {
                const tmp = new col.constructor(new_col);
                return typed_array.concat(col, tmp);
            }
        }
        else
            throw new Error("unsupported array types");
    }
    exports.stream_to_column = stream_to_column;
    // exported for testing
    function slice(ind, length) {
        let start, step, stop;
        if (types_1.isNumber(ind)) {
            start = ind;
            stop = ind + 1;
            step = 1;
        }
        else {
            start = ind.start != null ? ind.start : 0;
            stop = ind.stop != null ? ind.stop : length;
            step = ind.step != null ? ind.step : 1;
        }
        return [start, stop, step];
    }
    exports.slice = slice;
    // exported for testing
    function patch_to_column(col, patch, shapes) {
        const patched = new data_structures_1.Set();
        let patched_range = false;
        for (const [ind, val] of patch) {
            // make the single index case look like the length-3 multi-index case
            let item, shape;
            let index;
            let value;
            if (types_1.isArray(ind)) {
                const [i] = ind;
                patched.add(i);
                shape = shapes[i];
                item = col[i];
                value = val;
                // this is basically like NumPy's "newaxis", inserting an empty dimension
                // makes length 2 and 3 multi-index cases uniform, so that the same code
                // can handle both
                if (ind.length === 2) {
                    shape = [1, shape[0]];
                    index = [ind[0], 0, ind[1]];
                }
                else
                    index = ind;
            }
            else {
                if (types_1.isNumber(ind)) {
                    value = [val];
                    patched.add(ind);
                }
                else {
                    value = val;
                    patched_range = true;
                }
                index = [0, 0, ind];
                shape = [1, col.length];
                item = col;
            }
            // now this one nested loop handles all cases
            let flat_index = 0;
            const [istart, istop, istep] = slice(index[1], shape[0]);
            const [jstart, jstop, jstep] = slice(index[2], shape[1]);
            for (let i = istart; i < istop; i += istep) {
                for (let j = jstart; j < jstop; j += jstep) {
                    if (patched_range) {
                        patched.add(j);
                    }
                    item[(i * shape[1]) + j] = value[flat_index];
                    flat_index++;
                }
            }
        }
        return patched;
    }
    exports.patch_to_column = patch_to_column;
    class ColumnDataSource extends columnar_data_source_1.ColumnarDataSource {
        constructor(attrs) {
            super(attrs);
        }
        static init_ColumnDataSource() {
            this.define({
                data: [p.Any, {}],
            });
        }
        initialize() {
            super.initialize();
            [this.data, this._shapes] = serialization_1.decode_column_data(this.data);
        }
        attributes_as_json(include_defaults = true, value_to_json = ColumnDataSource._value_to_json) {
            const attrs = {};
            const obj = this.serializable_attributes();
            for (const key of object_1.keys(obj)) {
                let value = obj[key];
                if (key === 'data')
                    value = serialization_1.encode_column_data(value, this._shapes);
                if (include_defaults)
                    attrs[key] = value;
                else if (key in this._set_after_defaults)
                    attrs[key] = value;
            }
            return value_to_json("attributes", attrs, this);
        }
        static _value_to_json(key, value, optional_parent_object) {
            if (types_1.isPlainObject(value) && key === 'data')
                return serialization_1.encode_column_data(value, optional_parent_object._shapes); // XXX: unknown vs. any
            else
                return has_props_1.HasProps._value_to_json(key, value, optional_parent_object);
        }
        stream(new_data, rollover, setter_id) {
            const { data } = this;
            for (const k in new_data) {
                data[k] = stream_to_column(data[k], new_data[k], rollover);
            }
            this.setv({ data }, { silent: true });
            this.streaming.emit();
            if (this.document != null) {
                const hint = new events_1.ColumnsStreamedEvent(this.document, this.ref(), new_data, rollover);
                this.document._notify_change(this, 'data', null, null, { setter_id, hint });
            }
        }
        patch(patches, setter_id) {
            const { data } = this;
            let patched = new data_structures_1.Set();
            for (const k in patches) {
                const patch = patches[k];
                patched = patched.union(patch_to_column(data[k], patch, this._shapes[k]));
            }
            this.setv({ data }, { silent: true });
            this.patching.emit(patched.values);
            if (this.document != null) {
                const hint = new events_1.ColumnsPatchedEvent(this.document, this.ref(), patches);
                this.document._notify_change(this, 'data', null, null, { setter_id, hint });
            }
        }
    }
    exports.ColumnDataSource = ColumnDataSource;
    ColumnDataSource.__name__ = "ColumnDataSource";
    ColumnDataSource.init_ColumnDataSource();
},
/* models/sources/columnar_data_source.js */ function _(require, module, exports) {
    const data_source_1 = require(70) /* ./data_source */;
    const signaling_1 = require(13) /* ../../core/signaling */;
    const logging_1 = require(65) /* ../../core/logging */;
    const selection_manager_1 = require(72) /* ../../core/selection_manager */;
    const p = require(18) /* ../../core/properties */;
    const types_1 = require(7) /* ../../core/util/types */;
    const array_1 = require(8) /* ../../core/util/array */;
    const object_1 = require(22) /* ../../core/util/object */;
    const selection_1 = require(71) /* ../selections/selection */;
    const interaction_policy_1 = require(93) /* ../selections/interaction_policy */;
    class ColumnarDataSource extends data_source_1.DataSource {
        constructor(attrs) {
            super(attrs);
        }
        get_array(key) {
            let column = this.data[key];
            if (column == null)
                this.data[key] = column = [];
            else if (!types_1.isArray(column))
                this.data[key] = column = Array.from(column);
            return column;
        }
        static init_ColumnarDataSource() {
            this.define({
                selection_policy: [p.Instance, () => new interaction_policy_1.UnionRenderers()],
            });
            this.internal({
                selection_manager: [p.Instance, (self) => new selection_manager_1.SelectionManager({ source: self })],
                inspected: [p.Instance, () => new selection_1.Selection()],
                _shapes: [p.Any, {}],
            });
        }
        initialize() {
            super.initialize();
            this._select = new signaling_1.Signal0(this, "select");
            this.inspect = new signaling_1.Signal(this, "inspect"); // XXX: <[indices, tool, renderer-view, source, data], this>
            this.streaming = new signaling_1.Signal0(this, "streaming");
            this.patching = new signaling_1.Signal(this, "patching");
        }
        get_column(colname) {
            const column = this.data[colname];
            return column != null ? column : null;
        }
        columns() {
            // return the column names in this data source
            return object_1.keys(this.data);
        }
        get_length(soft = true) {
            const lengths = array_1.uniq(object_1.values(this.data).map((v) => v.length));
            switch (lengths.length) {
                case 0: {
                    return null; // XXX: don't guess, treat on case-by-case basis
                }
                case 1: {
                    return lengths[0];
                }
                default: {
                    const msg = "data source has columns of inconsistent lengths";
                    if (soft) {
                        logging_1.logger.warn(msg);
                        return lengths.sort()[0];
                    }
                    else
                        throw new Error(msg);
                }
            }
        }
        get_indices() {
            const length = this.get_length();
            return array_1.range(0, length != null ? length : 1);
            //TODO: returns [0] when no data, should it?
        }
        clear() {
            const empty = {};
            for (const col of this.columns()) {
                empty[col] = new this.data[col].constructor(0);
            }
            this.data = empty;
        }
    }
    exports.ColumnarDataSource = ColumnarDataSource;
    ColumnarDataSource.__name__ = "ColumnarDataSource";
    ColumnarDataSource.init_ColumnarDataSource();
},
/* models/sources/data_source.js */ function _(require, module, exports) {
    const model_1 = require(64) /* ../../model */;
    const selection_1 = require(71) /* ../selections/selection */;
    const p = require(18) /* ../../core/properties */;
    class DataSource extends model_1.Model {
        constructor(attrs) {
            super(attrs);
        }
        static init_DataSource() {
            this.define({
                selected: [p.Instance, () => new selection_1.Selection()],
                callback: [p.Any],
            });
        }
        connect_signals() {
            super.connect_signals();
            this.connect(this.selected.change, () => {
                if (this.callback != null)
                    this.callback.execute(this);
            });
        }
    }
    exports.DataSource = DataSource;
    DataSource.__name__ = "DataSource";
    DataSource.init_DataSource();
},
/* models/selections/selection.js */ function _(require, module, exports) {
    const model_1 = require(64) /* ../../model */;
    const p = require(18) /* ../../core/properties */;
    const array_1 = require(8) /* ../../core/util/array */;
    const object_1 = require(22) /* ../../core/util/object */;
    class Selection extends model_1.Model {
        constructor(attrs) {
            super(attrs);
        }
        static init_Selection() {
            this.define({
                indices: [p.Array, []],
                line_indices: [p.Array, []],
                multiline_indices: [p.Any, {}],
            });
            this.internal({
                final: [p.Boolean],
                selected_glyphs: [p.Array, []],
                get_view: [p.Any],
                image_indices: [p.Array, []],
            });
        }
        initialize() {
            super.initialize();
            this['0d'] = { glyph: null, indices: [], flag: false, get_view: () => null };
            this['1d'] = { indices: this.indices };
            this['2d'] = { indices: {} };
            this.get_view = () => null;
            this.connect(this.properties.indices.change, () => this['1d'].indices = this.indices);
            this.connect(this.properties.line_indices.change, () => {
                this['0d'].indices = this.line_indices;
                this['0d'].flag = this.line_indices.length != 0;
            });
            this.connect(this.properties.selected_glyphs.change, () => this['0d'].glyph = this.selected_glyph);
            this.connect(this.properties.get_view.change, () => this['0d'].get_view = this.get_view);
            this.connect(this.properties.multiline_indices.change, () => this['2d'].indices = this.multiline_indices);
        }
        get selected_glyph() {
            return this.selected_glyphs.length > 0 ? this.selected_glyphs[0] : null;
        }
        add_to_selected_glyphs(glyph) {
            this.selected_glyphs.push(glyph);
        }
        update(selection, final, append) {
            this.final = final;
            if (append)
                this.update_through_union(selection);
            else {
                this.indices = selection.indices;
                this.line_indices = selection.line_indices;
                this.selected_glyphs = selection.selected_glyphs;
                this.get_view = selection.get_view;
                this.multiline_indices = selection.multiline_indices;
                this.image_indices = selection.image_indices;
            }
        }
        clear() {
            this.final = true;
            this.indices = [];
            this.line_indices = [];
            this.multiline_indices = {};
            this.get_view = () => null;
            this.selected_glyphs = [];
        }
        is_empty() {
            return this.indices.length == 0 && this.line_indices.length == 0 && this.image_indices.length == 0;
        }
        update_through_union(other) {
            this.indices = array_1.union(other.indices, this.indices);
            this.selected_glyphs = array_1.union(other.selected_glyphs, this.selected_glyphs);
            this.line_indices = array_1.union(other.line_indices, this.line_indices);
            if (!this.get_view())
                this.get_view = other.get_view;
            this.multiline_indices = object_1.merge(other.multiline_indices, this.multiline_indices);
        }
        update_through_intersection(other) {
            this.indices = array_1.intersection(other.indices, this.indices);
            // TODO: think through and fix any logic below
            this.selected_glyphs = array_1.union(other.selected_glyphs, this.selected_glyphs);
            this.line_indices = array_1.union(other.line_indices, this.line_indices);
            if (!this.get_view())
                this.get_view = other.get_view;
            this.multiline_indices = object_1.merge(other.multiline_indices, this.multiline_indices);
        }
    }
    exports.Selection = Selection;
    Selection.__name__ = "Selection";
    Selection.init_Selection();
},
/* core/selection_manager.js */ function _(require, module, exports) {
    const has_props_1 = require(12) /* ./has_props */;
    const selection_1 = require(71) /* ../models/selections/selection */;
    const glyph_renderer_1 = require(73) /* ../models/renderers/glyph_renderer */;
    const graph_renderer_1 = require(90) /* ../models/renderers/graph_renderer */;
    const p = require(18) /* ./properties */;
    class SelectionManager extends has_props_1.HasProps {
        constructor(attrs) {
            super(attrs);
            this.inspectors = {};
        }
        static init_SelectionManager() {
            this.internal({
                source: [p.Any],
            });
        }
        select(renderer_views, geometry, final, append = false) {
            // divide renderers into glyph_renderers or graph_renderers
            const glyph_renderer_views = [];
            const graph_renderer_views = [];
            for (const r of renderer_views) {
                if (r instanceof glyph_renderer_1.GlyphRendererView)
                    glyph_renderer_views.push(r);
                else if (r instanceof graph_renderer_1.GraphRendererView)
                    graph_renderer_views.push(r);
            }
            let did_hit = false;
            // graph renderer case
            for (const r of graph_renderer_views) {
                const hit_test_result = r.model.selection_policy.hit_test(geometry, r);
                did_hit = did_hit || r.model.selection_policy.do_selection(hit_test_result, r.model, final, append);
            }
            // glyph renderers
            if (glyph_renderer_views.length > 0) {
                const hit_test_result = this.source.selection_policy.hit_test(geometry, glyph_renderer_views);
                did_hit = did_hit || this.source.selection_policy.do_selection(hit_test_result, this.source, final, append);
            }
            return did_hit;
        }
        inspect(renderer_view, geometry) {
            let did_hit = false;
            if (renderer_view instanceof glyph_renderer_1.GlyphRendererView) {
                const hit_test_result = renderer_view.hit_test(geometry);
                if (hit_test_result != null) {
                    did_hit = !hit_test_result.is_empty();
                    const inspection = this.get_or_create_inspector(renderer_view.model);
                    inspection.update(hit_test_result, true, false);
                    this.source.setv({ inspected: inspection }, { silent: true });
                    this.source.inspect.emit([renderer_view, { geometry }]);
                }
            }
            else if (renderer_view instanceof graph_renderer_1.GraphRendererView) {
                const hit_test_result = renderer_view.model.inspection_policy.hit_test(geometry, renderer_view);
                did_hit = did_hit || renderer_view.model.inspection_policy.do_inspection(hit_test_result, geometry, renderer_view, false, false);
            }
            return did_hit;
        }
        clear(rview) {
            this.source.selected.clear();
            if (rview != null)
                this.get_or_create_inspector(rview.model).clear();
        }
        get_or_create_inspector(rmodel) {
            if (this.inspectors[rmodel.id] == null)
                this.inspectors[rmodel.id] = new selection_1.Selection();
            return this.inspectors[rmodel.id];
        }
    }
    exports.SelectionManager = SelectionManager;
    SelectionManager.__name__ = "SelectionManager";
    SelectionManager.init_SelectionManager();
},
/* models/renderers/glyph_renderer.js */ function _(require, module, exports) {
    const data_renderer_1 = require(74) /* ./data_renderer */;
    const line_1 = require(75) /* ../glyphs/line */;
    const patch_1 = require(85) /* ../glyphs/patch */;
    const harea_1 = require(86) /* ../glyphs/harea */;
    const varea_1 = require(88) /* ../glyphs/varea */;
    const cds_view_1 = require(89) /* ../sources/cds_view */;
    const logging_1 = require(65) /* ../../core/logging */;
    const p = require(18) /* ../../core/properties */;
    const arrayable_1 = require(11) /* ../../core/util/arrayable */;
    const array_1 = require(8) /* ../../core/util/array */;
    const object_1 = require(22) /* ../../core/util/object */;
    const factor_range_1 = require(82) /* ../ranges/factor_range */;
    const selection_defaults = {
        fill: {},
        line: {},
    };
    const decimated_defaults = {
        fill: { fill_alpha: 0.3, fill_color: "grey" },
        line: { line_alpha: 0.3, line_color: "grey" },
    };
    const nonselection_defaults = {
        fill: { fill_alpha: 0.2 },
        line: {},
    };
    class GlyphRendererView extends data_renderer_1.DataRendererView {
        initialize() {
            super.initialize();
            const base_glyph = this.model.glyph;
            const has_fill = array_1.includes(base_glyph.mixins, "fill");
            const has_line = array_1.includes(base_glyph.mixins, "line");
            const glyph_attrs = object_1.clone(base_glyph.attributes);
            delete glyph_attrs.id;
            function mk_glyph(defaults) {
                const attrs = object_1.clone(glyph_attrs);
                if (has_fill)
                    object_1.extend(attrs, defaults.fill);
                if (has_line)
                    object_1.extend(attrs, defaults.line);
                return new base_glyph.constructor(attrs);
            }
            this.glyph = this.build_glyph_view(base_glyph);
            let { selection_glyph } = this.model;
            if (selection_glyph == null)
                selection_glyph = mk_glyph({ fill: {}, line: {} });
            else if (selection_glyph === "auto")
                selection_glyph = mk_glyph(selection_defaults);
            this.selection_glyph = this.build_glyph_view(selection_glyph);
            let { nonselection_glyph } = this.model;
            if ((nonselection_glyph == null))
                nonselection_glyph = mk_glyph({ fill: {}, line: {} });
            else if (nonselection_glyph === "auto")
                nonselection_glyph = mk_glyph(nonselection_defaults);
            this.nonselection_glyph = this.build_glyph_view(nonselection_glyph);
            const { hover_glyph } = this.model;
            if (hover_glyph != null)
                this.hover_glyph = this.build_glyph_view(hover_glyph);
            const { muted_glyph } = this.model;
            if (muted_glyph != null)
                this.muted_glyph = this.build_glyph_view(muted_glyph);
            const decimated_glyph = mk_glyph(decimated_defaults);
            this.decimated_glyph = this.build_glyph_view(decimated_glyph);
            this.xscale = this.plot_view.frame.xscales[this.model.x_range_name];
            this.yscale = this.plot_view.frame.yscales[this.model.y_range_name];
            this.set_data(false);
        }
        build_glyph_view(model) {
            return new model.default_view({ model, parent: this }); // XXX
        }
        connect_signals() {
            super.connect_signals();
            this.connect(this.model.change, () => this.request_render());
            this.connect(this.model.glyph.change, () => this.set_data());
            this.connect(this.model.data_source.change, () => this.set_data());
            this.connect(this.model.data_source.streaming, () => this.set_data());
            this.connect(this.model.data_source.patching, (indices /* XXX: WHY? */) => this.set_data(true, indices));
            this.connect(this.model.data_source.selected.change, () => this.request_render());
            this.connect(this.model.data_source._select, () => this.request_render());
            if (this.hover_glyph != null)
                this.connect(this.model.data_source.inspect, () => this.request_render());
            this.connect(this.model.properties.view.change, () => this.set_data());
            this.connect(this.model.view.change, () => this.set_data());
            this.connect(this.model.properties.visible.change, () => this.plot_view.update_dataranges());
            const { x_ranges, y_ranges } = this.plot_view.frame;
            for (const name in x_ranges) {
                const rng = x_ranges[name];
                if (rng instanceof factor_range_1.FactorRange)
                    this.connect(rng.change, () => this.set_data());
            }
            for (const name in y_ranges) {
                const rng = y_ranges[name];
                if (rng instanceof factor_range_1.FactorRange)
                    this.connect(rng.change, () => this.set_data());
            }
            this.connect(this.model.glyph.transformchange, () => this.set_data());
        }
        have_selection_glyphs() {
            return this.selection_glyph != null && this.nonselection_glyph != null;
        }
        // in case of partial updates like patching, the list of indices that actually
        // changed may be passed as the "indices" parameter to afford any optional optimizations
        set_data(request_render = true, indices = null) {
            const t0 = Date.now();
            const source = this.model.data_source;
            this.all_indices = this.model.view.indices;
            // TODO (bev) this is a bit clunky, need to make sure glyphs use the correct ranges when they call
            // mapping functions on the base Renderer class
            this.glyph.model.setv({ x_range_name: this.model.x_range_name,
                y_range_name: this.model.y_range_name }, { silent: true });
            this.glyph.set_data(source, this.all_indices, indices);
            this.glyph.set_visuals(source);
            this.decimated_glyph.set_visuals(source);
            if (this.have_selection_glyphs()) {
                this.selection_glyph.set_visuals(source);
                this.nonselection_glyph.set_visuals(source);
            }
            if (this.hover_glyph != null)
                this.hover_glyph.set_visuals(source);
            if (this.muted_glyph != null)
                this.muted_glyph.set_visuals(source);
            const { lod_factor } = this.plot_model;
            this.decimated = [];
            for (let i = 0, end = Math.floor(this.all_indices.length / lod_factor); i < end; i++) {
                this.decimated.push(i * lod_factor);
            }
            const dt = Date.now() - t0;
            logging_1.logger.debug(`${this.glyph.model.type} GlyphRenderer (${this.model.id}): set_data finished in ${dt}ms`);
            this.set_data_timestamp = Date.now();
            if (request_render)
                this.request_render();
        }
        get has_webgl() {
            return this.glyph.glglyph != null;
        }
        render() {
            if (!this.model.visible)
                return;
            const t0 = Date.now();
            const glsupport = this.has_webgl;
            this.glyph.map_data();
            const dtmap = Date.now() - t0;
            const tmask = Date.now();
            // all_indices is in full data space, indices is converted to subset space
            // either by mask_data (that uses the spatial index) or manually
            let indices = this.glyph.mask_data(this.all_indices);
            if (indices.length === this.all_indices.length) {
                indices = array_1.range(0, this.all_indices.length);
            }
            const dtmask = Date.now() - tmask;
            const { ctx } = this.plot_view.canvas_view;
            ctx.save();
            // selected is in full set space
            const { selected } = this.model.data_source;
            let selected_full_indices;
            if (!selected || selected.is_empty())
                selected_full_indices = [];
            else {
                if (this.glyph instanceof line_1.LineView && selected.selected_glyph === this.glyph.model)
                    selected_full_indices = this.model.view.convert_indices_from_subset(indices);
                else
                    selected_full_indices = selected.indices;
            }
            // inspected is in full set space
            const { inspected } = this.model.data_source;
            const inspected_full_indices = new Set((() => {
                if (!inspected || inspected.is_empty())
                    return [];
                else {
                    if (inspected['0d'].glyph)
                        return this.model.view.convert_indices_from_subset(indices);
                    else if (inspected['1d'].indices.length > 0)
                        return inspected['1d'].indices;
                    else
                        return arrayable_1.map(Object.keys(inspected["2d"].indices), (i) => parseInt(i));
                }
            })());
            // inspected is transformed to subset space
            const inspected_subset_indices = arrayable_1.filter(indices, (i) => inspected_full_indices.has(this.all_indices[i]));
            const { lod_threshold } = this.plot_model;
            let glyph;
            let nonselection_glyph;
            let selection_glyph;
            if ((this.model.document != null ? this.model.document.interactive_duration() > 0 : false)
                && !glsupport && lod_threshold != null && this.all_indices.length > lod_threshold) {
                // Render decimated during interaction if too many elements and not using GL
                indices = this.decimated;
                glyph = this.decimated_glyph;
                nonselection_glyph = this.decimated_glyph;
                selection_glyph = this.selection_glyph;
            }
            else {
                glyph = this.model.muted && this.muted_glyph != null ? this.muted_glyph : this.glyph;
                nonselection_glyph = this.nonselection_glyph;
                selection_glyph = this.selection_glyph;
            }
            if (this.hover_glyph != null && inspected_subset_indices.length)
                indices = array_1.difference(indices, inspected_subset_indices);
            // Render with no selection
            let dtselect = null;
            let trender;
            if (!(selected_full_indices.length && this.have_selection_glyphs())) {
                trender = Date.now();
                if (this.glyph instanceof line_1.LineView) {
                    if (this.hover_glyph && inspected_subset_indices.length)
                        this.hover_glyph.render(ctx, this.model.view.convert_indices_from_subset(inspected_subset_indices), this.glyph);
                    else
                        glyph.render(ctx, this.all_indices, this.glyph);
                }
                else if (this.glyph instanceof patch_1.PatchView || this.glyph instanceof harea_1.HAreaView || this.glyph instanceof varea_1.VAreaView) {
                    if (inspected.selected_glyphs.length == 0 || this.hover_glyph == null) {
                        glyph.render(ctx, this.all_indices, this.glyph);
                    }
                    else {
                        for (const sglyph of inspected.selected_glyphs) {
                            if (sglyph.id == this.glyph.model.id)
                                this.hover_glyph.render(ctx, this.all_indices, this.glyph);
                        }
                    }
                }
                else {
                    glyph.render(ctx, indices, this.glyph);
                    if (this.hover_glyph && inspected_subset_indices.length)
                        this.hover_glyph.render(ctx, inspected_subset_indices, this.glyph);
                }
                // Render with selection
            }
            else {
                // reset the selection mask
                const tselect = Date.now();
                const selected_mask = {};
                for (const i of selected_full_indices) {
                    selected_mask[i] = true;
                }
                // intersect/different selection with render mask
                const selected_subset_indices = new Array();
                const nonselected_subset_indices = new Array();
                // now, selected is changed to subset space, except for Line glyph
                if (this.glyph instanceof line_1.LineView) {
                    for (const i of this.all_indices) {
                        if (selected_mask[i] != null)
                            selected_subset_indices.push(i);
                        else
                            nonselected_subset_indices.push(i);
                    }
                }
                else {
                    for (const i of indices) {
                        if (selected_mask[this.all_indices[i]] != null)
                            selected_subset_indices.push(i);
                        else
                            nonselected_subset_indices.push(i);
                    }
                }
                dtselect = Date.now() - tselect;
                trender = Date.now();
                nonselection_glyph.render(ctx, nonselected_subset_indices, this.glyph);
                selection_glyph.render(ctx, selected_subset_indices, this.glyph);
                if (this.hover_glyph != null) {
                    if (this.glyph instanceof line_1.LineView)
                        this.hover_glyph.render(ctx, this.model.view.convert_indices_from_subset(inspected_subset_indices), this.glyph);
                    else
                        this.hover_glyph.render(ctx, inspected_subset_indices, this.glyph);
                }
            }
            const dtrender = Date.now() - trender;
            this.last_dtrender = dtrender;
            const dttot = Date.now() - t0;
            logging_1.logger.debug(`${this.glyph.model.type} GlyphRenderer (${this.model.id}): render finished in ${dttot}ms`);
            logging_1.logger.trace(` - map_data finished in       : ${dtmap}ms`);
            logging_1.logger.trace(` - mask_data finished in      : ${dtmask}ms`);
            if (dtselect != null) {
                logging_1.logger.trace(` - selection mask finished in : ${dtselect}ms`);
            }
            logging_1.logger.trace(` - glyph renders finished in  : ${dtrender}ms`);
            ctx.restore();
        }
        draw_legend(ctx, x0, x1, y0, y1, field, label, index) {
            if (index == null)
                index = this.model.get_reference_point(field, label);
            this.glyph.draw_legend_for_index(ctx, { x0, x1, y0, y1 }, index);
        }
        hit_test(geometry) {
            if (!this.model.visible)
                return null;
            const hit_test_result = this.glyph.hit_test(geometry);
            // glyphs that don't have hit-testing implemented will return null
            if (hit_test_result == null)
                return null;
            return this.model.view.convert_selection_from_subset(hit_test_result);
        }
    }
    exports.GlyphRendererView = GlyphRendererView;
    GlyphRendererView.__name__ = "GlyphRendererView";
    class GlyphRenderer extends data_renderer_1.DataRenderer {
        constructor(attrs) {
            super(attrs);
        }
        static init_GlyphRenderer() {
            this.prototype.default_view = GlyphRendererView;
            this.define({
                data_source: [p.Instance],
                view: [p.Instance, () => new cds_view_1.CDSView()],
                glyph: [p.Instance],
                hover_glyph: [p.Instance],
                nonselection_glyph: [p.Any, 'auto'],
                selection_glyph: [p.Any, 'auto'],
                muted_glyph: [p.Instance],
                muted: [p.Boolean, false],
            });
        }
        initialize() {
            super.initialize();
            if (this.view.source == null) {
                this.view.source = this.data_source;
                this.view.compute_indices();
            }
        }
        get_reference_point(field, value) {
            let index = 0;
            if (field != null) {
                const data = this.data_source.get_column(field);
                if (data != null) {
                    const i = arrayable_1.indexOf(data, value);
                    if (i != -1)
                        index = i;
                }
            }
            return index;
        }
        get_selection_manager() {
            return this.data_source.selection_manager;
        }
    }
    exports.GlyphRenderer = GlyphRenderer;
    GlyphRenderer.__name__ = "GlyphRenderer";
    GlyphRenderer.init_GlyphRenderer();
},
/* models/renderers/data_renderer.js */ function _(require, module, exports) {
    const renderer_1 = require(58) /* ./renderer */;
    const p = require(18) /* ../../core/properties */;
    class DataRendererView extends renderer_1.RendererView {
    }
    exports.DataRendererView = DataRendererView;
    DataRendererView.__name__ = "DataRendererView";
    class DataRenderer extends renderer_1.Renderer {
        constructor(attrs) {
            super(attrs);
        }
        static init_DataRenderer() {
            this.define({
                x_range_name: [p.String, 'default'],
                y_range_name: [p.String, 'default'],
            });
            this.override({
                level: 'glyph',
            });
        }
    }
    exports.DataRenderer = DataRenderer;
    DataRenderer.__name__ = "DataRenderer";
    DataRenderer.init_DataRenderer();
},
/* models/glyphs/line.js */ function _(require, module, exports) {
    const xy_glyph_1 = require(76) /* ./xy_glyph */;
    const utils_1 = require(84) /* ./utils */;
    const hittest = require(81) /* ../../core/hittest */;
    class LineView extends xy_glyph_1.XYGlyphView {
        _render(ctx, indices, { sx, sy }) {
            let drawing = false;
            let last_index = null;
            this.visuals.line.set_value(ctx);
            for (const i of indices) {
                if (drawing) {
                    if (!isFinite(sx[i] + sy[i])) {
                        ctx.stroke();
                        ctx.beginPath();
                        drawing = false;
                        last_index = i;
                        continue;
                    }
                    if (last_index != null && i - last_index > 1) {
                        ctx.stroke();
                        drawing = false;
                    }
                }
                if (drawing)
                    ctx.lineTo(sx[i], sy[i]);
                else {
                    ctx.beginPath();
                    ctx.moveTo(sx[i], sy[i]);
                    drawing = true;
                }
                last_index = i;
            }
            if (drawing)
                ctx.stroke();
        }
        _hit_point(geometry) {
            /* Check if the point geometry hits this line glyph and return an object
            that describes the hit result:
              Args:
                * geometry (object): object with the following keys
                  * sx (float): screen x coordinate of the point
                  * sy (float): screen y coordinate of the point
                  * type (str): type of geometry (in this case it's a point)
              Output:
                Object with the following keys:
                  * 0d (bool): whether the point hits the glyph or not
                  * 1d (array(int)): array with the indices hit by the point
            */
            const result = hittest.create_empty_hit_test_result();
            const point = { x: geometry.sx, y: geometry.sy };
            let shortest = 9999;
            const threshold = Math.max(2, this.visuals.line.line_width.value() / 2);
            for (let i = 0, end = this.sx.length - 1; i < end; i++) {
                const p0 = { x: this.sx[i], y: this.sy[i] };
                const p1 = { x: this.sx[i + 1], y: this.sy[i + 1] };
                const dist = hittest.dist_to_segment(point, p0, p1);
                if (dist < threshold && dist < shortest) {
                    shortest = dist;
                    result.add_to_selected_glyphs(this.model);
                    result.get_view = () => this;
                    result.line_indices = [i];
                }
            }
            return result;
        }
        _hit_span(geometry) {
            const { sx, sy } = geometry;
            const result = hittest.create_empty_hit_test_result();
            let val;
            let values;
            if (geometry.direction == 'v') {
                val = this.renderer.yscale.invert(sy);
                values = this._y;
            }
            else {
                val = this.renderer.xscale.invert(sx);
                values = this._x;
            }
            for (let i = 0, end = values.length - 1; i < end; i++) {
                if ((values[i] <= val && val <= values[i + 1]) || (values[i + 1] <= val && val <= values[i])) {
                    result.add_to_selected_glyphs(this.model);
                    result.get_view = () => this;
                    result.line_indices.push(i);
                }
            }
            return result;
        }
        get_interpolation_hit(i, geometry) {
            const [x2, y2, x3, y3] = [this._x[i], this._y[i], this._x[i + 1], this._y[i + 1]];
            return utils_1.line_interpolation(this.renderer, geometry, x2, y2, x3, y3);
        }
        draw_legend_for_index(ctx, bbox, index) {
            utils_1.generic_line_legend(this.visuals, ctx, bbox, index);
        }
    }
    exports.LineView = LineView;
    LineView.__name__ = "LineView";
    class Line extends xy_glyph_1.XYGlyph {
        constructor(attrs) {
            super(attrs);
        }
        static init_Line() {
            this.prototype.default_view = LineView;
            this.mixins(['line']);
        }
    }
    exports.Line = Line;
    Line.__name__ = "Line";
    Line.init_Line();
},
/* models/glyphs/xy_glyph.js */ function _(require, module, exports) {
    const spatial_1 = require(77) /* ../../core/util/spatial */;
    const glyph_1 = require(80) /* ./glyph */;
    class XYGlyphView extends glyph_1.GlyphView {
        _index_data() {
            const points = [];
            for (let i = 0, end = this._x.length; i < end; i++) {
                const x = this._x[i];
                const y = this._y[i];
                if (isNaN(x + y) || !isFinite(x + y))
                    continue;
                points.push({ x0: x, y0: y, x1: x, y1: y, i });
            }
            return new spatial_1.SpatialIndex(points);
        }
        scenterx(i) {
            return this.sx[i];
        }
        scentery(i) {
            return this.sy[i];
        }
    }
    exports.XYGlyphView = XYGlyphView;
    XYGlyphView.__name__ = "XYGlyphView";
    class XYGlyph extends glyph_1.Glyph {
        constructor(attrs) {
            super(attrs);
        }
        static init_XYGlyph() {
            this.coords([['x', 'y']]);
        }
    }
    exports.XYGlyph = XYGlyph;
    XYGlyph.__name__ = "XYGlyph";
    XYGlyph.init_XYGlyph();
},
/* core/util/spatial.js */ function _(require, module, exports) {
    const FlatBush = require(78) /* flatbush */;
    const bbox_1 = require(79) /* ./bbox */;
    class SpatialIndex {
        constructor(points) {
            this.points = points;
            this.index = null;
            if (points.length > 0) {
                this.index = new FlatBush(points.length);
                for (const p of points) {
                    const { x0, y0, x1, y1 } = p;
                    this.index.add(x0, y0, x1, y1);
                }
                this.index.finish();
            }
        }
        _normalize(rect) {
            let { x0, y0, x1, y1 } = rect;
            if (x0 > x1)
                [x0, x1] = [x1, x0];
            if (y0 > y1)
                [y0, y1] = [y1, y0];
            return { x0, y0, x1, y1 };
        }
        get bbox() {
            if (this.index == null)
                return bbox_1.empty();
            else {
                const { minX, minY, maxX, maxY } = this.index;
                return { x0: minX, y0: minY, x1: maxX, y1: maxY };
            }
        }
        search(rect) {
            if (this.index == null)
                return [];
            else {
                const { x0, y0, x1, y1 } = this._normalize(rect);
                const indices = this.index.search(x0, y0, x1, y1);
                return indices.map((j) => this.points[j]);
            }
        }
        indices(rect) {
            return this.search(rect).map(({ i }) => i);
        }
    }
    exports.SpatialIndex = SpatialIndex;
    SpatialIndex.__name__ = "SpatialIndex";
},
/* flatbush/flatbush.js */ function _(require, module, exports) {
    (function (global, factory) {
        typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
            typeof define === 'function' && define.amd ? define(factory) :
                (global = global || self, global.Flatbush = factory());
    }(this, function () {
        'use strict';
        var FlatQueue = function FlatQueue() {
            this.ids = [];
            this.values = [];
            this.length = 0;
        };
        FlatQueue.prototype.clear = function clear() {
            this.length = this.ids.length = this.values.length = 0;
        };
        FlatQueue.prototype.push = function push(id, value) {
            this.ids.push(id);
            this.values.push(value);
            var pos = this.length++;
            while (pos > 0) {
                var parent = (pos - 1) >> 1;
                var parentValue = this.values[parent];
                if (value >= parentValue) {
                    break;
                }
                this.ids[pos] = this.ids[parent];
                this.values[pos] = parentValue;
                pos = parent;
            }
            this.ids[pos] = id;
            this.values[pos] = value;
        };
        FlatQueue.prototype.pop = function pop() {
            if (this.length === 0) {
                return undefined;
            }
            var top = this.ids[0];
            this.length--;
            if (this.length > 0) {
                var id = this.ids[0] = this.ids[this.length];
                var value = this.values[0] = this.values[this.length];
                var halfLength = this.length >> 1;
                var pos = 0;
                while (pos < halfLength) {
                    var left = (pos << 1) + 1;
                    var right = left + 1;
                    var bestIndex = this.ids[left];
                    var bestValue = this.values[left];
                    var rightValue = this.values[right];
                    if (right < this.length && rightValue < bestValue) {
                        left = right;
                        bestIndex = this.ids[right];
                        bestValue = rightValue;
                    }
                    if (bestValue >= value) {
                        break;
                    }
                    this.ids[pos] = bestIndex;
                    this.values[pos] = bestValue;
                    pos = left;
                }
                this.ids[pos] = id;
                this.values[pos] = value;
            }
            this.ids.pop();
            this.values.pop();
            return top;
        };
        FlatQueue.prototype.peek = function peek() {
            return this.ids[0];
        };
        FlatQueue.prototype.peekValue = function peekValue() {
            return this.values[0];
        };
        var ARRAY_TYPES = [
            Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array,
            Int32Array, Uint32Array, Float32Array, Float64Array
        ];
        var VERSION = 3; // serialized format version
        var Flatbush = function Flatbush(numItems, nodeSize, ArrayType, data) {
            if (nodeSize === void 0)
                nodeSize = 16;
            if (ArrayType === void 0)
                ArrayType = Float64Array;
            if (numItems === undefined) {
                throw new Error('Missing required argument: numItems.');
            }
            if (isNaN(numItems) || numItems <= 0) {
                throw new Error(("Unpexpected numItems value: " + numItems + "."));
            }
            this.numItems = +numItems;
            this.nodeSize = Math.min(Math.max(+nodeSize, 2), 65535);
            // calculate the total number of nodes in the R-tree to allocate space for
            // and the index of each tree level (used in search later)
            var n = numItems;
            var numNodes = n;
            this._levelBounds = [n * 4];
            do {
                n = Math.ceil(n / this.nodeSize);
                numNodes += n;
                this._levelBounds.push(numNodes * 4);
            } while (n !== 1);
            this.ArrayType = ArrayType || Float64Array;
            this.IndexArrayType = numNodes < 16384 ? Uint16Array : Uint32Array;
            var arrayTypeIndex = ARRAY_TYPES.indexOf(this.ArrayType);
            var nodesByteSize = numNodes * 4 * this.ArrayType.BYTES_PER_ELEMENT;
            if (arrayTypeIndex < 0) {
                throw new Error(("Unexpected typed array class: " + ArrayType + "."));
            }
            if (data && (data instanceof ArrayBuffer)) {
                this.data = data;
                this._boxes = new this.ArrayType(this.data, 8, numNodes * 4);
                this._indices = new this.IndexArrayType(this.data, 8 + nodesByteSize, numNodes);
                this._pos = numNodes * 4;
                this.minX = this._boxes[this._pos - 4];
                this.minY = this._boxes[this._pos - 3];
                this.maxX = this._boxes[this._pos - 2];
                this.maxY = this._boxes[this._pos - 1];
            }
            else {
                this.data = new ArrayBuffer(8 + nodesByteSize + numNodes * this.IndexArrayType.BYTES_PER_ELEMENT);
                this._boxes = new this.ArrayType(this.data, 8, numNodes * 4);
                this._indices = new this.IndexArrayType(this.data, 8 + nodesByteSize, numNodes);
                this._pos = 0;
                this.minX = Infinity;
                this.minY = Infinity;
                this.maxX = -Infinity;
                this.maxY = -Infinity;
                new Uint8Array(this.data, 0, 2).set([0xfb, (VERSION << 4) + arrayTypeIndex]);
                new Uint16Array(this.data, 2, 1)[0] = nodeSize;
                new Uint32Array(this.data, 4, 1)[0] = numItems;
            }
            // a priority queue for k-nearest-neighbors queries
            this._queue = new FlatQueue();
        };
        Flatbush.from = function from(data) {
            if (!(data instanceof ArrayBuffer)) {
                throw new Error('Data must be an instance of ArrayBuffer.');
            }
            var ref = new Uint8Array(data, 0, 2);
            var magic = ref[0];
            var versionAndType = ref[1];
            if (magic !== 0xfb) {
                throw new Error('Data does not appear to be in a Flatbush format.');
            }
            if (versionAndType >> 4 !== VERSION) {
                throw new Error(("Got v" + (versionAndType >> 4) + " data when expected v" + VERSION + "."));
            }
            var ref$1 = new Uint16Array(data, 2, 1);
            var nodeSize = ref$1[0];
            var ref$2 = new Uint32Array(data, 4, 1);
            var numItems = ref$2[0];
            return new Flatbush(numItems, nodeSize, ARRAY_TYPES[versionAndType & 0x0f], data);
        };
        Flatbush.prototype.add = function add(minX, minY, maxX, maxY) {
            var index = this._pos >> 2;
            this._indices[index] = index;
            this._boxes[this._pos++] = minX;
            this._boxes[this._pos++] = minY;
            this._boxes[this._pos++] = maxX;
            this._boxes[this._pos++] = maxY;
            if (minX < this.minX) {
                this.minX = minX;
            }
            if (minY < this.minY) {
                this.minY = minY;
            }
            if (maxX > this.maxX) {
                this.maxX = maxX;
            }
            if (maxY > this.maxY) {
                this.maxY = maxY;
            }
        };
        Flatbush.prototype.finish = function finish() {
            if (this._pos >> 2 !== this.numItems) {
                throw new Error(("Added " + (this._pos >> 2) + " items when expected " + (this.numItems) + "."));
            }
            var width = this.maxX - this.minX;
            var height = this.maxY - this.minY;
            var hilbertValues = new Uint32Array(this.numItems);
            var hilbertMax = (1 << 16) - 1;
            // map item centers into Hilbert coordinate space and calculate Hilbert values
            for (var i = 0; i < this.numItems; i++) {
                var pos = 4 * i;
                var minX = this._boxes[pos++];
                var minY = this._boxes[pos++];
                var maxX = this._boxes[pos++];
                var maxY = this._boxes[pos++];
                var x = Math.floor(hilbertMax * ((minX + maxX) / 2 - this.minX) / width);
                var y = Math.floor(hilbertMax * ((minY + maxY) / 2 - this.minY) / height);
                hilbertValues[i] = hilbert(x, y);
            }
            // sort items by their Hilbert value (for packing later)
            sort(hilbertValues, this._boxes, this._indices, 0, this.numItems - 1);
            // generate nodes at each tree level, bottom-up
            for (var i$1 = 0, pos$1 = 0; i$1 < this._levelBounds.length - 1; i$1++) {
                var end = this._levelBounds[i$1];
                // generate a parent node for each block of consecutive <nodeSize> nodes
                while (pos$1 < end) {
                    var nodeMinX = Infinity;
                    var nodeMinY = Infinity;
                    var nodeMaxX = -Infinity;
                    var nodeMaxY = -Infinity;
                    var nodeIndex = pos$1;
                    // calculate bbox for the new node
                    for (var i$2 = 0; i$2 < this.nodeSize && pos$1 < end; i$2++) {
                        var minX$1 = this._boxes[pos$1++];
                        var minY$1 = this._boxes[pos$1++];
                        var maxX$1 = this._boxes[pos$1++];
                        var maxY$1 = this._boxes[pos$1++];
                        if (minX$1 < nodeMinX) {
                            nodeMinX = minX$1;
                        }
                        if (minY$1 < nodeMinY) {
                            nodeMinY = minY$1;
                        }
                        if (maxX$1 > nodeMaxX) {
                            nodeMaxX = maxX$1;
                        }
                        if (maxY$1 > nodeMaxY) {
                            nodeMaxY = maxY$1;
                        }
                    }
                    // add the new node to the tree data
                    this._indices[this._pos >> 2] = nodeIndex;
                    this._boxes[this._pos++] = nodeMinX;
                    this._boxes[this._pos++] = nodeMinY;
                    this._boxes[this._pos++] = nodeMaxX;
                    this._boxes[this._pos++] = nodeMaxY;
                }
            }
        };
        Flatbush.prototype.search = function search(minX, minY, maxX, maxY, filterFn) {
            if (this._pos !== this._boxes.length) {
                throw new Error('Data not yet indexed - call index.finish().');
            }
            var nodeIndex = this._boxes.length - 4;
            var level = this._levelBounds.length - 1;
            var queue = [];
            var results = [];
            while (nodeIndex !== undefined) {
                // find the end index of the node
                var end = Math.min(nodeIndex + this.nodeSize * 4, this._levelBounds[level]);
                // search through child nodes
                for (var pos = nodeIndex; pos < end; pos += 4) {
                    var index = this._indices[pos >> 2] | 0;
                    // check if node bbox intersects with query bbox
                    if (maxX < this._boxes[pos]) {
                        continue;
                    } // maxX < nodeMinX
                    if (maxY < this._boxes[pos + 1]) {
                        continue;
                    } // maxY < nodeMinY
                    if (minX > this._boxes[pos + 2]) {
                        continue;
                    } // minX > nodeMaxX
                    if (minY > this._boxes[pos + 3]) {
                        continue;
                    } // minY > nodeMaxY
                    if (nodeIndex < this.numItems * 4) {
                        if (filterFn === undefined || filterFn(index)) {
                            results.push(index); // leaf item
                        }
                    }
                    else {
                        queue.push(index); // node; add it to the search queue
                        queue.push(level - 1);
                    }
                }
                level = queue.pop();
                nodeIndex = queue.pop();
            }
            return results;
        };
        Flatbush.prototype.neighbors = function neighbors(x, y, maxResults, maxDistance, filterFn) {
            if (maxResults === void 0)
                maxResults = Infinity;
            if (maxDistance === void 0)
                maxDistance = Infinity;
            if (this._pos !== this._boxes.length) {
                throw new Error('Data not yet indexed - call index.finish().');
            }
            var nodeIndex = this._boxes.length - 4;
            var q = this._queue;
            var results = [];
            var maxDistSquared = maxDistance * maxDistance;
            while (nodeIndex !== undefined) {
                // find the end index of the node
                var end = Math.min(nodeIndex + this.nodeSize * 4, upperBound(nodeIndex, this._levelBounds));
                // add child nodes to the queue
                for (var pos = nodeIndex; pos < end; pos += 4) {
                    var index = this._indices[pos >> 2] | 0;
                    var dx = axisDist(x, this._boxes[pos], this._boxes[pos + 2]);
                    var dy = axisDist(y, this._boxes[pos + 1], this._boxes[pos + 3]);
                    var dist = dx * dx + dy * dy;
                    if (nodeIndex < this.numItems * 4) { // leaf node
                        if (filterFn === undefined || filterFn(index)) {
                            // put a negative index if it's an item rather than a node, to recognize later
                            q.push(-index - 1, dist);
                        }
                    }
                    else {
                        q.push(index, dist);
                    }
                }
                // pop items from the queue
                while (q.length && q.peek() < 0) {
                    var dist$1 = q.peekValue();
                    if (dist$1 > maxDistSquared) {
                        q.clear();
                        return results;
                    }
                    results.push(-q.pop() - 1);
                    if (results.length === maxResults) {
                        q.clear();
                        return results;
                    }
                }
                nodeIndex = q.pop();
            }
            q.clear();
            return results;
        };
        function axisDist(k, min, max) {
            return k < min ? min - k : k <= max ? 0 : k - max;
        }
        // binary search for the first value in the array bigger than the given
        function upperBound(value, arr) {
            var i = 0;
            var j = arr.length - 1;
            while (i < j) {
                var m = (i + j) >> 1;
                if (arr[m] > value) {
                    j = m;
                }
                else {
                    i = m + 1;
                }
            }
            return arr[i];
        }
        // custom quicksort that sorts bbox data alongside the hilbert values
        function sort(values, boxes, indices, left, right) {
            if (left >= right) {
                return;
            }
            var pivot = values[(left + right) >> 1];
            var i = left - 1;
            var j = right + 1;
            while (true) {
                do {
                    i++;
                } while (values[i] < pivot);
                do {
                    j--;
                } while (values[j] > pivot);
                if (i >= j) {
                    break;
                }
                swap(values, boxes, indices, i, j);
            }
            sort(values, boxes, indices, left, j);
            sort(values, boxes, indices, j + 1, right);
        }
        // swap two values and two corresponding boxes
        function swap(values, boxes, indices, i, j) {
            var temp = values[i];
            values[i] = values[j];
            values[j] = temp;
            var k = 4 * i;
            var m = 4 * j;
            var a = boxes[k];
            var b = boxes[k + 1];
            var c = boxes[k + 2];
            var d = boxes[k + 3];
            boxes[k] = boxes[m];
            boxes[k + 1] = boxes[m + 1];
            boxes[k + 2] = boxes[m + 2];
            boxes[k + 3] = boxes[m + 3];
            boxes[m] = a;
            boxes[m + 1] = b;
            boxes[m + 2] = c;
            boxes[m + 3] = d;
            var e = indices[i];
            indices[i] = indices[j];
            indices[j] = e;
        }
        // Fast Hilbert curve algorithm by http://threadlocalmutex.com/
        // Ported from C++ https://github.com/rawrunprotected/hilbert_curves (public domain)
        function hilbert(x, y) {
            var a = x ^ y;
            var b = 0xFFFF ^ a;
            var c = 0xFFFF ^ (x | y);
            var d = x & (y ^ 0xFFFF);
            var A = a | (b >> 1);
            var B = (a >> 1) ^ a;
            var C = ((c >> 1) ^ (b & (d >> 1))) ^ c;
            var D = ((a & (c >> 1)) ^ (d >> 1)) ^ d;
            a = A;
            b = B;
            c = C;
            d = D;
            A = ((a & (a >> 2)) ^ (b & (b >> 2)));
            B = ((a & (b >> 2)) ^ (b & ((a ^ b) >> 2)));
            C ^= ((a & (c >> 2)) ^ (b & (d >> 2)));
            D ^= ((b & (c >> 2)) ^ ((a ^ b) & (d >> 2)));
            a = A;
            b = B;
            c = C;
            d = D;
            A = ((a & (a >> 4)) ^ (b & (b >> 4)));
            B = ((a & (b >> 4)) ^ (b & ((a ^ b) >> 4)));
            C ^= ((a & (c >> 4)) ^ (b & (d >> 4)));
            D ^= ((b & (c >> 4)) ^ ((a ^ b) & (d >> 4)));
            a = A;
            b = B;
            c = C;
            d = D;
            C ^= ((a & (c >> 8)) ^ (b & (d >> 8)));
            D ^= ((b & (c >> 8)) ^ ((a ^ b) & (d >> 8)));
            a = C ^ (C >> 1);
            b = D ^ (D >> 1);
            var i0 = x ^ y;
            var i1 = b | (0xFFFF ^ (i0 | a));
            i0 = (i0 | (i0 << 8)) & 0x00FF00FF;
            i0 = (i0 | (i0 << 4)) & 0x0F0F0F0F;
            i0 = (i0 | (i0 << 2)) & 0x33333333;
            i0 = (i0 | (i0 << 1)) & 0x55555555;
            i1 = (i1 | (i1 << 8)) & 0x00FF00FF;
            i1 = (i1 | (i1 << 4)) & 0x0F0F0F0F;
            i1 = (i1 | (i1 << 2)) & 0x33333333;
            i1 = (i1 | (i1 << 1)) & 0x55555555;
            return ((i1 << 1) | i0) >>> 0;
        }
        return Flatbush;
    }));
},
/* core/util/bbox.js */ function _(require, module, exports) {
    const { min, max } = Math;
    function empty() {
        return {
            x0: Infinity,
            y0: Infinity,
            x1: -Infinity,
            y1: -Infinity,
        };
    }
    exports.empty = empty;
    function positive_x() {
        return {
            x0: Number.MIN_VALUE,
            y0: -Infinity,
            x1: Infinity,
            y1: Infinity,
        };
    }
    exports.positive_x = positive_x;
    function positive_y() {
        return {
            x0: -Infinity,
            y0: Number.MIN_VALUE,
            x1: Infinity,
            y1: Infinity,
        };
    }
    exports.positive_y = positive_y;
    function union(a, b) {
        return {
            x0: min(a.x0, b.x0),
            x1: max(a.x1, b.x1),
            y0: min(a.y0, b.y0),
            y1: max(a.y1, b.y1),
        };
    }
    exports.union = union;
    class BBox {
        constructor(box) {
            if (box == null) {
                this.x0 = 0;
                this.y0 = 0;
                this.x1 = 0;
                this.y1 = 0;
            }
            else if ('x0' in box) {
                const { x0, y0, x1, y1 } = box;
                if (!(x0 <= x1 && y0 <= y1))
                    throw new Error(`invalid bbox {x0: ${x0}, y0: ${y0}, x1: ${x1}, y1: ${y1}}`);
                this.x0 = x0;
                this.y0 = y0;
                this.x1 = x1;
                this.y1 = y1;
            }
            else if ("x" in box) {
                const { x, y, width, height } = box;
                if (!(width >= 0 && height >= 0))
                    throw new Error(`invalid bbox {x: ${x}, y: ${y}, width: ${width}, height: ${height}}`);
                this.x0 = x;
                this.y0 = y;
                this.x1 = x + width;
                this.y1 = y + height;
            }
            else {
                let left, right;
                let top, bottom;
                if ("width" in box) {
                    if ("left" in box) {
                        left = box.left;
                        right = left + box.width;
                    }
                    else if ("right" in box) {
                        right = box.right;
                        left = right - box.width;
                    }
                    else {
                        const w2 = box.width / 2;
                        left = box.hcenter - w2;
                        right = box.hcenter + w2;
                    }
                }
                else {
                    left = box.left;
                    right = box.right;
                }
                if ("height" in box) {
                    if ("top" in box) {
                        top = box.top;
                        bottom = top + box.height;
                    }
                    else if ("bottom" in box) {
                        bottom = box.bottom;
                        top = bottom - box.height;
                    }
                    else {
                        const h2 = box.height / 2;
                        top = box.vcenter - h2;
                        bottom = box.vcenter + h2;
                    }
                }
                else {
                    top = box.top;
                    bottom = box.bottom;
                }
                if (!(left <= right && top <= bottom))
                    throw new Error(`invalid bbox {left: ${left}, top: ${top}, right: ${right}, bottom: ${bottom}}`);
                this.x0 = left;
                this.y0 = top;
                this.x1 = right;
                this.y1 = bottom;
            }
        }
        toString() {
            return `BBox({left: ${this.left}, top: ${this.top}, width: ${this.width}, height: ${this.height}})`;
        }
        get left() { return this.x0; }
        get top() { return this.y0; }
        get right() { return this.x1; }
        get bottom() { return this.y1; }
        get p0() { return [this.x0, this.y0]; }
        get p1() { return [this.x1, this.y1]; }
        get x() { return this.x0; }
        get y() { return this.y0; }
        get width() { return this.x1 - this.x0; }
        get height() { return this.y1 - this.y0; }
        get rect() { return { x0: this.x0, y0: this.y0, x1: this.x1, y1: this.y1 }; }
        get box() { return { x: this.x, y: this.y, width: this.width, height: this.height }; }
        get h_range() { return { start: this.x0, end: this.x1 }; }
        get v_range() { return { start: this.y0, end: this.y1 }; }
        get ranges() { return [this.h_range, this.v_range]; }
        get aspect() { return this.width / this.height; }
        get hcenter() { return (this.left + this.right) / 2; }
        get vcenter() { return (this.top + this.bottom) / 2; }
        contains(x, y) {
            return x >= this.x0 && x <= this.x1 && y >= this.y0 && y <= this.y1;
        }
        clip(x, y) {
            if (x < this.x0)
                x = this.x0;
            else if (x > this.x1)
                x = this.x1;
            if (y < this.y0)
                y = this.y0;
            else if (y > this.y1)
                y = this.y1;
            return [x, y];
        }
        union(that) {
            return new BBox({
                x0: min(this.x0, that.x0),
                y0: min(this.y0, that.y0),
                x1: max(this.x1, that.x1),
                y1: max(this.y1, that.y1),
            });
        }
        equals(that) {
            return this.x0 == that.x0 && this.y0 == that.y0 && this.x1 == that.x1 && this.y1 == that.y1;
        }
        get xview() {
            return {
                compute: (x) => {
                    return this.left + x;
                },
                v_compute: (xx) => {
                    const _xx = new Float64Array(xx.length);
                    const left = this.left;
                    for (let i = 0; i < xx.length; i++) {
                        _xx[i] = left + xx[i];
                    }
                    return _xx;
                },
            };
        }
        get yview() {
            return {
                compute: (y) => {
                    return this.bottom - y;
                },
                v_compute: (yy) => {
                    const _yy = new Float64Array(yy.length);
                    const bottom = this.bottom;
                    for (let i = 0; i < yy.length; i++) {
                        _yy[i] = bottom - yy[i];
                    }
                    return _yy;
                },
            };
        }
    }
    exports.BBox = BBox;
    BBox.__name__ = "BBox";
},
/* models/glyphs/glyph.js */ function _(require, module, exports) {
    const hittest = require(81) /* ../../core/hittest */;
    const p = require(18) /* ../../core/properties */;
    const bbox = require(79) /* ../../core/util/bbox */;
    const proj = require(30) /* ../../core/util/projections */;
    const visuals = require(63) /* ../../core/visuals */;
    const view_1 = require(60) /* ../../core/view */;
    const model_1 = require(64) /* ../../model */;
    const logging_1 = require(65) /* ../../core/logging */;
    const arrayable_1 = require(11) /* ../../core/util/arrayable */;
    const object_1 = require(22) /* ../../core/util/object */;
    const types_1 = require(7) /* ../../core/util/types */;
    const line_1 = require(75) /* ./line */;
    const factor_range_1 = require(82) /* ../ranges/factor_range */;
    class GlyphView extends view_1.View {
        constructor() {
            super(...arguments);
            this._nohit_warned = {};
        }
        get renderer() {
            return this.parent;
        }
        initialize() {
            super.initialize();
            this._nohit_warned = {};
            this.visuals = new visuals.Visuals(this.model);
            // Init gl (this should really be done anytime renderer is set,
            // and not done if it isn't ever set, but for now it only
            // matters in the unit tests because we build a view without a
            // renderer there)
            const { gl } = this.renderer.plot_view;
            if (gl != null) {
                let webgl_module = null;
                try {
                    webgl_module = require(352) /* ./webgl/index */;
                }
                catch (e) {
                    if (e.code === 'MODULE_NOT_FOUND') {
                        logging_1.logger.warn('WebGL was requested and is supported, but bokeh-gl(.min).js is not available, falling back to 2D rendering.');
                    }
                    else
                        throw e;
                }
                if (webgl_module != null) {
                    const Cls = webgl_module[this.model.type + 'GLGlyph'];
                    if (Cls != null)
                        this.glglyph = new Cls(gl.ctx, this);
                }
            }
        }
        set_visuals(source) {
            this.visuals.warm_cache(source);
            if (this.glglyph != null)
                this.glglyph.set_visuals_changed();
        }
        render(ctx, indices, data) {
            ctx.beginPath();
            if (this.glglyph != null) {
                if (this.glglyph.render(ctx, indices, data))
                    return;
            }
            this._render(ctx, indices, data);
        }
        has_finished() {
            return true;
        }
        notify_finished() {
            this.renderer.notify_finished();
        }
        _bounds(bounds) {
            return bounds;
        }
        bounds() {
            return this._bounds(this.index.bbox);
        }
        log_bounds() {
            const bb = bbox.empty();
            const positive_x_bbs = this.index.search(bbox.positive_x());
            for (const x of positive_x_bbs) {
                if (x.x0 < bb.x0)
                    bb.x0 = x.x0;
                if (x.x1 > bb.x1)
                    bb.x1 = x.x1;
            }
            const positive_y_bbs = this.index.search(bbox.positive_y());
            for (const y of positive_y_bbs) {
                if (y.y0 < bb.y0)
                    bb.y0 = y.y0;
                if (y.y1 > bb.y1)
                    bb.y1 = y.y1;
            }
            return this._bounds(bb);
        }
        get_anchor_point(anchor, i, [sx, sy]) {
            switch (anchor) {
                case "center": return { x: this.scenterx(i, sx, sy), y: this.scentery(i, sx, sy) };
                default: return null;
            }
        }
        sdist(scale, pts, spans, pts_location = "edge", dilate = false) {
            let pt0;
            let pt1;
            const n = pts.length;
            if (pts_location == 'center') {
                const halfspan = arrayable_1.map(spans, (d) => d / 2);
                pt0 = new Float64Array(n);
                for (let i = 0; i < n; i++) {
                    pt0[i] = pts[i] - halfspan[i];
                }
                pt1 = new Float64Array(n);
                for (let i = 0; i < n; i++) {
                    pt1[i] = pts[i] + halfspan[i];
                }
            }
            else {
                pt0 = pts;
                pt1 = new Float64Array(n);
                for (let i = 0; i < n; i++) {
                    pt1[i] = pt0[i] + spans[i];
                }
            }
            const spt0 = scale.v_compute(pt0);
            const spt1 = scale.v_compute(pt1);
            if (dilate)
                return arrayable_1.map(spt0, (_, i) => Math.ceil(Math.abs(spt1[i] - spt0[i])));
            else
                return arrayable_1.map(spt0, (_, i) => Math.abs(spt1[i] - spt0[i]));
        }
        draw_legend_for_index(_ctx, _bbox, _index) { }
        hit_test(geometry) {
            let result = null;
            const func = `_hit_${geometry.type}`;
            if (this[func] != null) {
                result = this[func](geometry);
            }
            else if (this._nohit_warned[geometry.type] == null) {
                logging_1.logger.debug(`'${geometry.type}' selection not available for ${this.model.type}`);
                this._nohit_warned[geometry.type] = true;
            }
            return result;
        }
        _hit_rect_against_index(geometry) {
            const { sx0, sx1, sy0, sy1 } = geometry;
            const [x0, x1] = this.renderer.xscale.r_invert(sx0, sx1);
            const [y0, y1] = this.renderer.yscale.r_invert(sy0, sy1);
            const result = hittest.create_empty_hit_test_result();
            result.indices = this.index.indices({ x0, x1, y0, y1 });
            return result;
        }
        set_data(source, indices, indices_to_update) {
            let data = this.model.materialize_dataspecs(source);
            this.visuals.set_all_indices(indices);
            if (indices && !(this instanceof line_1.LineView)) {
                const data_subset = {};
                for (const k in data) {
                    const v = data[k];
                    if (k.charAt(0) === '_')
                        data_subset[k] = indices.map((i) => v[i]);
                    else
                        data_subset[k] = v;
                }
                data = data_subset;
            }
            const self = this;
            object_1.extend(self, data);
            // TODO (bev) Should really probably delegate computing projected
            // coordinates to glyphs, instead of centralizing here in one place.
            if (this.renderer.plot_view.model.use_map) {
                if (self._x != null)
                    [self._x, self._y] = proj.project_xy(self._x, self._y);
                if (self._xs != null)
                    [self._xs, self._ys] = proj.project_xsys(self._xs, self._ys);
                if (self._x0 != null)
                    [self._x0, self._y0] = proj.project_xy(self._x0, self._y0);
                if (self._x1 != null)
                    [self._x1, self._y1] = proj.project_xy(self._x1, self._y1);
            }
            // if we have any coordinates that are categorical, convert them to
            // synthetic coords here
            if (this.renderer.plot_view.frame.x_ranges != null) { // XXXX JUST TEMP FOR TESTS TO PASS
                const xr = this.renderer.plot_view.frame.x_ranges[this.model.x_range_name];
                const yr = this.renderer.plot_view.frame.y_ranges[this.model.y_range_name];
                for (let [xname, yname] of this.model._coords) {
                    xname = `_${xname}`;
                    yname = `_${yname}`;
                    // TODO (bev) more robust detection of multi-glyph case
                    // hand multi glyph case
                    if (self._xs != null) {
                        if (xr instanceof factor_range_1.FactorRange) {
                            self[xname] = arrayable_1.map(self[xname], (arr) => xr.v_synthetic(arr));
                        }
                        if (yr instanceof factor_range_1.FactorRange) {
                            self[yname] = arrayable_1.map(self[yname], (arr) => yr.v_synthetic(arr));
                        }
                    }
                    else {
                        // hand standard glyph case
                        if (xr instanceof factor_range_1.FactorRange) {
                            self[xname] = xr.v_synthetic(self[xname]);
                        }
                        if (yr instanceof factor_range_1.FactorRange) {
                            self[yname] = yr.v_synthetic(self[yname]);
                        }
                    }
                }
            }
            if (this.glglyph != null)
                this.glglyph.set_data_changed(self._x.length);
            this._set_data(indices_to_update); //TODO doesn't take subset indices into account
            this.index_data();
        }
        _set_data(_indices) { }
        index_data() {
            this.index = this._index_data();
        }
        mask_data(indices) {
            // WebGL can do the clipping much more efficiently
            if (this.glglyph != null || this._mask_data == null)
                return indices;
            else
                return this._mask_data();
        }
        map_data() {
            // TODO: if using gl, skip this (when is this called?)
            // map all the coordinate fields
            const self = this;
            for (let [xname, yname] of this.model._coords) {
                const sxname = `s${xname}`;
                const syname = `s${yname}`;
                xname = `_${xname}`;
                yname = `_${yname}`;
                if (self[xname] != null && (types_1.isArray(self[xname][0]) || types_1.isTypedArray(self[xname][0]))) {
                    const n = self[xname].length;
                    self[sxname] = new Array(n);
                    self[syname] = new Array(n);
                    for (let i = 0; i < n; i++) {
                        const [sx, sy] = this.map_to_screen(self[xname][i], self[yname][i]);
                        self[sxname][i] = sx;
                        self[syname][i] = sy;
                    }
                }
                else
                    [self[sxname], self[syname]] = this.map_to_screen(self[xname], self[yname]);
            }
            this._map_data();
        }
        // This is where specs not included in coords are computed, e.g. radius.
        _map_data() { }
        map_to_screen(x, y) {
            return this.renderer.plot_view.map_to_screen(x, y, this.model.x_range_name, this.model.y_range_name);
        }
    }
    exports.GlyphView = GlyphView;
    GlyphView.__name__ = "GlyphView";
    class Glyph extends model_1.Model {
        constructor(attrs) {
            super(attrs);
        }
        static init_Glyph() {
            this.prototype._coords = [];
            this.internal({
                x_range_name: [p.String, 'default'],
                y_range_name: [p.String, 'default'],
            });
        }
        static coords(coords) {
            const _coords = this.prototype._coords.concat(coords);
            this.prototype._coords = _coords;
            const result = {};
            for (const [x, y] of coords) {
                result[x] = [p.CoordinateSpec];
                result[y] = [p.CoordinateSpec];
            }
            this.define(result);
        }
    }
    exports.Glyph = Glyph;
    Glyph.__name__ = "Glyph";
    Glyph.init_Glyph();
},
/* core/hittest.js */ function _(require, module, exports) {
    const array_1 = require(8) /* ./util/array */;
    const selection_1 = require(71) /* ../models/selections/selection */;
    function point_in_poly(x, y, px, py) {
        let inside = false;
        let x1 = px[px.length - 1];
        let y1 = py[py.length - 1];
        for (let i = 0; i < px.length; i++) {
            const x2 = px[i];
            const y2 = py[i];
            if ((y1 < y) != (y2 < y)) {
                if (x1 + (y - y1) / (y2 - y1) * (x2 - x1) < x)
                    inside = !inside;
            }
            x1 = x2;
            y1 = y2;
        }
        return inside;
    }
    exports.point_in_poly = point_in_poly;
    function point_in_ellipse(x, y, angle, b, a, x0, y0) {
        const A = (Math.pow((Math.cos(angle) / a), 2) + Math.pow((Math.sin(angle) / b), 2));
        const B = 2 * Math.cos(angle) * Math.sin(angle) * (Math.pow((1 / a), 2) - Math.pow((1 / b), 2));
        const C = (Math.pow((Math.cos(angle) / b), 2) + Math.pow((Math.sin(angle) / a), 2));
        const eqn = A * Math.pow((x - x0), 2) + B * (x - x0) * (y - y0) + C * Math.pow((y - y0), 2);
        const inside = eqn <= 1;
        return inside;
    }
    exports.point_in_ellipse = point_in_ellipse;
    function create_empty_hit_test_result() {
        return new selection_1.Selection();
    }
    exports.create_empty_hit_test_result = create_empty_hit_test_result;
    function create_hit_test_result_from_hits(hits) {
        const result = new selection_1.Selection();
        result.indices = array_1.sort_by(hits, ([_i, dist]) => dist).map(([i, _dist]) => i);
        return result;
    }
    exports.create_hit_test_result_from_hits = create_hit_test_result_from_hits;
    function sqr(x) {
        return x * x;
    }
    function dist_2_pts(p0, p1) {
        return sqr(p0.x - p1.x) + sqr(p0.y - p1.y);
    }
    exports.dist_2_pts = dist_2_pts;
    function dist_to_segment_squared(p, v, w) {
        const l2 = dist_2_pts(v, w);
        if (l2 == 0)
            return dist_2_pts(p, v);
        const t = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2;
        if (t < 0)
            return dist_2_pts(p, v);
        if (t > 1)
            return dist_2_pts(p, w);
        const q = { x: v.x + t * (w.x - v.x), y: v.y + t * (w.y - v.y) };
        return dist_2_pts(p, q);
    }
    exports.dist_to_segment_squared = dist_to_segment_squared;
    function dist_to_segment(p, v, w) {
        return Math.sqrt(dist_to_segment_squared(p, v, w));
    }
    exports.dist_to_segment = dist_to_segment;
    function check_2_segments_intersect(l0_x0, l0_y0, l0_x1, l0_y1, l1_x0, l1_y0, l1_x1, l1_y1) {
        /*
         *  Check if 2 segments (l0 and l1) intersect. Returns a structure with
         *  the following attributes:
         *   * hit (boolean): whether the 2 segments intersect
         *   * x (float): x coordinate of the intersection point
         *   * y (float): y coordinate of the intersection point
         */
        const den = ((l1_y1 - l1_y0) * (l0_x1 - l0_x0)) - ((l1_x1 - l1_x0) * (l0_y1 - l0_y0));
        if (den == 0) {
            return { hit: false, x: null, y: null };
        }
        else {
            let a = l0_y0 - l1_y0;
            let b = l0_x0 - l1_x0;
            const num1 = ((l1_x1 - l1_x0) * a) - ((l1_y1 - l1_y0) * b);
            const num2 = ((l0_x1 - l0_x0) * a) - ((l0_y1 - l0_y0) * b);
            a = num1 / den;
            b = num2 / den;
            const x = l0_x0 + (a * (l0_x1 - l0_x0));
            const y = l0_y0 + (a * (l0_y1 - l0_y0));
            return { hit: (a > 0 && a < 1) && (b > 0 && b < 1), x, y };
        }
    }
    exports.check_2_segments_intersect = check_2_segments_intersect;
},
/* models/ranges/factor_range.js */ function _(require, module, exports) {
    const range_1 = require(83) /* ./range */;
    const p = require(18) /* ../../core/properties */;
    const arrayable_1 = require(11) /* ../../core/util/arrayable */;
    const array_1 = require(8) /* ../../core/util/array */;
    const types_1 = require(7) /* ../../core/util/types */;
    function map_one_level(factors, padding, offset = 0) {
        const mapping = {};
        for (let i = 0; i < factors.length; i++) {
            const factor = factors[i];
            if (factor in mapping)
                throw new Error(`duplicate factor or subfactor: ${factor}`);
            else
                mapping[factor] = { value: 0.5 + i * (1 + padding) + offset };
        }
        return [mapping, (factors.length - 1) * padding];
    }
    exports.map_one_level = map_one_level;
    function map_two_levels(factors, outer_pad, factor_pad, offset = 0) {
        const mapping = {};
        const tops = {};
        const tops_order = [];
        for (const [f0, f1] of factors) {
            if (!(f0 in tops)) {
                tops[f0] = [];
                tops_order.push(f0);
            }
            tops[f0].push(f1);
        }
        let suboffset = offset;
        let total_subpad = 0;
        for (const f0 of tops_order) {
            const n = tops[f0].length;
            const [submap, subpad] = map_one_level(tops[f0], factor_pad, suboffset);
            total_subpad += subpad;
            const subtot = array_1.sum(tops[f0].map((f1) => submap[f1].value));
            mapping[f0] = { value: subtot / n, mapping: submap };
            suboffset += n + outer_pad + subpad;
        }
        return [mapping, tops_order, (tops_order.length - 1) * outer_pad + total_subpad];
    }
    exports.map_two_levels = map_two_levels;
    function map_three_levels(factors, outer_pad, inner_pad, factor_pad, offset = 0) {
        const mapping = {};
        const tops = {};
        const tops_order = [];
        for (const [f0, f1, f2] of factors) {
            if (!(f0 in tops)) {
                tops[f0] = [];
                tops_order.push(f0);
            }
            tops[f0].push([f1, f2]);
        }
        const mids_order = [];
        let suboffset = offset;
        let total_subpad = 0;
        for (const f0 of tops_order) {
            const n = tops[f0].length;
            const [submap, submids_order, subpad] = map_two_levels(tops[f0], inner_pad, factor_pad, suboffset);
            for (const f1 of submids_order)
                mids_order.push([f0, f1]);
            total_subpad += subpad;
            const subtot = array_1.sum(tops[f0].map(([f1]) => submap[f1].value));
            mapping[f0] = { value: subtot / n, mapping: submap };
            suboffset += n + outer_pad + subpad;
        }
        return [mapping, tops_order, mids_order, (tops_order.length - 1) * outer_pad + total_subpad];
    }
    exports.map_three_levels = map_three_levels;
    class FactorRange extends range_1.Range {
        constructor(attrs) {
            super(attrs);
        }
        static init_FactorRange() {
            this.define({
                factors: [p.Array, []],
                factor_padding: [p.Number, 0],
                subgroup_padding: [p.Number, 0.8],
                group_padding: [p.Number, 1.4],
                range_padding: [p.Number, 0],
                range_padding_units: [p.PaddingUnits, "percent"],
                start: [p.Number],
                end: [p.Number],
            });
            this.internal({
                levels: [p.Number],
                mids: [p.Array],
                tops: [p.Array],
                tops_groups: [p.Array],
            });
        }
        get min() {
            return this.start;
        }
        get max() {
            return this.end;
        }
        initialize() {
            super.initialize();
            this._init(true);
        }
        connect_signals() {
            super.connect_signals();
            this.connect(this.properties.factors.change, () => this.reset());
            this.connect(this.properties.factor_padding.change, () => this.reset());
            this.connect(this.properties.group_padding.change, () => this.reset());
            this.connect(this.properties.subgroup_padding.change, () => this.reset());
            this.connect(this.properties.range_padding.change, () => this.reset());
            this.connect(this.properties.range_padding_units.change, () => this.reset());
        }
        reset() {
            this._init(false);
            this.change.emit();
        }
        _lookup(x) {
            if (x.length == 1) {
                const m = this._mapping;
                if (!m.hasOwnProperty(x[0])) {
                    return NaN;
                }
                return m[x[0]].value;
            }
            else if (x.length == 2) {
                const m = this._mapping;
                if (!m.hasOwnProperty(x[0]) || !m[x[0]].mapping.hasOwnProperty(x[1])) {
                    return NaN;
                }
                return m[x[0]].mapping[x[1]].value;
            }
            else if (x.length == 3) {
                const m = this._mapping;
                if (!m.hasOwnProperty(x[0]) || !m[x[0]].mapping.hasOwnProperty(x[1]) || !m[x[0]].mapping[x[1]].mapping.hasOwnProperty(x[2])) {
                    return NaN;
                }
                return m[x[0]].mapping[x[1]].mapping[x[2]].value;
            }
            else
                throw new Error("unreachable code");
        }
        // convert a string factor into a synthetic coordinate
        synthetic(x) {
            if (types_1.isNumber(x))
                return x;
            if (types_1.isString(x))
                return this._lookup([x]);
            let offset = 0;
            const off = x[x.length - 1];
            if (types_1.isNumber(off)) {
                offset = off;
                x = x.slice(0, -1);
            }
            return this._lookup(x) + offset;
        }
        // convert an array of string factors into synthetic coordinates
        v_synthetic(xs) {
            return arrayable_1.map(xs, (x) => this.synthetic(x));
        }
        _init(silent) {
            let levels;
            let inside_padding;
            if (array_1.every(this.factors, types_1.isString)) {
                levels = 1;
                [this._mapping, inside_padding] = map_one_level(this.factors, this.factor_padding);
            }
            else if (array_1.every(this.factors, (x) => types_1.isArray(x) && x.length == 2 && types_1.isString(x[0]) && types_1.isString(x[1]))) {
                levels = 2;
                [this._mapping, this.tops, inside_padding] = map_two_levels(this.factors, this.group_padding, this.factor_padding);
            }
            else if (array_1.every(this.factors, (x) => types_1.isArray(x) && x.length == 3 && types_1.isString(x[0]) && types_1.isString(x[1]) && types_1.isString(x[2]))) {
                levels = 3;
                [this._mapping, this.tops, this.mids, inside_padding] = map_three_levels(this.factors, this.group_padding, this.subgroup_padding, this.factor_padding);
            }
            else
                throw new Error("???");
            let start = 0;
            let end = this.factors.length + inside_padding;
            if (this.range_padding_units == "percent") {
                const half_span = (end - start) * this.range_padding / 2;
                start -= half_span;
                end += half_span;
            }
            else {
                start -= this.range_padding;
                end += this.range_padding;
            }
            this.setv({ start, end, levels }, { silent });
            if (this.bounds == "auto")
                this.setv({ bounds: [start, end] }, { silent: true });
        }
    }
    exports.FactorRange = FactorRange;
    FactorRange.__name__ = "FactorRange";
    FactorRange.init_FactorRange();
},
/* models/ranges/range.js */ function _(require, module, exports) {
    const model_1 = require(64) /* ../../model */;
    const p = require(18) /* ../../core/properties */;
    const types_1 = require(7) /* ../../core/util/types */;
    class Range extends model_1.Model {
        constructor(attrs) {
            super(attrs);
            this.have_updated_interactively = false;
        }
        static init_Range() {
            this.define({
                callback: [p.Any],
                bounds: [p.Any],
                min_interval: [p.Any],
                max_interval: [p.Any],
            });
            this.internal({
                plots: [p.Array, []],
            });
        }
        connect_signals() {
            super.connect_signals();
            this.connect(this.change, () => this._emit_callback());
        }
        _emit_callback() {
            if (this.callback != null) {
                if (types_1.isFunction(this.callback))
                    this.callback(this);
                else
                    this.callback.execute(this, {});
            }
        }
        get is_reversed() {
            return this.start > this.end;
        }
    }
    exports.Range = Range;
    Range.__name__ = "Range";
    Range.init_Range();
},
/* models/glyphs/utils.js */ function _(require, module, exports) {
    const hittest = require(81) /* ../../core/hittest */;
    function generic_line_legend(visuals, ctx, { x0, x1, y0, y1 }, index) {
        ctx.save();
        ctx.beginPath();
        ctx.moveTo(x0, (y0 + y1) / 2);
        ctx.lineTo(x1, (y0 + y1) / 2);
        if (visuals.line.doit) {
            visuals.line.set_vectorize(ctx, index);
            ctx.stroke();
        }
        ctx.restore();
    }
    exports.generic_line_legend = generic_line_legend;
    function generic_area_legend(visuals, ctx, { x0, x1, y0, y1 }, index) {
        const w = Math.abs(x1 - x0);
        const dw = w * 0.1;
        const h = Math.abs(y1 - y0);
        const dh = h * 0.1;
        const sx0 = x0 + dw;
        const sx1 = x1 - dw;
        const sy0 = y0 + dh;
        const sy1 = y1 - dh;
        if (visuals.fill.doit) {
            visuals.fill.set_vectorize(ctx, index);
            ctx.fillRect(sx0, sy0, sx1 - sx0, sy1 - sy0);
        }
        if (visuals.hatch != null && visuals.hatch.doit) {
            visuals.hatch.set_vectorize(ctx, index);
            ctx.fillRect(sx0, sy0, sx1 - sx0, sy1 - sy0);
        }
        if (visuals.line && visuals.line.doit) {
            ctx.beginPath();
            ctx.rect(sx0, sy0, sx1 - sx0, sy1 - sy0);
            visuals.line.set_vectorize(ctx, index);
            ctx.stroke();
        }
    }
    exports.generic_area_legend = generic_area_legend;
    function line_interpolation(renderer, geometry, x2, y2, x3, y3) {
        const { sx, sy } = geometry;
        let x0, x1;
        let y0, y1;
        if (geometry.type == 'point') {
            // The +/- adjustments here are to dilate the hit point into a virtual "segment" to use below
            [y0, y1] = renderer.yscale.r_invert(sy - 1, sy + 1);
            [x0, x1] = renderer.xscale.r_invert(sx - 1, sx + 1);
        }
        else {
            // The +/- adjustments here are to handle cases such as purely horizontal or vertical lines
            if (geometry.direction == 'v') {
                [y0, y1] = renderer.yscale.r_invert(sy, sy);
                [x0, x1] = [Math.min(x2 - 1, x3 - 1), Math.max(x2 + 1, x3 + 1)];
            }
            else {
                [x0, x1] = renderer.xscale.r_invert(sx, sx);
                [y0, y1] = [Math.min(y2 - 1, y3 - 1), Math.max(y2 + 1, y3 + 1)];
            }
        }
        const { x, y } = hittest.check_2_segments_intersect(x0, y0, x1, y1, x2, y2, x3, y3);
        return [x, y]; // XXX: null is not handled at use sites
    }
    exports.line_interpolation = line_interpolation;
},
/* models/glyphs/patch.js */ function _(require, module, exports) {
    const xy_glyph_1 = require(76) /* ./xy_glyph */;
    const utils_1 = require(84) /* ./utils */;
    const hittest = require(81) /* ../../core/hittest */;
    class PatchView extends xy_glyph_1.XYGlyphView {
        _inner_loop(ctx, indices, sx, sy, func) {
            for (const i of indices) {
                if (i == 0) {
                    ctx.beginPath();
                    ctx.moveTo(sx[i], sy[i]);
                    continue;
                }
                else if (isNaN(sx[i] + sy[i])) {
                    ctx.closePath();
                    func.apply(ctx);
                    ctx.beginPath();
                    continue;
                }
                else
                    ctx.lineTo(sx[i], sy[i]);
            }
            ctx.closePath();
            func.call(ctx);
        }
        _render(ctx, indices, { sx, sy }) {
            if (this.visuals.fill.doit) {
                this.visuals.fill.set_value(ctx);
                this._inner_loop(ctx, indices, sx, sy, ctx.fill);
            }
            this.visuals.hatch.doit2(ctx, 0, () => this._inner_loop(ctx, indices, sx, sy, ctx.fill), () => this.renderer.request_render());
            if (this.visuals.line.doit) {
                this.visuals.line.set_value(ctx);
                this._inner_loop(ctx, indices, sx, sy, ctx.stroke);
            }
        }
        draw_legend_for_index(ctx, bbox, index) {
            utils_1.generic_area_legend(this.visuals, ctx, bbox, index);
        }
        _hit_point(geometry) {
            const result = hittest.create_empty_hit_test_result();
            if (hittest.point_in_poly(geometry.sx, geometry.sy, this.sx, this.sy)) {
                result.add_to_selected_glyphs(this.model);
                result.get_view = () => this;
            }
            return result;
        }
    }
    exports.PatchView = PatchView;
    PatchView.__name__ = "PatchView";
    class Patch extends xy_glyph_1.XYGlyph {
        constructor(attrs) {
            super(attrs);
        }
        static init_Patch() {
            this.prototype.default_view = PatchView;
            this.mixins(['line', 'fill', 'hatch']);
        }
    }
    exports.Patch = Patch;
    Patch.__name__ = "Patch";
    Patch.init_Patch();
},
/* models/glyphs/harea.js */ function _(require, module, exports) {
    const area_1 = require(87) /* ./area */;
    const spatial_1 = require(77) /* ../../core/util/spatial */;
    const hittest = require(81) /* ../../core/hittest */;
    const p = require(18) /* ../../core/properties */;
    class HAreaView extends area_1.AreaView {
        _index_data() {
            const points = [];
            for (let i = 0, end = this._x1.length; i < end; i++) {
                const x1 = this._x1[i];
                const x2 = this._x2[i];
                const y = this._y[i];
                if (isNaN(x1 + x2 + y) || !isFinite(x1 + x2 + y))
                    continue;
                points.push({ x0: Math.min(x1, x2), y0: y, x1: Math.max(x1, x2), y1: y, i });
            }
            return new spatial_1.SpatialIndex(points);
        }
        _inner(ctx, sx1, sx2, sy, func) {
            ctx.beginPath();
            for (let i = 0, end = sx1.length; i < end; i++) {
                ctx.lineTo(sx1[i], sy[i]);
            }
            // iterate backwards so that the upper end is below the lower start
            for (let start = sx2.length - 1, i = start; i >= 0; i--) {
                ctx.lineTo(sx2[i], sy[i]);
            }
            ctx.closePath();
            func.call(ctx);
        }
        _render(ctx, _indices, { sx1, sx2, sy }) {
            if (this.visuals.fill.doit) {
                this.visuals.fill.set_value(ctx);
                this._inner(ctx, sx1, sx2, sy, ctx.fill);
            }
            this.visuals.hatch.doit2(ctx, 0, () => this._inner(ctx, sx1, sx2, sy, ctx.fill), () => this.renderer.request_render());
        }
        _hit_point(geometry) {
            const result = hittest.create_empty_hit_test_result();
            const L = this.sy.length;
            const sx = new Float64Array(2 * L);
            const sy = new Float64Array(2 * L);
            for (let i = 0, end = L; i < end; i++) {
                sx[i] = this.sx1[i];
                sy[i] = this.sy[i];
                sx[L + i] = this.sx2[L - i - 1];
                sy[L + i] = this.sy[L - i - 1];
            }
            if (hittest.point_in_poly(geometry.sx, geometry.sy, sx, sy)) {
                result.add_to_selected_glyphs(this.model);
                result.get_view = () => this;
            }
            return result;
        }
        scenterx(i) {
            return (this.sx1[i] + this.sx2[i]) / 2;
        }
        scentery(i) {
            return this.sy[i];
        }
        _map_data() {
            this.sx1 = this.renderer.xscale.v_compute(this._x1);
            this.sx2 = this.renderer.xscale.v_compute(this._x2);
            this.sy = this.renderer.yscale.v_compute(this._y);
        }
    }
    exports.HAreaView = HAreaView;
    HAreaView.__name__ = "HAreaView";
    class HArea extends area_1.Area {
        constructor(attrs) {
            super(attrs);
        }
        static init_HArea() {
            this.prototype.default_view = HAreaView;
            this.define({
                x1: [p.CoordinateSpec],
                x2: [p.CoordinateSpec],
                y: [p.CoordinateSpec],
            });
        }
    }
    exports.HArea = HArea;
    HArea.__name__ = "HArea";
    HArea.init_HArea();
},
/* models/glyphs/area.js */ function _(require, module, exports) {
    const glyph_1 = require(80) /* ./glyph */;
    const utils_1 = require(84) /* ./utils */;
    class AreaView extends glyph_1.GlyphView {
        draw_legend_for_index(ctx, bbox, index) {
            utils_1.generic_area_legend(this.visuals, ctx, bbox, index);
        }
    }
    exports.AreaView = AreaView;
    AreaView.__name__ = "AreaView";
    class Area extends glyph_1.Glyph {
        constructor(attrs) {
            super(attrs);
        }
        static init_Area() {
            this.mixins(['fill', 'hatch']);
        }
    }
    exports.Area = Area;
    Area.__name__ = "Area";
    Area.init_Area();
},
/* models/glyphs/varea.js */ function _(require, module, exports) {
    const area_1 = require(87) /* ./area */;
    const spatial_1 = require(77) /* ../../core/util/spatial */;
    const hittest = require(81) /* ../../core/hittest */;
    const p = require(18) /* ../../core/properties */;
    class VAreaView extends area_1.AreaView {
        _index_data() {
            const points = [];
            for (let i = 0, end = this._x.length; i < end; i++) {
                const x = this._x[i];
                const y1 = this._y1[i];
                const y2 = this._y2[i];
                if (isNaN(x + y1 + y2) || !isFinite(x + y1 + y2))
                    continue;
                points.push({ x0: x, y0: Math.min(y1, y2), x1: x, y1: Math.max(y1, y2), i });
            }
            return new spatial_1.SpatialIndex(points);
        }
        _inner(ctx, sx, sy1, sy2, func) {
            ctx.beginPath();
            for (let i = 0, end = sy1.length; i < end; i++) {
                ctx.lineTo(sx[i], sy1[i]);
            }
            // iterate backwards so that the upper end is below the lower start
            for (let start = sy2.length - 1, i = start; i >= 0; i--) {
                ctx.lineTo(sx[i], sy2[i]);
            }
            ctx.closePath();
            func.call(ctx);
        }
        _render(ctx, _indices, { sx, sy1, sy2 }) {
            if (this.visuals.fill.doit) {
                this.visuals.fill.set_value(ctx);
                this._inner(ctx, sx, sy1, sy2, ctx.fill);
            }
            this.visuals.hatch.doit2(ctx, 0, () => this._inner(ctx, sx, sy1, sy2, ctx.fill), () => this.renderer.request_render());
        }
        scenterx(i) {
            return this.sx[i];
        }
        scentery(i) {
            return (this.sy1[i] + this.sy2[i]) / 2;
        }
        _hit_point(geometry) {
            const result = hittest.create_empty_hit_test_result();
            const L = this.sx.length;
            const sx = new Float64Array(2 * L);
            const sy = new Float64Array(2 * L);
            for (let i = 0, end = L; i < end; i++) {
                sx[i] = this.sx[i];
                sy[i] = this.sy1[i];
                sx[L + i] = this.sx[L - i - 1];
                sy[L + i] = this.sy2[L - i - 1];
            }
            if (hittest.point_in_poly(geometry.sx, geometry.sy, sx, sy)) {
                result.add_to_selected_glyphs(this.model);
                result.get_view = () => this;
            }
            return result;
        }
        _map_data() {
            this.sx = this.renderer.xscale.v_compute(this._x);
            this.sy1 = this.renderer.yscale.v_compute(this._y1);
            this.sy2 = this.renderer.yscale.v_compute(this._y2);
        }
    }
    exports.VAreaView = VAreaView;
    VAreaView.__name__ = "VAreaView";
    class VArea extends area_1.Area {
        constructor(attrs) {
            super(attrs);
        }
        static init_VArea() {
            this.prototype.default_view = VAreaView;
            this.define({
                x: [p.CoordinateSpec],
                y1: [p.CoordinateSpec],
                y2: [p.CoordinateSpec],
            });
        }
    }
    exports.VArea = VArea;
    VArea.__name__ = "VArea";
    VArea.init_VArea();
},
/* models/sources/cds_view.js */ function _(require, module, exports) {
    const model_1 = require(64) /* ../../model */;
    const p = require(18) /* ../../core/properties */;
    const selection_1 = require(71) /* ../selections/selection */;
    const array_1 = require(8) /* ../../core/util/array */;
    const columnar_data_source_1 = require(69) /* ./columnar_data_source */;
    class CDSView extends model_1.Model {
        constructor(attrs) {
            super(attrs);
        }
        static init_CDSView() {
            this.define({
                filters: [p.Array, []],
                source: [p.Instance],
            });
            this.internal({
                indices: [p.Array, []],
                indices_map: [p.Any, {}],
            });
        }
        initialize() {
            super.initialize();
            this.compute_indices();
        }
        connect_signals() {
            super.connect_signals();
            this.connect(this.properties.filters.change, () => {
                this.compute_indices();
                this.change.emit();
            });
            const connect_listeners = () => {
                const fn = () => this.compute_indices();
                if (this.source != null) {
                    this.connect(this.source.change, fn);
                    if (this.source instanceof columnar_data_source_1.ColumnarDataSource) {
                        this.connect(this.source.streaming, fn);
                        this.connect(this.source.patching, fn);
                    }
                }
            };
            let initialized = this.source != null;
            if (initialized)
                connect_listeners();
            else {
                this.connect(this.properties.source.change, () => {
                    if (!initialized) {
                        connect_listeners();
                        initialized = true;
                    }
                });
            }
        }
        compute_indices() {
            const indices = this.filters
                .map((filter) => filter.compute_indices(this.source))
                .filter((indices) => indices != null);
            if (indices.length > 0)
                this.indices = array_1.intersection.apply(this, indices);
            else if (this.source instanceof columnar_data_source_1.ColumnarDataSource)
                this.indices = this.source.get_indices();
            this.indices_map_to_subset();
        }
        indices_map_to_subset() {
            this.indices_map = {};
            for (let i = 0; i < this.indices.length; i++) {
                this.indices_map[this.indices[i]] = i;
            }
        }
        convert_selection_from_subset(selection_subset) {
            const selection_full = new selection_1.Selection();
            selection_full.update_through_union(selection_subset);
            const indices_1d = selection_subset.indices.map((i) => this.indices[i]);
            selection_full.indices = indices_1d;
            selection_full.image_indices = selection_subset.image_indices;
            return selection_full;
        }
        convert_selection_to_subset(selection_full) {
            const selection_subset = new selection_1.Selection();
            selection_subset.update_through_union(selection_full);
            const indices_1d = selection_full.indices.map((i) => this.indices_map[i]);
            selection_subset.indices = indices_1d;
            selection_subset.image_indices = selection_full.image_indices;
            return selection_subset;
        }
        convert_indices_from_subset(indices) {
            return indices.map((i) => this.indices[i]);
        }
    }
    exports.CDSView = CDSView;
    CDSView.__name__ = "CDSView";
    CDSView.init_CDSView();
},
/* models/renderers/graph_renderer.js */ function _(require, module, exports) {
    const data_renderer_1 = require(74) /* ./data_renderer */;
    const graph_hit_test_policy_1 = require(91) /* ../graphs/graph_hit_test_policy */;
    const p = require(18) /* ../../core/properties */;
    const build_views_1 = require(92) /* ../../core/build_views */;
    class GraphRendererView extends data_renderer_1.DataRendererView {
        initialize() {
            super.initialize();
            this.xscale = this.plot_view.frame.xscales.default;
            this.yscale = this.plot_view.frame.yscales.default;
            this._renderer_views = {};
            [this.node_view, this.edge_view] = build_views_1.build_views(this._renderer_views, [
                this.model.node_renderer,
                this.model.edge_renderer,
            ], { parent: this.parent });
            this.set_data();
        }
        connect_signals() {
            super.connect_signals();
            this.connect(this.model.layout_provider.change, () => this.set_data());
            this.connect(this.model.node_renderer.data_source._select, () => this.set_data());
            this.connect(this.model.node_renderer.data_source.inspect, () => this.set_data());
            this.connect(this.model.node_renderer.data_source.change, () => this.set_data());
            this.connect(this.model.edge_renderer.data_source._select, () => this.set_data());
            this.connect(this.model.edge_renderer.data_source.inspect, () => this.set_data());
            this.connect(this.model.edge_renderer.data_source.change, () => this.set_data());
            const { x_ranges, y_ranges } = this.plot_view.frame;
            for (const name in x_ranges) {
                const rng = x_ranges[name];
                this.connect(rng.change, () => this.set_data());
            }
            for (const name in y_ranges) {
                const rng = y_ranges[name];
                this.connect(rng.change, () => this.set_data());
            }
        }
        set_data(request_render = true) {
            // TODO (bev) this is a bit clunky, need to make sure glyphs use the correct ranges when they call
            // mapping functions on the base Renderer class
            this.node_view.glyph.model.setv({ x_range_name: this.model.x_range_name, y_range_name: this.model.y_range_name }, { silent: true });
            this.edge_view.glyph.model.setv({ x_range_name: this.model.x_range_name, y_range_name: this.model.y_range_name }, { silent: true });
            // XXX
            const node_glyph = this.node_view.glyph;
            [node_glyph._x, node_glyph._y] =
                this.model.layout_provider.get_node_coordinates(this.model.node_renderer.data_source);
            const edge_glyph = this.edge_view.glyph;
            [edge_glyph._xs, edge_glyph._ys] =
                this.model.layout_provider.get_edge_coordinates(this.model.edge_renderer.data_source);
            node_glyph.index_data();
            edge_glyph.index_data();
            if (request_render)
                this.request_render();
        }
        render() {
            this.edge_view.render();
            this.node_view.render();
        }
    }
    exports.GraphRendererView = GraphRendererView;
    GraphRendererView.__name__ = "GraphRendererView";
    class GraphRenderer extends data_renderer_1.DataRenderer {
        constructor(attrs) {
            super(attrs);
        }
        static init_GraphRenderer() {
            this.prototype.default_view = GraphRendererView;
            this.define({
                layout_provider: [p.Instance],
                node_renderer: [p.Instance],
                edge_renderer: [p.Instance],
                selection_policy: [p.Instance, () => new graph_hit_test_policy_1.NodesOnly()],
                inspection_policy: [p.Instance, () => new graph_hit_test_policy_1.NodesOnly()],
            });
        }
        get_selection_manager() {
            return this.node_renderer.data_source.selection_manager;
        }
    }
    exports.GraphRenderer = GraphRenderer;
    GraphRenderer.__name__ = "GraphRenderer";
    GraphRenderer.init_GraphRenderer();
},
/* models/graphs/graph_hit_test_policy.js */ function _(require, module, exports) {
    const model_1 = require(64) /* ../../model */;
    const arrayable_1 = require(11) /* ../../core/util/arrayable */;
    const array_1 = require(8) /* ../../core/util/array */;
    const hittest_1 = require(81) /* ../../core/hittest */;
    class GraphHitTestPolicy extends model_1.Model {
        constructor(attrs) {
            super(attrs);
        }
        _hit_test_nodes(geometry, graph_view) {
            if (!graph_view.model.visible)
                return null;
            const hit_test_result = graph_view.node_view.glyph.hit_test(geometry);
            if (hit_test_result == null)
                return null;
            else
                return graph_view.node_view.model.view.convert_selection_from_subset(hit_test_result);
        }
        _hit_test_edges(geometry, graph_view) {
            if (!graph_view.model.visible)
                return null;
            const hit_test_result = graph_view.edge_view.glyph.hit_test(geometry);
            if (hit_test_result == null)
                return null;
            else
                return graph_view.edge_view.model.view.convert_selection_from_subset(hit_test_result);
        }
    }
    exports.GraphHitTestPolicy = GraphHitTestPolicy;
    GraphHitTestPolicy.__name__ = "GraphHitTestPolicy";
    class NodesOnly extends GraphHitTestPolicy {
        constructor(attrs) {
            super(attrs);
        }
        hit_test(geometry, graph_view) {
            return this._hit_test_nodes(geometry, graph_view);
        }
        do_selection(hit_test_result, graph, final, append) {
            if (hit_test_result == null)
                return false;
            const node_selection = graph.node_renderer.data_source.selected;
            node_selection.update(hit_test_result, final, append);
            graph.node_renderer.data_source._select.emit();
            return !node_selection.is_empty();
        }
        do_inspection(hit_test_result, geometry, graph_view, final, append) {
            if (hit_test_result == null)
                return false;
            const node_inspection = graph_view.model.get_selection_manager().get_or_create_inspector(graph_view.node_view.model);
            node_inspection.update(hit_test_result, final, append);
            // silently set inspected attr to avoid triggering data_source.change event and rerender
            graph_view.node_view.model.data_source.setv({ inspected: node_inspection }, { silent: true });
            graph_view.node_view.model.data_source.inspect.emit([graph_view.node_view, { geometry }]);
            return !node_inspection.is_empty();
        }
    }
    exports.NodesOnly = NodesOnly;
    NodesOnly.__name__ = "NodesOnly";
    class NodesAndLinkedEdges extends GraphHitTestPolicy {
        constructor(attrs) {
            super(attrs);
        }
        hit_test(geometry, graph_view) {
            return this._hit_test_nodes(geometry, graph_view);
        }
        get_linked_edges(node_source, edge_source, mode) {
            let node_indices = [];
            if (mode == 'selection') {
                node_indices = node_source.selected.indices.map((i) => node_source.data.index[i]);
            }
            else if (mode == 'inspection') {
                node_indices = node_source.inspected.indices.map((i) => node_source.data.index[i]);
            }
            const edge_indices = [];
            for (let i = 0; i < edge_source.data.start.length; i++) {
                if (array_1.contains(node_indices, edge_source.data.start[i]) || array_1.contains(node_indices, edge_source.data.end[i]))
                    edge_indices.push(i);
            }
            const linked_edges = hittest_1.create_empty_hit_test_result();
            for (const i of edge_indices) {
                linked_edges.multiline_indices[i] = [0]; //currently only supports 2-element multilines, so this is all of it
            }
            linked_edges.indices = edge_indices;
            return linked_edges;
        }
        do_selection(hit_test_result, graph, final, append) {
            if (hit_test_result == null)
                return false;
            const node_selection = graph.node_renderer.data_source.selected;
            node_selection.update(hit_test_result, final, append);
            const edge_selection = graph.edge_renderer.data_source.selected;
            const linked_edges_selection = this.get_linked_edges(graph.node_renderer.data_source, graph.edge_renderer.data_source, 'selection');
            edge_selection.update(linked_edges_selection, final, append);
            graph.node_renderer.data_source._select.emit();
            return !node_selection.is_empty();
        }
        do_inspection(hit_test_result, geometry, graph_view, final, append) {
            if (hit_test_result == null)
                return false;
            const node_inspection = graph_view.node_view.model.data_source.selection_manager.get_or_create_inspector(graph_view.node_view.model);
            node_inspection.update(hit_test_result, final, append);
            graph_view.node_view.model.data_source.setv({ inspected: node_inspection }, { silent: true });
            const edge_inspection = graph_view.edge_view.model.data_source.selection_manager.get_or_create_inspector(graph_view.edge_view.model);
            const linked_edges = this.get_linked_edges(graph_view.node_view.model.data_source, graph_view.edge_view.model.data_source, 'inspection');
            edge_inspection.update(linked_edges, final, append);
            //silently set inspected attr to avoid triggering data_source.change event and rerender
            graph_view.edge_view.model.data_source.setv({ inspected: edge_inspection }, { silent: true });
            graph_view.node_view.model.data_source.inspect.emit([graph_view.node_view, { geometry }]);
            return !node_inspection.is_empty();
        }
    }
    exports.NodesAndLinkedEdges = NodesAndLinkedEdges;
    NodesAndLinkedEdges.__name__ = "NodesAndLinkedEdges";
    class EdgesAndLinkedNodes extends GraphHitTestPolicy {
        constructor(attrs) {
            super(attrs);
        }
        hit_test(geometry, graph_view) {
            return this._hit_test_edges(geometry, graph_view);
        }
        get_linked_nodes(node_source, edge_source, mode) {
            let edge_indices = [];
            if (mode == 'selection')
                edge_indices = edge_source.selected.indices;
            else if (mode == 'inspection')
                edge_indices = edge_source.inspected.indices;
            const nodes = [];
            for (const i of edge_indices) {
                nodes.push(edge_source.data.start[i]);
                nodes.push(edge_source.data.end[i]);
            }
            const node_indices = array_1.uniq(nodes).map((i) => arrayable_1.indexOf(node_source.data.index, i));
            const linked_nodes = hittest_1.create_empty_hit_test_result();
            linked_nodes.indices = node_indices;
            return linked_nodes;
        }
        do_selection(hit_test_result, graph, final, append) {
            if (hit_test_result == null)
                return false;
            const edge_selection = graph.edge_renderer.data_source.selected;
            edge_selection.update(hit_test_result, final, append);
            const node_selection = graph.node_renderer.data_source.selected;
            const linked_nodes = this.get_linked_nodes(graph.node_renderer.data_source, graph.edge_renderer.data_source, 'selection');
            node_selection.update(linked_nodes, final, append);
            graph.edge_renderer.data_source._select.emit();
            return !edge_selection.is_empty();
        }
        do_inspection(hit_test_result, geometry, graph_view, final, append) {
            if (hit_test_result == null)
                return false;
            const edge_inspection = graph_view.edge_view.model.data_source.selection_manager.get_or_create_inspector(graph_view.edge_view.model);
            edge_inspection.update(hit_test_result, final, append);
            graph_view.edge_view.model.data_source.setv({ inspected: edge_inspection }, { silent: true });
            const node_inspection = graph_view.node_view.model.data_source.selection_manager.get_or_create_inspector(graph_view.node_view.model);
            const linked_nodes = this.get_linked_nodes(graph_view.node_view.model.data_source, graph_view.edge_view.model.data_source, 'inspection');
            node_inspection.update(linked_nodes, final, append);
            // silently set inspected attr to avoid triggering data_source.change event and rerender
            graph_view.node_view.model.data_source.setv({ inspected: node_inspection }, { silent: true });
            graph_view.edge_view.model.data_source.inspect.emit([graph_view.edge_view, { geometry }]);
            return !edge_inspection.is_empty();
        }
    }
    exports.EdgesAndLinkedNodes = EdgesAndLinkedNodes;
    EdgesAndLinkedNodes.__name__ = "EdgesAndLinkedNodes";
},
/* core/build_views.js */ function _(require, module, exports) {
    const array_1 = require(8) /* ./util/array */;
    function build_views(view_storage, models, options, cls = (model) => model.default_view) {
        const to_remove = array_1.difference(Object.keys(view_storage), models.map((model) => model.id));
        for (const model_id of to_remove) {
            view_storage[model_id].remove();
            delete view_storage[model_id];
        }
        const created_views = [];
        const new_models = models.filter((model) => view_storage[model.id] == null);
        for (const model of new_models) {
            const view_cls = cls(model);
            const view_options = Object.assign(Object.assign({}, options), { model, connect_signals: false });
            const view = new view_cls(view_options);
            view_storage[model.id] = view;
            created_views.push(view);
        }
        for (const view of created_views)
            view.connect_signals();
        return created_views;
    }
    exports.build_views = build_views;
    function remove_views(view_storage) {
        for (const id in view_storage) {
            view_storage[id].remove();
            delete view_storage[id];
        }
    }
    exports.remove_views = remove_views;
},
/* models/selections/interaction_policy.js */ function _(require, module, exports) {
    const model_1 = require(64) /* ../../model */;
    class SelectionPolicy extends model_1.Model {
        do_selection(hit_test_result, source, final, append) {
            if (hit_test_result === null) {
                return false;
            }
            else {
                source.selected.update(hit_test_result, final, append);
                source._select.emit();
                return !source.selected.is_empty();
            }
        }
    }
    exports.SelectionPolicy = SelectionPolicy;
    SelectionPolicy.__name__ = "SelectionPolicy";
    class IntersectRenderers extends SelectionPolicy {
        hit_test(geometry, renderer_views) {
            const hit_test_result_renderers = [];
            for (const r of renderer_views) {
                const result = r.hit_test(geometry);
                if (result !== null)
                    hit_test_result_renderers.push(result);
            }
            if (hit_test_result_renderers.length > 0) {
                const hit_test_result = hit_test_result_renderers[0];
                for (const hit_test_result_other of hit_test_result_renderers) {
                    hit_test_result.update_through_intersection(hit_test_result_other);
                }
                return hit_test_result;
            }
            else {
                return null;
            }
        }
    }
    exports.IntersectRenderers = IntersectRenderers;
    IntersectRenderers.__name__ = "IntersectRenderers";
    class UnionRenderers extends SelectionPolicy {
        hit_test(geometry, renderer_views) {
            const hit_test_result_renderers = [];
            for (const r of renderer_views) {
                const result = r.hit_test(geometry);
                if (result !== null)
                    hit_test_result_renderers.push(result);
            }
            if (hit_test_result_renderers.length > 0) {
                const hit_test_result = hit_test_result_renderers[0];
                for (const hit_test_result_other of hit_test_result_renderers) {
                    hit_test_result.update_through_union(hit_test_result_other);
                }
                return hit_test_result;
            }
            else {
                return null;
            }
        }
    }
    exports.UnionRenderers = UnionRenderers;
    UnionRenderers.__name__ = "UnionRenderers";
},
/* core/util/serialization.js */ function _(require, module, exports) {
    const types_1 = require(7) /* ./types */;
    const compat_1 = require(95) /* ./compat */;
    exports.ARRAY_TYPES = {
        uint8: Uint8Array,
        int8: Int8Array,
        uint16: Uint16Array,
        int16: Int16Array,
        uint32: Uint32Array,
        int32: Int32Array,
        float32: Float32Array,
        float64: Float64Array,
    };
    exports.DTYPES = {
        Uint8Array: "uint8",
        Int8Array: "int8",
        Uint16Array: "uint16",
        Int16Array: "int16",
        Uint32Array: "uint32",
        Int32Array: "int32",
        Float32Array: "float32",
        Float64Array: "float64",
    };
    function arrayName(array) {
        if ("name" in array.constructor)
            return array.constructor.name;
        else {
            switch (true) {
                case array instanceof Uint8Array: return "Uint8Array";
                case array instanceof Int8Array: return "Int8Array";
                case array instanceof Uint16Array: return "Uint16Array";
                case array instanceof Int16Array: return "Int16Array";
                case array instanceof Uint32Array: return "Uint32Array";
                case array instanceof Int32Array: return "Int32Array";
                case array instanceof Float32Array: return "Float32Array";
                case array instanceof Float64Array: return "Float64Array";
                default:
                    throw new Error("unsupported typed array");
            }
        }
    }
    exports.BYTE_ORDER = compat_1.is_little_endian ? "little" : "big";
    function swap16(a) {
        const x = new Uint8Array(a.buffer, a.byteOffset, a.length * 2);
        for (let i = 0, end = x.length; i < end; i += 2) {
            const t = x[i];
            x[i] = x[i + 1];
            x[i + 1] = t;
        }
    }
    exports.swap16 = swap16;
    function swap32(a) {
        const x = new Uint8Array(a.buffer, a.byteOffset, a.length * 4);
        for (let i = 0, end = x.length; i < end; i += 4) {
            let t = x[i];
            x[i] = x[i + 3];
            x[i + 3] = t;
            t = x[i + 1];
            x[i + 1] = x[i + 2];
            x[i + 2] = t;
        }
    }
    exports.swap32 = swap32;
    function swap64(a) {
        const x = new Uint8Array(a.buffer, a.byteOffset, a.length * 8);
        for (let i = 0, end = x.length; i < end; i += 8) {
            let t = x[i];
            x[i] = x[i + 7];
            x[i + 7] = t;
            t = x[i + 1];
            x[i + 1] = x[i + 6];
            x[i + 6] = t;
            t = x[i + 2];
            x[i + 2] = x[i + 5];
            x[i + 5] = t;
            t = x[i + 3];
            x[i + 3] = x[i + 4];
            x[i + 4] = t;
        }
    }
    exports.swap64 = swap64;
    function process_buffer(specification, buffers) {
        const need_swap = specification.order !== exports.BYTE_ORDER;
        const { shape } = specification;
        let bytes = null;
        for (const buf of buffers) {
            const header = JSON.parse(buf[0]);
            if (header.id === specification.__buffer__) {
                bytes = buf[1];
                break;
            }
        }
        const arr = new (exports.ARRAY_TYPES[specification.dtype])(bytes);
        if (need_swap) {
            if (arr.BYTES_PER_ELEMENT === 2) {
                swap16(arr);
            }
            else if (arr.BYTES_PER_ELEMENT === 4) {
                swap32(arr);
            }
            else if (arr.BYTES_PER_ELEMENT === 8) {
                swap64(arr);
            }
        }
        return [arr, shape];
    }
    exports.process_buffer = process_buffer;
    function process_array(obj, buffers) {
        if (types_1.isObject(obj) && '__ndarray__' in obj)
            return decode_base64(obj);
        else if (types_1.isObject(obj) && '__buffer__' in obj)
            return process_buffer(obj, buffers);
        else if (types_1.isArray(obj) || types_1.isTypedArray(obj))
            return [obj, []];
        else
            return undefined;
    }
    exports.process_array = process_array;
    function arrayBufferToBase64(buffer) {
        const bytes = new Uint8Array(buffer);
        const chars = Array.from(bytes).map((b) => String.fromCharCode(b));
        return btoa(chars.join(""));
    }
    exports.arrayBufferToBase64 = arrayBufferToBase64;
    function base64ToArrayBuffer(base64) {
        const binary_string = atob(base64);
        const len = binary_string.length;
        const bytes = new Uint8Array(len);
        for (let i = 0, end = len; i < end; i++) {
            bytes[i] = binary_string.charCodeAt(i);
        }
        return bytes.buffer;
    }
    exports.base64ToArrayBuffer = base64ToArrayBuffer;
    function decode_base64(input) {
        const bytes = base64ToArrayBuffer(input.__ndarray__);
        const dtype = input.dtype;
        const shape = input.shape;
        let array;
        if (dtype in exports.ARRAY_TYPES)
            array = new (exports.ARRAY_TYPES[dtype])(bytes);
        else
            throw new Error(`unknown dtype: ${dtype}`);
        return [array, shape];
    }
    exports.decode_base64 = decode_base64;
    function encode_base64(array, shape) {
        const b64 = arrayBufferToBase64(array.buffer);
        const name = arrayName(array);
        let dtype;
        if (name in exports.DTYPES)
            dtype = exports.DTYPES[name];
        else
            throw new Error(`unknown array type: ${name}`);
        const data = {
            __ndarray__: b64,
            shape,
            dtype,
        };
        return data;
    }
    exports.encode_base64 = encode_base64;
    function decode_traverse_data(v, buffers) {
        // v is just a regular array of scalars
        if (v.length == 0 || !(types_1.isObject(v[0]) || types_1.isArray(v[0]))) {
            return [v, []];
        }
        const arrays = [];
        const shapes = [];
        for (const obj of v) {
            const [arr, shape] = types_1.isArray(obj) ? decode_traverse_data(obj, buffers)
                : process_array(obj, buffers);
            arrays.push(arr);
            shapes.push(shape);
        }
        // If there is a list of empty lists, reduce that to just a list
        const filtered_shapes = shapes.map((shape) => shape.filter((v) => v.length != 0));
        return [arrays, filtered_shapes];
    }
    function decode_column_data(data, buffers = []) {
        const new_data = {};
        const new_shapes = {};
        for (const k in data) {
            // might be array of scalars, or might be ragged array or arrays
            const v = data[k];
            if (types_1.isArray(v)) {
                // v is just a regular array of scalars
                if (v.length == 0 || !(types_1.isObject(v[0]) || types_1.isArray(v[0]))) {
                    new_data[k] = v;
                    continue;
                }
                // v is a ragged array of arrays
                const [arrays, shapes] = decode_traverse_data(v, buffers);
                new_data[k] = arrays;
                new_shapes[k] = shapes;
                // must be object or array (single array case)
            }
            else {
                const [arr, shape] = process_array(v, buffers);
                new_data[k] = arr;
                new_shapes[k] = shape;
            }
        }
        return [new_data, new_shapes];
    }
    exports.decode_column_data = decode_column_data;
    function encode_traverse_data(v, shapes) {
        const new_array = [];
        for (let i = 0, end = v.length; i < end; i++) {
            const item = v[i];
            if (types_1.isTypedArray(item)) {
                const shape = shapes[i] ? shapes[i] : undefined;
                new_array.push(encode_base64(item, shape));
            }
            else if (types_1.isArray(item)) {
                new_array.push(encode_traverse_data(item, shapes ? shapes[i] : []));
            }
            else
                new_array.push(item);
        }
        return new_array;
    }
    function encode_column_data(data, shapes) {
        const new_data = {};
        for (const k in data) {
            const v = data[k];
            const shapes_k = shapes != null ? shapes[k] : undefined;
            let new_v;
            if (types_1.isTypedArray(v)) {
                new_v = encode_base64(v, shapes_k);
            }
            else if (types_1.isArray(v)) {
                new_v = encode_traverse_data(v, shapes_k || []);
            }
            else
                new_v = v;
            new_data[k] = new_v;
        }
        return new_data;
    }
    exports.encode_column_data = encode_column_data;
},
/* core/util/compat.js */ function _(require, module, exports) {
    exports.is_ie = (() => {
        const ua = typeof navigator !== "undefined" ? navigator.userAgent : "";
        return ua.indexOf('MSIE') >= 0 || ua.indexOf('Trident') > 0 || ua.indexOf('Edge') > 0;
    })();
    exports.is_mobile = (() => {
        return typeof window !== "undefined" && ("ontouchstart" in window || navigator.maxTouchPoints > 0);
    })();
    exports.is_little_endian = (() => {
        const buf = new ArrayBuffer(4);
        const buf8 = new Uint8Array(buf);
        const buf32 = new Uint32Array(buf);
        buf32[1] = 0x0a0b0c0d;
        let little_endian = true;
        if (buf8[4] == 0x0a && buf8[5] == 0x0b && buf8[6] == 0x0c && buf8[7] == 0x0d) {
            little_endian = false;
        }
        return little_endian;
    })();
},
/* core/util/typed_array.js */ function _(require, module, exports) {
    function concat(array0, ...arrays) {
        let n = array0.length;
        for (const array of arrays)
            n += array.length;
        const result = new array0.constructor(n);
        result.set(array0, 0);
        let i = array0.length;
        for (const array of arrays) {
            result.set(array, i);
            i += array.length;
        }
        return result;
    }
    exports.concat = concat;
},
/* document/events.js */ function _(require, module, exports) {
    const has_props_1 = require(12) /* ../core/has_props */;
    class DocumentChangedEvent {
        constructor(document) {
            this.document = document;
        }
    }
    exports.DocumentChangedEvent = DocumentChangedEvent;
    DocumentChangedEvent.__name__ = "DocumentChangedEvent";
    class ModelChangedEvent extends DocumentChangedEvent {
        constructor(document, model, attr, old, new_, setter_id, hint) {
            super(document);
            this.model = model;
            this.attr = attr;
            this.old = old;
            this.new_ = new_;
            this.setter_id = setter_id;
            this.hint = hint;
        }
        json(references) {
            if (this.attr === "id") {
                throw new Error("'id' field should never change, whatever code just set it is wrong");
            }
            if (this.hint != null)
                return this.hint.json(references);
            const value = this.new_;
            const value_json = has_props_1.HasProps._value_to_json(this.attr, value, this.model);
            const value_refs = {};
            has_props_1.HasProps._value_record_references(value, value_refs, true); // true = recurse
            if (this.model.id in value_refs && this.model !== value) {
                // we know we don't want a whole new copy of the obj we're
                // patching unless it's also the value itself
                delete value_refs[this.model.id];
            }
            for (const id in value_refs) {
                references[id] = value_refs[id];
            }
            return {
                kind: "ModelChanged",
                model: this.model.ref(),
                attr: this.attr,
                new: value_json,
            };
        }
    }
    exports.ModelChangedEvent = ModelChangedEvent;
    ModelChangedEvent.__name__ = "ModelChangedEvent";
    class ColumnsPatchedEvent extends DocumentChangedEvent {
        constructor(document, column_source, patches) {
            super(document);
            this.column_source = column_source;
            this.patches = patches;
        }
        json(_references) {
            return {
                kind: "ColumnsPatched",
                column_source: this.column_source,
                patches: this.patches,
            };
        }
    }
    exports.ColumnsPatchedEvent = ColumnsPatchedEvent;
    ColumnsPatchedEvent.__name__ = "ColumnsPatchedEvent";
    class ColumnsStreamedEvent extends DocumentChangedEvent {
        constructor(document, column_source, data, rollover) {
            super(document);
            this.column_source = column_source;
            this.data = data;
            this.rollover = rollover;
        }
        json(_references) {
            return {
                kind: "ColumnsStreamed",
                column_source: this.column_source,
                data: this.data,
                rollover: this.rollover,
            };
        }
    }
    exports.ColumnsStreamedEvent = ColumnsStreamedEvent;
    ColumnsStreamedEvent.__name__ = "ColumnsStreamedEvent";
    class TitleChangedEvent extends DocumentChangedEvent {
        constructor(document, title, setter_id) {
            super(document);
            this.title = title;
            this.setter_id = setter_id;
        }
        json(_references) {
            return {
                kind: "TitleChanged",
                title: this.title,
            };
        }
    }
    exports.TitleChangedEvent = TitleChangedEvent;
    TitleChangedEvent.__name__ = "TitleChangedEvent";
    class RootAddedEvent extends DocumentChangedEvent {
        constructor(document, model, setter_id) {
            super(document);
            this.model = model;
            this.setter_id = setter_id;
        }
        json(references) {
            has_props_1.HasProps._value_record_references(this.model, references, true);
            return {
                kind: "RootAdded",
                model: this.model.ref(),
            };
        }
    }
    exports.RootAddedEvent = RootAddedEvent;
    RootAddedEvent.__name__ = "RootAddedEvent";
    class RootRemovedEvent extends DocumentChangedEvent {
        constructor(document, model, setter_id) {
            super(document);
            this.model = model;
            this.setter_id = setter_id;
        }
        json(_references) {
            return {
                kind: "RootRemoved",
                model: this.model.ref(),
            };
        }
    }
    exports.RootRemovedEvent = RootRemovedEvent;
    RootRemovedEvent.__name__ = "RootRemovedEvent";
},
/* models/annotations/band.js */ function _(require, module, exports) {
    const annotation_1 = require(29) /* ./annotation */;
    const column_data_source_1 = require(68) /* ../sources/column_data_source */;
    const p = require(18) /* ../../core/properties */;
    class BandView extends annotation_1.AnnotationView {
        initialize() {
            super.initialize();
            this.set_data(this.model.source);
        }
        connect_signals() {
            super.connect_signals();
            this.connect(this.model.source.streaming, () => this.set_data(this.model.source));
            this.connect(this.model.source.patching, () => this.set_data(this.model.source));
            this.connect(this.model.source.change, () => this.set_data(this.model.source));
        }
        set_data(source) {
            super.set_data(source);
            this.visuals.warm_cache(source);
            this.plot_view.request_render();
        }
        _map_data() {
            const { frame } = this.plot_view;
            const dim = this.model.dimension;
            const xscale = frame.xscales[this.model.x_range_name];
            const yscale = frame.yscales[this.model.y_range_name];
            const limit_scale = dim == "height" ? yscale : xscale;
            const base_scale = dim == "height" ? xscale : yscale;
            const limit_view = dim == "height" ? frame.yview : frame.xview;
            const base_view = dim == "height" ? frame.xview : frame.yview;
            let _lower_sx;
            if (this.model.properties.lower.units == "data")
                _lower_sx = limit_scale.v_compute(this._lower);
            else
                _lower_sx = limit_view.v_compute(this._lower);
            let _upper_sx;
            if (this.model.properties.upper.units == "data")
                _upper_sx = limit_scale.v_compute(this._upper);
            else
                _upper_sx = limit_view.v_compute(this._upper);
            let _base_sx;
            if (this.model.properties.base.units == "data")
                _base_sx = base_scale.v_compute(this._base);
            else
                _base_sx = base_view.v_compute(this._base);
            const [i, j] = dim == 'height' ? [1, 0] : [0, 1];
            const _lower = [_lower_sx, _base_sx];
            const _upper = [_upper_sx, _base_sx];
            this._lower_sx = _lower[i];
            this._lower_sy = _lower[j];
            this._upper_sx = _upper[i];
            this._upper_sy = _upper[j];
        }
        render() {
            if (!this.model.visible)
                return;
            this._map_data();
            const { ctx } = this.plot_view.canvas_view;
            // Draw the band body
            ctx.beginPath();
            ctx.moveTo(this._lower_sx[0], this._lower_sy[0]);
            for (let i = 0, end = this._lower_sx.length; i < end; i++) {
                ctx.lineTo(this._lower_sx[i], this._lower_sy[i]);
            }
            // iterate backwards so that the upper end is below the lower start
            for (let start = this._upper_sx.length - 1, i = start; i >= 0; i--) {
                ctx.lineTo(this._upper_sx[i], this._upper_sy[i]);
            }
            ctx.closePath();
            if (this.visuals.fill.doit) {
                this.visuals.fill.set_value(ctx);
                ctx.fill();
            }
            // Draw the lower band edge
            ctx.beginPath();
            ctx.moveTo(this._lower_sx[0], this._lower_sy[0]);
            for (let i = 0, end = this._lower_sx.length; i < end; i++) {
                ctx.lineTo(this._lower_sx[i], this._lower_sy[i]);
            }
            if (this.visuals.line.doit) {
                this.visuals.line.set_value(ctx);
                ctx.stroke();
            }
            // Draw the upper band edge
            ctx.beginPath();
            ctx.moveTo(this._upper_sx[0], this._upper_sy[0]);
            for (let i = 0, end = this._upper_sx.length; i < end; i++) {
                ctx.lineTo(this._upper_sx[i], this._upper_sy[i]);
            }
            if (this.visuals.line.doit) {
                this.visuals.line.set_value(ctx);
                ctx.stroke();
            }
        }
    }
    exports.BandView = BandView;
    BandView.__name__ = "BandView";
    class Band extends annotation_1.Annotation {
        constructor(attrs) {
            super(attrs);
        }
        static init_Band() {
            this.prototype.default_view = BandView;
            this.mixins(['line', 'fill']);
            this.define({
                lower: [p.DistanceSpec],
                upper: [p.DistanceSpec],
                base: [p.DistanceSpec],
                dimension: [p.Dimension, 'height'],
                source: [p.Instance, () => new column_data_source_1.ColumnDataSource()],
                x_range_name: [p.String, 'default'],
                y_range_name: [p.String, 'default'],
            });
            this.override({
                fill_color: "#fff9ba",
                fill_alpha: 0.4,
                line_color: "#cccccc",
                line_alpha: 0.3,
            });
        }
    }
    exports.Band = Band;
    Band.__name__ = "Band";
    Band.init_Band();
},
/* models/annotations/box_annotation.js */ function _(require, module, exports) {
    const annotation_1 = require(29) /* ./annotation */;
    const signaling_1 = require(13) /* ../../core/signaling */;
    const dom_1 = require(61) /* ../../core/dom */;
    const p = require(18) /* ../../core/properties */;
    const bbox_1 = require(79) /* ../../core/util/bbox */;
    const annotations_1 = require(100) /* ../../styles/annotations */;
    exports.EDGE_TOLERANCE = 2.5;
    class BoxAnnotationView extends annotation_1.AnnotationView {
        initialize() {
            super.initialize();
            this.plot_view.canvas_overlays.appendChild(this.el);
            this.el.classList.add(annotations_1.bk_shading);
            dom_1.undisplay(this.el);
        }
        connect_signals() {
            super.connect_signals();
            // need to respond to either normal BB change events or silent
            // "data only updates" that tools might want to use
            if (this.model.render_mode == 'css') {
                // dispatch CSS update immediately
                this.connect(this.model.change, () => this.render());
                this.connect(this.model.data_update, () => this.render());
            }
            else {
                this.connect(this.model.change, () => this.plot_view.request_render());
                this.connect(this.model.data_update, () => this.plot_view.request_render());
            }
        }
        render() {
            if (!this.model.visible && this.model.render_mode == 'css')
                dom_1.undisplay(this.el);
            if (!this.model.visible)
                return;
            // don't render if *all* position are null
            if (this.model.left == null && this.model.right == null && this.model.top == null && this.model.bottom == null) {
                dom_1.undisplay(this.el);
                return;
            }
            const { frame } = this.plot_view;
            const xscale = frame.xscales[this.model.x_range_name];
            const yscale = frame.yscales[this.model.y_range_name];
            const _calc_dim = (dim, dim_units, scale, view, frame_extrema) => {
                let sdim;
                if (dim != null) {
                    if (this.model.screen)
                        sdim = dim;
                    else {
                        if (dim_units == 'data')
                            sdim = scale.compute(dim);
                        else
                            sdim = view.compute(dim);
                    }
                }
                else
                    sdim = frame_extrema;
                return sdim;
            };
            this.sleft = _calc_dim(this.model.left, this.model.left_units, xscale, frame.xview, frame._left.value);
            this.sright = _calc_dim(this.model.right, this.model.right_units, xscale, frame.xview, frame._right.value);
            this.stop = _calc_dim(this.model.top, this.model.top_units, yscale, frame.yview, frame._top.value);
            this.sbottom = _calc_dim(this.model.bottom, this.model.bottom_units, yscale, frame.yview, frame._bottom.value);
            const draw = this.model.render_mode == 'css' ? this._css_box.bind(this) : this._canvas_box.bind(this);
            draw(this.sleft, this.sright, this.sbottom, this.stop);
        }
        _css_box(sleft, sright, sbottom, stop) {
            const line_width = this.model.properties.line_width.value();
            const sw = Math.floor(sright - sleft) - line_width;
            const sh = Math.floor(sbottom - stop) - line_width;
            this.el.style.left = `${sleft}px`;
            this.el.style.width = `${sw}px`;
            this.el.style.top = `${stop}px`;
            this.el.style.height = `${sh}px`;
            this.el.style.borderWidth = `${line_width}px`;
            this.el.style.borderColor = this.model.properties.line_color.value();
            this.el.style.backgroundColor = this.model.properties.fill_color.value();
            this.el.style.opacity = this.model.properties.fill_alpha.value();
            // try our best to honor line dashing in some way, if we can
            const ld = this.model.properties.line_dash.value().length < 2 ? "solid" : "dashed";
            this.el.style.borderStyle = ld;
            dom_1.display(this.el);
        }
        _canvas_box(sleft, sright, sbottom, stop) {
            const { ctx } = this.plot_view.canvas_view;
            ctx.save();
            ctx.beginPath();
            ctx.rect(sleft, stop, sright - sleft, sbottom - stop);
            this.visuals.fill.set_value(ctx);
            ctx.fill();
            this.visuals.line.set_value(ctx);
            ctx.stroke();
            ctx.restore();
        }
        interactive_bbox() {
            const tol = this.model.properties.line_width.value() + exports.EDGE_TOLERANCE;
            return new bbox_1.BBox({
                x0: this.sleft - tol,
                y0: this.stop - tol,
                x1: this.sright + tol,
                y1: this.sbottom + tol,
            });
        }
        interactive_hit(sx, sy) {
            if (this.model.in_cursor == null)
                return false;
            const bbox = this.interactive_bbox();
            return bbox.contains(sx, sy);
        }
        cursor(sx, sy) {
            const tol = 3;
            if (Math.abs(sx - this.sleft) < tol || Math.abs(sx - this.sright) < tol)
                return this.model.ew_cursor;
            else if (Math.abs(sy - this.sbottom) < tol || Math.abs(sy - this.stop) < tol)
                return this.model.ns_cursor;
            else if (sx > this.sleft && sx < this.sright && sy > this.stop && sy < this.sbottom)
                return this.model.in_cursor;
            else
                return null;
        }
    }
    exports.BoxAnnotationView = BoxAnnotationView;
    BoxAnnotationView.__name__ = "BoxAnnotationView";
    class BoxAnnotation extends annotation_1.Annotation {
        constructor(attrs) {
            super(attrs);
        }
        static init_BoxAnnotation() {
            this.prototype.default_view = BoxAnnotationView;
            this.mixins(['line', 'fill']);
            this.define({
                render_mode: [p.RenderMode, 'canvas'],
                x_range_name: [p.String, 'default'],
                y_range_name: [p.String, 'default'],
                top: [p.Number, null],
                top_units: [p.SpatialUnits, 'data'],
                bottom: [p.Number, null],
                bottom_units: [p.SpatialUnits, 'data'],
                left: [p.Number, null],
                left_units: [p.SpatialUnits, 'data'],
                right: [p.Number, null],
                right_units: [p.SpatialUnits, 'data'],
            });
            this.internal({
                screen: [p.Boolean, false],
                ew_cursor: [p.String, null],
                ns_cursor: [p.String, null],
                in_cursor: [p.String, null],
            });
            this.override({
                fill_color: '#fff9ba',
                fill_alpha: 0.4,
                line_color: '#cccccc',
                line_alpha: 0.3,
            });
        }
        initialize() {
            super.initialize();
            this.data_update = new signaling_1.Signal0(this, "data_update");
        }
        update({ left, right, top, bottom }) {
            this.setv({ left, right, top, bottom, screen: true }, { silent: true });
            this.data_update.emit();
        }
    }
    exports.BoxAnnotation = BoxAnnotation;
    BoxAnnotation.__name__ = "BoxAnnotation";
    BoxAnnotation.init_BoxAnnotation();
},
/* styles/annotations.js */ function _(require, module, exports) {
    require(62) /* ./root */;
    const _a = require(61) /* ../core/dom */;
    _a.styles.append(".bk-root .bk-shading {\n  position: absolute;\n  display: block;\n  border: 1px dashed green;\n}\n");
    exports.bk_annotation = "bk-annotation";
    exports.bk_shading = "bk-shading";
    exports.bk_annotation_child = "bk-annotation-child";
},
/* models/annotations/color_bar.js */ function _(require, module, exports) {
    const annotation_1 = require(29) /* ./annotation */;
    const basic_ticker_1 = require(102) /* ../tickers/basic_ticker */;
    const basic_tick_formatter_1 = require(106) /* ../formatters/basic_tick_formatter */;
    const linear_color_mapper_1 = require(108) /* ../mappers/linear_color_mapper */;
    const linear_scale_1 = require(113) /* ../scales/linear_scale */;
    const log_scale_1 = require(122) /* ../scales/log_scale */;
    const range1d_1 = require(123) /* ../ranges/range1d */;
    const p = require(18) /* ../../core/properties */;
    const text_util = require(124) /* ../../core/util/text */;
    const array_1 = require(8) /* ../../core/util/array */;
    const arrayable_1 = require(11) /* ../../core/util/arrayable */;
    const object_1 = require(22) /* ../../core/util/object */;
    const types_1 = require(7) /* ../../core/util/types */;
    const SHORT_DIM = 25;
    const LONG_DIM_MIN_SCALAR = 0.3;
    const LONG_DIM_MAX_SCALAR = 0.8;
    class ColorBarView extends annotation_1.AnnotationView {
        initialize() {
            super.initialize();
            this._set_canvas_image();
        }
        connect_signals() {
            super.connect_signals();
            this.connect(this.model.properties.visible.change, () => this.plot_view.request_render());
            this.connect(this.model.ticker.change, () => this.plot_view.request_render());
            this.connect(this.model.formatter.change, () => this.plot_view.request_render());
            if (this.model.color_mapper != null) {
                this.connect(this.model.color_mapper.change, () => {
                    this._set_canvas_image();
                    this.plot_view.request_render();
                });
            }
        }
        _get_size() {
            if (this.model.color_mapper == null)
                return { width: 0, height: 0 };
            else {
                const { width, height } = this.compute_legend_dimensions();
                return { width, height };
            }
        }
        _set_canvas_image() {
            if (this.model.color_mapper == null)
                return;
            let { palette } = this.model.color_mapper;
            if (this.model.orientation == 'vertical')
                palette = array_1.reversed(palette);
            let w, h;
            switch (this.model.orientation) {
                case "vertical": {
                    [w, h] = [1, palette.length];
                    break;
                }
                case "horizontal": {
                    [w, h] = [palette.length, 1];
                    break;
                }
                default:
                    throw new Error("unreachable code");
            }
            const canvas = document.createElement('canvas');
            canvas.width = w;
            canvas.height = h;
            const image_ctx = canvas.getContext('2d');
            const image_data = image_ctx.getImageData(0, 0, w, h);
            // We always want to draw the entire palette linearly, so we create a new
            // LinearColorMapper instance and map a monotonic range of values with
            // length = palette.length to get each palette color in order.
            const cmap = new linear_color_mapper_1.LinearColorMapper({ palette }).rgba_mapper;
            const buf8 = cmap.v_compute(array_1.range(0, palette.length));
            image_data.data.set(buf8);
            image_ctx.putImageData(image_data, 0, 0);
            this.image = canvas;
        }
        compute_legend_dimensions() {
            const image_dimensions = this._computed_image_dimensions();
            const [image_height, image_width] = [image_dimensions.height, image_dimensions.width];
            const label_extent = this._get_label_extent();
            const title_extent = this._title_extent();
            const tick_extent = this._tick_extent();
            const { padding } = this.model;
            let legend_height, legend_width;
            switch (this.model.orientation) {
                case "vertical":
                    legend_height = image_height + title_extent + 2 * padding;
                    legend_width = image_width + tick_extent + label_extent + 2 * padding;
                    break;
                case "horizontal":
                    legend_height = image_height + title_extent + tick_extent + label_extent + 2 * padding;
                    legend_width = image_width + 2 * padding;
                    break;
                default:
                    throw new Error("unreachable code");
            }
            return { width: legend_width, height: legend_height };
        }
        compute_legend_location() {
            const legend_dimensions = this.compute_legend_dimensions();
            const [legend_height, legend_width] = [legend_dimensions.height, legend_dimensions.width];
            const legend_margin = this.model.margin;
            const panel = this.panel != null ? this.panel : this.plot_view.frame;
            const [hr, vr] = panel.bbox.ranges;
            const { location } = this.model;
            let sx, sy;
            if (types_1.isString(location)) {
                switch (location) {
                    case 'top_left':
                        sx = hr.start + legend_margin;
                        sy = vr.start + legend_margin;
                        break;
                    case 'top_center':
                        sx = (hr.end + hr.start) / 2 - legend_width / 2;
                        sy = vr.start + legend_margin;
                        break;
                    case 'top_right':
                        sx = hr.end - legend_margin - legend_width;
                        sy = vr.start + legend_margin;
                        break;
                    case 'bottom_right':
                        sx = hr.end - legend_margin - legend_width;
                        sy = vr.end - legend_margin - legend_height;
                        break;
                    case 'bottom_center':
                        sx = (hr.end + hr.start) / 2 - legend_width / 2;
                        sy = vr.end - legend_margin - legend_height;
                        break;
                    case 'bottom_left':
                        sx = hr.start + legend_margin;
                        sy = vr.end - legend_margin - legend_height;
                        break;
                    case 'center_left':
                        sx = hr.start + legend_margin;
                        sy = (vr.end + vr.start) / 2 - legend_height / 2;
                        break;
                    case 'center':
                        sx = (hr.end + hr.start) / 2 - legend_width / 2;
                        sy = (vr.end + vr.start) / 2 - legend_height / 2;
                        break;
                    case 'center_right':
                        sx = hr.end - legend_margin - legend_width;
                        sy = (vr.end + vr.start) / 2 - legend_height / 2;
                        break;
                    default:
                        throw new Error("unreachable code");
                }
            }
            else if (types_1.isArray(location) && location.length == 2) {
                const [vx, vy] = location;
                sx = panel.xview.compute(vx);
                sy = panel.yview.compute(vy) - legend_height;
            }
            else
                throw new Error("unreachable code");
            return { sx, sy };
        }
        render() {
            if (!this.model.visible || this.model.color_mapper == null)
                return;
            const { ctx } = this.plot_view.canvas_view;
            ctx.save();
            const { sx, sy } = this.compute_legend_location();
            ctx.translate(sx, sy);
            this._draw_bbox(ctx);
            const image_offset = this._get_image_offset();
            ctx.translate(image_offset.x, image_offset.y);
            this._draw_image(ctx);
            if (this.model.color_mapper.low != null && this.model.color_mapper.high != null) {
                const tick_info = this.tick_info();
                this._draw_major_ticks(ctx, tick_info);
                this._draw_minor_ticks(ctx, tick_info);
                this._draw_major_labels(ctx, tick_info);
            }
            if (this.model.title)
                this._draw_title(ctx);
            ctx.restore();
        }
        _draw_bbox(ctx) {
            const bbox = this.compute_legend_dimensions();
            ctx.save();
            if (this.visuals.background_fill.doit) {
                this.visuals.background_fill.set_value(ctx);
                ctx.fillRect(0, 0, bbox.width, bbox.height);
            }
            if (this.visuals.border_line.doit) {
                this.visuals.border_line.set_value(ctx);
                ctx.strokeRect(0, 0, bbox.width, bbox.height);
            }
            ctx.restore();
        }
        _draw_image(ctx) {
            const image = this._computed_image_dimensions();
            ctx.save();
            ctx.setImageSmoothingEnabled(false);
            ctx.globalAlpha = this.model.scale_alpha;
            ctx.drawImage(this.image, 0, 0, image.width, image.height);
            if (this.visuals.bar_line.doit) {
                this.visuals.bar_line.set_value(ctx);
                ctx.strokeRect(0, 0, image.width, image.height);
            }
            ctx.restore();
        }
        _draw_major_ticks(ctx, tick_info) {
            if (!this.visuals.major_tick_line.doit)
                return;
            const [nx, ny] = this._normals();
            const image = this._computed_image_dimensions();
            const [x_offset, y_offset] = [image.width * nx, image.height * ny];
            const [sx, sy] = tick_info.coords.major;
            const tin = this.model.major_tick_in;
            const tout = this.model.major_tick_out;
            ctx.save();
            ctx.translate(x_offset, y_offset);
            this.visuals.major_tick_line.set_value(ctx);
            for (let i = 0, end = sx.length; i < end; i++) {
                ctx.beginPath();
                ctx.moveTo(Math.round(sx[i] + nx * tout), Math.round(sy[i] + ny * tout));
                ctx.lineTo(Math.round(sx[i] - nx * tin), Math.round(sy[i] - ny * tin));
                ctx.stroke();
            }
            ctx.restore();
        }
        _draw_minor_ticks(ctx, tick_info) {
            if (!this.visuals.minor_tick_line.doit)
                return;
            const [nx, ny] = this._normals();
            const image = this._computed_image_dimensions();
            const [x_offset, y_offset] = [image.width * nx, image.height * ny];
            const [sx, sy] = tick_info.coords.minor;
            const tin = this.model.minor_tick_in;
            const tout = this.model.minor_tick_out;
            ctx.save();
            ctx.translate(x_offset, y_offset);
            this.visuals.minor_tick_line.set_value(ctx);
            for (let i = 0, end = sx.length; i < end; i++) {
                ctx.beginPath();
                ctx.moveTo(Math.round(sx[i] + nx * tout), Math.round(sy[i] + ny * tout));
                ctx.lineTo(Math.round(sx[i] - nx * tin), Math.round(sy[i] - ny * tin));
                ctx.stroke();
            }
            ctx.restore();
        }
        _draw_major_labels(ctx, tick_info) {
            if (!this.visuals.major_label_text.doit)
                return;
            const [nx, ny] = this._normals();
            const image = this._computed_image_dimensions();
            const [x_offset, y_offset] = [image.width * nx, image.height * ny];
            const standoff = (this.model.label_standoff + this._tick_extent());
            const [x_standoff, y_standoff] = [standoff * nx, standoff * ny];
            const [sx, sy] = tick_info.coords.major;
            const formatted_labels = tick_info.labels.major;
            this.visuals.major_label_text.set_value(ctx);
            ctx.save();
            ctx.translate(x_offset + x_standoff, y_offset + y_standoff);
            for (let i = 0, end = sx.length; i < end; i++) {
                ctx.fillText(formatted_labels[i], Math.round(sx[i] + nx * this.model.label_standoff), Math.round(sy[i] + ny * this.model.label_standoff));
            }
            ctx.restore();
        }
        _draw_title(ctx) {
            if (!this.visuals.title_text.doit)
                return;
            ctx.save();
            this.visuals.title_text.set_value(ctx);
            ctx.fillText(this.model.title, 0, -this.model.title_standoff);
            ctx.restore();
        }
        /*protected*/ _get_label_extent() {
            const major_labels = this.tick_info().labels.major;
            let label_extent;
            if (this.model.color_mapper.low != null && this.model.color_mapper.high != null && !object_1.isEmpty(major_labels)) {
                const { ctx } = this.plot_view.canvas_view;
                ctx.save();
                this.visuals.major_label_text.set_value(ctx);
                switch (this.model.orientation) {
                    case "vertical":
                        label_extent = array_1.max((major_labels.map((label) => ctx.measureText(label.toString()).width)));
                        break;
                    case "horizontal":
                        label_extent = text_util.measure_font(this.visuals.major_label_text.font_value()).height;
                        break;
                    default:
                        throw new Error("unreachable code");
                }
                label_extent += this.model.label_standoff;
                ctx.restore();
            }
            else
                label_extent = 0;
            return label_extent;
        }
        /*protected*/ _get_image_offset() {
            // Returns image offset relative to legend bounding box
            const x = this.model.padding;
            const y = this.model.padding + this._title_extent();
            return { x, y };
        }
        // {{{ TODO: state
        _normals() {
            return this.model.orientation == 'vertical' ? [1, 0] : [0, 1];
        }
        _title_extent() {
            const font_value = this.model.title_text_font + " " + this.model.title_text_font_size + " " + this.model.title_text_font_style;
            const title_extent = this.model.title ? text_util.measure_font(font_value).height + this.model.title_standoff : 0;
            return title_extent;
        }
        _tick_extent() {
            if (this.model.color_mapper.low != null && this.model.color_mapper.high != null)
                return array_1.max([this.model.major_tick_out, this.model.minor_tick_out]);
            else
                return 0;
        }
        _computed_image_dimensions() {
            /*
            Heuristics to determine ColorBar image dimensions if set to "auto"
        
            Note: Returns the height/width values for the ColorBar's scale image, not
            the dimensions of the entire ColorBar.
        
            If the short dimension (the width of a vertical bar or height of a
            horizontal bar) is set to "auto", the resulting dimension will be set to
            25 px.
        
            For a ColorBar in a side panel with the long dimension (the height of a
            vertical bar or width of a horizontal bar) set to "auto", the
            resulting dimension will be as long as the adjacent frame edge, so that the
            bar "fits" to the plot.
        
            For a ColorBar in the plot frame with the long dimension set to "auto", the
            resulting dimension will be the greater of:
              * The length of the color palette * 25px
              * The parallel frame dimension * 0.30
                (i.e the frame height for a vertical ColorBar)
            But not greater than:
              * The parallel frame dimension * 0.80
            */
            const frame_height = this.plot_view.frame._height.value;
            const frame_width = this.plot_view.frame._width.value;
            const title_extent = this._title_extent();
            let height, width;
            switch (this.model.orientation) {
                case "vertical": {
                    if (this.model.height == 'auto') {
                        if (this.panel != null)
                            height = frame_height - 2 * this.model.padding - title_extent;
                        else {
                            height = array_1.max([this.model.color_mapper.palette.length * SHORT_DIM, frame_height * LONG_DIM_MIN_SCALAR]);
                            height = array_1.min([height, frame_height * LONG_DIM_MAX_SCALAR - 2 * this.model.padding - title_extent]);
                        }
                    }
                    else
                        height = this.model.height;
                    width = this.model.width == 'auto' ? SHORT_DIM : this.model.width;
                    break;
                }
                case "horizontal": {
                    height = this.model.height == 'auto' ? SHORT_DIM : this.model.height;
                    if (this.model.width == 'auto') {
                        if (this.panel != null)
                            width = frame_width - 2 * this.model.padding;
                        else {
                            width = array_1.max([this.model.color_mapper.palette.length * SHORT_DIM, frame_width * LONG_DIM_MIN_SCALAR]);
                            width = array_1.min([width, frame_width * LONG_DIM_MAX_SCALAR - 2 * this.model.padding]);
                        }
                    }
                    else
                        width = this.model.width;
                    break;
                }
                default:
                    throw new Error("unreachable code");
            }
            return { width, height };
        }
        /*protected*/ _tick_coordinate_scale(scale_length) {
            /*
            Creates and returns a scale instance that maps the `color_mapper` range
            (low to high) to a screen space range equal to the length of the ColorBar's
            scale image. The scale is used to calculate the tick coordinates in screen
            coordinates for plotting purposes.
        
            Note: the type of color_mapper has to match the type of scale (i.e.
            a LinearColorMapper will require a corresponding LinearScale instance).
            */
            const ranges = {
                source_range: new range1d_1.Range1d({
                    start: this.model.color_mapper.low,
                    end: this.model.color_mapper.high,
                }),
                target_range: new range1d_1.Range1d({
                    start: 0,
                    end: scale_length,
                }),
            };
            switch (this.model.color_mapper.type) {
                case "LinearColorMapper": return new linear_scale_1.LinearScale(ranges);
                case "LogColorMapper": return new log_scale_1.LogScale(ranges);
                default:
                    throw new Error("unreachable code");
            }
        }
        _format_major_labels(initial_labels, major_ticks) {
            // XXX: passing null as cross_loc probably means MercatorTickFormatters, etc
            // will not function properly in conjunction with colorbars
            const formatted_labels = this.model.formatter.doFormat(initial_labels, null);
            for (let i = 0, end = major_ticks.length; i < end; i++) {
                if (major_ticks[i] in this.model.major_label_overrides)
                    formatted_labels[i] = this.model.major_label_overrides[major_ticks[i]];
            }
            return formatted_labels;
        }
        tick_info() {
            const image_dimensions = this._computed_image_dimensions();
            let scale_length;
            switch (this.model.orientation) {
                case "vertical": {
                    scale_length = image_dimensions.height;
                    break;
                }
                case "horizontal": {
                    scale_length = image_dimensions.width;
                    break;
                }
                default:
                    throw new Error("unreachable code");
            }
            const scale = this._tick_coordinate_scale(scale_length);
            const [i, j] = this._normals();
            const [start, end] = [this.model.color_mapper.low, this.model.color_mapper.high];
            // XXX: passing null as cross_loc probably means MercatorTickers, etc
            // will not function properly in conjunction with colorbars
            const ticks = this.model.ticker.get_ticks(start, end, null, null, this.model.ticker.desired_num_ticks);
            const majors = ticks.major;
            const minors = ticks.minor;
            const major_coords = [[], []];
            const minor_coords = [[], []];
            for (let ii = 0, _end = majors.length; ii < _end; ii++) {
                if (majors[ii] < start || majors[ii] > end)
                    continue;
                major_coords[i].push(majors[ii]);
                major_coords[j].push(0);
            }
            for (let ii = 0, _end = minors.length; ii < _end; ii++) {
                if (minors[ii] < start || minors[ii] > end)
                    continue;
                minor_coords[i].push(minors[ii]);
                minor_coords[j].push(0);
            }
            const labels = { major: this._format_major_labels(major_coords[i], majors) };
            const coords = {
                major: [[], []],
                minor: [[], []],
            };
            coords.major[i] = scale.v_compute(major_coords[i]);
            coords.minor[i] = scale.v_compute(minor_coords[i]);
            coords.major[j] = major_coords[j];
            coords.minor[j] = minor_coords[j];
            // Because we want the scale to be reversed
            if (this.model.orientation == 'vertical') {
                coords.major[i] = arrayable_1.map(coords.major[i], (coord) => scale_length - coord);
                coords.minor[i] = arrayable_1.map(coords.minor[i], (coord) => scale_length - coord);
            }
            return { coords, labels };
        }
    }
    exports.ColorBarView = ColorBarView;
    ColorBarView.__name__ = "ColorBarView";
    class ColorBar extends annotation_1.Annotation {
        constructor(attrs) {
            super(attrs);
        }
        static init_ColorBar() {
            this.prototype.default_view = ColorBarView;
            this.mixins([
                'text:major_label_',
                'text:title_',
                'line:major_tick_',
                'line:minor_tick_',
                'line:border_',
                'line:bar_',
                'fill:background_',
            ]);
            this.define({
                location: [p.Any, 'top_right'],
                orientation: [p.Orientation, 'vertical'],
                title: [p.String],
                title_standoff: [p.Number, 2],
                width: [p.Any, 'auto'],
                height: [p.Any, 'auto'],
                scale_alpha: [p.Number, 1.0],
                ticker: [p.Instance, () => new basic_ticker_1.BasicTicker()],
                formatter: [p.Instance, () => new basic_tick_formatter_1.BasicTickFormatter()],
                major_label_overrides: [p.Any, {}],
                color_mapper: [p.Instance],
                label_standoff: [p.Number, 5],
                margin: [p.Number, 30],
                padding: [p.Number, 10],
                major_tick_in: [p.Number, 5],
                major_tick_out: [p.Number, 0],
                minor_tick_in: [p.Number, 0],
                minor_tick_out: [p.Number, 0],
            });
            this.override({
                background_fill_color: "#ffffff",
                background_fill_alpha: 0.95,
                bar_line_color: null,
                border_line_color: null,
                major_label_text_align: "center",
                major_label_text_baseline: "middle",
                major_label_text_font_size: "8pt",
                major_tick_line_color: "#ffffff",
                minor_tick_line_color: null,
                title_text_font_size: "10pt",
                title_text_font_style: "italic",
            });
        }
    }
    exports.ColorBar = ColorBar;
    ColorBar.__name__ = "ColorBar";
    ColorBar.init_ColorBar();
},
/* models/tickers/basic_ticker.js */ function _(require, module, exports) {
    const adaptive_ticker_1 = require(103) /* ./adaptive_ticker */;
    class BasicTicker extends adaptive_ticker_1.AdaptiveTicker {
        constructor(attrs) {
            super(attrs);
        }
    }
    exports.BasicTicker = BasicTicker;
    BasicTicker.__name__ = "BasicTicker";
},
/* models/tickers/adaptive_ticker.js */ function _(require, module, exports) {
    const continuous_ticker_1 = require(104) /* ./continuous_ticker */;
    const array_1 = require(8) /* ../../core/util/array */;
    const p = require(18) /* ../../core/properties */;
    // Forces a number x into a specified range [min_val, max_val].
    function clamp(x, min_val, max_val) {
        return Math.max(min_val, Math.min(max_val, x));
    }
    // A log function with an optional base.
    function log(x, base = Math.E) {
        return Math.log(x) / Math.log(base);
    }
    class AdaptiveTicker extends continuous_ticker_1.ContinuousTicker {
        constructor(attrs) {
            super(attrs);
        }
        static init_AdaptiveTicker() {
            this.define({
                base: [p.Number, 10.0],
                mantissas: [p.Array, [1, 2, 5]],
                min_interval: [p.Number, 0.0],
                max_interval: [p.Number],
            });
        }
        // These arguments control the range of possible intervals.  The interval I
        // returned by get_interval() will be the one that most closely matches the
        // desired number of ticks, subject to the following constraints:
        // I = (M * B^N), where
        // M is a member of mantissas,
        // B is base,
        // and N is an integer;
        // and min_interval <= I <= max_interval.
        initialize() {
            super.initialize();
            const prefix_mantissa = array_1.nth(this.mantissas, -1) / this.base;
            const suffix_mantissa = array_1.nth(this.mantissas, 0) * this.base;
            this.extended_mantissas = [prefix_mantissa, ...this.mantissas, suffix_mantissa];
            this.base_factor = this.get_min_interval() === 0.0 ? 1.0 : this.get_min_interval();
        }
        get_interval(data_low, data_high, desired_n_ticks) {
            const data_range = data_high - data_low;
            const ideal_interval = this.get_ideal_interval(data_low, data_high, desired_n_ticks);
            const interval_exponent = Math.floor(log(ideal_interval / this.base_factor, this.base));
            const ideal_magnitude = Math.pow(this.base, interval_exponent) * this.base_factor;
            // An untested optimization.
            //   const ideal_mantissa = ideal_interval / ideal_magnitude
            //   index = sorted_index(this.extended_mantissas, ideal_mantissa)
            //   candidate_mantissas = this.extended_mantissas[index..index + 1]
            const candidate_mantissas = this.extended_mantissas;
            const errors = candidate_mantissas.map((mantissa) => {
                return Math.abs(desired_n_ticks - (data_range / (mantissa * ideal_magnitude)));
            });
            const best_mantissa = candidate_mantissas[array_1.argmin(errors)];
            const interval = best_mantissa * ideal_magnitude;
            return clamp(interval, this.get_min_interval(), this.get_max_interval());
        }
    }
    exports.AdaptiveTicker = AdaptiveTicker;
    AdaptiveTicker.__name__ = "AdaptiveTicker";
    AdaptiveTicker.init_AdaptiveTicker();
},
/* models/tickers/continuous_ticker.js */ function _(require, module, exports) {
    const ticker_1 = require(105) /* ./ticker */;
    const p = require(18) /* ../../core/properties */;
    const array_1 = require(8) /* ../../core/util/array */;
    const types_1 = require(7) /* ../../core/util/types */;
    class ContinuousTicker extends ticker_1.Ticker {
        constructor(attrs) {
            super(attrs);
        }
        static init_ContinuousTicker() {
            this.define({
                num_minor_ticks: [p.Number, 5],
                desired_num_ticks: [p.Number, 6],
            });
        }
        get_ticks(data_low, data_high, _range, cross_loc, _) {
            return this.get_ticks_no_defaults(data_low, data_high, cross_loc, this.desired_num_ticks);
        }
        // The version of get_ticks() that does the work (and the version that
        // should be overridden in subclasses).
        get_ticks_no_defaults(data_low, data_high, _cross_loc, desired_n_ticks) {
            const interval = this.get_interval(data_low, data_high, desired_n_ticks);
            const start_factor = Math.floor(data_low / interval);
            const end_factor = Math.ceil(data_high / interval);
            let factors;
            if (types_1.isStrictNaN(start_factor) || types_1.isStrictNaN(end_factor))
                factors = [];
            else
                factors = array_1.range(start_factor, end_factor + 1);
            const ticks = factors
                .map((factor) => factor * interval)
                .filter((tick) => data_low <= tick && tick <= data_high);
            const num_minor_ticks = this.num_minor_ticks;
            const minor_ticks = [];
            if (num_minor_ticks > 0 && ticks.length > 0) {
                const minor_interval = interval / num_minor_ticks;
                const minor_offsets = array_1.range(0, num_minor_ticks).map((i) => i * minor_interval);
                for (const x of minor_offsets.slice(1)) {
                    const mt = ticks[0] - x;
                    if (data_low <= mt && mt <= data_high) {
                        minor_ticks.push(mt);
                    }
                }
                for (const tick of ticks) {
                    for (const x of minor_offsets) {
                        const mt = tick + x;
                        if (data_low <= mt && mt <= data_high) {
                            minor_ticks.push(mt);
                        }
                    }
                }
            }
            return {
                major: ticks,
                minor: minor_ticks,
            };
        }
        // Returns the smallest interval that can be returned by get_interval().
        get_min_interval() {
            return this.min_interval;
        }
        // Returns the largest interval that can be returned by get_interval().
        get_max_interval() {
            return this.max_interval != null ? this.max_interval : Infinity;
        }
        // Returns the interval size that would produce exactly the number of
        // desired ticks.  (In general we won't use exactly this interval, because
        // we want the ticks to be round numbers.)
        get_ideal_interval(data_low, data_high, desired_n_ticks) {
            const data_range = data_high - data_low;
            return data_range / desired_n_ticks;
        }
    }
    exports.ContinuousTicker = ContinuousTicker;
    ContinuousTicker.__name__ = "ContinuousTicker";
    ContinuousTicker.init_ContinuousTicker();
},
/* models/tickers/ticker.js */ function _(require, module, exports) {
    const model_1 = require(64) /* ../../model */;
    class Ticker extends model_1.Model {
        constructor(attrs) {
            super(attrs);
        }
    }
    exports.Ticker = Ticker;
    Ticker.__name__ = "Ticker";
},
/* models/formatters/basic_tick_formatter.js */ function _(require, module, exports) {
    const tick_formatter_1 = require(107) /* ./tick_formatter */;
    const p = require(18) /* ../../core/properties */;
    const types_1 = require(7) /* ../../core/util/types */;
    class BasicTickFormatter extends tick_formatter_1.TickFormatter {
        constructor(attrs) {
            super(attrs);
            this.last_precision = 3;
        }
        static init_BasicTickFormatter() {
            this.define({
                precision: [p.Any, 'auto'],
                use_scientific: [p.Boolean, true],
                power_limit_high: [p.Number, 5],
                power_limit_low: [p.Number, -3],
            });
        }
        get scientific_limit_low() {
            return Math.pow(10.0, this.power_limit_low);
        }
        get scientific_limit_high() {
            return Math.pow(10.0, this.power_limit_high);
        }
        doFormat(ticks, _opts) {
            if (ticks.length == 0)
                return [];
            let zero_eps = 0;
            if (ticks.length >= 2)
                zero_eps = Math.abs(ticks[1] - ticks[0]) / 10000;
            let need_sci = false;
            if (this.use_scientific) {
                for (const tick of ticks) {
                    const tick_abs = Math.abs(tick);
                    if (tick_abs > zero_eps && (tick_abs >= this.scientific_limit_high || tick_abs <= this.scientific_limit_low)) {
                        need_sci = true;
                        break;
                    }
                }
            }
            const labels = new Array(ticks.length);
            const { precision } = this;
            if (precision == null || types_1.isNumber(precision)) {
                if (need_sci) {
                    for (let i = 0, end = ticks.length; i < end; i++) {
                        labels[i] = ticks[i].toExponential(precision || undefined);
                    }
                }
                else {
                    for (let i = 0, end = ticks.length; i < end; i++) {
                        labels[i] = ticks[i].toFixed(precision || undefined).replace(/(\.[0-9]*?)0+$/, "$1").replace(/\.$/, "");
                    }
                }
            }
            else {
                for (let x = this.last_precision, asc = this.last_precision <= 15; asc ? x <= 15 : x >= 15; asc ? x++ : x--) {
                    let is_ok = true;
                    if (need_sci) {
                        for (let i = 0, end = ticks.length; i < end; i++) {
                            labels[i] = ticks[i].toExponential(x);
                            if (i > 0) {
                                if (labels[i] === labels[i - 1]) {
                                    is_ok = false;
                                    break;
                                }
                            }
                        }
                        if (is_ok) {
                            break;
                        }
                    }
                    else {
                        for (let i = 0, end = ticks.length; i < end; i++) {
                            labels[i] = ticks[i].toFixed(x).replace(/(\.[0-9]*?)0+$/, "$1").replace(/\.$/, "");
                            if (i > 0) {
                                if (labels[i] == labels[i - 1]) {
                                    is_ok = false;
                                    break;
                                }
                            }
                        }
                        if (is_ok) {
                            break;
                        }
                    }
                    if (is_ok) {
                        this.last_precision = x;
                        break;
                    }
                }
            }
            return labels;
        }
    }
    exports.BasicTickFormatter = BasicTickFormatter;
    BasicTickFormatter.__name__ = "BasicTickFormatter";
    BasicTickFormatter.init_BasicTickFormatter();
},
/* models/formatters/tick_formatter.js */ function _(require, module, exports) {
    const model_1 = require(64) /* ../../model */;
    class TickFormatter extends model_1.Model {
        constructor(attrs) {
            super(attrs);
        }
    }
    exports.TickFormatter = TickFormatter;
    TickFormatter.__name__ = "TickFormatter";
},
/* models/mappers/linear_color_mapper.js */ function _(require, module, exports) {
    const continuous_color_mapper_1 = require(109) /* ./continuous_color_mapper */;
    const arrayable_1 = require(11) /* ../../core/util/arrayable */;
    class LinearColorMapper extends continuous_color_mapper_1.ContinuousColorMapper {
        constructor(attrs) {
            super(attrs);
        }
        _v_compute(data, values, palette, colors) {
            const { nan_color, low_color, high_color } = colors;
            const low = this.low != null ? this.low : arrayable_1.min(data);
            const high = this.high != null ? this.high : arrayable_1.max(data);
            const max_key = palette.length - 1;
            const norm_factor = 1 / (high - low);
            const normed_interval = 1 / palette.length;
            for (let i = 0, end = data.length; i < end; i++) {
                const d = data[i];
                if (isNaN(d)) {
                    values[i] = nan_color;
                    continue;
                }
                // This handles the edge case where d == high, since the code below maps
                // values exactly equal to high to palette.length, which is greater than
                // max_key
                if (d == high) {
                    values[i] = palette[max_key];
                    continue;
                }
                const normed_d = (d - low) * norm_factor;
                const key = Math.floor(normed_d / normed_interval);
                if (key < 0)
                    values[i] = low_color != null ? low_color : palette[0];
                else if (key > max_key)
                    values[i] = high_color != null ? high_color : palette[max_key];
                else
                    values[i] = palette[key];
            }
        }
    }
    exports.LinearColorMapper = LinearColorMapper;
    LinearColorMapper.__name__ = "LinearColorMapper";
},
/* models/mappers/continuous_color_mapper.js */ function _(require, module, exports) {
    const color_mapper_1 = require(110) /* ./color_mapper */;
    const p = require(18) /* ../../core/properties */;
    class ContinuousColorMapper extends color_mapper_1.ColorMapper {
        constructor(attrs) {
            super(attrs);
        }
        static init_ContinuousColorMapper() {
            this.define({
                high: [p.Number],
                low: [p.Number],
                high_color: [p.Color],
                low_color: [p.Color],
            });
        }
        _colors(conv) {
            return Object.assign(Object.assign({}, super._colors(conv)), { low_color: this.low_color != null ? conv(this.low_color) : undefined, high_color: this.high_color != null ? conv(this.high_color) : undefined });
        }
    }
    exports.ContinuousColorMapper = ContinuousColorMapper;
    ContinuousColorMapper.__name__ = "ContinuousColorMapper";
    ContinuousColorMapper.init_ContinuousColorMapper();
},
/* models/mappers/color_mapper.js */ function _(require, module, exports) {
    const mapper_1 = require(111) /* ./mapper */;
    const p = require(18) /* ../../core/properties */;
    const types_1 = require(7) /* ../../core/util/types */;
    const color_1 = require(20) /* ../../core/util/color */;
    const compat_1 = require(95) /* ../../core/util/compat */;
    function _convert_color(color) {
        if (types_1.isNumber(color))
            return color;
        if (color[0] != "#")
            color = color_1.color2hex(color);
        if (color.length != 9)
            color = color + 'ff';
        return parseInt(color.slice(1), 16);
    }
    exports._convert_color = _convert_color;
    function _convert_palette(palette) {
        const new_palette = new Uint32Array(palette.length);
        for (let i = 0, end = palette.length; i < end; i++)
            new_palette[i] = _convert_color(palette[i]);
        return new_palette;
    }
    exports._convert_palette = _convert_palette;
    function _uint32_to_rgba(values) {
        if (compat_1.is_little_endian) {
            const view = new DataView(values.buffer);
            for (let i = 0, end = values.length; i < end; i++)
                view.setUint32(i * 4, values[i]);
        }
        return new Uint8Array(values.buffer);
    }
    exports._uint32_to_rgba = _uint32_to_rgba;
    class ColorMapper extends mapper_1.Mapper {
        constructor(attrs) {
            super(attrs);
        }
        static init_ColorMapper() {
            this.define({
                palette: [p.Any],
                nan_color: [p.Color, "gray"],
            });
        }
        v_compute(xs) {
            const values = new Array(xs.length);
            this._v_compute(xs, values, this.palette, this._colors((c) => c));
            return values;
        }
        get rgba_mapper() {
            const self = this;
            const palette = _convert_palette(this.palette);
            const colors = this._colors(_convert_color);
            return {
                v_compute(xs) {
                    const values = new Uint32Array(xs.length);
                    self._v_compute(xs, values, palette, colors);
                    return _uint32_to_rgba(values);
                },
            };
        }
        _colors(conv) {
            return { nan_color: conv(this.nan_color) };
        }
    }
    exports.ColorMapper = ColorMapper;
    ColorMapper.__name__ = "ColorMapper";
    ColorMapper.init_ColorMapper();
},
/* models/mappers/mapper.js */ function _(require, module, exports) {
    const transform_1 = require(112) /* ../transforms/transform */;
    class Mapper extends transform_1.Transform {
        constructor(attrs) {
            super(attrs);
        }
        compute(_x) {
            // If it's just a single value, then a mapper doesn't really make sense.
            throw new Error("mapping single values is not supported");
        }
    }
    exports.Mapper = Mapper;
    Mapper.__name__ = "Mapper";
},
/* models/transforms/transform.js */ function _(require, module, exports) {
    const model_1 = require(64) /* ../../model */;
    class Transform extends model_1.Model {
        constructor(attrs) {
            super(attrs);
        }
    }
    exports.Transform = Transform;
    Transform.__name__ = "Transform";
},
/* models/scales/linear_scale.js */ function _(require, module, exports) {
    const scale_1 = require(114) /* ./scale */;
    class LinearScale extends scale_1.Scale {
        constructor(attrs) {
            super(attrs);
        }
        compute(x) {
            const [factor, offset] = this._compute_state();
            return factor * x + offset;
        }
        v_compute(xs) {
            const [factor, offset] = this._compute_state();
            const result = new Float64Array(xs.length);
            for (let i = 0; i < xs.length; i++)
                result[i] = factor * xs[i] + offset;
            return result;
        }
        invert(xprime) {
            const [factor, offset] = this._compute_state();
            return (xprime - offset) / factor;
        }
        v_invert(xprimes) {
            const [factor, offset] = this._compute_state();
            const result = new Float64Array(xprimes.length);
            for (let i = 0; i < xprimes.length; i++)
                result[i] = (xprimes[i] - offset) / factor;
            return result;
        }
        /*protected*/ _compute_state() {
            //
            //  (t1 - t0)       (t1 - t0)
            //  --------- * x - --------- * s0 + t0
            //  (s1 - s0)       (s1 - s0)
            //
            // [  factor  ]     [    offset    ]
            //
            const source_start = this.source_range.start;
            const source_end = this.source_range.end;
            const target_start = this.target_range.start;
            const target_end = this.target_range.end;
            const factor = (target_end - target_start) / (source_end - source_start);
            const offset = -(factor * source_start) + target_start;
            return [factor, offset];
        }
    }
    exports.LinearScale = LinearScale;
    LinearScale.__name__ = "LinearScale";
},
/* models/scales/scale.js */ function _(require, module, exports) {
    const transforms_1 = require(115) /* ../transforms */;
    const p = require(18) /* ../../core/properties */;
    class Scale extends transforms_1.Transform {
        constructor(attrs) {
            super(attrs);
        }
        static init_Scale() {
            this.internal({
                source_range: [p.Any],
                target_range: [p.Any],
            });
        }
        r_compute(x0, x1) {
            if (this.target_range.is_reversed)
                return [this.compute(x1), this.compute(x0)];
            else
                return [this.compute(x0), this.compute(x1)];
        }
        r_invert(sx0, sx1) {
            if (this.target_range.is_reversed)
                return [this.invert(sx1), this.invert(sx0)];
            else
                return [this.invert(sx0), this.invert(sx1)];
        }
    }
    exports.Scale = Scale;
    Scale.__name__ = "Scale";
    Scale.init_Scale();
},
/* models/transforms/index.js */ function _(require, module, exports) {
    var customjs_transform_1 = require(116) /* ./customjs_transform */;
    exports.CustomJSTransform = customjs_transform_1.CustomJSTransform;
    var dodge_1 = require(117) /* ./dodge */;
    exports.Dodge = dodge_1.Dodge;
    var interpolator_1 = require(118) /* ./interpolator */;
    exports.Interpolator = interpolator_1.Interpolator;
    var jitter_1 = require(119) /* ./jitter */;
    exports.Jitter = jitter_1.Jitter;
    var linear_interpolator_1 = require(120) /* ./linear_interpolator */;
    exports.LinearInterpolator = linear_interpolator_1.LinearInterpolator;
    var step_interpolator_1 = require(121) /* ./step_interpolator */;
    exports.StepInterpolator = step_interpolator_1.StepInterpolator;
    var transform_1 = require(112) /* ./transform */;
    exports.Transform = transform_1.Transform;
},
/* models/transforms/customjs_transform.js */ function _(require, module, exports) {
    const transform_1 = require(112) /* ./transform */;
    const p = require(18) /* ../../core/properties */;
    const object_1 = require(22) /* ../../core/util/object */;
    const string_1 = require(25) /* ../../core/util/string */;
    class CustomJSTransform extends transform_1.Transform {
        constructor(attrs) {
            super(attrs);
        }
        static init_CustomJSTransform() {
            this.define({
                args: [p.Any, {}],
                func: [p.String, ""],
                v_func: [p.String, ""],
                use_strict: [p.Boolean, false],
            });
        }
        get names() {
            return object_1.keys(this.args);
        }
        get values() {
            return object_1.values(this.args);
        }
        _make_transform(name, func) {
            const code = this.use_strict ? string_1.use_strict(func) : func;
            return new Function(...this.names, name, "require", "exports", code);
        }
        get scalar_transform() {
            return this._make_transform("x", this.func);
        }
        get vector_transform() {
            return this._make_transform("xs", this.v_func);
        }
        compute(x) {
            return this.scalar_transform(...this.values, x, require, {});
        }
        v_compute(xs) {
            return this.vector_transform(...this.values, xs, require, {});
        }
    }
    exports.CustomJSTransform = CustomJSTransform;
    CustomJSTransform.__name__ = "CustomJSTransform";
    CustomJSTransform.init_CustomJSTransform();
},
/* models/transforms/dodge.js */ function _(require, module, exports) {
    const transform_1 = require(112) /* ./transform */;
    const factor_range_1 = require(82) /* ../ranges/factor_range */;
    const p = require(18) /* ../../core/properties */;
    const types_1 = require(7) /* ../../core/util/types */;
    class Dodge extends transform_1.Transform {
        constructor(attrs) {
            super(attrs);
        }
        static init_Dodge() {
            this.define({
                value: [p.Number, 0],
                range: [p.Instance],
            });
        }
        // XXX: this is repeated in ./jitter.ts
        v_compute(xs0) {
            let xs;
            if (this.range instanceof factor_range_1.FactorRange)
                xs = this.range.v_synthetic(xs0);
            else if (types_1.isArrayableOf(xs0, types_1.isNumber))
                xs = xs0;
            else
                throw new Error("unexpected");
            const result = new Float64Array(xs.length);
            for (let i = 0; i < xs.length; i++) {
                const x = xs[i];
                result[i] = this._compute(x);
            }
            return result;
        }
        compute(x) {
            if (this.range instanceof factor_range_1.FactorRange)
                return this._compute(this.range.synthetic(x));
            else if (types_1.isNumber(x))
                return this._compute(x);
            else
                throw new Error("unexpected");
        }
        _compute(x) {
            return x + this.value;
        }
    }
    exports.Dodge = Dodge;
    Dodge.__name__ = "Dodge";
    Dodge.init_Dodge();
},
/* models/transforms/interpolator.js */ function _(require, module, exports) {
    const transform_1 = require(112) /* ./transform */;
    const p = require(18) /* ../../core/properties */;
    const array_1 = require(8) /* ../../core/util/array */;
    const types_1 = require(7) /* ../../core/util/types */;
    class Interpolator extends transform_1.Transform {
        constructor(attrs) {
            super(attrs);
            this._sorted_dirty = true;
        }
        static init_Interpolator() {
            this.define({
                x: [p.Any],
                y: [p.Any],
                data: [p.Any],
                clip: [p.Boolean, true],
            });
        }
        connect_signals() {
            super.connect_signals();
            this.connect(this.change, () => this._sorted_dirty = true);
        }
        v_compute(xs) {
            const result = new Float64Array(xs.length);
            for (let i = 0; i < xs.length; i++) {
                const x = xs[i];
                result[i] = this.compute(x);
            }
            return result;
        }
        sort(descending = false) {
            if (!this._sorted_dirty)
                return;
            let tsx;
            let tsy;
            if (types_1.isString(this.x) && types_1.isString(this.y) && this.data != null) {
                const column_names = this.data.columns();
                if (!array_1.includes(column_names, this.x))
                    throw new Error("The x parameter does not correspond to a valid column name defined in the data parameter");
                if (!array_1.includes(column_names, this.y))
                    throw new Error("The y parameter does not correspond to a valid column name defined in the data parameter");
                tsx = this.data.get_column(this.x);
                tsy = this.data.get_column(this.y);
            }
            else if (types_1.isArray(this.x) && types_1.isArray(this.y)) {
                tsx = this.x;
                tsy = this.y;
            }
            else {
                throw new Error("parameters 'x' and 'y' must be both either string fields or arrays");
            }
            if (tsx.length !== tsy.length)
                throw new Error("The length for x and y do not match");
            if (tsx.length < 2)
                throw new Error("x and y must have at least two elements to support interpolation");
            // The following sorting code is referenced from:
            // http://stackoverflow.com/questions/11499268/sort-two-arrays-the-same-way
            const list = [];
            for (const j in tsx) {
                list.push({ x: tsx[j], y: tsy[j] });
            }
            if (descending)
                list.sort((a, b) => a.x > b.x ? -1 : (a.x == b.x ? 0 : 1));
            else
                list.sort((a, b) => a.x < b.x ? -1 : (a.x == b.x ? 0 : 1));
            this._x_sorted = [];
            this._y_sorted = [];
            for (const { x, y } of list) {
                this._x_sorted.push(x);
                this._y_sorted.push(y);
            }
            this._sorted_dirty = false;
        }
    }
    exports.Interpolator = Interpolator;
    Interpolator.__name__ = "Interpolator";
    Interpolator.init_Interpolator();
},
/* models/transforms/jitter.js */ function _(require, module, exports) {
    const transform_1 = require(112) /* ./transform */;
    const factor_range_1 = require(82) /* ../ranges/factor_range */;
    const types_1 = require(7) /* ../../core/util/types */;
    const p = require(18) /* ../../core/properties */;
    const bokeh_math = require(9) /* ../../core/util/math */;
    class Jitter extends transform_1.Transform {
        constructor(attrs) {
            super(attrs);
        }
        static init_Jitter() {
            this.define({
                mean: [p.Number, 0],
                width: [p.Number, 1],
                distribution: [p.Distribution, 'uniform'],
                range: [p.Instance],
            });
            this.internal({
                previous_values: [p.Array],
            });
        }
        v_compute(xs0) {
            if (this.previous_values != null && this.previous_values.length == xs0.length)
                return this.previous_values;
            let xs;
            if (this.range instanceof factor_range_1.FactorRange)
                xs = this.range.v_synthetic(xs0);
            else if (types_1.isArrayableOf(xs0, types_1.isNumber))
                xs = xs0;
            else
                throw new Error("unexpected");
            const result = new Float64Array(xs.length);
            for (let i = 0; i < xs.length; i++) {
                const x = xs[i];
                result[i] = this._compute(x);
            }
            this.previous_values = result;
            return result;
        }
        compute(x) {
            if (this.range instanceof factor_range_1.FactorRange)
                return this._compute(this.range.synthetic(x));
            else if (types_1.isNumber(x))
                return this._compute(x);
            else
                throw new Error("unexpected");
        }
        _compute(x) {
            switch (this.distribution) {
                case "uniform":
                    return x + this.mean + (bokeh_math.random() - 0.5) * this.width;
                case "normal":
                    return x + bokeh_math.rnorm(this.mean, this.width);
            }
        }
    }
    exports.Jitter = Jitter;
    Jitter.__name__ = "Jitter";
    Jitter.init_Jitter();
},
/* models/transforms/linear_interpolator.js */ function _(require, module, exports) {
    const array_1 = require(8) /* ../../core/util/array */;
    const interpolator_1 = require(118) /* ./interpolator */;
    class LinearInterpolator extends interpolator_1.Interpolator {
        constructor(attrs) {
            super(attrs);
        }
        compute(x) {
            this.sort(false);
            if (this.clip) {
                if (x < this._x_sorted[0] || x > this._x_sorted[this._x_sorted.length - 1])
                    return NaN;
            }
            else {
                if (x < this._x_sorted[0])
                    return this._y_sorted[0];
                if (x > this._x_sorted[this._x_sorted.length - 1])
                    return this._y_sorted[this._y_sorted.length - 1];
            }
            if (x == this._x_sorted[0])
                return this._y_sorted[0];
            const ind = array_1.find_last_index(this._x_sorted, num => num < x);
            const x1 = this._x_sorted[ind];
            const x2 = this._x_sorted[ind + 1];
            const y1 = this._y_sorted[ind];
            const y2 = this._y_sorted[ind + 1];
            return y1 + (((x - x1) / (x2 - x1)) * (y2 - y1));
        }
    }
    exports.LinearInterpolator = LinearInterpolator;
    LinearInterpolator.__name__ = "LinearInterpolator";
},
/* models/transforms/step_interpolator.js */ function _(require, module, exports) {
    const interpolator_1 = require(118) /* ./interpolator */;
    const p = require(18) /* ../../core/properties */;
    const array_1 = require(8) /* ../../core/util/array */;
    class StepInterpolator extends interpolator_1.Interpolator {
        constructor(attrs) {
            super(attrs);
        }
        static init_StepInterpolator() {
            this.define({
                mode: [p.StepMode, "after"],
            });
        }
        compute(x) {
            this.sort(false);
            if (this.clip) {
                if (x < this._x_sorted[0] || x > this._x_sorted[this._x_sorted.length - 1])
                    return NaN;
            }
            else {
                if (x < this._x_sorted[0])
                    return this._y_sorted[0];
                if (x > this._x_sorted[this._x_sorted.length - 1])
                    return this._y_sorted[this._y_sorted.length - 1];
            }
            let ind;
            switch (this.mode) {
                case "after": {
                    ind = array_1.find_last_index(this._x_sorted, num => x >= num);
                    break;
                }
                case "before": {
                    ind = array_1.find_index(this._x_sorted, num => x <= num);
                    break;
                }
                case "center": {
                    const diffs = this._x_sorted.map((tx) => Math.abs(tx - x));
                    const mdiff = array_1.min(diffs);
                    ind = array_1.find_index(diffs, num => mdiff === num);
                    break;
                }
                default:
                    throw new Error(`unknown mode: ${this.mode}`);
            }
            return ind != -1 ? this._y_sorted[ind] : NaN;
        }
    }
    exports.StepInterpolator = StepInterpolator;
    StepInterpolator.__name__ = "StepInterpolator";
    StepInterpolator.init_StepInterpolator();
},
/* models/scales/log_scale.js */ function _(require, module, exports) {
    const scale_1 = require(114) /* ./scale */;
    class LogScale extends scale_1.Scale {
        constructor(attrs) {
            super(attrs);
        }
        compute(x) {
            const [factor, offset, inter_factor, inter_offset] = this._compute_state();
            let value;
            if (inter_factor == 0)
                value = 0;
            else {
                const _x = (Math.log(x) - inter_offset) / inter_factor;
                if (isFinite(_x))
                    value = _x * factor + offset;
                else
                    value = NaN;
            }
            return value;
        }
        v_compute(xs) {
            const [factor, offset, inter_factor, inter_offset] = this._compute_state();
            const result = new Float64Array(xs.length);
            if (inter_factor == 0) {
                for (let i = 0; i < xs.length; i++)
                    result[i] = 0;
            }
            else {
                for (let i = 0; i < xs.length; i++) {
                    const _x = (Math.log(xs[i]) - inter_offset) / inter_factor;
                    let value;
                    if (isFinite(_x))
                        value = _x * factor + offset;
                    else
                        value = NaN;
                    result[i] = value;
                }
            }
            return result;
        }
        invert(xprime) {
            const [factor, offset, inter_factor, inter_offset] = this._compute_state();
            const value = (xprime - offset) / factor;
            return Math.exp(inter_factor * value + inter_offset);
        }
        v_invert(xprimes) {
            const [factor, offset, inter_factor, inter_offset] = this._compute_state();
            const result = new Float64Array(xprimes.length);
            for (let i = 0; i < xprimes.length; i++) {
                const value = (xprimes[i] - offset) / factor;
                result[i] = Math.exp(inter_factor * value + inter_offset);
            }
            return result;
        }
        _get_safe_factor(orig_start, orig_end) {
            let start = orig_start < 0 ? 0 : orig_start;
            let end = orig_end < 0 ? 0 : orig_end;
            if (start == end) {
                if (start == 0)
                    [start, end] = [1, 10];
                else {
                    const log_val = Math.log(start) / Math.log(10);
                    start = Math.pow(10, Math.floor(log_val));
                    if (Math.ceil(log_val) != Math.floor(log_val))
                        end = Math.pow(10, Math.ceil(log_val));
                    else
                        end = Math.pow(10, Math.ceil(log_val) + 1);
                }
            }
            return [start, end];
        }
        /*protected*/ _compute_state() {
            const source_start = this.source_range.start;
            const source_end = this.source_range.end;
            const target_start = this.target_range.start;
            const target_end = this.target_range.end;
            const screen_range = target_end - target_start;
            const [start, end] = this._get_safe_factor(source_start, source_end);
            let inter_factor;
            let inter_offset;
            if (start == 0) {
                inter_factor = Math.log(end);
                inter_offset = 0;
            }
            else {
                inter_factor = Math.log(end) - Math.log(start);
                inter_offset = Math.log(start);
            }
            const factor = screen_range;
            const offset = target_start;
            return [factor, offset, inter_factor, inter_offset];
        }
    }
    exports.LogScale = LogScale;
    LogScale.__name__ = "LogScale";
},
/* models/ranges/range1d.js */ function _(require, module, exports) {
    const range_1 = require(83) /* ./range */;
    const p = require(18) /* ../../core/properties */;
    class Range1d extends range_1.Range {
        constructor(attrs) {
            super(attrs);
        }
        static init_Range1d() {
            this.define({
                start: [p.Number, 0],
                end: [p.Number, 1],
                reset_start: [p.Number],
                reset_end: [p.Number],
            });
        }
        _set_auto_bounds() {
            if (this.bounds == 'auto') {
                const min = Math.min(this.reset_start, this.reset_end);
                const max = Math.max(this.reset_start, this.reset_end);
                this.setv({ bounds: [min, max] }, { silent: true });
            }
        }
        initialize() {
            super.initialize();
            if (this.reset_start == null) {
                this.reset_start = this.start;
            }
            if (this.reset_end == null) {
                this.reset_end = this.end;
            }
            this._set_auto_bounds();
        }
        get min() {
            return Math.min(this.start, this.end);
        }
        get max() {
            return Math.max(this.start, this.end);
        }
        reset() {
            this._set_auto_bounds();
            if (this.start != this.reset_start || this.end != this.reset_end)
                this.setv({ start: this.reset_start, end: this.reset_end });
            else
                this.change.emit();
        }
    }
    exports.Range1d = Range1d;
    Range1d.__name__ = "Range1d";
    Range1d.init_Range1d();
},
/* core/util/text.js */ function _(require, module, exports) {
    const dom_1 = require(61) /* ../dom */;
    const cache = {};
    function measure_font(font) {
        if (cache[font] != null)
            return cache[font];
        const text = dom_1.span({ style: { font } }, "Hg");
        const block = dom_1.div({ style: { display: "inline-block", width: "1px", height: "0px" } });
        const elem = dom_1.div({}, text, block);
        document.body.appendChild(elem);
        try {
            block.style.verticalAlign = "baseline";
            const ascent = dom_1.offset(block).top - dom_1.offset(text).top;
            block.style.verticalAlign = "bottom";
            const height = dom_1.offset(block).top - dom_1.offset(text).top;
            const result = { height, ascent, descent: height - ascent };
            cache[font] = result;
            return result;
        }
        finally {
            document.body.removeChild(elem);
        }
    }
    exports.measure_font = measure_font;
    const _cache = {};
    function measure_text(text, font) {
        const text_cache = _cache[font];
        if (text_cache != null) {
            const size = text_cache[text];
            if (size != null)
                return size;
        }
        else
            _cache[font] = {};
        const el = dom_1.div({ style: { display: "inline-block", "white-space": "nowrap", font } }, text);
        document.body.appendChild(el);
        try {
            const { width, height } = el.getBoundingClientRect();
            _cache[font][text] = { width, height };
            return { width, height };
        }
        finally {
            document.body.removeChild(el);
        }
    }
    exports.measure_text = measure_text;
},
/* models/annotations/label.js */ function _(require, module, exports) {
    const text_annotation_1 = require(126) /* ./text_annotation */;
    const dom_1 = require(61) /* ../../core/dom */;
    const p = require(18) /* ../../core/properties */;
    class LabelView extends text_annotation_1.TextAnnotationView {
        initialize() {
            super.initialize();
            this.visuals.warm_cache();
        }
        _get_size() {
            const { ctx } = this.plot_view.canvas_view;
            this.visuals.text.set_value(ctx);
            const { width, ascent } = ctx.measureText(this.model.text);
            return { width, height: ascent };
        }
        render() {
            if (!this.model.visible && this.model.render_mode == 'css')
                dom_1.undisplay(this.el);
            if (!this.model.visible)
                return;
            // Here because AngleSpec does units transform and label doesn't support specs
            let angle;
            switch (this.model.angle_units) {
                case "rad": {
                    angle = -this.model.angle;
                    break;
                }
                case "deg": {
                    angle = (-this.model.angle * Math.PI) / 180.0;
                    break;
                }
                default:
                    throw new Error("unreachable code");
            }
            const panel = this.panel != null ? this.panel : this.plot_view.frame;
            const xscale = this.plot_view.frame.xscales[this.model.x_range_name];
            const yscale = this.plot_view.frame.yscales[this.model.y_range_name];
            let sx = this.model.x_units == "data" ? xscale.compute(this.model.x) : panel.xview.compute(this.model.x);
            let sy = this.model.y_units == "data" ? yscale.compute(this.model.y) : panel.yview.compute(this.model.y);
            sx += this.model.x_offset;
            sy -= this.model.y_offset;
            const draw = this.model.render_mode == 'canvas' ? this._canvas_text.bind(this) : this._css_text.bind(this);
            draw(this.plot_view.canvas_view.ctx, this.model.text, sx, sy, angle);
        }
    }
    exports.LabelView = LabelView;
    LabelView.__name__ = "LabelView";
    class Label extends text_annotation_1.TextAnnotation {
        constructor(attrs) {
            super(attrs);
        }
        static init_Label() {
            this.prototype.default_view = LabelView;
            this.mixins(['text', 'line:border_', 'fill:background_']);
            this.define({
                x: [p.Number],
                x_units: [p.SpatialUnits, 'data'],
                y: [p.Number],
                y_units: [p.SpatialUnits, 'data'],
                text: [p.String],
                angle: [p.Angle, 0],
                angle_units: [p.AngleUnits, 'rad'],
                x_offset: [p.Number, 0],
                y_offset: [p.Number, 0],
                x_range_name: [p.String, 'default'],
                y_range_name: [p.String, 'default'],
            });
            this.override({
                background_fill_color: null,
                border_line_color: null,
            });
        }
    }
    exports.Label = Label;
    Label.__name__ = "Label";
    Label.init_Label();
},
/* models/annotations/text_annotation.js */ function _(require, module, exports) {
    const annotation_1 = require(29) /* ./annotation */;
    const dom_1 = require(61) /* ../../core/dom */;
    const p = require(18) /* ../../core/properties */;
    const text_1 = require(124) /* ../../core/util/text */;
    const annotations_1 = require(100) /* ../../styles/annotations */;
    class TextAnnotationView extends annotation_1.AnnotationView {
        constructor() {
            super(...arguments);
            this.rotate = true;
        }
        initialize() {
            super.initialize();
            if (this.model.render_mode == 'css') {
                this.el.classList.add(annotations_1.bk_annotation);
                this.plot_view.canvas_overlays.appendChild(this.el);
            }
        }
        connect_signals() {
            super.connect_signals();
            if (this.model.render_mode == 'css') {
                // dispatch CSS update immediately
                this.connect(this.model.change, () => this.render());
            }
            else {
                this.connect(this.model.change, () => this.plot_view.request_render());
            }
        }
        _calculate_text_dimensions(ctx, text) {
            const { width } = ctx.measureText(text);
            const { height } = text_1.measure_font(this.visuals.text.font_value());
            return [width, height];
        }
        _calculate_bounding_box_dimensions(ctx, text) {
            const [width, height] = this._calculate_text_dimensions(ctx, text);
            let x_offset;
            switch (ctx.textAlign) {
                case 'left':
                    x_offset = 0;
                    break;
                case 'center':
                    x_offset = -width / 2;
                    break;
                case 'right':
                    x_offset = -width;
                    break;
                default:
                    throw new Error("unreachable code");
            }
            // guestimated from https://www.w3.org/TR/2dcontext/#dom-context-2d-textbaseline
            let y_offset;
            switch (ctx.textBaseline) {
                case 'top':
                    y_offset = 0.0;
                    break;
                case 'middle':
                    y_offset = -0.5 * height;
                    break;
                case 'bottom':
                    y_offset = -1.0 * height;
                    break;
                case 'alphabetic':
                    y_offset = -0.8 * height;
                    break;
                case 'hanging':
                    y_offset = -0.17 * height;
                    break;
                case 'ideographic':
                    y_offset = -0.83 * height;
                    break;
                default:
                    throw new Error("unreachable code");
            }
            return [x_offset, y_offset, width, height];
        }
        _canvas_text(ctx, text, sx, sy, angle) {
            this.visuals.text.set_value(ctx);
            const bbox_dims = this._calculate_bounding_box_dimensions(ctx, text);
            ctx.save();
            ctx.beginPath();
            ctx.translate(sx, sy);
            if (angle)
                ctx.rotate(angle);
            ctx.rect(bbox_dims[0], bbox_dims[1], bbox_dims[2], bbox_dims[3]);
            if (this.visuals.background_fill.doit) {
                this.visuals.background_fill.set_value(ctx);
                ctx.fill();
            }
            if (this.visuals.border_line.doit) {
                this.visuals.border_line.set_value(ctx);
                ctx.stroke();
            }
            if (this.visuals.text.doit) {
                this.visuals.text.set_value(ctx);
                ctx.fillText(text, 0, 0);
            }
            ctx.restore();
        }
        _css_text(ctx, text, sx, sy, angle) {
            dom_1.undisplay(this.el);
            this.visuals.text.set_value(ctx);
            const bbox_dims = this._calculate_bounding_box_dimensions(ctx, text);
            // attempt to support vector string-style ("8 4 8") line dashing for css mode
            const ld = this.visuals.border_line.line_dash.value();
            const line_dash = ld.length < 2 ? "solid" : "dashed";
            this.visuals.border_line.set_value(ctx);
            this.visuals.background_fill.set_value(ctx);
            this.el.style.position = 'absolute';
            this.el.style.left = `${sx + bbox_dims[0]}px`;
            this.el.style.top = `${sy + bbox_dims[1]}px`;
            this.el.style.color = `${this.visuals.text.text_color.value()}`;
            this.el.style.opacity = `${this.visuals.text.text_alpha.value()}`;
            this.el.style.font = `${this.visuals.text.font_value()}`;
            this.el.style.lineHeight = "normal"; // needed to prevent ipynb css override
            if (angle) {
                this.el.style.transform = `rotate(${angle}rad)`;
            }
            if (this.visuals.background_fill.doit) {
                this.el.style.backgroundColor = `${this.visuals.background_fill.color_value()}`;
            }
            if (this.visuals.border_line.doit) {
                this.el.style.borderStyle = `${line_dash}`;
                this.el.style.borderWidth = `${this.visuals.border_line.line_width.value()}px`;
                this.el.style.borderColor = `${this.visuals.border_line.color_value()}`;
            }
            this.el.textContent = text;
            dom_1.display(this.el);
        }
    }
    exports.TextAnnotationView = TextAnnotationView;
    TextAnnotationView.__name__ = "TextAnnotationView";
    class TextAnnotation extends annotation_1.Annotation {
        constructor(attrs) {
            super(attrs);
        }
        static init_TextAnnotation() {
            this.define({
                render_mode: [p.RenderMode, "canvas"],
            });
        }
    }
    exports.TextAnnotation = TextAnnotation;
    TextAnnotation.__name__ = "TextAnnotation";
    TextAnnotation.init_TextAnnotation();
},
/* models/annotations/label_set.js */ function _(require, module, exports) {
    const text_annotation_1 = require(126) /* ./text_annotation */;
    const column_data_source_1 = require(68) /* ../sources/column_data_source */;
    const dom_1 = require(61) /* ../../core/dom */;
    const p = require(18) /* ../../core/properties */;
    const annotations_1 = require(100) /* ../../styles/annotations */;
    class LabelSetView extends text_annotation_1.TextAnnotationView {
        initialize() {
            super.initialize();
            this.set_data(this.model.source);
            if (this.model.render_mode == 'css') {
                for (let i = 0, end = this._text.length; i < end; i++) {
                    const el = dom_1.div({ class: annotations_1.bk_annotation_child, style: { display: "none" } });
                    this.el.appendChild(el);
                }
            }
        }
        connect_signals() {
            super.connect_signals();
            if (this.model.render_mode == 'css') {
                // dispatch CSS update immediately
                this.connect(this.model.change, () => {
                    this.set_data(this.model.source);
                    this.render();
                });
                this.connect(this.model.source.streaming, () => {
                    this.set_data(this.model.source);
                    this.render();
                });
                this.connect(this.model.source.patching, () => {
                    this.set_data(this.model.source);
                    this.render();
                });
                this.connect(this.model.source.change, () => {
                    this.set_data(this.model.source);
                    this.render();
                });
            }
            else {
                this.connect(this.model.change, () => {
                    this.set_data(this.model.source);
                    this.plot_view.request_render();
                });
                this.connect(this.model.source.streaming, () => {
                    this.set_data(this.model.source);
                    this.plot_view.request_render();
                });
                this.connect(this.model.source.patching, () => {
                    this.set_data(this.model.source);
                    this.plot_view.request_render();
                });
                this.connect(this.model.source.change, () => {
                    this.set_data(this.model.source);
                    this.plot_view.request_render();
                });
            }
        }
        set_data(source) {
            super.set_data(source);
            this.visuals.warm_cache(source);
        }
        _map_data() {
            const xscale = this.plot_view.frame.xscales[this.model.x_range_name];
            const yscale = this.plot_view.frame.yscales[this.model.y_range_name];
            const panel = this.panel != null ? this.panel : this.plot_view.frame;
            const sx = this.model.x_units == "data" ? xscale.v_compute(this._x) : panel.xview.v_compute(this._x);
            const sy = this.model.y_units == "data" ? yscale.v_compute(this._y) : panel.yview.v_compute(this._y);
            return [sx, sy];
        }
        render() {
            if (!this.model.visible && this.model.render_mode == 'css')
                dom_1.undisplay(this.el);
            if (!this.model.visible)
                return;
            const draw = this.model.render_mode == 'canvas' ? this._v_canvas_text.bind(this) : this._v_css_text.bind(this);
            const { ctx } = this.plot_view.canvas_view;
            const [sx, sy] = this._map_data();
            for (let i = 0, end = this._text.length; i < end; i++) {
                draw(ctx, i, this._text[i], sx[i] + this._x_offset[i], sy[i] - this._y_offset[i], this._angle[i]);
            }
        }
        _get_size() {
            const { ctx } = this.plot_view.canvas_view;
            this.visuals.text.set_value(ctx);
            const { width, ascent } = ctx.measureText(this._text[0]);
            return { width, height: ascent };
        }
        _v_canvas_text(ctx, i, text, sx, sy, angle) {
            this.visuals.text.set_vectorize(ctx, i);
            const bbox_dims = this._calculate_bounding_box_dimensions(ctx, text);
            ctx.save();
            ctx.beginPath();
            ctx.translate(sx, sy);
            ctx.rotate(angle);
            ctx.rect(bbox_dims[0], bbox_dims[1], bbox_dims[2], bbox_dims[3]);
            if (this.visuals.background_fill.doit) {
                this.visuals.background_fill.set_vectorize(ctx, i);
                ctx.fill();
            }
            if (this.visuals.border_line.doit) {
                this.visuals.border_line.set_vectorize(ctx, i);
                ctx.stroke();
            }
            if (this.visuals.text.doit) {
                this.visuals.text.set_vectorize(ctx, i);
                ctx.fillText(text, 0, 0);
            }
            ctx.restore();
        }
        _v_css_text(ctx, i, text, sx, sy, angle) {
            const el = this.el.children[i];
            el.textContent = text;
            this.visuals.text.set_vectorize(ctx, i);
            const bbox_dims = this._calculate_bounding_box_dimensions(ctx, text);
            // attempt to support vector-style ("8 4 8") line dashing for css mode
            const ld = this.visuals.border_line.line_dash.value();
            const line_dash = ld.length < 2 ? "solid" : "dashed";
            this.visuals.border_line.set_vectorize(ctx, i);
            this.visuals.background_fill.set_vectorize(ctx, i);
            el.style.position = 'absolute';
            el.style.left = `${sx + bbox_dims[0]}px`;
            el.style.top = `${sy + bbox_dims[1]}px`;
            el.style.color = `${this.visuals.text.text_color.value()}`;
            el.style.opacity = `${this.visuals.text.text_alpha.value()}`;
            el.style.font = `${this.visuals.text.font_value()}`;
            el.style.lineHeight = "normal"; // needed to prevent ipynb css override
            if (angle) {
                el.style.transform = `rotate(${angle}rad)`;
            }
            if (this.visuals.background_fill.doit) {
                el.style.backgroundColor = `${this.visuals.background_fill.color_value()}`;
            }
            if (this.visuals.border_line.doit) {
                el.style.borderStyle = `${line_dash}`;
                el.style.borderWidth = `${this.visuals.border_line.line_width.value()}px`;
                el.style.borderColor = `${this.visuals.border_line.color_value()}`;
            }
            dom_1.display(el);
        }
    }
    exports.LabelSetView = LabelSetView;
    LabelSetView.__name__ = "LabelSetView";
    class LabelSet extends text_annotation_1.TextAnnotation {
        constructor(attrs) {
            super(attrs);
        }
        static init_LabelSet() {
            this.prototype.default_view = LabelSetView;
            this.mixins(['text', 'line:border_', 'fill:background_']);
            this.define({
                x: [p.NumberSpec],
                y: [p.NumberSpec],
                x_units: [p.SpatialUnits, 'data'],
                y_units: [p.SpatialUnits, 'data'],
                text: [p.StringSpec, { field: "text" }],
                angle: [p.AngleSpec, 0],
                x_offset: [p.NumberSpec, { value: 0 }],
                y_offset: [p.NumberSpec, { value: 0 }],
                source: [p.Instance, () => new column_data_source_1.ColumnDataSource()],
                x_range_name: [p.String, 'default'],
                y_range_name: [p.String, 'default'],
            });
            this.override({
                background_fill_color: null,
                border_line_color: null,
            });
        }
    }
    exports.LabelSet = LabelSet;
    LabelSet.__name__ = "LabelSet";
    LabelSet.init_LabelSet();
},
/* models/annotations/legend.js */ function _(require, module, exports) {
    const annotation_1 = require(29) /* ./annotation */;
    const p = require(18) /* ../../core/properties */;
    const signaling_1 = require(13) /* ../../core/signaling */;
    const text_1 = require(124) /* ../../core/util/text */;
    const bbox_1 = require(79) /* ../../core/util/bbox */;
    const array_1 = require(8) /* ../../core/util/array */;
    const object_1 = require(22) /* ../../core/util/object */;
    const types_1 = require(7) /* ../../core/util/types */;
    class LegendView extends annotation_1.AnnotationView {
        cursor(_sx, _sy) {
            return this.model.click_policy == "none" ? null : "pointer";
        }
        get legend_padding() {
            return this.visuals.border_line.line_color.value() != null ? this.model.padding : 0;
        }
        connect_signals() {
            super.connect_signals();
            this.connect(this.model.change, () => this.plot_view.request_render());
            this.connect(this.model.item_change, () => this.plot_view.request_render());
        }
        compute_legend_bbox() {
            const legend_names = this.model.get_legend_names();
            const { glyph_height, glyph_width } = this.model;
            const { label_height, label_width } = this.model;
            this.max_label_height = array_1.max([text_1.measure_font(this.visuals.label_text.font_value()).height, label_height, glyph_height]);
            // this is to measure text properties
            const { ctx } = this.plot_view.canvas_view;
            ctx.save();
            this.visuals.label_text.set_value(ctx);
            this.text_widths = {};
            for (const name of legend_names) {
                this.text_widths[name] = array_1.max([ctx.measureText(name).width, label_width]);
            }
            this.visuals.title_text.set_value(ctx);
            this.title_height = this.model.title ? text_1.measure_font(this.visuals.title_text.font_value()).height + this.model.title_standoff : 0;
            this.title_width = this.model.title ? ctx.measureText(this.model.title).width : 0;
            ctx.restore();
            const max_label_width = Math.max(array_1.max(object_1.values(this.text_widths)), 0);
            const legend_margin = this.model.margin;
            const { legend_padding } = this;
            const legend_spacing = this.model.spacing;
            const { label_standoff } = this.model;
            let legend_height, legend_width;
            if (this.model.orientation == "vertical") {
                legend_height = legend_names.length * this.max_label_height + Math.max(legend_names.length - 1, 0) * legend_spacing + 2 * legend_padding + this.title_height;
                legend_width = array_1.max([(max_label_width + glyph_width + label_standoff + 2 * legend_padding), this.title_width + 2 * legend_padding]);
            }
            else {
                let item_width = 2 * legend_padding + Math.max(legend_names.length - 1, 0) * legend_spacing;
                for (const name in this.text_widths) {
                    const width = this.text_widths[name];
                    item_width += array_1.max([width, label_width]) + glyph_width + label_standoff;
                }
                legend_width = array_1.max([this.title_width + 2 * legend_padding, item_width]);
                legend_height = this.max_label_height + this.title_height + 2 * legend_padding;
            }
            const panel = this.panel != null ? this.panel : this.plot_view.frame;
            const [hr, vr] = panel.bbox.ranges;
            const { location } = this.model;
            let sx, sy;
            if (types_1.isString(location)) {
                switch (location) {
                    case 'top_left':
                        sx = hr.start + legend_margin;
                        sy = vr.start + legend_margin;
                        break;
                    case 'top_center':
                        sx = (hr.end + hr.start) / 2 - legend_width / 2;
                        sy = vr.start + legend_margin;
                        break;
                    case 'top_right':
                        sx = hr.end - legend_margin - legend_width;
                        sy = vr.start + legend_margin;
                        break;
                    case 'bottom_right':
                        sx = hr.end - legend_margin - legend_width;
                        sy = vr.end - legend_margin - legend_height;
                        break;
                    case 'bottom_center':
                        sx = (hr.end + hr.start) / 2 - legend_width / 2;
                        sy = vr.end - legend_margin - legend_height;
                        break;
                    case 'bottom_left':
                        sx = hr.start + legend_margin;
                        sy = vr.end - legend_margin - legend_height;
                        break;
                    case 'center_left':
                        sx = hr.start + legend_margin;
                        sy = (vr.end + vr.start) / 2 - legend_height / 2;
                        break;
                    case 'center':
                        sx = (hr.end + hr.start) / 2 - legend_width / 2;
                        sy = (vr.end + vr.start) / 2 - legend_height / 2;
                        break;
                    case 'center_right':
                        sx = hr.end - legend_margin - legend_width;
                        sy = (vr.end + vr.start) / 2 - legend_height / 2;
                        break;
                    default:
                        throw new Error("unreachable code");
                }
            }
            else if (types_1.isArray(location) && location.length == 2) {
                const [vx, vy] = location;
                sx = panel.xview.compute(vx);
                sy = panel.yview.compute(vy) - legend_height;
            }
            else
                throw new Error("unreachable code");
            return new bbox_1.BBox({ left: sx, top: sy, width: legend_width, height: legend_height });
        }
        interactive_bbox() {
            return this.compute_legend_bbox();
        }
        interactive_hit(sx, sy) {
            const bbox = this.interactive_bbox();
            return bbox.contains(sx, sy);
        }
        on_hit(sx, sy) {
            let yoffset;
            const { glyph_width } = this.model;
            const { legend_padding } = this;
            const legend_spacing = this.model.spacing;
            const { label_standoff } = this.model;
            let xoffset = (yoffset = legend_padding);
            const legend_bbox = this.compute_legend_bbox();
            const vertical = this.model.orientation == "vertical";
            for (const item of this.model.items) {
                const labels = item.get_labels_list_from_label_prop();
                for (const label of labels) {
                    const x1 = legend_bbox.x + xoffset;
                    const y1 = legend_bbox.y + yoffset + this.title_height;
                    let w, h;
                    if (vertical)
                        [w, h] = [legend_bbox.width - 2 * legend_padding, this.max_label_height];
                    else
                        [w, h] = [this.text_widths[label] + glyph_width + label_standoff, this.max_label_height];
                    const bbox = new bbox_1.BBox({ left: x1, top: y1, width: w, height: h });
                    if (bbox.contains(sx, sy)) {
                        switch (this.model.click_policy) {
                            case "hide": {
                                for (const r of item.renderers)
                                    r.visible = !r.visible;
                                break;
                            }
                            case "mute": {
                                for (const r of item.renderers)
                                    r.muted = !r.muted;
                                break;
                            }
                        }
                        return true;
                    }
                    if (vertical)
                        yoffset += this.max_label_height + legend_spacing;
                    else
                        xoffset += this.text_widths[label] + glyph_width + label_standoff + legend_spacing;
                }
            }
            return false;
        }
        render() {
            if (!this.model.visible)
                return;
            if (this.model.items.length == 0)
                return;
            // set a backref on render so that items can later signal item_change upates
            // on the model to trigger a re-render
            for (const item of this.model.items) {
                item.legend = this.model;
            }
            const { ctx } = this.plot_view.canvas_view;
            const bbox = this.compute_legend_bbox();
            ctx.save();
            this._draw_legend_box(ctx, bbox);
            this._draw_legend_items(ctx, bbox);
            if (this.model.title)
                this._draw_title(ctx, bbox);
            ctx.restore();
        }
        _draw_legend_box(ctx, bbox) {
            ctx.beginPath();
            ctx.rect(bbox.x, bbox.y, bbox.width, bbox.height);
            this.visuals.background_fill.set_value(ctx);
            ctx.fill();
            if (this.visuals.border_line.doit) {
                this.visuals.border_line.set_value(ctx);
                ctx.stroke();
            }
        }
        _draw_legend_items(ctx, bbox) {
            const { glyph_width, glyph_height } = this.model;
            const { legend_padding } = this;
            const legend_spacing = this.model.spacing;
            const { label_standoff } = this.model;
            let xoffset = legend_padding;
            let yoffset = legend_padding;
            const vertical = this.model.orientation == "vertical";
            for (const item of this.model.items) {
                const labels = item.get_labels_list_from_label_prop();
                const field = item.get_field_from_label_prop();
                if (labels.length == 0)
                    continue;
                const active = (() => {
                    switch (this.model.click_policy) {
                        case "none": return true;
                        case "hide": return array_1.every(item.renderers, r => r.visible);
                        case "mute": return array_1.every(item.renderers, r => !r.muted);
                    }
                })();
                for (const label of labels) {
                    const x1 = bbox.x + xoffset;
                    const y1 = bbox.y + yoffset + this.title_height;
                    const x2 = x1 + glyph_width;
                    const y2 = y1 + glyph_height;
                    if (vertical)
                        yoffset += this.max_label_height + legend_spacing;
                    else
                        xoffset += this.text_widths[label] + glyph_width + label_standoff + legend_spacing;
                    this.visuals.label_text.set_value(ctx);
                    ctx.fillText(label, x2 + label_standoff, y1 + this.max_label_height / 2.0);
                    for (const r of item.renderers) {
                        const view = this.plot_view.renderer_views[r.id];
                        view.draw_legend(ctx, x1, x2, y1, y2, field, label, item.index);
                    }
                    if (!active) {
                        let w, h;
                        if (vertical)
                            [w, h] = [bbox.width - 2 * legend_padding, this.max_label_height];
                        else
                            [w, h] = [this.text_widths[label] + glyph_width + label_standoff, this.max_label_height];
                        ctx.beginPath();
                        ctx.rect(x1, y1, w, h);
                        this.visuals.inactive_fill.set_value(ctx);
                        ctx.fill();
                    }
                }
            }
        }
        _draw_title(ctx, bbox) {
            if (!this.visuals.title_text.doit)
                return;
            ctx.save();
            ctx.translate(bbox.x0, bbox.y0 + this.title_height);
            this.visuals.title_text.set_value(ctx);
            ctx.fillText(this.model.title, this.legend_padding, this.legend_padding - this.model.title_standoff);
            ctx.restore();
        }
        _get_size() {
            const { width, height } = this.compute_legend_bbox();
            return {
                width: width + 2 * this.model.margin,
                height: height + 2 * this.model.margin,
            };
        }
    }
    exports.LegendView = LegendView;
    LegendView.__name__ = "LegendView";
    class Legend extends annotation_1.Annotation {
        constructor(attrs) {
            super(attrs);
        }
        initialize() {
            super.initialize();
            this.item_change = new signaling_1.Signal0(this, "item_change");
        }
        static init_Legend() {
            this.prototype.default_view = LegendView;
            this.mixins([
                'text:label_',
                'text:title_',
                'fill:inactive_',
                'line:border_',
                'fill:background_',
            ]);
            this.define({
                orientation: [p.Orientation, 'vertical'],
                location: [p.Any, 'top_right'],
                title: [p.String],
                title_standoff: [p.Number, 5],
                label_standoff: [p.Number, 5],
                glyph_height: [p.Number, 20],
                glyph_width: [p.Number, 20],
                label_height: [p.Number, 20],
                label_width: [p.Number, 20],
                margin: [p.Number, 10],
                padding: [p.Number, 10],
                spacing: [p.Number, 3],
                items: [p.Array, []],
                click_policy: [p.Any, "none"],
            });
            this.override({
                border_line_color: "#e5e5e5",
                border_line_alpha: 0.5,
                border_line_width: 1,
                background_fill_color: "#ffffff",
                background_fill_alpha: 0.95,
                inactive_fill_color: "white",
                inactive_fill_alpha: 0.7,
                label_text_font_size: "10pt",
                label_text_baseline: "middle",
                title_text_font_size: "10pt",
                title_text_font_style: "italic",
            });
        }
        get_legend_names() {
            const legend_names = [];
            for (const item of this.items) {
                const labels = item.get_labels_list_from_label_prop();
                legend_names.push(...labels);
            }
            return legend_names;
        }
    }
    exports.Legend = Legend;
    Legend.__name__ = "Legend";
    Legend.init_Legend();
},
/* models/annotations/legend_item.js */ function _(require, module, exports) {
    const model_1 = require(64) /* ../../model */;
    const columnar_data_source_1 = require(69) /* ../sources/columnar_data_source */;
    const vectorization_1 = require(130) /* ../../core/vectorization */;
    const p = require(18) /* ../../core/properties */;
    const logging_1 = require(65) /* ../../core/logging */;
    const array_1 = require(8) /* ../../core/util/array */;
    class LegendItem extends model_1.Model {
        constructor(attrs) {
            super(attrs);
        }
        static init_LegendItem() {
            this.define({
                label: [p.StringSpec, null],
                renderers: [p.Array, []],
                index: [p.Number, null],
            });
        }
        /*protected*/ _check_data_sources_on_renderers() {
            const field = this.get_field_from_label_prop();
            if (field != null) {
                if (this.renderers.length < 1) {
                    return false;
                }
                const source = this.renderers[0].data_source;
                if (source != null) {
                    for (const r of this.renderers) {
                        if (r.data_source != source) {
                            return false;
                        }
                    }
                }
            }
            return true;
        }
        /*protected*/ _check_field_label_on_data_source() {
            const field = this.get_field_from_label_prop();
            if (field != null) {
                if (this.renderers.length < 1) {
                    return false;
                }
                const source = this.renderers[0].data_source;
                if (source != null && !array_1.includes(source.columns(), field)) {
                    return false;
                }
            }
            return true;
        }
        initialize() {
            super.initialize();
            this.legend = null;
            this.connect(this.change, () => {
                if (this.legend != null)
                    this.legend.item_change.emit();
            });
            // Validate data_sources match
            const data_source_validation = this._check_data_sources_on_renderers();
            if (!data_source_validation)
                logging_1.logger.error("Non matching data sources on legend item renderers");
            // Validate label in data_source
            const field_validation = this._check_field_label_on_data_source();
            if (!field_validation)
                logging_1.logger.error(`Bad column name on label: ${this.label}`);
        }
        get_field_from_label_prop() {
            const { label } = this;
            return vectorization_1.isField(label) ? label.field : null;
        }
        get_labels_list_from_label_prop() {
            // Always return a list of the labels
            if (vectorization_1.isValue(this.label)) {
                const { value } = this.label;
                return value != null ? [value] : [];
            }
            const field = this.get_field_from_label_prop();
            if (field != null) {
                let source;
                if (this.renderers[0] && this.renderers[0].data_source != null)
                    source = this.renderers[0].data_source;
                else
                    return ["No source found"];
                if (source instanceof columnar_data_source_1.ColumnarDataSource) {
                    const data = source.get_column(field);
                    if (data != null)
                        return array_1.uniq(Array.from(data));
                    else
                        return ["Invalid field"];
                }
            }
            return [];
        }
    }
    exports.LegendItem = LegendItem;
    LegendItem.__name__ = "LegendItem";
    LegendItem.init_LegendItem();
},
/* core/vectorization.js */ function _(require, module, exports) {
    const types_1 = require(7) /* ./util/types */;
    function isValue(obj) {
        return types_1.isPlainObject(obj) && "value" in obj;
    }
    exports.isValue = isValue;
    function isField(obj) {
        return types_1.isPlainObject(obj) && "field" in obj;
    }
    exports.isField = isField;
},
/* models/annotations/poly_annotation.js */ function _(require, module, exports) {
    const annotation_1 = require(29) /* ./annotation */;
    const signaling_1 = require(13) /* ../../core/signaling */;
    const p = require(18) /* ../../core/properties */;
    class PolyAnnotationView extends annotation_1.AnnotationView {
        connect_signals() {
            super.connect_signals();
            // need to respond to either normal BB change events or silent
            // "data only updates" that tools might want to use
            this.connect(this.model.change, () => this.plot_view.request_render());
            this.connect(this.model.data_update, () => this.plot_view.request_render());
        }
        render() {
            if (!this.model.visible)
                return;
            const { xs, ys } = this.model;
            if (xs.length != ys.length)
                return;
            if (xs.length < 3 || ys.length < 3)
                return;
            const { frame } = this.plot_view;
            const { ctx } = this.plot_view.canvas_view;
            for (let i = 0, end = xs.length; i < end; i++) {
                let sx;
                if (this.model.xs_units == 'screen')
                    sx = this.model.screen ? xs[i] : frame.xview.compute(xs[i]);
                else
                    throw new Error("not implemented");
                let sy;
                if (this.model.ys_units == 'screen')
                    sy = this.model.screen ? ys[i] : frame.yview.compute(ys[i]);
                else
                    throw new Error("not implemented");
                if (i == 0) {
                    ctx.beginPath();
                    ctx.moveTo(sx, sy);
                }
                else {
                    ctx.lineTo(sx, sy);
                }
            }
            ctx.closePath();
            if (this.visuals.line.doit) {
                this.visuals.line.set_value(ctx);
                ctx.stroke();
            }
            if (this.visuals.fill.doit) {
                this.visuals.fill.set_value(ctx);
                ctx.fill();
            }
        }
    }
    exports.PolyAnnotationView = PolyAnnotationView;
    PolyAnnotationView.__name__ = "PolyAnnotationView";
    class PolyAnnotation extends annotation_1.Annotation {
        constructor(attrs) {
            super(attrs);
        }
        static init_PolyAnnotation() {
            this.prototype.default_view = PolyAnnotationView;
            this.mixins(['line', 'fill']);
            this.define({
                xs: [p.Array, []],
                xs_units: [p.SpatialUnits, 'data'],
                ys: [p.Array, []],
                ys_units: [p.SpatialUnits, 'data'],
                x_range_name: [p.String, 'default'],
                y_range_name: [p.String, 'default'],
            });
            this.internal({
                screen: [p.Boolean, false],
            });
            this.override({
                fill_color: "#fff9ba",
                fill_alpha: 0.4,
                line_color: "#cccccc",
                line_alpha: 0.3,
            });
        }
        initialize() {
            super.initialize();
            this.data_update = new signaling_1.Signal0(this, "data_update");
        }
        update({ xs, ys }) {
            this.setv({ xs, ys, screen: true }, { silent: true });
            this.data_update.emit();
        }
    }
    exports.PolyAnnotation = PolyAnnotation;
    PolyAnnotation.__name__ = "PolyAnnotation";
    PolyAnnotation.init_PolyAnnotation();
},
/* models/annotations/slope.js */ function _(require, module, exports) {
    const annotation_1 = require(29) /* ./annotation */;
    const p = require(18) /* ../../core/properties */;
    class SlopeView extends annotation_1.AnnotationView {
        initialize() {
            super.initialize();
        }
        connect_signals() {
            super.connect_signals();
            this.connect(this.model.change, () => this.plot_view.request_render());
        }
        render() {
            if (!this.model.visible)
                return;
            this._draw_slope();
        }
        _draw_slope() {
            const gradient = this.model.gradient;
            const y_intercept = this.model.y_intercept;
            if (gradient == null || y_intercept == null) {
                return;
            }
            const { frame } = this.plot_view;
            const xscale = frame.xscales[this.model.x_range_name];
            const yscale = frame.yscales[this.model.y_range_name];
            const sy_start = frame._top.value;
            const sy_end = sy_start + frame._height.value;
            const y_start = yscale.invert(sy_start);
            const y_end = yscale.invert(sy_end);
            const x_start = (y_start - y_intercept) / gradient;
            const x_end = (y_end - y_intercept) / gradient;
            const sx_start = xscale.compute(x_start);
            const sx_end = xscale.compute(x_end);
            const { ctx } = this.plot_view.canvas_view;
            ctx.save();
            ctx.beginPath();
            this.visuals.line.set_value(ctx);
            ctx.moveTo(sx_start, sy_start);
            ctx.lineTo(sx_end, sy_end);
            ctx.stroke();
            ctx.restore();
        }
    }
    exports.SlopeView = SlopeView;
    SlopeView.__name__ = "SlopeView";
    class Slope extends annotation_1.Annotation {
        constructor(attrs) {
            super(attrs);
        }
        static init_Slope() {
            this.prototype.default_view = SlopeView;
            this.mixins(['line']);
            this.define({
                gradient: [p.Number, null],
                y_intercept: [p.Number, null],
                x_range_name: [p.String, 'default'],
                y_range_name: [p.String, 'default'],
            });
            this.override({
                line_color: 'black',
            });
        }
    }
    exports.Slope = Slope;
    Slope.__name__ = "Slope";
    Slope.init_Slope();
},
/* models/annotations/span.js */ function _(require, module, exports) {
    const annotation_1 = require(29) /* ./annotation */;
    const dom_1 = require(61) /* ../../core/dom */;
    const p = require(18) /* ../../core/properties */;
    class SpanView extends annotation_1.AnnotationView {
        initialize() {
            super.initialize();
            this.plot_view.canvas_overlays.appendChild(this.el);
            this.el.style.position = "absolute";
            dom_1.undisplay(this.el);
        }
        connect_signals() {
            super.connect_signals();
            if (this.model.for_hover)
                this.connect(this.model.properties.computed_location.change, () => this._draw_span());
            else {
                if (this.model.render_mode == 'canvas') {
                    this.connect(this.model.change, () => this.plot_view.request_render());
                    this.connect(this.model.properties.location.change, () => this.plot_view.request_render());
                }
                else {
                    this.connect(this.model.change, () => this.render());
                    this.connect(this.model.properties.location.change, () => this._draw_span());
                }
            }
        }
        render() {
            if (!this.model.visible && this.model.render_mode == 'css')
                dom_1.undisplay(this.el);
            if (!this.model.visible)
                return;
            this._draw_span();
        }
        _draw_span() {
            const loc = this.model.for_hover ? this.model.computed_location : this.model.location;
            if (loc == null) {
                dom_1.undisplay(this.el);
                return;
            }
            const { frame } = this.plot_view;
            const xscale = frame.xscales[this.model.x_range_name];
            const yscale = frame.yscales[this.model.y_range_name];
            const _calc_dim = (scale, view) => {
                if (this.model.for_hover)
                    return this.model.computed_location;
                else {
                    if (this.model.location_units == 'data')
                        return scale.compute(loc);
                    else
                        return view.compute(loc);
                }
            };
            let height, sleft, stop, width;
            if (this.model.dimension == 'width') {
                stop = _calc_dim(yscale, frame.yview);
                sleft = frame._left.value;
                width = frame._width.value;
                height = this.model.properties.line_width.value();
            }
            else {
                stop = frame._top.value;
                sleft = _calc_dim(xscale, frame.xview);
                width = this.model.properties.line_width.value();
                height = frame._height.value;
            }
            if (this.model.render_mode == "css") {
                this.el.style.top = `${stop}px`;
                this.el.style.left = `${sleft}px`;
                this.el.style.width = `${width}px`;
                this.el.style.height = `${height}px`;
                this.el.style.backgroundColor = this.model.properties.line_color.value();
                this.el.style.opacity = this.model.properties.line_alpha.value();
                dom_1.display(this.el);
            }
            else if (this.model.render_mode == "canvas") {
                const { ctx } = this.plot_view.canvas_view;
                ctx.save();
                ctx.beginPath();
                this.visuals.line.set_value(ctx);
                ctx.moveTo(sleft, stop);
                if (this.model.dimension == "width") {
                    ctx.lineTo(sleft + width, stop);
                }
                else {
                    ctx.lineTo(sleft, stop + height);
                }
                ctx.stroke();
                ctx.restore();
            }
        }
    }
    exports.SpanView = SpanView;
    SpanView.__name__ = "SpanView";
    class Span extends annotation_1.Annotation {
        constructor(attrs) {
            super(attrs);
        }
        static init_Span() {
            this.prototype.default_view = SpanView;
            this.mixins(['line']);
            this.define({
                render_mode: [p.RenderMode, 'canvas'],
                x_range_name: [p.String, 'default'],
                y_range_name: [p.String, 'default'],
                location: [p.Number, null],
                location_units: [p.SpatialUnits, 'data'],
                dimension: [p.Dimension, 'width'],
            });
            this.override({
                line_color: 'black',
            });
            this.internal({
                for_hover: [p.Boolean, false],
                computed_location: [p.Number, null],
            });
        }
    }
    exports.Span = Span;
    Span.__name__ = "Span";
    Span.init_Span();
},
/* models/annotations/title.js */ function _(require, module, exports) {
    const text_annotation_1 = require(126) /* ./text_annotation */;
    const dom_1 = require(61) /* ../../core/dom */;
    const visuals_1 = require(63) /* ../../core/visuals */;
    const p = require(18) /* ../../core/properties */;
    class TitleView extends text_annotation_1.TextAnnotationView {
        initialize() {
            super.initialize();
            this.visuals.text = new visuals_1.Text(this.model);
        }
        _get_location() {
            const panel = this.panel;
            const hmargin = this.model.offset;
            const vmargin = 5;
            let sx, sy;
            switch (panel.side) {
                case 'above':
                case 'below': {
                    switch (this.model.vertical_align) {
                        case 'top':
                            sy = panel._top.value + vmargin;
                            break;
                        case 'middle':
                            sy = panel._vcenter.value;
                            break;
                        case 'bottom':
                            sy = panel._bottom.value - vmargin;
                            break;
                        default: throw new Error("unreachable code");
                    }
                    switch (this.model.align) {
                        case 'left':
                            sx = panel._left.value + hmargin;
                            break;
                        case 'center':
                            sx = panel._hcenter.value;
                            break;
                        case 'right':
                            sx = panel._right.value - hmargin;
                            break;
                        default: throw new Error("unreachable code");
                    }
                    break;
                }
                case 'left': {
                    switch (this.model.vertical_align) {
                        case 'top':
                            sx = panel._left.value - vmargin;
                            break;
                        case 'middle':
                            sx = panel._hcenter.value;
                            break;
                        case 'bottom':
                            sx = panel._right.value + vmargin;
                            break;
                        default: throw new Error("unreachable code");
                    }
                    switch (this.model.align) {
                        case 'left':
                            sy = panel._bottom.value - hmargin;
                            break;
                        case 'center':
                            sy = panel._vcenter.value;
                            break;
                        case 'right':
                            sy = panel._top.value + hmargin;
                            break;
                        default: throw new Error("unreachable code");
                    }
                    break;
                }
                case 'right': {
                    switch (this.model.vertical_align) {
                        case 'top':
                            sx = panel._right.value - vmargin;
                            break;
                        case 'middle':
                            sx = panel._hcenter.value;
                            break;
                        case 'bottom':
                            sx = panel._left.value + vmargin;
                            break;
                        default: throw new Error("unreachable code");
                    }
                    switch (this.model.align) {
                        case 'left':
                            sy = panel._top.value + hmargin;
                            break;
                        case 'center':
                            sy = panel._vcenter.value;
                            break;
                        case 'right':
                            sy = panel._bottom.value - hmargin;
                            break;
                        default: throw new Error("unreachable code");
                    }
                    break;
                }
                default: throw new Error("unreachable code");
            }
            return [sx, sy];
        }
        render() {
            if (!this.model.visible) {
                if (this.model.render_mode == 'css')
                    dom_1.undisplay(this.el);
                return;
            }
            const { text } = this.model;
            if (text == null || text.length == 0)
                return;
            this.model.text_baseline = this.model.vertical_align;
            this.model.text_align = this.model.align;
            const [sx, sy] = this._get_location();
            const angle = this.panel.get_label_angle_heuristic('parallel');
            const draw = this.model.render_mode == 'canvas' ? this._canvas_text.bind(this) : this._css_text.bind(this);
            draw(this.plot_view.canvas_view.ctx, text, sx, sy, angle);
        }
        _get_size() {
            const { text } = this.model;
            if (text == null || text.length == 0)
                return { width: 0, height: 0 };
            else {
                this.visuals.text.set_value(this.ctx);
                const { width, ascent } = this.ctx.measureText(text);
                return { width, height: ascent * this.visuals.text.text_line_height.value() + 10 };
            }
        }
    }
    exports.TitleView = TitleView;
    TitleView.__name__ = "TitleView";
    class Title extends text_annotation_1.TextAnnotation {
        constructor(attrs) {
            super(attrs);
        }
        static init_Title() {
            this.prototype.default_view = TitleView;
            this.mixins(['line:border_', 'fill:background_']);
            this.define({
                text: [p.String],
                text_font: [p.Font, 'helvetica'],
                text_font_size: [p.FontSizeSpec, '10pt'],
                text_font_style: [p.FontStyle, 'bold'],
                text_color: [p.ColorSpec, '#444444'],
                text_alpha: [p.NumberSpec, 1.0],
                text_line_height: [p.Number, 1.0],
                vertical_align: [p.VerticalAlign, 'bottom'],
                align: [p.TextAlign, 'left'],
                offset: [p.Number, 0],
            });
            this.override({
                background_fill_color: null,
                border_line_color: null,
            });
            this.internal({
                text_align: [p.TextAlign, 'left'],
                text_baseline: [p.TextBaseline, 'bottom'],
            });
        }
    }
    exports.Title = Title;
    Title.__name__ = "Title";
    Title.init_Title();
},
/* models/annotations/toolbar_panel.js */ function _(require, module, exports) {
    const annotation_1 = require(29) /* ./annotation */;
    const build_views_1 = require(92) /* ../../core/build_views */;
    const dom_1 = require(61) /* ../../core/dom */;
    const p = require(18) /* ../../core/properties */;
    class ToolbarPanelView extends annotation_1.AnnotationView {
        constructor() {
            super(...arguments);
            this.rotate = true;
        }
        initialize() {
            super.initialize();
            this.plot_view.canvas_events.appendChild(this.el);
            this._toolbar_views = {};
            build_views_1.build_views(this._toolbar_views, [this.model.toolbar], { parent: this });
            const toolbar_view = this._toolbar_views[this.model.toolbar.id];
            this.plot_view.visibility_callbacks.push((visible) => toolbar_view.set_visibility(visible));
        }
        remove() {
            build_views_1.remove_views(this._toolbar_views);
            super.remove();
        }
        render() {
            super.render();
            if (!this.model.visible) {
                dom_1.undisplay(this.el);
                return;
            }
            this.el.style.position = "absolute";
            this.el.style.overflow = "hidden";
            dom_1.position(this.el, this.panel.bbox);
            const toolbar_view = this._toolbar_views[this.model.toolbar.id];
            toolbar_view.render();
            dom_1.empty(this.el);
            this.el.appendChild(toolbar_view.el);
            dom_1.display(this.el);
        }
        _get_size() {
            const { tools, logo } = this.model.toolbar;
            return {
                width: tools.length * 30 + (logo != null ? 25 : 0),
                height: 30,
            };
        }
    }
    exports.ToolbarPanelView = ToolbarPanelView;
    ToolbarPanelView.__name__ = "ToolbarPanelView";
    class ToolbarPanel extends annotation_1.Annotation {
        constructor(attrs) {
            super(attrs);
        }
        static init_ToolbarPanel() {
            this.prototype.default_view = ToolbarPanelView;
            this.define({
                toolbar: [p.Instance],
            });
        }
    }
    exports.ToolbarPanel = ToolbarPanel;
    ToolbarPanel.__name__ = "ToolbarPanel";
    ToolbarPanel.init_ToolbarPanel();
},
/* models/annotations/tooltip.js */ function _(require, module, exports) {
    const annotation_1 = require(29) /* ./annotation */;
    const dom_1 = require(61) /* ../../core/dom */;
    const p = require(18) /* ../../core/properties */;
    const tooltips_1 = require(137) /* ../../styles/tooltips */;
    const mixins_1 = require(138) /* ../../styles/mixins */;
    function compute_side(attachment, sx, sy, hcenter, vcenter) {
        switch (attachment) {
            case "horizontal":
                return sx < hcenter ? "right" : "left";
            case "vertical":
                return sy < vcenter ? "below" : "above";
            default:
                return attachment;
        }
    }
    exports.compute_side = compute_side;
    class TooltipView extends annotation_1.AnnotationView {
        initialize() {
            super.initialize();
            // TODO (bev) really probably need multiple divs
            this.plot_view.canvas_overlays.appendChild(this.el);
            dom_1.undisplay(this.el);
        }
        connect_signals() {
            super.connect_signals();
            this.connect(this.model.properties.data.change, () => this._draw_tips());
        }
        css_classes() {
            return super.css_classes().concat(tooltips_1.bk_tooltip);
        }
        render() {
            if (!this.model.visible)
                return;
            this._draw_tips();
        }
        _draw_tips() {
            const { data } = this.model;
            dom_1.empty(this.el);
            dom_1.undisplay(this.el);
            if (this.model.custom)
                this.el.classList.add(tooltips_1.bk_tooltip_custom);
            else
                this.el.classList.remove(tooltips_1.bk_tooltip_custom);
            if (data.length == 0)
                return;
            const { frame } = this.plot_view;
            for (const [sx, sy, content] of data) {
                if (this.model.inner_only && !frame.bbox.contains(sx, sy))
                    continue;
                const tip = dom_1.div({}, content);
                this.el.appendChild(tip);
            }
            const [sx, sy] = data[data.length - 1]; // XXX: this previously depended on {sx, sy} leaking from the for-loop
            const side = compute_side(this.model.attachment, sx, sy, frame._hcenter.value, frame._vcenter.value);
            this.el.classList.remove(mixins_1.bk_right);
            this.el.classList.remove(mixins_1.bk_left);
            this.el.classList.remove(mixins_1.bk_above);
            this.el.classList.remove(mixins_1.bk_below);
            const arrow_size = 10; // XXX: keep in sync with less
            dom_1.display(this.el); // XXX: {offset,client}Width() gives 0 when display="none"
            // slightly confusing: side "left" (for example) is relative to point that
            // is being annotated but CS class ".bk-left" is relative to the tooltip itself
            let left, top;
            switch (side) {
                case "right":
                    this.el.classList.add(mixins_1.bk_left);
                    left = sx + (this.el.offsetWidth - this.el.clientWidth) + arrow_size;
                    top = sy - this.el.offsetHeight / 2;
                    break;
                case "left":
                    this.el.classList.add(mixins_1.bk_right);
                    left = sx - this.el.offsetWidth - arrow_size;
                    top = sy - this.el.offsetHeight / 2;
                    break;
                case "below":
                    this.el.classList.add(mixins_1.bk_above);
                    top = sy + (this.el.offsetHeight - this.el.clientHeight) + arrow_size;
                    left = Math.round(sx - this.el.offsetWidth / 2);
                    break;
                case "above":
                    this.el.classList.add(mixins_1.bk_below);
                    top = sy - this.el.offsetHeight - arrow_size;
                    left = Math.round(sx - this.el.offsetWidth / 2);
                    break;
                default:
                    throw new Error("unreachable code");
            }
            if (this.model.show_arrow)
                this.el.classList.add(tooltips_1.bk_tooltip_arrow);
            // TODO (bev) this is not currently bulletproof. If there are
            // two hits, not colocated and one is off the screen, that can
            // be problematic
            if (this.el.childNodes.length > 0) {
                this.el.style.top = `${top}px`;
                this.el.style.left = `${left}px`;
            }
            else
                dom_1.undisplay(this.el);
        }
    }
    exports.TooltipView = TooltipView;
    TooltipView.__name__ = "TooltipView";
    class Tooltip extends annotation_1.Annotation {
        constructor(attrs) {
            super(attrs);
        }
        static init_Tooltip() {
            this.prototype.default_view = TooltipView;
            this.define({
                attachment: [p.TooltipAttachment, 'horizontal'],
                inner_only: [p.Boolean, true],
                show_arrow: [p.Boolean, true],
            });
            this.override({
                level: 'overlay',
            });
            this.internal({
                data: [p.Any, []],
                custom: [p.Any],
            });
        }
        clear() {
            this.data = [];
        }
        add(sx, sy, content) {
            this.data = this.data.concat([[sx, sy, content]]);
        }
    }
    exports.Tooltip = Tooltip;
    Tooltip.__name__ = "Tooltip";
    Tooltip.init_Tooltip();
},
/* styles/tooltips.js */ function _(require, module, exports) {
    require(62) /* ./root */;
    const _a = require(61) /* ../core/dom */;
    _a.styles.append(".bk-root {\n  /* Same border color used everywhere */\n  /* Gray of icons */\n}\n.bk-root .bk-tooltip {\n  font-weight: 300;\n  font-size: 12px;\n  position: absolute;\n  padding: 5px;\n  border: 1px solid #e5e5e5;\n  color: #2f2f2f;\n  background-color: white;\n  pointer-events: none;\n  opacity: 0.95;\n  z-index: 100;\n}\n.bk-root .bk-tooltip > div:not(:first-child) {\n  /* gives space when multiple elements are being hovered over */\n  margin-top: 5px;\n  border-top: #e5e5e5 1px dashed;\n}\n.bk-root .bk-tooltip.bk-left.bk-tooltip-arrow::before {\n  position: absolute;\n  margin: -7px 0 0 0;\n  top: 50%;\n  width: 0;\n  height: 0;\n  border-style: solid;\n  border-width: 7px 0 7px 0;\n  border-color: transparent;\n  content: \" \";\n  display: block;\n  left: -10px;\n  border-right-width: 10px;\n  border-right-color: #909599;\n}\n.bk-root .bk-tooltip.bk-left::before {\n  left: -10px;\n  border-right-width: 10px;\n  border-right-color: #909599;\n}\n.bk-root .bk-tooltip.bk-right.bk-tooltip-arrow::after {\n  position: absolute;\n  margin: -7px 0 0 0;\n  top: 50%;\n  width: 0;\n  height: 0;\n  border-style: solid;\n  border-width: 7px 0 7px 0;\n  border-color: transparent;\n  content: \" \";\n  display: block;\n  right: -10px;\n  border-left-width: 10px;\n  border-left-color: #909599;\n}\n.bk-root .bk-tooltip.bk-right::after {\n  right: -10px;\n  border-left-width: 10px;\n  border-left-color: #909599;\n}\n.bk-root .bk-tooltip.bk-above::before {\n  position: absolute;\n  margin: 0 0 0 -7px;\n  left: 50%;\n  width: 0;\n  height: 0;\n  border-style: solid;\n  border-width: 0 7px 0 7px;\n  border-color: transparent;\n  content: \" \";\n  display: block;\n  top: -10px;\n  border-bottom-width: 10px;\n  border-bottom-color: #909599;\n}\n.bk-root .bk-tooltip.bk-below::after {\n  position: absolute;\n  margin: 0 0 0 -7px;\n  left: 50%;\n  width: 0;\n  height: 0;\n  border-style: solid;\n  border-width: 0 7px 0 7px;\n  border-color: transparent;\n  content: \" \";\n  display: block;\n  bottom: -10px;\n  border-top-width: 10px;\n  border-top-color: #909599;\n}\n.bk-root .bk-tooltip-row-label {\n  text-align: right;\n  color: #26aae1;\n  /* blue from toolbar highlighting */\n}\n.bk-root .bk-tooltip-row-value {\n  color: default;\n  /* seems to be necessary for notebook */\n}\n.bk-root .bk-tooltip-color-block {\n  width: 12px;\n  height: 12px;\n  margin-left: 5px;\n  margin-right: 5px;\n  outline: #dddddd solid 1px;\n  display: inline-block;\n}\n");
    exports.bk_tooltip = "bk-tooltip";
    exports.bk_tooltip_arrow = "bk-tooltip-arrow";
    exports.bk_tooltip_custom = "bk-tooltip-custom";
    exports.bk_tooltip_row_label = "bk-tooltip-row-label";
    exports.bk_tooltip_row_value = "bk-tooltip-row-value";
    exports.bk_tooltip_color_block = "bk-tooltip-color-block";
},
/* styles/mixins.js */ function _(require, module, exports) {
    const _a = require(61) /* ../core/dom */;
    _a.styles.append("");
    exports.bk_active = "bk-active";
    exports.bk_inline = "bk-inline";
    exports.bk_left = "bk-left";
    exports.bk_right = "bk-right";
    exports.bk_above = "bk-above";
    exports.bk_below = "bk-below";
    exports.bk_up = "bk-up";
    exports.bk_down = "bk-down";
    function bk_side(side) {
        switch (side) {
            case "above": return exports.bk_above;
            case "below": return exports.bk_below;
            case "left": return exports.bk_left;
            case "right": return exports.bk_right;
        }
    }
    exports.bk_side = bk_side;
},
/* models/annotations/whisker.js */ function _(require, module, exports) {
    const annotation_1 = require(29) /* ./annotation */;
    const column_data_source_1 = require(68) /* ../sources/column_data_source */;
    const arrow_head_1 = require(67) /* ./arrow_head */;
    const p = require(18) /* ../../core/properties */;
    class WhiskerView extends annotation_1.AnnotationView {
        initialize() {
            super.initialize();
            this.set_data(this.model.source);
        }
        connect_signals() {
            super.connect_signals();
            this.connect(this.model.source.streaming, () => this.set_data(this.model.source));
            this.connect(this.model.source.patching, () => this.set_data(this.model.source));
            this.connect(this.model.source.change, () => this.set_data(this.model.source));
        }
        set_data(source) {
            super.set_data(source);
            this.visuals.warm_cache(source);
            this.plot_view.request_render();
        }
        _map_data() {
            const { frame } = this.plot_view;
            const dim = this.model.dimension;
            const xscale = frame.xscales[this.model.x_range_name];
            const yscale = frame.yscales[this.model.y_range_name];
            const limit_scale = dim == "height" ? yscale : xscale;
            const base_scale = dim == "height" ? xscale : yscale;
            const limit_view = dim == "height" ? frame.yview : frame.xview;
            const base_view = dim == "height" ? frame.xview : frame.yview;
            let _lower_sx;
            if (this.model.properties.lower.units == "data")
                _lower_sx = limit_scale.v_compute(this._lower);
            else
                _lower_sx = limit_view.v_compute(this._lower);
            let _upper_sx;
            if (this.model.properties.upper.units == "data")
                _upper_sx = limit_scale.v_compute(this._upper);
            else
                _upper_sx = limit_view.v_compute(this._upper);
            let _base_sx;
            if (this.model.properties.base.units == "data")
                _base_sx = base_scale.v_compute(this._base);
            else
                _base_sx = base_view.v_compute(this._base);
            const [i, j] = dim == 'height' ? [1, 0] : [0, 1];
            const _lower = [_lower_sx, _base_sx];
            const _upper = [_upper_sx, _base_sx];
            this._lower_sx = _lower[i];
            this._lower_sy = _lower[j];
            this._upper_sx = _upper[i];
            this._upper_sy = _upper[j];
        }
        render() {
            if (!this.model.visible)
                return;
            this._map_data();
            const { ctx } = this.plot_view.canvas_view;
            if (this.visuals.line.doit) {
                for (let i = 0, end = this._lower_sx.length; i < end; i++) {
                    this.visuals.line.set_vectorize(ctx, i);
                    ctx.beginPath();
                    ctx.moveTo(this._lower_sx[i], this._lower_sy[i]);
                    ctx.lineTo(this._upper_sx[i], this._upper_sy[i]);
                    ctx.stroke();
                }
            }
            const angle = this.model.dimension == "height" ? 0 : Math.PI / 2;
            if (this.model.lower_head != null) {
                for (let i = 0, end = this._lower_sx.length; i < end; i++) {
                    ctx.save();
                    ctx.translate(this._lower_sx[i], this._lower_sy[i]);
                    ctx.rotate(angle + Math.PI);
                    this.model.lower_head.render(ctx, i);
                    ctx.restore();
                }
            }
            if (this.model.upper_head != null) {
                for (let i = 0, end = this._upper_sx.length; i < end; i++) {
                    ctx.save();
                    ctx.translate(this._upper_sx[i], this._upper_sy[i]);
                    ctx.rotate(angle);
                    this.model.upper_head.render(ctx, i);
                    ctx.restore();
                }
            }
        }
    }
    exports.WhiskerView = WhiskerView;
    WhiskerView.__name__ = "WhiskerView";
    class Whisker extends annotation_1.Annotation {
        constructor(attrs) {
            super(attrs);
        }
        static init_Whisker() {
            this.prototype.default_view = WhiskerView;
            this.mixins(['line']);
            this.define({
                lower: [p.DistanceSpec],
                lower_head: [p.Instance, () => new arrow_head_1.TeeHead({ level: "underlay", size: 10 })],
                upper: [p.DistanceSpec],
                upper_head: [p.Instance, () => new arrow_head_1.TeeHead({ level: "underlay", size: 10 })],
                base: [p.DistanceSpec],
                dimension: [p.Dimension, 'height'],
                source: [p.Instance, () => new column_data_source_1.ColumnDataSource()],
                x_range_name: [p.String, 'default'],
                y_range_name: [p.String, 'default'],
            });
            this.override({
                level: 'underlay',
            });
        }
    }
    exports.Whisker = Whisker;
    Whisker.__name__ = "Whisker";
    Whisker.init_Whisker();
},
/* models/axes/index.js */ function _(require, module, exports) {
    var axis_1 = require(141) /* ./axis */;
    exports.Axis = axis_1.Axis;
    var categorical_axis_1 = require(143) /* ./categorical_axis */;
    exports.CategoricalAxis = categorical_axis_1.CategoricalAxis;
    var continuous_axis_1 = require(146) /* ./continuous_axis */;
    exports.ContinuousAxis = continuous_axis_1.ContinuousAxis;
    var datetime_axis_1 = require(147) /* ./datetime_axis */;
    exports.DatetimeAxis = datetime_axis_1.DatetimeAxis;
    var linear_axis_1 = require(148) /* ./linear_axis */;
    exports.LinearAxis = linear_axis_1.LinearAxis;
    var log_axis_1 = require(161) /* ./log_axis */;
    exports.LogAxis = log_axis_1.LogAxis;
    var mercator_axis_1 = require(164) /* ./mercator_axis */;
    exports.MercatorAxis = mercator_axis_1.MercatorAxis;
},
/* models/axes/axis.js */ function _(require, module, exports) {
    const guide_renderer_1 = require(142) /* ../renderers/guide_renderer */;
    const p = require(18) /* ../../core/properties */;
    const array_1 = require(8) /* ../../core/util/array */;
    const types_1 = require(7) /* ../../core/util/types */;
    const factor_range_1 = require(82) /* ../ranges/factor_range */;
    const { abs, min, max } = Math;
    class AxisView extends guide_renderer_1.GuideRendererView {
        constructor() {
            super(...arguments);
            this.rotate = true;
        }
        get panel() {
            return this.layout;
        }
        render() {
            if (!this.model.visible)
                return;
            const extents = {
                tick: this._tick_extent(),
                tick_label: this._tick_label_extents(),
                axis_label: this._axis_label_extent(),
            };
            const tick_coords = this.tick_coords;
            const ctx = this.plot_view.canvas_view.ctx;
            ctx.save();
            this._draw_rule(ctx, extents);
            this._draw_major_ticks(ctx, extents, tick_coords);
            this._draw_minor_ticks(ctx, extents, tick_coords);
            this._draw_major_labels(ctx, extents, tick_coords);
            this._draw_axis_label(ctx, extents, tick_coords);
            if (this._render != null)
                this._render(ctx, extents, tick_coords);
            ctx.restore();
        }
        connect_signals() {
            super.connect_signals();
            this.connect(this.model.change, () => this.plot_view.request_paint());
            const p = this.model.properties;
            this.on_change(p.visible, () => this.plot_view.request_layout());
        }
        get_size() {
            if (this.model.visible && this.model.fixed_location == null) {
                const size = this._get_size();
                return { width: 0 /* max */, height: Math.round(size) };
            }
            else
                return { width: 0, height: 0 };
        }
        _get_size() {
            return this._tick_extent() + this._tick_label_extent() + this._axis_label_extent();
        }
        get needs_clip() {
            return this.model.fixed_location != null;
        }
        // drawing sub functions -----------------------------------------------------
        _draw_rule(ctx, _extents) {
            if (!this.visuals.axis_line.doit)
                return;
            const [xs, ys] = this.rule_coords;
            const [sxs, sys] = this.plot_view.map_to_screen(xs, ys, this.model.x_range_name, this.model.y_range_name);
            const [nx, ny] = this.normals;
            const [xoff, yoff] = this.offsets;
            this.visuals.axis_line.set_value(ctx);
            ctx.beginPath();
            ctx.moveTo(Math.round(sxs[0] + nx * xoff), Math.round(sys[0] + ny * yoff));
            for (let i = 1; i < sxs.length; i++) {
                const sx = Math.round(sxs[i] + nx * xoff);
                const sy = Math.round(sys[i] + ny * yoff);
                ctx.lineTo(sx, sy);
            }
            ctx.stroke();
        }
        _draw_major_ticks(ctx, _extents, tick_coords) {
            const tin = this.model.major_tick_in;
            const tout = this.model.major_tick_out;
            const visuals = this.visuals.major_tick_line;
            this._draw_ticks(ctx, tick_coords.major, tin, tout, visuals);
        }
        _draw_minor_ticks(ctx, _extents, tick_coords) {
            const tin = this.model.minor_tick_in;
            const tout = this.model.minor_tick_out;
            const visuals = this.visuals.minor_tick_line;
            this._draw_ticks(ctx, tick_coords.minor, tin, tout, visuals);
        }
        _draw_major_labels(ctx, extents, tick_coords) {
            const coords = tick_coords.major;
            const labels = this.compute_labels(coords[this.dimension]);
            const orient = this.model.major_label_orientation;
            const standoff = extents.tick + this.model.major_label_standoff;
            const visuals = this.visuals.major_label_text;
            this._draw_oriented_labels(ctx, labels, coords, orient, this.panel.side, standoff, visuals);
        }
        _draw_axis_label(ctx, extents, _tick_coords) {
            if (this.model.axis_label == null || this.model.axis_label.length == 0 || this.model.fixed_location != null)
                return;
            let sx;
            let sy;
            switch (this.panel.side) {
                case "above":
                    sx = this.panel._hcenter.value;
                    sy = this.panel._bottom.value;
                    break;
                case "below":
                    sx = this.panel._hcenter.value;
                    sy = this.panel._top.value;
                    break;
                case "left":
                    sx = this.panel._right.value;
                    sy = this.panel._vcenter.value;
                    break;
                case "right":
                    sx = this.panel._left.value;
                    sy = this.panel._vcenter.value;
                    break;
                default:
                    throw new Error(`unknown side: ${this.panel.side}`);
            }
            const coords = [[sx], [sy]];
            const standoff = extents.tick + array_1.sum(extents.tick_label) + this.model.axis_label_standoff;
            const visuals = this.visuals.axis_label_text;
            this._draw_oriented_labels(ctx, [this.model.axis_label], coords, 'parallel', this.panel.side, standoff, visuals, "screen");
        }
        _draw_ticks(ctx, coords, tin, tout, visuals) {
            if (!visuals.doit)
                return;
            const [x, y] = coords;
            const [sxs, sys] = this.plot_view.map_to_screen(x, y, this.model.x_range_name, this.model.y_range_name);
            const [nx, ny] = this.normals;
            const [xoff, yoff] = this.offsets;
            const [nxin, nyin] = [nx * (xoff - tin), ny * (yoff - tin)];
            const [nxout, nyout] = [nx * (xoff + tout), ny * (yoff + tout)];
            visuals.set_value(ctx);
            for (let i = 0; i < sxs.length; i++) {
                const sx0 = Math.round(sxs[i] + nxout);
                const sy0 = Math.round(sys[i] + nyout);
                const sx1 = Math.round(sxs[i] + nxin);
                const sy1 = Math.round(sys[i] + nyin);
                ctx.beginPath();
                ctx.moveTo(sx0, sy0);
                ctx.lineTo(sx1, sy1);
                ctx.stroke();
            }
        }
        _draw_oriented_labels(ctx, labels, coords, orient, _side, standoff, visuals, units = "data") {
            if (!visuals.doit || labels.length == 0)
                return;
            let sxs, sys;
            let xoff, yoff;
            if (units == "screen") {
                [sxs, sys] = coords;
                [xoff, yoff] = [0, 0];
            }
            else {
                const [dxs, dys] = coords;
                [sxs, sys] = this.plot_view.map_to_screen(dxs, dys, this.model.x_range_name, this.model.y_range_name);
                [xoff, yoff] = this.offsets;
            }
            const [nx, ny] = this.normals;
            const nxd = nx * (xoff + standoff);
            const nyd = ny * (yoff + standoff);
            visuals.set_value(ctx);
            this.panel.apply_label_text_heuristics(ctx, orient);
            let angle;
            if (types_1.isString(orient))
                angle = this.panel.get_label_angle_heuristic(orient);
            else
                angle = -orient;
            for (let i = 0; i < sxs.length; i++) {
                const sx = Math.round(sxs[i] + nxd);
                const sy = Math.round(sys[i] + nyd);
                ctx.translate(sx, sy);
                ctx.rotate(angle);
                ctx.fillText(labels[i], 0, 0);
                ctx.rotate(-angle);
                ctx.translate(-sx, -sy);
            }
        }
        // extents sub functions -----------------------------------------------------
        /*protected*/ _axis_label_extent() {
            if (this.model.axis_label == null || this.model.axis_label == "")
                return 0;
            const standoff = this.model.axis_label_standoff;
            const visuals = this.visuals.axis_label_text;
            return this._oriented_labels_extent([this.model.axis_label], "parallel", this.panel.side, standoff, visuals);
        }
        /*protected*/ _tick_extent() {
            return this.model.major_tick_out;
        }
        /*protected*/ _tick_label_extent() {
            return array_1.sum(this._tick_label_extents());
        }
        _tick_label_extents() {
            const coords = this.tick_coords.major;
            const labels = this.compute_labels(coords[this.dimension]);
            const orient = this.model.major_label_orientation;
            const standoff = this.model.major_label_standoff;
            const visuals = this.visuals.major_label_text;
            return [this._oriented_labels_extent(labels, orient, this.panel.side, standoff, visuals)];
        }
        _oriented_labels_extent(labels, orient, side, standoff, visuals) {
            if (labels.length == 0)
                return 0;
            const ctx = this.plot_view.canvas_view.ctx;
            visuals.set_value(ctx);
            let hscale;
            let angle;
            if (types_1.isString(orient)) {
                hscale = 1;
                angle = this.panel.get_label_angle_heuristic(orient);
            }
            else {
                hscale = 2;
                angle = -orient;
            }
            angle = Math.abs(angle);
            const c = Math.cos(angle);
            const s = Math.sin(angle);
            let extent = 0;
            for (let i = 0; i < labels.length; i++) {
                const w = ctx.measureText(labels[i]).width * 1.1;
                const h = ctx.measureText(labels[i]).ascent * 0.9;
                let val;
                if (side == "above" || side == "below")
                    val = w * s + (h / hscale) * c;
                else
                    val = w * c + (h / hscale) * s;
                // update extent if current value is larger
                if (val > extent)
                    extent = val;
            }
            // only apply the standoff if we already have non-zero extent
            if (extent > 0)
                extent += standoff;
            return extent;
        }
        // {{{ TODO: state
        get normals() {
            return this.panel.normals;
        }
        get dimension() {
            return this.panel.dimension;
        }
        compute_labels(ticks) {
            const labels = this.model.formatter.doFormat(ticks, this);
            for (let i = 0; i < ticks.length; i++) {
                if (ticks[i] in this.model.major_label_overrides)
                    labels[i] = this.model.major_label_overrides[ticks[i]];
            }
            return labels;
        }
        get offsets() {
            // If we have a fixed_position then we should respect that exactly and
            // not apply any offsets (https://github.com/bokeh/bokeh/issues/8552)
            if (this.model.fixed_location != null)
                return [0, 0];
            const { frame } = this.plot_view;
            let [xoff, yoff] = [0, 0];
            switch (this.panel.side) {
                case "below":
                    yoff = abs(this.panel._top.value - frame._bottom.value);
                    break;
                case "above":
                    yoff = abs(this.panel._bottom.value - frame._top.value);
                    break;
                case "right":
                    xoff = abs(this.panel._left.value - frame._right.value);
                    break;
                case "left":
                    xoff = abs(this.panel._right.value - frame._left.value);
                    break;
            }
            return [xoff, yoff];
        }
        get ranges() {
            const i = this.dimension;
            const j = (i + 1) % 2;
            const { frame } = this.plot_view;
            const ranges = [
                frame.x_ranges[this.model.x_range_name],
                frame.y_ranges[this.model.y_range_name],
            ];
            return [ranges[i], ranges[j]];
        }
        get computed_bounds() {
            const [range] = this.ranges;
            const user_bounds = this.model.bounds; // XXX: ? 'auto'
            const range_bounds = [range.min, range.max];
            if (user_bounds == 'auto')
                return [range.min, range.max];
            else if (types_1.isArray(user_bounds)) {
                let start;
                let end;
                const [user_start, user_end] = user_bounds;
                const [range_start, range_end] = range_bounds;
                if (abs(user_start - user_end) > abs(range_start - range_end)) {
                    start = max(min(user_start, user_end), range_start);
                    end = min(max(user_start, user_end), range_end);
                }
                else {
                    start = min(user_start, user_end);
                    end = max(user_start, user_end);
                }
                return [start, end];
            }
            else
                throw new Error(`user bounds '${user_bounds}' not understood`);
        }
        get rule_coords() {
            const i = this.dimension;
            const j = (i + 1) % 2;
            const [range] = this.ranges;
            const [start, end] = this.computed_bounds;
            const xs = new Array(2);
            const ys = new Array(2);
            const coords = [xs, ys];
            coords[i][0] = Math.max(start, range.min);
            coords[i][1] = Math.min(end, range.max);
            if (coords[i][0] > coords[i][1])
                coords[i][0] = coords[i][1] = NaN;
            coords[j][0] = this.loc;
            coords[j][1] = this.loc;
            return coords;
        }
        get tick_coords() {
            const i = this.dimension;
            const j = (i + 1) % 2;
            const [range] = this.ranges;
            const [start, end] = this.computed_bounds;
            const ticks = this.model.ticker.get_ticks(start, end, range, this.loc, {});
            const majors = ticks.major;
            const minors = ticks.minor;
            const xs = [];
            const ys = [];
            const coords = [xs, ys];
            const minor_xs = [];
            const minor_ys = [];
            const minor_coords = [minor_xs, minor_ys];
            const [range_min, range_max] = [range.min, range.max];
            for (let ii = 0; ii < majors.length; ii++) {
                if (majors[ii] < range_min || majors[ii] > range_max)
                    continue;
                coords[i].push(majors[ii]);
                coords[j].push(this.loc);
            }
            for (let ii = 0; ii < minors.length; ii++) {
                if (minors[ii] < range_min || minors[ii] > range_max)
                    continue;
                minor_coords[i].push(minors[ii]);
                minor_coords[j].push(this.loc);
            }
            return {
                major: coords,
                minor: minor_coords,
            };
        }
        get loc() {
            const { fixed_location } = this.model;
            if (fixed_location != null) {
                if (types_1.isNumber(fixed_location))
                    return fixed_location;
                const [, cross_range] = this.ranges;
                if (cross_range instanceof factor_range_1.FactorRange)
                    return cross_range.synthetic(fixed_location);
                throw new Error("unexpected");
            }
            const [, cross_range] = this.ranges;
            switch (this.panel.side) {
                case 'left':
                case 'below':
                    return cross_range.start;
                case 'right':
                case 'above':
                    return cross_range.end;
            }
        }
        // }}}
        serializable_state() {
            return Object.assign(Object.assign({}, super.serializable_state()), { bbox: this.layout.bbox.box });
        }
    }
    exports.AxisView = AxisView;
    AxisView.__name__ = "AxisView";
    class Axis extends guide_renderer_1.GuideRenderer {
        constructor(attrs) {
            super(attrs);
        }
        static init_Axis() {
            this.prototype.default_view = AxisView;
            this.mixins([
                'line:axis_',
                'line:major_tick_',
                'line:minor_tick_',
                'text:major_label_',
                'text:axis_label_',
            ]);
            this.define({
                bounds: [p.Any, 'auto'],
                ticker: [p.Instance],
                formatter: [p.Instance],
                x_range_name: [p.String, 'default'],
                y_range_name: [p.String, 'default'],
                axis_label: [p.String, ''],
                axis_label_standoff: [p.Int, 5],
                major_label_standoff: [p.Int, 5],
                major_label_orientation: [p.Any, "horizontal"],
                major_label_overrides: [p.Any, {}],
                major_tick_in: [p.Number, 2],
                major_tick_out: [p.Number, 6],
                minor_tick_in: [p.Number, 0],
                minor_tick_out: [p.Number, 4],
                fixed_location: [p.Any, null],
            });
            this.override({
                axis_line_color: 'black',
                major_tick_line_color: 'black',
                minor_tick_line_color: 'black',
                major_label_text_font_size: "8pt",
                major_label_text_align: "center",
                major_label_text_baseline: "alphabetic",
                axis_label_text_font_size: "10pt",
                axis_label_text_font_style: "italic",
            });
        }
    }
    exports.Axis = Axis;
    Axis.__name__ = "Axis";
    Axis.init_Axis();
},
/* models/renderers/guide_renderer.js */ function _(require, module, exports) {
    const renderer_1 = require(58) /* ./renderer */;
    class GuideRendererView extends renderer_1.RendererView {
    }
    exports.GuideRendererView = GuideRendererView;
    GuideRendererView.__name__ = "GuideRendererView";
    class GuideRenderer extends renderer_1.Renderer {
        constructor(attrs) {
            super(attrs);
        }
        static init_GuideRenderer() {
            this.override({
                level: "overlay",
            });
        }
    }
    exports.GuideRenderer = GuideRenderer;
    GuideRenderer.__name__ = "GuideRenderer";
    GuideRenderer.init_GuideRenderer();
},
/* models/axes/categorical_axis.js */ function _(require, module, exports) {
    const axis_1 = require(141) /* ./axis */;
    const categorical_ticker_1 = require(144) /* ../tickers/categorical_ticker */;
    const categorical_tick_formatter_1 = require(145) /* ../formatters/categorical_tick_formatter */;
    const p = require(18) /* ../../core/properties */;
    class CategoricalAxisView extends axis_1.AxisView {
        _render(ctx, extents, tick_coords) {
            this._draw_group_separators(ctx, extents, tick_coords);
        }
        _draw_group_separators(ctx, _extents, _tick_coords) {
            const [range] = this.ranges;
            const [start, end] = this.computed_bounds;
            if (!range.tops || range.tops.length < 2 || !this.visuals.separator_line.doit)
                return;
            const dim = this.dimension;
            const alt = (dim + 1) % 2;
            const coords = [[], []];
            let ind = 0;
            for (let i = 0; i < range.tops.length - 1; i++) {
                let first, last;
                for (let j = ind; j < range.factors.length; j++) {
                    if (range.factors[j][0] == range.tops[i + 1]) {
                        [first, last] = [range.factors[j - 1], range.factors[j]];
                        ind = j;
                        break;
                    }
                }
                const pt = (range.synthetic(first) + range.synthetic(last)) / 2;
                if (pt > start && pt < end) {
                    coords[dim].push(pt);
                    coords[alt].push(this.loc);
                }
            }
            const tex = this._tick_label_extent();
            this._draw_ticks(ctx, coords, -3, (tex - 6), this.visuals.separator_line);
        }
        _draw_major_labels(ctx, extents, _tick_coords) {
            const info = this._get_factor_info();
            let standoff = extents.tick + this.model.major_label_standoff;
            for (let i = 0; i < info.length; i++) {
                const [labels, coords, orient, visuals] = info[i];
                this._draw_oriented_labels(ctx, labels, coords, orient, this.panel.side, standoff, visuals);
                standoff += extents.tick_label[i];
            }
        }
        _tick_label_extents() {
            const info = this._get_factor_info();
            const extents = [];
            for (const [labels, , orient, visuals] of info) {
                const extent = this._oriented_labels_extent(labels, orient, this.panel.side, this.model.major_label_standoff, visuals);
                extents.push(extent);
            }
            return extents;
        }
        _get_factor_info() {
            const [range] = this.ranges;
            const [start, end] = this.computed_bounds;
            const loc = this.loc;
            const ticks = this.model.ticker.get_ticks(start, end, range, loc, {});
            const coords = this.tick_coords;
            const info = [];
            if (range.levels == 1) {
                const major = ticks.major;
                const labels = this.model.formatter.doFormat(major, this);
                info.push([labels, coords.major, this.model.major_label_orientation, this.visuals.major_label_text]);
            }
            else if (range.levels == 2) {
                const major = ticks.major.map((x) => x[1]);
                const labels = this.model.formatter.doFormat(major, this);
                info.push([labels, coords.major, this.model.major_label_orientation, this.visuals.major_label_text]);
                info.push([ticks.tops, coords.tops, this.model.group_label_orientation, this.visuals.group_text]);
            }
            else if (range.levels == 3) {
                const major = ticks.major.map((x) => x[2]);
                const labels = this.model.formatter.doFormat(major, this);
                const mid_labels = ticks.mids.map((x) => x[1]);
                info.push([labels, coords.major, this.model.major_label_orientation, this.visuals.major_label_text]);
                info.push([mid_labels, coords.mids, this.model.subgroup_label_orientation, this.visuals.subgroup_text]);
                info.push([ticks.tops, coords.tops, this.model.group_label_orientation, this.visuals.group_text]);
            }
            return info;
        }
        // {{{ TODO: state
        get tick_coords() {
            const i = this.dimension;
            const j = (i + 1) % 2;
            const [range] = this.ranges;
            const [start, end] = this.computed_bounds;
            const ticks = this.model.ticker.get_ticks(start, end, range, this.loc, {});
            const coords = {
                major: [[], []],
                mids: [[], []],
                tops: [[], []],
                minor: [[], []],
            };
            coords.major[i] = ticks.major;
            coords.major[j] = ticks.major.map((_x) => this.loc);
            if (range.levels == 3) {
                coords.mids[i] = ticks.mids;
                coords.mids[j] = ticks.mids.map((_x) => this.loc);
            }
            if (range.levels > 1) {
                coords.tops[i] = ticks.tops;
                coords.tops[j] = ticks.tops.map((_x) => this.loc);
            }
            return coords;
        }
    }
    exports.CategoricalAxisView = CategoricalAxisView;
    CategoricalAxisView.__name__ = "CategoricalAxisView";
    class CategoricalAxis extends axis_1.Axis {
        constructor(attrs) {
            super(attrs);
        }
        static init_CategoricalAxis() {
            this.prototype.default_view = CategoricalAxisView;
            this.mixins([
                "line:separator_",
                "text:group_",
                "text:subgroup_",
            ]);
            this.define({
                group_label_orientation: [p.Any, "parallel"],
                subgroup_label_orientation: [p.Any, "parallel"],
            });
            this.override({
                ticker: () => new categorical_ticker_1.CategoricalTicker(),
                formatter: () => new categorical_tick_formatter_1.CategoricalTickFormatter(),
                separator_line_color: "lightgrey",
                separator_line_width: 2,
                group_text_font_style: "bold",
                group_text_font_size: "8pt",
                group_text_color: "grey",
                subgroup_text_font_style: "bold",
                subgroup_text_font_size: "8pt",
            });
        }
    }
    exports.CategoricalAxis = CategoricalAxis;
    CategoricalAxis.__name__ = "CategoricalAxis";
    CategoricalAxis.init_CategoricalAxis();
},
/* models/tickers/categorical_ticker.js */ function _(require, module, exports) {
    const ticker_1 = require(105) /* ./ticker */;
    class CategoricalTicker extends ticker_1.Ticker {
        constructor(attrs) {
            super(attrs);
        }
        get_ticks(start, end, range, _cross_loc, _) {
            const majors = this._collect(range.factors, range, start, end);
            const tops = this._collect(range.tops || [], range, start, end);
            const mids = this._collect(range.mids || [], range, start, end);
            return {
                major: majors,
                minor: [],
                tops,
                mids,
            };
        }
        _collect(factors, range, start, end) {
            const result = [];
            for (const factor of factors) {
                const coord = range.synthetic(factor);
                if (coord > start && coord < end)
                    result.push(factor);
            }
            return result;
        }
    }
    exports.CategoricalTicker = CategoricalTicker;
    CategoricalTicker.__name__ = "CategoricalTicker";
},
/* models/formatters/categorical_tick_formatter.js */ function _(require, module, exports) {
    const tick_formatter_1 = require(107) /* ./tick_formatter */;
    const array_1 = require(8) /* ../../core/util/array */;
    class CategoricalTickFormatter extends tick_formatter_1.TickFormatter {
        constructor(attrs) {
            super(attrs);
        }
        doFormat(ticks, _opts) {
            return array_1.copy(ticks);
        }
    }
    exports.CategoricalTickFormatter = CategoricalTickFormatter;
    CategoricalTickFormatter.__name__ = "CategoricalTickFormatter";
},
/* models/axes/continuous_axis.js */ function _(require, module, exports) {
    const axis_1 = require(141) /* ./axis */;
    class ContinuousAxis extends axis_1.Axis {
        constructor(attrs) {
            super(attrs);
        }
    }
    exports.ContinuousAxis = ContinuousAxis;
    ContinuousAxis.__name__ = "ContinuousAxis";
},
/* models/axes/datetime_axis.js */ function _(require, module, exports) {
    const linear_axis_1 = require(148) /* ./linear_axis */;
    const datetime_tick_formatter_1 = require(149) /* ../formatters/datetime_tick_formatter */;
    const datetime_ticker_1 = require(154) /* ../tickers/datetime_ticker */;
    class DatetimeAxisView extends linear_axis_1.LinearAxisView {
    }
    exports.DatetimeAxisView = DatetimeAxisView;
    DatetimeAxisView.__name__ = "DatetimeAxisView";
    class DatetimeAxis extends linear_axis_1.LinearAxis {
        constructor(attrs) {
            super(attrs);
        }
        static init_DatetimeAxis() {
            this.prototype.default_view = DatetimeAxisView;
            this.override({
                ticker: () => new datetime_ticker_1.DatetimeTicker(),
                formatter: () => new datetime_tick_formatter_1.DatetimeTickFormatter(),
            });
        }
    }
    exports.DatetimeAxis = DatetimeAxis;
    DatetimeAxis.__name__ = "DatetimeAxis";
    DatetimeAxis.init_DatetimeAxis();
},
/* models/axes/linear_axis.js */ function _(require, module, exports) {
    const axis_1 = require(141) /* ./axis */;
    const continuous_axis_1 = require(146) /* ./continuous_axis */;
    const basic_tick_formatter_1 = require(106) /* ../formatters/basic_tick_formatter */;
    const basic_ticker_1 = require(102) /* ../tickers/basic_ticker */;
    class LinearAxisView extends axis_1.AxisView {
    }
    exports.LinearAxisView = LinearAxisView;
    LinearAxisView.__name__ = "LinearAxisView";
    class LinearAxis extends continuous_axis_1.ContinuousAxis {
        constructor(attrs) {
            super(attrs);
        }
        static init_LinearAxis() {
            this.prototype.default_view = LinearAxisView;
            this.override({
                ticker: () => new basic_ticker_1.BasicTicker(),
                formatter: () => new basic_tick_formatter_1.BasicTickFormatter(),
            });
        }
    }
    exports.LinearAxis = LinearAxis;
    LinearAxis.__name__ = "LinearAxis";
    LinearAxis.init_LinearAxis();
},
/* models/formatters/datetime_tick_formatter.js */ function _(require, module, exports) {
    const tz = require(150) /* timezone */;
    const tick_formatter_1 = require(107) /* ./tick_formatter */;
    const logging_1 = require(65) /* ../../core/logging */;
    const p = require(18) /* ../../core/properties */;
    const templating_1 = require(151) /* ../../core/util/templating */;
    const array_1 = require(8) /* ../../core/util/array */;
    const types_1 = require(7) /* ../../core/util/types */;
    function _us(t) {
        // From double-precision unix (millisecond) timestamp get
        // microsecond since last second. Precision seems to run
        // out around the hundreds of nanoseconds scale, so rounding
        // to the nearest microsecond should round to a nice
        // microsecond / millisecond tick.
        return Math.round(((t / 1000) % 1) * 1000000);
    }
    function _array(t) {
        return tz(t, "%Y %m %d %H %M %S").split(/\s+/).map(e => parseInt(e, 10));
    }
    function _strftime(t, format) {
        if (types_1.isFunction(format)) {
            return format(t);
        }
        else {
            // Python's datetime library augments the microsecond directive %f, which is not
            // supported by the javascript library timezone: http://bigeasy.github.io/timezone/.
            // Use a regular expression to replace %f directive with microseconds.
            // TODO: what should we do for negative microsecond strings?
            const microsecond_replacement_string = templating_1.sprintf("$1%06d", _us(t));
            format = format.replace(/((^|[^%])(%%)*)%f/, microsecond_replacement_string);
            if (format.indexOf("%") == -1) {
                // timezone seems to ignore any strings without any formatting directives,
                // and just return the time argument back instead of the string argument.
                // But we want the string argument, in case a user supplies a format string
                // which doesn't contain a formatting directive or is only using %f.
                return format;
            }
            return tz(t, format);
        }
    }
    // Labels of time units, from finest to coarsest.
    const format_order = [
        'microseconds', 'milliseconds', 'seconds', 'minsec', 'minutes', 'hourmin', 'hours', 'days', 'months', 'years',
    ];
    class DatetimeTickFormatter extends tick_formatter_1.TickFormatter {
        constructor(attrs) {
            super(attrs);
            // Whether or not to strip the leading zeros on tick labels.
            this.strip_leading_zeros = true;
        }
        static init_DatetimeTickFormatter() {
            this.define({
                microseconds: [p.Array, ['%fus']],
                milliseconds: [p.Array, ['%3Nms', '%S.%3Ns']],
                seconds: [p.Array, ['%Ss']],
                minsec: [p.Array, [':%M:%S']],
                minutes: [p.Array, [':%M', '%Mm']],
                hourmin: [p.Array, ['%H:%M']],
                hours: [p.Array, ['%Hh', '%H:%M']],
                days: [p.Array, ['%m/%d', '%a%d']],
                months: [p.Array, ['%m/%Y', '%b %Y']],
                years: [p.Array, ['%Y']],
            });
        }
        initialize() {
            super.initialize();
            // TODO (bev) trigger update on format change
            this._update_width_formats();
        }
        _update_width_formats() {
            const now = +tz(new Date());
            const _widths = function (fmt_strings) {
                const sizes = fmt_strings.map((fmt_string) => _strftime(now, fmt_string).length);
                const sorted = array_1.sort_by(array_1.zip(sizes, fmt_strings), ([size]) => size);
                return array_1.unzip(sorted);
            };
            this._width_formats = {
                microseconds: _widths(this.microseconds),
                milliseconds: _widths(this.milliseconds),
                seconds: _widths(this.seconds),
                minsec: _widths(this.minsec),
                minutes: _widths(this.minutes),
                hourmin: _widths(this.hourmin),
                hours: _widths(this.hours),
                days: _widths(this.days),
                months: _widths(this.months),
                years: _widths(this.years),
            };
        }
        // FIXME There is some unfortunate flicker when panning/zooming near the
        // span boundaries.
        // FIXME Rounding is weird at the 20-us scale and below.
        _get_resolution_str(resolution_secs, span_secs) {
            // Our resolution boundaries should not be round numbers, because we want
            // them to fall between the possible tick intervals (which *are* round
            // numbers, as we've worked hard to ensure).  Consequently, we adjust the
            // resolution upwards a small amount (less than any possible step in
            // scales) to make the effective boundaries slightly lower.
            const adjusted_secs = resolution_secs * 1.1;
            switch (false) {
                case !(adjusted_secs < 1e-3): return "microseconds";
                case !(adjusted_secs < 1.0): return "milliseconds";
                case !(adjusted_secs < 60): return span_secs >= 60 ? "minsec" : "seconds";
                case !(adjusted_secs < 3600): return span_secs >= 3600 ? "hourmin" : "minutes";
                case !(adjusted_secs < (24 * 3600)): return "hours";
                case !(adjusted_secs < (31 * 24 * 3600)): return "days";
                case !(adjusted_secs < (365 * 24 * 3600)): return "months";
                default: return "years";
            }
        }
        doFormat(ticks, _opts) {
            // In order to pick the right set of labels, we need to determine
            // the resolution of the ticks.  We can do this using a ticker if
            // it's provided, or by computing the resolution from the actual
            // ticks we've been given.
            if (ticks.length == 0)
                return [];
            const span = Math.abs(ticks[ticks.length - 1] - ticks[0]) / 1000.0;
            const r = span / (ticks.length - 1);
            const resol = this._get_resolution_str(r, span);
            const [, [format]] = this._width_formats[resol];
            // Apply the format to the tick values
            const labels = [];
            const resol_ndx = format_order.indexOf(resol);
            // This dictionary maps the name of a time resolution (in @format_order)
            // to its index in a time.localtime() timetuple.  The default is to map
            // everything to index 0, which is year.  This is not ideal; it might cause
            // a problem with the tick at midnight, january 1st, 0 a.d. being incorrectly
            // promoted at certain tick resolutions.
            const time_tuple_ndx_for_resol = {};
            for (const fmt of format_order) {
                time_tuple_ndx_for_resol[fmt] = 0;
            }
            time_tuple_ndx_for_resol.seconds = 5;
            time_tuple_ndx_for_resol.minsec = 4;
            time_tuple_ndx_for_resol.minutes = 4;
            time_tuple_ndx_for_resol.hourmin = 3;
            time_tuple_ndx_for_resol.hours = 3;
            // As we format each tick, check to see if we are at a boundary of the
            // next higher unit of time.  If so, replace the current format with one
            // from that resolution.  This is not the best heuristic in the world,
            // but it works!  There is some trickiness here due to having to deal
            // with hybrid formats in a reasonable manner.
            for (const t of ticks) {
                let s, tm;
                try {
                    tm = _array(t);
                    s = _strftime(t, format);
                }
                catch (error) {
                    logging_1.logger.warn(`unable to format tick for timestamp value ${t}`);
                    logging_1.logger.warn(` - ${error}`);
                    labels.push("ERR");
                    continue;
                }
                let hybrid_handled = false;
                let next_ndx = resol_ndx;
                // The way to check that we are at the boundary of the next unit of
                // time is by checking that we have 0 units of the resolution, i.e.
                // we are at zero minutes, so display hours, or we are at zero seconds,
                // so display minutes (and if that is zero as well, then display hours).
                while (tm[time_tuple_ndx_for_resol[format_order[next_ndx]]] == 0) {
                    let next_format;
                    next_ndx += 1;
                    if (next_ndx == format_order.length)
                        break;
                    if ((resol == "minsec" || resol == "hourmin") && !hybrid_handled) {
                        if ((resol == "minsec" && tm[4] == 0 && tm[5] != 0) || (resol == "hourmin" && tm[3] == 0 && tm[4] != 0)) {
                            next_format = this._width_formats[format_order[resol_ndx - 1]][1][0];
                            s = _strftime(t, next_format);
                            break;
                        }
                        else {
                            hybrid_handled = true;
                        }
                    }
                    next_format = this._width_formats[format_order[next_ndx]][1][0];
                    s = _strftime(t, next_format);
                }
                // TODO: should expose this in api. %H, %d, etc use leading zeros and
                // users might prefer to see them lined up correctly.
                if (this.strip_leading_zeros) {
                    let ss = s.replace(/^0+/g, "");
                    if (ss != s && isNaN(parseInt(ss))) {
                        // If the string can now be parsed as starting with an integer, then
                        // leave all zeros stripped, otherwise start with a zero. Hence:
                        // A label such as '000ms' should leave one zero.
                        // A label such as '001ms' or '0-1ms' should not leave a leading zero.
                        ss = `0${ss}`;
                    }
                    labels.push(ss);
                }
                else
                    labels.push(s);
            }
            return labels;
        }
    }
    exports.DatetimeTickFormatter = DatetimeTickFormatter;
    DatetimeTickFormatter.__name__ = "DatetimeTickFormatter";
    DatetimeTickFormatter.init_DatetimeTickFormatter();
},
/* timezone/index.js */ function _(require, module, exports) {
    !function (definition) {
        if (typeof module == "object" && module.exports)
            module.exports = definition();
        else if (typeof define == "function")
            define(definition);
        else
            this.tz = definition();
    }(function () {
        /*
          function die () {
            console.log.apply(console, __slice.call(arguments, 0));
            return process.exit(1);
          }
        
          function say () { return console.log.apply(console, __slice.call(arguments, 0)) }
        */
        function actualize(entry, rule, year) {
            var actualized, date = rule.day[1];
            do {
                actualized = new Date(Date.UTC(year, rule.month, Math.abs(date++)));
            } while (rule.day[0] < 7 && actualized.getUTCDay() != rule.day[0]);
            actualized = {
                clock: rule.clock,
                sort: actualized.getTime(),
                rule: rule,
                save: rule.save * 6e4,
                offset: entry.offset
            };
            actualized[actualized.clock] = actualized.sort + rule.time * 6e4;
            if (actualized.posix) {
                actualized.wallclock = actualized[actualized.clock] + (entry.offset + rule.saved);
            }
            else {
                actualized.posix = actualized[actualized.clock] - (entry.offset + rule.saved);
            }
            return actualized;
        }
        function find(request, clock, time) {
            var i, I, entry, found, zone = request[request.zone], actualized = [], abbrev, rules, j, year = new Date(time).getUTCFullYear(), off = 1;
            for (i = 1, I = zone.length; i < I; i++)
                if (zone[i][clock] <= time)
                    break;
            entry = zone[i];
            if (entry.rules) {
                rules = request[entry.rules];
                for (j = year + 1; j >= year - off; --j)
                    for (i = 0, I = rules.length; i < I; i++)
                        if (rules[i].from <= j && j <= rules[i].to)
                            actualized.push(actualize(entry, rules[i], j));
                        else if (rules[i].to < j && off == 1)
                            off = j - rules[i].to;
                actualized.sort(function (a, b) { return a.sort - b.sort; });
                for (i = 0, I = actualized.length; i < I; i++) {
                    if (time >= actualized[i][clock] && actualized[i][actualized[i].clock] > entry[actualized[i].clock])
                        found = actualized[i];
                }
            }
            if (found) {
                if (abbrev = /^(.*)\/(.*)$/.exec(entry.format)) {
                    found.abbrev = abbrev[found.save ? 2 : 1];
                }
                else {
                    found.abbrev = entry.format.replace(/%s/, found.rule.letter);
                }
            }
            return found || entry;
        }
        function convertToWallclock(request, posix) {
            if (request.zone == "UTC")
                return posix;
            request.entry = find(request, "posix", posix);
            return posix + request.entry.offset + request.entry.save;
        }
        function convertToPOSIX(request, wallclock) {
            if (request.zone == "UTC")
                return wallclock;
            var entry, diff;
            request.entry = entry = find(request, "wallclock", wallclock);
            diff = wallclock - entry.wallclock;
            return 0 < diff && diff < entry.save ? null : wallclock - entry.offset - entry.save;
        }
        function adjust(request, posix, match) {
            var increment = +(match[1] + 1) // conversion necessary for week day addition
            , offset = match[2] * increment, index = UNITS.indexOf(match[3].toLowerCase()), date;
            if (index > 9) {
                posix += offset * TIME[index - 10];
            }
            else {
                date = new Date(convertToWallclock(request, posix));
                if (index < 7) {
                    while (offset) {
                        date.setUTCDate(date.getUTCDate() + increment);
                        if (date.getUTCDay() == index)
                            offset -= increment;
                    }
                }
                else if (index == 7) {
                    date.setUTCFullYear(date.getUTCFullYear() + offset);
                }
                else if (index == 8) {
                    date.setUTCMonth(date.getUTCMonth() + offset);
                }
                else {
                    date.setUTCDate(date.getUTCDate() + offset);
                }
                if ((posix = convertToPOSIX(request, date.getTime())) == null) {
                    posix = convertToPOSIX(request, date.getTime() + 864e5 * increment) - 864e5 * increment;
                }
            }
            return posix;
        }
        function convert(vargs) {
            if (!vargs.length)
                return "1.0.22";
            var request = Object.create(this), adjustments = [], i, I, $, argument, date;
            for (i = 0; i < vargs.length; i++) { // leave the for loop alone, it works.
                argument = vargs[i];
                // https://twitter.com/bigeasy/status/215112186572439552
                if (Array.isArray(argument)) {
                    if (!i && !isNaN(argument[1])) {
                        date = argument;
                    }
                    else {
                        argument.splice.apply(vargs, [i--, 1].concat(argument));
                    }
                }
                else if (isNaN(argument)) {
                    $ = typeof argument;
                    if ($ == "string") {
                        if (~argument.indexOf("%")) {
                            request.format = argument;
                        }
                        else if (!i && argument == "*") {
                            date = argument;
                        }
                        else if (!i && ($ = /^(\d{4})-(\d{2})-(\d{2})(?:[T\s](\d{2}):(\d{2})(?::(\d{2})(?:\.(\d+))?)?(Z|(([+-])(\d{2}(:\d{2}){0,2})))?)?$/.exec(argument))) {
                            date = [];
                            date.push.apply(date, $.slice(1, 8));
                            if ($[9]) {
                                date.push($[10] + 1);
                                date.push.apply(date, $[11].split(/:/));
                            }
                            else if ($[8]) {
                                date.push(1);
                            }
                        }
                        else if (/^\w{2,3}_\w{2}$/.test(argument)) {
                            request.locale = argument;
                        }
                        else if ($ = UNIT_RE.exec(argument)) {
                            adjustments.push($);
                        }
                        else {
                            request.zone = argument;
                        }
                    }
                    else if ($ == "function") {
                        if ($ = argument.call(request))
                            return $;
                    }
                    else if (/^\w{2,3}_\w{2}$/.test(argument.name)) {
                        request[argument.name] = argument;
                    }
                    else if (argument.zones) {
                        for ($ in argument.zones)
                            request[$] = argument.zones[$];
                        for ($ in argument.rules)
                            request[$] = argument.rules[$];
                    }
                }
                else if (!i) {
                    date = argument;
                }
            }
            if (!request[request.locale])
                delete request.locale;
            if (!request[request.zone])
                delete request.zone;
            if (date != null) {
                if (date == "*") {
                    date = request.clock();
                }
                else if (Array.isArray(date)) {
                    $ = [];
                    I = !date[7];
                    for (i = 0; i < 11; i++)
                        $[i] = +(date[i] || 0); // conversion necessary for decrement
                    --$[1]; // Grr..
                    date = Date.UTC.apply(Date.UTC, $) + -$[7] * ($[8] * 36e5 + $[9] * 6e4 + $[10] * 1e3);
                }
                else {
                    date = Math.floor(date);
                }
                if (!isNaN(date)) {
                    if (I)
                        date = convertToPOSIX(request, date);
                    if (date == null)
                        return date;
                    for (i = 0, I = adjustments.length; i < I; i++) {
                        date = adjust(request, date, adjustments[i]);
                    }
                    if (!request.format)
                        return date;
                    $ = new Date(convertToWallclock(request, date));
                    return request.format.replace(/%([-0_^]?)(:{0,3})(\d*)(.)/g, function (value, flag, colons, padding, specifier) {
                        var f, fill = "0", pad;
                        if (f = request[specifier]) {
                            value = String(f.call(request, $, date, flag, colons.length));
                            if ((flag || f.style) == "_")
                                fill = " ";
                            pad = flag == "-" ? 0 : f.pad || 0;
                            while (value.length < pad)
                                value = fill + value;
                            pad = flag == "-" ? 0 : padding || f.pad;
                            while (value.length < pad)
                                value = fill + value;
                            if (specifier == "N" && pad < value.length)
                                value = value.slice(0, pad);
                            if (flag == "^")
                                value = value.toUpperCase();
                        }
                        return value;
                    });
                }
            }
            return function () { return request.convert(arguments); };
        }
        var context = { clock: function () { return +(new Date()); },
            zone: "UTC",
            entry: { abbrev: "UTC", offset: 0, save: 0 },
            UTC: 1,
            z: function (date, posix, flag, delimiters) {
                var offset = this.entry.offset + this.entry.save, seconds = Math.abs(offset / 1000), parts = [], part = 3600, i, z;
                for (i = 0; i < 3; i++) {
                    parts.push(("0" + Math.floor(seconds / part)).slice(-2));
                    seconds %= part;
                    part /= 60;
                }
                if (flag == "^" && !offset)
                    return "Z";
                if (flag == "^")
                    delimiters = 3;
                if (delimiters == 3) {
                    z = parts.join(":");
                    z = z.replace(/:00$/, "");
                    if (flag != "^")
                        z = z.replace(/:00$/, "");
                }
                else if (delimiters) {
                    z = parts.slice(0, delimiters + 1).join(":");
                    if (flag == "^")
                        z = z.replace(/:00$/, "");
                }
                else {
                    z = parts.slice(0, 2).join("");
                }
                z = (offset < 0 ? "-" : "+") + z;
                z = z.replace(/([-+])(0)/, { "_": " $1", "-": "$1" }[flag] || "$1$2");
                return z;
            },
            "%": function (date) { return "%"; },
            n: function (date) { return "\n"; },
            t: function (date) { return "\t"; },
            U: function (date) { return weekOfYear(date, 0); },
            W: function (date) { return weekOfYear(date, 1); },
            V: function (date) { return isoWeek(date)[0]; },
            G: function (date) { return isoWeek(date)[1]; },
            g: function (date) { return isoWeek(date)[1] % 100; },
            j: function (date) { return Math.floor((date.getTime() - Date.UTC(date.getUTCFullYear(), 0)) / 864e5) + 1; },
            s: function (date) { return Math.floor(date.getTime() / 1000); },
            C: function (date) { return Math.floor(date.getUTCFullYear() / 100); },
            N: function (date) { return date.getTime() % 1000 * 1000000; },
            m: function (date) { return date.getUTCMonth() + 1; },
            Y: function (date) { return date.getUTCFullYear(); },
            y: function (date) { return date.getUTCFullYear() % 100; },
            H: function (date) { return date.getUTCHours(); },
            M: function (date) { return date.getUTCMinutes(); },
            S: function (date) { return date.getUTCSeconds(); },
            e: function (date) { return date.getUTCDate(); },
            d: function (date) { return date.getUTCDate(); },
            u: function (date) { return date.getUTCDay() || 7; },
            w: function (date) { return date.getUTCDay(); },
            l: function (date) { return date.getUTCHours() % 12 || 12; },
            I: function (date) { return date.getUTCHours() % 12 || 12; },
            k: function (date) { return date.getUTCHours(); },
            Z: function (date) { return this.entry.abbrev; },
            a: function (date) { return this[this.locale].day.abbrev[date.getUTCDay()]; },
            A: function (date) { return this[this.locale].day.full[date.getUTCDay()]; },
            h: function (date) { return this[this.locale].month.abbrev[date.getUTCMonth()]; },
            b: function (date) { return this[this.locale].month.abbrev[date.getUTCMonth()]; },
            B: function (date) { return this[this.locale].month.full[date.getUTCMonth()]; },
            P: function (date) { return this[this.locale].meridiem[Math.floor(date.getUTCHours() / 12)].toLowerCase(); },
            p: function (date) { return this[this.locale].meridiem[Math.floor(date.getUTCHours() / 12)]; },
            R: function (date, posix) { return this.convert([posix, "%H:%M"]); },
            T: function (date, posix) { return this.convert([posix, "%H:%M:%S"]); },
            D: function (date, posix) { return this.convert([posix, "%m/%d/%y"]); },
            F: function (date, posix) { return this.convert([posix, "%Y-%m-%d"]); },
            x: function (date, posix) { return this.convert([posix, this[this.locale].date]); },
            r: function (date, posix) { return this.convert([posix, this[this.locale].time12 || '%I:%M:%S']); },
            X: function (date, posix) { return this.convert([posix, this[this.locale].time24]); },
            c: function (date, posix) { return this.convert([posix, this[this.locale].dateTime]); },
            convert: convert,
            locale: "en_US",
            en_US: {
                date: "%m/%d/%Y",
                time24: "%I:%M:%S %p",
                time12: "%I:%M:%S %p",
                dateTime: "%a %d %b %Y %I:%M:%S %p %Z",
                meridiem: ["AM", "PM"],
                month: {
                    abbrev: "Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec".split("|"),
                    full: "January|February|March|April|May|June|July|August|September|October|November|December".split("|")
                },
                day: {
                    abbrev: "Sun|Mon|Tue|Wed|Thu|Fri|Sat".split("|"),
                    full: "Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday".split("|")
                }
            }
        };
        var UNITS = "Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|year|month|day|hour|minute|second|millisecond", UNIT_RE = new RegExp("^\\s*([+-])(\\d+)\\s+(" + UNITS + ")s?\\s*$", "i"), TIME = [36e5, 6e4, 1e3, 1];
        UNITS = UNITS.toLowerCase().split("|");
        "delmHMSUWVgCIky".replace(/./g, function (e) { context[e].pad = 2; });
        context.N.pad = 9;
        context.j.pad = 3;
        context.k.style = "_";
        context.l.style = "_";
        context.e.style = "_";
        function weekOfYear(date, startOfWeek) {
            var diff, nyd, weekStart;
            nyd = new Date(Date.UTC(date.getUTCFullYear(), 0));
            diff = Math.floor((date.getTime() - nyd.getTime()) / 864e5);
            if (nyd.getUTCDay() == startOfWeek) {
                weekStart = 0;
            }
            else {
                weekStart = 7 - nyd.getUTCDay() + startOfWeek;
                if (weekStart == 8) {
                    weekStart = 1;
                }
            }
            return diff >= weekStart ? Math.floor((diff - weekStart) / 7) + 1 : 0;
        }
        function isoWeek(date) {
            var nyd, nyy, week;
            nyy = date.getUTCFullYear();
            nyd = new Date(Date.UTC(nyy, 0)).getUTCDay();
            week = weekOfYear(date, 1) + (nyd > 1 && nyd <= 4 ? 1 : 0);
            if (!week) {
                nyy = date.getUTCFullYear() - 1;
                nyd = new Date(Date.UTC(nyy, 0)).getUTCDay();
                week = nyd == 4 || (nyd == 3 && new Date(nyy, 1, 29).getDate() == 29) ? 53 : 52;
                return [week, date.getUTCFullYear() - 1];
            }
            else if (week == 53 && !(nyd == 4 || (nyd == 3 && new Date(nyy, 1, 29).getDate() == 29))) {
                return [1, date.getUTCFullYear() + 1];
            }
            else {
                return [week, date.getUTCFullYear()];
            }
        }
        return function () { return context.convert(arguments); };
    });
},
/* core/util/templating.js */ function _(require, module, exports) {
    const sprintf_js_1 = require(152) /* sprintf-js */;
    const Numbro = require(153) /* numbro */;
    const tz = require(150) /* timezone */;
    const string_1 = require(25) /* ./string */;
    const types_1 = require(7) /* ./types */;
    function sprintf(format, ...args) {
        return sprintf_js_1.sprintf(format, ...args);
    }
    exports.sprintf = sprintf;
    exports.DEFAULT_FORMATTERS = {
        numeral: (value, format, _special_vars) => Numbro.format(value, format),
        datetime: (value, format, _special_vars) => tz(value, format),
        printf: (value, format, _special_vars) => sprintf(format, value),
    };
    function basic_formatter(value, _format, _special_vars) {
        if (types_1.isNumber(value)) {
            const format = (() => {
                switch (false) {
                    case Math.floor(value) != value:
                        return "%d";
                    case !(Math.abs(value) > 0.1) || !(Math.abs(value) < 1000):
                        return "%0.3f";
                    default:
                        return "%0.3e";
                }
            })();
            return sprintf(format, value);
        }
        else
            return `${value}`; // get strings for categorical types
    }
    exports.basic_formatter = basic_formatter;
    function get_formatter(name, raw_spec, format, formatters) {
        // no format, use default built in formatter
        if (format == null)
            return basic_formatter;
        // format spec in the formatters dict, use that
        if (formatters != null && (name in formatters || raw_spec in formatters)) {
            // some day (Bokeh 2.0) we can get rid of the check for name, and just check the raw spec
            // keep it now for compatibility but do not demonstrate it anywhere
            const key = raw_spec in formatters ? raw_spec : name;
            const formatter = formatters[key];
            if (types_1.isString(formatter)) {
                if (formatter in exports.DEFAULT_FORMATTERS)
                    return exports.DEFAULT_FORMATTERS[formatter];
                else
                    throw new Error(`Unknown tooltip field formatter type '${formatter}'`);
            }
            return function (value, format, special_vars) {
                return formatter.format(value, format, special_vars);
            };
        }
        // otherwise use "numeral" as default
        return exports.DEFAULT_FORMATTERS.numeral;
    }
    exports.get_formatter = get_formatter;
    function get_value(name, data_source, i, special_vars) {
        if (name[0] == "$") {
            if (name.substring(1) in special_vars)
                return special_vars[name.substring(1)];
            else
                throw new Error(`Unknown special variable '${name}'`);
        }
        const column = data_source.get_column(name);
        // missing column
        if (column == null)
            return null;
        // typical (non-image) index
        if (types_1.isNumber(i))
            return column[i];
        // image index
        const data = column[i.index];
        if (types_1.isTypedArray(data) || types_1.isArray(data)) {
            // inspect array of arrays
            if (types_1.isArray(data[0])) {
                const row = data[i.dim2];
                return row[i.dim1];
            }
            else
                return data[i.flat_index]; // inspect flat array
        }
        else
            return data; // inspect per-image scalar data
    }
    exports.get_value = get_value;
    function replace_placeholders(str, data_source, i, formatters, special_vars = {}) {
        // this extracts the $x, @x, @{x} without any trailing {format}
        const raw_spec = str.replace(/(?:^|[^@])([@|\$](?:\w+|{[^{}]+}))(?:{[^{}]+})?/g, (_match, raw_spec, _format) => `${raw_spec}`);
        // this handles the special case @$name, replacing it with an @var corresponding to special_vars.name
        str = str.replace(/@\$name/g, (_match) => `@{${special_vars.name}}`);
        // this prepends special vars with "@", e.g "$x" becomes "@$x", so subsequent processing is simpler
        str = str.replace(/(^|[^\$])\$(\w+)/g, (_match, prefix, name) => `${prefix}@$${name}`);
        str = str.replace(/(^|[^@])@(?:(\$?\w+)|{([^{}]+)})(?:{([^{}]+)})?/g, (_match, prefix, name, long_name, format) => {
            name = long_name != null ? long_name : name;
            const value = get_value(name, data_source, i, special_vars);
            // missing value, return ???
            if (value == null)
                return `${prefix}${string_1.escape("???")}`;
            // 'safe' format, return the value as-is
            if (format == 'safe')
                return `${prefix}${value}`;
            // format and escape everything else
            const formatter = get_formatter(name, raw_spec, format, formatters);
            return `${prefix}${string_1.escape(formatter(value, format, special_vars))}`;
        });
        return str;
    }
    exports.replace_placeholders = replace_placeholders;
},
/* sprintf-js/src/sprintf.js */ function _(require, module, exports) {
    /* global window, exports, define */
    !function () {
        'use strict';
        var re = {
            not_string: /[^s]/,
            not_bool: /[^t]/,
            not_type: /[^T]/,
            not_primitive: /[^v]/,
            number: /[diefg]/,
            numeric_arg: /[bcdiefguxX]/,
            json: /[j]/,
            not_json: /[^j]/,
            text: /^[^\x25]+/,
            modulo: /^\x25{2}/,
            placeholder: /^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,
            key: /^([a-z_][a-z_\d]*)/i,
            key_access: /^\.([a-z_][a-z_\d]*)/i,
            index_access: /^\[(\d+)\]/,
            sign: /^[+-]/
        };
        function sprintf(key) {
            // `arguments` is not an array, but should be fine for this call
            return sprintf_format(sprintf_parse(key), arguments);
        }
        function vsprintf(fmt, argv) {
            return sprintf.apply(null, [fmt].concat(argv || []));
        }
        function sprintf_format(parse_tree, argv) {
            var cursor = 1, tree_length = parse_tree.length, arg, output = '', i, k, ph, pad, pad_character, pad_length, is_positive, sign;
            for (i = 0; i < tree_length; i++) {
                if (typeof parse_tree[i] === 'string') {
                    output += parse_tree[i];
                }
                else if (typeof parse_tree[i] === 'object') {
                    ph = parse_tree[i]; // convenience purposes only
                    if (ph.keys) { // keyword argument
                        arg = argv[cursor];
                        for (k = 0; k < ph.keys.length; k++) {
                            if (arg == undefined) {
                                throw new Error(sprintf('[sprintf] Cannot access property "%s" of undefined value "%s"', ph.keys[k], ph.keys[k - 1]));
                            }
                            arg = arg[ph.keys[k]];
                        }
                    }
                    else if (ph.param_no) { // positional argument (explicit)
                        arg = argv[ph.param_no];
                    }
                    else { // positional argument (implicit)
                        arg = argv[cursor++];
                    }
                    if (re.not_type.test(ph.type) && re.not_primitive.test(ph.type) && arg instanceof Function) {
                        arg = arg();
                    }
                    if (re.numeric_arg.test(ph.type) && (typeof arg !== 'number' && isNaN(arg))) {
                        throw new TypeError(sprintf('[sprintf] expecting number but found %T', arg));
                    }
                    if (re.number.test(ph.type)) {
                        is_positive = arg >= 0;
                    }
                    switch (ph.type) {
                        case 'b':
                            arg = parseInt(arg, 10).toString(2);
                            break;
                        case 'c':
                            arg = String.fromCharCode(parseInt(arg, 10));
                            break;
                        case 'd':
                        case 'i':
                            arg = parseInt(arg, 10);
                            break;
                        case 'j':
                            arg = JSON.stringify(arg, null, ph.width ? parseInt(ph.width) : 0);
                            break;
                        case 'e':
                            arg = ph.precision ? parseFloat(arg).toExponential(ph.precision) : parseFloat(arg).toExponential();
                            break;
                        case 'f':
                            arg = ph.precision ? parseFloat(arg).toFixed(ph.precision) : parseFloat(arg);
                            break;
                        case 'g':
                            arg = ph.precision ? String(Number(arg.toPrecision(ph.precision))) : parseFloat(arg);
                            break;
                        case 'o':
                            arg = (parseInt(arg, 10) >>> 0).toString(8);
                            break;
                        case 's':
                            arg = String(arg);
                            arg = (ph.precision ? arg.substring(0, ph.precision) : arg);
                            break;
                        case 't':
                            arg = String(!!arg);
                            arg = (ph.precision ? arg.substring(0, ph.precision) : arg);
                            break;
                        case 'T':
                            arg = Object.prototype.toString.call(arg).slice(8, -1).toLowerCase();
                            arg = (ph.precision ? arg.substring(0, ph.precision) : arg);
                            break;
                        case 'u':
                            arg = parseInt(arg, 10) >>> 0;
                            break;
                        case 'v':
                            arg = arg.valueOf();
                            arg = (ph.precision ? arg.substring(0, ph.precision) : arg);
                            break;
                        case 'x':
                            arg = (parseInt(arg, 10) >>> 0).toString(16);
                            break;
                        case 'X':
                            arg = (parseInt(arg, 10) >>> 0).toString(16).toUpperCase();
                            break;
                    }
                    if (re.json.test(ph.type)) {
                        output += arg;
                    }
                    else {
                        if (re.number.test(ph.type) && (!is_positive || ph.sign)) {
                            sign = is_positive ? '+' : '-';
                            arg = arg.toString().replace(re.sign, '');
                        }
                        else {
                            sign = '';
                        }
                        pad_character = ph.pad_char ? ph.pad_char === '0' ? '0' : ph.pad_char.charAt(1) : ' ';
                        pad_length = ph.width - (sign + arg).length;
                        pad = ph.width ? (pad_length > 0 ? pad_character.repeat(pad_length) : '') : '';
                        output += ph.align ? sign + arg + pad : (pad_character === '0' ? sign + pad + arg : pad + sign + arg);
                    }
                }
            }
            return output;
        }
        var sprintf_cache = Object.create(null);
        function sprintf_parse(fmt) {
            if (sprintf_cache[fmt]) {
                return sprintf_cache[fmt];
            }
            var _fmt = fmt, match, parse_tree = [], arg_names = 0;
            while (_fmt) {
                if ((match = re.text.exec(_fmt)) !== null) {
                    parse_tree.push(match[0]);
                }
                else if ((match = re.modulo.exec(_fmt)) !== null) {
                    parse_tree.push('%');
                }
                else if ((match = re.placeholder.exec(_fmt)) !== null) {
                    if (match[2]) {
                        arg_names |= 1;
                        var field_list = [], replacement_field = match[2], field_match = [];
                        if ((field_match = re.key.exec(replacement_field)) !== null) {
                            field_list.push(field_match[1]);
                            while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
                                if ((field_match = re.key_access.exec(replacement_field)) !== null) {
                                    field_list.push(field_match[1]);
                                }
                                else if ((field_match = re.index_access.exec(replacement_field)) !== null) {
                                    field_list.push(field_match[1]);
                                }
                                else {
                                    throw new SyntaxError('[sprintf] failed to parse named argument key');
                                }
                            }
                        }
                        else {
                            throw new SyntaxError('[sprintf] failed to parse named argument key');
                        }
                        match[2] = field_list;
                    }
                    else {
                        arg_names |= 2;
                    }
                    if (arg_names === 3) {
                        throw new Error('[sprintf] mixing positional and named placeholders is not (yet) supported');
                    }
                    parse_tree.push({
                        placeholder: match[0],
                        param_no: match[1],
                        keys: match[2],
                        sign: match[3],
                        pad_char: match[4],
                        align: match[5],
                        width: match[6],
                        precision: match[7],
                        type: match[8]
                    });
                }
                else {
                    throw new SyntaxError('[sprintf] unexpected placeholder');
                }
                _fmt = _fmt.substring(match[0].length);
            }
            return sprintf_cache[fmt] = parse_tree;
        }
        /**
         * export to either browser or node.js
         */
        /* eslint-disable quote-props */
        if (typeof exports !== 'undefined') {
            exports['sprintf'] = sprintf;
            exports['vsprintf'] = vsprintf;
        }
        if (typeof window !== 'undefined') {
            window['sprintf'] = sprintf;
            window['vsprintf'] = vsprintf;
            if (typeof define === 'function' && define['amd']) {
                define(function () {
                    return {
                        'sprintf': sprintf,
                        'vsprintf': vsprintf
                    };
                });
            }
        }
        /* eslint-enable quote-props */
    }(); // eslint-disable-line
},
/* numbro/numbro.js */ function _(require, module, exports) {
    /*!
     * numbro.js
     * version : 1.6.2
     * author : Företagsplatsen AB
     * license : MIT
     * http://www.foretagsplatsen.se
     */
    /************************************
        Constants
    ************************************/
    var numbro, VERSION = '1.6.2', 
    // internal storage for culture config files
    cultures = {}, 
    // Todo: Remove in 2.0.0
    languages = cultures, currentCulture = 'en-US', zeroFormat = null, defaultFormat = '0,0', defaultCurrencyFormat = '0$', 
    // check for nodeJS
    hasModule = (typeof module !== 'undefined' && module.exports), 
    // default culture
    enUS = {
        delimiters: {
            thousands: ',',
            decimal: '.'
        },
        abbreviations: {
            thousand: 'k',
            million: 'm',
            billion: 'b',
            trillion: 't'
        },
        ordinal: function (number) {
            var b = number % 10;
            return (~~(number % 100 / 10) === 1) ? 'th' :
                (b === 1) ? 'st' :
                    (b === 2) ? 'nd' :
                        (b === 3) ? 'rd' : 'th';
        },
        currency: {
            symbol: '$',
            position: 'prefix'
        },
        defaults: {
            currencyFormat: ',0000 a'
        },
        formats: {
            fourDigits: '0000 a',
            fullWithTwoDecimals: '$ ,0.00',
            fullWithTwoDecimalsNoCurrency: ',0.00'
        }
    };
    /************************************
        Constructors
    ************************************/
    // Numbro prototype object
    function Numbro(number) {
        this._value = number;
    }
    function zeroes(count) {
        var i, ret = '';
        for (i = 0; i < count; i++) {
            ret += '0';
        }
        return ret;
    }
    /**
     * Implementation of toFixed() for numbers with exponent > 21
     *
     *
     */
    function toFixedLarge(value, precision) {
        var mantissa, beforeDec, afterDec, exponent, str;
        str = value.toString();
        mantissa = str.split('e')[0];
        exponent = str.split('e')[1];
        beforeDec = mantissa.split('.')[0];
        afterDec = mantissa.split('.')[1] || '';
        str = beforeDec + afterDec + zeroes(exponent - afterDec.length);
        if (precision > 0) {
            str += '.' + zeroes(precision);
        }
        return str;
    }
    /**
     * Implementation of toFixed() that treats floats more like decimals
     *
     * Fixes binary rounding issues (eg. (0.615).toFixed(2) === '0.61') that present
     * problems for accounting- and finance-related software.
     */
    function toFixed(value, precision, roundingFunction, optionals) {
        var power = Math.pow(10, precision), optionalsRegExp, output;
        if (value.toFixed(0).search('e') > -1) {
            // Above 1e21, toFixed returns scientific notation, which
            // is useless and unexpected
            output = toFixedLarge(value, precision);
        }
        else {
            //roundingFunction = (roundingFunction !== undefined ? roundingFunction : Math.round);
            // Multiply up by precision, round accurately, then divide and use native toFixed():
            output = (roundingFunction(value * power) / power).toFixed(precision);
        }
        if (optionals) {
            optionalsRegExp = new RegExp('0{1,' + optionals + '}$');
            output = output.replace(optionalsRegExp, '');
        }
        return output;
    }
    /************************************
        Formatting
    ************************************/
    // determine what type of formatting we need to do
    function formatNumbro(value, format, roundingFunction) {
        var output;
        // TODO: do something with `language`
        // figure out what kind of format we are dealing with
        if (format.indexOf('$') > -1) { // currency!!!!!
            output = formatCurrency(value, format, roundingFunction);
        }
        else if (format.indexOf('%') > -1) { // percentage
            output = formatPercentage(value, format, roundingFunction);
        }
        else if (format.indexOf(':') > -1) { // time
            output = formatTime(value);
        }
        else { // plain ol' numbers or bytes
            output = formatNumber(value, format, roundingFunction);
        }
        // return string
        return output;
    }
    function formatCurrency(value, originalFormat, roundingFunction) {
        var format = originalFormat, symbolIndex = format.indexOf('$'), openParenIndex = format.indexOf('('), plusSignIndex = format.indexOf('+'), minusSignIndex = format.indexOf('-'), space = '', decimalSeparator = '', spliceIndex, output;
        if (format.indexOf('$') === -1) {
            // Use defaults instead of the format provided
            if (cultures[currentCulture].currency.position === 'infix') {
                decimalSeparator = cultures[currentCulture].currency.symbol;
                if (cultures[currentCulture].currency.spaceSeparated) {
                    decimalSeparator = ' ' + decimalSeparator + ' ';
                }
            }
            else if (cultures[currentCulture].currency.spaceSeparated) {
                space = ' ';
            }
        }
        else {
            // check for space before or after currency
            if (format.indexOf(' $') > -1) {
                space = ' ';
                format = format.replace(' $', '');
            }
            else if (format.indexOf('$ ') > -1) {
                space = ' ';
                format = format.replace('$ ', '');
            }
            else {
                format = format.replace('$', '');
            }
        }
        // Format The Number
        output = formatNumber(value, format, roundingFunction, decimalSeparator);
        if (originalFormat.indexOf('$') === -1) {
            // Use defaults instead of the format provided
            switch (cultures[currentCulture].currency.position) {
                case 'postfix':
                    if (output.indexOf(')') > -1) {
                        output = output.split('');
                        output.splice(-1, 0, space + cultures[currentCulture].currency.symbol);
                        output = output.join('');
                    }
                    else {
                        output = output + space + cultures[currentCulture].currency.symbol;
                    }
                    break;
                case 'infix':
                    break;
                case 'prefix':
                    if (output.indexOf('(') > -1 || output.indexOf('-') > -1) {
                        output = output.split('');
                        spliceIndex = Math.max(openParenIndex, minusSignIndex) + 1;
                        output.splice(spliceIndex, 0, cultures[currentCulture].currency.symbol + space);
                        output = output.join('');
                    }
                    else {
                        output = cultures[currentCulture].currency.symbol + space + output;
                    }
                    break;
                default:
                    throw Error('Currency position should be among ["prefix", "infix", "postfix"]');
            }
        }
        else {
            // position the symbol
            if (symbolIndex <= 1) {
                if (output.indexOf('(') > -1 || output.indexOf('+') > -1 || output.indexOf('-') > -1) {
                    output = output.split('');
                    spliceIndex = 1;
                    if (symbolIndex < openParenIndex || symbolIndex < plusSignIndex || symbolIndex < minusSignIndex) {
                        // the symbol appears before the "(", "+" or "-"
                        spliceIndex = 0;
                    }
                    output.splice(spliceIndex, 0, cultures[currentCulture].currency.symbol + space);
                    output = output.join('');
                }
                else {
                    output = cultures[currentCulture].currency.symbol + space + output;
                }
            }
            else {
                if (output.indexOf(')') > -1) {
                    output = output.split('');
                    output.splice(-1, 0, space + cultures[currentCulture].currency.symbol);
                    output = output.join('');
                }
                else {
                    output = output + space + cultures[currentCulture].currency.symbol;
                }
            }
        }
        return output;
    }
    function formatPercentage(value, format, roundingFunction) {
        var space = '', output;
        value = value * 100;
        // check for space before %
        if (format.indexOf(' %') > -1) {
            space = ' ';
            format = format.replace(' %', '');
        }
        else {
            format = format.replace('%', '');
        }
        output = formatNumber(value, format, roundingFunction);
        if (output.indexOf(')') > -1) {
            output = output.split('');
            output.splice(-1, 0, space + '%');
            output = output.join('');
        }
        else {
            output = output + space + '%';
        }
        return output;
    }
    function formatTime(value) {
        var hours = Math.floor(value / 60 / 60), minutes = Math.floor((value - (hours * 60 * 60)) / 60), seconds = Math.round(value - (hours * 60 * 60) - (minutes * 60));
        return hours + ':' +
            ((minutes < 10) ? '0' + minutes : minutes) + ':' +
            ((seconds < 10) ? '0' + seconds : seconds);
    }
    function formatNumber(value, format, roundingFunction, sep) {
        var negP = false, signed = false, optDec = false, abbr = '', i, abbrK = false, // force abbreviation to thousands
        abbrM = false, // force abbreviation to millions
        abbrB = false, // force abbreviation to billions
        abbrT = false, // force abbreviation to trillions
        abbrForce = false, // force abbreviation
        bytes = '', ord = '', abs = Math.abs(value), binarySuffixes = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'], decimalSuffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'], min, max, power, totalLength, length, minimumPrecision, pow, w, intPrecision, precision, prefix, postfix, thousands, d = '', forcedNeg = false, neg = false, indexOpenP, size, indexMinus, paren = '', minlen;
        // check if number is zero and a custom zero format has been set
        if (value === 0 && zeroFormat !== null) {
            return zeroFormat;
        }
        if (!isFinite(value)) {
            return '' + value;
        }
        if (format.indexOf('{') === 0) {
            var end = format.indexOf('}');
            if (end === -1) {
                throw Error('Format should also contain a "}"');
            }
            prefix = format.slice(1, end);
            format = format.slice(end + 1);
        }
        else {
            prefix = '';
        }
        if (format.indexOf('}') === format.length - 1) {
            var start = format.indexOf('{');
            if (start === -1) {
                throw Error('Format should also contain a "{"');
            }
            postfix = format.slice(start + 1, -1);
            format = format.slice(0, start + 1);
        }
        else {
            postfix = '';
        }
        // check for min length
        var info;
        if (format.indexOf('.') === -1) {
            info = format.match(/([0-9]+).*/);
        }
        else {
            info = format.match(/([0-9]+)\..*/);
        }
        minlen = info === null ? -1 : info[1].length;
        // see if we should use parentheses for negative number or if we should prefix with a sign
        // if both are present we default to parentheses
        if (format.indexOf('-') !== -1) {
            forcedNeg = true;
        }
        if (format.indexOf('(') > -1) {
            negP = true;
            format = format.slice(1, -1);
        }
        else if (format.indexOf('+') > -1) {
            signed = true;
            format = format.replace(/\+/g, '');
        }
        // see if abbreviation is wanted
        if (format.indexOf('a') > -1) {
            intPrecision = format.split('.')[0].match(/[0-9]+/g) || ['0'];
            intPrecision = parseInt(intPrecision[0], 10);
            // check if abbreviation is specified
            abbrK = format.indexOf('aK') >= 0;
            abbrM = format.indexOf('aM') >= 0;
            abbrB = format.indexOf('aB') >= 0;
            abbrT = format.indexOf('aT') >= 0;
            abbrForce = abbrK || abbrM || abbrB || abbrT;
            // check for space before abbreviation
            if (format.indexOf(' a') > -1) {
                abbr = ' ';
                format = format.replace(' a', '');
            }
            else {
                format = format.replace('a', '');
            }
            totalLength = Math.floor(Math.log(abs) / Math.LN10) + 1;
            minimumPrecision = totalLength % 3;
            minimumPrecision = minimumPrecision === 0 ? 3 : minimumPrecision;
            if (intPrecision && abs !== 0) {
                length = Math.floor(Math.log(abs) / Math.LN10) + 1 - intPrecision;
                pow = 3 * ~~((Math.min(intPrecision, totalLength) - minimumPrecision) / 3);
                abs = abs / Math.pow(10, pow);
                if (format.indexOf('.') === -1 && intPrecision > 3) {
                    format += '[.]';
                    size = length === 0 ? 0 : 3 * ~~(length / 3) - length;
                    size = size < 0 ? size + 3 : size;
                    for (i = 0; i < size; i++) {
                        format += '0';
                    }
                }
            }
            if (Math.floor(Math.log(Math.abs(value)) / Math.LN10) + 1 !== intPrecision) {
                if (abs >= Math.pow(10, 12) && !abbrForce || abbrT) {
                    // trillion
                    abbr = abbr + cultures[currentCulture].abbreviations.trillion;
                    value = value / Math.pow(10, 12);
                }
                else if (abs < Math.pow(10, 12) && abs >= Math.pow(10, 9) && !abbrForce || abbrB) {
                    // billion
                    abbr = abbr + cultures[currentCulture].abbreviations.billion;
                    value = value / Math.pow(10, 9);
                }
                else if (abs < Math.pow(10, 9) && abs >= Math.pow(10, 6) && !abbrForce || abbrM) {
                    // million
                    abbr = abbr + cultures[currentCulture].abbreviations.million;
                    value = value / Math.pow(10, 6);
                }
                else if (abs < Math.pow(10, 6) && abs >= Math.pow(10, 3) && !abbrForce || abbrK) {
                    // thousand
                    abbr = abbr + cultures[currentCulture].abbreviations.thousand;
                    value = value / Math.pow(10, 3);
                }
            }
        }
        // see if we are formatting binary bytes
        if (format.indexOf('b') > -1) {
            // check for space before
            if (format.indexOf(' b') > -1) {
                bytes = ' ';
                format = format.replace(' b', '');
            }
            else {
                format = format.replace('b', '');
            }
            for (power = 0; power <= binarySuffixes.length; power++) {
                min = Math.pow(1024, power);
                max = Math.pow(1024, power + 1);
                if (value >= min && value < max) {
                    bytes = bytes + binarySuffixes[power];
                    if (min > 0) {
                        value = value / min;
                    }
                    break;
                }
            }
        }
        // see if we are formatting decimal bytes
        if (format.indexOf('d') > -1) {
            // check for space before
            if (format.indexOf(' d') > -1) {
                bytes = ' ';
                format = format.replace(' d', '');
            }
            else {
                format = format.replace('d', '');
            }
            for (power = 0; power <= decimalSuffixes.length; power++) {
                min = Math.pow(1000, power);
                max = Math.pow(1000, power + 1);
                if (value >= min && value < max) {
                    bytes = bytes + decimalSuffixes[power];
                    if (min > 0) {
                        value = value / min;
                    }
                    break;
                }
            }
        }
        // see if ordinal is wanted
        if (format.indexOf('o') > -1) {
            // check for space before
            if (format.indexOf(' o') > -1) {
                ord = ' ';
                format = format.replace(' o', '');
            }
            else {
                format = format.replace('o', '');
            }
            if (cultures[currentCulture].ordinal) {
                ord = ord + cultures[currentCulture].ordinal(value);
            }
        }
        if (format.indexOf('[.]') > -1) {
            optDec = true;
            format = format.replace('[.]', '.');
        }
        w = value.toString().split('.')[0];
        precision = format.split('.')[1];
        thousands = format.indexOf(',');
        if (precision) {
            if (precision.indexOf('*') !== -1) {
                d = toFixed(value, value.toString().split('.')[1].length, roundingFunction);
            }
            else {
                if (precision.indexOf('[') > -1) {
                    precision = precision.replace(']', '');
                    precision = precision.split('[');
                    d = toFixed(value, (precision[0].length + precision[1].length), roundingFunction, precision[1].length);
                }
                else {
                    d = toFixed(value, precision.length, roundingFunction);
                }
            }
            w = d.split('.')[0];
            if (d.split('.')[1].length) {
                var p = sep ? abbr + sep : cultures[currentCulture].delimiters.decimal;
                d = p + d.split('.')[1];
            }
            else {
                d = '';
            }
            if (optDec && Number(d.slice(1)) === 0) {
                d = '';
            }
        }
        else {
            w = toFixed(value, null, roundingFunction);
        }
        // format number
        if (w.indexOf('-') > -1) {
            w = w.slice(1);
            neg = true;
        }
        if (w.length < minlen) {
            w = new Array(minlen - w.length + 1).join('0') + w;
        }
        if (thousands > -1) {
            w = w.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1' +
                cultures[currentCulture].delimiters.thousands);
        }
        if (format.indexOf('.') === 0) {
            w = '';
        }
        indexOpenP = format.indexOf('(');
        indexMinus = format.indexOf('-');
        if (indexOpenP < indexMinus) {
            paren = ((negP && neg) ? '(' : '') + (((forcedNeg && neg) || (!negP && neg)) ? '-' : '');
        }
        else {
            paren = (((forcedNeg && neg) || (!negP && neg)) ? '-' : '') + ((negP && neg) ? '(' : '');
        }
        return prefix +
            paren + ((!neg && signed && value !== 0) ? '+' : '') +
            w + d +
            ((ord) ? ord : '') +
            ((abbr && !sep) ? abbr : '') +
            ((bytes) ? bytes : '') +
            ((negP && neg) ? ')' : '') +
            postfix;
    }
    /************************************
        Top Level Functions
    ************************************/
    numbro = function (input) {
        if (numbro.isNumbro(input)) {
            input = input.value();
        }
        else if (input === 0 || typeof input === 'undefined') {
            input = 0;
        }
        else if (!Number(input)) {
            input = numbro.fn.unformat(input);
        }
        return new Numbro(Number(input));
    };
    // version number
    numbro.version = VERSION;
    // compare numbro object
    numbro.isNumbro = function (obj) {
        return obj instanceof Numbro;
    };
    /**
     * This function allow the user to set a new language with a fallback if
     * the language does not exist. If no fallback language is provided,
     * it fallbacks to english.
     *
     * @deprecated Since in version 1.6.0. It will be deleted in version 2.0
     * `setCulture` should be used instead.
     */
    numbro.setLanguage = function (newLanguage, fallbackLanguage) {
        console.warn('`setLanguage` is deprecated since version 1.6.0. Use `setCulture` instead');
        var key = newLanguage, prefix = newLanguage.split('-')[0], matchingLanguage = null;
        if (!languages[key]) {
            Object.keys(languages).forEach(function (language) {
                if (!matchingLanguage && language.split('-')[0] === prefix) {
                    matchingLanguage = language;
                }
            });
            key = matchingLanguage || fallbackLanguage || 'en-US';
        }
        chooseCulture(key);
    };
    /**
     * This function allow the user to set a new culture with a fallback if
     * the culture does not exist. If no fallback culture is provided,
     * it fallbacks to "en-US".
     */
    numbro.setCulture = function (newCulture, fallbackCulture) {
        var key = newCulture, suffix = newCulture.split('-')[1], matchingCulture = null;
        if (!cultures[key]) {
            if (suffix) {
                Object.keys(cultures).forEach(function (language) {
                    if (!matchingCulture && language.split('-')[1] === suffix) {
                        matchingCulture = language;
                    }
                });
            }
            key = matchingCulture || fallbackCulture || 'en-US';
        }
        chooseCulture(key);
    };
    /**
     * This function will load languages and then set the global language.  If
     * no arguments are passed in, it will simply return the current global
     * language key.
     *
     * @deprecated Since in version 1.6.0. It will be deleted in version 2.0
     * `culture` should be used instead.
     */
    numbro.language = function (key, values) {
        console.warn('`language` is deprecated since version 1.6.0. Use `culture` instead');
        if (!key) {
            return currentCulture;
        }
        if (key && !values) {
            if (!languages[key]) {
                throw new Error('Unknown language : ' + key);
            }
            chooseCulture(key);
        }
        if (values || !languages[key]) {
            setCulture(key, values);
        }
        return numbro;
    };
    /**
     * This function will load cultures and then set the global culture.  If
     * no arguments are passed in, it will simply return the current global
     * culture code.
     */
    numbro.culture = function (code, values) {
        if (!code) {
            return currentCulture;
        }
        if (code && !values) {
            if (!cultures[code]) {
                throw new Error('Unknown culture : ' + code);
            }
            chooseCulture(code);
        }
        if (values || !cultures[code]) {
            setCulture(code, values);
        }
        return numbro;
    };
    /**
     * This function provides access to the loaded language data.  If
     * no arguments are passed in, it will simply return the current
     * global language object.
     *
     * @deprecated Since in version 1.6.0. It will be deleted in version 2.0
     * `culture` should be used instead.
     */
    numbro.languageData = function (key) {
        console.warn('`languageData` is deprecated since version 1.6.0. Use `cultureData` instead');
        if (!key) {
            return languages[currentCulture];
        }
        if (!languages[key]) {
            throw new Error('Unknown language : ' + key);
        }
        return languages[key];
    };
    /**
     * This function provides access to the loaded culture data.  If
     * no arguments are passed in, it will simply return the current
     * global culture object.
     */
    numbro.cultureData = function (code) {
        if (!code) {
            return cultures[currentCulture];
        }
        if (!cultures[code]) {
            throw new Error('Unknown culture : ' + code);
        }
        return cultures[code];
    };
    numbro.culture('en-US', enUS);
    /**
     * @deprecated Since in version 1.6.0. It will be deleted in version 2.0
     * `cultures` should be used instead.
     */
    numbro.languages = function () {
        console.warn('`languages` is deprecated since version 1.6.0. Use `cultures` instead');
        return languages;
    };
    numbro.cultures = function () {
        return cultures;
    };
    numbro.zeroFormat = function (format) {
        zeroFormat = typeof (format) === 'string' ? format : null;
    };
    numbro.defaultFormat = function (format) {
        defaultFormat = typeof (format) === 'string' ? format : '0.0';
    };
    numbro.defaultCurrencyFormat = function (format) {
        defaultCurrencyFormat = typeof (format) === 'string' ? format : '0$';
    };
    numbro.validate = function (val, culture) {
        var _decimalSep, _thousandSep, _currSymbol, _valArray, _abbrObj, _thousandRegEx, cultureData, temp;
        //coerce val to string
        if (typeof val !== 'string') {
            val += '';
            if (console.warn) {
                console.warn('Numbro.js: Value is not string. It has been co-erced to: ', val);
            }
        }
        //trim whitespaces from either sides
        val = val.trim();
        //if val is just digits return true
        if (!!val.match(/^\d+$/)) {
            return true;
        }
        //if val is empty return false
        if (val === '') {
            return false;
        }
        //get the decimal and thousands separator from numbro.cultureData
        try {
            //check if the culture is understood by numbro. if not, default it to current culture
            cultureData = numbro.cultureData(culture);
        }
        catch (e) {
            cultureData = numbro.cultureData(numbro.culture());
        }
        //setup the delimiters and currency symbol based on culture
        _currSymbol = cultureData.currency.symbol;
        _abbrObj = cultureData.abbreviations;
        _decimalSep = cultureData.delimiters.decimal;
        if (cultureData.delimiters.thousands === '.') {
            _thousandSep = '\\.';
        }
        else {
            _thousandSep = cultureData.delimiters.thousands;
        }
        // validating currency symbol
        temp = val.match(/^[^\d]+/);
        if (temp !== null) {
            val = val.substr(1);
            if (temp[0] !== _currSymbol) {
                return false;
            }
        }
        //validating abbreviation symbol
        temp = val.match(/[^\d]+$/);
        if (temp !== null) {
            val = val.slice(0, -1);
            if (temp[0] !== _abbrObj.thousand && temp[0] !== _abbrObj.million &&
                temp[0] !== _abbrObj.billion && temp[0] !== _abbrObj.trillion) {
                return false;
            }
        }
        _thousandRegEx = new RegExp(_thousandSep + '{2}');
        if (!val.match(/[^\d.,]/g)) {
            _valArray = val.split(_decimalSep);
            if (_valArray.length > 2) {
                return false;
            }
            else {
                if (_valArray.length < 2) {
                    return (!!_valArray[0].match(/^\d+.*\d$/) && !_valArray[0].match(_thousandRegEx));
                }
                else {
                    if (_valArray[0].length === 1) {
                        return (!!_valArray[0].match(/^\d+$/) &&
                            !_valArray[0].match(_thousandRegEx) &&
                            !!_valArray[1].match(/^\d+$/));
                    }
                    else {
                        return (!!_valArray[0].match(/^\d+.*\d$/) &&
                            !_valArray[0].match(_thousandRegEx) &&
                            !!_valArray[1].match(/^\d+$/));
                    }
                }
            }
        }
        return false;
    };
    /************************************
        Helpers
    ************************************/
    function setCulture(code, values) {
        cultures[code] = values;
    }
    function chooseCulture(code) {
        currentCulture = code;
        var defaults = cultures[code].defaults;
        if (defaults && defaults.format) {
            numbro.defaultFormat(defaults.format);
        }
        if (defaults && defaults.currencyFormat) {
            numbro.defaultCurrencyFormat(defaults.currencyFormat);
        }
    }
    function format(input, formatString, language, roundingFunction) {
        if (language != null && language !== numbro.culture()) {
            numbro.setCulture(language);
        }
        return formatNumbro(Number(input), formatString != null ? formatString : defaultFormat, roundingFunction == null ? Math.round : roundingFunction);
    }
    module.exports = { "format": format };
},
/* models/tickers/datetime_ticker.js */ function _(require, module, exports) {
    const array_1 = require(8) /* ../../core/util/array */;
    const adaptive_ticker_1 = require(103) /* ./adaptive_ticker */;
    const composite_ticker_1 = require(155) /* ./composite_ticker */;
    const days_ticker_1 = require(156) /* ./days_ticker */;
    const months_ticker_1 = require(159) /* ./months_ticker */;
    const years_ticker_1 = require(160) /* ./years_ticker */;
    const util_1 = require(158) /* ./util */;
    class DatetimeTicker extends composite_ticker_1.CompositeTicker {
        constructor(attrs) {
            super(attrs);
        }
        static init_DatetimeTicker() {
            this.override({
                num_minor_ticks: 0,
                tickers: () => [
                    // Sub-second.
                    new adaptive_ticker_1.AdaptiveTicker({
                        mantissas: [1, 2, 5],
                        base: 10,
                        min_interval: 0,
                        max_interval: 500 * util_1.ONE_MILLI,
                        num_minor_ticks: 0,
                    }),
                    // Seconds, minutes.
                    new adaptive_ticker_1.AdaptiveTicker({
                        mantissas: [1, 2, 5, 10, 15, 20, 30],
                        base: 60,
                        min_interval: util_1.ONE_SECOND,
                        max_interval: 30 * util_1.ONE_MINUTE,
                        num_minor_ticks: 0,
                    }),
                    // Hours.
                    new adaptive_ticker_1.AdaptiveTicker({
                        mantissas: [1, 2, 4, 6, 8, 12],
                        base: 24.0,
                        min_interval: util_1.ONE_HOUR,
                        max_interval: 12 * util_1.ONE_HOUR,
                        num_minor_ticks: 0,
                    }),
                    // Days.
                    new days_ticker_1.DaysTicker({ days: array_1.range(1, 32) }),
                    new days_ticker_1.DaysTicker({ days: array_1.range(1, 31, 3) }),
                    new days_ticker_1.DaysTicker({ days: [1, 8, 15, 22] }),
                    new days_ticker_1.DaysTicker({ days: [1, 15] }),
                    // Months.
                    new months_ticker_1.MonthsTicker({ months: array_1.range(0, 12, 1) }),
                    new months_ticker_1.MonthsTicker({ months: array_1.range(0, 12, 2) }),
                    new months_ticker_1.MonthsTicker({ months: array_1.range(0, 12, 4) }),
                    new months_ticker_1.MonthsTicker({ months: array_1.range(0, 12, 6) }),
                    // Years
                    new years_ticker_1.YearsTicker({}),
                ],
            });
        }
    }
    exports.DatetimeTicker = DatetimeTicker;
    DatetimeTicker.__name__ = "DatetimeTicker";
    DatetimeTicker.init_DatetimeTicker();
},
/* models/tickers/composite_ticker.js */ function _(require, module, exports) {
    const continuous_ticker_1 = require(104) /* ./continuous_ticker */;
    const p = require(18) /* ../../core/properties */;
    const array_1 = require(8) /* ../../core/util/array */;
    const object_1 = require(22) /* ../../core/util/object */;
    class CompositeTicker extends continuous_ticker_1.ContinuousTicker {
        constructor(attrs) {
            super(attrs);
        }
        static init_CompositeTicker() {
            this.define({
                tickers: [p.Array, []],
            });
        }
        // The tickers should be in order of increasing interval size; specifically,
        // if S comes before T, then it should be the case that
        // S.get_max_interval() < T.get_min_interval().
        // FIXME Enforce this automatically.
        get min_intervals() {
            return this.tickers.map((ticker) => ticker.get_min_interval());
        }
        get max_intervals() {
            return this.tickers.map((ticker) => ticker.get_max_interval());
        }
        get min_interval() {
            return this.min_intervals[0];
        }
        get max_interval() {
            return this.max_intervals[0];
        }
        get_best_ticker(data_low, data_high, desired_n_ticks) {
            const data_range = data_high - data_low;
            const ideal_interval = this.get_ideal_interval(data_low, data_high, desired_n_ticks);
            const ticker_ndxs = [
                array_1.sorted_index(this.min_intervals, ideal_interval) - 1,
                array_1.sorted_index(this.max_intervals, ideal_interval),
            ];
            const intervals = [
                this.min_intervals[ticker_ndxs[0]],
                this.max_intervals[ticker_ndxs[1]],
            ];
            const errors = intervals.map((interval) => {
                return Math.abs(desired_n_ticks - (data_range / interval));
            });
            let best_ticker;
            if (object_1.isEmpty(errors.filter((e) => !isNaN(e)))) {
                // this can happen if the data isn't loaded yet, we just default to the first scale
                best_ticker = this.tickers[0];
            }
            else {
                const best_index = array_1.argmin(errors);
                const best_ticker_ndx = ticker_ndxs[best_index];
                best_ticker = this.tickers[best_ticker_ndx];
            }
            return best_ticker;
        }
        get_interval(data_low, data_high, desired_n_ticks) {
            const best_ticker = this.get_best_ticker(data_low, data_high, desired_n_ticks);
            return best_ticker.get_interval(data_low, data_high, desired_n_ticks);
        }
        get_ticks_no_defaults(data_low, data_high, cross_loc, desired_n_ticks) {
            const best_ticker = this.get_best_ticker(data_low, data_high, desired_n_ticks);
            return best_ticker.get_ticks_no_defaults(data_low, data_high, cross_loc, desired_n_ticks);
        }
    }
    exports.CompositeTicker = CompositeTicker;
    CompositeTicker.__name__ = "CompositeTicker";
    CompositeTicker.init_CompositeTicker();
},
/* models/tickers/days_ticker.js */ function _(require, module, exports) {
    const single_interval_ticker_1 = require(157) /* ./single_interval_ticker */;
    const util_1 = require(158) /* ./util */;
    const p = require(18) /* ../../core/properties */;
    const array_1 = require(8) /* ../../core/util/array */;
    // Given a start and end time in millis, returns the shortest array of
    // consecutive months (as Dates) that surrounds both times.
    function date_range_by_month(start_time, end_time) {
        const start_date = util_1.last_month_no_later_than(new Date(start_time));
        const end_date = util_1.last_month_no_later_than(new Date(end_time));
        // XXX This is not a reliable technique in general, but it should be
        // safe when the day of the month is 1.  (The problem case is this:
        // Mar 31 -> Apr 31, which becomes May 1.)
        end_date.setUTCMonth(end_date.getUTCMonth() + 1);
        const dates = [];
        const date = start_date;
        while (true) {
            dates.push(util_1.copy_date(date));
            date.setUTCMonth(date.getUTCMonth() + 1);
            if (date > end_date)
                break;
        }
        return dates;
    }
    class DaysTicker extends single_interval_ticker_1.SingleIntervalTicker {
        constructor(attrs) {
            super(attrs);
        }
        static init_DaysTicker() {
            this.define({
                days: [p.Array, []],
            });
            this.override({
                num_minor_ticks: 0,
            });
        }
        initialize() {
            super.initialize();
            const days = this.days;
            if (days.length > 1)
                this.interval = (days[1] - days[0]) * util_1.ONE_DAY;
            else
                this.interval = 31 * util_1.ONE_DAY;
        }
        get_ticks_no_defaults(data_low, data_high, _cross_loc, _desired_n_ticks) {
            const month_dates = date_range_by_month(data_low, data_high);
            const days = this.days;
            const days_of_month = (month_date, interval) => {
                const current_month = month_date.getUTCMonth();
                const dates = [];
                for (const day of days) {
                    const day_date = util_1.copy_date(month_date);
                    day_date.setUTCDate(day);
                    // We can't use all of the values in this.days, because they may not
                    // fall within the current month.  In fact, if, e.g., our month is 28 days
                    // and we're marking every third day, we don't want day 28 to show up
                    // because it'll be right next to the 1st of the next month.  So we
                    // make sure we have a bit of room before we include a day.
                    // TODO (bev) The above description does not exactly work because JS Date
                    // is broken and will happily consider "Feb 28 + 3*ONE_DAY" to have month "2"
                    const future_date = new Date(day_date.getTime() + (interval / 2));
                    if (future_date.getUTCMonth() == current_month)
                        dates.push(day_date);
                }
                return dates;
            };
            const interval = this.interval;
            const day_dates = array_1.concat(month_dates.map((date) => days_of_month(date, interval)));
            const all_ticks = day_dates.map((day_date) => day_date.getTime());
            const ticks_in_range = all_ticks.filter((tick) => data_low <= tick && tick <= data_high);
            return {
                major: ticks_in_range,
                minor: [],
            };
        }
    }
    exports.DaysTicker = DaysTicker;
    DaysTicker.__name__ = "DaysTicker";
    DaysTicker.init_DaysTicker();
},
/* models/tickers/single_interval_ticker.js */ function _(require, module, exports) {
    const continuous_ticker_1 = require(104) /* ./continuous_ticker */;
    const p = require(18) /* ../../core/properties */;
    class SingleIntervalTicker extends continuous_ticker_1.ContinuousTicker {
        constructor(attrs) {
            super(attrs);
        }
        static init_SingleIntervalTicker() {
            this.define({
                interval: [p.Number],
            });
        }
        get_interval(_data_low, _data_high, _n_desired_ticks) {
            return this.interval;
        }
        get min_interval() {
            return this.interval;
        }
        get max_interval() {
            return this.interval;
        }
    }
    exports.SingleIntervalTicker = SingleIntervalTicker;
    SingleIntervalTicker.__name__ = "SingleIntervalTicker";
    SingleIntervalTicker.init_SingleIntervalTicker();
},
/* models/tickers/util.js */ function _(require, module, exports) {
    // Some time constants, in milliseconds.
    exports.ONE_MILLI = 1.0;
    exports.ONE_SECOND = 1000.0;
    exports.ONE_MINUTE = 60.0 * exports.ONE_SECOND;
    exports.ONE_HOUR = 60 * exports.ONE_MINUTE;
    exports.ONE_DAY = 24 * exports.ONE_HOUR;
    exports.ONE_MONTH = 30 * exports.ONE_DAY; // An approximation, obviously.
    exports.ONE_YEAR = 365 * exports.ONE_DAY;
    // ---------------------------------------------------------------------------
    // Date/time utility functions
    // ---------------------------------------------------------------------------
    // Makes a copy of a date object.
    function copy_date(date) {
        return new Date(date.getTime());
    }
    exports.copy_date = copy_date;
    // Rounds a date down to the month.
    function last_month_no_later_than(date) {
        const new_date = copy_date(date);
        new_date.setUTCDate(1);
        new_date.setUTCHours(0);
        new_date.setUTCMinutes(0);
        new_date.setUTCSeconds(0);
        new_date.setUTCMilliseconds(0);
        return new_date;
    }
    exports.last_month_no_later_than = last_month_no_later_than;
    // Rounds a date down to the year.
    function last_year_no_later_than(date) {
        const new_date = last_month_no_later_than(date);
        new_date.setUTCMonth(0);
        return new_date;
    }
    exports.last_year_no_later_than = last_year_no_later_than;
},
/* models/tickers/months_ticker.js */ function _(require, module, exports) {
    const single_interval_ticker_1 = require(157) /* ./single_interval_ticker */;
    const util_1 = require(158) /* ./util */;
    const p = require(18) /* ../../core/properties */;
    const array_1 = require(8) /* ../../core/util/array */;
    // Given a start and end time in millis, returns the shortest array of
    // consecutive years (as Dates) that surrounds both times.
    function date_range_by_year(start_time, end_time) {
        const start_date = util_1.last_year_no_later_than(new Date(start_time));
        const end_date = util_1.last_year_no_later_than(new Date(end_time));
        end_date.setUTCFullYear(end_date.getUTCFullYear() + 1);
        const dates = [];
        const date = start_date;
        while (true) {
            dates.push(util_1.copy_date(date));
            date.setUTCFullYear(date.getUTCFullYear() + 1);
            if (date > end_date)
                break;
        }
        return dates;
    }
    class MonthsTicker extends single_interval_ticker_1.SingleIntervalTicker {
        constructor(attrs) {
            super(attrs);
        }
        static init_MonthsTicker() {
            this.define({
                months: [p.Array, []],
            });
        }
        initialize() {
            super.initialize();
            const months = this.months;
            if (months.length > 1)
                this.interval = (months[1] - months[0]) * util_1.ONE_MONTH;
            else
                this.interval = 12 * util_1.ONE_MONTH;
        }
        get_ticks_no_defaults(data_low, data_high, _cross_loc, _desired_n_ticks) {
            const year_dates = date_range_by_year(data_low, data_high);
            const months = this.months;
            const months_of_year = (year_date) => {
                return months.map((month) => {
                    const month_date = util_1.copy_date(year_date);
                    month_date.setUTCMonth(month);
                    return month_date;
                });
            };
            const month_dates = array_1.concat(year_dates.map(months_of_year));
            const all_ticks = month_dates.map((month_date) => month_date.getTime());
            const ticks_in_range = all_ticks.filter((tick) => data_low <= tick && tick <= data_high);
            return {
                major: ticks_in_range,
                minor: [],
            };
        }
    }
    exports.MonthsTicker = MonthsTicker;
    MonthsTicker.__name__ = "MonthsTicker";
    MonthsTicker.init_MonthsTicker();
},
/* models/tickers/years_ticker.js */ function _(require, module, exports) {
    const basic_ticker_1 = require(102) /* ./basic_ticker */;
    const single_interval_ticker_1 = require(157) /* ./single_interval_ticker */;
    const util_1 = require(158) /* ./util */;
    class YearsTicker extends single_interval_ticker_1.SingleIntervalTicker {
        constructor(attrs) {
            super(attrs);
        }
        initialize() {
            super.initialize();
            this.interval = util_1.ONE_YEAR;
            this.basic_ticker = new basic_ticker_1.BasicTicker({ num_minor_ticks: 0 });
        }
        get_ticks_no_defaults(data_low, data_high, cross_loc, desired_n_ticks) {
            const start_year = util_1.last_year_no_later_than(new Date(data_low)).getUTCFullYear();
            const end_year = util_1.last_year_no_later_than(new Date(data_high)).getUTCFullYear();
            const years = this.basic_ticker.get_ticks_no_defaults(start_year, end_year, cross_loc, desired_n_ticks).major;
            const all_ticks = years.map((year) => Date.UTC(year, 0, 1));
            const ticks_in_range = all_ticks.filter((tick) => data_low <= tick && tick <= data_high);
            return {
                major: ticks_in_range,
                minor: [],
            };
        }
    }
    exports.YearsTicker = YearsTicker;
    YearsTicker.__name__ = "YearsTicker";
},
/* models/axes/log_axis.js */ function _(require, module, exports) {
    const axis_1 = require(141) /* ./axis */;
    const continuous_axis_1 = require(146) /* ./continuous_axis */;
    const log_tick_formatter_1 = require(162) /* ../formatters/log_tick_formatter */;
    const log_ticker_1 = require(163) /* ../tickers/log_ticker */;
    class LogAxisView extends axis_1.AxisView {
    }
    exports.LogAxisView = LogAxisView;
    LogAxisView.__name__ = "LogAxisView";
    class LogAxis extends continuous_axis_1.ContinuousAxis {
        constructor(attrs) {
            super(attrs);
        }
        static init_LogAxis() {
            this.prototype.default_view = LogAxisView;
            this.override({
                ticker: () => new log_ticker_1.LogTicker(),
                formatter: () => new log_tick_formatter_1.LogTickFormatter(),
            });
        }
    }
    exports.LogAxis = LogAxis;
    LogAxis.__name__ = "LogAxis";
    LogAxis.init_LogAxis();
},
/* models/formatters/log_tick_formatter.js */ function _(require, module, exports) {
    const tick_formatter_1 = require(107) /* ./tick_formatter */;
    const basic_tick_formatter_1 = require(106) /* ./basic_tick_formatter */;
    const logging_1 = require(65) /* ../../core/logging */;
    const p = require(18) /* ../../core/properties */;
    class LogTickFormatter extends tick_formatter_1.TickFormatter {
        constructor(attrs) {
            super(attrs);
        }
        static init_LogTickFormatter() {
            this.define({
                ticker: [p.Instance, null],
            });
        }
        initialize() {
            super.initialize();
            this.basic_formatter = new basic_tick_formatter_1.BasicTickFormatter();
            if (this.ticker == null)
                logging_1.logger.warn("LogTickFormatter not configured with a ticker, using default base of 10 (labels will be incorrect if ticker base is not 10)");
        }
        doFormat(ticks, opts) {
            if (ticks.length == 0)
                return [];
            const base = this.ticker != null ? this.ticker.base : 10;
            let small_interval = false;
            const labels = new Array(ticks.length);
            for (let i = 0, end = ticks.length; i < end; i++) {
                labels[i] = `${base}^${Math.round(Math.log(ticks[i]) / Math.log(base))}`;
                if (i > 0 && labels[i] == labels[i - 1]) {
                    small_interval = true;
                    break;
                }
            }
            if (small_interval)
                return this.basic_formatter.doFormat(ticks, opts);
            else
                return labels;
        }
    }
    exports.LogTickFormatter = LogTickFormatter;
    LogTickFormatter.__name__ = "LogTickFormatter";
    LogTickFormatter.init_LogTickFormatter();
},
/* models/tickers/log_ticker.js */ function _(require, module, exports) {
    const adaptive_ticker_1 = require(103) /* ./adaptive_ticker */;
    const array_1 = require(8) /* ../../core/util/array */;
    class LogTicker extends adaptive_ticker_1.AdaptiveTicker {
        constructor(attrs) {
            super(attrs);
        }
        static init_LogTicker() {
            this.override({
                mantissas: [1, 5],
            });
        }
        get_ticks_no_defaults(data_low, data_high, _cross_loc, desired_n_ticks) {
            const num_minor_ticks = this.num_minor_ticks;
            const minor_ticks = [];
            const base = this.base;
            const log_low = Math.log(data_low) / Math.log(base);
            const log_high = Math.log(data_high) / Math.log(base);
            const log_interval = log_high - log_low;
            let ticks;
            if (!isFinite(log_interval)) {
                ticks = [];
            }
            else if (log_interval < 2) { // treat as linear ticker
                const interval = this.get_interval(data_low, data_high, desired_n_ticks);
                const start_factor = Math.floor(data_low / interval);
                const end_factor = Math.ceil(data_high / interval);
                ticks = array_1.range(start_factor, end_factor + 1)
                    .filter((factor) => factor != 0)
                    .map((factor) => factor * interval)
                    .filter((tick) => data_low <= tick && tick <= data_high);
                if (num_minor_ticks > 0 && ticks.length > 0) {
                    const minor_interval = interval / num_minor_ticks;
                    const minor_offsets = array_1.range(0, num_minor_ticks).map((i) => i * minor_interval);
                    for (const x of minor_offsets.slice(1)) {
                        minor_ticks.push(ticks[0] - x);
                    }
                    for (const tick of ticks) {
                        for (const x of minor_offsets) {
                            minor_ticks.push(tick + x);
                        }
                    }
                }
            }
            else {
                const startlog = Math.ceil(log_low * 0.999999);
                const endlog = Math.floor(log_high * 1.000001);
                const interval = Math.ceil((endlog - startlog) / 9.0);
                ticks = array_1.range(startlog - 1, endlog + 1, interval)
                    .map((i) => Math.pow(base, i));
                if (num_minor_ticks > 0 && ticks.length > 0) {
                    const minor_interval = Math.pow(base, interval) / num_minor_ticks;
                    const minor_offsets = array_1.range(1, num_minor_ticks + 1).map((i) => i * minor_interval);
                    for (const x of minor_offsets) {
                        minor_ticks.push(ticks[0] / x);
                    }
                    minor_ticks.push(ticks[0]);
                    for (const tick of ticks) {
                        for (const x of minor_offsets) {
                            minor_ticks.push(tick * x);
                        }
                    }
                }
            }
            return {
                major: ticks.filter((tick) => data_low <= tick && tick <= data_high),
                minor: minor_ticks.filter((tick) => data_low <= tick && tick <= data_high),
            };
        }
    }
    exports.LogTicker = LogTicker;
    LogTicker.__name__ = "LogTicker";
    LogTicker.init_LogTicker();
},
/* models/axes/mercator_axis.js */ function _(require, module, exports) {
    const axis_1 = require(141) /* ./axis */;
    const linear_axis_1 = require(148) /* ./linear_axis */;
    const mercator_tick_formatter_1 = require(165) /* ../formatters/mercator_tick_formatter */;
    const mercator_ticker_1 = require(166) /* ../tickers/mercator_ticker */;
    class MercatorAxisView extends axis_1.AxisView {
    }
    exports.MercatorAxisView = MercatorAxisView;
    MercatorAxisView.__name__ = "MercatorAxisView";
    class MercatorAxis extends linear_axis_1.LinearAxis {
        constructor(attrs) {
            super(attrs);
        }
        static init_MercatorAxis() {
            this.prototype.default_view = MercatorAxisView;
            this.override({
                ticker: () => new mercator_ticker_1.MercatorTicker({ dimension: "lat" }),
                formatter: () => new mercator_tick_formatter_1.MercatorTickFormatter({ dimension: "lat" }),
            });
        }
    }
    exports.MercatorAxis = MercatorAxis;
    MercatorAxis.__name__ = "MercatorAxis";
    MercatorAxis.init_MercatorAxis();
},
/* models/formatters/mercator_tick_formatter.js */ function _(require, module, exports) {
    const basic_tick_formatter_1 = require(106) /* ./basic_tick_formatter */;
    const p = require(18) /* ../../core/properties */;
    const projections_1 = require(30) /* ../../core/util/projections */;
    class MercatorTickFormatter extends basic_tick_formatter_1.BasicTickFormatter {
        constructor(attrs) {
            super(attrs);
        }
        static init_MercatorTickFormatter() {
            this.define({
                dimension: [p.LatLon],
            });
        }
        doFormat(ticks, opts) {
            if (this.dimension == null)
                throw new Error("MercatorTickFormatter.dimension not configured");
            if (ticks.length == 0)
                return [];
            const n = ticks.length;
            const proj_ticks = new Array(n);
            if (this.dimension == "lon") {
                for (let i = 0; i < n; i++) {
                    const [lon] = projections_1.wgs84_mercator.inverse([ticks[i], opts.loc]);
                    proj_ticks[i] = lon;
                }
            }
            else {
                for (let i = 0; i < n; i++) {
                    const [, lat] = projections_1.wgs84_mercator.inverse([opts.loc, ticks[i]]);
                    proj_ticks[i] = lat;
                }
            }
            return super.doFormat(proj_ticks, opts);
        }
    }
    exports.MercatorTickFormatter = MercatorTickFormatter;
    MercatorTickFormatter.__name__ = "MercatorTickFormatter";
    MercatorTickFormatter.init_MercatorTickFormatter();
},
/* models/tickers/mercator_ticker.js */ function _(require, module, exports) {
    const basic_ticker_1 = require(102) /* ./basic_ticker */;
    const p = require(18) /* ../../core/properties */;
    const projections_1 = require(30) /* ../../core/util/projections */;
    class MercatorTicker extends basic_ticker_1.BasicTicker {
        constructor(attrs) {
            super(attrs);
        }
        static init_MercatorTicker() {
            this.define({
                dimension: [p.LatLon],
            });
        }
        get_ticks_no_defaults(data_low, data_high, cross_loc, desired_n_ticks) {
            if (this.dimension == null) {
                throw new Error("MercatorTicker.dimension not configured");
            }
            [data_low, data_high] = projections_1.clip_mercator(data_low, data_high, this.dimension);
            let proj_low, proj_high, proj_cross_loc;
            if (this.dimension === "lon") {
                [proj_low, proj_cross_loc] = projections_1.wgs84_mercator.inverse([data_low, cross_loc]);
                [proj_high, proj_cross_loc] = projections_1.wgs84_mercator.inverse([data_high, cross_loc]);
            }
            else {
                [proj_cross_loc, proj_low] = projections_1.wgs84_mercator.inverse([cross_loc, data_low]);
                [proj_cross_loc, proj_high] = projections_1.wgs84_mercator.inverse([cross_loc, data_high]);
            }
            const proj_ticks = super.get_ticks_no_defaults(proj_low, proj_high, cross_loc, desired_n_ticks);
            const major = [];
            const minor = [];
            if (this.dimension === "lon") {
                for (const tick of proj_ticks.major) {
                    if (projections_1.in_bounds(tick, 'lon')) {
                        const [lon] = projections_1.wgs84_mercator.forward([tick, proj_cross_loc]);
                        major.push(lon);
                    }
                }
                for (const tick of proj_ticks.minor) {
                    if (projections_1.in_bounds(tick, 'lon')) {
                        const [lon] = projections_1.wgs84_mercator.forward([tick, proj_cross_loc]);
                        minor.push(lon);
                    }
                }
            }
            else {
                for (const tick of proj_ticks.major) {
                    if (projections_1.in_bounds(tick, 'lat')) {
                        const [, lat] = projections_1.wgs84_mercator.forward([proj_cross_loc, tick]);
                        major.push(lat);
                    }
                }
                for (const tick of proj_ticks.minor) {
                    if (projections_1.in_bounds(tick, 'lat')) {
                        const [, lat] = projections_1.wgs84_mercator.forward([proj_cross_loc, tick]);
                        minor.push(lat);
                    }
                }
            }
            return { major, minor };
        }
    }
    exports.MercatorTicker = MercatorTicker;
    MercatorTicker.__name__ = "MercatorTicker";
    MercatorTicker.init_MercatorTicker();
},
/* models/callbacks/index.js */ function _(require, module, exports) {
    var customjs_1 = require(168) /* ./customjs */;
    exports.CustomJS = customjs_1.CustomJS;
    var open_url_1 = require(170) /* ./open_url */;
    exports.OpenURL = open_url_1.OpenURL;
},
/* models/callbacks/customjs.js */ function _(require, module, exports) {
    const callback_1 = require(169) /* ./callback */;
    const p = require(18) /* ../../core/properties */;
    const object_1 = require(22) /* ../../core/util/object */;
    const string_1 = require(25) /* ../../core/util/string */;
    class CustomJS extends callback_1.Callback {
        constructor(attrs) {
            super(attrs);
        }
        static init_CustomJS() {
            this.define({
                args: [p.Any, {}],
                code: [p.String, ''],
                use_strict: [p.Boolean, false],
            });
        }
        get names() {
            return object_1.keys(this.args);
        }
        get values() {
            return object_1.values(this.args);
        }
        get func() {
            const code = this.use_strict ? string_1.use_strict(this.code) : this.code;
            return new Function(...this.names, "cb_obj", "cb_data", "require", "exports", code);
        }
        execute(cb_obj, cb_data = {}) {
            return this.func.apply(cb_obj, this.values.concat(cb_obj, cb_data, require, {}));
        }
    }
    exports.CustomJS = CustomJS;
    CustomJS.__name__ = "CustomJS";
    CustomJS.init_CustomJS();
},
/* models/callbacks/callback.js */ function _(require, module, exports) {
    const model_1 = require(64) /* ../../model */;
    class Callback extends model_1.Model {
        constructor(attrs) {
            super(attrs);
        }
    }
    exports.Callback = Callback;
    Callback.__name__ = "Callback";
},
/* models/callbacks/open_url.js */ function _(require, module, exports) {
    const callback_1 = require(169) /* ./callback */;
    const templating_1 = require(151) /* ../../core/util/templating */;
    const p = require(18) /* ../../core/properties */;
    class OpenURL extends callback_1.Callback {
        constructor(attrs) {
            super(attrs);
        }
        static init_OpenURL() {
            this.define({
                url: [p.String, 'http://'],
                same_tab: [p.Boolean, false],
            });
        }
        execute(_cb_obj, { source }) {
            const open_url = (i) => {
                const url = templating_1.replace_placeholders(this.url, source, i);
                if (this.same_tab)
                    window.location.href = url;
                else
                    window.open(url);
            };
            const { selected } = source;
            for (const i of selected.indices)
                open_url(i);
            for (const i of selected.line_indices)
                open_url(i);
            // TODO: multiline_indices: {[key: string]: number[]}
        }
    }
    exports.OpenURL = OpenURL;
    OpenURL.__name__ = "OpenURL";
    OpenURL.init_OpenURL();
},
/* models/canvas/index.js */ function _(require, module, exports) {
    var canvas_1 = require(172) /* ./canvas */;
    exports.Canvas = canvas_1.Canvas;
    var cartesian_frame_1 = require(176) /* ./cartesian_frame */;
    exports.CartesianFrame = cartesian_frame_1.CartesianFrame;
},
/* models/canvas/canvas.js */ function _(require, module, exports) {
    const has_props_1 = require(12) /* ../../core/has_props */;
    const dom_view_1 = require(59) /* ../../core/dom_view */;
    const logging_1 = require(65) /* ../../core/logging */;
    const p = require(18) /* ../../core/properties */;
    const dom_1 = require(61) /* ../../core/dom */;
    const bbox_1 = require(79) /* ../../core/util/bbox */;
    const compat_1 = require(95) /* ../../core/util/compat */;
    const canvas_1 = require(173) /* ../../core/util/canvas */;
    const canvas_2 = require(174) /* ../../styles/canvas */;
    // fixes up a problem with some versions of IE11
    // ref: http://stackoverflow.com/questions/22062313/imagedata-set-in-internetexplorer
    if (compat_1.is_ie && typeof CanvasPixelArray !== "undefined") {
        CanvasPixelArray.prototype.set = function (arr) {
            for (let i = 0; i < this.length; i++) {
                this[i] = arr[i];
            }
        };
    }
    const canvas2svg = require(175) /* canvas2svg */;
    class CanvasView extends dom_view_1.DOMView {
        get ctx() {
            return this._ctx;
        }
        initialize() {
            super.initialize();
            this.map_el = this.model.map ? this.el.appendChild(dom_1.div({ class: canvas_2.bk_canvas_map })) : null;
            const style = {
                position: "absolute",
                top: "0",
                left: "0",
                width: "100%",
                height: "100%",
            };
            switch (this.model.output_backend) {
                case "canvas":
                case "webgl": {
                    this.canvas_el = this.el.appendChild(dom_1.canvas({ class: canvas_2.bk_canvas, style }));
                    const ctx = this.canvas_el.getContext('2d');
                    if (ctx == null)
                        throw new Error("unable to obtain 2D rendering context");
                    this._ctx = ctx;
                    break;
                }
                case "svg": {
                    const ctx = new canvas2svg();
                    this._ctx = ctx;
                    this.canvas_el = this.el.appendChild(ctx.getSvg());
                    break;
                }
            }
            this.overlays_el = this.el.appendChild(dom_1.div({ class: canvas_2.bk_canvas_overlays, style }));
            this.events_el = this.el.appendChild(dom_1.div({ class: canvas_2.bk_canvas_events, style }));
            canvas_1.fixup_ctx(this._ctx);
            logging_1.logger.debug("CanvasView initialized");
        }
        get_canvas_element() {
            return this.canvas_el;
        }
        prepare_canvas(width, height) {
            // Ensure canvas has the correct size, taking HIDPI into account
            this.bbox = new bbox_1.BBox({ left: 0, top: 0, width, height });
            this.el.style.width = `${width}px`;
            this.el.style.height = `${height}px`;
            const pixel_ratio = canvas_1.get_scale_ratio(this.ctx, this.model.use_hidpi, this.model.output_backend);
            this.model.pixel_ratio = pixel_ratio;
            this.canvas_el.style.width = `${width}px`;
            this.canvas_el.style.height = `${height}px`;
            // XXX: io.export and canvas2svg don't like this
            // this.canvas_el.width = width*pixel_ratio
            // this.canvas_el.height = height*pixel_ratio
            this.canvas_el.setAttribute("width", `${width * pixel_ratio}`);
            this.canvas_el.setAttribute("height", `${height * pixel_ratio}`);
            logging_1.logger.debug(`Rendering CanvasView with width: ${width}, height: ${height}, pixel ratio: ${pixel_ratio}`);
        }
    }
    exports.CanvasView = CanvasView;
    CanvasView.__name__ = "CanvasView";
    class Canvas extends has_props_1.HasProps {
        constructor(attrs) {
            super(attrs);
        }
        static init_Canvas() {
            this.prototype.default_view = CanvasView;
            this.internal({
                map: [p.Boolean, false],
                use_hidpi: [p.Boolean, true],
                pixel_ratio: [p.Number, 1],
                output_backend: [p.OutputBackend, "canvas"],
            });
        }
    }
    exports.Canvas = Canvas;
    Canvas.__name__ = "Canvas";
    Canvas.init_Canvas();
},
/* core/util/canvas.js */ function _(require, module, exports) {
    function fixup_line_dash(ctx) {
        if (!ctx.setLineDash) {
            ctx.setLineDash = (dash) => {
                ctx.mozDash = dash;
                ctx.webkitLineDash = dash;
            };
        }
        if (!ctx.getLineDash) {
            ctx.getLineDash = () => {
                return ctx.mozDash;
            };
        }
    }
    function fixup_line_dash_offset(ctx) {
        ctx.setLineDashOffset = (offset) => {
            ctx.lineDashOffset = offset;
            ctx.mozDashOffset = offset;
            ctx.webkitLineDashOffset = offset;
        };
        ctx.getLineDashOffset = () => {
            return ctx.mozDashOffset;
        };
    }
    function fixup_image_smoothing(ctx) {
        ctx.setImageSmoothingEnabled = (value) => {
            ctx.imageSmoothingEnabled = value;
            ctx.mozImageSmoothingEnabled = value;
            ctx.oImageSmoothingEnabled = value;
            ctx.webkitImageSmoothingEnabled = value;
            ctx.msImageSmoothingEnabled = value;
        };
        ctx.getImageSmoothingEnabled = () => {
            const val = ctx.imageSmoothingEnabled;
            return val != null ? val : true;
        };
    }
    function fixup_measure_text(ctx) {
        if (ctx.measureText && ctx.html5MeasureText == null) {
            ctx.html5MeasureText = ctx.measureText;
            ctx.measureText = (text) => {
                const textMetrics = ctx.html5MeasureText(text);
                // fake it til you make it
                textMetrics.ascent = ctx.html5MeasureText("m").width * 1.6;
                return textMetrics;
            };
        }
    }
    function fixup_ellipse(ctx) {
        // implementing the ctx.ellipse function with bezier curves
        // we don't implement the startAngle, endAngle and anticlockwise arguments.
        function ellipse_bezier(x, y, radiusX, radiusY, rotation, _startAngle, _endAngle, anticlockwise = false) {
            const c = 0.551784; // see http://www.tinaja.com/glib/ellipse4.pdf
            ctx.translate(x, y);
            ctx.rotate(rotation);
            let rx = radiusX;
            let ry = radiusY;
            if (anticlockwise) {
                rx = -radiusX;
                ry = -radiusY;
            }
            ctx.moveTo(-rx, 0); // start point of first curve
            ctx.bezierCurveTo(-rx, ry * c, -rx * c, ry, 0, ry);
            ctx.bezierCurveTo(rx * c, ry, rx, ry * c, rx, 0);
            ctx.bezierCurveTo(rx, -ry * c, rx * c, -ry, 0, -ry);
            ctx.bezierCurveTo(-rx * c, -ry, -rx, -ry * c, -rx, 0);
            ctx.rotate(-rotation);
            ctx.translate(-x, -y);
        }
        if (!ctx.ellipse)
            ctx.ellipse = ellipse_bezier;
    }
    function fixup_ctx(ctx) {
        fixup_line_dash(ctx);
        fixup_line_dash_offset(ctx);
        fixup_image_smoothing(ctx);
        fixup_measure_text(ctx);
        fixup_ellipse(ctx);
    }
    exports.fixup_ctx = fixup_ctx;
    function get_scale_ratio(ctx, hidpi, backend) {
        if (backend == "svg")
            return 1;
        else if (hidpi) {
            const devicePixelRatio = window.devicePixelRatio || 1;
            const backingStoreRatio = ctx.webkitBackingStorePixelRatio ||
                ctx.mozBackingStorePixelRatio ||
                ctx.msBackingStorePixelRatio ||
                ctx.oBackingStorePixelRatio ||
                ctx.backingStorePixelRatio || 1;
            return devicePixelRatio / backingStoreRatio;
        }
        else
            return 1;
    }
    exports.get_scale_ratio = get_scale_ratio;
},
/* styles/canvas.js */ function _(require, module, exports) {
    require(62) /* ./root */;
    exports.bk_canvas = "bk-canvas";
    exports.bk_canvas_map = "bk-canvas-map";
    exports.bk_canvas_overlays = "bk-canvas-overlays";
    exports.bk_canvas_events = "bk-canvas-events";
},
/* canvas2svg/canvas2svg.js */ function _(require, module, exports) {
    /*!!
     *  Canvas 2 Svg v1.0.21
     *  A low level canvas to SVG converter. Uses a mock canvas context to build an SVG document.
     *
     *  Licensed under the MIT license:
     *  http://www.opensource.org/licenses/mit-license.php
     *
     *  Author:
     *  Kerry Liu
     *
     *  Copyright (c) 2014 Gliffy Inc.
     */
    ;
    (function () {
        "use strict";
        var STYLES, ctx, CanvasGradient, CanvasPattern, namedEntities;
        //helper function to format a string
        function format(str, args) {
            var keys = Object.keys(args), i;
            for (i = 0; i < keys.length; i++) {
                str = str.replace(new RegExp("\\{" + keys[i] + "\\}", "gi"), args[keys[i]]);
            }
            return str;
        }
        //helper function that generates a random string
        function randomString(holder) {
            var chars, randomstring, i;
            if (!holder) {
                throw new Error("cannot create a random attribute name for an undefined object");
            }
            chars = "ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
            randomstring = "";
            do {
                randomstring = "";
                for (i = 0; i < 12; i++) {
                    randomstring += chars[Math.floor(Math.random() * chars.length)];
                }
            } while (holder[randomstring]);
            return randomstring;
        }
        //helper function to map named to numbered entities
        function createNamedToNumberedLookup(items, radix) {
            var i, entity, lookup = {}, base10, base16;
            items = items.split(',');
            radix = radix || 10;
            // Map from named to numbered entities.
            for (i = 0; i < items.length; i += 2) {
                entity = '&' + items[i + 1] + ';';
                base10 = parseInt(items[i], radix);
                lookup[entity] = '&#' + base10 + ';';
            }
            //FF and IE need to create a regex from hex values ie &nbsp; == \xa0
            lookup["\\xa0"] = '&#160;';
            return lookup;
        }
        //helper function to map canvas-textAlign to svg-textAnchor
        function getTextAnchor(textAlign) {
            //TODO: support rtl languages
            var mapping = { "left": "start", "right": "end", "center": "middle", "start": "start", "end": "end" };
            return mapping[textAlign] || mapping.start;
        }
        //helper function to map canvas-textBaseline to svg-dominantBaseline
        function getDominantBaseline(textBaseline) {
            //INFO: not supported in all browsers
            var mapping = { "alphabetic": "alphabetic", "hanging": "hanging", "top": "text-before-edge", "bottom": "text-after-edge", "middle": "central" };
            return mapping[textBaseline] || mapping.alphabetic;
        }
        // Unpack entities lookup where the numbers are in radix 32 to reduce the size
        // entity mapping courtesy of tinymce
        namedEntities = createNamedToNumberedLookup('50,nbsp,51,iexcl,52,cent,53,pound,54,curren,55,yen,56,brvbar,57,sect,58,uml,59,copy,' +
            '5a,ordf,5b,laquo,5c,not,5d,shy,5e,reg,5f,macr,5g,deg,5h,plusmn,5i,sup2,5j,sup3,5k,acute,' +
            '5l,micro,5m,para,5n,middot,5o,cedil,5p,sup1,5q,ordm,5r,raquo,5s,frac14,5t,frac12,5u,frac34,' +
            '5v,iquest,60,Agrave,61,Aacute,62,Acirc,63,Atilde,64,Auml,65,Aring,66,AElig,67,Ccedil,' +
            '68,Egrave,69,Eacute,6a,Ecirc,6b,Euml,6c,Igrave,6d,Iacute,6e,Icirc,6f,Iuml,6g,ETH,6h,Ntilde,' +
            '6i,Ograve,6j,Oacute,6k,Ocirc,6l,Otilde,6m,Ouml,6n,times,6o,Oslash,6p,Ugrave,6q,Uacute,' +
            '6r,Ucirc,6s,Uuml,6t,Yacute,6u,THORN,6v,szlig,70,agrave,71,aacute,72,acirc,73,atilde,74,auml,' +
            '75,aring,76,aelig,77,ccedil,78,egrave,79,eacute,7a,ecirc,7b,euml,7c,igrave,7d,iacute,7e,icirc,' +
            '7f,iuml,7g,eth,7h,ntilde,7i,ograve,7j,oacute,7k,ocirc,7l,otilde,7m,ouml,7n,divide,7o,oslash,' +
            '7p,ugrave,7q,uacute,7r,ucirc,7s,uuml,7t,yacute,7u,thorn,7v,yuml,ci,fnof,sh,Alpha,si,Beta,' +
            'sj,Gamma,sk,Delta,sl,Epsilon,sm,Zeta,sn,Eta,so,Theta,sp,Iota,sq,Kappa,sr,Lambda,ss,Mu,' +
            'st,Nu,su,Xi,sv,Omicron,t0,Pi,t1,Rho,t3,Sigma,t4,Tau,t5,Upsilon,t6,Phi,t7,Chi,t8,Psi,' +
            't9,Omega,th,alpha,ti,beta,tj,gamma,tk,delta,tl,epsilon,tm,zeta,tn,eta,to,theta,tp,iota,' +
            'tq,kappa,tr,lambda,ts,mu,tt,nu,tu,xi,tv,omicron,u0,pi,u1,rho,u2,sigmaf,u3,sigma,u4,tau,' +
            'u5,upsilon,u6,phi,u7,chi,u8,psi,u9,omega,uh,thetasym,ui,upsih,um,piv,812,bull,816,hellip,' +
            '81i,prime,81j,Prime,81u,oline,824,frasl,88o,weierp,88h,image,88s,real,892,trade,89l,alefsym,' +
            '8cg,larr,8ch,uarr,8ci,rarr,8cj,darr,8ck,harr,8dl,crarr,8eg,lArr,8eh,uArr,8ei,rArr,8ej,dArr,' +
            '8ek,hArr,8g0,forall,8g2,part,8g3,exist,8g5,empty,8g7,nabla,8g8,isin,8g9,notin,8gb,ni,8gf,prod,' +
            '8gh,sum,8gi,minus,8gn,lowast,8gq,radic,8gt,prop,8gu,infin,8h0,ang,8h7,and,8h8,or,8h9,cap,8ha,cup,' +
            '8hb,int,8hk,there4,8hs,sim,8i5,cong,8i8,asymp,8j0,ne,8j1,equiv,8j4,le,8j5,ge,8k2,sub,8k3,sup,8k4,' +
            'nsub,8k6,sube,8k7,supe,8kl,oplus,8kn,otimes,8l5,perp,8m5,sdot,8o8,lceil,8o9,rceil,8oa,lfloor,8ob,' +
            'rfloor,8p9,lang,8pa,rang,9ea,loz,9j0,spades,9j3,clubs,9j5,hearts,9j6,diams,ai,OElig,aj,oelig,b0,' +
            'Scaron,b1,scaron,bo,Yuml,m6,circ,ms,tilde,802,ensp,803,emsp,809,thinsp,80c,zwnj,80d,zwj,80e,lrm,' +
            '80f,rlm,80j,ndash,80k,mdash,80o,lsquo,80p,rsquo,80q,sbquo,80s,ldquo,80t,rdquo,80u,bdquo,810,dagger,' +
            '811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro', 32);
        //Some basic mappings for attributes and default values.
        STYLES = {
            "strokeStyle": {
                svgAttr: "stroke",
                canvas: "#000000",
                svg: "none",
                apply: "stroke" //apply on stroke() or fill()
            },
            "fillStyle": {
                svgAttr: "fill",
                canvas: "#000000",
                svg: null,
                apply: "fill"
            },
            "lineCap": {
                svgAttr: "stroke-linecap",
                canvas: "butt",
                svg: "butt",
                apply: "stroke"
            },
            "lineJoin": {
                svgAttr: "stroke-linejoin",
                canvas: "miter",
                svg: "miter",
                apply: "stroke"
            },
            "miterLimit": {
                svgAttr: "stroke-miterlimit",
                canvas: 10,
                svg: 4,
                apply: "stroke"
            },
            "lineWidth": {
                svgAttr: "stroke-width",
                canvas: 1,
                svg: 1,
                apply: "stroke"
            },
            "globalAlpha": {
                svgAttr: "opacity",
                canvas: 1,
                svg: 1,
                apply: "fill stroke"
            },
            "font": {
                //font converts to multiple svg attributes, there is custom logic for this
                canvas: "10px sans-serif"
            },
            "shadowColor": {
                canvas: "#000000"
            },
            "shadowOffsetX": {
                canvas: 0
            },
            "shadowOffsetY": {
                canvas: 0
            },
            "shadowBlur": {
                canvas: 0
            },
            "textAlign": {
                canvas: "start"
            },
            "textBaseline": {
                canvas: "alphabetic"
            },
            "lineDash": {
                svgAttr: "stroke-dasharray",
                canvas: [],
                svg: null,
                apply: "stroke"
            }
        };
        /**
         *
         * @param gradientNode - reference to the gradient
         * @constructor
         */
        CanvasGradient = function (gradientNode, ctx) {
            this.__root = gradientNode;
            this.__ctx = ctx;
        };
        /**
         * Adds a color stop to the gradient root
         */
        CanvasGradient.prototype.addColorStop = function (offset, color) {
            var stop = this.__ctx.__createElement("stop"), regex, matches;
            stop.setAttribute("offset", offset);
            if (color.indexOf("rgba") !== -1) {
                //separate alpha value, since webkit can't handle it
                regex = /rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d?\.?\d*)\s*\)/gi;
                matches = regex.exec(color);
                stop.setAttribute("stop-color", format("rgb({r},{g},{b})", { r: matches[1], g: matches[2], b: matches[3] }));
                stop.setAttribute("stop-opacity", matches[4]);
            }
            else {
                stop.setAttribute("stop-color", color);
            }
            this.__root.appendChild(stop);
        };
        CanvasPattern = function (pattern, ctx) {
            this.__root = pattern;
            this.__ctx = ctx;
        };
        /**
         * The mock canvas context
         * @param o - options include:
         * ctx - existing Context2D to wrap around
         * width - width of your canvas (defaults to 500)
         * height - height of your canvas (defaults to 500)
         * enableMirroring - enables canvas mirroring (get image data) (defaults to false)
         * document - the document object (defaults to the current document)
         */
        ctx = function (o) {
            var defaultOptions = { width: 500, height: 500, enableMirroring: false }, options;
            //keep support for this way of calling C2S: new C2S(width,height)
            if (arguments.length > 1) {
                options = defaultOptions;
                options.width = arguments[0];
                options.height = arguments[1];
            }
            else if (!o) {
                options = defaultOptions;
            }
            else {
                options = o;
            }
            if (!(this instanceof ctx)) {
                //did someone call this without new?
                return new ctx(options);
            }
            //setup options
            this.width = options.width || defaultOptions.width;
            this.height = options.height || defaultOptions.height;
            this.enableMirroring = options.enableMirroring !== undefined ? options.enableMirroring : defaultOptions.enableMirroring;
            this.canvas = this; ///point back to this instance!
            this.__document = options.document || document;
            // allow passing in an existing context to wrap around
            // if a context is passed in, we know a canvas already exist
            if (options.ctx) {
                this.__ctx = options.ctx;
            }
            else {
                this.__canvas = this.__document.createElement("canvas");
                this.__ctx = this.__canvas.getContext("2d");
            }
            this.__setDefaultStyles();
            this.__stack = [this.__getStyleState()];
            this.__groupStack = [];
            //the root svg element
            this.__root = this.__document.createElementNS("http://www.w3.org/2000/svg", "svg");
            this.__root.setAttribute("version", 1.1);
            this.__root.setAttribute("xmlns", "http://www.w3.org/2000/svg");
            this.__root.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
            this.__root.setAttribute("width", this.width);
            this.__root.setAttribute("height", this.height);
            //make sure we don't generate the same ids in defs
            this.__ids = {};
            //defs tag
            this.__defs = this.__document.createElementNS("http://www.w3.org/2000/svg", "defs");
            this.__root.appendChild(this.__defs);
            //also add a group child. the svg element can't use the transform attribute
            this.__currentElement = this.__document.createElementNS("http://www.w3.org/2000/svg", "g");
            this.__root.appendChild(this.__currentElement);
        };
        /**
         * Creates the specified svg element
         * @private
         */
        ctx.prototype.__createElement = function (elementName, properties, resetFill) {
            if (typeof properties === "undefined") {
                properties = {};
            }
            var element = this.__document.createElementNS("http://www.w3.org/2000/svg", elementName), keys = Object.keys(properties), i, key;
            if (resetFill) {
                //if fill or stroke is not specified, the svg element should not display. By default SVG's fill is black.
                element.setAttribute("fill", "none");
                element.setAttribute("stroke", "none");
            }
            for (i = 0; i < keys.length; i++) {
                key = keys[i];
                element.setAttribute(key, properties[key]);
            }
            return element;
        };
        /**
         * Applies default canvas styles to the context
         * @private
         */
        ctx.prototype.__setDefaultStyles = function () {
            //default 2d canvas context properties see:http://www.w3.org/TR/2dcontext/
            var keys = Object.keys(STYLES), i, key;
            for (i = 0; i < keys.length; i++) {
                key = keys[i];
                this[key] = STYLES[key].canvas;
            }
        };
        /**
         * Applies styles on restore
         * @param styleState
         * @private
         */
        ctx.prototype.__applyStyleState = function (styleState) {
            var keys = Object.keys(styleState), i, key;
            for (i = 0; i < keys.length; i++) {
                key = keys[i];
                this[key] = styleState[key];
            }
        };
        /**
         * Gets the current style state
         * @return {Object}
         * @private
         */
        ctx.prototype.__getStyleState = function () {
            var i, styleState = {}, keys = Object.keys(STYLES), key;
            for (i = 0; i < keys.length; i++) {
                key = keys[i];
                styleState[key] = this[key];
            }
            return styleState;
        };
        /**
         * Apples the current styles to the current SVG element. On "ctx.fill" or "ctx.stroke"
         * @param type
         * @private
         */
        ctx.prototype.__applyStyleToCurrentElement = function (type) {
            var currentElement = this.__currentElement;
            var currentStyleGroup = this.__currentElementsToStyle;
            if (currentStyleGroup) {
                currentElement.setAttribute(type, "");
                currentElement = currentStyleGroup.element;
                currentStyleGroup.children.forEach(function (node) {
                    node.setAttribute(type, "");
                });
            }
            var keys = Object.keys(STYLES), i, style, value, id, regex, matches;
            for (i = 0; i < keys.length; i++) {
                style = STYLES[keys[i]];
                value = this[keys[i]];
                if (style.apply) {
                    //is this a gradient or pattern?
                    if (value instanceof CanvasPattern) {
                        //pattern
                        if (value.__ctx) {
                            //copy over defs
                            while (value.__ctx.__defs.childNodes.length) {
                                id = value.__ctx.__defs.childNodes[0].getAttribute("id");
                                this.__ids[id] = id;
                                this.__defs.appendChild(value.__ctx.__defs.childNodes[0]);
                            }
                        }
                        currentElement.setAttribute(style.apply, format("url(#{id})", { id: value.__root.getAttribute("id") }));
                    }
                    else if (value instanceof CanvasGradient) {
                        //gradient
                        currentElement.setAttribute(style.apply, format("url(#{id})", { id: value.__root.getAttribute("id") }));
                    }
                    else if (style.apply.indexOf(type) !== -1 && style.svg !== value) {
                        if ((style.svgAttr === "stroke" || style.svgAttr === "fill") && value.indexOf("rgba") !== -1) {
                            //separate alpha value, since illustrator can't handle it
                            regex = /rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d?\.?\d*)\s*\)/gi;
                            matches = regex.exec(value);
                            currentElement.setAttribute(style.svgAttr, format("rgb({r},{g},{b})", { r: matches[1], g: matches[2], b: matches[3] }));
                            //should take globalAlpha here
                            var opacity = matches[4];
                            var globalAlpha = this.globalAlpha;
                            if (globalAlpha != null) {
                                opacity *= globalAlpha;
                            }
                            currentElement.setAttribute(style.svgAttr + "-opacity", opacity);
                        }
                        else {
                            var attr = style.svgAttr;
                            if (keys[i] === 'globalAlpha') {
                                attr = type + '-' + style.svgAttr;
                                if (currentElement.getAttribute(attr)) {
                                    //fill-opacity or stroke-opacity has already been set by stroke or fill.
                                    continue;
                                }
                            }
                            //otherwise only update attribute if right type, and not svg default
                            currentElement.setAttribute(attr, value);
                        }
                    }
                }
            }
        };
        /**
         * Will return the closest group or svg node. May return the current element.
         * @private
         */
        ctx.prototype.__closestGroupOrSvg = function (node) {
            node = node || this.__currentElement;
            if (node.nodeName === "g" || node.nodeName === "svg") {
                return node;
            }
            else {
                return this.__closestGroupOrSvg(node.parentNode);
            }
        };
        /**
         * Returns the serialized value of the svg so far
         * @param fixNamedEntities - Standalone SVG doesn't support named entities, which document.createTextNode encodes.
         *                           If true, we attempt to find all named entities and encode it as a numeric entity.
         * @return serialized svg
         */
        ctx.prototype.getSerializedSvg = function (fixNamedEntities) {
            var serialized = new XMLSerializer().serializeToString(this.__root), keys, i, key, value, regexp, xmlns;
            //IE search for a duplicate xmnls because they didn't implement setAttributeNS correctly
            xmlns = /xmlns="http:\/\/www\.w3\.org\/2000\/svg".+xmlns="http:\/\/www\.w3\.org\/2000\/svg/gi;
            if (xmlns.test(serialized)) {
                serialized = serialized.replace('xmlns="http://www.w3.org/2000/svg', 'xmlns:xlink="http://www.w3.org/1999/xlink');
            }
            if (fixNamedEntities) {
                keys = Object.keys(namedEntities);
                //loop over each named entity and replace with the proper equivalent.
                for (i = 0; i < keys.length; i++) {
                    key = keys[i];
                    value = namedEntities[key];
                    regexp = new RegExp(key, "gi");
                    if (regexp.test(serialized)) {
                        serialized = serialized.replace(regexp, value);
                    }
                }
            }
            return serialized;
        };
        /**
         * Returns the root svg
         * @return
         */
        ctx.prototype.getSvg = function () {
            return this.__root;
        };
        /**
         * Will generate a group tag.
         */
        ctx.prototype.save = function () {
            var group = this.__createElement("g");
            var parent = this.__closestGroupOrSvg();
            this.__groupStack.push(parent);
            parent.appendChild(group);
            this.__currentElement = group;
            this.__stack.push(this.__getStyleState());
        };
        /**
         * Sets current element to parent, or just root if already root
         */
        ctx.prototype.restore = function () {
            this.__currentElement = this.__groupStack.pop();
            this.__currentElementsToStyle = null;
            //Clearing canvas will make the poped group invalid, currentElement is set to the root group node.
            if (!this.__currentElement) {
                this.__currentElement = this.__root.childNodes[1];
            }
            var state = this.__stack.pop();
            this.__applyStyleState(state);
        };
        /**
         * Helper method to add transform
         * @private
         */
        ctx.prototype.__addTransform = function (t) {
            //if the current element has siblings, add another group
            var parent = this.__closestGroupOrSvg();
            if (parent.childNodes.length > 0) {
                if (this.__currentElement.nodeName === "path") {
                    if (!this.__currentElementsToStyle)
                        this.__currentElementsToStyle = { element: parent, children: [] };
                    this.__currentElementsToStyle.children.push(this.__currentElement);
                    this.__applyCurrentDefaultPath();
                }
                var group = this.__createElement("g");
                parent.appendChild(group);
                this.__currentElement = group;
            }
            var transform = this.__currentElement.getAttribute("transform");
            if (transform) {
                transform += " ";
            }
            else {
                transform = "";
            }
            transform += t;
            this.__currentElement.setAttribute("transform", transform);
        };
        /**
         *  scales the current element
         */
        ctx.prototype.scale = function (x, y) {
            if (y === undefined) {
                y = x;
            }
            this.__addTransform(format("scale({x},{y})", { x: x, y: y }));
        };
        /**
         * rotates the current element
         */
        ctx.prototype.rotate = function (angle) {
            var degrees = (angle * 180 / Math.PI);
            this.__addTransform(format("rotate({angle},{cx},{cy})", { angle: degrees, cx: 0, cy: 0 }));
        };
        /**
         * translates the current element
         */
        ctx.prototype.translate = function (x, y) {
            this.__addTransform(format("translate({x},{y})", { x: x, y: y }));
        };
        /**
         * applies a transform to the current element
         */
        ctx.prototype.transform = function (a, b, c, d, e, f) {
            this.__addTransform(format("matrix({a},{b},{c},{d},{e},{f})", { a: a, b: b, c: c, d: d, e: e, f: f }));
        };
        /**
         * Create a new Path Element
         */
        ctx.prototype.beginPath = function () {
            var path, parent;
            // Note that there is only one current default path, it is not part of the drawing state.
            // See also: https://html.spec.whatwg.org/multipage/scripting.html#current-default-path
            this.__currentDefaultPath = "";
            this.__currentPosition = {};
            path = this.__createElement("path", {}, true);
            parent = this.__closestGroupOrSvg();
            parent.appendChild(path);
            this.__currentElement = path;
        };
        /**
         * Helper function to apply currentDefaultPath to current path element
         * @private
         */
        ctx.prototype.__applyCurrentDefaultPath = function () {
            var currentElement = this.__currentElement;
            if (currentElement.nodeName === "path") {
                currentElement.setAttribute("d", this.__currentDefaultPath);
            }
            else {
                console.error("Attempted to apply path command to node", currentElement.nodeName);
            }
        };
        /**
         * Helper function to add path command
         * @private
         */
        ctx.prototype.__addPathCommand = function (command) {
            this.__currentDefaultPath += " ";
            this.__currentDefaultPath += command;
        };
        /**
         * Adds the move command to the current path element,
         * if the currentPathElement is not empty create a new path element
         */
        ctx.prototype.moveTo = function (x, y) {
            if (this.__currentElement.nodeName !== "path") {
                this.beginPath();
            }
            // creates a new subpath with the given point
            this.__currentPosition = { x: x, y: y };
            this.__addPathCommand(format("M {x} {y}", { x: x, y: y }));
        };
        /**
         * Closes the current path
         */
        ctx.prototype.closePath = function () {
            if (this.__currentDefaultPath) {
                this.__addPathCommand("Z");
            }
        };
        /**
         * Adds a line to command
         */
        ctx.prototype.lineTo = function (x, y) {
            this.__currentPosition = { x: x, y: y };
            if (this.__currentDefaultPath.indexOf('M') > -1) {
                this.__addPathCommand(format("L {x} {y}", { x: x, y: y }));
            }
            else {
                this.__addPathCommand(format("M {x} {y}", { x: x, y: y }));
            }
        };
        /**
         * Add a bezier command
         */
        ctx.prototype.bezierCurveTo = function (cp1x, cp1y, cp2x, cp2y, x, y) {
            this.__currentPosition = { x: x, y: y };
            this.__addPathCommand(format("C {cp1x} {cp1y} {cp2x} {cp2y} {x} {y}", { cp1x: cp1x, cp1y: cp1y, cp2x: cp2x, cp2y: cp2y, x: x, y: y }));
        };
        /**
         * Adds a quadratic curve to command
         */
        ctx.prototype.quadraticCurveTo = function (cpx, cpy, x, y) {
            this.__currentPosition = { x: x, y: y };
            this.__addPathCommand(format("Q {cpx} {cpy} {x} {y}", { cpx: cpx, cpy: cpy, x: x, y: y }));
        };
        /**
         * Return a new normalized vector of given vector
         */
        var normalize = function (vector) {
            var len = Math.sqrt(vector[0] * vector[0] + vector[1] * vector[1]);
            return [vector[0] / len, vector[1] / len];
        };
        /**
         * Adds the arcTo to the current path
         *
         * @see http://www.w3.org/TR/2015/WD-2dcontext-20150514/#dom-context-2d-arcto
         */
        ctx.prototype.arcTo = function (x1, y1, x2, y2, radius) {
            // Let the point (x0, y0) be the last point in the subpath.
            var x0 = this.__currentPosition && this.__currentPosition.x;
            var y0 = this.__currentPosition && this.__currentPosition.y;
            // First ensure there is a subpath for (x1, y1).
            if (typeof x0 == "undefined" || typeof y0 == "undefined") {
                return;
            }
            // Negative values for radius must cause the implementation to throw an IndexSizeError exception.
            if (radius < 0) {
                throw new Error("IndexSizeError: The radius provided (" + radius + ") is negative.");
            }
            // If the point (x0, y0) is equal to the point (x1, y1),
            // or if the point (x1, y1) is equal to the point (x2, y2),
            // or if the radius radius is zero,
            // then the method must add the point (x1, y1) to the subpath,
            // and connect that point to the previous point (x0, y0) by a straight line.
            if (((x0 === x1) && (y0 === y1))
                || ((x1 === x2) && (y1 === y2))
                || (radius === 0)) {
                this.lineTo(x1, y1);
                return;
            }
            // Otherwise, if the points (x0, y0), (x1, y1), and (x2, y2) all lie on a single straight line,
            // then the method must add the point (x1, y1) to the subpath,
            // and connect that point to the previous point (x0, y0) by a straight line.
            var unit_vec_p1_p0 = normalize([x0 - x1, y0 - y1]);
            var unit_vec_p1_p2 = normalize([x2 - x1, y2 - y1]);
            if (unit_vec_p1_p0[0] * unit_vec_p1_p2[1] === unit_vec_p1_p0[1] * unit_vec_p1_p2[0]) {
                this.lineTo(x1, y1);
                return;
            }
            // Otherwise, let The Arc be the shortest arc given by circumference of the circle that has radius radius,
            // and that has one point tangent to the half-infinite line that crosses the point (x0, y0) and ends at the point (x1, y1),
            // and that has a different point tangent to the half-infinite line that ends at the point (x1, y1), and crosses the point (x2, y2).
            // The points at which this circle touches these two lines are called the start and end tangent points respectively.
            // note that both vectors are unit vectors, so the length is 1
            var cos = (unit_vec_p1_p0[0] * unit_vec_p1_p2[0] + unit_vec_p1_p0[1] * unit_vec_p1_p2[1]);
            var theta = Math.acos(Math.abs(cos));
            // Calculate origin
            var unit_vec_p1_origin = normalize([
                unit_vec_p1_p0[0] + unit_vec_p1_p2[0],
                unit_vec_p1_p0[1] + unit_vec_p1_p2[1]
            ]);
            var len_p1_origin = radius / Math.sin(theta / 2);
            var x = x1 + len_p1_origin * unit_vec_p1_origin[0];
            var y = y1 + len_p1_origin * unit_vec_p1_origin[1];
            // Calculate start angle and end angle
            // rotate 90deg clockwise (note that y axis points to its down)
            var unit_vec_origin_start_tangent = [
                -unit_vec_p1_p0[1],
                unit_vec_p1_p0[0]
            ];
            // rotate 90deg counter clockwise (note that y axis points to its down)
            var unit_vec_origin_end_tangent = [
                unit_vec_p1_p2[1],
                -unit_vec_p1_p2[0]
            ];
            var getAngle = function (vector) {
                // get angle (clockwise) between vector and (1, 0)
                var x = vector[0];
                var y = vector[1];
                if (y >= 0) { // note that y axis points to its down
                    return Math.acos(x);
                }
                else {
                    return -Math.acos(x);
                }
            };
            var startAngle = getAngle(unit_vec_origin_start_tangent);
            var endAngle = getAngle(unit_vec_origin_end_tangent);
            // Connect the point (x0, y0) to the start tangent point by a straight line
            this.lineTo(x + unit_vec_origin_start_tangent[0] * radius, y + unit_vec_origin_start_tangent[1] * radius);
            // Connect the start tangent point to the end tangent point by arc
            // and adding the end tangent point to the subpath.
            this.arc(x, y, radius, startAngle, endAngle);
        };
        /**
         * Sets the stroke property on the current element
         */
        ctx.prototype.stroke = function () {
            if (this.__currentElement.nodeName === "path") {
                this.__currentElement.setAttribute("paint-order", "fill stroke markers");
            }
            this.__applyCurrentDefaultPath();
            this.__applyStyleToCurrentElement("stroke");
        };
        /**
         * Sets fill properties on the current element
         */
        ctx.prototype.fill = function () {
            if (this.__currentElement.nodeName === "path") {
                this.__currentElement.setAttribute("paint-order", "stroke fill markers");
            }
            this.__applyCurrentDefaultPath();
            this.__applyStyleToCurrentElement("fill");
        };
        /**
         *  Adds a rectangle to the path.
         */
        ctx.prototype.rect = function (x, y, width, height) {
            if (this.__currentElement.nodeName !== "path") {
                this.beginPath();
            }
            this.moveTo(x, y);
            this.lineTo(x + width, y);
            this.lineTo(x + width, y + height);
            this.lineTo(x, y + height);
            this.lineTo(x, y);
            this.closePath();
        };
        /**
         * adds a rectangle element
         */
        ctx.prototype.fillRect = function (x, y, width, height) {
            var rect, parent;
            rect = this.__createElement("rect", {
                x: x,
                y: y,
                width: width,
                height: height
            }, true);
            parent = this.__closestGroupOrSvg();
            parent.appendChild(rect);
            this.__currentElement = rect;
            this.__applyStyleToCurrentElement("fill");
        };
        /**
         * Draws a rectangle with no fill
         * @param x
         * @param y
         * @param width
         * @param height
         */
        ctx.prototype.strokeRect = function (x, y, width, height) {
            var rect, parent;
            rect = this.__createElement("rect", {
                x: x,
                y: y,
                width: width,
                height: height
            }, true);
            parent = this.__closestGroupOrSvg();
            parent.appendChild(rect);
            this.__currentElement = rect;
            this.__applyStyleToCurrentElement("stroke");
        };
        /**
         * Clear entire canvas:
         * 1. save current transforms
         * 2. remove all the childNodes of the root g element
         */
        ctx.prototype.__clearCanvas = function () {
            var current = this.__closestGroupOrSvg(), transform = current.getAttribute("transform");
            var rootGroup = this.__root.childNodes[1];
            var childNodes = rootGroup.childNodes;
            for (var i = childNodes.length - 1; i >= 0; i--) {
                if (childNodes[i]) {
                    rootGroup.removeChild(childNodes[i]);
                }
            }
            this.__currentElement = rootGroup;
            //reset __groupStack as all the child group nodes are all removed.
            this.__groupStack = [];
            if (transform) {
                this.__addTransform(transform);
            }
        };
        /**
         * "Clears" a canvas by just drawing a white rectangle in the current group.
         */
        ctx.prototype.clearRect = function (x, y, width, height) {
            //clear entire canvas
            if (x === 0 && y === 0 && width === this.width && height === this.height) {
                this.__clearCanvas();
                return;
            }
            var rect, parent = this.__closestGroupOrSvg();
            rect = this.__createElement("rect", {
                x: x,
                y: y,
                width: width,
                height: height,
                fill: "#FFFFFF"
            }, true);
            parent.appendChild(rect);
        };
        /**
         * Adds a linear gradient to a defs tag.
         * Returns a canvas gradient object that has a reference to it's parent def
         */
        ctx.prototype.createLinearGradient = function (x1, y1, x2, y2) {
            var grad = this.__createElement("linearGradient", {
                id: randomString(this.__ids),
                x1: x1 + "px",
                x2: x2 + "px",
                y1: y1 + "px",
                y2: y2 + "px",
                "gradientUnits": "userSpaceOnUse"
            }, false);
            this.__defs.appendChild(grad);
            return new CanvasGradient(grad, this);
        };
        /**
         * Adds a radial gradient to a defs tag.
         * Returns a canvas gradient object that has a reference to it's parent def
         */
        ctx.prototype.createRadialGradient = function (x0, y0, r0, x1, y1, r1) {
            var grad = this.__createElement("radialGradient", {
                id: randomString(this.__ids),
                cx: x1 + "px",
                cy: y1 + "px",
                r: r1 + "px",
                fx: x0 + "px",
                fy: y0 + "px",
                "gradientUnits": "userSpaceOnUse"
            }, false);
            this.__defs.appendChild(grad);
            return new CanvasGradient(grad, this);
        };
        /**
         * Parses the font string and returns svg mapping
         * @private
         */
        ctx.prototype.__parseFont = function () {
            var regex = /^\s*(?=(?:(?:[-a-z]+\s*){0,2}(italic|oblique))?)(?=(?:(?:[-a-z]+\s*){0,2}(small-caps))?)(?=(?:(?:[-a-z]+\s*){0,2}(bold(?:er)?|lighter|[1-9]00))?)(?:(?:normal|\1|\2|\3)\s*){0,3}((?:xx?-)?(?:small|large)|medium|smaller|larger|[.\d]+(?:\%|in|[cem]m|ex|p[ctx]))(?:\s*\/\s*(normal|[.\d]+(?:\%|in|[cem]m|ex|p[ctx])))?\s*([-,\'\"\sa-z0-9]+?)\s*$/i;
            var fontPart = regex.exec(this.font);
            var data = {
                style: fontPart[1] || 'normal',
                size: fontPart[4] || '10px',
                family: fontPart[6] || 'sans-serif',
                weight: fontPart[3] || 'normal',
                decoration: fontPart[2] || 'normal',
                href: null
            };
            //canvas doesn't support underline natively, but we can pass this attribute
            if (this.__fontUnderline === "underline") {
                data.decoration = "underline";
            }
            //canvas also doesn't support linking, but we can pass this as well
            if (this.__fontHref) {
                data.href = this.__fontHref;
            }
            return data;
        };
        /**
         * Helper to link text fragments
         * @param font
         * @param element
         * @return {*}
         * @private
         */
        ctx.prototype.__wrapTextLink = function (font, element) {
            if (font.href) {
                var a = this.__createElement("a");
                a.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", font.href);
                a.appendChild(element);
                return a;
            }
            return element;
        };
        /**
         * Fills or strokes text
         * @param text
         * @param x
         * @param y
         * @param action - stroke or fill
         * @private
         */
        ctx.prototype.__applyText = function (text, x, y, action) {
            var font = this.__parseFont(), parent = this.__closestGroupOrSvg(), textElement = this.__createElement("text", {
                "font-family": font.family,
                "font-size": font.size,
                "font-style": font.style,
                "font-weight": font.weight,
                "text-decoration": font.decoration,
                "x": x,
                "y": y,
                "text-anchor": getTextAnchor(this.textAlign),
                "dominant-baseline": getDominantBaseline(this.textBaseline)
            }, true);
            textElement.appendChild(this.__document.createTextNode(text));
            this.__currentElement = textElement;
            this.__applyStyleToCurrentElement(action);
            parent.appendChild(this.__wrapTextLink(font, textElement));
        };
        /**
         * Creates a text element
         * @param text
         * @param x
         * @param y
         */
        ctx.prototype.fillText = function (text, x, y) {
            this.__applyText(text, x, y, "fill");
        };
        /**
         * Strokes text
         * @param text
         * @param x
         * @param y
         */
        ctx.prototype.strokeText = function (text, x, y) {
            this.__applyText(text, x, y, "stroke");
        };
        /**
         * No need to implement this for svg.
         * @param text
         * @return {TextMetrics}
         */
        ctx.prototype.measureText = function (text) {
            this.__ctx.font = this.font;
            return this.__ctx.measureText(text);
        };
        /**
         *  Arc command!
         */
        ctx.prototype.arc = function (x, y, radius, startAngle, endAngle, counterClockwise) {
            // in canvas no circle is drawn if no angle is provided.
            if (startAngle === endAngle) {
                return;
            }
            startAngle = startAngle % (2 * Math.PI);
            endAngle = endAngle % (2 * Math.PI);
            if (startAngle === endAngle) {
                //circle time! subtract some of the angle so svg is happy (svg elliptical arc can't draw a full circle)
                endAngle = ((endAngle + (2 * Math.PI)) - 0.001 * (counterClockwise ? -1 : 1)) % (2 * Math.PI);
            }
            var endX = x + radius * Math.cos(endAngle), endY = y + radius * Math.sin(endAngle), startX = x + radius * Math.cos(startAngle), startY = y + radius * Math.sin(startAngle), sweepFlag = counterClockwise ? 0 : 1, largeArcFlag = 0, diff = endAngle - startAngle;
            // https://github.com/gliffy/canvas2svg/issues/4
            if (diff < 0) {
                diff += 2 * Math.PI;
            }
            if (counterClockwise) {
                largeArcFlag = diff > Math.PI ? 0 : 1;
            }
            else {
                largeArcFlag = diff > Math.PI ? 1 : 0;
            }
            this.lineTo(startX, startY);
            this.__addPathCommand(format("A {rx} {ry} {xAxisRotation} {largeArcFlag} {sweepFlag} {endX} {endY}", { rx: radius, ry: radius, xAxisRotation: 0, largeArcFlag: largeArcFlag, sweepFlag: sweepFlag, endX: endX, endY: endY }));
            this.__currentPosition = { x: endX, y: endY };
        };
        /**
         * Generates a ClipPath from the clip command.
         */
        ctx.prototype.clip = function () {
            var group = this.__closestGroupOrSvg(), clipPath = this.__createElement("clipPath"), id = randomString(this.__ids), newGroup = this.__createElement("g");
            this.__applyCurrentDefaultPath();
            group.removeChild(this.__currentElement);
            clipPath.setAttribute("id", id);
            clipPath.appendChild(this.__currentElement);
            this.__defs.appendChild(clipPath);
            //set the clip path to this group
            group.setAttribute("clip-path", format("url(#{id})", { id: id }));
            //clip paths can be scaled and transformed, we need to add another wrapper group to avoid later transformations
            // to this path
            group.appendChild(newGroup);
            this.__currentElement = newGroup;
        };
        /**
         * Draws a canvas, image or mock context to this canvas.
         * Note that all svg dom manipulation uses node.childNodes rather than node.children for IE support.
         * http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage
         */
        ctx.prototype.drawImage = function () {
            //convert arguments to a real array
            var args = Array.prototype.slice.call(arguments), image = args[0], dx, dy, dw, dh, sx = 0, sy = 0, sw, sh, parent, svg, defs, group, currentElement, svgImage, canvas, context, id;
            if (args.length === 3) {
                dx = args[1];
                dy = args[2];
                sw = image.width;
                sh = image.height;
                dw = sw;
                dh = sh;
            }
            else if (args.length === 5) {
                dx = args[1];
                dy = args[2];
                dw = args[3];
                dh = args[4];
                sw = image.width;
                sh = image.height;
            }
            else if (args.length === 9) {
                sx = args[1];
                sy = args[2];
                sw = args[3];
                sh = args[4];
                dx = args[5];
                dy = args[6];
                dw = args[7];
                dh = args[8];
            }
            else {
                throw new Error("Inavlid number of arguments passed to drawImage: " + arguments.length);
            }
            parent = this.__closestGroupOrSvg();
            currentElement = this.__currentElement;
            var translateDirective = "translate(" + dx + ", " + dy + ")";
            if (image instanceof ctx) {
                //canvas2svg mock canvas context. In the future we may want to clone nodes instead.
                //also I'm currently ignoring dw, dh, sw, sh, sx, sy for a mock context.
                svg = image.getSvg().cloneNode(true);
                if (svg.childNodes && svg.childNodes.length > 1) {
                    defs = svg.childNodes[0];
                    while (defs.childNodes.length) {
                        id = defs.childNodes[0].getAttribute("id");
                        this.__ids[id] = id;
                        this.__defs.appendChild(defs.childNodes[0]);
                    }
                    group = svg.childNodes[1];
                    if (group) {
                        //save original transform
                        var originTransform = group.getAttribute("transform");
                        var transformDirective;
                        if (originTransform) {
                            transformDirective = originTransform + " " + translateDirective;
                        }
                        else {
                            transformDirective = translateDirective;
                        }
                        group.setAttribute("transform", transformDirective);
                        parent.appendChild(group);
                    }
                }
            }
            else if (image.nodeName === "IMG") {
                svgImage = this.__createElement("image");
                svgImage.setAttribute("width", dw);
                svgImage.setAttribute("height", dh);
                svgImage.setAttribute("preserveAspectRatio", "none");
                if (sx || sy || sw !== image.width || sh !== image.height) {
                    //crop the image using a temporary canvas
                    canvas = this.__document.createElement("canvas");
                    canvas.width = dw;
                    canvas.height = dh;
                    context = canvas.getContext("2d");
                    context.drawImage(image, sx, sy, sw, sh, 0, 0, dw, dh);
                    image = canvas;
                }
                svgImage.setAttribute("transform", translateDirective);
                svgImage.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", image.nodeName === "CANVAS" ? image.toDataURL() : image.getAttribute("src"));
                parent.appendChild(svgImage);
            }
            else if (image.nodeName === "CANVAS") {
                svgImage = this.__createElement("image");
                svgImage.setAttribute("width", dw);
                svgImage.setAttribute("height", dh);
                svgImage.setAttribute("preserveAspectRatio", "none");
                // draw canvas onto temporary canvas so that smoothing can be handled
                canvas = this.__document.createElement("canvas");
                canvas.width = dw;
                canvas.height = dh;
                context = canvas.getContext("2d");
                context.imageSmoothingEnabled = false;
                context.mozImageSmoothingEnabled = false;
                context.oImageSmoothingEnabled = false;
                context.webkitImageSmoothingEnabled = false;
                context.drawImage(image, sx, sy, sw, sh, 0, 0, dw, dh);
                image = canvas;
                svgImage.setAttribute("transform", translateDirective);
                svgImage.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", image.toDataURL());
                parent.appendChild(svgImage);
            }
        };
        /**
         * Generates a pattern tag
         */
        ctx.prototype.createPattern = function (image, repetition) {
            var pattern = this.__document.createElementNS("http://www.w3.org/2000/svg", "pattern"), id = randomString(this.__ids), img;
            pattern.setAttribute("id", id);
            pattern.setAttribute("width", image.width);
            pattern.setAttribute("height", image.height);
            if (image.nodeName === "CANVAS" || image.nodeName === "IMG") {
                img = this.__document.createElementNS("http://www.w3.org/2000/svg", "image");
                img.setAttribute("width", image.width);
                img.setAttribute("height", image.height);
                img.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", image.nodeName === "CANVAS" ? image.toDataURL() : image.getAttribute("src"));
                pattern.appendChild(img);
                this.__defs.appendChild(pattern);
            }
            else if (image instanceof ctx) {
                pattern.appendChild(image.__root.childNodes[1]);
                this.__defs.appendChild(pattern);
            }
            return new CanvasPattern(pattern, this);
        };
        ctx.prototype.setLineDash = function (dashArray) {
            if (dashArray && dashArray.length > 0) {
                this.lineDash = dashArray.join(",");
            }
            else {
                this.lineDash = null;
            }
        };
        /**
         * Not yet implemented
         */
        ctx.prototype.drawFocusRing = function () { };
        ctx.prototype.createImageData = function () { };
        ctx.prototype.getImageData = function () { };
        ctx.prototype.putImageData = function () { };
        ctx.prototype.globalCompositeOperation = function () { };
        ctx.prototype.setTransform = function () { };
        //add options for alternative namespace
        if (typeof window === "object") {
            window.C2S = ctx;
        }
        // CommonJS/Browserify
        if (typeof module === "object" && typeof module.exports === "object") {
            module.exports = ctx;
        }
    }());
},
/* models/canvas/cartesian_frame.js */ function _(require, module, exports) {
    const categorical_scale_1 = require(177) /* ../scales/categorical_scale */;
    const linear_scale_1 = require(113) /* ../scales/linear_scale */;
    const log_scale_1 = require(122) /* ../scales/log_scale */;
    const range1d_1 = require(123) /* ../ranges/range1d */;
    const data_range1d_1 = require(178) /* ../ranges/data_range1d */;
    const factor_range_1 = require(82) /* ../ranges/factor_range */;
    const layout_1 = require(180) /* ../../core/layout */;
    class CartesianFrame extends layout_1.LayoutItem {
        constructor(x_scale, y_scale, x_range, y_range, extra_x_ranges = {}, extra_y_ranges = {}) {
            super();
            this.x_scale = x_scale;
            this.y_scale = y_scale;
            this.x_range = x_range;
            this.y_range = y_range;
            this.extra_x_ranges = extra_x_ranges;
            this.extra_y_ranges = extra_y_ranges;
            this._configure_scales();
        }
        map_to_screen(x, y, x_name = "default", y_name = "default") {
            const sx = this.xscales[x_name].v_compute(x);
            const sy = this.yscales[y_name].v_compute(y);
            return [sx, sy];
        }
        _get_ranges(range, extra_ranges) {
            const ranges = {};
            ranges.default = range;
            if (extra_ranges != null) {
                for (const name in extra_ranges)
                    ranges[name] = extra_ranges[name];
            }
            return ranges;
        }
        /*protected*/ _get_scales(scale, ranges, frame_range) {
            const scales = {};
            for (const name in ranges) {
                const range = ranges[name];
                if (range instanceof data_range1d_1.DataRange1d || range instanceof range1d_1.Range1d) {
                    if (!(scale instanceof log_scale_1.LogScale) && !(scale instanceof linear_scale_1.LinearScale))
                        throw new Error(`Range ${range.type} is incompatible is Scale ${scale.type}`);
                    // XXX: special case because CategoricalScale is a subclass of LinearScale, should be removed in future
                    if (scale instanceof categorical_scale_1.CategoricalScale)
                        throw new Error(`Range ${range.type} is incompatible is Scale ${scale.type}`);
                }
                if (range instanceof factor_range_1.FactorRange) {
                    if (!(scale instanceof categorical_scale_1.CategoricalScale))
                        throw new Error(`Range ${range.type} is incompatible is Scale ${scale.type}`);
                }
                if (scale instanceof log_scale_1.LogScale && range instanceof data_range1d_1.DataRange1d)
                    range.scale_hint = "log";
                const s = scale.clone();
                s.setv({ source_range: range, target_range: frame_range });
                scales[name] = s;
            }
            return scales;
        }
        _configure_frame_ranges() {
            // data to/from screen space transform (left-bottom <-> left-top origin)
            this._h_target = new range1d_1.Range1d({ start: this._left.value, end: this._right.value });
            this._v_target = new range1d_1.Range1d({ start: this._bottom.value, end: this._top.value });
        }
        _configure_scales() {
            this._configure_frame_ranges();
            this._x_ranges = this._get_ranges(this.x_range, this.extra_x_ranges);
            this._y_ranges = this._get_ranges(this.y_range, this.extra_y_ranges);
            this._xscales = this._get_scales(this.x_scale, this._x_ranges, this._h_target);
            this._yscales = this._get_scales(this.y_scale, this._y_ranges, this._v_target);
        }
        _update_scales() {
            this._configure_frame_ranges();
            for (const name in this._xscales) {
                const scale = this._xscales[name];
                scale.target_range = this._h_target;
            }
            for (const name in this._yscales) {
                const scale = this._yscales[name];
                scale.target_range = this._v_target;
            }
        }
        _set_geometry(outer, inner) {
            super._set_geometry(outer, inner);
            this._update_scales();
        }
        get x_ranges() {
            return this._x_ranges;
        }
        get y_ranges() {
            return this._y_ranges;
        }
        get xscales() {
            return this._xscales;
        }
        get yscales() {
            return this._yscales;
        }
    }
    exports.CartesianFrame = CartesianFrame;
    CartesianFrame.__name__ = "CartesianFrame";
},
/* models/scales/categorical_scale.js */ function _(require, module, exports) {
    const linear_scale_1 = require(113) /* ./linear_scale */;
    class CategoricalScale extends linear_scale_1.LinearScale {
        constructor(attrs) {
            super(attrs);
        }
        compute(x) {
            return super.compute(this.source_range.synthetic(x));
        }
        v_compute(xs) {
            return super.v_compute(this.source_range.v_synthetic(xs));
        }
    }
    exports.CategoricalScale = CategoricalScale;
    CategoricalScale.__name__ = "CategoricalScale";
},
/* models/ranges/data_range1d.js */ function _(require, module, exports) {
    const data_range_1 = require(179) /* ./data_range */;
    const glyph_renderer_1 = require(73) /* ../renderers/glyph_renderer */;
    const logging_1 = require(65) /* ../../core/logging */;
    const p = require(18) /* ../../core/properties */;
    const bbox = require(79) /* ../../core/util/bbox */;
    const array_1 = require(8) /* ../../core/util/array */;
    class DataRange1d extends data_range_1.DataRange {
        constructor(attrs) {
            super(attrs);
            this._plot_bounds = {};
            this.have_updated_interactively = false;
        }
        static init_DataRange1d() {
            this.define({
                start: [p.Number],
                end: [p.Number],
                range_padding: [p.Number, 0.1],
                range_padding_units: [p.PaddingUnits, "percent"],
                flipped: [p.Boolean, false],
                follow: [p.StartEnd],
                follow_interval: [p.Number],
                default_span: [p.Number, 2],
                only_visible: [p.Boolean, false],
            });
            this.internal({
                scale_hint: [p.String, 'auto'],
            });
        }
        initialize() {
            super.initialize();
            this._initial_start = this.start;
            this._initial_end = this.end;
            this._initial_range_padding = this.range_padding;
            this._initial_range_padding_units = this.range_padding_units;
            this._initial_follow = this.follow;
            this._initial_follow_interval = this.follow_interval;
            this._initial_default_span = this.default_span;
        }
        get min() {
            return Math.min(this.start, this.end);
        }
        get max() {
            return Math.max(this.start, this.end);
        }
        computed_renderers() {
            // TODO (bev) check that renderers actually configured with this range
            const names = this.names;
            let renderers = this.renderers;
            if (renderers.length == 0) {
                for (const plot of this.plots) {
                    const rs = plot.renderers.filter((r) => r instanceof glyph_renderer_1.GlyphRenderer);
                    renderers = renderers.concat(rs);
                }
            }
            if (names.length > 0)
                renderers = renderers.filter((r) => array_1.includes(names, r.name));
            logging_1.logger.debug(`computed ${renderers.length} renderers for DataRange1d ${this.id}`);
            for (const r of renderers) {
                logging_1.logger.trace(` - ${r.type} ${r.id}`);
            }
            return renderers;
        }
        /*protected*/ _compute_plot_bounds(renderers, bounds) {
            let result = bbox.empty();
            for (const r of renderers) {
                if (bounds[r.id] != null && (r.visible || !this.only_visible))
                    result = bbox.union(result, bounds[r.id]);
            }
            return result;
        }
        adjust_bounds_for_aspect(bounds, ratio) {
            const result = bbox.empty();
            let width = bounds.x1 - bounds.x0;
            if (width <= 0) {
                width = 1.0;
            }
            let height = bounds.y1 - bounds.y0;
            if (height <= 0) {
                height = 1.0;
            }
            const xcenter = 0.5 * (bounds.x1 + bounds.x0);
            const ycenter = 0.5 * (bounds.y1 + bounds.y0);
            if (width < ratio * height) {
                width = ratio * height;
            }
            else {
                height = width / ratio;
            }
            result.x1 = xcenter + 0.5 * width;
            result.x0 = xcenter - 0.5 * width;
            result.y1 = ycenter + 0.5 * height;
            result.y0 = ycenter - 0.5 * height;
            return result;
        }
        /*protected*/ _compute_min_max(plot_bounds, dimension) {
            let overall = bbox.empty();
            for (const k in plot_bounds) {
                const v = plot_bounds[k];
                overall = bbox.union(overall, v);
            }
            let min, max;
            if (dimension == 0)
                [min, max] = [overall.x0, overall.x1];
            else
                [min, max] = [overall.y0, overall.y1];
            return [min, max];
        }
        /*protected*/ _compute_range(min, max) {
            const range_padding = this.range_padding; // XXX: ? 0
            let start, end;
            if (this.scale_hint == "log") {
                if (isNaN(min) || !isFinite(min) || min <= 0) {
                    if (isNaN(max) || !isFinite(max) || max <= 0)
                        min = 0.1;
                    else
                        min = max / 100;
                    logging_1.logger.warn(`could not determine minimum data value for log axis, DataRange1d using value ${min}`);
                }
                if (isNaN(max) || !isFinite(max) || max <= 0) {
                    if (isNaN(min) || !isFinite(min) || min <= 0)
                        max = 10;
                    else
                        max = min * 100;
                    logging_1.logger.warn(`could not determine maximum data value for log axis, DataRange1d using value ${max}`);
                }
                let center, span;
                if (max == min) {
                    span = this.default_span + 0.001;
                    center = Math.log(min) / Math.log(10);
                }
                else {
                    let log_min, log_max;
                    if (this.range_padding_units == "percent") {
                        log_min = Math.log(min) / Math.log(10);
                        log_max = Math.log(max) / Math.log(10);
                        span = (log_max - log_min) * (1 + range_padding);
                    }
                    else {
                        log_min = Math.log(min - range_padding) / Math.log(10);
                        log_max = Math.log(max + range_padding) / Math.log(10);
                        span = log_max - log_min;
                    }
                    center = (log_min + log_max) / 2.0;
                }
                start = Math.pow(10, center - span / 2.0);
                end = Math.pow(10, center + span / 2.0);
            }
            else {
                let span;
                if (max == min)
                    span = this.default_span;
                else {
                    if (this.range_padding_units == "percent")
                        span = (max - min) * (1 + range_padding);
                    else
                        span = (max - min) + 2 * range_padding;
                }
                const center = (max + min) / 2.0;
                start = center - span / 2.0;
                end = center + span / 2.0;
            }
            let follow_sign = +1;
            if (this.flipped) {
                [start, end] = [end, start];
                follow_sign = -1;
            }
            const follow_interval = this.follow_interval;
            if (follow_interval != null && Math.abs(start - end) > follow_interval) {
                if (this.follow == 'start')
                    end = start + follow_sign * follow_interval;
                else if (this.follow == 'end')
                    start = end - follow_sign * follow_interval;
            }
            return [start, end];
        }
        update(bounds, dimension, bounds_id, ratio) {
            if (this.have_updated_interactively)
                return;
            const renderers = this.computed_renderers();
            // update the raw data bounds for all renderers we care about
            let total_bounds = this._compute_plot_bounds(renderers, bounds);
            if (ratio != null)
                total_bounds = this.adjust_bounds_for_aspect(total_bounds, ratio);
            this._plot_bounds[bounds_id] = total_bounds;
            // compute the min/mix for our specified dimension
            const [min, max] = this._compute_min_max(this._plot_bounds, dimension);
            // derive start, end from bounds and data range config
            let [start, end] = this._compute_range(min, max);
            if (this._initial_start != null) {
                if (this.scale_hint == "log") {
                    if (this._initial_start > 0)
                        start = this._initial_start;
                }
                else
                    start = this._initial_start;
            }
            if (this._initial_end != null) {
                if (this.scale_hint == "log") {
                    if (this._initial_end > 0)
                        end = this._initial_end;
                }
                else
                    end = this._initial_end;
            }
            // only trigger updates when there are changes
            const [_start, _end] = [this.start, this.end];
            if (start != _start || end != _end) {
                const new_range = {};
                if (start != _start)
                    new_range.start = start;
                if (end != _end)
                    new_range.end = end;
                this.setv(new_range);
            }
            if (this.bounds == 'auto')
                this.setv({ bounds: [start, end] }, { silent: true });
            this.change.emit();
        }
        reset() {
            this.have_updated_interactively = false;
            // change events silenced as PlotView.update_dataranges triggers property callbacks
            this.setv({
                range_padding: this._initial_range_padding,
                range_padding_units: this._initial_range_padding_units,
                follow: this._initial_follow,
                follow_interval: this._initial_follow_interval,
                default_span: this._initial_default_span,
            }, { silent: true });
            this.change.emit();
        }
    }
    exports.DataRange1d = DataRange1d;
    DataRange1d.__name__ = "DataRange1d";
    DataRange1d.init_DataRange1d();
},
/* models/ranges/data_range.js */ function _(require, module, exports) {
    const range_1 = require(83) /* ./range */;
    const p = require(18) /* ../../core/properties */;
    class DataRange extends range_1.Range {
        constructor(attrs) {
            super(attrs);
        }
        static init_DataRange() {
            this.define({
                names: [p.Array, []],
                renderers: [p.Array, []],
            });
        }
    }
    exports.DataRange = DataRange;
    DataRange.__name__ = "DataRange";
    DataRange.init_DataRange();
},
/* core/layout/index.js */ function _(require, module, exports) {
    var types_1 = require(181) /* ./types */;
    exports.Sizeable = types_1.Sizeable;
    var layoutable_1 = require(182) /* ./layoutable */;
    exports.Layoutable = layoutable_1.Layoutable;
    exports.LayoutItem = layoutable_1.LayoutItem;
    var alignments_1 = require(183) /* ./alignments */;
    exports.HStack = alignments_1.HStack;
    exports.VStack = alignments_1.VStack;
    exports.AnchorLayout = alignments_1.AnchorLayout;
    var grid_1 = require(184) /* ./grid */;
    exports.Grid = grid_1.Grid;
    exports.Row = grid_1.Row;
    exports.Column = grid_1.Column;
    var html_1 = require(185) /* ./html */;
    exports.ContentBox = html_1.ContentBox;
    exports.VariadicBox = html_1.VariadicBox;
},
/* core/layout/types.js */ function _(require, module, exports) {
    const { min, max } = Math;
    class Sizeable {
        constructor(size = {}) {
            this.width = size.width != null ? size.width : 0;
            this.height = size.height != null ? size.height : 0;
        }
        bounded_to({ width, height }) {
            return new Sizeable({
                width: this.width == Infinity && width != null ? width : this.width,
                height: this.height == Infinity && height != null ? height : this.height,
            });
        }
        expanded_to({ width, height }) {
            return new Sizeable({
                width: width != Infinity ? max(this.width, width) : this.width,
                height: height != Infinity ? max(this.height, height) : this.height,
            });
        }
        expand_to({ width, height }) {
            this.width = max(this.width, width);
            this.height = max(this.height, height);
        }
        narrowed_to({ width, height }) {
            return new Sizeable({
                width: min(this.width, width),
                height: min(this.height, height),
            });
        }
        narrow_to({ width, height }) {
            this.width = min(this.width, width);
            this.height = min(this.height, height);
        }
        grow_by({ left, right, top, bottom }) {
            const width = this.width + left + right;
            const height = this.height + top + bottom;
            return new Sizeable({ width, height });
        }
        shrink_by({ left, right, top, bottom }) {
            const width = max(this.width - left - right, 0);
            const height = max(this.height - top - bottom, 0);
            return new Sizeable({ width, height });
        }
        map(w_fn, h_fn) {
            return new Sizeable({
                width: w_fn(this.width),
                height: (h_fn != null ? h_fn : w_fn)(this.height),
            });
        }
    }
    exports.Sizeable = Sizeable;
    Sizeable.__name__ = "Sizeable";
},
/* core/layout/layoutable.js */ function _(require, module, exports) {
    const types_1 = require(181) /* ./types */;
    const bbox_1 = require(79) /* ../util/bbox */;
    const { min, max, round } = Math;
    class Layoutable {
        constructor() {
            this._bbox = new bbox_1.BBox();
            this._inner_bbox = new bbox_1.BBox();
            const layout = this;
            this._top = { get value() { return layout.bbox.top; } };
            this._left = { get value() { return layout.bbox.left; } };
            this._width = { get value() { return layout.bbox.width; } };
            this._height = { get value() { return layout.bbox.height; } };
            this._right = { get value() { return layout.bbox.right; } };
            this._bottom = { get value() { return layout.bbox.bottom; } };
            this._hcenter = { get value() { return layout.bbox.hcenter; } };
            this._vcenter = { get value() { return layout.bbox.vcenter; } };
        }
        get bbox() {
            return this._bbox;
        }
        get inner_bbox() {
            return this._inner_bbox;
        }
        get sizing() {
            return this._sizing;
        }
        set_sizing(sizing) {
            const width_policy = sizing.width_policy || "fit";
            const width = sizing.width;
            const min_width = sizing.min_width != null ? sizing.min_width : 0;
            const max_width = sizing.max_width != null ? sizing.max_width : Infinity;
            const height_policy = sizing.height_policy || "fit";
            const height = sizing.height;
            const min_height = sizing.min_height != null ? sizing.min_height : 0;
            const max_height = sizing.max_height != null ? sizing.max_height : Infinity;
            const aspect = sizing.aspect;
            const margin = sizing.margin || { top: 0, right: 0, bottom: 0, left: 0 };
            const visible = sizing.visible !== false;
            const halign = sizing.halign || "start";
            const valign = sizing.valign || "start";
            this._sizing = {
                width_policy, min_width, width, max_width,
                height_policy, min_height, height, max_height,
                aspect,
                margin,
                visible,
                halign,
                valign,
                size: { width, height },
                min_size: { width: min_width, height: min_height },
                max_size: { width: max_width, height: max_height },
            };
            this._init();
        }
        _init() { }
        _set_geometry(outer, inner) {
            this._bbox = outer;
            this._inner_bbox = inner;
        }
        set_geometry(outer, inner) {
            this._set_geometry(outer, inner || outer);
        }
        is_width_expanding() {
            return this.sizing.width_policy == "max";
        }
        is_height_expanding() {
            return this.sizing.height_policy == "max";
        }
        apply_aspect(viewport, { width, height }) {
            const { aspect } = this.sizing;
            if (aspect != null) {
                const { width_policy, height_policy } = this.sizing;
                const gt = (width, height) => {
                    const policies = { max: 4, fit: 3, min: 2, fixed: 1 };
                    return policies[width] > policies[height];
                };
                if (width_policy != "fixed" && height_policy != "fixed") {
                    if (width_policy == height_policy) {
                        const w_width = width;
                        const w_height = round(width / aspect);
                        const h_width = round(height * aspect);
                        const h_height = height;
                        const w_diff = Math.abs(viewport.width - w_width) + Math.abs(viewport.height - w_height);
                        const h_diff = Math.abs(viewport.width - h_width) + Math.abs(viewport.height - h_height);
                        if (w_diff <= h_diff) {
                            width = w_width;
                            height = w_height;
                        }
                        else {
                            width = h_width;
                            height = h_height;
                        }
                    }
                    else if (gt(width_policy, height_policy)) {
                        height = round(width / aspect);
                    }
                    else {
                        width = round(height * aspect);
                    }
                }
                else if (width_policy == "fixed") {
                    height = round(width / aspect);
                }
                else if (height_policy == "fixed") {
                    width = round(height * aspect);
                }
            }
            return { width, height };
        }
        measure(viewport_size) {
            if (!this.sizing.visible)
                return { width: 0, height: 0 };
            const exact_width = (width) => {
                return this.sizing.width_policy == "fixed" && this.sizing.width != null ? this.sizing.width : width;
            };
            const exact_height = (height) => {
                return this.sizing.height_policy == "fixed" && this.sizing.height != null ? this.sizing.height : height;
            };
            const viewport = new types_1.Sizeable(viewport_size)
                .shrink_by(this.sizing.margin)
                .map(exact_width, exact_height);
            const computed = this._measure(viewport);
            const clipped = this.clip_size(computed);
            const width = exact_width(clipped.width);
            const height = exact_height(clipped.height);
            const size = this.apply_aspect(viewport, { width, height });
            return Object.assign(Object.assign({}, computed), size);
        }
        compute(viewport = {}) {
            const size_hint = this.measure({
                width: viewport.width != null && this.is_width_expanding() ? viewport.width : Infinity,
                height: viewport.height != null && this.is_height_expanding() ? viewport.height : Infinity,
            });
            const { width, height } = size_hint;
            const outer = new bbox_1.BBox({ left: 0, top: 0, width, height });
            let inner = undefined;
            if (size_hint.inner != null) {
                const { left, top, right, bottom } = size_hint.inner;
                inner = new bbox_1.BBox({ left, top, right: width - right, bottom: height - bottom });
            }
            this.set_geometry(outer, inner);
        }
        get xview() {
            return this.bbox.xview;
        }
        get yview() {
            return this.bbox.yview;
        }
        clip_width(width) {
            return max(this.sizing.min_width, min(width, this.sizing.max_width));
        }
        clip_height(height) {
            return max(this.sizing.min_height, min(height, this.sizing.max_height));
        }
        clip_size({ width, height }) {
            return {
                width: this.clip_width(width),
                height: this.clip_height(height),
            };
        }
    }
    exports.Layoutable = Layoutable;
    Layoutable.__name__ = "Layoutable";
    class LayoutItem extends Layoutable {
        /*
        constructor(readonly measure_fn: (viewport: Size) => Size) {
          super()
        }
        protected _measure(viewport: Size): SizeHint {
          return this.measure_fn(viewport)
        }
        protected _measure(viewport: Size): SizeHint {
          return {
            width: viewport.width != Infinity ? viewport.width : this.sizing.min_width,
            height: viewport.height != Infinity ? viewport.height : this.sizing.min_width,
          }
        }
        */
        _measure(viewport) {
            const { width_policy, height_policy } = this.sizing;
            let width;
            if (viewport.width == Infinity) {
                width = this.sizing.width != null ? this.sizing.width : 0;
            }
            else {
                if (width_policy == "fixed")
                    width = this.sizing.width != null ? this.sizing.width : 0;
                else if (width_policy == "min")
                    width = this.sizing.width != null ? min(viewport.width, this.sizing.width) : 0;
                else if (width_policy == "fit")
                    width = this.sizing.width != null ? min(viewport.width, this.sizing.width) : viewport.width;
                else if (width_policy == "max")
                    width = this.sizing.width != null ? max(viewport.width, this.sizing.width) : viewport.width;
                else
                    throw new Error("unrechable");
            }
            let height;
            if (viewport.height == Infinity) {
                height = this.sizing.height != null ? this.sizing.height : 0;
            }
            else {
                if (height_policy == "fixed")
                    height = this.sizing.height != null ? this.sizing.height : 0;
                else if (height_policy == "min")
                    height = this.sizing.height != null ? min(viewport.height, this.sizing.height) : 0;
                else if (height_policy == "fit")
                    height = this.sizing.height != null ? min(viewport.height, this.sizing.height) : viewport.height;
                else if (height_policy == "max")
                    height = this.sizing.height != null ? max(viewport.height, this.sizing.height) : viewport.height;
                else
                    throw new Error("unrechable");
            }
            return { width, height };
        }
    }
    exports.LayoutItem = LayoutItem;
    LayoutItem.__name__ = "LayoutItem";
    class ContentLayoutable extends Layoutable {
        _measure(viewport) {
            const content_size = this._content_size();
            const bounds = viewport
                .bounded_to(this.sizing.size)
                .bounded_to(content_size);
            const width = (() => {
                switch (this.sizing.width_policy) {
                    case "fixed":
                        return this.sizing.width != null ? this.sizing.width : content_size.width;
                    case "min":
                        return content_size.width;
                    case "fit":
                        return bounds.width;
                    case "max":
                        return Math.max(content_size.width, bounds.width);
                    default:
                        throw new Error("unexpected");
                }
            })();
            const height = (() => {
                switch (this.sizing.height_policy) {
                    case "fixed":
                        return this.sizing.height != null ? this.sizing.height : content_size.height;
                    case "min":
                        return content_size.height;
                    case "fit":
                        return bounds.height;
                    case "max":
                        return Math.max(content_size.height, bounds.height);
                    default:
                        throw new Error("unexpected");
                }
            })();
            return { width, height };
        }
    }
    exports.ContentLayoutable = ContentLayoutable;
    ContentLayoutable.__name__ = "ContentLayoutable";
},
/* core/layout/alignments.js */ function _(require, module, exports) {
    const layoutable_1 = require(182) /* ./layoutable */;
    const bbox_1 = require(79) /* ../util/bbox */;
    class Stack extends layoutable_1.Layoutable {
        constructor() {
            super(...arguments);
            this.children = [];
        }
    }
    exports.Stack = Stack;
    Stack.__name__ = "Stack";
    class HStack extends Stack {
        _measure(_viewport) {
            let width = 0;
            let height = 0;
            for (const child of this.children) {
                const size_hint = child.measure({ width: 0, height: 0 });
                width += size_hint.width;
                height = Math.max(height, size_hint.height);
            }
            return { width, height };
        }
        _set_geometry(outer, inner) {
            super._set_geometry(outer, inner);
            const { top, bottom } = outer;
            let { left } = outer;
            for (const child of this.children) {
                const { width } = child.measure({ width: 0, height: 0 });
                child.set_geometry(new bbox_1.BBox({ left, width, top, bottom }));
                left += width;
            }
        }
    }
    exports.HStack = HStack;
    HStack.__name__ = "HStack";
    class VStack extends Stack {
        _measure(_viewport) {
            let width = 0;
            let height = 0;
            for (const child of this.children) {
                const size_hint = child.measure({ width: 0, height: 0 });
                width = Math.max(width, size_hint.width);
                height += size_hint.height;
            }
            return { width, height };
        }
        _set_geometry(outer, inner) {
            super._set_geometry(outer, inner);
            const { left, right } = outer;
            let { top } = outer;
            for (const child of this.children) {
                const { height } = child.measure({ width: 0, height: 0 });
                child.set_geometry(new bbox_1.BBox({ top, height, left, right }));
                top += height;
            }
        }
    }
    exports.VStack = VStack;
    VStack.__name__ = "VStack";
    class AnchorLayout extends layoutable_1.Layoutable {
        constructor() {
            super(...arguments);
            this.children = [];
        }
        _measure(viewport) {
            let width = 0;
            let height = 0;
            for (const { layout } of this.children) {
                const size_hint = layout.measure(viewport);
                width = Math.max(width, size_hint.width);
                height = Math.max(height, size_hint.height);
            }
            return { width, height };
        }
        _set_geometry(outer, inner) {
            super._set_geometry(outer, inner);
            for (const { layout, anchor, margin } of this.children) {
                const { left, right, top, bottom, hcenter, vcenter } = outer;
                const { width, height } = layout.measure(outer);
                let bbox;
                switch (anchor) {
                    case 'top_left':
                        bbox = new bbox_1.BBox({ left: left + margin, top: top + margin, width, height });
                        break;
                    case 'top_center':
                        bbox = new bbox_1.BBox({ hcenter, top: top + margin, width, height });
                        break;
                    case 'top_right':
                        bbox = new bbox_1.BBox({ right: right - margin, top: top + margin, width, height });
                        break;
                    case 'bottom_right':
                        bbox = new bbox_1.BBox({ right: right - margin, bottom: bottom - margin, width, height });
                        break;
                    case 'bottom_center':
                        bbox = new bbox_1.BBox({ hcenter, bottom: bottom - margin, width, height });
                        break;
                    case 'bottom_left':
                        bbox = new bbox_1.BBox({ left: left + margin, bottom: bottom - margin, width, height });
                        break;
                    case 'center_left':
                        bbox = new bbox_1.BBox({ left: left + margin, vcenter, width, height });
                        break;
                    case 'center':
                        bbox = new bbox_1.BBox({ hcenter, vcenter, width, height });
                        break;
                    case 'center_right':
                        bbox = new bbox_1.BBox({ right: right - margin, vcenter, width, height });
                        break;
                    default:
                        throw new Error("unreachable");
                }
                layout.set_geometry(bbox);
            }
        }
    }
    exports.AnchorLayout = AnchorLayout;
    AnchorLayout.__name__ = "AnchorLayout";
},
/* core/layout/grid.js */ function _(require, module, exports) {
    const types_1 = require(181) /* ./types */;
    const layoutable_1 = require(182) /* ./layoutable */;
    const types_2 = require(7) /* ../util/types */;
    const bbox_1 = require(79) /* ../util/bbox */;
    const array_1 = require(8) /* ../util/array */;
    const { max, round } = Math;
    class DefaultMap {
        constructor(def) {
            this.def = def;
            this._map = new Map();
        }
        get(key) {
            let value = this._map.get(key);
            if (value === undefined) {
                value = this.def();
                this._map.set(key, value);
            }
            return value;
        }
        apply(key, fn) {
            const value = this.get(key);
            this._map.set(key, fn(value));
        }
    }
    DefaultMap.__name__ = "DefaultMap";
    class Container {
        constructor() {
            this._items = [];
            this._nrows = 0;
            this._ncols = 0;
        }
        get nrows() {
            return this._nrows;
        }
        get ncols() {
            return this._ncols;
        }
        add(span, data) {
            const { r1, c1 } = span;
            this._nrows = max(this._nrows, r1 + 1);
            this._ncols = max(this._ncols, c1 + 1);
            this._items.push({ span, data });
        }
        at(r, c) {
            const selected = this._items.filter(({ span }) => {
                return span.r0 <= r && r <= span.r1 &&
                    span.c0 <= c && c <= span.c1;
            });
            return selected.map(({ data }) => data);
        }
        row(r) {
            const selected = this._items.filter(({ span }) => span.r0 <= r && r <= span.r1);
            return selected.map(({ data }) => data);
        }
        col(c) {
            const selected = this._items.filter(({ span }) => span.c0 <= c && c <= span.c1);
            return selected.map(({ data }) => data);
        }
        foreach(fn) {
            for (const { span, data } of this._items) {
                fn(span, data);
            }
        }
        map(fn) {
            const result = new Container();
            for (const { span, data } of this._items) {
                result.add(span, fn(span, data));
            }
            return result;
        }
    }
    Container.__name__ = "Container";
    class Grid extends layoutable_1.Layoutable {
        constructor(items = []) {
            super();
            this.items = items;
            this.rows = "auto";
            this.cols = "auto";
            this.spacing = 0;
            this.absolute = false;
        }
        is_width_expanding() {
            if (super.is_width_expanding())
                return true;
            if (this.sizing.width_policy == "fixed")
                return false;
            const { cols } = this._state;
            return array_1.some(cols, (col) => col.policy == "max");
        }
        is_height_expanding() {
            if (super.is_height_expanding())
                return true;
            if (this.sizing.height_policy == "fixed")
                return false;
            const { rows } = this._state;
            return array_1.some(rows, (row) => row.policy == "max");
        }
        _init() {
            super._init();
            const items = new Container();
            for (const { layout, row, col, row_span, col_span } of this.items) {
                if (layout.sizing.visible) {
                    const r0 = row;
                    const c0 = col;
                    const r1 = row + (row_span != null ? row_span : 1) - 1;
                    const c1 = col + (col_span != null ? col_span : 1) - 1;
                    items.add({ r0, c0, r1, c1 }, layout);
                }
            }
            const { nrows, ncols } = items;
            const rows = new Array(nrows);
            for (let y = 0; y < nrows; y++) {
                const row = (() => {
                    const sizing = types_2.isPlainObject(this.rows) ? this.rows[y] || this.rows["*"] : this.rows;
                    if (sizing == null)
                        return { policy: "auto" };
                    else if (types_2.isNumber(sizing))
                        return { policy: "fixed", height: sizing };
                    else if (types_2.isString(sizing))
                        return { policy: sizing };
                    else
                        return sizing;
                })();
                const align = row.align || "auto";
                if (row.policy == "fixed")
                    rows[y] = { policy: "fixed", height: row.height, align };
                else if (row.policy == "min")
                    rows[y] = { policy: "min", align };
                else if (row.policy == "fit" || row.policy == "max")
                    rows[y] = { policy: row.policy, flex: row.flex || 1, align };
                else if (row.policy == "auto") {
                    if (array_1.some(items.row(y), (layout) => layout.is_height_expanding()))
                        rows[y] = { policy: "max", flex: 1, align };
                    else
                        rows[y] = { policy: "min", align };
                }
                else
                    throw new Error("unrechable");
            }
            const cols = new Array(ncols);
            for (let x = 0; x < ncols; x++) {
                const col = (() => {
                    const sizing = types_2.isPlainObject(this.cols) ? this.cols[x] || this.cols["*"] : this.cols;
                    if (sizing == null)
                        return { policy: "auto" };
                    else if (types_2.isNumber(sizing))
                        return { policy: "fixed", width: sizing };
                    else if (types_2.isString(sizing))
                        return { policy: sizing };
                    else
                        return sizing;
                })();
                const align = col.align || "auto";
                if (col.policy == "fixed")
                    cols[x] = { policy: "fixed", width: col.width, align };
                else if (col.policy == "min")
                    cols[x] = { policy: "min", align };
                else if (col.policy == "fit" || col.policy == "max")
                    cols[x] = { policy: col.policy, flex: col.flex || 1, align };
                else if (col.policy == "auto") {
                    if (array_1.some(items.col(x), (layout) => layout.is_width_expanding()))
                        cols[x] = { policy: "max", flex: 1, align };
                    else
                        cols[x] = { policy: "min", align };
                }
                else
                    throw new Error("unrechable");
            }
            const [rspacing, cspacing] = types_2.isNumber(this.spacing) ? [this.spacing, this.spacing] : this.spacing;
            this._state = { items, nrows, ncols, rows, cols, rspacing, cspacing };
        }
        _measure_totals(row_heights, col_widths) {
            const { nrows, ncols, rspacing, cspacing } = this._state;
            return {
                height: array_1.sum(row_heights) + (nrows - 1) * rspacing,
                width: array_1.sum(col_widths) + (ncols - 1) * cspacing,
            };
        }
        _measure_cells(cell_viewport) {
            const { items, nrows, ncols, rows, cols, rspacing, cspacing } = this._state;
            const row_heights = new Array(nrows);
            for (let r = 0; r < nrows; r++) {
                const row = rows[r];
                row_heights[r] = row.policy == "fixed" ? row.height : 0;
            }
            const col_widths = new Array(ncols);
            for (let c = 0; c < ncols; c++) {
                const col = cols[c];
                col_widths[c] = col.policy == "fixed" ? col.width : 0;
            }
            const size_hints = new Container();
            items.foreach((span, layout) => {
                const { r0, c0, r1, c1 } = span;
                const rspace = (r1 - r0) * rspacing;
                const cspace = (c1 - c0) * cspacing;
                let height = 0;
                for (let r = r0; r <= r1; r++) {
                    height += cell_viewport(r, c0).height;
                }
                height += rspace;
                let width = 0;
                for (let c = c0; c <= c1; c++) {
                    width += cell_viewport(r0, c).width;
                }
                width += cspace;
                const size_hint = layout.measure({ width, height });
                size_hints.add(span, { layout, size_hint });
                const size = new types_1.Sizeable(size_hint).grow_by(layout.sizing.margin);
                size.height -= rspace;
                size.width -= cspace;
                const radjustable = [];
                for (let r = r0; r <= r1; r++) {
                    const row = rows[r];
                    if (row.policy == "fixed")
                        size.height -= row.height;
                    else
                        radjustable.push(r);
                }
                if (size.height > 0) {
                    const rheight = round(size.height / radjustable.length);
                    for (const r of radjustable) {
                        row_heights[r] = max(row_heights[r], rheight);
                    }
                }
                const cadjustable = [];
                for (let c = c0; c <= c1; c++) {
                    const col = cols[c];
                    if (col.policy == "fixed")
                        size.width -= col.width;
                    else
                        cadjustable.push(c);
                }
                if (size.width > 0) {
                    const cwidth = round(size.width / cadjustable.length);
                    for (const c of cadjustable) {
                        col_widths[c] = max(col_widths[c], cwidth);
                    }
                }
            });
            const size = this._measure_totals(row_heights, col_widths);
            return { size, row_heights, col_widths, size_hints };
        }
        _measure_grid(viewport) {
            const { nrows, ncols, rows, cols, rspacing, cspacing } = this._state;
            const preferred = this._measure_cells((y, x) => {
                const row = rows[y];
                const col = cols[x];
                return {
                    width: col.policy == "fixed" ? col.width : Infinity,
                    height: row.policy == "fixed" ? row.height : Infinity,
                };
            });
            let available_height;
            if (this.sizing.height_policy == "fixed" && this.sizing.height != null)
                available_height = this.sizing.height;
            else if (viewport.height != Infinity && this.is_height_expanding())
                available_height = viewport.height;
            else
                available_height = preferred.size.height;
            let height_flex = 0;
            for (let y = 0; y < nrows; y++) {
                const row = rows[y];
                if (row.policy == "fit" || row.policy == "max")
                    height_flex += row.flex;
                else
                    available_height -= preferred.row_heights[y];
            }
            available_height -= (nrows - 1) * rspacing;
            if (height_flex != 0 && available_height > 0) {
                for (let y = 0; y < nrows; y++) {
                    const row = rows[y];
                    if (row.policy == "fit" || row.policy == "max") {
                        const height = round(available_height * (row.flex / height_flex));
                        available_height -= height;
                        preferred.row_heights[y] = height;
                        height_flex -= row.flex;
                    }
                }
            }
            else if (available_height < 0) {
                let nadjustable = 0;
                for (let y = 0; y < nrows; y++) {
                    const row = rows[y];
                    if (row.policy != "fixed")
                        nadjustable++;
                }
                let overflow_height = -available_height;
                for (let y = 0; y < nrows; y++) {
                    const row = rows[y];
                    if (row.policy != "fixed") {
                        const height = preferred.row_heights[y];
                        const cutoff = round(overflow_height / nadjustable);
                        preferred.row_heights[y] = max(height - cutoff, 0);
                        overflow_height -= cutoff > height ? height : cutoff;
                        nadjustable--;
                    }
                }
            }
            let available_width;
            if (this.sizing.width_policy == "fixed" && this.sizing.width != null)
                available_width = this.sizing.width;
            else if (viewport.width != Infinity && this.is_width_expanding())
                available_width = viewport.width;
            else
                available_width = preferred.size.width;
            let width_flex = 0;
            for (let x = 0; x < ncols; x++) {
                const col = cols[x];
                if (col.policy == "fit" || col.policy == "max")
                    width_flex += col.flex;
                else
                    available_width -= preferred.col_widths[x];
            }
            available_width -= (ncols - 1) * cspacing;
            if (width_flex != 0 && available_width > 0) {
                for (let x = 0; x < ncols; x++) {
                    const col = cols[x];
                    if (col.policy == "fit" || col.policy == "max") {
                        const width = round(available_width * (col.flex / width_flex));
                        available_width -= width;
                        preferred.col_widths[x] = width;
                        width_flex -= col.flex;
                    }
                }
            }
            else if (available_width < 0) {
                let nadjustable = 0;
                for (let x = 0; x < ncols; x++) {
                    const col = cols[x];
                    if (col.policy != "fixed")
                        nadjustable++;
                }
                let overflow_width = -available_width;
                for (let x = 0; x < ncols; x++) {
                    const col = cols[x];
                    if (col.policy != "fixed") {
                        const width = preferred.col_widths[x];
                        const cutoff = round(overflow_width / nadjustable);
                        preferred.col_widths[x] = max(width - cutoff, 0);
                        overflow_width -= cutoff > width ? width : cutoff;
                        nadjustable--;
                    }
                }
            }
            const { row_heights, col_widths, size_hints } = this._measure_cells((y, x) => {
                return {
                    width: preferred.col_widths[x],
                    height: preferred.row_heights[y],
                };
            });
            const size = this._measure_totals(row_heights, col_widths);
            return { size, row_heights, col_widths, size_hints };
        }
        _measure(viewport) {
            const { size } = this._measure_grid(viewport);
            return size;
        }
        _set_geometry(outer, inner) {
            super._set_geometry(outer, inner);
            const { nrows, ncols, rspacing, cspacing } = this._state;
            const { row_heights, col_widths, size_hints } = this._measure_grid(outer);
            const rows = this._state.rows.map((row, r) => {
                return Object.assign(Object.assign({}, row), { top: 0, height: row_heights[r], get bottom() { return this.top + this.height; } });
            });
            const cols = this._state.cols.map((col, c) => {
                return Object.assign(Object.assign({}, col), { left: 0, width: col_widths[c], get right() { return this.left + this.width; } });
            });
            const items = size_hints.map((_, item) => {
                return Object.assign(Object.assign({}, item), { outer: new bbox_1.BBox(), inner: new bbox_1.BBox() });
            });
            for (let r = 0, top = !this.absolute ? 0 : outer.top; r < nrows; r++) {
                const row = rows[r];
                row.top = top;
                top += row.height + rspacing;
            }
            for (let c = 0, left = !this.absolute ? 0 : outer.left; c < ncols; c++) {
                const col = cols[c];
                col.left = left;
                left += col.width + cspacing;
            }
            function span_width(c0, c1) {
                let width = (c1 - c0) * cspacing;
                for (let c = c0; c <= c1; c++) {
                    width += cols[c].width;
                }
                return width;
            }
            function span_height(r0, r1) {
                let height = (r1 - r0) * rspacing;
                for (let r = r0; r <= r1; r++) {
                    height += rows[r].height;
                }
                return height;
            }
            items.foreach(({ r0, c0, r1, c1 }, item) => {
                const { layout, size_hint } = item;
                const { sizing } = layout;
                const { width, height } = size_hint;
                const span = {
                    width: span_width(c0, c1),
                    height: span_height(r0, r1),
                };
                const halign = c0 == c1 && cols[c0].align != "auto" ? cols[c0].align : sizing.halign;
                const valign = r0 == r1 && rows[r0].align != "auto" ? rows[r0].align : sizing.valign;
                let left = cols[c0].left;
                if (halign == "start")
                    left += sizing.margin.left;
                else if (halign == "center")
                    left += round((span.width - width) / 2);
                else if (halign == "end")
                    left += span.width - sizing.margin.right - width;
                let top = rows[r0].top;
                if (valign == "start")
                    top += sizing.margin.top;
                else if (valign == "center")
                    top += round((span.height - height) / 2);
                else if (valign == "end")
                    top += span.height - sizing.margin.bottom - height;
                item.outer = new bbox_1.BBox({ left, top, width, height });
            });
            const row_aligns = rows.map(() => {
                return {
                    start: new DefaultMap(() => 0),
                    end: new DefaultMap(() => 0),
                };
            });
            const col_aligns = cols.map(() => {
                return {
                    start: new DefaultMap(() => 0),
                    end: new DefaultMap(() => 0),
                };
            });
            items.foreach(({ r0, c0, r1, c1 }, { size_hint, outer }) => {
                const { inner } = size_hint;
                if (inner != null) {
                    row_aligns[r0].start.apply(outer.top, (v) => max(v, inner.top));
                    row_aligns[r1].end.apply(rows[r1].bottom - outer.bottom, (v) => max(v, inner.bottom));
                    col_aligns[c0].start.apply(outer.left, (v) => max(v, inner.left));
                    col_aligns[c1].end.apply(cols[c1].right - outer.right, (v) => max(v, inner.right));
                }
            });
            items.foreach(({ r0, c0, r1, c1 }, item) => {
                const { size_hint, outer } = item;
                function inner_bbox({ left, right, top, bottom }) {
                    const width = outer.width - left - right;
                    const height = outer.height - top - bottom;
                    return new bbox_1.BBox({ left, top, width, height });
                }
                if (size_hint.inner != null) {
                    let inner = inner_bbox(size_hint.inner);
                    if (size_hint.align !== false) {
                        const top = row_aligns[r0].start.get(outer.top);
                        const bottom = row_aligns[r1].end.get(rows[r1].bottom - outer.bottom);
                        const left = col_aligns[c0].start.get(outer.left);
                        const right = col_aligns[c1].end.get(cols[c1].right - outer.right);
                        try {
                            inner = inner_bbox({ top, bottom, left, right });
                        }
                        catch (_a) { }
                    }
                    item.inner = inner;
                }
                else
                    item.inner = outer;
            });
            items.foreach((_, { layout, outer, inner }) => {
                layout.set_geometry(outer, inner);
            });
        }
    }
    exports.Grid = Grid;
    Grid.__name__ = "Grid";
    class Row extends Grid {
        constructor(items) {
            super();
            this.items = items.map((item, i) => ({ layout: item, row: 0, col: i }));
            this.rows = "fit";
        }
    }
    exports.Row = Row;
    Row.__name__ = "Row";
    class Column extends Grid {
        constructor(items) {
            super();
            this.items = items.map((item, i) => ({ layout: item, row: i, col: 0 }));
            this.cols = "fit";
        }
    }
    exports.Column = Column;
    Column.__name__ = "Column";
},
/* core/layout/html.js */ function _(require, module, exports) {
    const layoutable_1 = require(182) /* ./layoutable */;
    const types_1 = require(181) /* ./types */;
    const dom_1 = require(61) /* ../dom */;
    class ContentBox extends layoutable_1.ContentLayoutable {
        constructor(el) {
            super();
            this.content_size = dom_1.unsized(el, () => new types_1.Sizeable(dom_1.size(el)));
        }
        _content_size() {
            return this.content_size;
        }
    }
    exports.ContentBox = ContentBox;
    ContentBox.__name__ = "ContentBox";
    class VariadicBox extends layoutable_1.Layoutable {
        constructor(el) {
            super();
            this.el = el;
        }
        _measure(viewport) {
            const bounded = new types_1.Sizeable(viewport).bounded_to(this.sizing.size);
            return dom_1.sized(this.el, bounded, () => {
                const content = new types_1.Sizeable(dom_1.content_size(this.el));
                const { border, padding } = dom_1.extents(this.el);
                return content.grow_by(border).grow_by(padding).map(Math.ceil);
            });
        }
    }
    exports.VariadicBox = VariadicBox;
    VariadicBox.__name__ = "VariadicBox";
},
/* models/expressions/index.js */ function _(require, module, exports) {
    var expression_1 = require(187) /* ./expression */;
    exports.Expression = expression_1.Expression;
    var stack_1 = require(188) /* ./stack */;
    exports.Stack = stack_1.Stack;
    var cumsum_1 = require(189) /* ./cumsum */;
    exports.CumSum = cumsum_1.CumSum;
},
/* models/expressions/expression.js */ function _(require, module, exports) {
    const model_1 = require(64) /* ../../model */;
    class Expression extends model_1.Model {
        constructor(attrs) {
            super(attrs);
            this._connected = {};
            this._result = {};
        }
        initialize() {
            super.initialize();
            this._connected = {};
            this._result = {};
        }
        v_compute(source) {
            if (this._connected[source.id] == null) {
                this.connect(source.change, () => delete this._result[source.id]);
                this.connect(source.patching, () => delete this._result[source.id]);
                this.connect(source.streaming, () => delete this._result[source.id]);
                this._connected[source.id] = true;
            }
            let result = this._result[source.id];
            if (result == null)
                this._result[source.id] = result = this._v_compute(source);
            return result;
        }
    }
    exports.Expression = Expression;
    Expression.__name__ = "Expression";
},
/* models/expressions/stack.js */ function _(require, module, exports) {
    const expression_1 = require(187) /* ./expression */;
    const p = require(18) /* ../../core/properties */;
    class Stack extends expression_1.Expression {
        constructor(attrs) {
            super(attrs);
        }
        static init_Stack() {
            this.define({
                fields: [p.Array, []],
            });
        }
        _v_compute(source) {
            const n = source.get_length() || 0; // TODO: use ?? in TS 3.7
            const result = new Float64Array(n);
            for (const f of this.fields) {
                const column = source.data[f];
                if (column != null) {
                    for (let i = 0, k = Math.min(n, column.length); i < k; i++) {
                        result[i] += column[i];
                    }
                }
            }
            return result;
        }
    }
    exports.Stack = Stack;
    Stack.__name__ = "Stack";
    Stack.init_Stack();
},
/* models/expressions/cumsum.js */ function _(require, module, exports) {
    const expression_1 = require(187) /* ./expression */;
    const p = require(18) /* ../../core/properties */;
    class CumSum extends expression_1.Expression {
        constructor(attrs) {
            super(attrs);
        }
        static init_CumSum() {
            this.define({
                field: [p.String],
                include_zero: [p.Boolean, false],
            });
        }
        _v_compute(source) {
            const result = new Float64Array(source.get_length() || 0);
            const col = source.data[this.field];
            const offset = this.include_zero ? 1 : 0;
            result[0] = this.include_zero ? 0 : col[0];
            for (let i = 1; i < result.length; i++) {
                result[i] = result[i - 1] + col[i - offset];
            }
            return result;
        }
    }
    exports.CumSum = CumSum;
    CumSum.__name__ = "CumSum";
    CumSum.init_CumSum();
},
/* models/filters/index.js */ function _(require, module, exports) {
    var boolean_filter_1 = require(191) /* ./boolean_filter */;
    exports.BooleanFilter = boolean_filter_1.BooleanFilter;
    var customjs_filter_1 = require(193) /* ./customjs_filter */;
    exports.CustomJSFilter = customjs_filter_1.CustomJSFilter;
    var filter_1 = require(192) /* ./filter */;
    exports.Filter = filter_1.Filter;
    var group_filter_1 = require(194) /* ./group_filter */;
    exports.GroupFilter = group_filter_1.GroupFilter;
    var index_filter_1 = require(195) /* ./index_filter */;
    exports.IndexFilter = index_filter_1.IndexFilter;
},
/* models/filters/boolean_filter.js */ function _(require, module, exports) {
    const filter_1 = require(192) /* ./filter */;
    const p = require(18) /* ../../core/properties */;
    const logging_1 = require(65) /* ../../core/logging */;
    const array_1 = require(8) /* ../../core/util/array */;
    const types_1 = require(7) /* ../../core/util/types */;
    class BooleanFilter extends filter_1.Filter {
        constructor(attrs) {
            super(attrs);
        }
        static init_BooleanFilter() {
            this.define({
                booleans: [p.Array, null],
            });
        }
        compute_indices(source) {
            const booleans = this.booleans;
            if (booleans != null && booleans.length > 0) {
                if (array_1.every(booleans, types_1.isBoolean)) {
                    if (booleans.length !== source.get_length()) {
                        logging_1.logger.warn(`BooleanFilter ${this.id}: length of booleans doesn't match data source`);
                    }
                    return array_1.range(0, booleans.length).filter((i) => booleans[i] === true);
                }
                else {
                    logging_1.logger.warn(`BooleanFilter ${this.id}: booleans should be array of booleans, defaulting to no filtering`);
                    return null;
                }
            }
            else {
                if (booleans != null && booleans.length == 0)
                    logging_1.logger.warn(`BooleanFilter ${this.id}: booleans is empty, defaulting to no filtering`);
                else
                    logging_1.logger.warn(`BooleanFilter ${this.id}: booleans was not set, defaulting to no filtering`);
                return null;
            }
        }
    }
    exports.BooleanFilter = BooleanFilter;
    BooleanFilter.__name__ = "BooleanFilter";
    BooleanFilter.init_BooleanFilter();
},
/* models/filters/filter.js */ function _(require, module, exports) {
    const model_1 = require(64) /* ../../model */;
    const p = require(18) /* ../../core/properties */;
    const types_1 = require(7) /* ../../core/util/types */;
    const array_1 = require(8) /* ../../core/util/array */;
    const logging_1 = require(65) /* ../../core/logging */;
    class Filter extends model_1.Model {
        constructor(attrs) {
            super(attrs);
        }
        static init_Filter() {
            this.define({
                filter: [p.Array, null],
            });
        }
        compute_indices(_source) {
            const filter = this.filter;
            if (filter != null && filter.length >= 0) {
                if (types_1.isArrayOf(filter, types_1.isBoolean)) {
                    return array_1.range(0, filter.length).filter((i) => filter[i] === true);
                }
                if (types_1.isArrayOf(filter, types_1.isInteger)) {
                    return filter;
                }
                logging_1.logger.warn(`Filter ${this.id}: filter should either be array of only booleans or only integers, defaulting to no filtering`);
                return null;
            }
            else {
                logging_1.logger.warn(`Filter ${this.id}: filter was not set to be an array, defaulting to no filtering`);
                return null;
            }
        }
    }
    exports.Filter = Filter;
    Filter.__name__ = "Filter";
    Filter.init_Filter();
},
/* models/filters/customjs_filter.js */ function _(require, module, exports) {
    const filter_1 = require(192) /* ./filter */;
    const p = require(18) /* ../../core/properties */;
    const object_1 = require(22) /* ../../core/util/object */;
    const string_1 = require(25) /* ../../core/util/string */;
    class CustomJSFilter extends filter_1.Filter {
        constructor(attrs) {
            super(attrs);
        }
        static init_CustomJSFilter() {
            this.define({
                args: [p.Any, {}],
                code: [p.String, ''],
                use_strict: [p.Boolean, false],
            });
        }
        get names() {
            return object_1.keys(this.args);
        }
        get values() {
            return object_1.values(this.args);
        }
        get func() {
            const code = this.use_strict ? string_1.use_strict(this.code) : this.code;
            return new Function(...this.names, "source", "require", "exports", code);
        }
        compute_indices(source) {
            this.filter = this.func(...this.values, source, require, {});
            return super.compute_indices(source);
        }
    }
    exports.CustomJSFilter = CustomJSFilter;
    CustomJSFilter.__name__ = "CustomJSFilter";
    CustomJSFilter.init_CustomJSFilter();
},
/* models/filters/group_filter.js */ function _(require, module, exports) {
    const filter_1 = require(192) /* ./filter */;
    const p = require(18) /* ../../core/properties */;
    const logging_1 = require(65) /* ../../core/logging */;
    const array_1 = require(8) /* ../../core/util/array */;
    class GroupFilter extends filter_1.Filter {
        constructor(attrs) {
            super(attrs);
            this.indices = null;
        }
        static init_GroupFilter() {
            this.define({
                column_name: [p.String],
                group: [p.String],
            });
        }
        compute_indices(source) {
            const column = source.get_column(this.column_name);
            if (column == null) {
                logging_1.logger.warn("group filter: groupby column not found in data source");
                return null;
            }
            else {
                this.indices = array_1.range(0, source.get_length() || 0).filter((i) => column[i] === this.group);
                if (this.indices.length === 0) {
                    logging_1.logger.warn(`group filter: group '${this.group}' did not match any values in column '${this.column_name}'`);
                }
                return this.indices;
            }
        }
    }
    exports.GroupFilter = GroupFilter;
    GroupFilter.__name__ = "GroupFilter";
    GroupFilter.init_GroupFilter();
},
/* models/filters/index_filter.js */ function _(require, module, exports) {
    const filter_1 = require(192) /* ./filter */;
    const p = require(18) /* ../../core/properties */;
    const logging_1 = require(65) /* ../../core/logging */;
    const types_1 = require(7) /* ../../core/util/types */;
    const array_1 = require(8) /* ../../core/util/array */;
    class IndexFilter extends filter_1.Filter {
        constructor(attrs) {
            super(attrs);
        }
        static init_IndexFilter() {
            this.define({
                indices: [p.Array, null],
            });
        }
        compute_indices(_source) {
            if (this.indices != null && this.indices.length >= 0) {
                if (array_1.every(this.indices, types_1.isInteger))
                    return this.indices;
                else {
                    logging_1.logger.warn(`IndexFilter ${this.id}: indices should be array of integers, defaulting to no filtering`);
                    return null;
                }
            }
            else {
                logging_1.logger.warn(`IndexFilter ${this.id}: indices was not set, defaulting to no filtering`);
                return null;
            }
        }
    }
    exports.IndexFilter = IndexFilter;
    IndexFilter.__name__ = "IndexFilter";
    IndexFilter.init_IndexFilter();
},
/* models/formatters/index.js */ function _(require, module, exports) {
    var basic_tick_formatter_1 = require(106) /* ./basic_tick_formatter */;
    exports.BasicTickFormatter = basic_tick_formatter_1.BasicTickFormatter;
    var categorical_tick_formatter_1 = require(145) /* ./categorical_tick_formatter */;
    exports.CategoricalTickFormatter = categorical_tick_formatter_1.CategoricalTickFormatter;
    var datetime_tick_formatter_1 = require(149) /* ./datetime_tick_formatter */;
    exports.DatetimeTickFormatter = datetime_tick_formatter_1.DatetimeTickFormatter;
    var func_tick_formatter_1 = require(197) /* ./func_tick_formatter */;
    exports.FuncTickFormatter = func_tick_formatter_1.FuncTickFormatter;
    var log_tick_formatter_1 = require(162) /* ./log_tick_formatter */;
    exports.LogTickFormatter = log_tick_formatter_1.LogTickFormatter;
    var mercator_tick_formatter_1 = require(165) /* ./mercator_tick_formatter */;
    exports.MercatorTickFormatter = mercator_tick_formatter_1.MercatorTickFormatter;
    var numeral_tick_formatter_1 = require(198) /* ./numeral_tick_formatter */;
    exports.NumeralTickFormatter = numeral_tick_formatter_1.NumeralTickFormatter;
    var printf_tick_formatter_1 = require(199) /* ./printf_tick_formatter */;
    exports.PrintfTickFormatter = printf_tick_formatter_1.PrintfTickFormatter;
    var tick_formatter_1 = require(107) /* ./tick_formatter */;
    exports.TickFormatter = tick_formatter_1.TickFormatter;
},
/* models/formatters/func_tick_formatter.js */ function _(require, module, exports) {
    const tick_formatter_1 = require(107) /* ./tick_formatter */;
    const p = require(18) /* ../../core/properties */;
    const object_1 = require(22) /* ../../core/util/object */;
    const string_1 = require(25) /* ../../core/util/string */;
    class FuncTickFormatter extends tick_formatter_1.TickFormatter {
        constructor(attrs) {
            super(attrs);
        }
        static init_FuncTickFormatter() {
            this.define({
                args: [p.Any, {}],
                code: [p.String, ''],
                use_strict: [p.Boolean, false],
            });
        }
        get names() {
            return object_1.keys(this.args);
        }
        get values() {
            return object_1.values(this.args);
        }
        /*protected*/ _make_func() {
            const code = this.use_strict ? string_1.use_strict(this.code) : this.code;
            return new Function("tick", "index", "ticks", ...this.names, "require", "exports", code);
        }
        doFormat(ticks, _opts) {
            const cache = {};
            const func = this._make_func().bind(cache);
            return ticks.map((tick, index, ticks) => func(tick, index, ticks, ...this.values, require, {}));
        }
    }
    exports.FuncTickFormatter = FuncTickFormatter;
    FuncTickFormatter.__name__ = "FuncTickFormatter";
    FuncTickFormatter.init_FuncTickFormatter();
},
/* models/formatters/numeral_tick_formatter.js */ function _(require, module, exports) {
    const Numbro = require(153) /* numbro */;
    const tick_formatter_1 = require(107) /* ./tick_formatter */;
    const p = require(18) /* ../../core/properties */;
    class NumeralTickFormatter extends tick_formatter_1.TickFormatter {
        constructor(attrs) {
            super(attrs);
        }
        static init_NumeralTickFormatter() {
            this.define({
                // TODO (bev) all of these could be tightened up
                format: [p.String, '0,0'],
                language: [p.String, 'en'],
                rounding: [p.RoundingFunction, 'round'],
            });
        }
        get _rounding_fn() {
            switch (this.rounding) {
                case "round":
                case "nearest":
                    return Math.round;
                case "floor":
                case "rounddown":
                    return Math.floor;
                case "ceil":
                case "roundup":
                    return Math.ceil;
            }
        }
        doFormat(ticks, _opts) {
            const { format, language, _rounding_fn } = this;
            return ticks.map((tick) => Numbro.format(tick, format, language, _rounding_fn));
        }
    }
    exports.NumeralTickFormatter = NumeralTickFormatter;
    NumeralTickFormatter.__name__ = "NumeralTickFormatter";
    NumeralTickFormatter.init_NumeralTickFormatter();
},
/* models/formatters/printf_tick_formatter.js */ function _(require, module, exports) {
    const tick_formatter_1 = require(107) /* ./tick_formatter */;
    const templating_1 = require(151) /* ../../core/util/templating */;
    const p = require(18) /* ../../core/properties */;
    class PrintfTickFormatter extends tick_formatter_1.TickFormatter {
        constructor(attrs) {
            super(attrs);
        }
        static init_PrintfTickFormatter() {
            this.define({
                format: [p.String, '%s'],
            });
        }
        doFormat(ticks, _opts) {
            return ticks.map((tick) => templating_1.sprintf(this.format, tick));
        }
    }
    exports.PrintfTickFormatter = PrintfTickFormatter;
    PrintfTickFormatter.__name__ = "PrintfTickFormatter";
    PrintfTickFormatter.init_PrintfTickFormatter();
},
/* models/glyphs/index.js */ function _(require, module, exports) {
    var annular_wedge_1 = require(201) /* ./annular_wedge */;
    exports.AnnularWedge = annular_wedge_1.AnnularWedge;
    var annulus_1 = require(202) /* ./annulus */;
    exports.Annulus = annulus_1.Annulus;
    var arc_1 = require(203) /* ./arc */;
    exports.Arc = arc_1.Arc;
    var bezier_1 = require(204) /* ./bezier */;
    exports.Bezier = bezier_1.Bezier;
    var circle_1 = require(205) /* ./circle */;
    exports.Circle = circle_1.Circle;
    var center_rotatable_1 = require(206) /* ./center_rotatable */;
    exports.CenterRotatable = center_rotatable_1.CenterRotatable;
    var ellipse_1 = require(207) /* ./ellipse */;
    exports.Ellipse = ellipse_1.Ellipse;
    var ellipse_oval_1 = require(208) /* ./ellipse_oval */;
    exports.EllipseOval = ellipse_oval_1.EllipseOval;
    var glyph_1 = require(80) /* ./glyph */;
    exports.Glyph = glyph_1.Glyph;
    var harea_1 = require(86) /* ./harea */;
    exports.HArea = harea_1.HArea;
    var hbar_1 = require(209) /* ./hbar */;
    exports.HBar = hbar_1.HBar;
    var hex_tile_1 = require(211) /* ./hex_tile */;
    exports.HexTile = hex_tile_1.HexTile;
    var image_1 = require(212) /* ./image */;
    exports.Image = image_1.Image;
    var image_rgba_1 = require(214) /* ./image_rgba */;
    exports.ImageRGBA = image_rgba_1.ImageRGBA;
    var image_url_1 = require(215) /* ./image_url */;
    exports.ImageURL = image_url_1.ImageURL;
    var line_1 = require(75) /* ./line */;
    exports.Line = line_1.Line;
    var multi_line_1 = require(217) /* ./multi_line */;
    exports.MultiLine = multi_line_1.MultiLine;
    var multi_polygons_1 = require(218) /* ./multi_polygons */;
    exports.MultiPolygons = multi_polygons_1.MultiPolygons;
    var oval_1 = require(219) /* ./oval */;
    exports.Oval = oval_1.Oval;
    var patch_1 = require(85) /* ./patch */;
    exports.Patch = patch_1.Patch;
    var patches_1 = require(220) /* ./patches */;
    exports.Patches = patches_1.Patches;
    var quad_1 = require(221) /* ./quad */;
    exports.Quad = quad_1.Quad;
    var quadratic_1 = require(222) /* ./quadratic */;
    exports.Quadratic = quadratic_1.Quadratic;
    var ray_1 = require(223) /* ./ray */;
    exports.Ray = ray_1.Ray;
    var rect_1 = require(224) /* ./rect */;
    exports.Rect = rect_1.Rect;
    var segment_1 = require(225) /* ./segment */;
    exports.Segment = segment_1.Segment;
    var step_1 = require(226) /* ./step */;
    exports.Step = step_1.Step;
    var text_1 = require(227) /* ./text */;
    exports.Text = text_1.Text;
    var varea_1 = require(88) /* ./varea */;
    exports.VArea = varea_1.VArea;
    var vbar_1 = require(228) /* ./vbar */;
    exports.VBar = vbar_1.VBar;
    var wedge_1 = require(229) /* ./wedge */;
    exports.Wedge = wedge_1.Wedge;
    var xy_glyph_1 = require(76) /* ./xy_glyph */;
    exports.XYGlyph = xy_glyph_1.XYGlyph;
},
/* models/glyphs/annular_wedge.js */ function _(require, module, exports) {
    const xy_glyph_1 = require(76) /* ./xy_glyph */;
    const utils_1 = require(84) /* ./utils */;
    const hittest = require(81) /* ../../core/hittest */;
    const p = require(18) /* ../../core/properties */;
    const math_1 = require(9) /* ../../core/util/math */;
    class AnnularWedgeView extends xy_glyph_1.XYGlyphView {
        _map_data() {
            if (this.model.properties.inner_radius.units == "data")
                this.sinner_radius = this.sdist(this.renderer.xscale, this._x, this._inner_radius);
            else
                this.sinner_radius = this._inner_radius;
            if (this.model.properties.outer_radius.units == "data")
                this.souter_radius = this.sdist(this.renderer.xscale, this._x, this._outer_radius);
            else
                this.souter_radius = this._outer_radius;
            this._angle = new Float32Array(this._start_angle.length);
            for (let i = 0, end = this._start_angle.length; i < end; i++) {
                this._angle[i] = this._end_angle[i] - this._start_angle[i];
            }
        }
        _render(ctx, indices, { sx, sy, _start_angle, _angle, sinner_radius, souter_radius }) {
            const direction = this.model.properties.direction.value();
            for (const i of indices) {
                if (isNaN(sx[i] + sy[i] + sinner_radius[i] + souter_radius[i] + _start_angle[i] + _angle[i]))
                    continue;
                ctx.translate(sx[i], sy[i]);
                ctx.rotate(_start_angle[i]);
                ctx.moveTo(souter_radius[i], 0);
                ctx.beginPath();
                ctx.arc(0, 0, souter_radius[i], 0, _angle[i], direction);
                ctx.rotate(_angle[i]);
                ctx.lineTo(sinner_radius[i], 0);
                ctx.arc(0, 0, sinner_radius[i], 0, -_angle[i], !direction);
                ctx.closePath();
                ctx.rotate(-_angle[i] - _start_angle[i]);
                ctx.translate(-sx[i], -sy[i]);
                if (this.visuals.fill.doit) {
                    this.visuals.fill.set_vectorize(ctx, i);
                    ctx.fill();
                }
                if (this.visuals.line.doit) {
                    this.visuals.line.set_vectorize(ctx, i);
                    ctx.stroke();
                }
            }
        }
        _hit_point(geometry) {
            const { sx, sy } = geometry;
            const x = this.renderer.xscale.invert(sx);
            const y = this.renderer.yscale.invert(sy);
            // check radius first
            let x0, y0;
            let x1, y1;
            if (this.model.properties.outer_radius.units == "data") {
                x0 = x - this.max_outer_radius;
                x1 = x + this.max_outer_radius;
                y0 = y - this.max_outer_radius;
                y1 = y + this.max_outer_radius;
            }
            else {
                const sx0 = sx - this.max_outer_radius;
                const sx1 = sx + this.max_outer_radius;
                [x0, x1] = this.renderer.xscale.r_invert(sx0, sx1);
                const sy0 = sy - this.max_outer_radius;
                const sy1 = sy + this.max_outer_radius;
                [y0, y1] = this.renderer.yscale.r_invert(sy0, sy1);
            }
            const candidates = [];
            for (const i of this.index.indices({ x0, x1, y0, y1 })) {
                const or2 = Math.pow(this.souter_radius[i], 2);
                const ir2 = Math.pow(this.sinner_radius[i], 2);
                const [sx0, sx1] = this.renderer.xscale.r_compute(x, this._x[i]);
                const [sy0, sy1] = this.renderer.yscale.r_compute(y, this._y[i]);
                const dist = Math.pow(sx0 - sx1, 2) + Math.pow(sy0 - sy1, 2);
                if (dist <= or2 && dist >= ir2)
                    candidates.push([i, dist]);
            }
            const direction = this.model.properties.direction.value();
            const hits = [];
            for (const [i, dist] of candidates) {
                // NOTE: minus the angle because JS uses non-mathy convention for angles
                const angle = Math.atan2(sy - this.sy[i], sx - this.sx[i]);
                if (math_1.angle_between(-angle, -this._start_angle[i], -this._end_angle[i], direction)) {
                    hits.push([i, dist]);
                }
            }
            return hittest.create_hit_test_result_from_hits(hits);
        }
        draw_legend_for_index(ctx, bbox, index) {
            utils_1.generic_area_legend(this.visuals, ctx, bbox, index);
        }
        _scenterxy(i) {
            const r = (this.sinner_radius[i] + this.souter_radius[i]) / 2;
            const a = (this._start_angle[i] + this._end_angle[i]) / 2;
            return { x: this.sx[i] + (r * Math.cos(a)), y: this.sy[i] + (r * Math.sin(a)) };
        }
        scenterx(i) {
            return this._scenterxy(i).x;
        }
        scentery(i) {
            return this._scenterxy(i).y;
        }
    }
    exports.AnnularWedgeView = AnnularWedgeView;
    AnnularWedgeView.__name__ = "AnnularWedgeView";
    class AnnularWedge extends xy_glyph_1.XYGlyph {
        constructor(attrs) {
            super(attrs);
        }
        static init_AnnularWedge() {
            this.prototype.default_view = AnnularWedgeView;
            this.mixins(['line', 'fill']);
            this.define({
                direction: [p.Direction, 'anticlock'],
                inner_radius: [p.DistanceSpec],
                outer_radius: [p.DistanceSpec],
                start_angle: [p.AngleSpec],
                end_angle: [p.AngleSpec],
            });
        }
    }
    exports.AnnularWedge = AnnularWedge;
    AnnularWedge.__name__ = "AnnularWedge";
    AnnularWedge.init_AnnularWedge();
},
/* models/glyphs/annulus.js */ function _(require, module, exports) {
    const xy_glyph_1 = require(76) /* ./xy_glyph */;
    const hittest = require(81) /* ../../core/hittest */;
    const p = require(18) /* ../../core/properties */;
    const compat_1 = require(95) /* ../../core/util/compat */;
    class AnnulusView extends xy_glyph_1.XYGlyphView {
        _map_data() {
            if (this.model.properties.inner_radius.units == "data")
                this.sinner_radius = this.sdist(this.renderer.xscale, this._x, this._inner_radius);
            else
                this.sinner_radius = this._inner_radius;
            if (this.model.properties.outer_radius.units == "data")
                this.souter_radius = this.sdist(this.renderer.xscale, this._x, this._outer_radius);
            else
                this.souter_radius = this._outer_radius;
        }
        _render(ctx, indices, { sx, sy, sinner_radius, souter_radius }) {
            for (const i of indices) {
                if (isNaN(sx[i] + sy[i] + sinner_radius[i] + souter_radius[i]))
                    continue;
                // Because this visual has a whole in it, it proved "challenging"
                // for some browsers to render if drawn in one go --- i.e. it did not
                // work on IE. If we render in two parts (upper and lower part),
                // it is unambiguous what part should be filled. The line is
                // better drawn in one go though, otherwise the part where the pieces
                // meet will not be fully closed due to aa.
                if (this.visuals.fill.doit) {
                    this.visuals.fill.set_vectorize(ctx, i);
                    ctx.beginPath();
                    if (compat_1.is_ie) {
                        // Draw two halves of the donut. Works on IE, but causes an aa line on Safari.
                        for (const clockwise of [false, true]) {
                            ctx.arc(sx[i], sy[i], sinner_radius[i], 0, Math.PI, clockwise);
                            ctx.arc(sx[i], sy[i], souter_radius[i], Math.PI, 0, !clockwise);
                        }
                    }
                    else {
                        // Draw donut in one go. Does not work on iE.
                        ctx.arc(sx[i], sy[i], sinner_radius[i], 0, 2 * Math.PI, true);
                        ctx.arc(sx[i], sy[i], souter_radius[i], 2 * Math.PI, 0, false);
                    }
                    ctx.fill();
                }
                if (this.visuals.line.doit) {
                    this.visuals.line.set_vectorize(ctx, i);
                    ctx.beginPath();
                    ctx.arc(sx[i], sy[i], sinner_radius[i], 0, 2 * Math.PI);
                    ctx.moveTo(sx[i] + souter_radius[i], sy[i]);
                    ctx.arc(sx[i], sy[i], souter_radius[i], 0, 2 * Math.PI);
                    ctx.stroke();
                }
            }
        }
        _hit_point(geometry) {
            const { sx, sy } = geometry;
            const x = this.renderer.xscale.invert(sx);
            const y = this.renderer.yscale.invert(sy);
            let x0, y0;
            let x1, y1;
            if (this.model.properties.outer_radius.units == "data") {
                x0 = x - this.max_outer_radius;
                x1 = x + this.max_outer_radius;
                y0 = y - this.max_outer_radius;
                y1 = y + this.max_outer_radius;
            }
            else {
                const sx0 = sx - this.max_outer_radius;
                const sx1 = sx + this.max_outer_radius;
                [x0, x1] = this.renderer.xscale.r_invert(sx0, sx1);
                const sy0 = sy - this.max_outer_radius;
                const sy1 = sy + this.max_outer_radius;
                [y0, y1] = this.renderer.yscale.r_invert(sy0, sy1);
            }
            const hits = [];
            for (const i of this.index.indices({ x0, x1, y0, y1 })) {
                const or2 = Math.pow(this.souter_radius[i], 2);
                const ir2 = Math.pow(this.sinner_radius[i], 2);
                const [sx0, sx1] = this.renderer.xscale.r_compute(x, this._x[i]);
                const [sy0, sy1] = this.renderer.yscale.r_compute(y, this._y[i]);
                const dist = Math.pow(sx0 - sx1, 2) + Math.pow(sy0 - sy1, 2);
                if (dist <= or2 && dist >= ir2)
                    hits.push([i, dist]);
            }
            return hittest.create_hit_test_result_from_hits(hits);
        }
        draw_legend_for_index(ctx, { x0, y0, x1, y1 }, index) {
            const len = index + 1;
            const sx = new Array(len);
            sx[index] = (x0 + x1) / 2;
            const sy = new Array(len);
            sy[index] = (y0 + y1) / 2;
            const r = Math.min(Math.abs(x1 - x0), Math.abs(y1 - y0)) * 0.5;
            const sinner_radius = new Array(len);
            sinner_radius[index] = r * 0.4;
            const souter_radius = new Array(len);
            souter_radius[index] = r * 0.8;
            this._render(ctx, [index], { sx, sy, sinner_radius, souter_radius }); // XXX
        }
    }
    exports.AnnulusView = AnnulusView;
    AnnulusView.__name__ = "AnnulusView";
    class Annulus extends xy_glyph_1.XYGlyph {
        constructor(attrs) {
            super(attrs);
        }
        static init_Annulus() {
            this.prototype.default_view = AnnulusView;
            this.mixins(['line', 'fill']);
            this.define({
                inner_radius: [p.DistanceSpec],
                outer_radius: [p.DistanceSpec],
            });
        }
    }
    exports.Annulus = Annulus;
    Annulus.__name__ = "Annulus";
    Annulus.init_Annulus();
},
/* models/glyphs/arc.js */ function _(require, module, exports) {
    const xy_glyph_1 = require(76) /* ./xy_glyph */;
    const utils_1 = require(84) /* ./utils */;
    const p = require(18) /* ../../core/properties */;
    class ArcView extends xy_glyph_1.XYGlyphView {
        _map_data() {
            if (this.model.properties.radius.units == "data")
                this.sradius = this.sdist(this.renderer.xscale, this._x, this._radius);
            else
                this.sradius = this._radius;
        }
        _render(ctx, indices, { sx, sy, sradius, _start_angle, _end_angle }) {
            if (this.visuals.line.doit) {
                const direction = this.model.properties.direction.value();
                for (const i of indices) {
                    if (isNaN(sx[i] + sy[i] + sradius[i] + _start_angle[i] + _end_angle[i]))
                        continue;
                    ctx.beginPath();
                    ctx.arc(sx[i], sy[i], sradius[i], _start_angle[i], _end_angle[i], direction);
                    this.visuals.line.set_vectorize(ctx, i);
                    ctx.stroke();
                }
            }
        }
        draw_legend_for_index(ctx, bbox, index) {
            utils_1.generic_line_legend(this.visuals, ctx, bbox, index);
        }
    }
    exports.ArcView = ArcView;
    ArcView.__name__ = "ArcView";
    class Arc extends xy_glyph_1.XYGlyph {
        constructor(attrs) {
            super(attrs);
        }
        static init_Arc() {
            this.prototype.default_view = ArcView;
            this.mixins(['line']);
            this.define({
                direction: [p.Direction, 'anticlock'],
                radius: [p.DistanceSpec],
                start_angle: [p.AngleSpec],
                end_angle: [p.AngleSpec],
            });
        }
    }
    exports.Arc = Arc;
    Arc.__name__ = "Arc";
    Arc.init_Arc();
},
/* models/glyphs/bezier.js */ function _(require, module, exports) {
    const spatial_1 = require(77) /* ../../core/util/spatial */;
    const glyph_1 = require(80) /* ./glyph */;
    const utils_1 = require(84) /* ./utils */;
    // algorithm adapted from http://stackoverflow.com/a/14429749/3406693
    function _cbb(x0, y0, x1, y1, x2, y2, x3, y3) {
        const tvalues = [];
        const bounds = [[], []];
        for (let i = 0; i <= 2; i++) {
            let a, b, c;
            if (i === 0) {
                b = ((6 * x0) - (12 * x1)) + (6 * x2);
                a = (((-3 * x0) + (9 * x1)) - (9 * x2)) + (3 * x3);
                c = (3 * x1) - (3 * x0);
            }
            else {
                b = ((6 * y0) - (12 * y1)) + (6 * y2);
                a = (((-3 * y0) + (9 * y1)) - (9 * y2)) + (3 * y3);
                c = (3 * y1) - (3 * y0);
            }
            if (Math.abs(a) < 1e-12) { // Numerical robustness
                if (Math.abs(b) < 1e-12) // Numerical robustness
                    continue;
                const t = -c / b;
                if (0 < t && t < 1)
                    tvalues.push(t);
                continue;
            }
            const b2ac = (b * b) - (4 * c * a);
            const sqrtb2ac = Math.sqrt(b2ac);
            if (b2ac < 0)
                continue;
            const t1 = (-b + sqrtb2ac) / (2 * a);
            if (0 < t1 && t1 < 1)
                tvalues.push(t1);
            const t2 = (-b - sqrtb2ac) / (2 * a);
            if (0 < t2 && t2 < 1)
                tvalues.push(t2);
        }
        let j = tvalues.length;
        const jlen = j;
        while (j--) {
            const t = tvalues[j];
            const mt = 1 - t;
            const x = (mt * mt * mt * x0) + (3 * mt * mt * t * x1) + (3 * mt * t * t * x2) + (t * t * t * x3);
            bounds[0][j] = x;
            const y = (mt * mt * mt * y0) + (3 * mt * mt * t * y1) + (3 * mt * t * t * y2) + (t * t * t * y3);
            bounds[1][j] = y;
        }
        bounds[0][jlen] = x0;
        bounds[1][jlen] = y0;
        bounds[0][jlen + 1] = x3;
        bounds[1][jlen + 1] = y3;
        return [
            Math.min(...bounds[0]),
            Math.max(...bounds[1]),
            Math.max(...bounds[0]),
            Math.min(...bounds[1]),
        ];
    }
    class BezierView extends glyph_1.GlyphView {
        _index_data() {
            const points = [];
            for (let i = 0, end = this._x0.length; i < end; i++) {
                if (isNaN(this._x0[i] + this._x1[i] + this._y0[i] + this._y1[i] + this._cx0[i] + this._cy0[i] + this._cx1[i] + this._cy1[i]))
                    continue;
                const [x0, y0, x1, y1] = _cbb(this._x0[i], this._y0[i], this._x1[i], this._y1[i], this._cx0[i], this._cy0[i], this._cx1[i], this._cy1[i]);
                points.push({ x0, y0, x1, y1, i });
            }
            return new spatial_1.SpatialIndex(points);
        }
        _render(ctx, indices, { sx0, sy0, sx1, sy1, scx0, scy0, scx1, scy1 }) {
            if (this.visuals.line.doit) {
                for (const i of indices) {
                    if (isNaN(sx0[i] + sy0[i] + sx1[i] + sy1[i] + scx0[i] + scy0[i] + scx1[i] + scy1[i]))
                        continue;
                    ctx.beginPath();
                    ctx.moveTo(sx0[i], sy0[i]);
                    ctx.bezierCurveTo(scx0[i], scy0[i], scx1[i], scy1[i], sx1[i], sy1[i]);
                    this.visuals.line.set_vectorize(ctx, i);
                    ctx.stroke();
                }
            }
        }
        draw_legend_for_index(ctx, bbox, index) {
            utils_1.generic_line_legend(this.visuals, ctx, bbox, index);
        }
        scenterx() {
            throw new Error("not implemented");
        }
        scentery() {
            throw new Error("not implemented");
        }
    }
    exports.BezierView = BezierView;
    BezierView.__name__ = "BezierView";
    class Bezier extends glyph_1.Glyph {
        constructor(attrs) {
            super(attrs);
        }
        static init_Bezier() {
            this.prototype.default_view = BezierView;
            this.coords([['x0', 'y0'], ['x1', 'y1'], ['cx0', 'cy0'], ['cx1', 'cy1']]);
            this.mixins(['line']);
        }
    }
    exports.Bezier = Bezier;
    Bezier.__name__ = "Bezier";
    Bezier.init_Bezier();
},
/* models/glyphs/circle.js */ function _(require, module, exports) {
    const xy_glyph_1 = require(76) /* ./xy_glyph */;
    const hittest = require(81) /* ../../core/hittest */;
    const p = require(18) /* ../../core/properties */;
    const array_1 = require(8) /* ../../core/util/array */;
    const arrayable_1 = require(11) /* ../../core/util/arrayable */;
    class CircleView extends xy_glyph_1.XYGlyphView {
        _map_data() {
            // XXX: Order is important here: size is always present (at least
            // a default), but radius is only present if a user specifies it.
            if (this._radius != null) {
                if (this.model.properties.radius.spec.units == "data") {
                    const rd = this.model.properties.radius_dimension.spec.value;
                    switch (rd) {
                        case "x": {
                            this.sradius = this.sdist(this.renderer.xscale, this._x, this._radius);
                            break;
                        }
                        case "y": {
                            this.sradius = this.sdist(this.renderer.yscale, this._y, this._radius);
                            break;
                        }
                        case "max": {
                            const sradius_x = this.sdist(this.renderer.xscale, this._x, this._radius);
                            const sradius_y = this.sdist(this.renderer.yscale, this._y, this._radius);
                            this.sradius = arrayable_1.map(sradius_x, (s, i) => Math.max(s, sradius_y[i]));
                            break;
                        }
                        case "min": {
                            const sradius_x = this.sdist(this.renderer.xscale, this._x, this._radius);
                            const sradius_y = this.sdist(this.renderer.yscale, this._y, this._radius);
                            this.sradius = arrayable_1.map(sradius_x, (s, i) => Math.min(s, sradius_y[i]));
                            break;
                        }
                    }
                }
                else {
                    this.sradius = this._radius;
                    this.max_size = 2 * this.max_radius;
                }
            }
            else
                this.sradius = arrayable_1.map(this._size, (s) => s / 2);
        }
        _mask_data() {
            const [hr, vr] = this.renderer.plot_view.frame.bbox.ranges;
            let x0, y0;
            let x1, y1;
            if (this._radius != null && this.model.properties.radius.units == "data") {
                const sx0 = hr.start;
                const sx1 = hr.end;
                [x0, x1] = this.renderer.xscale.r_invert(sx0, sx1);
                x0 -= this.max_radius;
                x1 += this.max_radius;
                const sy0 = vr.start;
                const sy1 = vr.end;
                [y0, y1] = this.renderer.yscale.r_invert(sy0, sy1);
                y0 -= this.max_radius;
                y1 += this.max_radius;
            }
            else {
                const sx0 = hr.start - this.max_size;
                const sx1 = hr.end + this.max_size;
                [x0, x1] = this.renderer.xscale.r_invert(sx0, sx1);
                const sy0 = vr.start - this.max_size;
                const sy1 = vr.end + this.max_size;
                [y0, y1] = this.renderer.yscale.r_invert(sy0, sy1);
            }
            return this.index.indices({ x0, x1, y0, y1 });
        }
        _render(ctx, indices, { sx, sy, sradius }) {
            for (const i of indices) {
                if (isNaN(sx[i] + sy[i] + sradius[i]))
                    continue;
                ctx.beginPath();
                ctx.arc(sx[i], sy[i], sradius[i], 0, 2 * Math.PI, false);
                if (this.visuals.fill.doit) {
                    this.visuals.fill.set_vectorize(ctx, i);
                    ctx.fill();
                }
                if (this.visuals.line.doit) {
                    this.visuals.line.set_vectorize(ctx, i);
                    ctx.stroke();
                }
            }
        }
        _hit_point(geometry) {
            let dist, r2, sx0, sx1, sy0, sy1, x0, x1, y0, y1;
            const { sx, sy } = geometry;
            const x = this.renderer.xscale.invert(sx);
            const y = this.renderer.yscale.invert(sy);
            // check radius first
            if ((this._radius != null) && (this.model.properties.radius.units == "data")) {
                x0 = x - this.max_radius;
                x1 = x + this.max_radius;
                y0 = y - this.max_radius;
                y1 = y + this.max_radius;
            }
            else {
                sx0 = sx - this.max_size;
                sx1 = sx + this.max_size;
                [x0, x1] = this.renderer.xscale.r_invert(sx0, sx1);
                [x0, x1] = [Math.min(x0, x1), Math.max(x0, x1)];
                sy0 = sy - this.max_size;
                sy1 = sy + this.max_size;
                [y0, y1] = this.renderer.yscale.r_invert(sy0, sy1);
                [y0, y1] = [Math.min(y0, y1), Math.max(y0, y1)];
            }
            const candidates = this.index.indices({ x0, x1, y0, y1 });
            const hits = [];
            if ((this._radius != null) && (this.model.properties.radius.units == "data")) {
                for (const i of candidates) {
                    r2 = Math.pow(this.sradius[i], 2);
                    [sx0, sx1] = this.renderer.xscale.r_compute(x, this._x[i]);
                    [sy0, sy1] = this.renderer.yscale.r_compute(y, this._y[i]);
                    dist = Math.pow(sx0 - sx1, 2) + Math.pow(sy0 - sy1, 2);
                    if (dist <= r2) {
                        hits.push([i, dist]);
                    }
                }
            }
            else {
                for (const i of candidates) {
                    r2 = Math.pow(this.sradius[i], 2);
                    dist = Math.pow(this.sx[i] - sx, 2) + Math.pow(this.sy[i] - sy, 2);
                    if (dist <= r2) {
                        hits.push([i, dist]);
                    }
                }
            }
            return hittest.create_hit_test_result_from_hits(hits);
        }
        _hit_span(geometry) {
            const { sx, sy } = geometry;
            const bounds = this.bounds();
            const result = hittest.create_empty_hit_test_result();
            let x0, x1, y0, y1;
            if (geometry.direction == 'h') {
                // use circle bounds instead of current pointer y coordinates
                let sx0, sx1;
                y0 = bounds.y0;
                y1 = bounds.y1;
                if (this._radius != null && this.model.properties.radius.units == "data") {
                    sx0 = sx - this.max_radius;
                    sx1 = sx + this.max_radius;
                    [x0, x1] = this.renderer.xscale.r_invert(sx0, sx1);
                }
                else {
                    const ms = this.max_size / 2;
                    sx0 = sx - ms;
                    sx1 = sx + ms;
                    [x0, x1] = this.renderer.xscale.r_invert(sx0, sx1);
                }
            }
            else {
                // use circle bounds instead of current pointer x coordinates
                let sy0, sy1;
                x0 = bounds.x0;
                x1 = bounds.x1;
                if (this._radius != null && this.model.properties.radius.units == "data") {
                    sy0 = sy - this.max_radius;
                    sy1 = sy + this.max_radius;
                    [y0, y1] = this.renderer.yscale.r_invert(sy0, sy1);
                }
                else {
                    const ms = this.max_size / 2;
                    sy0 = sy - ms;
                    sy1 = sy + ms;
                    [y0, y1] = this.renderer.yscale.r_invert(sy0, sy1);
                }
            }
            const hits = this.index.indices({ x0, x1, y0, y1 });
            result.indices = hits;
            return result;
        }
        _hit_rect(geometry) {
            const { sx0, sx1, sy0, sy1 } = geometry;
            const [x0, x1] = this.renderer.xscale.r_invert(sx0, sx1);
            const [y0, y1] = this.renderer.yscale.r_invert(sy0, sy1);
            const result = hittest.create_empty_hit_test_result();
            result.indices = this.index.indices({ x0, x1, y0, y1 });
            return result;
        }
        _hit_poly(geometry) {
            const { sx, sy } = geometry;
            // TODO (bev) use spatial index to pare candidate list
            const candidates = array_1.range(0, this.sx.length);
            const hits = [];
            for (let i = 0, end = candidates.length; i < end; i++) {
                const idx = candidates[i];
                if (hittest.point_in_poly(this.sx[i], this.sy[i], sx, sy)) {
                    hits.push(idx);
                }
            }
            const result = hittest.create_empty_hit_test_result();
            result.indices = hits;
            return result;
        }
        // circle does not inherit from marker (since it also accepts radius) so we
        // must supply a draw_legend for it  here
        draw_legend_for_index(ctx, { x0, y0, x1, y1 }, index) {
            // using objects like this seems a little wonky, since the keys are coerced to
            // stings, but it works
            const len = index + 1;
            const sx = new Array(len);
            sx[index] = (x0 + x1) / 2;
            const sy = new Array(len);
            sy[index] = (y0 + y1) / 2;
            const sradius = new Array(len);
            sradius[index] = Math.min(Math.abs(x1 - x0), Math.abs(y1 - y0)) * 0.2;
            this._render(ctx, [index], { sx, sy, sradius }); // XXX
        }
    }
    exports.CircleView = CircleView;
    CircleView.__name__ = "CircleView";
    class Circle extends xy_glyph_1.XYGlyph {
        constructor(attrs) {
            super(attrs);
        }
        static init_Circle() {
            this.prototype.default_view = CircleView;
            this.mixins(['line', 'fill']);
            this.define({
                angle: [p.AngleSpec, 0],
                size: [p.DistanceSpec, { units: "screen", value: 4 }],
                radius: [p.DistanceSpec],
                radius_dimension: [p.RadiusDimension, 'x'],
            });
        }
        initialize() {
            super.initialize();
            this.properties.radius.optional = true;
        }
    }
    exports.Circle = Circle;
    Circle.__name__ = "Circle";
    Circle.init_Circle();
},
/* models/glyphs/center_rotatable.js */ function _(require, module, exports) {
    const xy_glyph_1 = require(76) /* ./xy_glyph */;
    const p = require(18) /* ../../core/properties */;
    class CenterRotatableView extends xy_glyph_1.XYGlyphView {
    }
    exports.CenterRotatableView = CenterRotatableView;
    CenterRotatableView.__name__ = "CenterRotatableView";
    class CenterRotatable extends xy_glyph_1.XYGlyph {
        constructor(attrs) {
            super(attrs);
        }
        static init_CenterRotatable() {
            this.mixins(['line', 'fill']);
            this.define({
                angle: [p.AngleSpec, 0],
                width: [p.DistanceSpec],
                height: [p.DistanceSpec],
            });
        }
    }
    exports.CenterRotatable = CenterRotatable;
    CenterRotatable.__name__ = "CenterRotatable";
    CenterRotatable.init_CenterRotatable();
},
/* models/glyphs/ellipse.js */ function _(require, module, exports) {
    const ellipse_oval_1 = require(208) /* ./ellipse_oval */;
    class EllipseView extends ellipse_oval_1.EllipseOvalView {
    }
    exports.EllipseView = EllipseView;
    EllipseView.__name__ = "EllipseView";
    class Ellipse extends ellipse_oval_1.EllipseOval {
        constructor(attrs) {
            super(attrs);
        }
        static init_Ellipse() {
            this.prototype.default_view = EllipseView;
        }
    }
    exports.Ellipse = Ellipse;
    Ellipse.__name__ = "Ellipse";
    Ellipse.init_Ellipse();
},
/* models/glyphs/ellipse_oval.js */ function _(require, module, exports) {
    const center_rotatable_1 = require(206) /* ./center_rotatable */;
    const hittest = require(81) /* ../../core/hittest */;
    class EllipseOvalView extends center_rotatable_1.CenterRotatableView {
        _set_data() {
            this.max_w2 = 0;
            if (this.model.properties.width.units == "data")
                this.max_w2 = this.max_width / 2;
            this.max_h2 = 0;
            if (this.model.properties.height.units == "data")
                this.max_h2 = this.max_height / 2;
        }
        _map_data() {
            if (this.model.properties.width.units == "data")
                this.sw = this.sdist(this.renderer.xscale, this._x, this._width, 'center');
            else
                this.sw = this._width;
            if (this.model.properties.height.units == "data")
                this.sh = this.sdist(this.renderer.yscale, this._y, this._height, 'center');
            else
                this.sh = this._height;
        }
        _render(ctx, indices, { sx, sy, sw, sh, _angle }) {
            for (const i of indices) {
                if (isNaN(sx[i] + sy[i] + sw[i] + sh[i] + _angle[i]))
                    continue;
                ctx.beginPath();
                ctx.ellipse(sx[i], sy[i], sw[i] / 2.0, sh[i] / 2.0, _angle[i], 0, 2 * Math.PI);
                if (this.visuals.fill.doit) {
                    this.visuals.fill.set_vectorize(ctx, i);
                    ctx.fill();
                }
                if (this.visuals.line.doit) {
                    this.visuals.line.set_vectorize(ctx, i);
                    ctx.stroke();
                }
            }
        }
        _hit_point(geometry) {
            let x0, x1, y0, y1, cond, dist, sx0, sx1, sy0, sy1;
            const { sx, sy } = geometry;
            const x = this.renderer.xscale.invert(sx);
            const y = this.renderer.yscale.invert(sy);
            if (this.model.properties.width.units == "data") {
                x0 = x - this.max_width;
                x1 = x + this.max_width;
            }
            else {
                sx0 = sx - this.max_width;
                sx1 = sx + this.max_width;
                [x0, x1] = this.renderer.xscale.r_invert(sx0, sx1);
            }
            if (this.model.properties.height.units == "data") {
                y0 = y - this.max_height;
                y1 = y + this.max_height;
            }
            else {
                sy0 = sy - this.max_height;
                sy1 = sy + this.max_height;
                [y0, y1] = this.renderer.yscale.r_invert(sy0, sy1);
            }
            const candidates = this.index.indices({ x0, x1, y0, y1 });
            const hits = [];
            for (const i of candidates) {
                cond = hittest.point_in_ellipse(sx, sy, this._angle[i], this.sh[i] / 2, this.sw[i] / 2, this.sx[i], this.sy[i]);
                if (cond) {
                    [sx0, sx1] = this.renderer.xscale.r_compute(x, this._x[i]);
                    [sy0, sy1] = this.renderer.yscale.r_compute(y, this._y[i]);
                    dist = Math.pow(sx0 - sx1, 2) + Math.pow(sy0 - sy1, 2);
                    hits.push([i, dist]);
                }
            }
            return hittest.create_hit_test_result_from_hits(hits);
        }
        draw_legend_for_index(ctx, { x0, y0, x1, y1 }, index) {
            const len = index + 1;
            const sx = new Array(len);
            sx[index] = (x0 + x1) / 2;
            const sy = new Array(len);
            sy[index] = (y0 + y1) / 2;
            const scale = this.sw[index] / this.sh[index];
            const d = Math.min(Math.abs(x1 - x0), Math.abs(y1 - y0)) * 0.8;
            const sw = new Array(len);
            const sh = new Array(len);
            if (scale > 1) {
                sw[index] = d;
                sh[index] = d / scale;
            }
            else {
                sw[index] = d * scale;
                sh[index] = d;
            }
            this._render(ctx, [index], { sx, sy, sw, sh, _angle: [0] }); // XXX
        }
        _bounds({ x0, x1, y0, y1 }) {
            return {
                x0: x0 - this.max_w2,
                x1: x1 + this.max_w2,
                y0: y0 - this.max_h2,
                y1: y1 + this.max_h2,
            };
        }
    }
    exports.EllipseOvalView = EllipseOvalView;
    EllipseOvalView.__name__ = "EllipseOvalView";
    class EllipseOval extends center_rotatable_1.CenterRotatable {
        constructor(attrs) {
            super(attrs);
        }
    }
    exports.EllipseOval = EllipseOval;
    EllipseOval.__name__ = "EllipseOval";
},
/* models/glyphs/hbar.js */ function _(require, module, exports) {
    const box_1 = require(210) /* ./box */;
    const p = require(18) /* ../../core/properties */;
    class HBarView extends box_1.BoxView {
        scenterx(i) {
            return (this.sleft[i] + this.sright[i]) / 2;
        }
        scentery(i) {
            return this.sy[i];
        }
        _index_data() {
            return this._index_box(this._y.length);
        }
        _lrtb(i) {
            const l = Math.min(this._left[i], this._right[i]);
            const r = Math.max(this._left[i], this._right[i]);
            const t = this._y[i] + 0.5 * this._height[i];
            const b = this._y[i] - 0.5 * this._height[i];
            return [l, r, t, b];
        }
        _map_data() {
            this.sy = this.renderer.yscale.v_compute(this._y);
            this.sh = this.sdist(this.renderer.yscale, this._y, this._height, "center");
            this.sleft = this.renderer.xscale.v_compute(this._left);
            this.sright = this.renderer.xscale.v_compute(this._right);
            const n = this.sy.length;
            this.stop = new Float64Array(n);
            this.sbottom = new Float64Array(n);
            for (let i = 0; i < n; i++) {
                this.stop[i] = this.sy[i] - this.sh[i] / 2;
                this.sbottom[i] = this.sy[i] + this.sh[i] / 2;
            }
            this._clamp_viewport();
        }
    }
    exports.HBarView = HBarView;
    HBarView.__name__ = "HBarView";
    class HBar extends box_1.Box {
        constructor(attrs) {
            super(attrs);
        }
        static init_HBar() {
            this.prototype.default_view = HBarView;
            this.coords([['left', 'y']]);
            this.define({
                height: [p.NumberSpec],
                right: [p.CoordinateSpec],
            });
            this.override({ left: 0 });
        }
    }
    exports.HBar = HBar;
    HBar.__name__ = "HBar";
    HBar.init_HBar();
},
/* models/glyphs/box.js */ function _(require, module, exports) {
    const spatial_1 = require(77) /* ../../core/util/spatial */;
    const glyph_1 = require(80) /* ./glyph */;
    const utils_1 = require(84) /* ./utils */;
    const hittest = require(81) /* ../../core/hittest */;
    class BoxView extends glyph_1.GlyphView {
        get_anchor_point(anchor, i, _spt) {
            const left = Math.min(this.sleft[i], this.sright[i]);
            const right = Math.max(this.sright[i], this.sleft[i]);
            const top = Math.min(this.stop[i], this.sbottom[i]); // screen coordinates !!!
            const bottom = Math.max(this.sbottom[i], this.stop[i]); //
            switch (anchor) {
                case "top_left": return { x: left, y: top };
                case "top_center": return { x: (left + right) / 2, y: top };
                case "top_right": return { x: right, y: top };
                case "bottom_left": return { x: left, y: bottom };
                case "bottom_center": return { x: (left + right) / 2, y: bottom };
                case "bottom_right": return { x: right, y: bottom };
                case "center_left": return { x: left, y: (top + bottom) / 2 };
                case "center": return { x: (left + right) / 2, y: (top + bottom) / 2 };
                case "center_right": return { x: right, y: (top + bottom) / 2 };
                default: return null;
            }
        }
        _index_box(len) {
            const points = [];
            for (let i = 0; i < len; i++) {
                const [l, r, t, b] = this._lrtb(i);
                if (isNaN(l + r + t + b) || !isFinite(l + r + t + b))
                    continue;
                points.push({
                    x0: Math.min(l, r),
                    y0: Math.min(t, b),
                    x1: Math.max(r, l),
                    y1: Math.max(t, b),
                    i,
                });
            }
            return new spatial_1.SpatialIndex(points);
        }
        _render(ctx, indices, { sleft, sright, stop, sbottom }) {
            for (const i of indices) {
                if (isNaN(sleft[i] + stop[i] + sright[i] + sbottom[i]))
                    continue;
                ctx.rect(sleft[i], stop[i], sright[i] - sleft[i], sbottom[i] - stop[i]);
                if (this.visuals.fill.doit) {
                    this.visuals.fill.set_vectorize(ctx, i);
                    ctx.beginPath();
                    ctx.rect(sleft[i], stop[i], sright[i] - sleft[i], sbottom[i] - stop[i]);
                    ctx.fill();
                }
                this.visuals.hatch.doit2(ctx, i, () => {
                    ctx.beginPath();
                    ctx.rect(sleft[i], stop[i], sright[i] - sleft[i], sbottom[i] - stop[i]);
                    ctx.fill();
                }, () => this.renderer.request_render());
                if (this.visuals.line.doit) {
                    this.visuals.line.set_vectorize(ctx, i);
                    ctx.beginPath();
                    ctx.rect(sleft[i], stop[i], sright[i] - sleft[i], sbottom[i] - stop[i]);
                    ctx.stroke();
                }
            }
        }
        // We need to clamp the endpoints inside the viewport, because various browser canvas
        // implementations have issues drawing rects with enpoints far outside the viewport
        _clamp_viewport() {
            const hr = this.renderer.plot_view.frame.bbox.h_range;
            const vr = this.renderer.plot_view.frame.bbox.v_range;
            const n = this.stop.length;
            for (let i = 0; i < n; i++) {
                this.stop[i] = Math.max(this.stop[i], vr.start);
                this.sbottom[i] = Math.min(this.sbottom[i], vr.end);
                this.sleft[i] = Math.max(this.sleft[i], hr.start);
                this.sright[i] = Math.min(this.sright[i], hr.end);
            }
        }
        _hit_rect(geometry) {
            return this._hit_rect_against_index(geometry);
        }
        _hit_point(geometry) {
            const { sx, sy } = geometry;
            const x = this.renderer.xscale.invert(sx);
            const y = this.renderer.yscale.invert(sy);
            const hits = this.index.indices({ x0: x, y0: y, x1: x, y1: y });
            const result = hittest.create_empty_hit_test_result();
            result.indices = hits;
            return result;
        }
        _hit_span(geometry) {
            const { sx, sy } = geometry;
            let hits;
            if (geometry.direction == 'v') {
                const y = this.renderer.yscale.invert(sy);
                const hr = this.renderer.plot_view.frame.bbox.h_range;
                const [x0, x1] = this.renderer.xscale.r_invert(hr.start, hr.end);
                hits = this.index.indices({ x0, y0: y, x1, y1: y });
            }
            else {
                const x = this.renderer.xscale.invert(sx);
                const vr = this.renderer.plot_view.frame.bbox.v_range;
                const [y0, y1] = this.renderer.yscale.r_invert(vr.start, vr.end);
                hits = this.index.indices({ x0: x, y0, x1: x, y1 });
            }
            const result = hittest.create_empty_hit_test_result();
            result.indices = hits;
            return result;
        }
        draw_legend_for_index(ctx, bbox, index) {
            utils_1.generic_area_legend(this.visuals, ctx, bbox, index);
        }
    }
    exports.BoxView = BoxView;
    BoxView.__name__ = "BoxView";
    class Box extends glyph_1.Glyph {
        constructor(attrs) {
            super(attrs);
        }
        static init_Box() {
            this.mixins(['line', 'fill', 'hatch']);
        }
    }
    exports.Box = Box;
    Box.__name__ = "Box";
    Box.init_Box();
},
/* models/glyphs/hex_tile.js */ function _(require, module, exports) {
    const glyph_1 = require(80) /* ./glyph */;
    const hittest = require(81) /* ../../core/hittest */;
    const p = require(18) /* ../../core/properties */;
    const spatial_1 = require(77) /* ../../core/util/spatial */;
    const utils_1 = require(84) /* ./utils */;
    class HexTileView extends glyph_1.GlyphView {
        scenterx(i) { return this.sx[i]; }
        scentery(i) { return this.sy[i]; }
        _set_data() {
            const n = this._q.length;
            const size = this.model.size;
            const aspect_scale = this.model.aspect_scale;
            this._x = new Float64Array(n);
            this._y = new Float64Array(n);
            if (this.model.orientation == "pointytop") {
                for (let i = 0; i < n; i++) {
                    this._x[i] = size * Math.sqrt(3) * (this._q[i] + this._r[i] / 2) / aspect_scale;
                    this._y[i] = -size * 3 / 2 * this._r[i];
                }
            }
            else {
                for (let i = 0; i < n; i++) {
                    this._x[i] = size * 3 / 2 * this._q[i];
                    this._y[i] = -size * Math.sqrt(3) * (this._r[i] + this._q[i] / 2) * aspect_scale;
                }
            }
        }
        _index_data() {
            let ysize = this.model.size;
            let xsize = Math.sqrt(3) * ysize / 2;
            if (this.model.orientation == "flattop") {
                [xsize, ysize] = [ysize, xsize];
                ysize *= this.model.aspect_scale;
            }
            else
                xsize /= this.model.aspect_scale;
            const points = [];
            for (let i = 0; i < this._x.length; i++) {
                const x = this._x[i];
                const y = this._y[i];
                if (isNaN(x + y) || !isFinite(x + y))
                    continue;
                points.push({ x0: x - xsize, y0: y - ysize, x1: x + xsize, y1: y + ysize, i });
            }
            return new spatial_1.SpatialIndex(points);
        }
        // overriding map_data instead of _map_data because the default automatic mappings
        // for other glyphs (with cartesian coordinates) is not useful
        map_data() {
            [this.sx, this.sy] = this.map_to_screen(this._x, this._y);
            [this.svx, this.svy] = this._get_unscaled_vertices();
        }
        _get_unscaled_vertices() {
            const size = this.model.size;
            const aspect_scale = this.model.aspect_scale;
            if (this.model.orientation == "pointytop") {
                const rscale = this.renderer.yscale;
                const hscale = this.renderer.xscale;
                const r = Math.abs(rscale.compute(0) - rscale.compute(size)); // assumes linear scale
                const h = Math.sqrt(3) / 2 * Math.abs(hscale.compute(0) - hscale.compute(size)) / aspect_scale; // assumes linear scale
                const r2 = r / 2.0;
                const svx = [0, -h, -h, 0, h, h];
                const svy = [r, r2, -r2, -r, -r2, r2];
                return [svx, svy];
            }
            else {
                const rscale = this.renderer.xscale;
                const hscale = this.renderer.yscale;
                const r = Math.abs(rscale.compute(0) - rscale.compute(size)); // assumes linear scale
                const h = Math.sqrt(3) / 2 * Math.abs(hscale.compute(0) - hscale.compute(size)) * aspect_scale; // assumes linear scale
                const r2 = r / 2.0;
                const svx = [r, r2, -r2, -r, -r2, r2];
                const svy = [0, -h, -h, 0, h, h];
                return [svx, svy];
            }
        }
        _render(ctx, indices, { sx, sy, svx, svy, _scale }) {
            for (const i of indices) {
                if (isNaN(sx[i] + sy[i] + _scale[i]))
                    continue;
                ctx.translate(sx[i], sy[i]);
                ctx.beginPath();
                for (let j = 0; j < 6; j++) {
                    ctx.lineTo(svx[j] * _scale[i], svy[j] * _scale[i]);
                }
                ctx.closePath();
                ctx.translate(-sx[i], -sy[i]);
                if (this.visuals.fill.doit) {
                    this.visuals.fill.set_vectorize(ctx, i);
                    ctx.fill();
                }
                if (this.visuals.line.doit) {
                    this.visuals.line.set_vectorize(ctx, i);
                    ctx.stroke();
                }
            }
        }
        _hit_point(geometry) {
            const { sx, sy } = geometry;
            const x = this.renderer.xscale.invert(sx);
            const y = this.renderer.yscale.invert(sy);
            const candidates = this.index.indices({ x0: x, y0: y, x1: x, y1: y });
            const hits = [];
            for (const i of candidates) {
                if (hittest.point_in_poly(sx - this.sx[i], sy - this.sy[i], this.svx, this.svy)) {
                    hits.push(i);
                }
            }
            const result = hittest.create_empty_hit_test_result();
            result.indices = hits;
            return result;
        }
        _hit_span(geometry) {
            const { sx, sy } = geometry;
            let hits;
            if (geometry.direction == 'v') {
                const y = this.renderer.yscale.invert(sy);
                const hr = this.renderer.plot_view.frame.bbox.h_range;
                const [x0, x1] = this.renderer.xscale.r_invert(hr.start, hr.end);
                hits = this.index.indices({ x0, y0: y, x1, y1: y });
            }
            else {
                const x = this.renderer.xscale.invert(sx);
                const vr = this.renderer.plot_view.frame.bbox.v_range;
                const [y0, y1] = this.renderer.yscale.r_invert(vr.start, vr.end);
                hits = this.index.indices({ x0: x, y0, x1: x, y1 });
            }
            const result = hittest.create_empty_hit_test_result();
            result.indices = hits;
            return result;
        }
        _hit_rect(geometry) {
            const { sx0, sx1, sy0, sy1 } = geometry;
            const [x0, x1] = this.renderer.xscale.r_invert(sx0, sx1);
            const [y0, y1] = this.renderer.yscale.r_invert(sy0, sy1);
            const result = hittest.create_empty_hit_test_result();
            result.indices = this.index.indices({ x0, x1, y0, y1 });
            return result;
        }
        draw_legend_for_index(ctx, bbox, index) {
            utils_1.generic_area_legend(this.visuals, ctx, bbox, index);
        }
    }
    exports.HexTileView = HexTileView;
    HexTileView.__name__ = "HexTileView";
    class HexTile extends glyph_1.Glyph {
        constructor(attrs) {
            super(attrs);
        }
        static init_HexTile() {
            this.prototype.default_view = HexTileView;
            this.coords([['r', 'q']]);
            this.mixins(['line', 'fill']);
            this.define({
                size: [p.Number, 1.0],
                aspect_scale: [p.Number, 1.0],
                scale: [p.NumberSpec, 1.0],
                orientation: [p.HexTileOrientation, "pointytop"],
            });
            this.override({ line_color: null });
        }
    }
    exports.HexTile = HexTile;
    HexTile.__name__ = "HexTile";
    HexTile.init_HexTile();
},
/* models/glyphs/image.js */ function _(require, module, exports) {
    const image_base_1 = require(213) /* ./image_base */;
    const linear_color_mapper_1 = require(108) /* ../mappers/linear_color_mapper */;
    const p = require(18) /* ../../core/properties */;
    const array_1 = require(8) /* ../../core/util/array */;
    class ImageView extends image_base_1.ImageBaseView {
        initialize() {
            super.initialize();
            this.connect(this.model.color_mapper.change, () => this._update_image());
            this.connect(this.model.properties.global_alpha.change, () => this.renderer.request_render());
        }
        _update_image() {
            // Only reset image_data if already initialized
            if (this.image_data != null) {
                this._set_data();
                this.renderer.plot_view.request_render();
            }
        }
        _set_data() {
            this._set_width_heigh_data();
            const cmap = this.model.color_mapper.rgba_mapper;
            for (let i = 0, end = this._image.length; i < end; i++) {
                let img;
                if (this._image_shape != null && this._image_shape[i].length > 0) {
                    img = this._image[i];
                    const shape = this._image_shape[i];
                    this._height[i] = shape[0];
                    this._width[i] = shape[1];
                }
                else {
                    const _image = this._image[i];
                    img = array_1.concat(_image);
                    this._height[i] = _image.length;
                    this._width[i] = _image[0].length;
                }
                const buf8 = cmap.v_compute(img);
                this._set_image_data_from_buffer(i, buf8);
            }
        }
        _render(ctx, indices, { image_data, sx, sy, sw, sh }) {
            const old_smoothing = ctx.getImageSmoothingEnabled();
            ctx.setImageSmoothingEnabled(false);
            ctx.globalAlpha = this.model.global_alpha;
            for (const i of indices) {
                if (image_data[i] == null)
                    continue;
                if (isNaN(sx[i] + sy[i] + sw[i] + sh[i]))
                    continue;
                const y_offset = sy[i];
                ctx.translate(0, y_offset);
                ctx.scale(1, -1);
                ctx.translate(0, -y_offset);
                ctx.drawImage(image_data[i], sx[i] | 0, sy[i] | 0, sw[i], sh[i]);
                ctx.translate(0, y_offset);
                ctx.scale(1, -1);
                ctx.translate(0, -y_offset);
            }
            ctx.setImageSmoothingEnabled(old_smoothing);
        }
    }
    exports.ImageView = ImageView;
    ImageView.__name__ = "ImageView";
    // NOTE: this needs to be redefined here, because palettes are located in bokeh-api.js bundle
    const Greys9 = () => ["#000000", "#252525", "#525252", "#737373", "#969696", "#bdbdbd", "#d9d9d9", "#f0f0f0", "#ffffff"];
    class Image extends image_base_1.ImageBase {
        constructor(attrs) {
            super(attrs);
        }
        static init_Image() {
            this.prototype.default_view = ImageView;
            this.define({
                color_mapper: [p.Instance, () => new linear_color_mapper_1.LinearColorMapper({ palette: Greys9() })],
            });
        }
    }
    exports.Image = Image;
    Image.__name__ = "Image";
    Image.init_Image();
},
/* models/glyphs/image_base.js */ function _(require, module, exports) {
    const xy_glyph_1 = require(76) /* ./xy_glyph */;
    const p = require(18) /* ../../core/properties */;
    const hittest = require(81) /* ../../core/hittest */;
    const spatial_1 = require(77) /* ../../core/util/spatial */;
    class ImageBaseView extends xy_glyph_1.XYGlyphView {
        _render(_ctx, _indices, _data) { }
        _index_data() {
            const points = [];
            for (let i = 0, end = this._x.length; i < end; i++) {
                const [l, r, t, b] = this._lrtb(i);
                if (isNaN(l + r + t + b) || !isFinite(l + r + t + b)) {
                    continue;
                }
                points.push({ x0: l, y0: b, x1: r, y1: t, i });
            }
            return new spatial_1.SpatialIndex(points);
        }
        _lrtb(i) {
            const xr = this.renderer.xscale.source_range;
            const x1 = this._x[i];
            const x2 = xr.is_reversed ? x1 - this._dw[i] : x1 + this._dw[i];
            const yr = this.renderer.yscale.source_range;
            const y1 = this._y[i];
            const y2 = yr.is_reversed ? y1 - this._dh[i] : y1 + this._dh[i];
            const [l, r] = x1 < x2 ? [x1, x2] : [x2, x1];
            const [b, t] = y1 < y2 ? [y1, y2] : [y2, y1];
            return [l, r, t, b];
        }
        _set_width_heigh_data() {
            if (this.image_data == null || this.image_data.length != this._image.length)
                this.image_data = new Array(this._image.length);
            if (this._width == null || this._width.length != this._image.length)
                this._width = new Array(this._image.length);
            if (this._height == null || this._height.length != this._image.length)
                this._height = new Array(this._image.length);
        }
        _get_or_create_canvas(i) {
            const _image_data = this.image_data[i];
            if (_image_data != null && _image_data.width == this._width[i] &&
                _image_data.height == this._height[i])
                return _image_data;
            else {
                const canvas = document.createElement('canvas');
                canvas.width = this._width[i];
                canvas.height = this._height[i];
                return canvas;
            }
        }
        _set_image_data_from_buffer(i, buf8) {
            const canvas = this._get_or_create_canvas(i);
            const ctx = canvas.getContext('2d');
            const image_data = ctx.getImageData(0, 0, this._width[i], this._height[i]);
            image_data.data.set(buf8);
            ctx.putImageData(image_data, 0, 0);
            this.image_data[i] = canvas;
        }
        _map_data() {
            switch (this.model.properties.dw.units) {
                case "data": {
                    this.sw = this.sdist(this.renderer.xscale, this._x, this._dw, 'edge', this.model.dilate);
                    break;
                }
                case "screen": {
                    this.sw = this._dw;
                    break;
                }
            }
            switch (this.model.properties.dh.units) {
                case "data": {
                    this.sh = this.sdist(this.renderer.yscale, this._y, this._dh, 'edge', this.model.dilate);
                    break;
                }
                case "screen": {
                    this.sh = this._dh;
                    break;
                }
            }
        }
        _image_index(index, x, y) {
            const [l, r, t, b] = this._lrtb(index);
            const width = this._width[index];
            const height = this._height[index];
            const dx = (r - l) / width;
            const dy = (t - b) / height;
            let dim1 = Math.floor((x - l) / dx);
            let dim2 = Math.floor((y - b) / dy);
            if (this.renderer.xscale.source_range.is_reversed)
                dim1 = width - dim1 - 1;
            if (this.renderer.yscale.source_range.is_reversed)
                dim2 = height - dim2 - 1;
            return { index, dim1, dim2, flat_index: dim2 * width + dim1 };
        }
        _hit_point(geometry) {
            const { sx, sy } = geometry;
            const x = this.renderer.xscale.invert(sx);
            const y = this.renderer.yscale.invert(sy);
            const candidates = this.index.indices({ x0: x, x1: x, y0: y, y1: y });
            const result = hittest.create_empty_hit_test_result();
            result.image_indices = [];
            for (const index of candidates) {
                if ((sx != Infinity) && (sy != Infinity)) {
                    result.image_indices.push(this._image_index(index, x, y));
                }
            }
            return result;
        }
    }
    exports.ImageBaseView = ImageBaseView;
    ImageBaseView.__name__ = "ImageBaseView";
    class ImageBase extends xy_glyph_1.XYGlyph {
        constructor(attrs) {
            super(attrs);
        }
        static init_ImageBase() {
            this.prototype.default_view = ImageBaseView;
            this.define({
                image: [p.NumberSpec],
                dw: [p.DistanceSpec],
                dh: [p.DistanceSpec],
                dilate: [p.Boolean, false],
                global_alpha: [p.Number, 1.0],
            });
        }
    }
    exports.ImageBase = ImageBase;
    ImageBase.__name__ = "ImageBase";
    ImageBase.init_ImageBase();
},
/* models/glyphs/image_rgba.js */ function _(require, module, exports) {
    const image_base_1 = require(213) /* ./image_base */;
    const array_1 = require(8) /* ../../core/util/array */;
    class ImageRGBAView extends image_base_1.ImageBaseView {
        initialize() {
            super.initialize();
            this.connect(this.model.properties.global_alpha.change, () => this.renderer.request_render());
        }
        _set_data(indices) {
            this._set_width_heigh_data();
            for (let i = 0, end = this._image.length; i < end; i++) {
                if (indices != null && indices.indexOf(i) < 0)
                    continue;
                let buf;
                if (this._image_shape != null && this._image_shape[i].length > 0) {
                    buf = this._image[i].buffer;
                    const shape = this._image_shape[i];
                    this._height[i] = shape[0];
                    this._width[i] = shape[1];
                }
                else {
                    const _image = this._image[i];
                    const flat = array_1.concat(_image);
                    buf = new ArrayBuffer(flat.length * 4);
                    const color = new Uint32Array(buf);
                    for (let j = 0, endj = flat.length; j < endj; j++) {
                        color[j] = flat[j];
                    }
                    this._height[i] = _image.length;
                    this._width[i] = _image[0].length;
                }
                const buf8 = new Uint8Array(buf);
                this._set_image_data_from_buffer(i, buf8);
            }
        }
        _render(ctx, indices, { image_data, sx, sy, sw, sh }) {
            const old_smoothing = ctx.getImageSmoothingEnabled();
            ctx.setImageSmoothingEnabled(false);
            ctx.globalAlpha = this.model.global_alpha;
            for (const i of indices) {
                if (isNaN(sx[i] + sy[i] + sw[i] + sh[i]))
                    continue;
                const y_offset = sy[i];
                ctx.translate(0, y_offset);
                ctx.scale(1, -1);
                ctx.translate(0, -y_offset);
                ctx.drawImage(image_data[i], sx[i] | 0, sy[i] | 0, sw[i], sh[i]);
                ctx.translate(0, y_offset);
                ctx.scale(1, -1);
                ctx.translate(0, -y_offset);
            }
            ctx.setImageSmoothingEnabled(old_smoothing);
        }
    }
    exports.ImageRGBAView = ImageRGBAView;
    ImageRGBAView.__name__ = "ImageRGBAView";
    class ImageRGBA extends image_base_1.ImageBase {
        constructor(attrs) {
            super(attrs);
        }
        static init_ImageRGBA() {
            this.prototype.default_view = ImageRGBAView;
        }
    }
    exports.ImageRGBA = ImageRGBA;
    ImageRGBA.__name__ = "ImageRGBA";
    ImageRGBA.init_ImageRGBA();
},
/* models/glyphs/image_url.js */ function _(require, module, exports) {
    const xy_glyph_1 = require(76) /* ./xy_glyph */;
    const p = require(18) /* ../../core/properties */;
    const arrayable_1 = require(11) /* ../../core/util/arrayable */;
    const spatial_1 = require(77) /* ../../core/util/spatial */;
    const image_1 = require(216) /* ../../core/util/image */;
    class ImageURLView extends xy_glyph_1.XYGlyphView {
        constructor() {
            super(...arguments);
            this._images_rendered = false;
        }
        initialize() {
            super.initialize();
            this.connect(this.model.properties.global_alpha.change, () => this.renderer.request_render());
        }
        _index_data() {
            return new spatial_1.SpatialIndex([]);
        }
        _set_data() {
            if (this.image == null || this.image.length != this._url.length)
                this.image = arrayable_1.map(this._url, () => null);
            const { retry_attempts, retry_timeout } = this.model;
            for (let i = 0, end = this._url.length; i < end; i++) {
                const url = this._url[i];
                if (url == null || url == "")
                    continue;
                new image_1.ImageLoader(url, {
                    loaded: (image) => {
                        this.image[i] = image;
                        this.renderer.request_render();
                    },
                    attempts: retry_attempts + 1,
                    timeout: retry_timeout,
                });
            }
            const w_data = this.model.properties.w.units == "data";
            const h_data = this.model.properties.h.units == "data";
            const n = this._x.length;
            const xs = new Array(w_data ? 2 * n : n);
            const ys = new Array(h_data ? 2 * n : n);
            for (let i = 0; i < n; i++) {
                xs[i] = this._x[i];
                ys[i] = this._y[i];
            }
            // if the width/height are in screen units, don't try to include them in bounds
            if (w_data) {
                for (let i = 0; i < n; i++)
                    xs[n + i] = this._x[i] + this._w[i];
            }
            if (h_data) {
                for (let i = 0; i < n; i++)
                    ys[n + i] = this._y[i] + this._h[i];
            }
            const x0 = arrayable_1.min(xs);
            const x1 = arrayable_1.max(xs);
            const y0 = arrayable_1.min(ys);
            const y1 = arrayable_1.max(ys);
            this._bounds_rect = { x0, x1, y0, y1 };
        }
        has_finished() {
            return super.has_finished() && this._images_rendered == true;
        }
        _map_data() {
            // Better to check this.model.w and this.model.h for null since the set_data
            // machinery will have converted this._w and this._w to lists of null
            const ws = this.model.w != null ? this._w : arrayable_1.map(this._x, () => NaN);
            const hs = this.model.h != null ? this._h : arrayable_1.map(this._x, () => NaN);
            switch (this.model.properties.w.units) {
                case "data": {
                    this.sw = this.sdist(this.renderer.xscale, this._x, ws, "edge", this.model.dilate);
                    break;
                }
                case "screen": {
                    this.sw = ws;
                    break;
                }
            }
            switch (this.model.properties.h.units) {
                case "data": {
                    this.sh = this.sdist(this.renderer.yscale, this._y, hs, "edge", this.model.dilate);
                    break;
                }
                case "screen": {
                    this.sh = hs;
                    break;
                }
            }
        }
        _render(ctx, indices, { image, sx, sy, sw, sh, _angle }) {
            // TODO (bev): take actual border width into account when clipping
            const { frame } = this.renderer.plot_view;
            ctx.rect(frame._left.value + 1, frame._top.value + 1, frame._width.value - 2, frame._height.value - 2);
            ctx.clip();
            let finished = true;
            for (const i of indices) {
                if (isNaN(sx[i] + sy[i] + _angle[i]))
                    continue;
                const img = image[i];
                if (img == null) {
                    finished = false;
                    continue;
                }
                this._render_image(ctx, i, img, sx, sy, sw, sh, _angle);
            }
            if (finished && !this._images_rendered) {
                this._images_rendered = true;
                this.notify_finished();
            }
        }
        _final_sx_sy(anchor, sx, sy, sw, sh) {
            switch (anchor) {
                case 'top_left': return [sx, sy];
                case 'top_center': return [sx - (sw / 2), sy];
                case 'top_right': return [sx - sw, sy];
                case 'center_right': return [sx - sw, sy - (sh / 2)];
                case 'bottom_right': return [sx - sw, sy - sh];
                case 'bottom_center': return [sx - (sw / 2), sy - sh];
                case 'bottom_left': return [sx, sy - sh];
                case 'center_left': return [sx, sy - (sh / 2)];
                case 'center': return [sx - (sw / 2), sy - (sh / 2)];
            }
        }
        _render_image(ctx, i, image, sx, sy, sw, sh, angle) {
            if (isNaN(sw[i]))
                sw[i] = image.width;
            if (isNaN(sh[i]))
                sh[i] = image.height;
            const { anchor } = this.model;
            const [sxi, syi] = this._final_sx_sy(anchor, sx[i], sy[i], sw[i], sh[i]);
            ctx.save();
            ctx.globalAlpha = this.model.global_alpha;
            if (angle[i]) {
                ctx.translate(sxi, syi);
                ctx.rotate(angle[i]);
                ctx.drawImage(image, 0, 0, sw[i], sh[i]);
                ctx.rotate(-angle[i]);
                ctx.translate(-sxi, -syi);
            }
            else
                ctx.drawImage(image, sxi, syi, sw[i], sh[i]);
            ctx.restore();
        }
        bounds() {
            return this._bounds_rect;
        }
    }
    exports.ImageURLView = ImageURLView;
    ImageURLView.__name__ = "ImageURLView";
    class ImageURL extends xy_glyph_1.XYGlyph {
        constructor(attrs) {
            super(attrs);
        }
        static init_ImageURL() {
            this.prototype.default_view = ImageURLView;
            this.define({
                url: [p.StringSpec],
                anchor: [p.Anchor, 'top_left'],
                global_alpha: [p.Number, 1.0],
                angle: [p.AngleSpec, 0],
                w: [p.DistanceSpec],
                h: [p.DistanceSpec],
                dilate: [p.Boolean, false],
                retry_attempts: [p.Number, 0],
                retry_timeout: [p.Number, 0],
            });
        }
    }
    exports.ImageURL = ImageURL;
    ImageURL.__name__ = "ImageURL";
    ImageURL.init_ImageURL();
},
/* core/util/image.js */ function _(require, module, exports) {
    const logging_1 = require(65) /* ../logging */;
    class ImageLoader {
        constructor(url, options = {}) {
            this._image = new Image();
            this._finished = false;
            const { attempts = 1, timeout = 1 } = options;
            this.promise = new Promise((resolve, _reject) => {
                this._image.crossOrigin = "anonymous";
                let retries = 0;
                this._image.onerror = () => {
                    if (++retries == attempts) {
                        const message = `unable to load ${url} image after ${attempts} attempts`;
                        logging_1.logger.warn(message);
                        if (this._image.crossOrigin != null) {
                            logging_1.logger.warn(`attempting to load ${url} without a cross origin policy`);
                            this._image.crossOrigin = null;
                            retries = 0;
                        }
                        else {
                            if (options.failed != null)
                                options.failed();
                            // reject(new Error(message))
                        }
                    }
                    setTimeout(() => this._image.src = url, timeout);
                };
                this._image.onload = () => {
                    this._finished = true;
                    if (options.loaded != null)
                        options.loaded(this._image);
                    resolve(this._image);
                };
                this._image.src = url;
            });
        }
        get finished() {
            return this._finished;
        }
        get image() {
            return this._image;
        }
    }
    exports.ImageLoader = ImageLoader;
    ImageLoader.__name__ = "ImageLoader";
},
/* models/glyphs/multi_line.js */ function _(require, module, exports) {
    const spatial_1 = require(77) /* ../../core/util/spatial */;
    const hittest = require(81) /* ../../core/hittest */;
    const object_1 = require(22) /* ../../core/util/object */;
    const array_1 = require(8) /* ../../core/util/array */;
    const types_1 = require(7) /* ../../core/util/types */;
    const glyph_1 = require(80) /* ./glyph */;
    const utils_1 = require(84) /* ./utils */;
    class MultiLineView extends glyph_1.GlyphView {
        _index_data() {
            const points = [];
            for (let i = 0, end = this._xs.length; i < end; i++) {
                if (this._xs[i] == null || this._xs[i].length === 0)
                    continue;
                const _xsi = this._xs[i];
                const xs = [];
                for (let j = 0, n = _xsi.length; j < n; j++) {
                    const x = _xsi[j];
                    if (!types_1.isStrictNaN(x))
                        xs.push(x);
                }
                const _ysi = this._ys[i];
                const ys = [];
                for (let j = 0, n = _ysi.length; j < n; j++) {
                    const y = _ysi[j];
                    if (!types_1.isStrictNaN(y))
                        ys.push(y);
                }
                const [x0, x1] = [array_1.min(xs), array_1.max(xs)];
                const [y0, y1] = [array_1.min(ys), array_1.max(ys)];
                points.push({ x0, y0, x1, y1, i });
            }
            return new spatial_1.SpatialIndex(points);
        }
        _render(ctx, indices, { sxs, sys }) {
            for (const i of indices) {
                const [sx, sy] = [sxs[i], sys[i]];
                this.visuals.line.set_vectorize(ctx, i);
                for (let j = 0, end = sx.length; j < end; j++) {
                    if (j == 0) {
                        ctx.beginPath();
                        ctx.moveTo(sx[j], sy[j]);
                        continue;
                    }
                    else if (isNaN(sx[j]) || isNaN(sy[j])) {
                        ctx.stroke();
                        ctx.beginPath();
                        continue;
                    }
                    else
                        ctx.lineTo(sx[j], sy[j]);
                }
                ctx.stroke();
            }
        }
        _hit_point(geometry) {
            const result = hittest.create_empty_hit_test_result();
            const point = { x: geometry.sx, y: geometry.sy };
            let shortest = 9999;
            const hits = {};
            for (let i = 0, end = this.sxs.length; i < end; i++) {
                const threshold = Math.max(2, this.visuals.line.cache_select('line_width', i) / 2);
                let points = null;
                for (let j = 0, endj = this.sxs[i].length - 1; j < endj; j++) {
                    const p0 = { x: this.sxs[i][j], y: this.sys[i][j] };
                    const p1 = { x: this.sxs[i][j + 1], y: this.sys[i][j + 1] };
                    const dist = hittest.dist_to_segment(point, p0, p1);
                    if (dist < threshold && dist < shortest) {
                        shortest = dist;
                        points = [j];
                    }
                }
                if (points)
                    hits[i] = points;
            }
            result.indices = object_1.keys(hits).map((x) => parseInt(x, 10));
            result.multiline_indices = hits;
            return result;
        }
        _hit_span(geometry) {
            const { sx, sy } = geometry;
            const result = hittest.create_empty_hit_test_result();
            let val;
            let values;
            if (geometry.direction === 'v') {
                val = this.renderer.yscale.invert(sy);
                values = this._ys;
            }
            else {
                val = this.renderer.xscale.invert(sx);
                values = this._xs;
            }
            const hits = {};
            for (let i = 0, end = values.length; i < end; i++) {
                const points = [];
                for (let j = 0, endj = values[i].length - 1; j < endj; j++) {
                    if (values[i][j] <= val && val <= values[i][j + 1])
                        points.push(j);
                }
                if (points.length > 0)
                    hits[i] = points;
            }
            result.indices = object_1.keys(hits).map((x) => parseInt(x, 10));
            result.multiline_indices = hits;
            return result;
        }
        get_interpolation_hit(i, point_i, geometry) {
            const [x2, y2, x3, y3] = [this._xs[i][point_i], this._ys[i][point_i], this._xs[i][point_i + 1], this._ys[i][point_i + 1]];
            return utils_1.line_interpolation(this.renderer, geometry, x2, y2, x3, y3);
        }
        draw_legend_for_index(ctx, bbox, index) {
            utils_1.generic_line_legend(this.visuals, ctx, bbox, index);
        }
        scenterx() {
            throw new Error("not implemented");
        }
        scentery() {
            throw new Error("not implemented");
        }
    }
    exports.MultiLineView = MultiLineView;
    MultiLineView.__name__ = "MultiLineView";
    class MultiLine extends glyph_1.Glyph {
        constructor(attrs) {
            super(attrs);
        }
        static init_MultiLine() {
            this.prototype.default_view = MultiLineView;
            this.coords([['xs', 'ys']]);
            this.mixins(['line']);
        }
    }
    exports.MultiLine = MultiLine;
    MultiLine.__name__ = "MultiLine";
    MultiLine.init_MultiLine();
},
/* models/glyphs/multi_polygons.js */ function _(require, module, exports) {
    const spatial_1 = require(77) /* ../../core/util/spatial */;
    const glyph_1 = require(80) /* ./glyph */;
    const utils_1 = require(84) /* ./utils */;
    const array_1 = require(8) /* ../../core/util/array */;
    const arrayable_1 = require(11) /* ../../core/util/arrayable */;
    const hittest = require(81) /* ../../core/hittest */;
    const types_1 = require(7) /* ../../core/util/types */;
    class MultiPolygonsView extends glyph_1.GlyphView {
        _index_data() {
            const points = [];
            for (let i = 0, end = this._xs.length; i < end; i++) {
                for (let j = 0, endj = this._xs[i].length; j < endj; j++) {
                    const xs = this._xs[i][j][0]; // do not use holes
                    const ys = this._ys[i][j][0]; // do not use holes
                    if (xs.length == 0)
                        continue;
                    points.push({ x0: array_1.min(xs), y0: array_1.min(ys), x1: array_1.max(xs), y1: array_1.max(ys), i });
                }
            }
            this.hole_index = this._index_hole_data(); // should this be set here?
            return new spatial_1.SpatialIndex(points);
        }
        _index_hole_data() {
            // need advice on how to use this sure if this could be more useful
            const points = [];
            for (let i = 0, end = this._xs.length; i < end; i++) {
                for (let j = 0, endj = this._xs[i].length; j < endj; j++) {
                    if (this._xs[i][j].length > 1) {
                        for (let k = 1, endk = this._xs[i][j].length; k < endk; k++) {
                            const xs = this._xs[i][j][k]; // only use holes
                            const ys = this._ys[i][j][k]; // only use holes
                            if (xs.length == 0)
                                continue;
                            points.push({ x0: array_1.min(xs), y0: array_1.min(ys), x1: array_1.max(xs), y1: array_1.max(ys), i });
                        }
                    }
                }
            }
            return new spatial_1.SpatialIndex(points);
        }
        _mask_data() {
            const xr = this.renderer.plot_view.frame.x_ranges.default;
            const [x0, x1] = [xr.min, xr.max];
            const yr = this.renderer.plot_view.frame.y_ranges.default;
            const [y0, y1] = [yr.min, yr.max];
            const indices = this.index.indices({ x0, x1, y0, y1 });
            // TODO this is probably needed in patches as well so that we don't draw glyphs multiple times
            return indices.sort((a, b) => a - b).filter((value, index, array) => {
                return (index === 0) || (value !== array[index - 1]);
            });
        }
        _inner_loop(ctx, sx, sy) {
            ctx.beginPath();
            for (let j = 0, endj = sx.length; j < endj; j++) {
                for (let k = 0, endk = sx[j].length; k < endk; k++) {
                    const _sx = sx[j][k];
                    const _sy = sy[j][k];
                    for (let l = 0, endl = _sx.length; l < endl; l++) {
                        if (l == 0) {
                            ctx.moveTo(_sx[l], _sy[l]);
                            continue;
                        }
                        else
                            ctx.lineTo(_sx[l], _sy[l]);
                    }
                    ctx.closePath();
                }
            }
        }
        _render(ctx, indices, { sxs, sys }) {
            if (this.visuals.fill.doit || this.visuals.line.doit) {
                for (const i of indices) {
                    const [sx, sy] = [sxs[i], sys[i]];
                    if (this.visuals.fill.doit) {
                        this.visuals.fill.set_vectorize(ctx, i);
                        this._inner_loop(ctx, sx, sy);
                        ctx.fill("evenodd");
                    }
                    this.visuals.hatch.doit2(ctx, i, () => {
                        this._inner_loop(ctx, sx, sy);
                        ctx.fill("evenodd");
                    }, () => this.renderer.request_render());
                    if (this.visuals.line.doit) {
                        this.visuals.line.set_vectorize(ctx, i);
                        this._inner_loop(ctx, sx, sy);
                        ctx.stroke();
                    }
                }
            }
        }
        _hit_point(geometry) {
            const { sx, sy } = geometry;
            const x = this.renderer.xscale.invert(sx);
            const y = this.renderer.yscale.invert(sy);
            const candidates = this.index.indices({ x0: x, y0: y, x1: x, y1: y });
            const hole_candidates = this.hole_index.indices({ x0: x, y0: y, x1: x, y1: y });
            const hits = [];
            for (let i = 0, end = candidates.length; i < end; i++) {
                const idx = candidates[i];
                const sxs = this.sxs[idx];
                const sys = this.sys[idx];
                for (let j = 0, endj = sxs.length; j < endj; j++) {
                    const nk = sxs[j].length;
                    if (hittest.point_in_poly(sx, sy, sxs[j][0], sys[j][0])) {
                        if (nk == 1) {
                            hits.push(idx);
                        }
                        else if (hole_candidates.indexOf(idx) == -1) {
                            hits.push(idx);
                        }
                        else if (nk > 1) {
                            let in_a_hole = false;
                            for (let k = 1; k < nk; k++) {
                                const sxs_k = sxs[j][k];
                                const sys_k = sys[j][k];
                                if (hittest.point_in_poly(sx, sy, sxs_k, sys_k)) {
                                    in_a_hole = true;
                                    break;
                                }
                                else {
                                    continue;
                                }
                            }
                            if (!in_a_hole) {
                                hits.push(idx);
                            }
                        }
                    }
                }
            }
            const result = hittest.create_empty_hit_test_result();
            result.indices = hits;
            return result;
        }
        _get_snap_coord(array) {
            return arrayable_1.sum(array) / array.length;
        }
        scenterx(i, sx, sy) {
            if (this.sxs[i].length == 1) {
                // We don't have discontinuous objects so we're ok
                return this._get_snap_coord(this.sxs[i][0][0]);
            }
            else {
                // We have discontinuous objects, so we need to find which
                // one we're in, we can use point_in_poly again
                const sxs = this.sxs[i];
                const sys = this.sys[i];
                for (let j = 0, end = sxs.length; j < end; j++) {
                    if (hittest.point_in_poly(sx, sy, sxs[j][0], sys[j][0]))
                        return this._get_snap_coord(sxs[j][0]);
                }
            }
            throw new Error("unreachable code");
        }
        scentery(i, sx, sy) {
            if (this.sys[i].length == 1) {
                // We don't have discontinuous objects so we're ok
                return this._get_snap_coord(this.sys[i][0][0]);
            }
            else {
                // We have discontinuous objects, so we need to find which
                // one we're in, we can use point_in_poly again
                const sxs = this.sxs[i];
                const sys = this.sys[i];
                for (let j = 0, end = sxs.length; j < end; j++) {
                    if (hittest.point_in_poly(sx, sy, sxs[j][0], sys[j][0]))
                        return this._get_snap_coord(sys[j][0]);
                }
            }
            throw new Error("unreachable code");
        }
        map_data() {
            const self = this;
            for (let [xname, yname] of this.model._coords) {
                const sxname = `s${xname}`;
                const syname = `s${yname}`;
                xname = `_${xname}`;
                yname = `_${yname}`;
                if (self[xname] != null && (types_1.isArray(self[xname][0]) || types_1.isTypedArray(self[xname][0]))) {
                    const ni = self[xname].length;
                    self[sxname] = new Array(ni);
                    self[syname] = new Array(ni);
                    for (let i = 0; i < ni; i++) {
                        const nj = self[xname][i].length;
                        self[sxname][i] = new Array(nj);
                        self[syname][i] = new Array(nj);
                        for (let j = 0; j < nj; j++) {
                            const nk = self[xname][i][j].length;
                            self[sxname][i][j] = new Array(nk);
                            self[syname][i][j] = new Array(nk);
                            for (let k = 0; k < nk; k++) {
                                const [sx, sy] = this.map_to_screen(self[xname][i][j][k], self[yname][i][j][k]);
                                self[sxname][i][j][k] = sx;
                                self[syname][i][j][k] = sy;
                            }
                        }
                    }
                }
            }
        }
        draw_legend_for_index(ctx, bbox, index) {
            utils_1.generic_area_legend(this.visuals, ctx, bbox, index);
        }
    }
    exports.MultiPolygonsView = MultiPolygonsView;
    MultiPolygonsView.__name__ = "MultiPolygonsView";
    class MultiPolygons extends glyph_1.Glyph {
        constructor(attrs) {
            super(attrs);
        }
        static init_MultiPolygons() {
            this.prototype.default_view = MultiPolygonsView;
            this.coords([['xs', 'ys']]);
            this.mixins(['line', 'fill', 'hatch']);
        }
    }
    exports.MultiPolygons = MultiPolygons;
    MultiPolygons.__name__ = "MultiPolygons";
    MultiPolygons.init_MultiPolygons();
},
/* models/glyphs/oval.js */ function _(require, module, exports) {
    const ellipse_oval_1 = require(208) /* ./ellipse_oval */;
    class OvalView extends ellipse_oval_1.EllipseOvalView {
        _map_data() {
            let sw;
            const n = this._x.length;
            this.sw = new Float64Array(n);
            if (this.model.properties.width.units == "data")
                sw = this.sdist(this.renderer.xscale, this._x, this._width, 'center');
            else
                sw = this._width;
            // oval drawn from bezier curves = ellipse with width reduced by 3/4
            for (let i = 0; i < n; i++)
                this.sw[i] = sw[i] * 0.75;
            if (this.model.properties.height.units == "data")
                this.sh = this.sdist(this.renderer.yscale, this._y, this._height, 'center');
            else
                this.sh = this._height;
        }
    }
    exports.OvalView = OvalView;
    OvalView.__name__ = "OvalView";
    class Oval extends ellipse_oval_1.EllipseOval {
        constructor(attrs) {
            super(attrs);
        }
        static init_Oval() {
            this.prototype.default_view = OvalView;
        }
    }
    exports.Oval = Oval;
    Oval.__name__ = "Oval";
    Oval.init_Oval();
},
/* models/glyphs/patches.js */ function _(require, module, exports) {
    const spatial_1 = require(77) /* ../../core/util/spatial */;
    const glyph_1 = require(80) /* ./glyph */;
    const utils_1 = require(84) /* ./utils */;
    const array_1 = require(8) /* ../../core/util/array */;
    const arrayable_1 = require(11) /* ../../core/util/arrayable */;
    const types_1 = require(7) /* ../../core/util/types */;
    const hittest = require(81) /* ../../core/hittest */;
    class PatchesView extends glyph_1.GlyphView {
        _build_discontinuous_object(nanned_qs) {
            // _s is this.xs, this.ys, this.sxs, this.sys
            // an object of n 1-d arrays in either data or screen units
            //
            // Each 1-d array gets broken to an array of arrays split
            // on any NaNs
            //
            // So:
            // { 0: [x11, x12],
            //   1: [x21, x22, x23],
            //   2: [x31, NaN, x32]
            // }
            // becomes
            // { 0: [[x11, x12]],
            //   1: [[x21, x22, x23]],
            //   2: [[x31],[x32]]
            // }
            const ds = [];
            for (let i = 0, end = nanned_qs.length; i < end; i++) {
                ds[i] = [];
                let qs = array_1.copy(nanned_qs[i]);
                while (qs.length > 0) {
                    const nan_index = array_1.find_last_index(qs, (q) => types_1.isStrictNaN(q));
                    let qs_part;
                    if (nan_index >= 0)
                        qs_part = qs.splice(nan_index);
                    else {
                        qs_part = qs;
                        qs = [];
                    }
                    const denanned = qs_part.filter((q) => !types_1.isStrictNaN(q));
                    ds[i].push(denanned);
                }
            }
            return ds;
        }
        _index_data() {
            const xss = this._build_discontinuous_object(this._xs); // XXX
            const yss = this._build_discontinuous_object(this._ys); // XXX
            const points = [];
            for (let i = 0, end = this._xs.length; i < end; i++) {
                for (let j = 0, endj = xss[i].length; j < endj; j++) {
                    const xs = xss[i][j];
                    const ys = yss[i][j];
                    if (xs.length == 0)
                        continue;
                    points.push({ x0: array_1.min(xs), y0: array_1.min(ys), x1: array_1.max(xs), y1: array_1.max(ys), i });
                }
            }
            return new spatial_1.SpatialIndex(points);
        }
        _mask_data() {
            const xr = this.renderer.plot_view.frame.x_ranges.default;
            const [x0, x1] = [xr.min, xr.max];
            const yr = this.renderer.plot_view.frame.y_ranges.default;
            const [y0, y1] = [yr.min, yr.max];
            const indices = this.index.indices({ x0, x1, y0, y1 });
            // TODO (bev) this should be under test
            return indices.sort((a, b) => a - b);
        }
        _inner_loop(ctx, sx, sy, func) {
            for (let j = 0, end = sx.length; j < end; j++) {
                if (j == 0) {
                    ctx.beginPath();
                    ctx.moveTo(sx[j], sy[j]);
                    continue;
                }
                else if (isNaN(sx[j] + sy[j])) {
                    ctx.closePath();
                    func.apply(ctx);
                    ctx.beginPath();
                    continue;
                }
                else
                    ctx.lineTo(sx[j], sy[j]);
            }
            ctx.closePath();
            func.call(ctx);
        }
        _render(ctx, indices, { sxs, sys }) {
            // this.sxss and this.syss are used by _hit_point and sxc, syc
            // This is the earliest we can build them, and only build them once
            this.sxss = this._build_discontinuous_object(sxs); // XXX
            this.syss = this._build_discontinuous_object(sys); // XXX
            for (const i of indices) {
                const [sx, sy] = [sxs[i], sys[i]];
                if (this.visuals.fill.doit) {
                    this.visuals.fill.set_vectorize(ctx, i);
                    this._inner_loop(ctx, sx, sy, ctx.fill);
                }
                this.visuals.hatch.doit2(ctx, i, () => this._inner_loop(ctx, sx, sy, ctx.fill), () => this.renderer.request_render());
                if (this.visuals.line.doit) {
                    this.visuals.line.set_vectorize(ctx, i);
                    this._inner_loop(ctx, sx, sy, ctx.stroke);
                }
            }
        }
        _hit_point(geometry) {
            const { sx, sy } = geometry;
            const x = this.renderer.xscale.invert(sx);
            const y = this.renderer.yscale.invert(sy);
            const candidates = this.index.indices({ x0: x, y0: y, x1: x, y1: y });
            const hits = [];
            for (let i = 0, end = candidates.length; i < end; i++) {
                const idx = candidates[i];
                const sxs = this.sxss[idx];
                const sys = this.syss[idx];
                for (let j = 0, endj = sxs.length; j < endj; j++) {
                    if (hittest.point_in_poly(sx, sy, sxs[j], sys[j])) {
                        hits.push(idx);
                    }
                }
            }
            const result = hittest.create_empty_hit_test_result();
            result.indices = hits;
            return result;
        }
        _get_snap_coord(array) {
            return arrayable_1.sum(array) / array.length;
        }
        scenterx(i, sx, sy) {
            if (this.sxss[i].length == 1) {
                // We don't have discontinuous objects so we're ok
                return this._get_snap_coord(this.sxs[i]);
            }
            else {
                // We have discontinuous objects, so we need to find which
                // one we're in, we can use point_in_poly again
                const sxs = this.sxss[i];
                const sys = this.syss[i];
                for (let j = 0, end = sxs.length; j < end; j++) {
                    if (hittest.point_in_poly(sx, sy, sxs[j], sys[j]))
                        return this._get_snap_coord(sxs[j]);
                }
            }
            throw new Error("unreachable code");
        }
        scentery(i, sx, sy) {
            if (this.syss[i].length == 1) {
                // We don't have discontinuous objects so we're ok
                return this._get_snap_coord(this.sys[i]);
            }
            else {
                // We have discontinuous objects, so we need to find which
                // one we're in, we can use point_in_poly again
                const sxs = this.sxss[i];
                const sys = this.syss[i];
                for (let j = 0, end = sxs.length; j < end; j++) {
                    if (hittest.point_in_poly(sx, sy, sxs[j], sys[j]))
                        return this._get_snap_coord(sys[j]);
                }
            }
            throw new Error("unreachable code");
        }
        draw_legend_for_index(ctx, bbox, index) {
            utils_1.generic_area_legend(this.visuals, ctx, bbox, index);
        }
    }
    exports.PatchesView = PatchesView;
    PatchesView.__name__ = "PatchesView";
    class Patches extends glyph_1.Glyph {
        constructor(attrs) {
            super(attrs);
        }
        static init_Patches() {
            this.prototype.default_view = PatchesView;
            this.coords([['xs', 'ys']]);
            this.mixins(['line', 'fill', 'hatch']);
        }
    }
    exports.Patches = Patches;
    Patches.__name__ = "Patches";
    Patches.init_Patches();
},
/* models/glyphs/quad.js */ function _(require, module, exports) {
    const box_1 = require(210) /* ./box */;
    class QuadView extends box_1.BoxView {
        scenterx(i) {
            return (this.sleft[i] + this.sright[i]) / 2;
        }
        scentery(i) {
            return (this.stop[i] + this.sbottom[i]) / 2;
        }
        _index_data() {
            return this._index_box(this._right.length);
        }
        _lrtb(i) {
            const l = this._left[i];
            const r = this._right[i];
            const t = this._top[i];
            const b = this._bottom[i];
            return [l, r, t, b];
        }
    }
    exports.QuadView = QuadView;
    QuadView.__name__ = "QuadView";
    class Quad extends box_1.Box {
        constructor(attrs) {
            super(attrs);
        }
        static init_Quad() {
            this.prototype.default_view = QuadView;
            this.coords([['right', 'bottom'], ['left', 'top']]);
        }
    }
    exports.Quad = Quad;
    Quad.__name__ = "Quad";
    Quad.init_Quad();
},
/* models/glyphs/quadratic.js */ function _(require, module, exports) {
    const spatial_1 = require(77) /* ../../core/util/spatial */;
    const glyph_1 = require(80) /* ./glyph */;
    const utils_1 = require(84) /* ./utils */;
    // Formula from: http://pomax.nihongoresources.com/pages/bezier/
    //
    // if segment is quadratic bezier do:
    //   for both directions do:
    //     if control between start and end, compute linear bounding box
    //     otherwise, compute
    //       bound = u(1-t)^2 + 2v(1-t)t + wt^2
    //         (with t = ((u-v) / (u-2v+w)), with {u = start, v = control, w = end})
    //       if control precedes start, min = bound, otherwise max = bound
    function _qbb(u, v, w) {
        if (v == (u + w) / 2)
            return [u, w];
        else {
            const t = (u - v) / ((u - (2 * v)) + w);
            const bd = (u * Math.pow((1 - t), 2)) + (2 * v * (1 - t) * t) + (w * Math.pow(t, 2));
            return [Math.min(u, w, bd), Math.max(u, w, bd)];
        }
    }
    class QuadraticView extends glyph_1.GlyphView {
        _index_data() {
            const points = [];
            for (let i = 0, end = this._x0.length; i < end; i++) {
                if (isNaN(this._x0[i] + this._x1[i] + this._y0[i] + this._y1[i] + this._cx[i] + this._cy[i]))
                    continue;
                const [x0, x1] = _qbb(this._x0[i], this._cx[i], this._x1[i]);
                const [y0, y1] = _qbb(this._y0[i], this._cy[i], this._y1[i]);
                points.push({ x0, y0, x1, y1, i });
            }
            return new spatial_1.SpatialIndex(points);
        }
        _render(ctx, indices, { sx0, sy0, sx1, sy1, scx, scy }) {
            if (this.visuals.line.doit) {
                for (const i of indices) {
                    if (isNaN(sx0[i] + sy0[i] + sx1[i] + sy1[i] + scx[i] + scy[i]))
                        continue;
                    ctx.beginPath();
                    ctx.moveTo(sx0[i], sy0[i]);
                    ctx.quadraticCurveTo(scx[i], scy[i], sx1[i], sy1[i]);
                    this.visuals.line.set_vectorize(ctx, i);
                    ctx.stroke();
                }
            }
        }
        draw_legend_for_index(ctx, bbox, index) {
            utils_1.generic_line_legend(this.visuals, ctx, bbox, index);
        }
        scenterx() {
            throw new Error("not implemented");
        }
        scentery() {
            throw new Error("not implemented");
        }
    }
    exports.QuadraticView = QuadraticView;
    QuadraticView.__name__ = "QuadraticView";
    class Quadratic extends glyph_1.Glyph {
        constructor(attrs) {
            super(attrs);
        }
        static init_Quadratic() {
            this.prototype.default_view = QuadraticView;
            this.coords([['x0', 'y0'], ['x1', 'y1'], ['cx', 'cy']]);
            this.mixins(['line']);
        }
    }
    exports.Quadratic = Quadratic;
    Quadratic.__name__ = "Quadratic";
    Quadratic.init_Quadratic();
},
/* models/glyphs/ray.js */ function _(require, module, exports) {
    const xy_glyph_1 = require(76) /* ./xy_glyph */;
    const utils_1 = require(84) /* ./utils */;
    const p = require(18) /* ../../core/properties */;
    class RayView extends xy_glyph_1.XYGlyphView {
        _map_data() {
            if (this.model.properties.length.units == "data")
                this.slength = this.sdist(this.renderer.xscale, this._x, this._length);
            else
                this.slength = this._length;
        }
        _render(ctx, indices, { sx, sy, slength, _angle }) {
            if (this.visuals.line.doit) {
                const width = this.renderer.plot_view.frame._width.value;
                const height = this.renderer.plot_view.frame._height.value;
                const inf_len = 2 * (width + height);
                for (let i = 0, end = slength.length; i < end; i++) {
                    if (slength[i] == 0)
                        slength[i] = inf_len;
                }
                for (const i of indices) {
                    if (isNaN(sx[i] + sy[i] + _angle[i] + slength[i]))
                        continue;
                    ctx.translate(sx[i], sy[i]);
                    ctx.rotate(_angle[i]);
                    ctx.beginPath();
                    ctx.moveTo(0, 0);
                    ctx.lineTo(slength[i], 0);
                    this.visuals.line.set_vectorize(ctx, i);
                    ctx.stroke();
                    ctx.rotate(-_angle[i]);
                    ctx.translate(-sx[i], -sy[i]);
                }
            }
        }
        draw_legend_for_index(ctx, bbox, index) {
            utils_1.generic_line_legend(this.visuals, ctx, bbox, index);
        }
    }
    exports.RayView = RayView;
    RayView.__name__ = "RayView";
    class Ray extends xy_glyph_1.XYGlyph {
        constructor(attrs) {
            super(attrs);
        }
        static init_Ray() {
            this.prototype.default_view = RayView;
            this.mixins(['line']);
            this.define({
                length: [p.DistanceSpec],
                angle: [p.AngleSpec],
            });
        }
    }
    exports.Ray = Ray;
    Ray.__name__ = "Ray";
    Ray.init_Ray();
},
/* models/glyphs/rect.js */ function _(require, module, exports) {
    const center_rotatable_1 = require(206) /* ./center_rotatable */;
    const utils_1 = require(84) /* ./utils */;
    const hittest = require(81) /* ../../core/hittest */;
    const p = require(18) /* ../../core/properties */;
    const arrayable_1 = require(11) /* ../../core/util/arrayable */;
    class RectView extends center_rotatable_1.CenterRotatableView {
        _set_data() {
            this.max_w2 = 0;
            if (this.model.properties.width.units == "data")
                this.max_w2 = this.max_width / 2;
            this.max_h2 = 0;
            if (this.model.properties.height.units == "data")
                this.max_h2 = this.max_height / 2;
        }
        _map_data() {
            if (this.model.properties.width.units == "data")
                [this.sw, this.sx0] = this._map_dist_corner_for_data_side_length(this._x, this._width, this.renderer.xscale);
            else {
                this.sw = this._width;
                const n = this.sx.length;
                this.sx0 = new Float64Array(n);
                for (let i = 0; i < n; i++)
                    this.sx0[i] = this.sx[i] - this.sw[i] / 2;
            }
            if (this.model.properties.height.units == "data")
                [this.sh, this.sy1] = this._map_dist_corner_for_data_side_length(this._y, this._height, this.renderer.yscale);
            else {
                this.sh = this._height;
                const n = this.sy.length;
                this.sy1 = new Float64Array(n);
                for (let i = 0; i < n; i++)
                    this.sy1[i] = this.sy[i] - this.sh[i] / 2;
            }
            const n = this.sw.length;
            this.ssemi_diag = new Float64Array(n);
            for (let i = 0; i < n; i++)
                this.ssemi_diag[i] = Math.sqrt((this.sw[i] / 2 * this.sw[i]) / 2 + (this.sh[i] / 2 * this.sh[i]) / 2);
        }
        _render(ctx, indices, { sx, sy, sx0, sy1, sw, sh, _angle }) {
            if (this.visuals.fill.doit) {
                for (const i of indices) {
                    if (isNaN(sx[i] + sy[i] + sx0[i] + sy1[i] + sw[i] + sh[i] + _angle[i]))
                        continue;
                    //no need to test the return value, we call fillRect for every glyph anyway
                    this.visuals.fill.set_vectorize(ctx, i);
                    if (_angle[i]) {
                        ctx.translate(sx[i], sy[i]);
                        ctx.rotate(_angle[i]);
                        ctx.fillRect(-sw[i] / 2, -sh[i] / 2, sw[i], sh[i]);
                        ctx.rotate(-_angle[i]);
                        ctx.translate(-sx[i], -sy[i]);
                    }
                    else
                        ctx.fillRect(sx0[i], sy1[i], sw[i], sh[i]);
                }
            }
            if (this.visuals.line.doit) {
                ctx.beginPath();
                for (const i of indices) {
                    if (isNaN(sx[i] + sy[i] + sx0[i] + sy1[i] + sw[i] + sh[i] + _angle[i]))
                        continue;
                    // fillRect does not fill zero-height or -width rects, but rect(...)
                    // does seem to stroke them (1px wide or tall). Explicitly ignore rects
                    // with zero width or height to be consistent
                    if (sw[i] == 0 || sh[i] == 0)
                        continue;
                    if (_angle[i]) {
                        ctx.translate(sx[i], sy[i]);
                        ctx.rotate(_angle[i]);
                        ctx.rect(-sw[i] / 2, -sh[i] / 2, sw[i], sh[i]);
                        ctx.rotate(-_angle[i]);
                        ctx.translate(-sx[i], -sy[i]);
                    }
                    else
                        ctx.rect(sx0[i], sy1[i], sw[i], sh[i]);
                    this.visuals.line.set_vectorize(ctx, i);
                    ctx.stroke();
                    ctx.beginPath();
                }
                ctx.stroke();
            }
        }
        _hit_rect(geometry) {
            return this._hit_rect_against_index(geometry);
        }
        _hit_point(geometry) {
            let { sx, sy } = geometry;
            const x = this.renderer.xscale.invert(sx);
            const y = this.renderer.yscale.invert(sy);
            const scenter_x = [];
            for (let i = 0, end = this.sx0.length; i < end; i++) {
                scenter_x.push(this.sx0[i] + this.sw[i] / 2);
            }
            const scenter_y = [];
            for (let i = 0, end = this.sy1.length; i < end; i++) {
                scenter_y.push(this.sy1[i] + this.sh[i] / 2);
            }
            const max_x2_ddist = arrayable_1.max(this._ddist(0, scenter_x, this.ssemi_diag));
            const max_y2_ddist = arrayable_1.max(this._ddist(1, scenter_y, this.ssemi_diag));
            const x0 = x - max_x2_ddist;
            const x1 = x + max_x2_ddist;
            const y0 = y - max_y2_ddist;
            const y1 = y + max_y2_ddist;
            const hits = [];
            for (const i of this.index.indices({ x0, x1, y0, y1 })) {
                let height_in, width_in;
                if (this._angle[i]) {
                    const s = Math.sin(-this._angle[i]);
                    const c = Math.cos(-this._angle[i]);
                    const px = c * (sx - this.sx[i]) - s * (sy - this.sy[i]) + this.sx[i];
                    const py = s * (sx - this.sx[i]) + c * (sy - this.sy[i]) + this.sy[i];
                    sx = px;
                    sy = py;
                    width_in = Math.abs(this.sx[i] - sx) <= this.sw[i] / 2;
                    height_in = Math.abs(this.sy[i] - sy) <= this.sh[i] / 2;
                }
                else {
                    width_in = (sx - this.sx0[i] <= this.sw[i]) && (sx - this.sx0[i] >= 0);
                    height_in = (sy - this.sy1[i] <= this.sh[i]) && (sy - this.sy1[i] >= 0);
                }
                if (height_in && width_in)
                    hits.push(i);
            }
            const result = hittest.create_empty_hit_test_result();
            result.indices = hits;
            return result;
        }
        _map_dist_corner_for_data_side_length(coord, side_length, scale) {
            const n = coord.length;
            const pt0 = new Float64Array(n);
            const pt1 = new Float64Array(n);
            for (let i = 0; i < n; i++) {
                pt0[i] = Number(coord[i]) - side_length[i] / 2;
                pt1[i] = Number(coord[i]) + side_length[i] / 2;
            }
            const spt0 = scale.v_compute(pt0);
            const spt1 = scale.v_compute(pt1);
            const sside_length = this.sdist(scale, pt0, side_length, 'edge', this.model.dilate);
            let spt_corner = spt0;
            for (let i = 0, end = spt0.length; i < end; i++) {
                if (spt0[i] != spt1[i]) {
                    spt_corner = spt0[i] < spt1[i] ? spt0 : spt1;
                    break;
                }
            }
            return [sside_length, spt_corner];
        }
        _ddist(dim, spts, spans) {
            const scale = dim == 0 ? this.renderer.xscale : this.renderer.yscale;
            const spt0 = spts;
            const m = spt0.length;
            const spt1 = new Float64Array(m);
            for (let i = 0; i < m; i++)
                spt1[i] = spt0[i] + spans[i];
            const pt0 = scale.v_invert(spt0);
            const pt1 = scale.v_invert(spt1);
            const n = pt0.length;
            const ddist = new Float64Array(n);
            for (let i = 0; i < n; i++)
                ddist[i] = Math.abs(pt1[i] - pt0[i]);
            return ddist;
        }
        draw_legend_for_index(ctx, bbox, index) {
            utils_1.generic_area_legend(this.visuals, ctx, bbox, index);
        }
        _bounds({ x0, x1, y0, y1 }) {
            return {
                x0: x0 - this.max_w2,
                x1: x1 + this.max_w2,
                y0: y0 - this.max_h2,
                y1: y1 + this.max_h2,
            };
        }
    }
    exports.RectView = RectView;
    RectView.__name__ = "RectView";
    class Rect extends center_rotatable_1.CenterRotatable {
        constructor(attrs) {
            super(attrs);
        }
        static init_Rect() {
            this.prototype.default_view = RectView;
            this.define({
                dilate: [p.Boolean, false],
            });
        }
    }
    exports.Rect = Rect;
    Rect.__name__ = "Rect";
    Rect.init_Rect();
},
/* models/glyphs/segment.js */ function _(require, module, exports) {
    const hittest = require(81) /* ../../core/hittest */;
    const spatial_1 = require(77) /* ../../core/util/spatial */;
    const glyph_1 = require(80) /* ./glyph */;
    const utils_1 = require(84) /* ./utils */;
    class SegmentView extends glyph_1.GlyphView {
        _index_data() {
            const points = [];
            for (let i = 0, end = this._x0.length; i < end; i++) {
                const x0 = this._x0[i];
                const x1 = this._x1[i];
                const y0 = this._y0[i];
                const y1 = this._y1[i];
                if (!isNaN(x0 + x1 + y0 + y1)) {
                    points.push({
                        x0: Math.min(x0, x1),
                        y0: Math.min(y0, y1),
                        x1: Math.max(x0, x1),
                        y1: Math.max(y0, y1),
                        i,
                    });
                }
            }
            return new spatial_1.SpatialIndex(points);
        }
        _render(ctx, indices, { sx0, sy0, sx1, sy1 }) {
            if (this.visuals.line.doit) {
                for (const i of indices) {
                    if (isNaN(sx0[i] + sy0[i] + sx1[i] + sy1[i]))
                        continue;
                    ctx.beginPath();
                    ctx.moveTo(sx0[i], sy0[i]);
                    ctx.lineTo(sx1[i], sy1[i]);
                    this.visuals.line.set_vectorize(ctx, i);
                    ctx.stroke();
                }
            }
        }
        _hit_point(geometry) {
            const { sx, sy } = geometry;
            const point = { x: sx, y: sy };
            const hits = [];
            const lw_voffset = 2; // FIXME: Use maximum of segments line_width/2 instead of magic constant 2
            const [x0, x1] = this.renderer.xscale.r_invert(sx - lw_voffset, sx + lw_voffset);
            const [y0, y1] = this.renderer.yscale.r_invert(sy - lw_voffset, sy + lw_voffset);
            const candidates = this.index.indices({ x0, y0, x1, y1 });
            for (const i of candidates) {
                const threshold2 = Math.pow(Math.max(2, this.visuals.line.cache_select('line_width', i) / 2), 2);
                const p0 = { x: this.sx0[i], y: this.sy0[i] };
                const p1 = { x: this.sx1[i], y: this.sy1[i] };
                const dist2 = hittest.dist_to_segment_squared(point, p0, p1);
                if (dist2 < threshold2)
                    hits.push(i);
            }
            const result = hittest.create_empty_hit_test_result();
            result.indices = hits;
            return result;
        }
        _hit_span(geometry) {
            const [hr, vr] = this.renderer.plot_view.frame.bbox.ranges;
            const { sx, sy } = geometry;
            let v0;
            let v1;
            let val;
            if (geometry.direction == 'v') {
                val = this.renderer.yscale.invert(sy);
                [v0, v1] = [this._y0, this._y1];
            }
            else {
                val = this.renderer.xscale.invert(sx);
                [v0, v1] = [this._x0, this._x1];
            }
            const hits = [];
            const [x0, x1] = this.renderer.xscale.r_invert(hr.start, hr.end);
            const [y0, y1] = this.renderer.yscale.r_invert(vr.start, vr.end);
            const candidates = this.index.indices({ x0, y0, x1, y1 });
            for (const i of candidates) {
                if ((v0[i] <= val && val <= v1[i]) || (v1[i] <= val && val <= v0[i]))
                    hits.push(i);
            }
            const result = hittest.create_empty_hit_test_result();
            result.indices = hits;
            return result;
        }
        scenterx(i) {
            return (this.sx0[i] + this.sx1[i]) / 2;
        }
        scentery(i) {
            return (this.sy0[i] + this.sy1[i]) / 2;
        }
        draw_legend_for_index(ctx, bbox, index) {
            utils_1.generic_line_legend(this.visuals, ctx, bbox, index);
        }
    }
    exports.SegmentView = SegmentView;
    SegmentView.__name__ = "SegmentView";
    class Segment extends glyph_1.Glyph {
        constructor(attrs) {
            super(attrs);
        }
        static init_Segment() {
            this.prototype.default_view = SegmentView;
            this.coords([['x0', 'y0'], ['x1', 'y1']]);
            this.mixins(['line']);
        }
    }
    exports.Segment = Segment;
    Segment.__name__ = "Segment";
    Segment.init_Segment();
},
/* models/glyphs/step.js */ function _(require, module, exports) {
    const xy_glyph_1 = require(76) /* ./xy_glyph */;
    const utils_1 = require(84) /* ./utils */;
    const p = require(18) /* ../../core/properties */;
    class StepView extends xy_glyph_1.XYGlyphView {
        _render(ctx, indices, { sx, sy }) {
            let drawing = false;
            let last_index = null;
            this.visuals.line.set_value(ctx);
            const L = indices.length;
            if (L < 2)
                return;
            ctx.beginPath();
            ctx.moveTo(sx[0], sy[0]);
            for (const i of indices) {
                let x1, x2;
                let y1, y2;
                switch (this.model.mode) {
                    case "before": {
                        [x1, y1] = [sx[i - 1], sy[i]];
                        [x2, y2] = [sx[i], sy[i]];
                        break;
                    }
                    case "after": {
                        [x1, y1] = [sx[i], sy[i - 1]];
                        [x2, y2] = [sx[i], sy[i]];
                        break;
                    }
                    case "center": {
                        const xm = (sx[i - 1] + sx[i]) / 2;
                        [x1, y1] = [xm, sy[i - 1]];
                        [x2, y2] = [xm, sy[i]];
                        break;
                    }
                    default:
                        throw new Error("unexpected");
                }
                if (drawing) {
                    if (!isFinite(sx[i] + sy[i])) {
                        ctx.stroke();
                        ctx.beginPath();
                        drawing = false;
                        last_index = i;
                        continue;
                    }
                    if (last_index != null && i - last_index > 1) {
                        ctx.stroke();
                        drawing = false;
                    }
                }
                if (drawing) {
                    ctx.lineTo(x1, y1);
                    ctx.lineTo(x2, y2);
                }
                else {
                    ctx.beginPath();
                    ctx.moveTo(sx[i], sy[i]);
                    drawing = true;
                }
                last_index = i;
            }
            ctx.lineTo(sx[L - 1], sy[L - 1]);
            ctx.stroke();
        }
        draw_legend_for_index(ctx, bbox, index) {
            utils_1.generic_line_legend(this.visuals, ctx, bbox, index);
        }
    }
    exports.StepView = StepView;
    StepView.__name__ = "StepView";
    class Step extends xy_glyph_1.XYGlyph {
        constructor(attrs) {
            super(attrs);
        }
        static init_Step() {
            this.prototype.default_view = StepView;
            this.mixins(['line']);
            this.define({
                mode: [p.StepMode, "before"],
            });
        }
    }
    exports.Step = Step;
    Step.__name__ = "Step";
    Step.init_Step();
},
/* models/glyphs/text.js */ function _(require, module, exports) {
    const xy_glyph_1 = require(76) /* ./xy_glyph */;
    const hittest = require(81) /* ../../core/hittest */;
    const p = require(18) /* ../../core/properties */;
    const text_1 = require(124) /* ../../core/util/text */;
    class TextView extends xy_glyph_1.XYGlyphView {
        _rotate_point(x, y, xoff, yoff, angle) {
            const sxr = (x - xoff) * Math.cos(angle) - (y - yoff) * Math.sin(angle) + xoff;
            const syr = (x - xoff) * Math.sin(angle) + (y - yoff) * Math.cos(angle) + yoff;
            return [sxr, syr];
        }
        _text_bounds(x0, y0, width, height) {
            const xvals = [x0, x0 + width, x0 + width, x0, x0];
            const yvals = [y0, y0, y0 - height, y0 - height, y0];
            return [xvals, yvals];
        }
        _render(ctx, indices, { sx, sy, _x_offset, _y_offset, _angle, _text }) {
            this._sys = [];
            this._sxs = [];
            for (const i of indices) {
                if (isNaN(sx[i] + sy[i] + _x_offset[i] + _y_offset[i] + _angle[i]) || _text[i] == null)
                    continue;
                this._sxs[i] = [];
                this._sys[i] = [];
                if (this.visuals.text.doit) {
                    const text = `${_text[i]}`;
                    ctx.save();
                    ctx.translate(sx[i] + _x_offset[i], sy[i] + _y_offset[i]);
                    ctx.rotate(_angle[i]);
                    this.visuals.text.set_vectorize(ctx, i);
                    const font = this.visuals.text.cache_select("font", i);
                    const { height } = text_1.measure_font(font);
                    const line_height = this.visuals.text.text_line_height.value() * height;
                    if (text.indexOf("\n") == -1) {
                        ctx.fillText(text, 0, 0);
                        const x0 = sx[i] + _x_offset[i];
                        const y0 = sy[i] + _y_offset[i];
                        const width = ctx.measureText(text).width;
                        const [xvalues, yvalues] = this._text_bounds(x0, y0, width, line_height);
                        this._sxs[i].push(xvalues);
                        this._sys[i].push(yvalues);
                    }
                    else {
                        const lines = text.split("\n");
                        const block_height = line_height * lines.length;
                        const baseline = this.visuals.text.cache_select("text_baseline", i);
                        let y;
                        switch (baseline) {
                            case "top": {
                                y = 0;
                                break;
                            }
                            case "middle": {
                                y = (-block_height / 2) + (line_height / 2);
                                break;
                            }
                            case "bottom": {
                                y = -block_height + line_height;
                                break;
                            }
                            default: {
                                y = 0;
                                console.warn(`'${baseline}' baseline not supported with multi line text`);
                            }
                        }
                        for (const line of lines) {
                            ctx.fillText(line, 0, y);
                            const x0 = sx[i] + _x_offset[i];
                            const y0 = y + sy[i] + _y_offset[i];
                            const width = ctx.measureText(line).width;
                            const [xvalues, yvalues] = this._text_bounds(x0, y0, width, line_height);
                            this._sxs[i].push(xvalues);
                            this._sys[i].push(yvalues);
                            y += line_height;
                        }
                    }
                    ctx.restore();
                }
            }
        }
        _hit_point(geometry) {
            const { sx, sy } = geometry;
            const hits = [];
            for (let i = 0; i < this._sxs.length; i++) {
                const sxs = this._sxs[i];
                const sys = this._sys[i];
                const n = sxs.length;
                for (let j = 0, endj = n; j < endj; j++) {
                    const [sxr, syr] = this._rotate_point(sx, sy, sxs[n - 1][0], sys[n - 1][0], -this._angle[i]);
                    if (hittest.point_in_poly(sxr, syr, sxs[j], sys[j])) {
                        hits.push(i);
                    }
                }
            }
            const result = hittest.create_empty_hit_test_result();
            result.indices = hits;
            return result;
        }
        _scenterxy(i) {
            const sx0 = this._sxs[i][0][0];
            const sy0 = this._sys[i][0][0];
            const sxc = (this._sxs[i][0][2] + sx0) / 2;
            const syc = (this._sys[i][0][2] + sy0) / 2;
            const [sxcr, sycr] = this._rotate_point(sxc, syc, sx0, sy0, this._angle[i]);
            return { x: sxcr, y: sycr };
        }
        scenterx(i) {
            return this._scenterxy(i).x;
        }
        scentery(i) {
            return this._scenterxy(i).y;
        }
    }
    exports.TextView = TextView;
    TextView.__name__ = "TextView";
    class Text extends xy_glyph_1.XYGlyph {
        constructor(attrs) {
            super(attrs);
        }
        static init_Text() {
            this.prototype.default_view = TextView;
            this.mixins(['text']);
            this.define({
                text: [p.NullStringSpec, { field: "text" }],
                angle: [p.AngleSpec, 0],
                x_offset: [p.NumberSpec, 0],
                y_offset: [p.NumberSpec, 0],
            });
        }
    }
    exports.Text = Text;
    Text.__name__ = "Text";
    Text.init_Text();
},
/* models/glyphs/vbar.js */ function _(require, module, exports) {
    const box_1 = require(210) /* ./box */;
    const p = require(18) /* ../../core/properties */;
    class VBarView extends box_1.BoxView {
        scenterx(i) {
            return this.sx[i];
        }
        scentery(i) {
            return (this.stop[i] + this.sbottom[i]) / 2;
        }
        _index_data() {
            return this._index_box(this._x.length);
        }
        _lrtb(i) {
            const l = this._x[i] - (this._width[i] / 2);
            const r = this._x[i] + (this._width[i] / 2);
            const t = Math.max(this._top[i], this._bottom[i]);
            const b = Math.min(this._top[i], this._bottom[i]);
            return [l, r, t, b];
        }
        _map_data() {
            this.sx = this.renderer.xscale.v_compute(this._x);
            this.sw = this.sdist(this.renderer.xscale, this._x, this._width, "center");
            this.stop = this.renderer.yscale.v_compute(this._top);
            this.sbottom = this.renderer.yscale.v_compute(this._bottom);
            const n = this.sx.length;
            this.sleft = new Float64Array(n);
            this.sright = new Float64Array(n);
            for (let i = 0; i < n; i++) {
                this.sleft[i] = this.sx[i] - this.sw[i] / 2;
                this.sright[i] = this.sx[i] + this.sw[i] / 2;
            }
            this._clamp_viewport();
        }
    }
    exports.VBarView = VBarView;
    VBarView.__name__ = "VBarView";
    class VBar extends box_1.Box {
        constructor(attrs) {
            super(attrs);
        }
        static init_VBar() {
            this.prototype.default_view = VBarView;
            this.coords([['x', 'bottom']]);
            this.define({
                width: [p.NumberSpec],
                top: [p.CoordinateSpec],
            });
            this.override({
                bottom: 0,
            });
        }
    }
    exports.VBar = VBar;
    VBar.__name__ = "VBar";
    VBar.init_VBar();
},
/* models/glyphs/wedge.js */ function _(require, module, exports) {
    const xy_glyph_1 = require(76) /* ./xy_glyph */;
    const utils_1 = require(84) /* ./utils */;
    const hittest = require(81) /* ../../core/hittest */;
    const p = require(18) /* ../../core/properties */;
    const math_1 = require(9) /* ../../core/util/math */;
    class WedgeView extends xy_glyph_1.XYGlyphView {
        _map_data() {
            if (this.model.properties.radius.units == "data")
                this.sradius = this.sdist(this.renderer.xscale, this._x, this._radius);
            else
                this.sradius = this._radius;
        }
        _render(ctx, indices, { sx, sy, sradius, _start_angle, _end_angle }) {
            const direction = this.model.properties.direction.value();
            for (const i of indices) {
                if (isNaN(sx[i] + sy[i] + sradius[i] + _start_angle[i] + _end_angle[i]))
                    continue;
                ctx.beginPath();
                ctx.arc(sx[i], sy[i], sradius[i], _start_angle[i], _end_angle[i], direction);
                ctx.lineTo(sx[i], sy[i]);
                ctx.closePath();
                if (this.visuals.fill.doit) {
                    this.visuals.fill.set_vectorize(ctx, i);
                    ctx.fill();
                }
                if (this.visuals.line.doit) {
                    this.visuals.line.set_vectorize(ctx, i);
                    ctx.stroke();
                }
            }
        }
        _hit_point(geometry) {
            let dist, sx0, sx1, sy0, sy1, x0, x1, y0, y1;
            const { sx, sy } = geometry;
            const x = this.renderer.xscale.invert(sx);
            const y = this.renderer.yscale.invert(sy);
            // check diameter first
            const max_diameter = 2 * this.max_radius;
            if (this.model.properties.radius.units === "data") {
                x0 = x - max_diameter;
                x1 = x + max_diameter;
                y0 = y - max_diameter;
                y1 = y + max_diameter;
            }
            else {
                sx0 = sx - max_diameter;
                sx1 = sx + max_diameter;
                [x0, x1] = this.renderer.xscale.r_invert(sx0, sx1);
                sy0 = sy - max_diameter;
                sy1 = sy + max_diameter;
                [y0, y1] = this.renderer.yscale.r_invert(sy0, sy1);
            }
            const candidates = [];
            for (const i of this.index.indices({ x0, x1, y0, y1 })) {
                const r2 = Math.pow(this.sradius[i], 2);
                [sx0, sx1] = this.renderer.xscale.r_compute(x, this._x[i]);
                [sy0, sy1] = this.renderer.yscale.r_compute(y, this._y[i]);
                dist = Math.pow(sx0 - sx1, 2) + Math.pow(sy0 - sy1, 2);
                if (dist <= r2) {
                    candidates.push([i, dist]);
                }
            }
            const direction = this.model.properties.direction.value();
            const hits = [];
            for (const [i, dist] of candidates) {
                // NOTE: minus the angle because JS uses non-mathy convention for angles
                const angle = Math.atan2(sy - this.sy[i], sx - this.sx[i]);
                if (math_1.angle_between(-angle, -this._start_angle[i], -this._end_angle[i], direction)) {
                    hits.push([i, dist]);
                }
            }
            return hittest.create_hit_test_result_from_hits(hits);
        }
        draw_legend_for_index(ctx, bbox, index) {
            utils_1.generic_area_legend(this.visuals, ctx, bbox, index);
        }
        _scenterxy(i) {
            const r = this.sradius[i] / 2;
            const a = (this._start_angle[i] + this._end_angle[i]) / 2;
            return { x: this.sx[i] + (r * Math.cos(a)), y: this.sy[i] + (r * Math.sin(a)) };
        }
        scenterx(i) {
            return this._scenterxy(i).x;
        }
        scentery(i) {
            return this._scenterxy(i).y;
        }
    }
    exports.WedgeView = WedgeView;
    WedgeView.__name__ = "WedgeView";
    class Wedge extends xy_glyph_1.XYGlyph {
        constructor(attrs) {
            super(attrs);
        }
        static init_Wedge() {
            this.prototype.default_view = WedgeView;
            this.mixins(['line', 'fill']);
            this.define({
                direction: [p.Direction, 'anticlock'],
                radius: [p.DistanceSpec],
                start_angle: [p.AngleSpec],
                end_angle: [p.AngleSpec],
            });
        }
    }
    exports.Wedge = Wedge;
    Wedge.__name__ = "Wedge";
    Wedge.init_Wedge();
},
/* models/graphs/index.js */ function _(require, module, exports) {
    function __export(m) {
        for (var p in m)
            if (!exports.hasOwnProperty(p))
                exports[p] = m[p];
    }
    __export(require(91) /* ./graph_hit_test_policy */);
    __export(require(231) /* ./layout_provider */);
    __export(require(232) /* ./static_layout_provider */);
},
/* models/graphs/layout_provider.js */ function _(require, module, exports) {
    const model_1 = require(64) /* ../../model */;
    class LayoutProvider extends model_1.Model {
        constructor(attrs) {
            super(attrs);
        }
    }
    exports.LayoutProvider = LayoutProvider;
    LayoutProvider.__name__ = "LayoutProvider";
},
/* models/graphs/static_layout_provider.js */ function _(require, module, exports) {
    const layout_provider_1 = require(231) /* ./layout_provider */;
    const p = require(18) /* ../../core/properties */;
    class StaticLayoutProvider extends layout_provider_1.LayoutProvider {
        constructor(attrs) {
            super(attrs);
        }
        static init_StaticLayoutProvider() {
            this.define({
                graph_layout: [p.Any, {}],
            });
        }
        get_node_coordinates(node_source) {
            const xs = [];
            const ys = [];
            const index = node_source.data.index;
            for (let i = 0, end = index.length; i < end; i++) {
                const point = this.graph_layout[index[i]];
                const [x, y] = point != null ? point : [NaN, NaN];
                xs.push(x);
                ys.push(y);
            }
            return [xs, ys];
        }
        get_edge_coordinates(edge_source) {
            const xs = [];
            const ys = [];
            const starts = edge_source.data.start;
            const ends = edge_source.data.end;
            const has_paths = (edge_source.data.xs != null) && (edge_source.data.ys != null);
            for (let i = 0, endi = starts.length; i < endi; i++) {
                const in_layout = (this.graph_layout[starts[i]] != null) && (this.graph_layout[ends[i]] != null);
                if (has_paths && in_layout) {
                    xs.push(edge_source.data.xs[i]);
                    ys.push(edge_source.data.ys[i]);
                }
                else {
                    let end, start;
                    if (in_layout)
                        [start, end] = [this.graph_layout[starts[i]], this.graph_layout[ends[i]]];
                    else
                        [start, end] = [[NaN, NaN], [NaN, NaN]];
                    xs.push([start[0], end[0]]);
                    ys.push([start[1], end[1]]);
                }
            }
            return [xs, ys];
        }
    }
    exports.StaticLayoutProvider = StaticLayoutProvider;
    StaticLayoutProvider.__name__ = "StaticLayoutProvider";
    StaticLayoutProvider.init_StaticLayoutProvider();
},
/* models/grids/index.js */ function _(require, module, exports) {
    var grid_1 = require(234) /* ./grid */;
    exports.Grid = grid_1.Grid;
},
/* models/grids/grid.js */ function _(require, module, exports) {
    const guide_renderer_1 = require(142) /* ../renderers/guide_renderer */;
    const p = require(18) /* ../../core/properties */;
    const types_1 = require(7) /* ../../core/util/types */;
    class GridView extends guide_renderer_1.GuideRendererView {
        get _x_range_name() {
            return this.model.x_range_name;
        }
        get _y_range_name() {
            return this.model.y_range_name;
        }
        render() {
            if (!this.model.visible)
                return;
            const ctx = this.plot_view.canvas_view.ctx;
            ctx.save();
            this._draw_regions(ctx);
            this._draw_minor_grids(ctx);
            this._draw_grids(ctx);
            ctx.restore();
        }
        connect_signals() {
            super.connect_signals();
            this.connect(this.model.change, () => this.request_render());
        }
        _draw_regions(ctx) {
            if (!this.visuals.band_fill.doit && !this.visuals.band_hatch.doit)
                return;
            this.visuals.band_fill.set_value(ctx);
            const [xs, ys] = this.grid_coords('major', false);
            for (let i = 0; i < xs.length - 1; i++) {
                if (i % 2 != 1)
                    continue;
                const [sx0, sy0] = this.plot_view.map_to_screen(xs[i], ys[i], this._x_range_name, this._y_range_name);
                const [sx1, sy1] = this.plot_view.map_to_screen(xs[i + 1], ys[i + 1], this._x_range_name, this._y_range_name);
                if (this.visuals.band_fill.doit)
                    ctx.fillRect(sx0[0], sy0[0], sx1[1] - sx0[0], sy1[1] - sy0[0]);
                this.visuals.band_hatch.doit2(ctx, i, () => {
                    ctx.fillRect(sx0[0], sy0[0], sx1[1] - sx0[0], sy1[1] - sy0[0]);
                }, () => this.request_render());
            }
        }
        _draw_grids(ctx) {
            if (!this.visuals.grid_line.doit)
                return;
            const [xs, ys] = this.grid_coords('major');
            this._draw_grid_helper(ctx, this.visuals.grid_line, xs, ys);
        }
        _draw_minor_grids(ctx) {
            if (!this.visuals.minor_grid_line.doit)
                return;
            const [xs, ys] = this.grid_coords('minor');
            this._draw_grid_helper(ctx, this.visuals.minor_grid_line, xs, ys);
        }
        _draw_grid_helper(ctx, visuals, xs, ys) {
            visuals.set_value(ctx);
            for (let i = 0; i < xs.length; i++) {
                const [sx, sy] = this.plot_view.map_to_screen(xs[i], ys[i], this._x_range_name, this._y_range_name);
                ctx.beginPath();
                ctx.moveTo(Math.round(sx[0]), Math.round(sy[0]));
                for (let i = 1; i < sx.length; i++)
                    ctx.lineTo(Math.round(sx[i]), Math.round(sy[i]));
                ctx.stroke();
            }
        }
        // {{{ TODO: state
        ranges() {
            const i = this.model.dimension;
            const j = (i + 1) % 2;
            const frame = this.plot_view.frame;
            const ranges = [
                frame.x_ranges[this.model.x_range_name],
                frame.y_ranges[this.model.y_range_name],
            ];
            return [ranges[i], ranges[j]];
        }
        computed_bounds() {
            const [range] = this.ranges();
            const user_bounds = this.model.bounds;
            const range_bounds = [range.min, range.max];
            let start;
            let end;
            if (types_1.isArray(user_bounds)) {
                start = Math.min(user_bounds[0], user_bounds[1]);
                end = Math.max(user_bounds[0], user_bounds[1]);
                if (start < range_bounds[0])
                    start = range_bounds[0];
                // XXX:
                //else if (start > range_bounds[1])
                //  start = null
                if (end > range_bounds[1])
                    end = range_bounds[1];
                // XXX:
                //else if (end < range_bounds[0])
                //  end = null
            }
            else {
                [start, end] = range_bounds;
                for (const axis_view of this.plot_view.axis_views) {
                    if (axis_view.dimension == this.model.dimension
                        && axis_view.model.x_range_name == this.model.x_range_name
                        && axis_view.model.y_range_name == this.model.y_range_name) {
                        [start, end] = axis_view.computed_bounds;
                    }
                }
            }
            return [start, end];
        }
        grid_coords(location, exclude_ends = true) {
            const i = this.model.dimension;
            const j = (i + 1) % 2;
            const [range, cross_range] = this.ranges();
            let [start, end] = this.computed_bounds();
            [start, end] = [Math.min(start, end), Math.max(start, end)];
            // TODO: (bev) using cross_range.min for cross_loc is a bit of a cheat. Since we
            // currently only support "straight line" grids, this should be OK for now. If
            // we ever want to support "curved" grids, e.g. for some projections, we may
            // have to communicate more than just a single cross location.
            const ticks = this.model.ticker.get_ticks(start, end, range, cross_range.min, {})[location];
            const min = range.min;
            const max = range.max;
            const cmin = cross_range.min;
            const cmax = cross_range.max;
            const coords = [[], []];
            if (!exclude_ends) {
                if (ticks[0] != min)
                    ticks.splice(0, 0, min);
                if (ticks[ticks.length - 1] != max)
                    ticks.push(max);
            }
            for (let ii = 0; ii < ticks.length; ii++) {
                if ((ticks[ii] == min || ticks[ii] == max) && exclude_ends)
                    continue;
                const dim_i = [];
                const dim_j = [];
                const N = 2;
                for (let n = 0; n < N; n++) {
                    const loc = cmin + (cmax - cmin) / (N - 1) * n;
                    dim_i.push(ticks[ii]);
                    dim_j.push(loc);
                }
                coords[i].push(dim_i);
                coords[j].push(dim_j);
            }
            return coords;
        }
    }
    exports.GridView = GridView;
    GridView.__name__ = "GridView";
    class Grid extends guide_renderer_1.GuideRenderer {
        constructor(attrs) {
            super(attrs);
        }
        static init_Grid() {
            this.prototype.default_view = GridView;
            this.mixins(['line:grid_', 'line:minor_grid_', 'fill:band_', 'hatch:band_']);
            this.define({
                bounds: [p.Any, 'auto'],
                dimension: [p.Any, 0],
                ticker: [p.Instance],
                x_range_name: [p.String, 'default'],
                y_range_name: [p.String, 'default'],
            });
            this.override({
                level: "underlay",
                band_fill_color: null,
                band_fill_alpha: 0,
                grid_line_color: '#e5e5e5',
                minor_grid_line_color: null,
            });
        }
    }
    exports.Grid = Grid;
    Grid.__name__ = "Grid";
    Grid.init_Grid();
},
/* models/layouts/index.js */ function _(require, module, exports) {
    var box_1 = require(236) /* ./box */;
    exports.Box = box_1.Box;
    var column_1 = require(238) /* ./column */;
    exports.Column = column_1.Column;
    var grid_box_1 = require(239) /* ./grid_box */;
    exports.GridBox = grid_box_1.GridBox;
    var html_box_1 = require(240) /* ./html_box */;
    exports.HTMLBox = html_box_1.HTMLBox;
    var layout_dom_1 = require(237) /* ./layout_dom */;
    exports.LayoutDOM = layout_dom_1.LayoutDOM;
    var row_1 = require(241) /* ./row */;
    exports.Row = row_1.Row;
    var spacer_1 = require(242) /* ./spacer */;
    exports.Spacer = spacer_1.Spacer;
    var tabs_1 = require(243) /* ./tabs */;
    exports.Panel = tabs_1.Panel;
    exports.Tabs = tabs_1.Tabs;
    var widget_box_1 = require(247) /* ./widget_box */;
    exports.WidgetBox = widget_box_1.WidgetBox;
},
/* models/layouts/box.js */ function _(require, module, exports) {
    const layout_dom_1 = require(237) /* ./layout_dom */;
    const p = require(18) /* ../../core/properties */;
    class BoxView extends layout_dom_1.LayoutDOMView {
        connect_signals() {
            super.connect_signals();
            this.connect(this.model.properties.children.change, () => this.rebuild());
        }
        get child_models() {
            return this.model.children;
        }
    }
    exports.BoxView = BoxView;
    BoxView.__name__ = "BoxView";
    class Box extends layout_dom_1.LayoutDOM {
        constructor(attrs) {
            super(attrs);
        }
        static init_Box() {
            this.define({
                children: [p.Array, []],
                spacing: [p.Number, 0],
            });
        }
    }
    exports.Box = Box;
    Box.__name__ = "Box";
    Box.init_Box();
},
/* models/layouts/layout_dom.js */ function _(require, module, exports) {
    const model_1 = require(64) /* ../../model */;
    const dom_1 = require(61) /* ../../core/dom */;
    const logging_1 = require(65) /* ../../core/logging */;
    const types_1 = require(7) /* ../../core/util/types */;
    const p = require(18) /* ../../core/properties */;
    const build_views_1 = require(92) /* ../../core/build_views */;
    const dom_view_1 = require(59) /* ../../core/dom_view */;
    const root_1 = require(62) /* ../../styles/root */;
    class LayoutDOMView extends dom_view_1.DOMView {
        constructor() {
            super(...arguments);
            this._idle_notified = false;
            this._offset_parent = null;
            this._viewport = {};
        }
        initialize() {
            super.initialize();
            this.el.style.position = this.is_root ? "relative" : "absolute";
            this._child_views = {};
            this.build_child_views();
        }
        remove() {
            for (const child_view of this.child_views)
                child_view.remove();
            this._child_views = {};
            super.remove();
        }
        connect_signals() {
            super.connect_signals();
            if (this.is_root) {
                this._on_resize = () => this.resize_layout();
                window.addEventListener("resize", this._on_resize);
                this._parent_observer = setInterval(() => {
                    const offset_parent = this.el.offsetParent;
                    if (this._offset_parent != offset_parent) {
                        this._offset_parent = offset_parent;
                        if (offset_parent != null) {
                            this.compute_viewport();
                            this.invalidate_layout();
                        }
                    }
                }, 250);
            }
            const p = this.model.properties;
            this.on_change([
                p.width, p.height,
                p.min_width, p.min_height,
                p.max_width, p.max_height,
                p.margin,
                p.width_policy, p.height_policy, p.sizing_mode,
                p.aspect_ratio,
                p.visible,
            ], () => this.invalidate_layout());
            this.on_change([
                p.background,
                p.css_classes,
            ], () => this.invalidate_render());
        }
        disconnect_signals() {
            if (this._parent_observer != null)
                clearTimeout(this._parent_observer);
            if (this._on_resize != null)
                window.removeEventListener("resize", this._on_resize);
            super.disconnect_signals();
        }
        css_classes() {
            return super.css_classes().concat(this.model.css_classes);
        }
        get child_views() {
            return this.child_models.map((child) => this._child_views[child.id]);
        }
        build_child_views() {
            build_views_1.build_views(this._child_views, this.child_models, { parent: this });
        }
        render() {
            super.render();
            dom_1.empty(this.el); // XXX: this should be in super
            const { background } = this.model;
            this.el.style.backgroundColor = background != null ? background : "";
            dom_1.classes(this.el).clear().add(...this.css_classes());
            for (const child_view of this.child_views) {
                this.el.appendChild(child_view.el);
                child_view.render();
            }
        }
        update_layout() {
            for (const child_view of this.child_views)
                child_view.update_layout();
            this._update_layout();
        }
        update_position() {
            this.el.style.display = this.model.visible ? "block" : "none";
            const margin = this.is_root ? this.layout.sizing.margin : undefined;
            dom_1.position(this.el, this.layout.bbox, margin);
            for (const child_view of this.child_views)
                child_view.update_position();
        }
        after_layout() {
            for (const child_view of this.child_views)
                child_view.after_layout();
            this._has_finished = true;
        }
        compute_viewport() {
            this._viewport = this._viewport_size();
        }
        renderTo(element) {
            element.appendChild(this.el);
            this._offset_parent = this.el.offsetParent;
            this.compute_viewport();
            this.build();
        }
        build() {
            this.assert_root();
            this.render();
            this.update_layout();
            this.compute_layout();
            return this;
        }
        rebuild() {
            this.build_child_views();
            this.invalidate_render();
        }
        compute_layout() {
            const start = Date.now();
            this.layout.compute(this._viewport);
            this.update_position();
            this.after_layout();
            logging_1.logger.debug(`layout computed in ${Date.now() - start} ms`);
            this.notify_finished();
        }
        resize_layout() {
            this.root.compute_viewport();
            this.root.compute_layout();
        }
        invalidate_layout() {
            this.root.update_layout();
            this.root.compute_layout();
        }
        invalidate_render() {
            this.render();
            this.invalidate_layout();
        }
        has_finished() {
            if (!super.has_finished())
                return false;
            for (const child_view of this.child_views) {
                if (!child_view.has_finished())
                    return false;
            }
            return true;
        }
        notify_finished() {
            if (!this.is_root)
                this.root.notify_finished();
            else {
                if (!this._idle_notified && this.has_finished()) {
                    if (this.model.document != null) {
                        this._idle_notified = true;
                        this.model.document.notify_idle(this.model);
                    }
                }
            }
        }
        _width_policy() {
            return this.model.width != null ? "fixed" : "fit";
        }
        _height_policy() {
            return this.model.height != null ? "fixed" : "fit";
        }
        box_sizing() {
            let { width_policy, height_policy, aspect_ratio } = this.model;
            if (width_policy == "auto")
                width_policy = this._width_policy();
            if (height_policy == "auto")
                height_policy = this._height_policy();
            const { sizing_mode } = this.model;
            if (sizing_mode != null) {
                if (sizing_mode == "fixed")
                    width_policy = height_policy = "fixed";
                else if (sizing_mode == "stretch_both")
                    width_policy = height_policy = "max";
                else if (sizing_mode == "stretch_width")
                    width_policy = "max";
                else if (sizing_mode == "stretch_height")
                    height_policy = "max";
                else {
                    if (aspect_ratio == null)
                        aspect_ratio = "auto";
                    switch (sizing_mode) {
                        case "scale_width":
                            width_policy = "max";
                            height_policy = "min";
                            break;
                        case "scale_height":
                            width_policy = "min";
                            height_policy = "max";
                            break;
                        case "scale_both":
                            width_policy = "max";
                            height_policy = "max";
                            break;
                        default:
                            throw new Error("unreachable");
                    }
                }
            }
            const sizing = { width_policy, height_policy };
            const { min_width, min_height } = this.model;
            if (min_width != null)
                sizing.min_width = min_width;
            if (min_height != null)
                sizing.min_height = min_height;
            const { width, height } = this.model;
            if (width != null)
                sizing.width = width;
            if (height != null)
                sizing.height = height;
            const { max_width, max_height } = this.model;
            if (max_width != null)
                sizing.max_width = max_width;
            if (max_height != null)
                sizing.max_height = max_height;
            if (aspect_ratio == "auto" && width != null && height != null)
                sizing.aspect = width / height;
            else if (types_1.isNumber(aspect_ratio))
                sizing.aspect = aspect_ratio;
            const { margin } = this.model;
            if (margin != null) {
                if (types_1.isNumber(margin))
                    sizing.margin = { top: margin, right: margin, bottom: margin, left: margin };
                else if (margin.length == 2) {
                    const [vertical, horizontal] = margin;
                    sizing.margin = { top: vertical, right: horizontal, bottom: vertical, left: horizontal };
                }
                else {
                    const [top, right, bottom, left] = margin;
                    sizing.margin = { top, right, bottom, left };
                }
            }
            sizing.visible = this.model.visible;
            const { align } = this.model;
            if (types_1.isArray(align))
                [sizing.halign, sizing.valign] = align;
            else
                sizing.halign = sizing.valign = align;
            return sizing;
        }
        _viewport_size() {
            return dom_1.undisplayed(this.el, () => {
                let measuring = this.el;
                while (measuring = measuring.parentElement) {
                    // .bk-root element doesn't bring any value
                    if (measuring.classList.contains(root_1.bk_root))
                        continue;
                    // we reached <body> element, so use viewport size
                    if (measuring == document.body) {
                        const { margin: { left, right, top, bottom } } = dom_1.extents(document.body);
                        const width = Math.ceil(document.documentElement.clientWidth - left - right);
                        const height = Math.ceil(document.documentElement.clientHeight - top - bottom);
                        return { width, height };
                    }
                    // stop on first element with sensible dimensions
                    const { padding: { left, right, top, bottom } } = dom_1.extents(measuring);
                    const { width, height } = measuring.getBoundingClientRect();
                    const inner_width = Math.ceil(width - left - right);
                    const inner_height = Math.ceil(height - top - bottom);
                    if (inner_width > 0 || inner_height > 0)
                        return {
                            width: inner_width > 0 ? inner_width : undefined,
                            height: inner_height > 0 ? inner_height : undefined,
                        };
                }
                // this element is detached from DOM
                return {};
            });
        }
        serializable_state() {
            return Object.assign(Object.assign({}, super.serializable_state()), { bbox: this.layout.bbox.box, children: this.child_views.map((child) => child.serializable_state()) });
        }
    }
    exports.LayoutDOMView = LayoutDOMView;
    LayoutDOMView.__name__ = "LayoutDOMView";
    class LayoutDOM extends model_1.Model {
        constructor(attrs) {
            super(attrs);
        }
        static init_LayoutDOM() {
            this.define({
                width: [p.Number, null],
                height: [p.Number, null],
                min_width: [p.Number, null],
                min_height: [p.Number, null],
                max_width: [p.Number, null],
                max_height: [p.Number, null],
                margin: [p.Any, [0, 0, 0, 0]],
                width_policy: [p.Any, "auto"],
                height_policy: [p.Any, "auto"],
                aspect_ratio: [p.Any, null],
                sizing_mode: [p.SizingMode, null],
                visible: [p.Boolean, true],
                disabled: [p.Boolean, false],
                align: [p.Any, "start"],
                background: [p.Color, null],
                css_classes: [p.Array, []],
            });
        }
    }
    exports.LayoutDOM = LayoutDOM;
    LayoutDOM.__name__ = "LayoutDOM";
    LayoutDOM.init_LayoutDOM();
},
/* models/layouts/column.js */ function _(require, module, exports) {
    const box_1 = require(236) /* ./box */;
    const grid_1 = require(184) /* ../../core/layout/grid */;
    const p = require(18) /* ../../core/properties */;
    class ColumnView extends box_1.BoxView {
        _update_layout() {
            const items = this.child_views.map((child) => child.layout);
            this.layout = new grid_1.Column(items);
            this.layout.rows = this.model.rows;
            this.layout.spacing = [this.model.spacing, 0];
            this.layout.set_sizing(this.box_sizing());
        }
    }
    exports.ColumnView = ColumnView;
    ColumnView.__name__ = "ColumnView";
    class Column extends box_1.Box {
        constructor(attrs) {
            super(attrs);
        }
        static init_Column() {
            this.prototype.default_view = ColumnView;
            this.define({
                rows: [p.Any, "auto"],
            });
        }
    }
    exports.Column = Column;
    Column.__name__ = "Column";
    Column.init_Column();
},
/* models/layouts/grid_box.js */ function _(require, module, exports) {
    const layout_dom_1 = require(237) /* ./layout_dom */;
    const grid_1 = require(184) /* ../../core/layout/grid */;
    const p = require(18) /* ../../core/properties */;
    class GridBoxView extends layout_dom_1.LayoutDOMView {
        connect_signals() {
            super.connect_signals();
            this.connect(this.model.properties.children.change, () => this.rebuild());
        }
        get child_models() {
            return this.model.children.map(([child]) => child);
        }
        _update_layout() {
            this.layout = new grid_1.Grid();
            this.layout.rows = this.model.rows;
            this.layout.cols = this.model.cols;
            this.layout.spacing = this.model.spacing;
            for (const [child, row, col, row_span, col_span] of this.model.children) {
                const child_view = this._child_views[child.id];
                this.layout.items.push({ layout: child_view.layout, row, col, row_span, col_span });
            }
            this.layout.set_sizing(this.box_sizing());
        }
    }
    exports.GridBoxView = GridBoxView;
    GridBoxView.__name__ = "GridBoxView";
    class GridBox extends layout_dom_1.LayoutDOM {
        constructor(attrs) {
            super(attrs);
        }
        static init_GridBox() {
            this.prototype.default_view = GridBoxView;
            this.define({
                children: [p.Array, []],
                rows: [p.Any, "auto"],
                cols: [p.Any, "auto"],
                spacing: [p.Any, 0],
            });
        }
    }
    exports.GridBox = GridBox;
    GridBox.__name__ = "GridBox";
    GridBox.init_GridBox();
},
/* models/layouts/html_box.js */ function _(require, module, exports) {
    const layout_dom_1 = require(237) /* ../layouts/layout_dom */;
    const layout_1 = require(180) /* ../../core/layout */;
    class HTMLBoxView extends layout_dom_1.LayoutDOMView {
        get child_models() {
            return [];
        }
        _update_layout() {
            this.layout = new layout_1.ContentBox(this.el);
            this.layout.set_sizing(this.box_sizing());
        }
    }
    exports.HTMLBoxView = HTMLBoxView;
    HTMLBoxView.__name__ = "HTMLBoxView";
    class HTMLBox extends layout_dom_1.LayoutDOM {
        constructor(attrs) {
            super(attrs);
        }
    }
    exports.HTMLBox = HTMLBox;
    HTMLBox.__name__ = "HTMLBox";
},
/* models/layouts/row.js */ function _(require, module, exports) {
    const box_1 = require(236) /* ./box */;
    const grid_1 = require(184) /* ../../core/layout/grid */;
    const p = require(18) /* ../../core/properties */;
    class RowView extends box_1.BoxView {
        _update_layout() {
            const items = this.child_views.map((child) => child.layout);
            this.layout = new grid_1.Row(items);
            this.layout.cols = this.model.cols;
            this.layout.spacing = [0, this.model.spacing];
            this.layout.set_sizing(this.box_sizing());
        }
    }
    exports.RowView = RowView;
    RowView.__name__ = "RowView";
    class Row extends box_1.Box {
        constructor(attrs) {
            super(attrs);
        }
        static init_Row() {
            this.prototype.default_view = RowView;
            this.define({
                cols: [p.Any, "auto"],
            });
        }
    }
    exports.Row = Row;
    Row.__name__ = "Row";
    Row.init_Row();
},
/* models/layouts/spacer.js */ function _(require, module, exports) {
    const layout_dom_1 = require(237) /* ./layout_dom */;
    const layout_1 = require(180) /* ../../core/layout */;
    class SpacerView extends layout_dom_1.LayoutDOMView {
        get child_models() {
            return [];
        }
        _update_layout() {
            this.layout = new layout_1.LayoutItem();
            this.layout.set_sizing(this.box_sizing());
        }
    }
    exports.SpacerView = SpacerView;
    SpacerView.__name__ = "SpacerView";
    class Spacer extends layout_dom_1.LayoutDOM {
        constructor(attrs) {
            super(attrs);
        }
        static init_Spacer() {
            this.prototype.default_view = SpacerView;
        }
    }
    exports.Spacer = Spacer;
    Spacer.__name__ = "Spacer";
    Spacer.init_Spacer();
},
/* models/layouts/tabs.js */ function _(require, module, exports) {
    const layout_1 = require(180) /* ../../core/layout */;
    const dom_1 = require(61) /* ../../core/dom */;
    const array_1 = require(8) /* ../../core/util/array */;
    const p = require(18) /* ../../core/properties */;
    const layout_dom_1 = require(237) /* ./layout_dom */;
    const model_1 = require(64) /* ../../model */;
    const mixins_1 = require(138) /* ../../styles/mixins */;
    const tabs_1 = require(244) /* ../../styles/tabs */;
    const buttons_1 = require(245) /* ../../styles/buttons */;
    const menus_1 = require(246) /* ../../styles/menus */;
    class TabsView extends layout_dom_1.LayoutDOMView {
        connect_signals() {
            super.connect_signals();
            this.connect(this.model.properties.tabs.change, () => this.rebuild());
            this.connect(this.model.properties.active.change, () => this.on_active_change());
        }
        get child_models() {
            return this.model.tabs.map((tab) => tab.child);
        }
        _update_layout() {
            const loc = this.model.tabs_location;
            const vertical = loc == "above" || loc == "below";
            // XXX: this is a hack, this should be handled by "fit" policy in grid layout
            const { scroll_el, headers_el } = this;
            this.header = new class extends layout_1.ContentBox {
                _measure(viewport) {
                    const min_headers = 3;
                    const scroll = dom_1.size(scroll_el);
                    const headers = dom_1.children(headers_el).slice(0, min_headers).map((el) => dom_1.size(el));
                    const { width, height } = super._measure(viewport);
                    if (vertical) {
                        const min_width = scroll.width + array_1.sum(headers.map((size) => size.width));
                        return { width: viewport.width != Infinity ? viewport.width : min_width, height };
                    }
                    else {
                        const min_height = scroll.height + array_1.sum(headers.map((size) => size.height));
                        return { width, height: viewport.height != Infinity ? viewport.height : min_height };
                    }
                }
            }(this.header_el);
            if (vertical)
                this.header.set_sizing({ width_policy: "fit", height_policy: "fixed" });
            else
                this.header.set_sizing({ width_policy: "fixed", height_policy: "fit" });
            let row = 1;
            let col = 1;
            switch (loc) {
                case "above":
                    row -= 1;
                    break;
                case "below":
                    row += 1;
                    break;
                case "left":
                    col -= 1;
                    break;
                case "right":
                    col += 1;
                    break;
            }
            const header = { layout: this.header, row, col };
            const panels = this.child_views.map((child_view) => {
                return { layout: child_view.layout, row: 1, col: 1 };
            });
            this.layout = new layout_1.Grid([header, ...panels]);
            this.layout.set_sizing(this.box_sizing());
        }
        update_position() {
            super.update_position();
            this.header_el.style.position = "absolute"; // XXX: do it in position()
            dom_1.position(this.header_el, this.header.bbox);
            const loc = this.model.tabs_location;
            const vertical = loc == "above" || loc == "below";
            const scroll_el_size = dom_1.size(this.scroll_el);
            const headers_el_size = dom_1.scroll_size(this.headers_el);
            if (vertical) {
                const { width } = this.header.bbox;
                if (headers_el_size.width > width) {
                    this.wrapper_el.style.maxWidth = `${width - scroll_el_size.width}px`;
                    dom_1.display(this.scroll_el);
                }
                else {
                    this.wrapper_el.style.maxWidth = "";
                    dom_1.undisplay(this.scroll_el);
                }
            }
            else {
                const { height } = this.header.bbox;
                if (headers_el_size.height > height) {
                    this.wrapper_el.style.maxHeight = `${height - scroll_el_size.height}px`;
                    dom_1.display(this.scroll_el);
                }
                else {
                    this.wrapper_el.style.maxHeight = "";
                    dom_1.undisplay(this.scroll_el);
                }
            }
            const { child_views } = this;
            for (const child_view of child_views)
                dom_1.hide(child_view.el);
            const tab = child_views[this.model.active];
            if (tab != null)
                dom_1.show(tab.el);
        }
        render() {
            super.render();
            const { active } = this.model;
            const loc = this.model.tabs_location;
            const vertical = loc == "above" || loc == "below";
            const headers = this.model.tabs.map((tab, i) => {
                const el = dom_1.div({ class: [tabs_1.bk_tab, i == active ? mixins_1.bk_active : null] }, tab.title);
                el.addEventListener("click", (event) => {
                    if (event.target == event.currentTarget)
                        this.change_active(i);
                });
                if (tab.closable) {
                    const close_el = dom_1.div({ class: tabs_1.bk_close });
                    close_el.addEventListener("click", (event) => {
                        if (event.target == event.currentTarget) {
                            this.model.tabs = array_1.remove_at(this.model.tabs, i);
                            const ntabs = this.model.tabs.length;
                            if (this.model.active > ntabs - 1)
                                this.model.active = ntabs - 1;
                        }
                    });
                    el.appendChild(close_el);
                }
                return el;
            });
            this.headers_el = dom_1.div({ class: [tabs_1.bk_headers] }, headers);
            this.wrapper_el = dom_1.div({ class: tabs_1.bk_headers_wrapper }, this.headers_el);
            const left_el = dom_1.div({ class: [buttons_1.bk_btn, buttons_1.bk_btn_default], disabled: "" }, dom_1.div({ class: [menus_1.bk_caret, mixins_1.bk_left] }));
            const right_el = dom_1.div({ class: [buttons_1.bk_btn, buttons_1.bk_btn_default] }, dom_1.div({ class: [menus_1.bk_caret, mixins_1.bk_right] }));
            let scroll_index = 0;
            const do_scroll = (dir) => {
                return () => {
                    const ntabs = this.model.tabs.length;
                    if (dir == "left")
                        scroll_index = Math.max(scroll_index - 1, 0);
                    else
                        scroll_index = Math.min(scroll_index + 1, ntabs - 1);
                    if (scroll_index == 0)
                        left_el.setAttribute("disabled", "");
                    else
                        left_el.removeAttribute("disabled");
                    if (scroll_index == ntabs - 1)
                        right_el.setAttribute("disabled", "");
                    else
                        right_el.removeAttribute("disabled");
                    const sizes = dom_1.children(this.headers_el)
                        .slice(0, scroll_index)
                        .map((el) => el.getBoundingClientRect());
                    if (vertical) {
                        const left = -array_1.sum(sizes.map((size) => size.width));
                        this.headers_el.style.left = `${left}px`;
                    }
                    else {
                        const top = -array_1.sum(sizes.map((size) => size.height));
                        this.headers_el.style.top = `${top}px`;
                    }
                };
            };
            left_el.addEventListener("click", do_scroll("left"));
            right_el.addEventListener("click", do_scroll("right"));
            this.scroll_el = dom_1.div({ class: buttons_1.bk_btn_group }, left_el, right_el);
            this.header_el = dom_1.div({ class: [tabs_1.bk_tabs_header, mixins_1.bk_side(loc)] }, this.scroll_el, this.wrapper_el);
            this.el.appendChild(this.header_el);
        }
        change_active(i) {
            if (i != this.model.active) {
                this.model.active = i;
                if (this.model.callback != null)
                    this.model.callback.execute(this.model);
            }
        }
        on_active_change() {
            const i = this.model.active;
            const headers = dom_1.children(this.headers_el);
            for (const el of headers)
                el.classList.remove(mixins_1.bk_active);
            headers[i].classList.add(mixins_1.bk_active);
            const { child_views } = this;
            for (const child_view of child_views)
                dom_1.hide(child_view.el);
            dom_1.show(child_views[i].el);
        }
    }
    exports.TabsView = TabsView;
    TabsView.__name__ = "TabsView";
    class Tabs extends layout_dom_1.LayoutDOM {
        constructor(attrs) {
            super(attrs);
        }
        static init_Tabs() {
            this.prototype.default_view = TabsView;
            this.define({
                tabs: [p.Array, []],
                tabs_location: [p.Location, "above"],
                active: [p.Number, 0],
                callback: [p.Any],
            });
        }
    }
    exports.Tabs = Tabs;
    Tabs.__name__ = "Tabs";
    Tabs.init_Tabs();
    class Panel extends model_1.Model {
        constructor(attrs) {
            super(attrs);
        }
        static init_Panel() {
            this.define({
                title: [p.String, ""],
                child: [p.Instance],
                closable: [p.Boolean, false],
            });
        }
    }
    exports.Panel = Panel;
    Panel.__name__ = "Panel";
    Panel.init_Panel();
},
/* styles/tabs.js */ function _(require, module, exports) {
    require(62) /* ./root */;
    const _a = require(61) /* ../core/dom */;
    _a.styles.append(".bk-root .bk-tabs-header {\n  display: flex;\n  display: -webkit-flex;\n  flex-wrap: nowrap;\n  -webkit-flex-wrap: nowrap;\n  align-items: center;\n  -webkit-align-items: center;\n  overflow: hidden;\n  user-select: none;\n  -ms-user-select: none;\n  -moz-user-select: none;\n  -webkit-user-select: none;\n}\n.bk-root .bk-tabs-header .bk-btn-group {\n  height: auto;\n  margin-right: 5px;\n}\n.bk-root .bk-tabs-header .bk-btn-group > .bk-btn {\n  flex-grow: 0;\n  -webkit-flex-grow: 0;\n  height: auto;\n  padding: 4px 4px;\n}\n.bk-root .bk-tabs-header .bk-headers-wrapper {\n  flex-grow: 1;\n  -webkit-flex-grow: 1;\n  overflow: hidden;\n  color: #666666;\n}\n.bk-root .bk-tabs-header.bk-above .bk-headers-wrapper {\n  border-bottom: 1px solid #e6e6e6;\n}\n.bk-root .bk-tabs-header.bk-right .bk-headers-wrapper {\n  border-left: 1px solid #e6e6e6;\n}\n.bk-root .bk-tabs-header.bk-below .bk-headers-wrapper {\n  border-top: 1px solid #e6e6e6;\n}\n.bk-root .bk-tabs-header.bk-left .bk-headers-wrapper {\n  border-right: 1px solid #e6e6e6;\n}\n.bk-root .bk-tabs-header.bk-above,\n.bk-root .bk-tabs-header.bk-below {\n  flex-direction: row;\n  -webkit-flex-direction: row;\n}\n.bk-root .bk-tabs-header.bk-above .bk-headers,\n.bk-root .bk-tabs-header.bk-below .bk-headers {\n  flex-direction: row;\n  -webkit-flex-direction: row;\n}\n.bk-root .bk-tabs-header.bk-left,\n.bk-root .bk-tabs-header.bk-right {\n  flex-direction: column;\n  -webkit-flex-direction: column;\n}\n.bk-root .bk-tabs-header.bk-left .bk-headers,\n.bk-root .bk-tabs-header.bk-right .bk-headers {\n  flex-direction: column;\n  -webkit-flex-direction: column;\n}\n.bk-root .bk-tabs-header .bk-headers {\n  position: relative;\n  display: flex;\n  display: -webkit-flex;\n  flex-wrap: nowrap;\n  -webkit-flex-wrap: nowrap;\n  align-items: center;\n  -webkit-align-items: center;\n}\n.bk-root .bk-tabs-header .bk-tab {\n  padding: 4px 8px;\n  border: solid transparent;\n  white-space: nowrap;\n  cursor: pointer;\n}\n.bk-root .bk-tabs-header .bk-tab:hover {\n  background-color: #f2f2f2;\n}\n.bk-root .bk-tabs-header .bk-tab.bk-active {\n  color: #4d4d4d;\n  background-color: white;\n  border-color: #e6e6e6;\n}\n.bk-root .bk-tabs-header .bk-tab .bk-close {\n  margin-left: 10px;\n}\n.bk-root .bk-tabs-header.bk-above .bk-tab {\n  border-width: 3px 1px 0px 1px;\n  border-radius: 4px 4px 0 0;\n}\n.bk-root .bk-tabs-header.bk-right .bk-tab {\n  border-width: 1px 3px 1px 0px;\n  border-radius: 0 4px 4px 0;\n}\n.bk-root .bk-tabs-header.bk-below .bk-tab {\n  border-width: 0px 1px 3px 1px;\n  border-radius: 0 0 4px 4px;\n}\n.bk-root .bk-tabs-header.bk-left .bk-tab {\n  border-width: 1px 0px 1px 3px;\n  border-radius: 4px 0 0 4px;\n}\n.bk-root .bk-close {\n  display: inline-block;\n  width: 10px;\n  height: 10px;\n  vertical-align: middle;\n  background-image: url('data:image/svg+xml;utf8,\\\n      <svg viewPort=\"0 0 10 10\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\\\n        <line x1=\"1\" y1=\"9\" x2=\"9\" y2=\"1\" stroke=\"gray\" stroke-width=\"2\"/>\\\n        <line x1=\"1\" y1=\"1\" x2=\"9\" y2=\"9\" stroke=\"gray\" stroke-width=\"2\"/>\\\n      </svg>');\n}\n.bk-root .bk-close:hover {\n  background-image: url('data:image/svg+xml;utf8,\\\n      <svg viewPort=\"0 0 10 10\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\\\n        <line x1=\"1\" y1=\"9\" x2=\"9\" y2=\"1\" stroke=\"red\" stroke-width=\"2\"/>\\\n        <line x1=\"1\" y1=\"1\" x2=\"9\" y2=\"9\" stroke=\"red\" stroke-width=\"2\"/>\\\n      </svg>');\n}\n");
    exports.bk_tabs_header = "bk-tabs-header";
    exports.bk_headers_wrapper = "bk-headers-wrapper";
    exports.bk_headers = "bk-headers";
    exports.bk_tab = "bk-tab";
    exports.bk_close = "bk-close";
},
/* styles/buttons.js */ function _(require, module, exports) {
    require(62) /* ./root */;
    const _a = require(61) /* ../core/dom */;
    _a.styles.append(".bk-root .bk-btn {\n  height: 100%;\n  display: inline-block;\n  text-align: center;\n  vertical-align: middle;\n  white-space: nowrap;\n  cursor: pointer;\n  padding: 6px 12px;\n  font-size: 12px;\n  border: 1px solid transparent;\n  border-radius: 4px;\n  outline: 0;\n  user-select: none;\n  -ms-user-select: none;\n  -moz-user-select: none;\n  -webkit-user-select: none;\n}\n.bk-root .bk-btn:hover,\n.bk-root .bk-btn:focus {\n  text-decoration: none;\n}\n.bk-root .bk-btn:active,\n.bk-root .bk-btn.bk-active {\n  background-image: none;\n  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.bk-root .bk-btn[disabled] {\n  cursor: not-allowed;\n  pointer-events: none;\n  opacity: 0.65;\n  box-shadow: none;\n}\n.bk-root .bk-btn-default {\n  color: #333;\n  background-color: #fff;\n  border-color: #ccc;\n}\n.bk-root .bk-btn-default:hover {\n  background-color: #f5f5f5;\n  border-color: #b8b8b8;\n}\n.bk-root .bk-btn-default.bk-active {\n  background-color: #ebebeb;\n  border-color: #adadad;\n}\n.bk-root .bk-btn-default[disabled],\n.bk-root .bk-btn-default[disabled]:hover,\n.bk-root .bk-btn-default[disabled]:focus,\n.bk-root .bk-btn-default[disabled]:active,\n.bk-root .bk-btn-default[disabled].bk-active {\n  background-color: #e6e6e6;\n  border-color: #ccc;\n}\n.bk-root .bk-btn-primary {\n  color: #fff;\n  background-color: #428bca;\n  border-color: #357ebd;\n}\n.bk-root .bk-btn-primary:hover {\n  background-color: #3681c1;\n  border-color: #2c699e;\n}\n.bk-root .bk-btn-primary.bk-active {\n  background-color: #3276b1;\n  border-color: #285e8e;\n}\n.bk-root .bk-btn-primary[disabled],\n.bk-root .bk-btn-primary[disabled]:hover,\n.bk-root .bk-btn-primary[disabled]:focus,\n.bk-root .bk-btn-primary[disabled]:active,\n.bk-root .bk-btn-primary[disabled].bk-active {\n  background-color: #506f89;\n  border-color: #357ebd;\n}\n.bk-root .bk-btn-success {\n  color: #fff;\n  background-color: #5cb85c;\n  border-color: #4cae4c;\n}\n.bk-root .bk-btn-success:hover {\n  background-color: #4eb24e;\n  border-color: #409240;\n}\n.bk-root .bk-btn-success.bk-active {\n  background-color: #47a447;\n  border-color: #398439;\n}\n.bk-root .bk-btn-success[disabled],\n.bk-root .bk-btn-success[disabled]:hover,\n.bk-root .bk-btn-success[disabled]:focus,\n.bk-root .bk-btn-success[disabled]:active,\n.bk-root .bk-btn-success[disabled].bk-active {\n  background-color: #667b66;\n  border-color: #4cae4c;\n}\n.bk-root .bk-btn-warning {\n  color: #fff;\n  background-color: #f0ad4e;\n  border-color: #eea236;\n}\n.bk-root .bk-btn-warning:hover {\n  background-color: #eea43b;\n  border-color: #e89014;\n}\n.bk-root .bk-btn-warning.bk-active {\n  background-color: #ed9c28;\n  border-color: #d58512;\n}\n.bk-root .bk-btn-warning[disabled],\n.bk-root .bk-btn-warning[disabled]:hover,\n.bk-root .bk-btn-warning[disabled]:focus,\n.bk-root .bk-btn-warning[disabled]:active,\n.bk-root .bk-btn-warning[disabled].bk-active {\n  background-color: #c89143;\n  border-color: #eea236;\n}\n.bk-root .bk-btn-danger {\n  color: #fff;\n  background-color: #d9534f;\n  border-color: #d43f3a;\n}\n.bk-root .bk-btn-danger:hover {\n  background-color: #d5433e;\n  border-color: #bd2d29;\n}\n.bk-root .bk-btn-danger.bk-active {\n  background-color: #d2322d;\n  border-color: #ac2925;\n}\n.bk-root .bk-btn-danger[disabled],\n.bk-root .bk-btn-danger[disabled]:hover,\n.bk-root .bk-btn-danger[disabled]:focus,\n.bk-root .bk-btn-danger[disabled]:active,\n.bk-root .bk-btn-danger[disabled].bk-active {\n  background-color: #a55350;\n  border-color: #d43f3a;\n}\n.bk-root .bk-btn-group {\n  height: 100%;\n  display: flex;\n  display: -webkit-flex;\n  flex-wrap: nowrap;\n  -webkit-flex-wrap: nowrap;\n  align-items: center;\n  -webkit-align-items: center;\n  flex-direction: row;\n  -webkit-flex-direction: row;\n}\n.bk-root .bk-btn-group > .bk-btn {\n  flex-grow: 1;\n  -webkit-flex-grow: 1;\n}\n.bk-root .bk-btn-group > .bk-btn + .bk-btn {\n  margin-left: -1px;\n}\n.bk-root .bk-btn-group > .bk-btn:first-child:not(:last-child) {\n  border-bottom-right-radius: 0;\n  border-top-right-radius: 0;\n}\n.bk-root .bk-btn-group > .bk-btn:not(:first-child):last-child {\n  border-bottom-left-radius: 0;\n  border-top-left-radius: 0;\n}\n.bk-root .bk-btn-group > .bk-btn:not(:first-child):not(:last-child) {\n  border-radius: 0;\n}\n.bk-root .bk-btn-group .bk-dropdown-toggle {\n  flex: 0 0 0;\n  -webkit-flex: 0 0 0;\n  padding: 6px 6px;\n}\n");
    exports.bk_btn = "bk-btn";
    exports.bk_btn_group = "bk-btn-group";
    exports.bk_btn_default = "bk-btn-default";
    exports.bk_btn_primary = "bk-btn-primary";
    exports.bk_btn_success = "bk-btn-success";
    exports.bk_btn_warning = "bk-btn-warning";
    exports.bk_btn_danger = "bk-btn-danger";
    function bk_btn_type(button_type) {
        switch (button_type) {
            case "default": return exports.bk_btn_default;
            case "primary": return exports.bk_btn_primary;
            case "success": return exports.bk_btn_success;
            case "warning": return exports.bk_btn_warning;
            case "danger": return exports.bk_btn_danger;
        }
    }
    exports.bk_btn_type = bk_btn_type;
    exports.bk_dropdown_toggle = "bk-dropdown-toggle";
},
/* styles/menus.js */ function _(require, module, exports) {
    require(62) /* ./root */;
    const _a = require(61) /* ../core/dom */;
    _a.styles.append(".bk-root .bk-menu {\n  position: absolute;\n  left: 0;\n  width: 100%;\n  z-index: 100;\n  cursor: pointer;\n  font-size: 12px;\n  background-color: #fff;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n}\n.bk-root .bk-menu.bk-above {\n  bottom: 100%;\n}\n.bk-root .bk-menu.bk-below {\n  top: 100%;\n}\n.bk-root .bk-menu > .bk-divider {\n  height: 1px;\n  margin: 7.5px 0;\n  overflow: hidden;\n  background-color: #e5e5e5;\n}\n.bk-root .bk-menu > :not(.bk-divider) {\n  padding: 6px 12px;\n}\n.bk-root .bk-menu > :not(.bk-divider):hover,\n.bk-root .bk-menu > :not(.bk-divider).bk-active {\n  background-color: #e6e6e6;\n}\n.bk-root .bk-caret {\n  display: inline-block;\n  vertical-align: middle;\n  width: 0;\n  height: 0;\n  margin: 0 5px;\n}\n.bk-root .bk-caret.bk-down {\n  border-top: 4px solid;\n}\n.bk-root .bk-caret.bk-up {\n  border-bottom: 4px solid;\n}\n.bk-root .bk-caret.bk-down,\n.bk-root .bk-caret.bk-up {\n  border-right: 4px solid transparent;\n  border-left: 4px solid transparent;\n}\n.bk-root .bk-caret.bk-left {\n  border-right: 4px solid;\n}\n.bk-root .bk-caret.bk-right {\n  border-left: 4px solid;\n}\n.bk-root .bk-caret.bk-left,\n.bk-root .bk-caret.bk-right {\n  border-top: 4px solid transparent;\n  border-bottom: 4px solid transparent;\n}\n");
    exports.bk_menu = "bk-menu";
    exports.bk_caret = "bk-caret";
    exports.bk_divider = "bk-divider";
},
/* models/layouts/widget_box.js */ function _(require, module, exports) {
    const column_1 = require(238) /* ./column */;
    class WidgetBoxView extends column_1.ColumnView {
    }
    exports.WidgetBoxView = WidgetBoxView;
    WidgetBoxView.__name__ = "WidgetBoxView";
    class WidgetBox extends column_1.Column {
        constructor(attrs) {
            super(attrs);
        }
        static init_WidgetBox() {
            this.prototype.default_view = WidgetBoxView;
        }
    }
    exports.WidgetBox = WidgetBox;
    WidgetBox.__name__ = "WidgetBox";
    WidgetBox.init_WidgetBox();
},
/* models/mappers/index.js */ function _(require, module, exports) {
    var categorical_color_mapper_1 = require(249) /* ./categorical_color_mapper */;
    exports.CategoricalColorMapper = categorical_color_mapper_1.CategoricalColorMapper;
    var categorical_marker_mapper_1 = require(251) /* ./categorical_marker_mapper */;
    exports.CategoricalMarkerMapper = categorical_marker_mapper_1.CategoricalMarkerMapper;
    var categorical_pattern_mapper_1 = require(252) /* ./categorical_pattern_mapper */;
    exports.CategoricalPatternMapper = categorical_pattern_mapper_1.CategoricalPatternMapper;
    var continuous_color_mapper_1 = require(109) /* ./continuous_color_mapper */;
    exports.ContinuousColorMapper = continuous_color_mapper_1.ContinuousColorMapper;
    var color_mapper_1 = require(110) /* ./color_mapper */;
    exports.ColorMapper = color_mapper_1.ColorMapper;
    var linear_color_mapper_1 = require(108) /* ./linear_color_mapper */;
    exports.LinearColorMapper = linear_color_mapper_1.LinearColorMapper;
    var log_color_mapper_1 = require(253) /* ./log_color_mapper */;
    exports.LogColorMapper = log_color_mapper_1.LogColorMapper;
},
/* models/mappers/categorical_color_mapper.js */ function _(require, module, exports) {
    const categorical_mapper_1 = require(250) /* ./categorical_mapper */;
    const color_mapper_1 = require(110) /* ./color_mapper */;
    const p = require(18) /* ../../core/properties */;
    class CategoricalColorMapper extends color_mapper_1.ColorMapper {
        constructor(attrs) {
            super(attrs);
        }
        static init_CategoricalColorMapper() {
            this.define({
                factors: [p.Array],
                start: [p.Number, 0],
                end: [p.Number],
            });
        }
        _v_compute(data, values, palette, { nan_color }) {
            categorical_mapper_1.cat_v_compute(data, this.factors, palette, values, this.start, this.end, nan_color);
        }
    }
    exports.CategoricalColorMapper = CategoricalColorMapper;
    CategoricalColorMapper.__name__ = "CategoricalColorMapper";
    CategoricalColorMapper.init_CategoricalColorMapper();
},
/* models/mappers/categorical_mapper.js */ function _(require, module, exports) {
    const arrayable_1 = require(11) /* ../../core/util/arrayable */;
    const types_1 = require(7) /* ../../core/util/types */;
    function _cat_equals(a, b) {
        if (a.length != b.length)
            return false;
        for (let i = 0, end = a.length; i < end; i++) {
            if (a[i] !== b[i])
                return false;
        }
        return true;
    }
    exports._cat_equals = _cat_equals;
    function cat_v_compute(data, factors, targets, values, start, end, extra_value) {
        for (let i = 0, N = data.length; i < N; i++) {
            let d = data[i];
            let key;
            if (types_1.isString(d))
                key = arrayable_1.index_of(factors, d);
            else {
                if (start != null) {
                    if (end != null)
                        d = d.slice(start, end);
                    else
                        d = d.slice(start);
                }
                else if (end != null)
                    d = d.slice(0, end);
                if (d.length == 1)
                    key = arrayable_1.index_of(factors, d[0]);
                else
                    key = arrayable_1.find_index(factors, (x) => _cat_equals(x, d));
            }
            let value;
            if (key < 0 || key >= targets.length)
                value = extra_value;
            else
                value = targets[key];
            values[i] = value;
        }
    }
    exports.cat_v_compute = cat_v_compute;
},
/* models/mappers/categorical_marker_mapper.js */ function _(require, module, exports) {
    const categorical_mapper_1 = require(250) /* ./categorical_mapper */;
    const mapper_1 = require(111) /* ./mapper */;
    const p = require(18) /* ../../core/properties */;
    class CategoricalMarkerMapper extends mapper_1.Mapper {
        constructor(attrs) {
            super(attrs);
        }
        static init_CategoricalMarkerMapper() {
            this.define({
                factors: [p.Array],
                markers: [p.Array],
                start: [p.Number, 0],
                end: [p.Number],
                default_value: [p.MarkerType, "circle"],
            });
        }
        v_compute(xs) {
            const values = new Array(xs.length);
            categorical_mapper_1.cat_v_compute(xs, this.factors, this.markers, values, this.start, this.end, this.default_value);
            return values;
        }
    }
    exports.CategoricalMarkerMapper = CategoricalMarkerMapper;
    CategoricalMarkerMapper.__name__ = "CategoricalMarkerMapper";
    CategoricalMarkerMapper.init_CategoricalMarkerMapper();
},
/* models/mappers/categorical_pattern_mapper.js */ function _(require, module, exports) {
    const categorical_mapper_1 = require(250) /* ./categorical_mapper */;
    const mapper_1 = require(111) /* ./mapper */;
    const p = require(18) /* ../../core/properties */;
    class CategoricalPatternMapper extends mapper_1.Mapper {
        constructor(attrs) {
            super(attrs);
        }
        static init_CategoricalPatternMapper() {
            this.define({
                factors: [p.Array],
                patterns: [p.Array],
                start: [p.Number, 0],
                end: [p.Number],
                default_value: [p.HatchPatternType, " "],
            });
        }
        v_compute(xs) {
            const values = new Array(xs.length);
            categorical_mapper_1.cat_v_compute(xs, this.factors, this.patterns, values, this.start, this.end, this.default_value);
            return values;
        }
    }
    exports.CategoricalPatternMapper = CategoricalPatternMapper;
    CategoricalPatternMapper.__name__ = "CategoricalPatternMapper";
    CategoricalPatternMapper.init_CategoricalPatternMapper();
},
/* models/mappers/log_color_mapper.js */ function _(require, module, exports) {
    const continuous_color_mapper_1 = require(109) /* ./continuous_color_mapper */;
    const arrayable_1 = require(11) /* ../../core/util/arrayable */;
    // Math.log1p() is not supported by any version of IE, so let's use a polyfill based on
    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log1p.
    const log1p = Math.log1p != null ? Math.log1p : (x) => Math.log(1 + x);
    class LogColorMapper extends continuous_color_mapper_1.ContinuousColorMapper {
        constructor(attrs) {
            super(attrs);
        }
        _v_compute(data, values, palette, colors) {
            const { nan_color, low_color, high_color } = colors;
            const n = palette.length;
            const low = this.low != null ? this.low : arrayable_1.min(data);
            const high = this.high != null ? this.high : arrayable_1.max(data);
            const scale = n / (log1p(high) - log1p(low)); // subtract the low offset
            const max_key = palette.length - 1;
            for (let i = 0, end = data.length; i < end; i++) {
                const d = data[i];
                // Check NaN
                if (isNaN(d)) {
                    values[i] = nan_color;
                    continue;
                }
                if (d > high) {
                    values[i] = high_color != null ? high_color : palette[max_key];
                    continue;
                }
                // This handles the edge case where d == high, since the code below maps
                // values exactly equal to high to palette.length, which is greater than
                // max_key
                if (d == high) {
                    values[i] = palette[max_key];
                    continue;
                }
                if (d < low) {
                    values[i] = low_color != null ? low_color : palette[0];
                    continue;
                }
                // Get the key
                const log = log1p(d) - log1p(low); // subtract the low offset
                let key = Math.floor(log * scale);
                // Deal with upper bound
                if (key > max_key)
                    key = max_key;
                values[i] = palette[key];
            }
        }
    }
    exports.LogColorMapper = LogColorMapper;
    LogColorMapper.__name__ = "LogColorMapper";
},
/* models/markers/index.js */ function _(require, module, exports) {
    function __export(m) {
        for (var p in m)
            if (!exports.hasOwnProperty(p))
                exports[p] = m[p];
    }
    __export(require(255) /* ./defs */);
    var marker_1 = require(256) /* ./marker */;
    exports.Marker = marker_1.Marker;
    var scatter_1 = require(257) /* ./scatter */;
    exports.Scatter = scatter_1.Scatter;
},
/* models/markers/defs.js */ function _(require, module, exports) {
    const marker_1 = require(256) /* ./marker */;
    const SQ3 = Math.sqrt(3);
    function _one_line(ctx, r) {
        ctx.moveTo(-r, 0);
        ctx.lineTo(r, 0);
    }
    function _one_x(ctx, r) {
        ctx.moveTo(-r, r);
        ctx.lineTo(r, -r);
        ctx.moveTo(-r, -r);
        ctx.lineTo(r, r);
    }
    function _one_cross(ctx, r) {
        ctx.moveTo(0, r);
        ctx.lineTo(0, -r);
        ctx.moveTo(-r, 0);
        ctx.lineTo(r, 0);
    }
    function _one_diamond(ctx, r) {
        ctx.moveTo(0, r);
        ctx.lineTo(r / 1.5, 0);
        ctx.lineTo(0, -r);
        ctx.lineTo(-r / 1.5, 0);
        ctx.closePath();
    }
    function _one_hex(ctx, r) {
        const r2 = r / 2;
        const h = SQ3 * r2;
        ctx.moveTo(r, 0);
        ctx.lineTo(r2, -h);
        ctx.lineTo(-r2, -h);
        ctx.lineTo(-r, 0);
        ctx.lineTo(-r2, h);
        ctx.lineTo(r2, h);
        ctx.closePath();
    }
    function _one_tri(ctx, r) {
        const h = r * SQ3;
        const a = h / 3;
        ctx.moveTo(-r, a);
        ctx.lineTo(r, a);
        ctx.lineTo(0, a - h);
        ctx.closePath();
    }
    function asterisk(ctx, i, r, line, _fill) {
        const r2 = r * 0.65;
        _one_cross(ctx, r);
        _one_x(ctx, r2);
        if (line.doit) {
            line.set_vectorize(ctx, i);
            ctx.stroke();
        }
    }
    function circle(ctx, i, r, line, fill) {
        ctx.arc(0, 0, r, 0, 2 * Math.PI, false);
        if (fill.doit) {
            fill.set_vectorize(ctx, i);
            ctx.fill();
        }
        if (line.doit) {
            line.set_vectorize(ctx, i);
            ctx.stroke();
        }
    }
    function circle_cross(ctx, i, r, line, fill) {
        ctx.arc(0, 0, r, 0, 2 * Math.PI, false);
        if (fill.doit) {
            fill.set_vectorize(ctx, i);
            ctx.fill();
        }
        if (line.doit) {
            line.set_vectorize(ctx, i);
            _one_cross(ctx, r);
            ctx.stroke();
        }
    }
    function circle_x(ctx, i, r, line, fill) {
        ctx.arc(0, 0, r, 0, 2 * Math.PI, false);
        if (fill.doit) {
            fill.set_vectorize(ctx, i);
            ctx.fill();
        }
        if (line.doit) {
            line.set_vectorize(ctx, i);
            _one_x(ctx, r);
            ctx.stroke();
        }
    }
    function cross(ctx, i, r, line, _fill) {
        _one_cross(ctx, r);
        if (line.doit) {
            line.set_vectorize(ctx, i);
            ctx.stroke();
        }
    }
    function diamond(ctx, i, r, line, fill) {
        _one_diamond(ctx, r);
        if (fill.doit) {
            fill.set_vectorize(ctx, i);
            ctx.fill();
        }
        if (line.doit) {
            line.set_vectorize(ctx, i);
            ctx.stroke();
        }
    }
    function diamond_cross(ctx, i, r, line, fill) {
        _one_diamond(ctx, r);
        if (fill.doit) {
            fill.set_vectorize(ctx, i);
            ctx.fill();
        }
        if (line.doit) {
            line.set_vectorize(ctx, i);
            _one_cross(ctx, r);
            ctx.stroke();
        }
    }
    function hex(ctx, i, r, line, fill) {
        _one_hex(ctx, r);
        if (fill.doit) {
            fill.set_vectorize(ctx, i);
            ctx.fill();
        }
        if (line.doit) {
            line.set_vectorize(ctx, i);
            ctx.stroke();
        }
    }
    function inverted_triangle(ctx, i, r, line, fill) {
        ctx.rotate(Math.PI);
        _one_tri(ctx, r);
        ctx.rotate(-Math.PI);
        if (fill.doit) {
            fill.set_vectorize(ctx, i);
            ctx.fill();
        }
        if (line.doit) {
            line.set_vectorize(ctx, i);
            ctx.stroke();
        }
    }
    function square(ctx, i, r, line, fill) {
        const size = 2 * r;
        ctx.rect(-r, -r, size, size);
        if (fill.doit) {
            fill.set_vectorize(ctx, i);
            ctx.fill();
        }
        if (line.doit) {
            line.set_vectorize(ctx, i);
            ctx.stroke();
        }
    }
    function square_cross(ctx, i, r, line, fill) {
        const size = 2 * r;
        ctx.rect(-r, -r, size, size);
        if (fill.doit) {
            fill.set_vectorize(ctx, i);
            ctx.fill();
        }
        if (line.doit) {
            line.set_vectorize(ctx, i);
            _one_cross(ctx, r);
            ctx.stroke();
        }
    }
    function square_x(ctx, i, r, line, fill) {
        const size = 2 * r;
        ctx.rect(-r, -r, size, size);
        if (fill.doit) {
            fill.set_vectorize(ctx, i);
            ctx.fill();
        }
        if (line.doit) {
            line.set_vectorize(ctx, i);
            _one_x(ctx, r);
            ctx.stroke();
        }
    }
    function triangle(ctx, i, r, line, fill) {
        _one_tri(ctx, r);
        if (fill.doit) {
            fill.set_vectorize(ctx, i);
            ctx.fill();
        }
        if (line.doit) {
            line.set_vectorize(ctx, i);
            ctx.stroke();
        }
    }
    function dash(ctx, i, r, line, _fill) {
        _one_line(ctx, r);
        if (line.doit) {
            line.set_vectorize(ctx, i);
            ctx.stroke();
        }
    }
    function x(ctx, i, r, line, _fill) {
        _one_x(ctx, r);
        if (line.doit) {
            line.set_vectorize(ctx, i);
            ctx.stroke();
        }
    }
    function _mk_model(type, f) {
        var _a;
        const view = class extends marker_1.MarkerView {
            static initClass() {
                this.prototype._render_one = f;
            }
        };
        view.initClass();
        const model = (_a = class extends marker_1.Marker {
            static initClass() {
                this.prototype.default_view = view;
            }
        },
            _a.__name__ = type,
            _a);
        model.initClass();
        return model;
    }
    // markers are final, so no need to export views
    exports.Asterisk = _mk_model('Asterisk', asterisk);
    exports.CircleCross = _mk_model('CircleCross', circle_cross);
    exports.CircleX = _mk_model('CircleX', circle_x);
    exports.Cross = _mk_model('Cross', cross);
    exports.Dash = _mk_model('Dash', dash);
    exports.Diamond = _mk_model('Diamond', diamond);
    exports.DiamondCross = _mk_model('DiamondCross', diamond_cross);
    exports.Hex = _mk_model('Hex', hex);
    exports.InvertedTriangle = _mk_model('InvertedTriangle', inverted_triangle);
    exports.Square = _mk_model('Square', square);
    exports.SquareCross = _mk_model('SquareCross', square_cross);
    exports.SquareX = _mk_model('SquareX', square_x);
    exports.Triangle = _mk_model('Triangle', triangle);
    exports.X = _mk_model('X', x);
    exports.marker_funcs = {
        asterisk,
        circle,
        circle_cross,
        circle_x,
        cross,
        diamond,
        diamond_cross,
        hex,
        inverted_triangle,
        square,
        square_cross,
        square_x,
        triangle,
        dash,
        x,
    };
},
/* models/markers/marker.js */ function _(require, module, exports) {
    const xy_glyph_1 = require(76) /* ../glyphs/xy_glyph */;
    const hittest = require(81) /* ../../core/hittest */;
    const p = require(18) /* ../../core/properties */;
    const array_1 = require(8) /* ../../core/util/array */;
    class MarkerView extends xy_glyph_1.XYGlyphView {
        _render(ctx, indices, { sx, sy, _size, _angle }) {
            for (const i of indices) {
                if (isNaN(sx[i] + sy[i] + _size[i] + _angle[i]))
                    continue;
                const r = _size[i] / 2;
                ctx.beginPath();
                ctx.translate(sx[i], sy[i]);
                if (_angle[i])
                    ctx.rotate(_angle[i]);
                this._render_one(ctx, i, r, this.visuals.line, this.visuals.fill);
                if (_angle[i])
                    ctx.rotate(-_angle[i]);
                ctx.translate(-sx[i], -sy[i]);
            }
        }
        _mask_data() {
            // dilate the inner screen region by max_size and map back to data space for use in
            // spatial query
            const hr = this.renderer.plot_view.frame.bbox.h_range;
            const sx0 = hr.start - this.max_size;
            const sx1 = hr.end + this.max_size;
            const [x0, x1] = this.renderer.xscale.r_invert(sx0, sx1);
            const vr = this.renderer.plot_view.frame.bbox.v_range;
            const sy0 = vr.start - this.max_size;
            const sy1 = vr.end + this.max_size;
            const [y0, y1] = this.renderer.yscale.r_invert(sy0, sy1);
            return this.index.indices({ x0, x1, y0, y1 });
        }
        _hit_point(geometry) {
            const { sx, sy } = geometry;
            const sx0 = sx - this.max_size;
            const sx1 = sx + this.max_size;
            const [x0, x1] = this.renderer.xscale.r_invert(sx0, sx1);
            const sy0 = sy - this.max_size;
            const sy1 = sy + this.max_size;
            const [y0, y1] = this.renderer.yscale.r_invert(sy0, sy1);
            const candidates = this.index.indices({ x0, x1, y0, y1 });
            const hits = [];
            for (const i of candidates) {
                const s2 = this._size[i] / 2;
                const dist = Math.abs(this.sx[i] - sx) + Math.abs(this.sy[i] - sy);
                if (Math.abs(this.sx[i] - sx) <= s2 && Math.abs(this.sy[i] - sy) <= s2) {
                    hits.push([i, dist]);
                }
            }
            return hittest.create_hit_test_result_from_hits(hits);
        }
        _hit_span(geometry) {
            const { sx, sy } = geometry;
            const bounds = this.bounds();
            const ms = this.max_size / 2;
            const result = hittest.create_empty_hit_test_result();
            let x0, x1, y0, y1;
            if (geometry.direction == 'h') {
                y0 = bounds.y0;
                y1 = bounds.y1;
                const sx0 = sx - ms;
                const sx1 = sx + ms;
                [x0, x1] = this.renderer.xscale.r_invert(sx0, sx1);
            }
            else {
                x0 = bounds.x0;
                x1 = bounds.x1;
                const sy0 = sy - ms;
                const sy1 = sy + ms;
                [y0, y1] = this.renderer.yscale.r_invert(sy0, sy1);
            }
            const hits = this.index.indices({ x0, x1, y0, y1 });
            result.indices = hits;
            return result;
        }
        _hit_rect(geometry) {
            const { sx0, sx1, sy0, sy1 } = geometry;
            const [x0, x1] = this.renderer.xscale.r_invert(sx0, sx1);
            const [y0, y1] = this.renderer.yscale.r_invert(sy0, sy1);
            const result = hittest.create_empty_hit_test_result();
            result.indices = this.index.indices({ x0, x1, y0, y1 });
            return result;
        }
        _hit_poly(geometry) {
            const { sx, sy } = geometry;
            // TODO (bev) use spatial index to pare candidate list
            const candidates = array_1.range(0, this.sx.length);
            const hits = [];
            for (let i = 0, end = candidates.length; i < end; i++) {
                const idx = candidates[i];
                if (hittest.point_in_poly(this.sx[i], this.sy[i], sx, sy))
                    hits.push(idx);
            }
            const result = hittest.create_empty_hit_test_result();
            result.indices = hits;
            return result;
        }
        draw_legend_for_index(ctx, { x0, x1, y0, y1 }, index) {
            // using objects like this seems a little wonky, since the keys are coerced to
            // stings, but it works
            const len = index + 1;
            const sx = new Array(len);
            sx[index] = (x0 + x1) / 2;
            const sy = new Array(len);
            sy[index] = (y0 + y1) / 2;
            const size = new Array(len);
            size[index] = Math.min(Math.abs(x1 - x0), Math.abs(y1 - y0)) * 0.4;
            const angle = new Array(len);
            angle[index] = 0; // don't attempt to match glyph angle
            this._render(ctx, [index], { sx, sy, _size: size, _angle: angle }); // XXX
        }
    }
    exports.MarkerView = MarkerView;
    MarkerView.__name__ = "MarkerView";
    class Marker extends xy_glyph_1.XYGlyph {
        constructor(attrs) {
            super(attrs);
        }
        static init_Marker() {
            this.mixins(['line', 'fill']);
            this.define({
                size: [p.DistanceSpec, { units: "screen", value: 4 }],
                angle: [p.AngleSpec, 0],
            });
        }
    }
    exports.Marker = Marker;
    Marker.__name__ = "Marker";
    Marker.init_Marker();
},
/* models/markers/scatter.js */ function _(require, module, exports) {
    const marker_1 = require(256) /* ./marker */;
    const defs_1 = require(255) /* ./defs */;
    const p = require(18) /* ../../core/properties */;
    class ScatterView extends marker_1.MarkerView {
        _render(ctx, indices, { sx, sy, _size, _angle, _marker }) {
            for (const i of indices) {
                if (isNaN(sx[i] + sy[i] + _size[i] + _angle[i]) || _marker[i] == null)
                    continue;
                const r = _size[i] / 2;
                ctx.beginPath();
                ctx.translate(sx[i], sy[i]);
                if (_angle[i])
                    ctx.rotate(_angle[i]);
                defs_1.marker_funcs[_marker[i]](ctx, i, r, this.visuals.line, this.visuals.fill);
                if (_angle[i])
                    ctx.rotate(-_angle[i]);
                ctx.translate(-sx[i], -sy[i]);
            }
        }
        draw_legend_for_index(ctx, { x0, x1, y0, y1 }, index) {
            // using objects like this seems a little wonky, since the keys are coerced to
            // stings, but it works
            const len = index + 1;
            const sx = new Array(len);
            sx[index] = (x0 + x1) / 2;
            const sy = new Array(len);
            sy[index] = (y0 + y1) / 2;
            const size = new Array(len);
            size[index] = Math.min(Math.abs(x1 - x0), Math.abs(y1 - y0)) * 0.4;
            const angle = new Array(len);
            angle[index] = 0; // don't attempt to match glyph angle
            const marker = new Array(len);
            marker[index] = this._marker[index];
            this._render(ctx, [index], { sx, sy, _size: size, _angle: angle, _marker: marker }); // XXX
        }
    }
    exports.ScatterView = ScatterView;
    ScatterView.__name__ = "ScatterView";
    class Scatter extends marker_1.Marker {
        constructor(attrs) {
            super(attrs);
        }
        static init_Scatter() {
            this.prototype.default_view = ScatterView;
            this.define({
                marker: [p.MarkerSpec, { value: "circle" }],
            });
        }
    }
    exports.Scatter = Scatter;
    Scatter.__name__ = "Scatter";
    Scatter.init_Scatter();
},
/* models/plots/index.js */ function _(require, module, exports) {
    var gmap_plot_1 = require(259) /* ./gmap_plot */;
    exports.MapOptions = gmap_plot_1.MapOptions;
    var gmap_plot_2 = require(259) /* ./gmap_plot */;
    exports.GMapOptions = gmap_plot_2.GMapOptions;
    var gmap_plot_3 = require(259) /* ./gmap_plot */;
    exports.GMapPlot = gmap_plot_3.GMapPlot;
    var plot_1 = require(260) /* ./plot */;
    exports.Plot = plot_1.Plot;
},
/* models/plots/gmap_plot.js */ function _(require, module, exports) {
    const logging_1 = require(65) /* ../../core/logging */;
    const plot_1 = require(260) /* ./plot */;
    const p = require(18) /* ../../core/properties */;
    const model_1 = require(64) /* ../../model */;
    const range1d_1 = require(123) /* ../ranges/range1d */;
    const gmap_plot_canvas_1 = require(280) /* ./gmap_plot_canvas */;
    exports.GMapPlotView = gmap_plot_canvas_1.GMapPlotView;
    class MapOptions extends model_1.Model {
        constructor(attrs) {
            super(attrs);
        }
        static init_MapOptions() {
            this.define({
                lat: [p.Number],
                lng: [p.Number],
                zoom: [p.Number, 12],
            });
        }
    }
    exports.MapOptions = MapOptions;
    MapOptions.__name__ = "MapOptions";
    MapOptions.init_MapOptions();
    class GMapOptions extends MapOptions {
        constructor(attrs) {
            super(attrs);
        }
        static init_GMapOptions() {
            this.define({
                map_type: [p.String, "roadmap"],
                scale_control: [p.Boolean, false],
                styles: [p.String],
                tilt: [p.Int, 45],
            });
        }
    }
    exports.GMapOptions = GMapOptions;
    GMapOptions.__name__ = "GMapOptions";
    GMapOptions.init_GMapOptions();
    class GMapPlot extends plot_1.Plot {
        constructor(attrs) {
            super(attrs);
        }
        static init_GMapPlot() {
            this.prototype.default_view = gmap_plot_canvas_1.GMapPlotView;
            // This seems to be necessary so that everything can initialize.
            // Feels very clumsy, but I'm not sure how the properties system wants
            // to handle something like this situation.
            this.define({
                map_options: [p.Instance],
                api_key: [p.String],
            });
            this.override({
                x_range: () => new range1d_1.Range1d(),
                y_range: () => new range1d_1.Range1d(),
            });
        }
        initialize() {
            super.initialize();
            this.use_map = true;
            if (!this.api_key)
                logging_1.logger.error("api_key is required. See https://developers.google.com/maps/documentation/javascript/get-api-key for more information on how to obtain your own.");
        }
    }
    exports.GMapPlot = GMapPlot;
    GMapPlot.__name__ = "GMapPlot";
    GMapPlot.init_GMapPlot();
},
/* models/plots/plot.js */ function _(require, module, exports) {
    const p = require(18) /* ../../core/properties */;
    const signaling_1 = require(13) /* ../../core/signaling */;
    const array_1 = require(8) /* ../../core/util/array */;
    const object_1 = require(22) /* ../../core/util/object */;
    const types_1 = require(7) /* ../../core/util/types */;
    const layout_dom_1 = require(237) /* ../layouts/layout_dom */;
    const title_1 = require(134) /* ../annotations/title */;
    const linear_scale_1 = require(113) /* ../scales/linear_scale */;
    const toolbar_1 = require(261) /* ../tools/toolbar */;
    const column_data_source_1 = require(68) /* ../sources/column_data_source */;
    const glyph_renderer_1 = require(73) /* ../renderers/glyph_renderer */;
    const data_range1d_1 = require(178) /* ../ranges/data_range1d */;
    const plot_canvas_1 = require(273) /* ./plot_canvas */;
    exports.PlotView = plot_canvas_1.PlotView;
    class Plot extends layout_dom_1.LayoutDOM {
        constructor(attrs) {
            super(attrs);
        }
        static init_Plot() {
            this.prototype.default_view = plot_canvas_1.PlotView;
            this.mixins(["line:outline_", "fill:background_", "fill:border_"]);
            this.define({
                toolbar: [p.Instance, () => new toolbar_1.Toolbar()],
                toolbar_location: [p.Location, 'right'],
                toolbar_sticky: [p.Boolean, true],
                plot_width: [p.Number, 600],
                plot_height: [p.Number, 600],
                frame_width: [p.Number, null],
                frame_height: [p.Number, null],
                title: [p.Any, () => new title_1.Title({ text: "" })],
                title_location: [p.Location, 'above'],
                above: [p.Array, []],
                below: [p.Array, []],
                left: [p.Array, []],
                right: [p.Array, []],
                center: [p.Array, []],
                renderers: [p.Array, []],
                x_range: [p.Instance, () => new data_range1d_1.DataRange1d()],
                extra_x_ranges: [p.Any, {}],
                y_range: [p.Instance, () => new data_range1d_1.DataRange1d()],
                extra_y_ranges: [p.Any, {}],
                x_scale: [p.Instance, () => new linear_scale_1.LinearScale()],
                y_scale: [p.Instance, () => new linear_scale_1.LinearScale()],
                lod_factor: [p.Number, 10],
                lod_interval: [p.Number, 300],
                lod_threshold: [p.Number, 2000],
                lod_timeout: [p.Number, 500],
                hidpi: [p.Boolean, true],
                output_backend: [p.OutputBackend, "canvas"],
                min_border: [p.Number, 5],
                min_border_top: [p.Number, null],
                min_border_left: [p.Number, null],
                min_border_bottom: [p.Number, null],
                min_border_right: [p.Number, null],
                inner_width: [p.Number],
                inner_height: [p.Number],
                outer_width: [p.Number],
                outer_height: [p.Number],
                match_aspect: [p.Boolean, false],
                aspect_scale: [p.Number, 1],
                reset_policy: [p.ResetPolicy, "standard"],
            });
            this.override({
                outline_line_color: "#e5e5e5",
                border_fill_color: "#ffffff",
                background_fill_color: "#ffffff",
            });
        }
        get width() {
            const width = this.getv("width");
            return width != null ? width : this.plot_width;
        }
        get height() {
            const height = this.getv("height");
            return height != null ? height : this.plot_height;
        }
        _doc_attached() {
            super._doc_attached();
            this._tell_document_about_change('inner_height', null, this.inner_height, {});
            this._tell_document_about_change('inner_width', null, this.inner_width, {});
        }
        initialize() {
            super.initialize();
            this.reset = new signaling_1.Signal0(this, "reset");
            for (const xr of object_1.values(this.extra_x_ranges).concat(this.x_range)) {
                let plots = xr.plots;
                if (types_1.isArray(plots)) {
                    plots = plots.concat(this);
                    xr.setv({ plots }, { silent: true });
                }
            }
            for (const yr of object_1.values(this.extra_y_ranges).concat(this.y_range)) {
                let plots = yr.plots;
                if (types_1.isArray(plots)) {
                    plots = plots.concat(this);
                    yr.setv({ plots }, { silent: true });
                }
            }
        }
        add_layout(renderer, side = "center") {
            const side_renderers = this.getv(side);
            side_renderers.push(renderer /* XXX */);
        }
        remove_layout(renderer) {
            const del = (items) => {
                array_1.remove_by(items, (item) => item == renderer);
            };
            del(this.left);
            del(this.right);
            del(this.above);
            del(this.below);
            del(this.center);
        }
        add_renderers(...renderers) {
            this.renderers = this.renderers.concat(renderers);
        }
        add_glyph(glyph, source = new column_data_source_1.ColumnDataSource(), extra_attrs = {}) {
            const attrs = Object.assign(Object.assign({}, extra_attrs), { data_source: source, glyph });
            const renderer = new glyph_renderer_1.GlyphRenderer(attrs);
            this.add_renderers(renderer);
            return renderer;
        }
        add_tools(...tools) {
            this.toolbar.tools = this.toolbar.tools.concat(tools);
        }
        get panels() {
            return this.side_panels.concat(this.center);
        }
        get side_panels() {
            const { above, below, left, right } = this;
            return array_1.concat([above, below, left, right]);
        }
    }
    exports.Plot = Plot;
    Plot.__name__ = "Plot";
    Plot.init_Plot();
},
/* models/tools/toolbar.js */ function _(require, module, exports) {
    const p = require(18) /* ../../core/properties */;
    const types_1 = require(7) /* ../../core/util/types */;
    const array_1 = require(8) /* ../../core/util/array */;
    const inspect_tool_1 = require(262) /* ./inspectors/inspect_tool */;
    const toolbar_base_1 = require(267) /* ./toolbar_base */;
    const _get_active_attr = (et) => {
        switch (et) {
            case 'tap': return 'active_tap';
            case 'pan': return 'active_drag';
            case 'pinch':
            case 'scroll': return 'active_scroll';
            case 'multi': return 'active_multi';
        }
        return null;
    };
    const _supports_auto = (et) => {
        return et == 'tap' || et == 'pan';
    };
    class Toolbar extends toolbar_base_1.ToolbarBase {
        constructor(attrs) {
            super(attrs);
        }
        static init_Toolbar() {
            this.prototype.default_view = toolbar_base_1.ToolbarBaseView;
            this.define({
                active_drag: [p.Any, 'auto'],
                active_inspect: [p.Any, 'auto'],
                active_scroll: [p.Any, 'auto'],
                active_tap: [p.Any, 'auto'],
                active_multi: [p.Any, null],
            });
        }
        connect_signals() {
            super.connect_signals();
            this.connect(this.properties.tools.change, () => this._init_tools());
        }
        _init_tools() {
            super._init_tools();
            if (this.active_inspect == 'auto') {
                // do nothing as all tools are active be default
            }
            else if (this.active_inspect instanceof inspect_tool_1.InspectTool) {
                let found = false;
                for (const inspector of this.inspectors) {
                    if (inspector != this.active_inspect)
                        inspector.active = false;
                    else
                        found = true;
                }
                if (!found) {
                    this.active_inspect = null;
                }
            }
            else if (types_1.isArray(this.active_inspect)) {
                const active_inspect = array_1.intersection(this.active_inspect, this.inspectors);
                if (active_inspect.length != this.active_inspect.length) {
                    this.active_inspect = active_inspect;
                }
                for (const inspector of this.inspectors) {
                    if (!array_1.includes(this.active_inspect, inspector))
                        inspector.active = false;
                }
            }
            else if (this.active_inspect == null) {
                for (const inspector of this.inspectors)
                    inspector.active = false;
            }
            const _activate_gesture = (tool) => {
                if (tool.active) {
                    // tool was activated by a proxy, but we need to finish configuration manually
                    this._active_change(tool);
                }
                else
                    tool.active = true;
            };
            // Connecting signals has to be done before changing the active state of the tools.
            for (const et in this.gestures) {
                const gesture = this.gestures[et];
                gesture.tools = array_1.sort_by(gesture.tools, (tool) => tool.default_order);
                for (const tool of gesture.tools) {
                    this.connect(tool.properties.active.change, this._active_change.bind(this, tool));
                }
            }
            for (const et in this.gestures) {
                const active_attr = _get_active_attr(et);
                if (active_attr) {
                    const active_tool = this[active_attr];
                    if (active_tool == 'auto') {
                        const gesture = this.gestures[et];
                        if (gesture.tools.length != 0 && _supports_auto(et)) {
                            _activate_gesture(gesture.tools[0]);
                        }
                    }
                    else if (active_tool != null) {
                        if (array_1.includes(this.tools, active_tool)) {
                            _activate_gesture(active_tool);
                        }
                        else {
                            this[active_attr] = null;
                        }
                    }
                }
            }
        }
    }
    exports.Toolbar = Toolbar;
    Toolbar.__name__ = "Toolbar";
    Toolbar.init_Toolbar();
},
/* models/tools/inspectors/inspect_tool.js */ function _(require, module, exports) {
    const button_tool_1 = require(263) /* ../button_tool */;
    const on_off_button_1 = require(266) /* ../on_off_button */;
    const p = require(18) /* ../../../core/properties */;
    class InspectToolView extends button_tool_1.ButtonToolView {
    }
    exports.InspectToolView = InspectToolView;
    InspectToolView.__name__ = "InspectToolView";
    class InspectTool extends button_tool_1.ButtonTool {
        constructor(attrs) {
            super(attrs);
            this.event_type = "move";
        }
        static init_InspectTool() {
            this.prototype.button_view = on_off_button_1.OnOffButtonView;
            this.define({
                toggleable: [p.Boolean, true],
            });
            this.override({
                active: true,
            });
        }
    }
    exports.InspectTool = InspectTool;
    InspectTool.__name__ = "InspectTool";
    InspectTool.init_InspectTool();
},
/* models/tools/button_tool.js */ function _(require, module, exports) {
    const dom_view_1 = require(59) /* ../../core/dom_view */;
    const tool_1 = require(264) /* ./tool */;
    const dom_1 = require(61) /* ../../core/dom */;
    const p = require(18) /* ../../core/properties */;
    const string_1 = require(25) /* ../../core/util/string */;
    const types_1 = require(7) /* ../../core/util/types */;
    const toolbar_1 = require(265) /* ../../styles/toolbar */;
    class ButtonToolButtonView extends dom_view_1.DOMView {
        initialize() {
            super.initialize();
            this.connect(this.model.change, () => this.render());
            this.el.addEventListener("click", () => this._clicked());
            this.render(); // XXX: this isn't governed by layout, for now
        }
        css_classes() {
            return super.css_classes().concat(toolbar_1.bk_toolbar_button);
        }
        render() {
            dom_1.empty(this.el);
            const icon = this.model.computed_icon;
            if (types_1.isString(icon)) {
                if (string_1.startsWith(icon, "data:image"))
                    this.el.style.backgroundImage = "url('" + icon + "')";
                else
                    this.el.classList.add(icon);
            }
            this.el.title = this.model.tooltip;
        }
    }
    exports.ButtonToolButtonView = ButtonToolButtonView;
    ButtonToolButtonView.__name__ = "ButtonToolButtonView";
    class ButtonToolView extends tool_1.ToolView {
    }
    exports.ButtonToolView = ButtonToolView;
    ButtonToolView.__name__ = "ButtonToolView";
    class ButtonTool extends tool_1.Tool {
        constructor(attrs) {
            super(attrs);
        }
        static init_ButtonTool() {
            this.internal({
                disabled: [p.Boolean, false],
            });
        }
        get tooltip() {
            return this.tool_name;
        }
        get computed_icon() {
            return this.icon;
        }
    }
    exports.ButtonTool = ButtonTool;
    ButtonTool.__name__ = "ButtonTool";
    ButtonTool.init_ButtonTool();
},
/* models/tools/tool.js */ function _(require, module, exports) {
    const p = require(18) /* ../../core/properties */;
    const view_1 = require(60) /* ../../core/view */;
    const array_1 = require(8) /* ../../core/util/array */;
    const model_1 = require(64) /* ../../model */;
    class ToolView extends view_1.View {
        get plot_view() {
            return this.parent;
        }
        get plot_model() {
            return this.parent.model;
        }
        connect_signals() {
            super.connect_signals();
            this.connect(this.model.properties.active.change, () => {
                if (this.model.active)
                    this.activate();
                else
                    this.deactivate();
            });
        }
        // activate is triggered by toolbar ui actions
        activate() { }
        // deactivate is triggered by toolbar ui actions
        deactivate() { }
    }
    exports.ToolView = ToolView;
    ToolView.__name__ = "ToolView";
    class Tool extends model_1.Model {
        constructor(attrs) {
            super(attrs);
        }
        static init_Tool() {
            this.internal({
                active: [p.Boolean, false],
            });
        }
        get synthetic_renderers() {
            return [];
        }
        // utility function to return a tool name, modified
        // by the active dimensions. Used by tools that have dimensions
        _get_dim_tooltip(name, dims) {
            switch (dims) {
                case "width": return `${name} (x-axis)`;
                case "height": return `${name} (y-axis)`;
                case "both": return name;
            }
        }
        // utility function to get limits along both dimensions, given
        // optional dimensional constraints
        _get_dim_limits([sx0, sy0], [sx1, sy1], frame, dims) {
            const hr = frame.bbox.h_range;
            let sxlim;
            if (dims == 'width' || dims == 'both') {
                sxlim = [array_1.min([sx0, sx1]), array_1.max([sx0, sx1])];
                sxlim = [array_1.max([sxlim[0], hr.start]), array_1.min([sxlim[1], hr.end])];
            }
            else
                sxlim = [hr.start, hr.end];
            const vr = frame.bbox.v_range;
            let sylim;
            if (dims == 'height' || dims == 'both') {
                sylim = [array_1.min([sy0, sy1]), array_1.max([sy0, sy1])];
                sylim = [array_1.max([sylim[0], vr.start]), array_1.min([sylim[1], vr.end])];
            }
            else
                sylim = [vr.start, vr.end];
            return [sxlim, sylim];
        }
    }
    exports.Tool = Tool;
    Tool.__name__ = "Tool";
    Tool.init_Tool();
},
/* styles/toolbar.js */ function _(require, module, exports) {
    require(62) /* ./root */;
    const _a = require(61) /* ../core/dom */;
    _a.styles.append(".bk-root .bk-toolbar-hidden {\n  visibility: hidden;\n  opacity: 0;\n  transition: visibility 0.3s linear, opacity 0.3s linear;\n}\n.bk-root .bk-toolbar,\n.bk-root .bk-button-bar {\n  display: flex;\n  display: -webkit-flex;\n  flex-wrap: nowrap;\n  -webkit-flex-wrap: nowrap;\n  align-items: center;\n  -webkit-align-items: center;\n  user-select: none;\n  -ms-user-select: none;\n  -moz-user-select: none;\n  -webkit-user-select: none;\n}\n.bk-root .bk-toolbar .bk-logo {\n  flex-shrink: 0;\n  -webkit-flex-shrink: 0;\n}\n.bk-root .bk-toolbar.bk-above,\n.bk-root .bk-toolbar.bk-below {\n  flex-direction: row;\n  -webkit-flex-direction: row;\n  justify-content: flex-end;\n  -webkit-justify-content: flex-end;\n}\n.bk-root .bk-toolbar.bk-above .bk-button-bar,\n.bk-root .bk-toolbar.bk-below .bk-button-bar {\n  display: flex;\n  display: -webkit-flex;\n  flex-direction: row;\n  -webkit-flex-direction: row;\n}\n.bk-root .bk-toolbar.bk-above .bk-logo,\n.bk-root .bk-toolbar.bk-below .bk-logo {\n  order: 1;\n  -webkit-order: 1;\n  margin-left: 5px;\n  margin-right: 0px;\n}\n.bk-root .bk-toolbar.bk-left,\n.bk-root .bk-toolbar.bk-right {\n  flex-direction: column;\n  -webkit-flex-direction: column;\n  justify-content: flex-start;\n  -webkit-justify-content: flex-start;\n}\n.bk-root .bk-toolbar.bk-left .bk-button-bar,\n.bk-root .bk-toolbar.bk-right .bk-button-bar {\n  display: flex;\n  display: -webkit-flex;\n  flex-direction: column;\n  -webkit-flex-direction: column;\n}\n.bk-root .bk-toolbar.bk-left .bk-logo,\n.bk-root .bk-toolbar.bk-right .bk-logo {\n  order: 0;\n  -webkit-order: 0;\n  margin-bottom: 5px;\n  margin-top: 0px;\n}\n.bk-root .bk-toolbar-button {\n  width: 30px;\n  height: 30px;\n  background-size: 60%;\n  background-color: transparent;\n  background-repeat: no-repeat;\n  background-position: center center;\n}\n.bk-root .bk-toolbar-button:hover {\n  background-color: #f9f9f9;\n}\n.bk-root .bk-toolbar-button:focus {\n  outline: none;\n}\n.bk-root .bk-toolbar-button::-moz-focus-inner {\n  border: 0;\n}\n.bk-root .bk-toolbar.bk-above .bk-toolbar-button {\n  border-bottom: 2px solid transparent;\n}\n.bk-root .bk-toolbar.bk-above .bk-toolbar-button.bk-active {\n  border-bottom-color: #26aae1;\n}\n.bk-root .bk-toolbar.bk-below .bk-toolbar-button {\n  border-top: 2px solid transparent;\n}\n.bk-root .bk-toolbar.bk-below .bk-toolbar-button.bk-active {\n  border-top-color: #26aae1;\n}\n.bk-root .bk-toolbar.bk-right .bk-toolbar-button {\n  border-left: 2px solid transparent;\n}\n.bk-root .bk-toolbar.bk-right .bk-toolbar-button.bk-active {\n  border-left-color: #26aae1;\n}\n.bk-root .bk-toolbar.bk-left .bk-toolbar-button {\n  border-right: 2px solid transparent;\n}\n.bk-root .bk-toolbar.bk-left .bk-toolbar-button.bk-active {\n  border-right-color: #26aae1;\n}\n.bk-root .bk-button-bar + .bk-button-bar:before {\n  content: \" \";\n  display: inline-block;\n  background-color: lightgray;\n}\n.bk-root .bk-toolbar.bk-above .bk-button-bar + .bk-button-bar:before,\n.bk-root .bk-toolbar.bk-below .bk-button-bar + .bk-button-bar:before {\n  height: 10px;\n  width: 1px;\n}\n.bk-root .bk-toolbar.bk-left .bk-button-bar + .bk-button-bar:before,\n.bk-root .bk-toolbar.bk-right .bk-button-bar + .bk-button-bar:before {\n  height: 1px;\n  width: 10px;\n}\n");
    exports.bk_toolbar = "bk-toolbar";
    exports.bk_toolbar_hidden = "bk-toolbar-hidden";
    exports.bk_toolbar_button = "bk-toolbar-button";
    exports.bk_button_bar = "bk-button-bar";
    exports.bk_toolbar_button_custom_action = "bk-toolbar-button-custom-action";
},
/* models/tools/on_off_button.js */ function _(require, module, exports) {
    const button_tool_1 = require(263) /* ./button_tool */;
    const mixins_1 = require(138) /* ../../styles/mixins */;
    class OnOffButtonView extends button_tool_1.ButtonToolButtonView {
        render() {
            super.render();
            if (this.model.active)
                this.el.classList.add(mixins_1.bk_active);
            else
                this.el.classList.remove(mixins_1.bk_active);
        }
        _clicked() {
            const active = this.model.active;
            this.model.active = !active;
        }
    }
    exports.OnOffButtonView = OnOffButtonView;
    OnOffButtonView.__name__ = "OnOffButtonView";
},
/* models/tools/toolbar_base.js */ function _(require, module, exports) {
    const logging_1 = require(65) /* ../../core/logging */;
    const dom_1 = require(61) /* ../../core/dom */;
    const build_views_1 = require(92) /* ../../core/build_views */;
    const p = require(18) /* ../../core/properties */;
    const dom_view_1 = require(59) /* ../../core/dom_view */;
    const array_1 = require(8) /* ../../core/util/array */;
    const data_structures_1 = require(14) /* ../../core/util/data_structures */;
    const types_1 = require(7) /* ../../core/util/types */;
    const model_1 = require(64) /* ../../model */;
    const gesture_tool_1 = require(268) /* ./gestures/gesture_tool */;
    const action_tool_1 = require(269) /* ./actions/action_tool */;
    const help_tool_1 = require(270) /* ./actions/help_tool */;
    const inspect_tool_1 = require(262) /* ./inspectors/inspect_tool */;
    const toolbar_1 = require(265) /* ../../styles/toolbar */;
    const logo_1 = require(272) /* ../../styles/logo */;
    const mixins_1 = require(138) /* ../../styles/mixins */;
    class ToolbarViewModel extends model_1.Model {
        constructor(attrs) {
            super(attrs);
        }
        static init_ToolbarViewModel() {
            this.define({
                _visible: [p.Any, null],
                autohide: [p.Boolean, false],
            });
        }
        get visible() {
            return (!this.autohide) ? true : (this._visible == null) ? false : this._visible;
        }
    }
    exports.ToolbarViewModel = ToolbarViewModel;
    ToolbarViewModel.__name__ = "ToolbarViewModel";
    ToolbarViewModel.init_ToolbarViewModel();
    class ToolbarBaseView extends dom_view_1.DOMView {
        initialize() {
            super.initialize();
            this._tool_button_views = {};
            this._build_tool_button_views();
            this._toolbar_view_model = new ToolbarViewModel({ autohide: this.model.autohide });
        }
        connect_signals() {
            super.connect_signals();
            this.connect(this.model.properties.tools.change, () => {
                this._build_tool_button_views();
                this.render();
            });
            this.connect(this.model.properties.autohide.change, () => {
                this._toolbar_view_model.autohide = this.model.autohide;
                this._on_visible_change();
            });
            this.connect(this._toolbar_view_model.properties._visible.change, () => this._on_visible_change());
        }
        remove() {
            build_views_1.remove_views(this._tool_button_views);
            super.remove();
        }
        _build_tool_button_views() {
            const tools = (this.model._proxied_tools != null ? this.model._proxied_tools : this.model.tools); // XXX
            build_views_1.build_views(this._tool_button_views, tools, { parent: this }, (tool) => tool.button_view);
        }
        set_visibility(visible) {
            if (visible != this._toolbar_view_model._visible) {
                this._toolbar_view_model._visible = visible;
            }
        }
        _on_visible_change() {
            const visible = this._toolbar_view_model.visible;
            const hidden_class = toolbar_1.bk_toolbar_hidden;
            if (this.el.classList.contains(hidden_class) && visible) {
                this.el.classList.remove(hidden_class);
            }
            else if (!visible) {
                this.el.classList.add(hidden_class);
            }
        }
        render() {
            dom_1.empty(this.el);
            this.el.classList.add(toolbar_1.bk_toolbar);
            this.el.classList.add(mixins_1.bk_side(this.model.toolbar_location));
            this._toolbar_view_model.autohide = this.model.autohide;
            this._on_visible_change();
            if (this.model.logo != null) {
                const gray = this.model.logo === "grey" ? logo_1.bk_grey : null;
                const logo = dom_1.a({ href: "https://bokeh.org/", target: "_blank", class: [logo_1.bk_logo, logo_1.bk_logo_small, gray] });
                this.el.appendChild(logo);
            }
            const bars = [];
            const el = (tool) => {
                return this._tool_button_views[tool.id].el;
            };
            const { gestures } = this.model;
            for (const et in gestures) {
                bars.push(gestures[et].tools.map(el));
            }
            bars.push(this.model.actions.map(el));
            bars.push(this.model.inspectors.filter((tool) => tool.toggleable).map(el));
            bars.push(this.model.help.map(el));
            for (const bar of bars) {
                if (bar.length !== 0) {
                    const el = dom_1.div({ class: toolbar_1.bk_button_bar }, bar);
                    this.el.appendChild(el);
                }
            }
        }
        update_layout() { }
        update_position() { }
        after_layout() {
            this._has_finished = true;
        }
    }
    exports.ToolbarBaseView = ToolbarBaseView;
    ToolbarBaseView.__name__ = "ToolbarBaseView";
    function createGestureMap() {
        return {
            pan: { tools: [], active: null },
            scroll: { tools: [], active: null },
            pinch: { tools: [], active: null },
            tap: { tools: [], active: null },
            doubletap: { tools: [], active: null },
            press: { tools: [], active: null },
            pressup: { tools: [], active: null },
            rotate: { tools: [], active: null },
            move: { tools: [], active: null },
            multi: { tools: [], active: null },
        };
    }
    class ToolbarBase extends model_1.Model {
        constructor(attrs) {
            super(attrs);
        }
        static init_ToolbarBase() {
            this.prototype.default_view = ToolbarBaseView;
            this.define({
                tools: [p.Array, []],
                logo: [p.Logo, 'normal'],
                autohide: [p.Boolean, false],
            });
            this.internal({
                gestures: [p.Any, createGestureMap],
                actions: [p.Array, []],
                inspectors: [p.Array, []],
                help: [p.Array, []],
                toolbar_location: [p.Location, 'right'],
            });
        }
        initialize() {
            super.initialize();
            this._init_tools();
        }
        _init_tools() {
            // The only purpose of this function is to avoid unnecessary property churning.
            const tools_changed = function (old_tools, new_tools) {
                if (old_tools.length != new_tools.length) {
                    return true;
                }
                const new_ids = new data_structures_1.Set(new_tools.map(t => t.id));
                return array_1.some(old_tools, t => !new_ids.has(t.id));
            };
            const new_inspectors = this.tools.filter(t => t instanceof inspect_tool_1.InspectTool);
            if (tools_changed(this.inspectors, new_inspectors)) {
                this.inspectors = new_inspectors;
            }
            const new_help = this.tools.filter(t => t instanceof help_tool_1.HelpTool);
            if (tools_changed(this.help, new_help)) {
                this.help = new_help;
            }
            const new_actions = this.tools.filter(t => t instanceof action_tool_1.ActionTool);
            if (tools_changed(this.actions, new_actions)) {
                this.actions = new_actions;
            }
            const check_event_type = (et, tool) => {
                if (!(et in this.gestures)) {
                    logging_1.logger.warn(`Toolbar: unknown event type '${et}' for tool: ${tool.type} (${tool.id})`);
                }
            };
            const new_gestures = createGestureMap();
            for (const tool of this.tools) {
                if (tool instanceof gesture_tool_1.GestureTool && tool.event_type) {
                    if (types_1.isString(tool.event_type)) {
                        new_gestures[tool.event_type].tools.push(tool);
                        check_event_type(tool.event_type, tool);
                    }
                    else {
                        new_gestures.multi.tools.push(tool);
                        for (const et of tool.event_type) {
                            check_event_type(et, tool);
                        }
                    }
                }
            }
            for (const et of Object.keys(new_gestures)) {
                const gm = this.gestures[et];
                if (tools_changed(gm.tools, new_gestures[et].tools)) {
                    gm.tools = new_gestures[et].tools;
                }
                if (gm.active && array_1.every(gm.tools, t => t.id != gm.active.id)) {
                    gm.active = null;
                }
            }
        }
        get horizontal() {
            return this.toolbar_location === "above" || this.toolbar_location === "below";
        }
        get vertical() {
            return this.toolbar_location === "left" || this.toolbar_location === "right";
        }
        _active_change(tool) {
            const { event_type } = tool;
            if (event_type == null)
                return;
            const event_types = types_1.isString(event_type) ? [event_type] : event_type;
            for (const et of event_types) {
                if (tool.active) {
                    const currently_active_tool = this.gestures[et].active;
                    if (currently_active_tool != null && tool != currently_active_tool) {
                        logging_1.logger.debug(`Toolbar: deactivating tool: ${currently_active_tool.type} (${currently_active_tool.id}) for event type '${et}'`);
                        currently_active_tool.active = false;
                    }
                    this.gestures[et].active = tool;
                    logging_1.logger.debug(`Toolbar: activating tool: ${tool.type} (${tool.id}) for event type '${et}'`);
                }
                else
                    this.gestures[et].active = null;
            }
        }
    }
    exports.ToolbarBase = ToolbarBase;
    ToolbarBase.__name__ = "ToolbarBase";
    ToolbarBase.init_ToolbarBase();
},
/* models/tools/gestures/gesture_tool.js */ function _(require, module, exports) {
    const button_tool_1 = require(263) /* ../button_tool */;
    const on_off_button_1 = require(266) /* ../on_off_button */;
    class GestureToolView extends button_tool_1.ButtonToolView {
    }
    exports.GestureToolView = GestureToolView;
    GestureToolView.__name__ = "GestureToolView";
    class GestureTool extends button_tool_1.ButtonTool {
        constructor(attrs) {
            super(attrs);
            this.button_view = on_off_button_1.OnOffButtonView;
        }
    }
    exports.GestureTool = GestureTool;
    GestureTool.__name__ = "GestureTool";
},
/* models/tools/actions/action_tool.js */ function _(require, module, exports) {
    const button_tool_1 = require(263) /* ../button_tool */;
    const signaling_1 = require(13) /* ../../../core/signaling */;
    class ActionToolButtonView extends button_tool_1.ButtonToolButtonView {
        _clicked() {
            this.model.do.emit();
        }
    }
    exports.ActionToolButtonView = ActionToolButtonView;
    ActionToolButtonView.__name__ = "ActionToolButtonView";
    class ActionToolView extends button_tool_1.ButtonToolView {
        connect_signals() {
            super.connect_signals();
            this.connect(this.model.do, () => this.doit());
        }
    }
    exports.ActionToolView = ActionToolView;
    ActionToolView.__name__ = "ActionToolView";
    class ActionTool extends button_tool_1.ButtonTool {
        constructor(attrs) {
            super(attrs);
            this.button_view = ActionToolButtonView;
            this.do = new signaling_1.Signal0(this, "do");
        }
    }
    exports.ActionTool = ActionTool;
    ActionTool.__name__ = "ActionTool";
},
/* models/tools/actions/help_tool.js */ function _(require, module, exports) {
    const action_tool_1 = require(269) /* ./action_tool */;
    const p = require(18) /* ../../../core/properties */;
    const icons_1 = require(271) /* ../../../styles/icons */;
    class HelpToolView extends action_tool_1.ActionToolView {
        doit() {
            window.open(this.model.redirect);
        }
    }
    exports.HelpToolView = HelpToolView;
    HelpToolView.__name__ = "HelpToolView";
    class HelpTool extends action_tool_1.ActionTool {
        constructor(attrs) {
            super(attrs);
            this.tool_name = "Help";
            this.icon = icons_1.bk_tool_icon_help;
        }
        static init_HelpTool() {
            this.prototype.default_view = HelpToolView;
            this.define({
                help_tooltip: [p.String, 'Click the question mark to learn more about Bokeh plot tools.'],
                redirect: [p.String, 'https://docs.bokeh.org/en/latest/docs/user_guide/tools.html'],
            });
        }
        get tooltip() {
            return this.help_tooltip;
        }
    }
    exports.HelpTool = HelpTool;
    HelpTool.__name__ = "HelpTool";
    HelpTool.init_HelpTool();
},
/* styles/icons.js */ function _(require, module, exports) {
    require(62) /* ./root */;
    const _a = require(61) /* ../core/dom */;
    _a.styles.append(".bk-root .bk-tool-icon-box-select {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gEMEg0kduFrowAAAIdJREFUWMPtVtEKwCAI9KL//4e9DPZ3+wP3KgOjNZouFYI4C8q7s7DtB1lGIeMoRMRinCLXg/ML3EcFqpjjloOyZxRntxpwQ8HsgHYARKFAtSFrCg3TCdMFCE1BuuALEXJLjC4qENsFVXCESZw38/kWLOkC/K4PcOc/Hj03WkoDT3EaWW9egQul6CUbq90JTwAAAABJRU5ErkJggg==\");\n}\n.bk-root .bk-tool-icon-box-zoom {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gEMEg82t254aQAAAkBJREFUWMPN11+E1FEUB/DPTFn2qaeIpcSwr5NlUyJiKWVXWUqvlUh/iE3RY9mUekkPPURtLKNRrFJEeuphGfUUaVliiX1aVjGs6aG7+XX9ZnZ+d2fTl2vmnHvPPfeee/79Sk+may2/UQq/q7Qu+bAJoxjHIKqB/wlfUMcMVqI9bLZ+DGIKwzlzQ2GcxCx2xwvKOUKlaHTiX8bHNspjDONHkOmJBW5jIof/FvPh/06MZOb6cRc7cGn1AKUE5cdzlM/gAr5F/O24H3xkFRfxAbVygvK+cIsspjGWo1zgjeFpxL+BvnLw7laBA4xjIFJwrgu52DoVjKdY4HBEX8dSF3JLYe1fe6UcYCii3xWQjdfuSTnAtoheKCC7GNED5Zx4L4qt61jbTLHA94geKSC7P7ZeShQ0Inoi1IJuEOeORooFXkV0FZNdZs5qvFfKAeqYy7nZ6yg//HG0MBfffh71lFrQDCW2EvEP4mt4okZUDftz9rmGZkotmMxJRtlisy+MTniAWrty3AlXw0hFM2TD89l+oNsoOJXjbIs4EpqNtTCLXbiZ0g+M4mFObj8U3vsNjoZCVcmk60ZwthpepLZkB/AsivWfOJZxtpUQHfWib7KWDwzjeegBZJSdKFiE2qJTFFTwElsi/unQ/awXrU4WGMD7nOJxBY/1EO2iYConq93CHT1GOwucjdqnRyFz+VcHmMNefMY9nNkA3SWUOoXhQviSWQ4huLIRFlirFixnQq/XaKXUgg2xQNGv4V7x/RcW+AXPB3h7H1PaiQAAAABJRU5ErkJggg==\");\n}\n.bk-root .bk-tool-icon-zoom-in {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gEMEgsUBmL8iQAAA2JJREFUWMO9l12IlFUYx3//MzPrLpSjkm5oN4FFIWVEl66IQlFYwtLOzozsjHdGRSCRF0sfBEXRVV0FQuQiLm5CZNBFgRRaRLVFhbJ2EdiN5gbK7toObTPn6eYdPTvNzPvOBz5Xh/ec5/n/n89zXtEHmZqeSXSuXBz/3zfdKvBWJHQrwZuRcP0El+QkbQXeBX6WZEgm6TtJk5lM5o4Lc+cV6qpf4Ga20Tm338zeATItVK9Ker6yvPzp4NDQ3+XieGsCU9MzTYumGbhz7m4ze9/MHgvBgItACrgfGAj2jgAvAYs3wlEujjc13kii8YyZrXXOfWhmo9GnFUlvOOemarVapVqtkslksmb2KjARqL62ecuWN9NxbRInzrldAXhV0uFSIfdew7G/gNLU9MwS8CwSmE3Oz88fcXG5blfpqVRq0Ix8VIAAX0XgrVL7HDCHGcCaWrV60LUBN8Dae58aQIxEqcA592I9M610JL0cpG/U9TIHJNKY3RV5z0R+7Nd4HZ0P1g/2RMBuegLAsRMnb4vT8d5vqKfMzOgtAlADrkmqGywmiMBTwfr3dC9j1Xv/r6Tvg/5/5ejxE6cO7M9faVbQZrYNOFSPmqQvVo9FKexvi5uWX58943aM7DwAfBDY+FbSCxP5sdkGx55GeguzrUEXPaSo2pFkAbiSZQCAzZJOmdkjwd6SpB/M7KykQTPbA2wDhoIzRzcNDx9MJwGNIXdJ0mEzmwbujL7dbma7gd03A7lKfnTOvf74nl0r6bonTUbujRSUCrm2d4L3/kvn3JPe+8+BDW2i9o+kT7z3kxP5sYsA6W47oE64TsR7P9tQL4vA2mh9WdIscKxUyJ0M7aR7acOGzikD65EQLEjaa2ZXzMwDFeB6qZBbbLTRE4EGeSaozNOZgYFf8qP7lmIvs354n0qlHpB0T7B9Ogl4IgJJrmjv/SiQjbrkD+BMUkfSbYATPdckrTOzkciWAXOlQu5cYgLdPEIapud9wMOR9zVJH3ViKx333mtHMJvNuoWFhZ3A+ojMcja77njXBEKwJJfTcqUyCIQ34Mf7nnh0paMnXacFuGoC1mr3AtuDfLzd8Zuyl+rfuGn4HLAD+Az4qZQf+61TAj0Noj8vX6oC35SL43u7teG6rf5+iXppwW7/JUL5D03qaFRvvUe+AAAAAElFTkSuQmCC\");\n}\n.bk-root .bk-tool-icon-zoom-out {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gEMEgsHgty9VwAAA0FJREFUWMO9l09oXFUUxn/fmXlpItppi22k7UJBRSlVkCytSAuKUloIdjKT0El3FXVXdVFKRVAQV7qQohsNwdA0UFvBhYtqUVyIVlRaogtFQVq7qSTVjA3z3nHzBq/jvPmTN/Ss7rv3nvN99/y794kByMzcfE/7picn/jenmwWeRUI3E7wdCRskuCSTdDfwBvCtJEdySV9KOhpF0e0/LF5SqKtBgbv7ZjObcvfXgShD9Zqk5+orKx8Oj4z8NT05kU1gZm6+bdK0Azezu9z9hLs/HoIBvwAF4H5gKFh7B3gBWFY3460kWve4+3oze9fdx9OpVUmvmNlMHMf1RqNBFEUldz8OHAxUX9q6bduryut+Sfvc/Wz62ZD0fK1afjND9y3gGSRwv1GMojstTxUUCoVhdyopEYDzKXjWwZ4FFnEHWBc3Goet00m7lZlZYQixKw0FZnakGZksHUnHgvCN5/KARBH37enpOVg58H13HV0Kxg/kIuD/ngSA2ZMLt3bTSZJkUzNk7k4+D0AM/CGpaXCyBw/sC8Y/qZd2GpZiuL9YLN4Sx/HpoP5/c/exQ1OVq+1yyt13SLoArEsJnMjlgfOffvK3u58Kprab2QezJxfG2iTzUzI70wRPG9jbmpmb95SNB9mpzp7/j2yVdNbdx4K565K+cvfPJQ27+x5gBzAS7Hlvy+jo4WIvoC3kWpcvS3rR3eeAO9K529x9N7C7zX6AC2b28hN7Hl1Vt44niVq13LUjmtlYkiQfA5s6eO+GpDNJkhw9NFX5ueNt2ARodyF1IHIN2JiOl4H16fiKpK+B2Vq1vBAqFAf4IJkGNiIhWJK0192vunsC1IE/a9XycquNXARa5OnApeeioaHvKuP7r3dTGsiLqFAo7JR0T7B8rhfwXARa2us4UEqr5Ffgs151i/08oTNKdIO770ptObBYq5Yv5ibQq/sl3Qc8lJ4+lnSqH1vFfp9koZRKJVtaWnqkWXqSVkqlDe+vmUDWpZMlK/X6MBDegKf3P/nYaj8ErN9fqZBYEsf3Ag8G8Xit33BaniTcvGX0IvAw8BHwTa1y4Md+CeRqRL9fudwAvpienNi7Vhu21uwflOT+L+i1X2TJP57iUvUFtHWsAAAAAElFTkSuQmCC\");\n}\n.bk-root .bk-tool-icon-help {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAABltpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgICAgICAgICAgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiCiAgICAgICAgICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPHRpZmY6Q29tcHJlc3Npb24+NTwvdGlmZjpDb21wcmVzc2lvbj4KICAgICAgICAgPHRpZmY6WFJlc29sdXRpb24+NzI8L3RpZmY6WFJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgICAgIDx0aWZmOllSZXNvbHV0aW9uPjcyPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+MzI8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+MzI8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPHhtcE1NOkluc3RhbmNlSUQ+eG1wLmlpZDpBODVDNDBDMzIwQjMxMUU0ODREQUYzNzM5QTM2MjBCRTwveG1wTU06SW5zdGFuY2VJRD4KICAgICAgICAgPHhtcE1NOkRvY3VtZW50SUQ+eG1wLmRpZDpBODVDNDBDNDIwQjMxMUU0ODREQUYzNzM5QTM2MjBCRTwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOkRlcml2ZWRGcm9tIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgPHN0UmVmOmluc3RhbmNlSUQ+eG1wLmlpZDpBODVDNDBDMTIwQjMxMUU0ODREQUYzNzM5QTM2MjBCRTwvc3RSZWY6aW5zdGFuY2VJRD4KICAgICAgICAgICAgPHN0UmVmOmRvY3VtZW50SUQ+eG1wLmRpZDpBODVDNDBDMjIwQjMxMUU0ODREQUYzNzM5QTM2MjBCRTwvc3RSZWY6ZG9jdW1lbnRJRD4KICAgICAgICAgPC94bXBNTTpEZXJpdmVkRnJvbT4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6U2VxLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxNjoxMToyOCAxMToxMTo4MjwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjY8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+Cphjt2AAAAT7SURBVFgJxRdbaFxFdGb2bhui227BWrsVKYgf2kJUbP9EUPuzEB803WTXJjH61Q/7Ya1+CMYKEVTsh4J/EpvY7BoabUiNiA8s1p+4KIhpoUUEselHqyS76TbZ3HuP58ydc3d2u4+IkQxczpz3mZkzZ86VYpXjvenpjZsLhUcliE4AuUuASAgptmt1EFdwPiclzIIUUwubNn17OJlcXo1p2UpodHRiux9xB1Eug1+slbzhFxGOKc851tu7/0oznYYBDA8Pt0U2tL8KQryIq2tvZqQhD0QJHRz3yqWhgYGBpXpydQMwqz6NCnurleCSADkJEfgKfOePqL80R/wV1ZaQyr1LenKfkPCkEPKeaj0xg7vxVL3duCmA0Vyuw/fl52hgBxsBED+h4Cv9z3R/zbRm8MTJTx7HQN7GQB6w5C4L4SX7M5lfLBpurjXMyvNIShiyi0l1pL8n9b7EDGPR8fHxzSsQ6XDB3618/xqo6Pk25V5MpVJllgHM1BO58RdQ612kOYZ+GXdij70TYQB05mpj+1kU5G2fB+l3PZtOf8NGx6ambnMXb3yAxg8wjSEG6OKKR9oicBQD+ZvpH2Wzj0lQpxCPG9qMv1x6hHNCsSAlHM7ZOa682vlI9tRDbvHGbD3nZAPpDoD/3JIrLpAs26UFkC3EMUA99hpfGtEBfJjNJnS2Gwnadnvl+Xw+iuc3DAJuNyIaSCHpilVldyDjjUxj3WDZIAhxhHHyRcdNuA7AAfUaXzVKODpzFiZ4/uLvh5G+m2no+C/pyIf7MqlEJB7bpqR6nXkEUfbeawuLaZsW2ISfNQ2vtaktQlGFQyIVGT0o2+2EC4iQNGwjBIN9qdQ5Qg4mk4X4rW3vCClLtowE2FOFUxKDfNmiZci3ovKKRFPh4FK9q4Zbdr+lKKJiA13TcHR2dmLBgdmQ0GAS2MZaEowY+XbAk09IvgtYZGp16SyvFhaHcIUh645t8T9DBCcnz5zZ4hZLu3DzK2QlL1QQa0Y+pHiJKPSuOGj3PmZTheM5w2TwqBxnvBZOTk7G5gvXJ5Aelms8wnJURL+olSWcfEhf6gDoUXPMq6ZlqbzWU2pE+3hi4s6F68tfIj9cBMlikr7Z0/P0b/X0yIcUXsDCF1WhtL4OROHaXk+xlkbV0Cu732Nmhc4peaWSg73pA8dq5RkvO37ldUTfXCKZv2q45MkhvG87WQEzpCCUSvV1d9GONBy3lMvgKSwrZig8gjAietWY0QriylO2jIo4yVbOSb7KB/qmI9BPKjHpSSXYauRyn92Nq9/Kcrj13x3s3v8D481glQ/0raiNYgX9njPSBOImbrHZePl+tfFmc9sH+Xaoh8NjOKSVdDMhjjYzQLy+dFceH5+IJQf9VYXX4tROg4ZFU8m31M3mfPEqUoJqCGJfvWpo2xnNfdrhC28n06SCeSzNZxlvBINGRXCtKS7EY1uV6V7HWAm38y1cXaXsMcOCvr9ySPj+af7A1U2HJXHzVNvUXVLIGyPf+jV0pf8GHoN+TLAyPkidTCi2RpPApmnR0Bd1zGRaB/B8Oj2HSw7LLbVR1MmskW8RdEWVXSJf3JbpAMgRtc4IZoxTh9qotQjCasm46M0YX9pV1VmbpvRH5OwwgdRtSg2vKaAz/1dNKVtb17Y8DCL4HVufHxMOYl1/zTgIgiYvBnFKfaNp3YjTdPz3n9Na8//X7/k/O1tdwopcZlcAAAAASUVORK5CYII=\");\n}\n.bk-root .bk-tool-icon-hover {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gEMEg4oVHp0SwAAAQJJREFUWMPtlsENgzAMRb8RQ5VJItFDOgaZAMaAA0iZpN3KPZSoEEHSQBCViI/G8pfNt/KAFFcPshPdoAGgZkYVVYjQAFCyFLN8tlAbXRwAxp61nc9XCkGERpZCxRDvBl0zoxp7K98GAACxxH29srNNmPsK2l7zHoHHXZDr+/9vwDfB3kgeSB5IHkgeOH0DmesJjSXi6pUvkYt5u9teVy6aWREDM0D0BRvmGRV5N6DsQkMzI64FidtI5t3AOKWaFhuioY8dlYf9TO1PREUh/9HVeAqzIThHgWZ6MuNmC1jiL1mK4pAzlKUojEmNsxcmL0J60tazWjLZFpClPbd9BMJfL95145YajN5RHQAAAABJRU5ErkJggg==\");\n}\n.bk-root .bk-tool-icon-crosshair {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAADEUlEQVRYR81XXVIaQRCeHqug8CXmBNETaE4gniDwIgpVspxAbxC9ATkBkCpQ8gKeQDiB5AQxNyAvUlrldr7eHxyGXZi1rMJ5opbp7m++7un+htSGF204vsoMoNXrlzSpfWa1oxQfhAegCZGaEtPorHo8znIoJwCt6+td8uk7ApUQCIHTF4BNAWzImq8ap6cP68CsBdDp9i9ZqXM7ML79g/EnCWD+jgMKENKqWT+tXK0CkQqgNRjs0OxpQIqKhoMxaG6/6JeRnK7T6yO2UvVqhYSlLX+ryORfgKn9ORDFIy7ky41yGcwsr0QAQfDH5zucOswx819fs4egI9OFCcD8DjBF7VNbEX0JzdWEt3NHSSASAcCxBDqMgt/623kvyTgNgNjJIfTjk4D4FqaJR1715MjmYAmA5Bx3AwUXQL+t105KaTlcBSC26XRvhjEIoLiq1yqXpr8FAGG16/ug4IT27fxBWu7EiQuAiImJpEMKE6nYM30uAIDDttSUOPfJP7JzbjPhAiBIh9QE67vIvoOi9WJfCwDavf40ulpjbCqmUf+W753ezURuh7Dg1SqflwAEHU6pgfyBq9Y4qx0LG++2fnZ/eUzcstmdM2AWH+jfc+liWdBJfSENf8Lifi3GVwC9mybOfi5dzatWVrbbLIHNva8p5h/16gkaFiLGGxbufkoE6XguwePiXLF3XmMfCUCUAqtKXU7sumd1CowOuJEi3Pg1FBpjitIGhyvVSfvmjci6ZR+rFQfDiPVE2jFYeICQ+PoewwjC5h7CZld6DBdyu6nDSKgzOyIMhmhK5TTqXYbRorZYM46TmpKAAOrGWwSJJekSB1yqJNOzp1Gs7YJ0EDeySDIMtJbQHh6Kf/uFfNFZkolJICRmz0P8DKWZuIG2g1hpok+Mk0Qphs0h9lzMtWRoNvYLuVImUWrmPJDlBKeRBDfATGOpHkhw670QSHWGLLckmF1PTsMlYqMJpyUbiO0weiMMceqLVTcotnMCYAYJJbcuQrVgZFP0NOOJYpr62pf3AmrHfWUG4O7abefGAfwH7EXSMJafOlYAAAAASUVORK5CYII=\");\n}\n.bk-root .bk-tool-icon-lasso-select {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gEMEgwlGP1qdAAABMBJREFUWMO9V1uIVVUY/r61z57ZMx4DnbzgkbQXL5iCJphlWdpIGY4jpFBkEiU9ZNaDRRcITcIwMwgxoQtU2IMXdAZfMjFvpERXYiSbysyBEXFmyuHMnLP32uvrwT2xnY5nxvHQ93Jg7fWv71/r//7L4a59TRgqJk+Z6v3a+sv0OI5nk5wu6VaSVZImAThHsgjgrKTvM5nMUWvtmf5n8HodCIKgOgzDhc65pSTrJQWDsSNpJX1ljHnDOfdT37oZLLHv+8OMMasKhcIJ59xHAJYMlhwAJGUAzJfUTHLFuFzOG5QDU6dNMyQfs9Yedc5tBpAD4IYYNQGoBrDtQnt7/b0LFrJsCHzfn2itfQfAnZLiazytA3AaQAuAiwDaEgeNpGkkswAWSBqRONB38b88z5uTKePt6iiKXkk8jq+iJC5LOmiMaTLGHLPWhmWeHr7vV0dRtATAapAzIVmSo51zyzIlbm2stesFPA6pKk0r6Ryg93y/ek8YFvPOOTg3cDSiKCoC2OP7/rEoirYm4rUkF12lAWNM1lr7lqQn0+QA8gI2jBg5cj6Aj8OwmB+KAKIoukhyp6SRJAUgl0ndPLDWPi9pJQCbuviXvu+/GIZhW1dnJ24UJFuTjCCA2ADA8sYGWmsXS3qmL94kDYAtkh4Nw7ANlQJ5U6INT1KrAYC9zQdykl7nFSj5fXp5Y8NWVBhy7mUAjqShMYdMXV2dJ2klyRwAJ8lIeuGWCRMP7N7frEqSG2OmAFhKshNAp5wrmO7u7jEAngPQm1S2z2pqapr+OPt7XEly0oxwzq2RdFmSD2AMgKKJouhhAL4kA+Cs53l7e3t7uytJHgRBreTWkXwkKVJnJD0B4GAGwIJE9R6AFufc6UqSZ7PZbD6ff5dkA4CQZEHSqwAOISmXtwGIE+F1SeqqIP8d+Xz+C0mLJYWSAODteXffczjdDQNJ0BWMCoLg5gqIbRTJNwHsljQhUb0luWPM2LE7Thw/9m/5NCT/TByxAOYWi8X6/gdWV1dnfN8fNRBxJpMZTXKdc+6IpFVJWAEgkvSJpA0X2tvtVTaSjgOYBCAEEADYSHK87/sfhmEYA9gShuEDkgzJHyWtB/B1irQ2juP7ADxkrX0wOUOpzmdpzEY590HJ7Ni1r2kSyZOSiv2+hSRjSTXp/QAukzySNJOJkmalyNIl10hqMcasdc61XDNcQRD8BnITgNp+36r6kfcNFMMlLQGwTNLMEuQGQBfJl2bdPru+HDkAZAqFQux53jZHEsC6aw0eg2gylNRBcqcx5v04ji999+03AwsWAOI4Lsy9a94WkisAnE5a5WCJYwCfA1g7LJudI2lTHMeXBm1faiQzxkyRtF3S5CTupeAB+KG2tnZFT0/P30NO2VKLzrmfAbwGMipjG5Oc0dPTc0Md05SZ5U4Q2FxChErtEYD7jTGNQ3UgM8Asv90Yc9I5LSKRlXSI5CxJa0jWSALJjKRnAewfkniT+vwf7N7fXHK9rq7O7+jo+BTA/NRrdBpjnnLOnUrvXd7YMPQXSBunneno6IhIHgYwW1JtkgmBpBkATlVMAwOk3nFJ+VSoqgCMr6gIy2FcLtdKspAedyQN/98caDt/3kpyabUmf8WvG/8A1vODTBVE/0MAAAAASUVORK5CYII=\");\n}\n.bk-root .bk-tool-icon-pan {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gEMEg4lKssI9gAAAOtJREFUWMPVll0KwyAMgNPgoc0JzDX2Mtgp3csKErSamGabIEUo/T6bHz0ezxdsjPJ5kvUDaROem7VJAp3gufkbtwtI+JYEOsHNEugIN0mgM1wtsVoF1MnyKtZHZBW4DVxoMh6jaAW0MTfnBAbALyUwCD6UwEB4VyJN4FXx4aqUAACgFLjzrsRP9AECAP4Cm88QtJeJrGivdeNdPpko+j1H7XzUB+6WYHmo4eDk4wj41XFMEfBZGXpK0F/eB+QhVcXslVo7i6eANjF5NYSojCN7wi05MJNgbfKiMaPZA75TBVKCrWWbnGrb3DPePZ9Bcbe/QecAAAAASUVORK5CYII=\");\n}\n.bk-root .bk-tool-icon-xpan {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gEMEg4X4hxZdgAAAMpJREFUWMPtlsEKwjAMhr/pwOOedINJe/PobWXCfAIvgo/nA4heOiilZQqN2yE5lpD/I38SWt3uD9aMHSuHAiiAAmwaYCqoM/0KMABtQYDW11wEaHyiEei28bWb8LGOkk5C4iEEgE11YBQWDyHGuAMD0CeS30IQPfACbC3o+Vd2bOIOWMCtoO1mC+ap3CfmoCokFs/SZd6E0ILjnzrhvFbyEJ2FIZzXyB6iZ3AkjITn8WOdSbbAoaD4NSW+tIZdQYBOPyQKoAAKkIsPv0se4A/1UC0AAAAASUVORK5CYII=\");\n}\n.bk-root .bk-tool-icon-ypan {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gEMEg4anK0lywAAAMVJREFUWMPtlzEKwzAMRX/S7rlpIMXeOnaLaME36FLo8XqCdNFghGljyc4kgQi2Q/SUj0F/eL7eMMTKz6j9wNlYPGRrFcSoLH4XxQPvdQeYuPOlcLbw2dRTgqvoXEaolWM0aP4LYm0NkHYWzyFSSwlmzjw2sR6OvAXNwgEcwAEcwAEcwAEcoGYk20SiMCHlmVoCzACoojEqjHBmCeJOCOo1lgPA7Q8E8TvdjMmHuzsV3NFD4w+1t+Ai/gTx3qHuOFqdMQB8ASMwJX0IEHOeAAAAAElFTkSuQmCC\");\n}\n.bk-root .bk-tool-icon-range {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAABCJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjcyPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj43MjwvdGlmZjpZUmVzb2x1dGlvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjMyPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6Q29sb3JTcGFjZT4xPC9leGlmOkNvbG9yU3BhY2U+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4zMjwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgICAgIDxkYzpzdWJqZWN0PgogICAgICAgICAgICA8cmRmOkJhZy8+CiAgICAgICAgIDwvZGM6c3ViamVjdD4KICAgICAgICAgPHhtcDpNb2RpZnlEYXRlPjIwMTgtMDQtMjhUMTQ6MDQ6NDk8L3htcDpNb2RpZnlEYXRlPgogICAgICAgICA8eG1wOkNyZWF0b3JUb29sPlBpeGVsbWF0b3IgMy43PC94bXA6Q3JlYXRvclRvb2w+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgrsrWBhAAAD60lEQVRYCcVWv2scRxSemZ097SHbSeWkcYwwclDhzr1Q5T6QE1LghP6BGNIYJGRWNlaZItiFK1mr+JAu4HQu0kjpU8sgF3ITAsaFg0hOvt2Zyfvmdsa7a610Unx44Zgf773vvfneezPHNzrbhn3CT3xC3wPXYOC8LDzqdi8YY/gwh4BeknS/2th6dr2kf94AOp3OFyWgMyziOPbMDxV9FTtJnl1ut795Xd0/YQ0/vtYQwMT1KXWCfr2IjOWwtNehwN4xL9ykTrm6Pzl58yLn3J+mKh9mXbT3uRjGEDph+O8/TjfP5dBp7Ha7AX7O3o5nZeD/0E/OGyXntDgzA0X6qmCnrVutVlrUWV9f/3xo+pwhGDhvEPHOjoxnZjJggXmMHzBQ7NGNp9vxk61fr0HR7e/u7pZzCGHlc7qwBYYTT7tJYSx1AQzppyFPft5apta9w7SKcn0b7P7+/jCsDQ5mbc0dCmIJGDN0ehdcjsmkm6A6KUeKFOTE11PLxrC7Ukqh3ylL2fT0NAP9q6ur6rRCJJYsbKB0JsbCKMuy+xREePDyxQPCz+Crlw062QcA5wBOOt1l6vIl2WiI9F1fN6Q+BBqit6hEC4Hk08GQJMn4myjSP7RavVxgdaVUh/3U6HCMsPr9pYnJKRziHtWQ+un58+hGs6nsjQSjpuTyKGN3CX+FBwHXSiEVgjP+O8X6N12kIePES+GzTKAkGbNp8yJsGUMVzz8jPKReiyAQRimy5/cjye5RpF8utFp/+nwmT7d/NMzcFkS7yjJNGDaPURQxIQThEQy0SyF4l5WJYYhBa816vZ6dU7A6CAhbZVow/pDe0O9hVOoCi13r4BgBAvJHqMSQL2vE/iH6IAXEwgrRVUmBoRRwnwJQT98xEeVeSUyB4dJ5nwJBKdCFFGRmUCcu7rwIYypCTblaChuNBhWODrman5ub+4v0rMNBt8z6Ezh7GksJQpCbm79cMQE7QBFm/X6f0rjWnv8WRYg/QdbUpwDAEBy8vPyA8rNGzg3a8MiElwiM7dAtRqNoNptjGPM1laVxP9umWEMGLOKhKUOJDtBwDmzsw9fC/CzHr9SGuCTi2LbbKvVtmqXpCjMihBFa79Wrt5fGx9PDzc3fmu32Lf8qFliwU9emKhBSp+kRKn/hu9k1COEDbFdt/BoKWOAkuEbdVYyoIXv8+I/QK9dMHEb1Knb7MHOv8LFFOsjzCVHWOD7Ltn+MXCRF4729vWMDK+p8rLkvwjLg4N4v741m5YuwCI9CvHp1Ha8gFdBoPnQAkGsYYGxxcfEI7QQlFCTGUXwjAz4tWF+EpymOWu7fglE7qsOvrYE6g4+9/x/vhRbMdLOCFgAAAABJRU5ErkJggg==\");\n}\n.bk-root .bk-tool-icon-polygon-select {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gEMEjc1OfiVKAAAAe1JREFUWMPt1r9rU1EUB/DPK0XbqphFHETo4OCiFhwF0V1KHbRSROLqon+AUMVRRFBwEbRFMBiV+mMW/wIxi5OD1kERRVKRJHUwLvfBTZrU5OWBGXLgQu7Jfe98z/ec7z0vKa88b2q1BDtRHdAPBaylm1NzsxsOjPnPNt6WSWprbft+/c3I3zOAjhT1Y4+fvcjEQJIXnVECSa+AhqIHqlHH5lWCZoe+Gk4GRgDG86j9SAUdlDBSQaZhlOkuHyoVdJmsw98D1S5fM4NYM1LCpqM+Lwa240oLgmZzpVZvzKT75VLZcqksSZKWlQeAy/iORVwIvh31xvotvK7VG3Px4aWHj3Jl4C2uYSvq+Bn8v6LLbaVWb9zsBiKLCvbiNG7gLm7jAYqbPHMJMziZ9lsKoh8GtqCEVVzHftwJn+TFHp4/hg8BSCYVfMOZoPEv2NZGdy9WCGUr9toDR3E2/H4V6nwRe/BmgN65H1ZhvMuB3XiKIyFoGefwO6ysVkUlrNUNsyAK/jli533Q+Y8cJFvAeXyMS1CI/jiMr/gUtD2LQwMGr4R3p7bY3oQHQ5b38CT4D2AXXg6YcQXHpyYnlqKsi5iOAVSwL9zd7zJ09r+Cpwq72omFMazjT9Dnibym0dTkRDUKrrgwH7MwXVyYB38BstaGDfLUTsgAAAAASUVORK5CYII=\");\n}\n.bk-root .bk-tool-icon-redo {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gEMEg4itK+dVQAAAaFJREFUWMPt1L1rFFEUBfDfJDaBBSslIFjbaSFp1FJQFMVCHkzhKIqdUYOCoBgErVz8rCwiTDMwBCIKipDWyip/gxAIWAmBgBC0eYFh2Gx2l9lFcA5M8e59782Zc84dWrT435Hs1siLchqn43MS0zgW22vYxjesYjVLw3YjBPKinMUTBOwf8J5fKLGYpWFjJAJ5Uc7gIW6jM6Kim3iNZ1katgYmEL/6I+YasvY7Lg6iRpIX5VF8wuEe/XV8wGf8jN6LWTiAc7iEQ7ucPZ+lYW0vAtfwvlbfwCKW9gpXDOv1mJvZHiSO91MiyYsyiQSuxtpXXM7SsDmM5nlRdrCMMz3sOJWl4Xevc/vwBzdwAl+yNNwZxfRI+GxelK9ikHcwh8d4NNR/YFRES1ZwoTYdR7I0rNf3TzVNIGbmSvR/Bx08mIgCFSVu4l2ltIWD9WxNGR+W8KOynqnZ0rwCeVG+wa0hjrxtWoF5dAfc28V8Mib/n+Nev5dnabg/zgw87aNEN/bHOwVRiRe4Wym9zNKwMKkpgIWKEt24njxiJlq0aPFv4i9ZWXMSPPhE/QAAAABJRU5ErkJggg==\");\n}\n.bk-root .bk-tool-icon-reset {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gEMEg4gWqH8eQAABLdJREFUWMPtlktsVGUUx3/nfvfOlLQaY2IiRRMQIRpI0PjamJhoVASDvNpCpYw1vJQYSVwZwIVQF6wwRHmkAUof9ElrI6VqDAXcID4TF0IiYQMkSlTokNCZ+b7jove2t+NMH7rQBWd3v+989/zP+Z8X3Jb/WGQySvUNTQBJESkNguAVYIWqzhaRhwBU9WcR+QXoymazn6jqzUQiMQSQzWZRVdal1vwzAI2tHQBPOuc2AbWTdOyQ53n7nHNfRwee51GzqoIQMCLDpr3x/tLQ0oZzrk5Vj0/BOEBt+KYuOlBVGlrahr0Wob27t3gEjnZ2AyQzmUwHsDgP6J/AYRE553neDwDOuUdU9QngNeCumK4TkRMhZUORcYC1qysLA6iuSQHIwkWLD6lqapQsuSmwTVV3h99I7EcAR462A2xR2Ilq6ehTaejvO1774kuLNALR33eclsaGsQDe3fYegHl43vyNwEeqGl1963mm2jl7YZRTQ82qlWP4HM6ZToC5ztkW4LHQoALru7s6Di5dvlIj/e6ujrEAWoZDn8hmMjXATMACGaAVuBjXTVVXFc/AxhaA+4zvn1DV+eHxVWPMAmvtb5GeMWZyZVhI2rt7qVy2pOh9U1snwIPW2vMi4oWJuBPYHkVAVScPoKmtkzVVK6cEMsyJraHhiCqJqJUwj/JRz7TW1iSSyR2rVyylqa0Ta+24Ic8vXaAEmDFc/l5Z2A/80OibuVyuz/f9ElUdHCmvw82t5HK5h6y1PYhsz2YyGw43t2KtBZHIGwB6+j4rCkBVUdV7gXrggnPuu8h4eP+xMeZS2D0rJYZ6AdAMzAt1b4nI26p6IFZOY8pugijcKSIHVLUK0LyST4vnrVfnWr3mjmP4QTATaERkXkypRFX3isjmuHdRJEK6Ckqquopp06bdKCkp2Sgi7XnGLcg7gzeutwNIiPYc8HixqIrIOlU9ONVIhHPEd851icgSVXUiskVV94gIqoonIt0i8gfQCfwae38e6BWRXuBZz5jZ8VbaOE4EIqlZVUEQBLlkMplS1QER2RwkEnsSyaREDUzyeNsvIhvCMqkH1kdIJ2o+k8iJB1LVVRfjZ6nqqlEAIbdVQGto8Lrv+/dbawcjAL7vc+6bs+zetetfLSHxniIFGofGGsU2oC7eOCbDfZ7nQawBOSAX74SF9oEPImOq+r7nmVmxb5raukZa8UReGmNmhbMkAwwBH467EYVZe49z7kdgenj8k7V2oTHm8kgdWcvrNdVFjR8cHkYzjDH9wLjDaEwEzpwa4MypgWvAjtjxfGNMj4jMiT+M+kFsZI/Q6Pv+HGNMT8w4wI7TAyevxXVPD5z8+zD64tRXAMHVK1eaVLUyVvuDqroV2BOnJF4ZIedviUidqt4Re9s+vbx8zZXLl7PR2+nl5Tz/zNOFp2FzxzGAklw22wUsLLaSKXwf8vhosZUM6PeDYEUum70VHfpBwKsVyyfeikOP6oBNwN1TrLbfgX3A1kKLzKeff8nLLzw38T5wZDgxn1LnNk5lLRfP26/OnR2hwfNYW2Atn9RCsrf+EECyrKysDFimqhXhyjY3VLkAXBKRDqA7nU6nS0tLhyIj6XSaN9bVclv+l/IXAmkwvZc+jNUAAAAASUVORK5CYII=\");\n}\n.bk-root .bk-tool-icon-save {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gEMEg4UexUIzAAAAIRJREFUWMNjXLhs5X+GAQRMDAMMWJDYjGhyf7CoIQf8x2H+f0KGM9M7BBio5FNcITo408CoA0YdQM1cwEhtB/ylgqMkCJmFLwrOQguj/xTg50hmkeyARAYGhlNUCIXjDAwM0eREwTUGBgbz0Ww46oBRB4w6YNQBow4YdcCIahP+H5EhAAAH2R8hH3Rg0QAAAABJRU5ErkJggg==\");\n}\n.bk-root .bk-tool-icon-tap-select {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo3NzIwRUFGMDYyMjE2ODExOTdBNUNBNjVEQTY5OTRDRSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpCOTJBQzE0RDQ0RDUxMUU0QTE0ODk2NTE1M0M0MkZENCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpCOTJBQzE0QzQ0RDUxMUU0QTE0ODk2NTE1M0M0MkZENCIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1LjEgTWFjaW50b3NoIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6OTQ0QzIwMUM1RjIxNjgxMUE3QkFFMzhGRjc2NTI3MjgiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NzcyMEVBRjA2MjIxNjgxMTk3QTVDQTY1REE2OTk0Q0UiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz6eYZ88AAADLklEQVR42rSXf2TUYRzHv7tuGcfE6Vwb5zLSSjEj7Y9KWqfEmFZJP+yPMdKKmUrrn0iUfjhWlLFi6YfNrF+StBoTo39iYkTGco4xxxG59P7k/T2PT8/37nu3bx9ezvPj+zyf5/PreS78bGLS8SmrwE6yje3NHJsDBTALpknBz6JhH3NiYAB0gHqPOVv52wJ6QQ48BzdAttTioRJjdeA8mAHHS2xuk3p+M8M16ipVQE49Ds6CiFO9RLjGONf05QLx6wPQaBlbBlPgJVgkP0ETiIJ2sB/E1XfimjfgBOOlKDUqCGOcqBcQnw6BYW5YTo4wbvQhMmCfGRemC2rBiGXzWUb+kM/NRZ6CHWBM9ce5R61NgX6ayhSJ5EPlItlDRNkz4JbFHf06BkSzHjXxM+gDv1S/mPUo2AXWgt9UUHL/IVhS8yUV1/EbV3o4N+NaoE9Fu/i827K5pNYHnqAVJECShWmAaddpscYFFXwR7vnXBRGlnUN/L6kqKJlxnRUuDbaDBiL+vst5d4gpcpBrqk/2jIgCKVUolhntplzivHmwh4stGOPfwBWwl/2dpp8p7xjQZqFLiQJtauKkivYm+kzccpK57yXfOUe+P23JqAnVbhMFmlXntCWnxbT31am9ZJ4BJifsUmNTqt0cYhA5ypympPg7VkEKunPbVb8cIG+0kyHLJZNR7fUMooUKFHAPkfQo58VLK+RzwRDd4FdWG9mjpaAXzqkJa1R7kQttqEABWXMjOOxxVRfnhRm5URX1prk/0pQHwNcKlchZ+jdpC+hFdVqO0my9Hj5dkYgCn1Rfh/KdlNDHrJhPqlDih+IfBd6qwpOgEqYMsorJ2HtWxtagLJDn/W3KRfPOZhoeBJfZPgVeGKeKrkQBh5dLXl25Ny3pc4/1fkTdbvFqFQgbxWeYD0hXulhQ0pYiM1jG547fcbMQpVnHTZEn9W3ljsCzwHxCdVteNHIZvQa7/7cC7nV6zHIfyFP9EXjFa7YxKAVqPP4bxhhoLWW+z9JyCb6M/MREg59/RlmmXbmneIybB+YC/ay+yrffqEddDzwGvKxxDmzhc0tc80XVgblqFfgjwAAPubcGjAOl1wAAAABJRU5ErkJggg==\");\n}\n.bk-root .bk-tool-icon-undo {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gEMEg4em8Dh0gAAAatJREFUWMPt1rFrFFEQBvDfGhACASshkL/ALpWVrSAKEQV5sIULWlgZNSgIFkGIVQ412gkBt1lYLERREFJqJRaW1oHAoZUQsDqwecWy7N3tbe6C4H2wxc682Zn3zTfvLXPM8b8j6RqYF+UCzsfnHBawGt3fMcAX7GEvS8NgKgXkRbmMxwg41TLsN0psZmnodyogL8pFPMIdLHUk7hA7eJKl4U/rAuKu3+HslFr/FZezNPSTFslX8QErDe4DvMVH/Iq9F7VwGpdwZUjsPtaSFjv/1vCBPjaxO0xcNbHejLpZrrlvJCMCT+JzA+2fcC1Lw+GE4l3CG1yIptfjCtiKoqtiJ0vD3aM0Py/K57iIMxgkQxat4EdN7e9xdRzlk+LEEPvDWvIDXJ928sYxjL36icWK+VaWhlezOIqbGFirJd/H7szugrwoX+D2BDEvszSsT5OBdfRaru/F9dPXQF6U27g/KnmWhgctxqyzBrZGMNGL/rHI0nDkKXiKexXTsywNGx0OnFbFNk3BRoWJXnw//j+ivCi32/S8CxPVNiWOAdUiJtXITIqYY45/Cn8B2D97FYW2H+IAAAAASUVORK5CYII=\");\n}\n.bk-root .bk-tool-icon-wheel-pan {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gEMEgswOmEYWAAABddJREFUWMO9l09oXNcVxn/n3vc0fzRjj2RHyIZ6ERuy6CarxJtS0pQSCsXNpqGFWK5tTHAwyqIGN7VdEts1LV04BEoxdlJnUbfNogtDCYWQRZOSxtAUCoFiJY0pWJVUjeTKM9LMe+9+Xcyb8ZMychuofeHCffeee7/vnXvOuefYlV/+mv932//tb91z/Y2rvxmMHQ+4FcEfOIGN4A+UwDDwoQScc7vM7AIwB8yZ2QXn3K77Ab6OgJnVgeOSbkqaBiaACUnTkm4Cx3OZzwf+qzcRQup1zNZ9RwDe+0YI4YKZTUn6zCGSMLOfAF/03r+QZdnyfwO+ePEiI6N1nPMgMDMkETLRbd2mXG8gCbd9YiIKIUxLKoLfBN7I+80+CUlTIYTp7RMT0b3Af37p8kh5y9gZcy4Fzt+5szqSaxkzUR7dwtrKMmaGW242d0t6vrD/He/90865o865o977p4F3Ctp4frnZ3L0Z+OryUrVSrZ0z8ZxhHjhcq1XPrS43q/0flDlK9XpPA2ma7gMeyvfPx3H8TJZlH4YQWiGEVpZlH8Zx/Awwn8s8lKbpvmq1ahvB641SXNk6dhLskNA2MIBtwKHK1vGTW8bKMRbAMgyPqWeETxUM8VSSJAv52JmZA0iSZMHMThWwnipXKp8hsLLcSaIR92oU8xjSayCQXotiHotG3Ku3m+0EOQwPQCDggMf7BzQajSs5eAk4B5zLx4O1vD2eJMmAQKliscgASJMw21pansFs1swQ/DNLmUmTMNuXX+taXHTDaj5OW612R1JZ0nFJJ/J+XFJ5aWmpA6S5bHV8fHsPHFU6q3pJCjtFxtrKMuXRLUUXXxdrRLazFOtUolZlsGhmACsgnHPTwJnCnjP5HMBKLotzxsTE9rgDL0t6LoriKsDIaB31ZEK+JxQJRHFUBR2NqLw8OTkZR0OC0ntm9k1JWU7OA4vD/mZ+YfElsANmNEKi75vztzB5M8uAr+bx48me88g757PQ1U5zNg52YH7hX8l6f+4Fi3c3BqHNmkI4YQOV2MGCNu9qHPYCewfzbrC+XSGcWEcgTRKA3wFfyzdDz5d+D3x9CIcfA4eBbQS9LscskgfLnHNPAnslvS/pbZDHLLPADpx9N9fqpSIBH8cxWZY9m6bpb4Ev5fN/iKLo2TRNgdx/eo8Wk5O7Ts/N/SOSdMjHdj4kmgkIEJLJzPZKetvMTkIvFLsR25Ml2gfuF5M7vnA66sdooJYkCSGERe/9VAjhzRxoKk3Tvg3U8nulVqvx8cyNpER2umM+SdOkbc5B8JhpqBdIgTRR24h+lpKen731aRIN7thscH9Zlv0d2F8YD2TIX7F2uw3A7ZWV1a0TYz9ca8cJZHRbuRuaDfUCw9/qJHamPOKToAwHtHN6lMvlSkH2o7wDMDo6WuGuQbbn5+YAKNcb3J5fSvrhtTY+vsOPuD1IOyRhMOkj9kSx29HfXB5RUnS964NT2+3vbGbxG9auO2cDNuV6A8NTb5TitBuOpQkfYD2vwOxgmvBB2g3Hto5X42EJyVsFlztbKpXGNgqVSqUxSWcLU2+tdToa9hasLjfPYlwGa+bTi8Dl1dvNsyvNtQQL9MO2w+HM7BqwlAtPdrvdq9773WAVsIr3fne3270KTOYyS2Z2bbXdHhogKmPj7YWF+VOSXs/v/9KdO+0fVBrjbRkgB/KIDBnYu9f/7D+ZmfmRxPd6qwB8YmZXcq1MAQ/nJhTM+OnDe/a8+PGNG9lm19V/D1Qw7HXZlcRa69+U6w38l5/4ipxzf5X0CPBILjcGPJH34pVcc8692FxcXLlXRnTwwH7+9P4f8aWe3fY59LIqo1NMyQBCCHNmdgx4BegUWefjDvCKmR0LIcz9L8nokSNH+PRvH4HC3YQ098pSbevg24qlmZmNmtmjkg4D3+j/tZldkvQXSa3PW5ptlpL3ZaIN99OS9F7+IgKUgSyEkNyv2nHT7DZX0dr9rpjua2l2r4rogRAYVqZvnPsPqVnpEXjEaB4AAAAASUVORK5CYII=\");\n}\n.bk-root .bk-tool-icon-wheel-zoom {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gEMEgskILvMJQAABTtJREFUWMPdl1+MXVUVxn/fPvf2zrSFmUKnoBCUdjRoVaIxEpO2JhilMYBCtBQS2hejpg1Uo2NUrIFAoyGmtiE+GHwQGtvQJhqDmKYRBv+URFsFDNCSptH60DJTO3dKnX/33rM/H7rvsDu9M20fDMaVnGTvtb69z7fWXmvtc/TEzqd4OyXwNsv/FwFJQVI/sA14SZKRLOlPkr5TrVYXHz70quYkEEK4TtI2YAgYkrQthHDdhV5uuw+43/ZrwCbgRttgY/tjtrc0m83X3/f+D6ydnJhYcB4BSZcBA7aP2d4ELAGW2N5k+xgwkDB0IH19CGGH7R8B1aQeAf4KvAw0ku4K2zu7uru3ApdPEyiKohd4TNKjtjt5h6RHgccSNrddbvuHtm9Jqoak7xVF8WFgdavV+pSk5cCObNmXgK++85prCj3z28HKqZMnH7D9YAY4BvwujT8BvCuL1INX9vVt+dfwcCvNb7f9q2RuSfrGvWu/sL2Nf3LX7pzvj4ENSGBPVarVd4fRkZFltjdmoMGiKO4IIWwIIWwoiuIOYDDzeOPoyMiyFLkum7WJCMDztrcrTTrIRuAQZ6NcK1utL4dWq/VZoC8BhqvV6l1lWb4YYxyLMY6VZflitVq9CxhOmL60hhCKeYiV7WMKIXw9jT1HpXw3c+bOAKzOjJubzebJrKQCQLPZPClpc7bP6rMYKtjXth2OMf7tIkr11Wz8oQDc1Fb09vY+kQw1YAuwJY2nbUluAnCWpKkaFl6IQIzxivaR2SYA89sJVK/Xp2x32R6w/a30DNjuqtfrU0ArYecDCEqgLqm94T0dEm9mBG7PxkdDlkBnkhebgIezNQ8nHcCZPL9ijE1Jf/bZZoPtzbavmqNZLbf9tSxq+yoduuJ+SZ+zXSZyBXCqU+d8fvC5yRUrV+0G2j3g2hDCLyXd/+Su3QdnvP/zCuH72LWsgf2k0oHlH2c2odlkxcpVEdgr6aDtjyb8x20/J+mA7T9I6rL9SWA5dne2/GdXLl58qNJh398An85yTMA+4DOz8Dgu6Zu2dwJXJ91ltm8Gbp7Fgb+EEB4aHhpq5CEtACqVyr3AC0AlPS8k3TSmQ2YPhhBuS/1/LpmS9JTtNTHGfwBU2uUALARotVqniqJYH2Pck85pfavVaufAwnQvnHc0McaDKVptebN94QAnJB0EdtjekydyZXqjs/0ZgLIs/w6sy8bnYGYJ63pgERKC05JutT1kOwITwL9tvzlzUQUYB+Zjs2DBgu6xsbGJZHstByZbezregcBXeCsEz1bnzXt5anLyzLq71zDLxTRdVgemdx0fv2e2w5thO5DbiqL4oKT3ZKpnpyYnz+SY2ZpTAPZmJfdIrVZbNBNUq9UW2X4kU+2dcf53Aj1pj2PA7y/6m1DS00A9za9uNBq7iqJYBuoGdRdFsazRaOzKSqye1rTbaa/tlbYrqXQP2X4FIA9/J1l39xrC0v7+w5IeB8XkwS1lWe6TGJAYKMty31tfO4qSHl/a3384I3CDpI+kzC4lnRfrue6GytEjR8oQwlY73gC0L4qlth/q0M1/LYWtR48cKQF6enrC6dOnVwGLEpnxnp7en4+O1i/tszzGOCTpPmB7ahb57QUwBWyXdF+McWg6MScmuoA8OX8xOlpvXGz422XYTsB/SnpA0h7bX5R0WzI9HUL4qe2XbI+dk3xl+V7gxoztD5jRI+YK/zkEEokx2/uB/RdzIfUtueqVN04cXwF8G3iHY3z9Urw/j8ClyhsnjrcS2Vv/J/8NLxT+/zqBTkcxU/cfEkyEAu3kmjAAAAAASUVORK5CYII=\");\n}\n.bk-root .bk-tool-icon-box-edit {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gEMEg4QfHjM1QAAAGRJREFUWMNjXLhsJcNAAiaGAQYsDAwM/+lsJ+OgCwGsLqMB+D8o08CoA0YdMOqAUQewDFQdMBoFIyoN/B/U7YFRB7DQIc7xyo9GwbBMA4xDqhxgISH1klXbDYk0QOseEeOgDgEAIS0JQleje6IAAAAASUVORK5CYII=\");\n}\n.bk-root .bk-tool-icon-freehand-draw {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAADTElEQVRYCeWWTWwMYRjH/88721X1lZJIGxJxcEE4OOiBgzjXWh8TJKR76kWacOBGxdEJIdk4VChZI/phidRBHMRRIr7DSUiaSCRFRM3u88gz+o7Z6bBTdjmYZPf9eJ55fv/5zzvvDPC/H9QsA66Olo9Ga+/MdR+Ljm2/KQIULsz9FqItGdOfJKLhApLgVkiSCGODjWit7QpKWy+TNrFeXvzKVUT8NiTVaIgDcbiCFJ7GiT8WkARXAdYBK0Lbhi/CenArRNskuM7/tgNp4ArQ42dwjf3WY5gWTqC7O/NbNn2Xkfw/YwdSw/We14HP2IEZwX+y9cZ9SH0LmgFP7UCz4KkENBNeV0Cz4b8U8DfgKiDxMWwUXETqLvJpCQpXZfawbzS7t9v5pL19cHBwfja7YA0y/lyCM0+E5hv5+piZXwKYcF23as+37bTXsQVqgkL0p/34fHR7DcBtbetFsBmGDwMOJCggYG55yw7dMlk6DuC1Bdu2RsCU9TYWQq2IoGbsreZ5NzvEqfSBsIsIy8OTbcdgiRHeh4o8AFAEwDakbY2AaCCpH7V9aGhoUUUy3UyVbkPYFuYLDlUZH8XBpwxkK0Dbgxg5HcVi0ent7a0RULMIozaHBSMfF9b2SzdutFcFB2FkwMIJOG6qfteXOa1nHZ48tyefuwyfT9s6wtzZ3t7eZse2DR2I228TtHXzuWCx9g8MtK5cuHCZTH4tiHEOa4xFngvTyS8f35d6enomiCi4/foEXBkZaQuukChL4FYA2Whd7YcC4gEdW3CpdL3LtGAVCVYJywEyTpAuJKeMOKXZs/Bw947C50KhUFOG4cwz35cjWNBlHGeD53n3xsfHP/T19U1qciggar8Fa4I3PHobIotBWBtc2hSiChyZxVzM53Pv7FVH6Tp3uVy+g0r1ImD2GjIrQGYIxjnfuXTZGICS5k/bBwJoubwEFX4TLah9EXomJGMA3za+f9913Yl4TnzsDQ+vE6YTZOjHh4ngibstt1pzQwd04F0bPStEBpXqRoBeQ/AKghfBnOEKgS+Q7z91Xfdz/HGKg8Ox7z8iYD9z6wqTkZFgnvhMGP9VZ2or1XVkPM9z0mytSfVsHa1RLBZbLoyNzUnK+ydz3wC6I9x+lwbngwAAAABJRU5ErkJggg==\");\n}\n.bk-root .bk-tool-icon-poly-draw {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gEMEjglo9eZgwAAAc5JREFUWMPt1zFrU1EUB/DfS4OmVTGDIChCP4BgnQXRxVHqIJUupp9AB8VBQcRBQUXIB9DWQoMRiXZzcnQSA34A7aAuHSJKkgo2LvfBrU3aJnlYkBy4vHcP557zP/9z3r33JdXa647N0kHSZd5Nn0rSxc8G3cXp85sMcnZZ8vge3osZ+l3vB8CWFA0iL14t79h210swAjACMAIwAjACkB90D/8/GchI9ve4nPwTBh5E9ws7OepzGWb9EddSn51Op9ZstadSg4VK1UKlKkmSDSMLALewiuNh/hVJq71Wxttmqz0dG88vPc+MgWP4grvYG3SLOBrZFFFrttqPe4HIDxh4GSei+98iSlusuYopXEAjBtEPA3tQwUpwluAbDm4TPJUz+BTW9l2Ce6G7L0X/Bw8D3T/7SKKIDzHg7QCcxjvcQAEtXAnrrg/RP0/DKPbqgcN4iVOR7gcO4dcQgRuoh7HSqwlP4n20m63jJu5n8MkWMYfP3UowhzdR8FU8w9iQwevBdyq3/27CMRzAE5yLuvsRLg+ZcR1nJ8YL81HWJUzGAPaFZwe/Q5MdyYDyNHgjzO90YyGHtVDncuiJchaHw8R4oREFV5qdiVmYLM3OgD9k5209/atmIAAAAABJRU5ErkJggg==\");\n}\n.bk-root .bk-tool-icon-point-draw {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gEMEiERGWPELgAAA4RJREFUWMO1lr1uG1cQhb9ztdRSP7AF1QxgwKlcuZSqRC9gWUUUINWqTh5AnaFOnVPEteQmRuhCURqWsSqqc9IolREXdEvQBElxtdw7KURSFEVKu4w8wAKLxdw9Z+bMnRmZGXfZ29//II8th4WwGVNyIoQLYB5vxA9Caq04iUd9A+7ZlsNC2I7TdSd2hZXMJKlnTqp9jtl/GBaqoyQ0noFKpUIzBicYYc+DEFpxkglc4oVJa5gvDn8v1xV2irG3FM4NSVwjUKlUaMcpJhCGmSEJQ6QGD8M5WnHCd8+f3QCXpPLx8WNwv0j6Bm9FMK7FJ3WBE+R/2t7c/GBmFvSBrzRTCsyTDjXrxUgEMtpxynJYmJoBJ4VAybwVARgvL7Oik0okCodnKpVKX7P0leiVMb0VvbJT+upznK4vh0GIeQwwQStJkHQD3MwsCALTJRG7Qrdrj5m/djgYaIa0hlkRdJk26XEgC9txurccBtVW3IudBImmZuACUP+ZlIDBt9FKcubYNTcAH/X0RYM1E7utJPlqe+uZzPxUcEkiSS4sTT95n15Mud0xWC0o2PAWOCdK3KYZlFxfM+tHOcnMzNr1es18ug+cgsVjP4yBU/Ppfrter1m/+l0+zYygML1xRVHU7TSb1cSzBzoBzszsH+AMdJJ49jrNZjWKou6wBnwOzcyndBpNbuueURR1Dw8Pq35p9cc5p/Dy9Dypt7jXrtdGwQECS9NPhr6Gq6txUzNigE6zydLK6lTw12/KT4FGFEUfJX2YJNONq5tVs4ODA7sD/DnwJ/BoADZuE3tHFs12dna6d4C/BI6AlbyzI8ii2TTw12/KK33gb2cdXsNZoAntbZC2SeO4c9592k/5eNQbiwvFd1kJuFGwLJr1wSPg/SwpvyFBHufOeXcFeAlE97U/uCxOY+P3b+Bn4B3Q+L8EdJfD4a+/AbC4UBzPxiPg3wlHZquB28Cn2IuR9x3gr3uV4DbwfvSDOvi4uFA8BDZmIRHkjHpS9Ht9iRqd8+5G3g05mAGcQbsdiX5QJ428G7Kygo8XYdb1/K4NWVmjzkNge2sz84bs+ELmpDDLtqWsNZBXgvmw8CTtpWVMT7x5YWBjLARnwZfKQNYN2U2LPvrh+5nBt7c2M2/It9bArCTKR8eZN+SJ13AScPnoODeRdqNenH+wul5w2gUr2WUjMFAt8bZ/0axX/wNnv4H8vTFb1QAAAABJRU5ErkJggg==\");\n}\n.bk-root .bk-tool-icon-poly-edit {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gELFi46qJmxxAAABV9JREFUWMOdl19vFFUYxn9n9u9sCyylUIzWUoMQBAWCMdEEIt6xIRQSLIEKtvHe6AcA4yeQb7CAUNJy0daLeomJN8SEULAC2kBBapBKoLvbmdl/c14vdmY7u91tF95kknPOnHmf95znPc97Ro2OTeBbdjFDT3c32ZxVHUOE9kSMB0/m6ExuoJn1H+ur6Y+OTfD50SMN5168OgrAlyf7CfuD+z7+iDs3p8hkLUQ0iFQ/yFl5Nm/qonfHVva+s32Zw9GxCYILsZ08tpNfBhbs+1YN4OH9+7huGdECSBVfqUosbsllfmauBqiR+cCNwOr7AEo8pPHJnymXykhg5fUWjoQpl0vVvhZhbSzGoUOHqgBlt6B6uruj2Zy1E9jo0fhfeyL2x4Mnc8VErK0KUEOB64JSyptfG4RSytsJjUJVxw2lsFy3urL9nx1Qd25ObctkrVMi+jQivd7U2ZyV/3Hzpq7h3h1b/7p9Y0o8v8rwAbTWrGpSocN/FGDlbAI0Rl23PCBan0Ok158H9Ipwzi25A/Mzc9Gl/BYx/E4kYqC1NKRARNAaDCNUM27Z+Zr+ouXs0q4+LSLBHPYCFkTkC6uU39kwCdsS7WRKmaYUiAhdnZ3MPX2K4+QjQI+C94A93rMzm8ltMwyDeDzWjMZeEb2pYQDdW3vITU2jtUZ5QThOPgm8C7wP7J15OPsBsB3oWpGnVWisCeDS1VHj4vBI92+/3tgB7Ab2AruAXiDBK5oIOkhtkEYRNRuJhObrd8Dl9ewf4D5wG7hVLpen29vb5wzD+BrkbBMaL3d1dk5nsrnlFDTTFWAWmAZueWD3gCemGde2k2fw1Al1YXhEvjozoO49eczdqekrWmsc2zlrmvEKOGoW1GUjFLqSk2KpJrCLwyMCPAP+BO54QL8DM6YZX/ClsP9YnwKkXnIBP4jdIpJRpdJTCYdMwwi98KU0Hjc/dDILNyUcwTCWdOSMJ0TRmBktGRhLugu0xyLk7CIqVNm+0bGJptl1YXikD0grpY4Rjc4a8Fbgdab/6OGbAJeCUuyJnnHmZH9pbSyGuBXV8NUwlUpR1EWyixmSyTWEwqGlJ2Swbo2JXbAAfgDGgGQA9I1A9t1tlq0AxrXxn0ilUpw4fhQqYkH/sT41OTnJJwf2s6FjI5mshdYa7bqVR2uezr9MJmJt14FvGrh/O9D+e6UkM/xyCuCqEKCYnJyUTKFQrZDHjxzGshwWLQcRsOz8Hi85P23id0ug/XilAMLBmm4tPGdoaKjSH5+oAGrhwvBI9SjZTn4QSK9yenoD7dlrExPoJlXW8G8ytpNHxRKk02lGxsdRKFwXLNvx5yY94HQLGhGk4LFCYQSqaE0AwWM1eOoEbR0dKBSW7bC4mKuffxs4D/wCLKwQQPAUzIkslfp6cVomROWSolh0GjldAM4nzDi2k9/i5UAzC9aKfwNJ3zgJg9YEvN6+C7SHgKm69+sD7RfNnKTTaZRPQfAut4oFV//IS7gkcB34VlVo8kGzphlfB+DU+TfNGBpZtRastvrvARJmfMF28ge9sc2B9/PNnCilMIDwK6y8/ow/Ai4kvILTljAXvDvEvrqKSUs60KolzPjBxspavQD2tKqCAGF/Ba+xE/Wbilu54wZV8NEKF5fXzQHl/bh4hUsE0WAXSlDMYcQSrQXgCmsTseXHsJkNnjqBFGwKJaHsKlxtUHYVhbLCzr1kaOA4bcn1y1Swmb+iLpJKpVrfgdpfsiVVCYcgluwgnU7jEgJ4s5UkLFtWYyHyEg0/N1q1tmQH+YXnAMFr97Nmv3p+0QsHQRsF8qpBOE5+rb9Nkaj50tVQKjqh4OU3GNL/1/So3vuUgbAAAAAASUVORK5CYII=\");\n}\n");
    exports.bk_tool_icon_box_select = "bk-tool-icon-box-select";
    exports.bk_tool_icon_box_zoom = "bk-tool-icon-box-zoom";
    exports.bk_tool_icon_zoom_in = "bk-tool-icon-zoom-in";
    exports.bk_tool_icon_zoom_out = "bk-tool-icon-zoom-out";
    exports.bk_tool_icon_help = "bk-tool-icon-help";
    exports.bk_tool_icon_hover = "bk-tool-icon-hover";
    exports.bk_tool_icon_crosshair = "bk-tool-icon-crosshair";
    exports.bk_tool_icon_lasso_select = "bk-tool-icon-lasso-select";
    exports.bk_tool_icon_pan = "bk-tool-icon-pan";
    exports.bk_tool_icon_xpan = "bk-tool-icon-xpan";
    exports.bk_tool_icon_ypan = "bk-tool-icon-ypan";
    exports.bk_tool_icon_range = "bk-tool-icon-range";
    exports.bk_tool_icon_polygon_select = "bk-tool-icon-polygon-select";
    exports.bk_tool_icon_redo = "bk-tool-icon-redo";
    exports.bk_tool_icon_reset = "bk-tool-icon-reset";
    exports.bk_tool_icon_save = "bk-tool-icon-save";
    exports.bk_tool_icon_tap_select = "bk-tool-icon-tap-select";
    exports.bk_tool_icon_undo = "bk-tool-icon-undo";
    exports.bk_tool_icon_wheel_pan = "bk-tool-icon-wheel-pan";
    exports.bk_tool_icon_wheel_zoom = "bk-tool-icon-wheel-zoom";
    exports.bk_tool_icon_box_edit = "bk-tool-icon-box-edit";
    exports.bk_tool_icon_freehand_draw = "bk-tool-icon-freehand-draw";
    exports.bk_tool_icon_poly_draw = "bk-tool-icon-poly-draw";
    exports.bk_tool_icon_point_draw = "bk-tool-icon-point-draw";
    exports.bk_tool_icon_poly_edit = "bk-tool-icon-poly-edit";
},
/* styles/logo.js */ function _(require, module, exports) {
    require(62) /* ./root */;
    const _a = require(61) /* ../core/dom */;
    _a.styles.append(".bk-root .bk-logo {\n  margin: 5px;\n  position: relative;\n  display: block;\n  background-repeat: no-repeat;\n}\n.bk-root .bk-logo.bk-grey {\n  filter: url(\"data:image/svg+xml;utf8,<svg xmlns=\\'http://www.w3.org/2000/svg\\'><filter id=\\'grayscale\\'><feColorMatrix type=\\'matrix\\' values=\\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\\'/></filter></svg>#grayscale\");\n  /* Firefox 10+, Firefox on Android */\n  filter: gray;\n  /* IE6-9 */\n  -webkit-filter: grayscale(100%);\n  /* Chrome 19+, Safari 6+, Safari 6+ iOS */\n}\n.bk-root .bk-logo-small {\n  width: 20px;\n  height: 20px;\n  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAAOkSURBVDiNjZRtaJVlGMd/1/08zzln5zjP1LWcU9N0NkN8m2CYjpgQYQXqSs0I84OLIC0hkEKoPtiH3gmKoiJDU7QpLgoLjLIQCpEsNJ1vqUOdO7ppbuec5+V+rj4ctwzd8IIbbi6u+8f1539dt3A78eXC7QizUF7gyV1fD1Yqg4JWz84yffhm0qkFqBogB9rM8tZdtwVsPUhWhGcFJngGeWrPzHm5oaMmkfEg1usvLFyc8jLRqDOMru7AyC8saQr7GG7f5fvDeH7Ej8CM66nIF+8yngt6HWaKh7k49Soy9nXurCi1o3qUbS3zWfrYeQDTB/Qj6kX6Ybhw4B+bOYoLKCC9H3Nu/leUTZ1JdRWkkn2ldcCamzrcf47KKXdAJllSlxAOkRgyHsGC/zRday5Qld9DyoM4/q/rUoy/CXh3jzOu3bHUVZeU+DEn8FInkPBFlu3+nW3Nw0mk6vCDiWg8CeJaxEwuHS3+z5RgY+YBR6V1Z1nxSOfoaPa4LASWxxdNp+VWTk7+4vzaou8v8PN+xo+KY2xsw6une2frhw05CTYOmQvsEhjhWjn0bmXPjpE1+kplmmkP3suftwTubK9Vq22qKmrBhpY4jvd5afdRA3wGjFAgcnTK2s4hY0/GPNIb0nErGMCRxWOOX64Z8RAC4oCXdklmEvcL8o0BfkNK4lUg9HTl+oPlQxdNo3Mg4Nv175e/1LDGzZen30MEjRUtmXSfiTVu1kK8W4txyV6BMKlbgk3lMwYCiusNy9fVfvvwMxv8Ynl6vxoByANLTWplvuj/nF9m2+PDtt1eiHPBr1oIfhCChQMBw6Aw0UulqTKZdfVvfG7VcfIqLG9bcldL/+pdWTLxLUy8Qq38heUIjh4XlzZxzQm19lLFlr8vdQ97rjZVOLf8nclzckbcD4wxXMidpX30sFd37Fv/GtwwhzhxGVAprjbg0gCAEeIgwCZyTV2Z1REEW8O4py0wsjeloKoMr6iCY6dP92H6Vw/oTyICIthibxjm/DfN9lVz8IqtqKYLUXfoKVMVQVVJOElGjrnnUt9T9wbgp8AyYKaGlqingHZU/uG2NTZSVqwHQTWkx9hxjkpWDaCg6Ckj5qebgBVbT3V3NNXMSiWSDdGV3hrtzla7J+duwPOToIg42ChPQOQjspnSlp1V+Gjdged7+8UN5CRAV7a5EdFNwCjEaBR27b3W890TE7g24NAP/mMDXRWrGoFPQI9ls/MWO2dWFAar/xcOIImbbpA3zgAAAABJRU5ErkJggg==);\n}\n.bk-root .bk-logo-notebook {\n  display: inline-block;\n  vertical-align: middle;\n  margin-right: 5px;\n}\n");
    exports.bk_logo = "bk-logo";
    exports.bk_logo_notebook = "bk-logo-notebook";
    exports.bk_logo_small = "bk-logo-small";
    exports.bk_grey = "bk-grey";
},
/* models/plots/plot_canvas.js */ function _(require, module, exports) {
    var __rest = (this && this.__rest) || function (s, e) {
        var t = {};
        for (var p in s)
            if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
                t[p] = s[p];
        if (s != null && typeof Object.getOwnPropertySymbols === "function")
            for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
                if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                    t[p[i]] = s[p[i]];
            }
        return t;
    };
    const cartesian_frame_1 = require(176) /* ../canvas/cartesian_frame */;
    const canvas_1 = require(172) /* ../canvas/canvas */;
    const data_range1d_1 = require(178) /* ../ranges/data_range1d */;
    const glyph_renderer_1 = require(73) /* ../renderers/glyph_renderer */;
    const layout_dom_1 = require(237) /* ../layouts/layout_dom */;
    const title_1 = require(134) /* ../annotations/title */;
    const axis_1 = require(141) /* ../axes/axis */;
    const toolbar_panel_1 = require(135) /* ../annotations/toolbar_panel */;
    const bokeh_events_1 = require(274) /* ../../core/bokeh_events */;
    const signaling_1 = require(13) /* ../../core/signaling */;
    const build_views_1 = require(92) /* ../../core/build_views */;
    const visuals_1 = require(63) /* ../../core/visuals */;
    const logging_1 = require(65) /* ../../core/logging */;
    const throttle_1 = require(275) /* ../../core/util/throttle */;
    const types_1 = require(7) /* ../../core/util/types */;
    const array_1 = require(8) /* ../../core/util/array */;
    const object_1 = require(22) /* ../../core/util/object */;
    const layout_1 = require(180) /* ../../core/layout */;
    const alignments_1 = require(183) /* ../../core/layout/alignments */;
    const side_panel_1 = require(276) /* ../../core/layout/side_panel */;
    const grid_1 = require(184) /* ../../core/layout/grid */;
    const bbox_1 = require(79) /* ../../core/util/bbox */;
    let global_gl = null;
    class PlotLayout extends layout_1.Layoutable {
        constructor() {
            super(...arguments);
            this.min_border = { left: 0, top: 0, right: 0, bottom: 0 };
        }
        _measure(viewport) {
            viewport = new layout_1.Sizeable(viewport).bounded_to(this.sizing.size);
            const left_hint = this.left_panel.measure({ width: 0, height: viewport.height });
            const left = Math.max(left_hint.width, this.min_border.left);
            const right_hint = this.right_panel.measure({ width: 0, height: viewport.height });
            const right = Math.max(right_hint.width, this.min_border.right);
            const top_hint = this.top_panel.measure({ width: viewport.width, height: 0 });
            const top = Math.max(top_hint.height, this.min_border.top);
            const bottom_hint = this.bottom_panel.measure({ width: viewport.width, height: 0 });
            const bottom = Math.max(bottom_hint.height, this.min_border.bottom);
            const center_viewport = new layout_1.Sizeable(viewport).shrink_by({ left, right, top, bottom });
            const center = this.center_panel.measure(center_viewport);
            const width = left + center.width + right;
            const height = top + center.height + bottom;
            const align = (() => {
                const { width_policy, height_policy } = this.center_panel.sizing;
                return width_policy != "fixed" && height_policy != "fixed";
            })();
            return { width, height, inner: { left, right, top, bottom }, align };
        }
        _set_geometry(outer, inner) {
            super._set_geometry(outer, inner);
            this.center_panel.set_geometry(inner);
            const left_hint = this.left_panel.measure({ width: 0, height: outer.height });
            const right_hint = this.right_panel.measure({ width: 0, height: outer.height });
            const top_hint = this.top_panel.measure({ width: outer.width, height: 0 });
            const bottom_hint = this.bottom_panel.measure({ width: outer.width, height: 0 });
            const { left, top, right, bottom } = inner;
            this.top_panel.set_geometry(new bbox_1.BBox({ left, right, bottom: top, height: top_hint.height }));
            this.bottom_panel.set_geometry(new bbox_1.BBox({ left, right, top: bottom, height: bottom_hint.height }));
            this.left_panel.set_geometry(new bbox_1.BBox({ top, bottom, right: left, width: left_hint.width }));
            this.right_panel.set_geometry(new bbox_1.BBox({ top, bottom, left: right, width: right_hint.width }));
        }
    }
    exports.PlotLayout = PlotLayout;
    PlotLayout.__name__ = "PlotLayout";
    class PlotView extends layout_dom_1.LayoutDOMView {
        constructor() {
            super(...arguments);
            this._outer_bbox = new bbox_1.BBox();
            this._inner_bbox = new bbox_1.BBox();
            this._needs_paint = true;
            this._needs_layout = false;
        }
        get canvas_overlays() {
            return this.canvas_view.overlays_el;
        }
        get canvas_events() {
            return this.canvas_view.events_el;
        }
        get is_paused() {
            return this._is_paused != null && this._is_paused !== 0;
        }
        get child_models() {
            return [];
        }
        pause() {
            if (this._is_paused == null)
                this._is_paused = 1;
            else
                this._is_paused += 1;
        }
        unpause(no_render = false) {
            if (this._is_paused == null)
                throw new Error("wasn't paused");
            this._is_paused -= 1;
            if (this._is_paused == 0 && !no_render)
                this.request_paint();
        }
        // TODO: this needs to be removed
        request_render() {
            this.request_paint();
        }
        request_paint() {
            if (!this.is_paused)
                this.throttled_paint();
        }
        request_layout() {
            this._needs_layout = true;
            this.request_paint();
        }
        reset() {
            if (this.model.reset_policy == "standard") {
                this.clear_state();
                this.reset_range();
                this.reset_selection();
            }
            this.model.trigger_event(new bokeh_events_1.Reset());
        }
        remove() {
            this.ui_event_bus.destroy();
            build_views_1.remove_views(this.renderer_views);
            build_views_1.remove_views(this.tool_views);
            this.canvas_view.remove();
            super.remove();
        }
        render() {
            super.render();
            this.el.appendChild(this.canvas_view.el);
            this.canvas_view.render();
        }
        initialize() {
            this.pause();
            super.initialize();
            this.force_paint = new signaling_1.Signal0(this, "force_paint");
            this.state_changed = new signaling_1.Signal0(this, "state_changed");
            this.lod_started = false;
            this.visuals = new visuals_1.Visuals(this.model); // XXX
            this._initial_state_info = {
                selection: {},
                dimensions: { width: 0, height: 0 },
            };
            this.visibility_callbacks = [];
            this.state = { history: [], index: -1 };
            this.canvas = new canvas_1.Canvas({
                map: this.model.use_map || false,
                use_hidpi: this.model.hidpi,
                output_backend: this.model.output_backend,
            });
            this.frame = new cartesian_frame_1.CartesianFrame(this.model.x_scale, this.model.y_scale, this.model.x_range, this.model.y_range, this.model.extra_x_ranges, this.model.extra_y_ranges);
            this.canvas_view = new this.canvas.default_view({ model: this.canvas, parent: this });
            // If requested, try enabling webgl
            if (this.model.output_backend == "webgl")
                this.init_webgl();
            this.throttled_paint = throttle_1.throttle((() => this.force_paint.emit()), 15); // TODO (bev) configurable
            // XXX: lazy value import to avoid touching window
            const { UIEvents } = require(277) /* ../../core/ui_events */;
            this.ui_event_bus = new UIEvents(this, this.model.toolbar, this.canvas_view.events_el);
            const { title_location, title } = this.model;
            if (title_location != null && title != null) {
                this._title = title instanceof title_1.Title ? title : new title_1.Title({ text: title });
            }
            const { toolbar_location, toolbar } = this.model;
            if (toolbar_location != null && toolbar != null) {
                this._toolbar = new toolbar_panel_1.ToolbarPanel({ toolbar });
                toolbar.toolbar_location = toolbar_location;
            }
            this.renderer_views = {};
            this.tool_views = {};
            this.build_renderer_views();
            this.build_tool_views();
            this.update_dataranges();
            this.unpause(true);
            logging_1.logger.debug("PlotView initialized");
        }
        _width_policy() {
            return this.model.frame_width == null ? super._width_policy() : "min";
        }
        _height_policy() {
            return this.model.frame_height == null ? super._height_policy() : "min";
        }
        _update_layout() {
            this.layout = new PlotLayout();
            this.layout.set_sizing(this.box_sizing());
            const { frame_width, frame_height } = this.model;
            this.layout.center_panel = this.frame;
            this.layout.center_panel.set_sizing(Object.assign(Object.assign({}, (frame_width != null ? { width_policy: "fixed", width: frame_width } : { width_policy: "fit" })), (frame_height != null ? { height_policy: "fixed", height: frame_height } : { height_policy: "fit" })));
            const above = array_1.copy(this.model.above);
            const below = array_1.copy(this.model.below);
            const left = array_1.copy(this.model.left);
            const right = array_1.copy(this.model.right);
            const get_side = (side) => {
                switch (side) {
                    case "above": return above;
                    case "below": return below;
                    case "left": return left;
                    case "right": return right;
                }
            };
            const { title_location, title } = this.model;
            if (title_location != null && title != null) {
                get_side(title_location).push(this._title);
            }
            const { toolbar_location, toolbar } = this.model;
            if (toolbar_location != null && toolbar != null) {
                const panels = get_side(toolbar_location);
                let push_toolbar = true;
                if (this.model.toolbar_sticky) {
                    for (let i = 0; i < panels.length; i++) {
                        const panel = panels[i];
                        if (panel instanceof title_1.Title) {
                            if (toolbar_location == "above" || toolbar_location == "below")
                                panels[i] = [panel, this._toolbar];
                            else
                                panels[i] = [this._toolbar, panel];
                            push_toolbar = false;
                            break;
                        }
                    }
                }
                if (push_toolbar)
                    panels.push(this._toolbar);
            }
            const set_layout = (side, model) => {
                const view = this.renderer_views[model.id];
                return view.layout = new side_panel_1.SidePanel(side, view);
            };
            const set_layouts = (side, panels) => {
                const horizontal = side == "above" || side == "below";
                const layouts = [];
                for (const panel of panels) {
                    if (types_1.isArray(panel)) {
                        const items = panel.map((subpanel) => {
                            const item = set_layout(side, subpanel);
                            if (subpanel instanceof toolbar_panel_1.ToolbarPanel) {
                                const dim = horizontal ? "width_policy" : "height_policy";
                                item.set_sizing(Object.assign(Object.assign({}, item.sizing), { [dim]: "min" }));
                            }
                            return item;
                        });
                        let layout;
                        if (horizontal) {
                            layout = new grid_1.Row(items);
                            layout.set_sizing({ width_policy: "max", height_policy: "min" });
                        }
                        else {
                            layout = new grid_1.Column(items);
                            layout.set_sizing({ width_policy: "min", height_policy: "max" });
                        }
                        layout.absolute = true;
                        layouts.push(layout);
                    }
                    else
                        layouts.push(set_layout(side, panel));
                }
                return layouts;
            };
            const min_border = this.model.min_border != null ? this.model.min_border : 0;
            this.layout.min_border = {
                left: this.model.min_border_left != null ? this.model.min_border_left : min_border,
                top: this.model.min_border_top != null ? this.model.min_border_top : min_border,
                right: this.model.min_border_right != null ? this.model.min_border_right : min_border,
                bottom: this.model.min_border_bottom != null ? this.model.min_border_bottom : min_border,
            };
            const top_panel = new alignments_1.VStack();
            const bottom_panel = new alignments_1.VStack();
            const left_panel = new alignments_1.HStack();
            const right_panel = new alignments_1.HStack();
            top_panel.children = array_1.reversed(set_layouts("above", above));
            bottom_panel.children = set_layouts("below", below);
            left_panel.children = array_1.reversed(set_layouts("left", left));
            right_panel.children = set_layouts("right", right);
            top_panel.set_sizing({ width_policy: "fit", height_policy: "min" /*, min_height: this.layout.min_border.top*/ });
            bottom_panel.set_sizing({ width_policy: "fit", height_policy: "min" /*, min_height: this.layout.min_width.bottom*/ });
            left_panel.set_sizing({ width_policy: "min", height_policy: "fit" /*, min_width: this.layout.min_width.left*/ });
            right_panel.set_sizing({ width_policy: "min", height_policy: "fit" /*, min_width: this.layout.min_width.right*/ });
            this.layout.top_panel = top_panel;
            this.layout.bottom_panel = bottom_panel;
            this.layout.left_panel = left_panel;
            this.layout.right_panel = right_panel;
        }
        get axis_views() {
            const views = [];
            for (const id in this.renderer_views) {
                const child_view = this.renderer_views[id];
                if (child_view instanceof axis_1.AxisView)
                    views.push(child_view);
            }
            return views;
        }
        set_cursor(cursor = "default") {
            this.canvas_view.el.style.cursor = cursor;
        }
        set_toolbar_visibility(visible) {
            for (const callback of this.visibility_callbacks)
                callback(visible);
        }
        init_webgl() {
            // We use a global invisible canvas and gl context. By having a global context,
            // we avoid the limitation of max 16 contexts that most browsers have.
            if (global_gl == null) {
                const canvas = document.createElement('canvas');
                const ctx = canvas.getContext("webgl", { premultipliedAlpha: true });
                // If WebGL is available, we store a reference to the gl canvas on
                // the ctx object, because that's what gets passed everywhere.
                if (ctx != null)
                    global_gl = { canvas, ctx };
            }
            if (global_gl != null)
                this.gl = global_gl;
            else
                logging_1.logger.warn('WebGL is not supported, falling back to 2D canvas.');
        }
        prepare_webgl(ratio, frame_box) {
            // Prepare WebGL for a drawing pass
            if (this.gl != null) {
                const canvas = this.canvas_view.get_canvas_element();
                // Sync canvas size
                this.gl.canvas.width = canvas.width;
                this.gl.canvas.height = canvas.height;
                const { ctx: gl } = this.gl;
                // Clipping
                gl.enable(gl.SCISSOR_TEST);
                const [sx, sy, w, h] = frame_box;
                const { xview, yview } = this.canvas_view.bbox;
                const vx = xview.compute(sx);
                const vy = yview.compute(sy + h);
                gl.scissor(ratio * vx, ratio * vy, ratio * w, ratio * h); // lower left corner, width, height
                // Setup blending
                gl.enable(gl.BLEND);
                gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE_MINUS_DST_ALPHA, gl.ONE); // premultipliedAlpha == true
            }
        }
        clear_webgl() {
            if (this.gl != null) {
                // Prepare GL for drawing
                const { ctx: gl } = this.gl;
                gl.viewport(0, 0, this.gl.canvas.width, this.gl.canvas.height);
                gl.clearColor(0, 0, 0, 0);
                gl.clear(gl.COLOR_BUFFER_BIT || gl.DEPTH_BUFFER_BIT);
            }
        }
        blit_webgl() {
            // This should be called when the ctx has no state except the HIDPI transform
            const { ctx } = this.canvas_view;
            if (this.gl != null) {
                // Blit gl canvas into the 2D canvas. To do 1-on-1 blitting, we need
                // to remove the hidpi transform, then blit, then restore.
                // ctx.globalCompositeOperation = "source-over"  -> OK; is the default
                logging_1.logger.debug('drawing with WebGL');
                ctx.restore();
                ctx.drawImage(this.gl.canvas, 0, 0);
                // Set back hidpi transform
                ctx.save();
                const ratio = this.canvas.pixel_ratio;
                ctx.scale(ratio, ratio);
                ctx.translate(0.5, 0.5);
            }
        }
        update_dataranges() {
            // Update any DataRange1ds here
            const bounds = {};
            const log_bounds = {};
            let calculate_log_bounds = false;
            for (const r of object_1.values(this.frame.x_ranges).concat(object_1.values(this.frame.y_ranges))) {
                if (r instanceof data_range1d_1.DataRange1d) {
                    if (r.scale_hint == "log")
                        calculate_log_bounds = true;
                }
            }
            for (const id in this.renderer_views) {
                const view = this.renderer_views[id];
                if (view instanceof glyph_renderer_1.GlyphRendererView) {
                    const bds = view.glyph.bounds();
                    if (bds != null)
                        bounds[id] = bds;
                    if (calculate_log_bounds) {
                        const log_bds = view.glyph.log_bounds();
                        if (log_bds != null)
                            log_bounds[id] = log_bds;
                    }
                }
            }
            let follow_enabled = false;
            let has_bounds = false;
            const { width, height } = this.frame.bbox;
            let r;
            if (this.model.match_aspect !== false && width != 0 && height != 0)
                r = (1 / this.model.aspect_scale) * (width / height);
            for (const xr of object_1.values(this.frame.x_ranges)) {
                if (xr instanceof data_range1d_1.DataRange1d) {
                    const bounds_to_use = xr.scale_hint == "log" ? log_bounds : bounds;
                    xr.update(bounds_to_use, 0, this.model.id, r);
                    if (xr.follow) {
                        follow_enabled = true;
                    }
                }
                if (xr.bounds != null)
                    has_bounds = true;
            }
            for (const yr of object_1.values(this.frame.y_ranges)) {
                if (yr instanceof data_range1d_1.DataRange1d) {
                    const bounds_to_use = yr.scale_hint == "log" ? log_bounds : bounds;
                    yr.update(bounds_to_use, 1, this.model.id, r);
                    if (yr.follow) {
                        follow_enabled = true;
                    }
                }
                if (yr.bounds != null)
                    has_bounds = true;
            }
            if (follow_enabled && has_bounds) {
                logging_1.logger.warn('Follow enabled so bounds are unset.');
                for (const xr of object_1.values(this.frame.x_ranges)) {
                    xr.bounds = null;
                }
                for (const yr of object_1.values(this.frame.y_ranges)) {
                    yr.bounds = null;
                }
            }
            this.range_update_timestamp = Date.now();
        }
        map_to_screen(x, y, x_name = "default", y_name = "default") {
            return this.frame.map_to_screen(x, y, x_name, y_name);
        }
        push_state(type, new_info) {
            const { history, index } = this.state;
            const prev_info = history[index] != null ? history[index].info : {};
            const info = Object.assign(Object.assign(Object.assign({}, this._initial_state_info), prev_info), new_info);
            this.state.history = this.state.history.slice(0, this.state.index + 1);
            this.state.history.push({ type, info });
            this.state.index = this.state.history.length - 1;
            this.state_changed.emit();
        }
        clear_state() {
            this.state = { history: [], index: -1 };
            this.state_changed.emit();
        }
        can_undo() {
            return this.state.index >= 0;
        }
        can_redo() {
            return this.state.index < this.state.history.length - 1;
        }
        undo() {
            if (this.can_undo()) {
                this.state.index -= 1;
                this._do_state_change(this.state.index);
                this.state_changed.emit();
            }
        }
        redo() {
            if (this.can_redo()) {
                this.state.index += 1;
                this._do_state_change(this.state.index);
                this.state_changed.emit();
            }
        }
        _do_state_change(index) {
            const info = this.state.history[index] != null ? this.state.history[index].info : this._initial_state_info;
            if (info.range != null)
                this.update_range(info.range);
            if (info.selection != null)
                this.update_selection(info.selection);
        }
        get_selection() {
            const selection = {};
            for (const renderer of this.model.renderers) {
                if (renderer instanceof glyph_renderer_1.GlyphRenderer) {
                    const { selected } = renderer.data_source;
                    selection[renderer.id] = selected;
                }
            }
            return selection;
        }
        update_selection(selection) {
            for (const renderer of this.model.renderers) {
                if (!(renderer instanceof glyph_renderer_1.GlyphRenderer))
                    continue;
                const ds = renderer.data_source;
                if (selection != null) {
                    if (selection[renderer.id] != null)
                        ds.selected.update(selection[renderer.id], true, false);
                }
                else
                    ds.selection_manager.clear();
            }
        }
        reset_selection() {
            this.update_selection(null);
        }
        _update_ranges_together(range_info_iter) {
            // Get weight needed to scale the diff of the range to honor interval limits
            let weight = 1.0;
            for (const [rng, range_info] of range_info_iter) {
                weight = Math.min(weight, this._get_weight_to_constrain_interval(rng, range_info));
            }
            // Apply shared weight to all ranges
            if (weight < 1) {
                for (const [rng, range_info] of range_info_iter) {
                    range_info.start = weight * range_info.start + (1 - weight) * rng.start;
                    range_info.end = weight * range_info.end + (1 - weight) * rng.end;
                }
            }
        }
        _update_ranges_individually(range_info_iter, is_panning, is_scrolling, maintain_focus) {
            let hit_bound = false;
            for (const [rng, range_info] of range_info_iter) {
                // Limit range interval first. Note that for scroll events,
                // the interval has already been limited for all ranges simultaneously
                if (!is_scrolling) {
                    const weight = this._get_weight_to_constrain_interval(rng, range_info);
                    if (weight < 1) {
                        range_info.start = weight * range_info.start + (1 - weight) * rng.start;
                        range_info.end = weight * range_info.end + (1 - weight) * rng.end;
                    }
                }
                // Prevent range from going outside limits
                // Also ensure that range keeps the same delta when panning/scrolling
                if (rng.bounds != null && rng.bounds != "auto") { // check `auto` for type-checking purpose
                    const [min, max] = rng.bounds;
                    const new_interval = Math.abs(range_info.end - range_info.start);
                    if (rng.is_reversed) {
                        if (min != null) {
                            if (min >= range_info.end) {
                                hit_bound = true;
                                range_info.end = min;
                                if (is_panning || is_scrolling) {
                                    range_info.start = min + new_interval;
                                }
                            }
                        }
                        if (max != null) {
                            if (max <= range_info.start) {
                                hit_bound = true;
                                range_info.start = max;
                                if (is_panning || is_scrolling) {
                                    range_info.end = max - new_interval;
                                }
                            }
                        }
                    }
                    else {
                        if (min != null) {
                            if (min >= range_info.start) {
                                hit_bound = true;
                                range_info.start = min;
                                if (is_panning || is_scrolling) {
                                    range_info.end = min + new_interval;
                                }
                            }
                        }
                        if (max != null) {
                            if (max <= range_info.end) {
                                hit_bound = true;
                                range_info.end = max;
                                if (is_panning || is_scrolling) {
                                    range_info.start = max - new_interval;
                                }
                            }
                        }
                    }
                }
            }
            // Cancel the event when hitting a bound while scrolling. This ensures that
            // the scroll-zoom tool maintains its focus position. Setting `maintain_focus`
            // to false results in a more "gliding" behavior, allowing one to
            // zoom out more smoothly, at the cost of losing the focus position.
            if (is_scrolling && hit_bound && maintain_focus)
                return;
            for (const [rng, range_info] of range_info_iter) {
                rng.have_updated_interactively = true;
                if (rng.start != range_info.start || rng.end != range_info.end)
                    rng.setv(range_info);
            }
        }
        _get_weight_to_constrain_interval(rng, range_info) {
            // Get the weight by which a range-update can be applied
            // to still honor the interval limits (including the implicit
            // max interval imposed by the bounds)
            const { min_interval } = rng;
            let { max_interval } = rng;
            // Express bounds as a max_interval. By doing this, the application of
            // bounds and interval limits can be applied independent from each-other.
            if (rng.bounds != null && rng.bounds != "auto") { // check `auto` for type-checking purpose
                const [min, max] = rng.bounds;
                if (min != null && max != null) {
                    const max_interval2 = Math.abs(max - min);
                    max_interval = max_interval != null ? Math.min(max_interval, max_interval2) : max_interval2;
                }
            }
            let weight = 1.0;
            if (min_interval != null || max_interval != null) {
                const old_interval = Math.abs(rng.end - rng.start);
                const new_interval = Math.abs(range_info.end - range_info.start);
                if (min_interval > 0 && new_interval < min_interval) {
                    weight = (old_interval - min_interval) / (old_interval - new_interval);
                }
                if (max_interval > 0 && new_interval > max_interval) {
                    weight = (max_interval - old_interval) / (new_interval - old_interval);
                }
                weight = Math.max(0.0, Math.min(1.0, weight));
            }
            return weight;
        }
        update_range(range_info, is_panning = false, is_scrolling = false, maintain_focus = true) {
            this.pause();
            const { x_ranges, y_ranges } = this.frame;
            if (range_info == null) {
                for (const name in x_ranges) {
                    const rng = x_ranges[name];
                    rng.reset();
                }
                for (const name in y_ranges) {
                    const rng = y_ranges[name];
                    rng.reset();
                }
                this.update_dataranges();
            }
            else {
                const range_info_iter = [];
                for (const name in x_ranges) {
                    const rng = x_ranges[name];
                    range_info_iter.push([rng, range_info.xrs[name]]);
                }
                for (const name in y_ranges) {
                    const rng = y_ranges[name];
                    range_info_iter.push([rng, range_info.yrs[name]]);
                }
                if (is_scrolling) {
                    this._update_ranges_together(range_info_iter); // apply interval bounds while keeping aspect
                }
                this._update_ranges_individually(range_info_iter, is_panning, is_scrolling, maintain_focus);
            }
            this.unpause();
        }
        reset_range() {
            this.update_range(null);
        }
        _invalidate_layout() {
            const needs_layout = () => {
                for (const panel of this.model.side_panels) {
                    const view = this.renderer_views[panel.id];
                    if (view.layout.has_size_changed())
                        return true;
                }
                return false;
            };
            if (needs_layout())
                this.root.compute_layout();
        }
        build_renderer_views() {
            this.computed_renderers = [];
            this.computed_renderers.push(...this.model.above);
            this.computed_renderers.push(...this.model.below);
            this.computed_renderers.push(...this.model.left);
            this.computed_renderers.push(...this.model.right);
            this.computed_renderers.push(...this.model.center);
            this.computed_renderers.push(...this.model.renderers);
            if (this._title != null)
                this.computed_renderers.push(this._title);
            if (this._toolbar != null)
                this.computed_renderers.push(this._toolbar);
            for (const tool of this.model.toolbar.tools) {
                if (tool.overlay != null)
                    this.computed_renderers.push(tool.overlay);
                this.computed_renderers.push(...tool.synthetic_renderers);
            }
            build_views_1.build_views(this.renderer_views, this.computed_renderers, { parent: this });
        }
        get_renderer_views() {
            return this.computed_renderers.map((r) => this.renderer_views[r.id]);
        }
        build_tool_views() {
            const tool_models = this.model.toolbar.tools;
            const new_tool_views = build_views_1.build_views(this.tool_views, tool_models, { parent: this });
            new_tool_views.map((tool_view) => this.ui_event_bus.register_tool(tool_view));
        }
        connect_signals() {
            super.connect_signals();
            this.connect(this.force_paint, () => this.repaint());
            const { x_ranges, y_ranges } = this.frame;
            for (const name in x_ranges) {
                const rng = x_ranges[name];
                this.connect(rng.change, () => { this._needs_layout = true; this.request_paint(); });
            }
            for (const name in y_ranges) {
                const rng = y_ranges[name];
                this.connect(rng.change, () => { this._needs_layout = true; this.request_paint(); });
            }
            this.connect(this.model.properties.renderers.change, () => this.build_renderer_views());
            this.connect(this.model.toolbar.properties.tools.change, () => { this.build_renderer_views(); this.build_tool_views(); });
            this.connect(this.model.change, () => this.request_paint());
            this.connect(this.model.reset, () => this.reset());
        }
        set_initial_range() {
            // check for good values for ranges before setting initial range
            let good_vals = true;
            const { x_ranges, y_ranges } = this.frame;
            const xrs = {};
            const yrs = {};
            for (const name in x_ranges) {
                const { start, end } = x_ranges[name];
                if (start == null || end == null || types_1.isStrictNaN(start + end)) {
                    good_vals = false;
                    break;
                }
                xrs[name] = { start, end };
            }
            if (good_vals) {
                for (const name in y_ranges) {
                    const { start, end } = y_ranges[name];
                    if (start == null || end == null || types_1.isStrictNaN(start + end)) {
                        good_vals = false;
                        break;
                    }
                    yrs[name] = { start, end };
                }
            }
            if (good_vals) {
                this._initial_state_info.range = { xrs, yrs };
                logging_1.logger.debug("initial ranges set");
            }
            else
                logging_1.logger.warn('could not set initial ranges');
        }
        has_finished() {
            if (!super.has_finished())
                return false;
            for (const id in this.renderer_views) {
                const view = this.renderer_views[id];
                if (!view.has_finished())
                    return false;
            }
            return true;
        }
        after_layout() {
            super.after_layout();
            this._needs_layout = false;
            this.model.setv({
                inner_width: Math.round(this.frame._width.value),
                inner_height: Math.round(this.frame._height.value),
                outer_width: Math.round(this.layout._width.value),
                outer_height: Math.round(this.layout._height.value),
            }, { no_change: true });
            if (this.model.match_aspect !== false) {
                this.pause();
                this.update_dataranges();
                this.unpause(true);
            }
            if (!this._outer_bbox.equals(this.layout.bbox)) {
                const { width, height } = this.layout.bbox;
                this.canvas_view.prepare_canvas(width, height);
                this._outer_bbox = this.layout.bbox;
                this._needs_paint = true;
            }
            if (!this._inner_bbox.equals(this.frame.inner_bbox)) {
                this._inner_bbox = this.layout.inner_bbox;
                this._needs_paint = true;
            }
            if (this._needs_paint) {
                // XXX: can't be this.request_paint(), because it would trigger back-and-forth
                // layout recomputing feedback loop between plots. Plots are also much more
                // responsive this way, especially in interactive mode.
                this._needs_paint = false;
                this.paint();
            }
        }
        repaint() {
            if (this._needs_layout)
                this._invalidate_layout();
            this.paint();
        }
        paint() {
            if (this.is_paused)
                return;
            logging_1.logger.trace(`PlotView.paint() for ${this.model.id}`);
            const { document } = this.model;
            if (document != null) {
                const interactive_duration = document.interactive_duration();
                if (interactive_duration >= 0 && interactive_duration < this.model.lod_interval) {
                    setTimeout(() => {
                        if (document.interactive_duration() > this.model.lod_timeout) {
                            document.interactive_stop(this.model);
                        }
                        this.request_paint();
                    }, this.model.lod_timeout);
                }
                else
                    document.interactive_stop(this.model);
            }
            for (const id in this.renderer_views) {
                const v = this.renderer_views[id];
                if (this.range_update_timestamp == null ||
                    (v instanceof glyph_renderer_1.GlyphRendererView && v.set_data_timestamp > this.range_update_timestamp)) {
                    this.update_dataranges();
                    break;
                }
            }
            const { ctx } = this.canvas_view;
            const ratio = this.canvas.pixel_ratio;
            // Set hidpi-transform
            ctx.save(); // Save default state, do *after* getting ratio, cause setting canvas.width resets transforms
            ctx.scale(ratio, ratio);
            ctx.translate(0.5, 0.5);
            const frame_box = [
                this.frame._left.value,
                this.frame._top.value,
                this.frame._width.value,
                this.frame._height.value,
            ];
            this._map_hook(ctx, frame_box);
            this._paint_empty(ctx, frame_box);
            this.prepare_webgl(ratio, frame_box);
            this.clear_webgl();
            if (this.visuals.outline_line.doit) {
                ctx.save();
                this.visuals.outline_line.set_value(ctx);
                let [x0, y0, w, h] = frame_box;
                // XXX: shrink outline region by 1px to make right and bottom lines visible
                // if they are on the edge of the canvas.
                if (x0 + w == this.layout._width.value) {
                    w -= 1;
                }
                if (y0 + h == this.layout._height.value) {
                    h -= 1;
                }
                ctx.strokeRect(x0, y0, w, h);
                ctx.restore();
            }
            this._paint_levels(ctx, ['image', 'underlay', 'glyph'], frame_box, true);
            this._paint_levels(ctx, ['annotation'], frame_box, false);
            this._paint_levels(ctx, ['overlay'], frame_box, false);
            if (this._initial_state_info.range == null)
                this.set_initial_range();
            ctx.restore(); // Restore to default state
        }
        _paint_levels(ctx, levels, clip_region, global_clip) {
            for (const level of levels) {
                for (const renderer of this.computed_renderers) {
                    if (renderer.level != level)
                        continue;
                    const renderer_view = this.renderer_views[renderer.id];
                    ctx.save();
                    if (global_clip || renderer_view.needs_clip) {
                        ctx.beginPath();
                        ctx.rect(...clip_region);
                        ctx.clip();
                    }
                    renderer_view.render();
                    ctx.restore();
                    if (renderer_view.has_webgl) {
                        this.blit_webgl();
                        this.clear_webgl();
                    }
                }
            }
        }
        _map_hook(_ctx, _frame_box) { }
        _paint_empty(ctx, frame_box) {
            const [cx, cy, cw, ch] = [0, 0, this.layout._width.value, this.layout._height.value];
            const [fx, fy, fw, fh] = frame_box;
            ctx.clearRect(cx, cy, cw, ch);
            if (this.visuals.border_fill.doit) {
                this.visuals.border_fill.set_value(ctx);
                ctx.fillRect(cx, cy, cw, ch);
                ctx.clearRect(fx, fy, fw, fh);
            }
            if (this.visuals.background_fill.doit) {
                this.visuals.background_fill.set_value(ctx);
                ctx.fillRect(fx, fy, fw, fh);
            }
        }
        save(name) {
            switch (this.model.output_backend) {
                case "canvas":
                case "webgl": {
                    const canvas = this.canvas_view.get_canvas_element();
                    if (canvas.msToBlob != null) {
                        const blob = canvas.msToBlob();
                        window.navigator.msSaveBlob(blob, name);
                    }
                    else {
                        const link = document.createElement('a');
                        link.href = canvas.toDataURL('image/png');
                        link.download = name + ".png";
                        link.target = "_blank";
                        link.dispatchEvent(new MouseEvent('click'));
                    }
                    break;
                }
                case "svg": {
                    const ctx = this.canvas_view._ctx;
                    const svg = ctx.getSerializedSvg(true);
                    const svgblob = new Blob([svg], { type: 'text/plain' });
                    const downloadLink = document.createElement("a");
                    downloadLink.download = name + ".svg";
                    downloadLink.innerHTML = "Download svg";
                    downloadLink.href = window.URL.createObjectURL(svgblob);
                    downloadLink.onclick = (event) => document.body.removeChild(event.target);
                    downloadLink.style.display = "none";
                    document.body.appendChild(downloadLink);
                    downloadLink.click();
                    break;
                }
            }
        }
        serializable_state() {
            const _a = super.serializable_state(), { children } = _a, state = __rest(_a, ["children"]);
            const renderers = this.get_renderer_views()
                .map((view) => view.serializable_state())
                .filter((item) => "bbox" in item);
            return Object.assign(Object.assign({}, state), { children: [...children, ...renderers] }); // XXX
        }
    }
    exports.PlotView = PlotView;
    PlotView.__name__ = "PlotView";
},
/* core/bokeh_events.js */ function _(require, module, exports) {
    var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
        var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
        if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
            r = Reflect.decorate(decorators, target, key, desc);
        else
            for (var i = decorators.length - 1; i >= 0; i--)
                if (d = decorators[i])
                    r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
        return c > 3 && r && Object.defineProperty(target, key, r), r;
    };
    function event(event_name) {
        return function (cls) {
            cls.prototype.event_name = event_name;
        };
    }
    class BokehEvent {
        to_json() {
            const { event_name } = this;
            return { event_name, event_values: this._to_json() };
        }
        _to_json() {
            const { origin } = this;
            return { model_id: origin != null ? origin.id : null };
        }
    }
    exports.BokehEvent = BokehEvent;
    BokehEvent.__name__ = "BokehEvent";
    let ButtonClick = class ButtonClick extends BokehEvent {
    };
    ButtonClick.__name__ = "ButtonClick";
    ButtonClick = __decorate([
        event("button_click")
    ], ButtonClick);
    exports.ButtonClick = ButtonClick;
    let MenuItemClick = class MenuItemClick extends BokehEvent {
        constructor(item) {
            super();
            this.item = item;
        }
        _to_json() {
            const { item } = this;
            return Object.assign(Object.assign({}, super._to_json()), { item });
        }
    };
    MenuItemClick.__name__ = "MenuItemClick";
    MenuItemClick = __decorate([
        event("menu_item_click")
    ], MenuItemClick);
    exports.MenuItemClick = MenuItemClick;
    // A UIEvent is an event originating on a canvas this includes.
    // DOM events such as keystrokes as well as hammer events and LOD events.
    class UIEvent extends BokehEvent {
    }
    exports.UIEvent = UIEvent;
    UIEvent.__name__ = "UIEvent";
    let LODStart = class LODStart extends UIEvent {
    };
    LODStart.__name__ = "LODStart";
    LODStart = __decorate([
        event("lodstart")
    ], LODStart);
    exports.LODStart = LODStart;
    let LODEnd = class LODEnd extends UIEvent {
    };
    LODEnd.__name__ = "LODEnd";
    LODEnd = __decorate([
        event("lodend")
    ], LODEnd);
    exports.LODEnd = LODEnd;
    let SelectionGeometry = class SelectionGeometry extends UIEvent {
        constructor(geometry, final) {
            super();
            this.geometry = geometry;
            this.final = final;
        }
        _to_json() {
            const { geometry, final } = this;
            return Object.assign(Object.assign({}, super._to_json()), { geometry, final });
        }
    };
    SelectionGeometry.__name__ = "SelectionGeometry";
    SelectionGeometry = __decorate([
        event("selectiongeometry")
    ], SelectionGeometry);
    exports.SelectionGeometry = SelectionGeometry;
    let Reset = class Reset extends UIEvent {
    };
    Reset.__name__ = "Reset";
    Reset = __decorate([
        event("reset")
    ], Reset);
    exports.Reset = Reset;
    class PointEvent extends UIEvent {
        constructor(sx, sy, x, y) {
            super();
            this.sx = sx;
            this.sy = sy;
            this.x = x;
            this.y = y;
        }
        _to_json() {
            const { sx, sy, x, y } = this;
            return Object.assign(Object.assign({}, super._to_json()), { sx, sy, x, y });
        }
    }
    exports.PointEvent = PointEvent;
    PointEvent.__name__ = "PointEvent";
    let Pan = class Pan extends PointEvent {
        /* TODO: direction: -1 | 1 */
        constructor(sx, sy, x, y, delta_x, delta_y) {
            super(sx, sy, x, y);
            this.sx = sx;
            this.sy = sy;
            this.x = x;
            this.y = y;
            this.delta_x = delta_x;
            this.delta_y = delta_y;
        }
        _to_json() {
            const { delta_x, delta_y /*, direction*/ } = this;
            return Object.assign(Object.assign({}, super._to_json()), { delta_x, delta_y /*, direction*/ });
        }
    };
    Pan.__name__ = "Pan";
    Pan = __decorate([
        event("pan")
    ], Pan);
    exports.Pan = Pan;
    let Pinch = class Pinch extends PointEvent {
        constructor(sx, sy, x, y, scale) {
            super(sx, sy, x, y);
            this.sx = sx;
            this.sy = sy;
            this.x = x;
            this.y = y;
            this.scale = scale;
        }
        _to_json() {
            const { scale } = this;
            return Object.assign(Object.assign({}, super._to_json()), { scale });
        }
    };
    Pinch.__name__ = "Pinch";
    Pinch = __decorate([
        event("pinch")
    ], Pinch);
    exports.Pinch = Pinch;
    let Rotate = class Rotate extends PointEvent {
        constructor(sx, sy, x, y, rotation) {
            super(sx, sy, x, y);
            this.sx = sx;
            this.sy = sy;
            this.x = x;
            this.y = y;
            this.rotation = rotation;
        }
        _to_json() {
            const { rotation } = this;
            return Object.assign(Object.assign({}, super._to_json()), { rotation });
        }
    };
    Rotate.__name__ = "Rotate";
    Rotate = __decorate([
        event("rotate")
    ], Rotate);
    exports.Rotate = Rotate;
    let MouseWheel = class MouseWheel extends PointEvent {
        constructor(sx, sy, x, y, delta) {
            super(sx, sy, x, y);
            this.sx = sx;
            this.sy = sy;
            this.x = x;
            this.y = y;
            this.delta = delta;
        }
        _to_json() {
            const { delta } = this;
            return Object.assign(Object.assign({}, super._to_json()), { delta });
        }
    };
    MouseWheel.__name__ = "MouseWheel";
    MouseWheel = __decorate([
        event("wheel")
    ], MouseWheel);
    exports.MouseWheel = MouseWheel;
    let MouseMove = class MouseMove extends PointEvent {
    };
    MouseMove.__name__ = "MouseMove";
    MouseMove = __decorate([
        event("mousemove")
    ], MouseMove);
    exports.MouseMove = MouseMove;
    let MouseEnter = class MouseEnter extends PointEvent {
    };
    MouseEnter.__name__ = "MouseEnter";
    MouseEnter = __decorate([
        event("mouseenter")
    ], MouseEnter);
    exports.MouseEnter = MouseEnter;
    let MouseLeave = class MouseLeave extends PointEvent {
    };
    MouseLeave.__name__ = "MouseLeave";
    MouseLeave = __decorate([
        event("mouseleave")
    ], MouseLeave);
    exports.MouseLeave = MouseLeave;
    let Tap = class Tap extends PointEvent {
    };
    Tap.__name__ = "Tap";
    Tap = __decorate([
        event("tap")
    ], Tap);
    exports.Tap = Tap;
    let DoubleTap = class DoubleTap extends PointEvent {
    };
    DoubleTap.__name__ = "DoubleTap";
    DoubleTap = __decorate([
        event("doubletap")
    ], DoubleTap);
    exports.DoubleTap = DoubleTap;
    let Press = class Press extends PointEvent {
    };
    Press.__name__ = "Press";
    Press = __decorate([
        event("press")
    ], Press);
    exports.Press = Press;
    let PressUp = class PressUp extends PointEvent {
    };
    PressUp.__name__ = "PressUp";
    PressUp = __decorate([
        event("pressup")
    ], PressUp);
    exports.PressUp = PressUp;
    let PanStart = class PanStart extends PointEvent {
    };
    PanStart.__name__ = "PanStart";
    PanStart = __decorate([
        event("panstart")
    ], PanStart);
    exports.PanStart = PanStart;
    let PanEnd = class PanEnd extends PointEvent {
    };
    PanEnd.__name__ = "PanEnd";
    PanEnd = __decorate([
        event("panend")
    ], PanEnd);
    exports.PanEnd = PanEnd;
    let PinchStart = class PinchStart extends PointEvent {
    };
    PinchStart.__name__ = "PinchStart";
    PinchStart = __decorate([
        event("pinchstart")
    ], PinchStart);
    exports.PinchStart = PinchStart;
    let PinchEnd = class PinchEnd extends PointEvent {
    };
    PinchEnd.__name__ = "PinchEnd";
    PinchEnd = __decorate([
        event("pinchend")
    ], PinchEnd);
    exports.PinchEnd = PinchEnd;
    let RotateStart = class RotateStart extends PointEvent {
    };
    RotateStart.__name__ = "RotateStart";
    RotateStart = __decorate([
        event("rotatestart")
    ], RotateStart);
    exports.RotateStart = RotateStart;
    let RotateEnd = class RotateEnd extends PointEvent {
    };
    RotateEnd.__name__ = "RotateEnd";
    RotateEnd = __decorate([
        event("rotateend")
    ], RotateEnd);
    exports.RotateEnd = RotateEnd;
},
/* core/util/throttle.js */ function _(require, module, exports) {
    function _delay_animation(callback) {
        callback(Date.now()); // XXX: performance.now()
        return -1;
    }
    const delay_animation = (typeof window !== 'undefined' ? window.requestAnimationFrame : undefined) ||
        (typeof window !== 'undefined' ? window.webkitRequestAnimationFrame : undefined) ||
        (typeof window !== 'undefined' ? window.mozRequestAnimationFrame : undefined) ||
        (typeof window !== 'undefined' ? window.msRequestAnimationFrame : undefined) || _delay_animation;
    // Returns a function, that, when invoked, will only be triggered at
    // most once during a given window of time.
    //
    // In addition, if the browser supports requestAnimationFrame, the
    // throttled function will be run no more frequently than request
    // animation frame allows.
    //
    // @param func [function] the function to throttle
    // @param wait [number] time in milliseconds to use for window
    // @return [function] throttled function
    //
    function throttle(func, wait) {
        let timeout = null;
        let previous = 0;
        let pending = false;
        const later = function () {
            previous = Date.now();
            timeout = null;
            pending = false;
            func();
        };
        return function () {
            const now = Date.now();
            const remaining = wait - (now - previous);
            if (remaining <= 0 && !pending) {
                if (timeout != null)
                    clearTimeout(timeout);
                pending = true;
                delay_animation(later);
            }
            else if (!timeout && !pending)
                timeout = setTimeout(() => delay_animation(later), remaining);
        };
    }
    exports.throttle = throttle;
},
/* core/layout/side_panel.js */ function _(require, module, exports) {
    const types_1 = require(181) /* ./types */;
    const layoutable_1 = require(182) /* ./layoutable */;
    const types_2 = require(7) /* ../util/types */;
    // This table lays out the rules for configuring the baseline, alignment, etc. of
    // title text, based on it's location and orientation
    //
    // side    orient        baseline   align     angle   normal-dist
    // ------------------------------------------------------------------------------
    // above   parallel      bottom     center    0       height
    //         normal        middle     left      -90     width
    //         horizontal    bottom     center    0       height
    //         [angle > 0]   middle     left              width * sin + height * cos
    //         [angle < 0]   middle     right             width * sin + height * cos
    //
    // below   parallel      top        center    0       height
    //         normal        middle     right     90      width
    //         horizontal    top        center    0       height
    //         [angle > 0]   middle     right             width * sin + height * cos
    //         [angle < 0]   middle     left              width * sin + height * cos
    //
    // left    parallel      bottom     center    90      height
    //         normal        middle     right     0       width
    //         horizontal    middle     right     0       width
    //         [angle > 0]   middle     right             width * cos + height * sin
    //         [angle < 0]   middle     right             width * cos + height + sin
    //
    // right   parallel      bottom     center   -90      height
    //         normal        middle     left     0        width
    //         horizontal    middle     left     0        width
    //         [angle > 0]   middle     left              width * cos + height * sin
    //         [angle < 0]   middle     left              width * cos + height + sin
    const pi2 = Math.PI / 2;
    const ALPHABETIC = 'alphabetic';
    const TOP = 'top';
    const BOTTOM = 'bottom';
    const MIDDLE = 'middle';
    const HANGING = 'hanging';
    const LEFT = 'left';
    const RIGHT = 'right';
    const CENTER = 'center';
    const _angle_lookup = {
        above: {
            parallel: 0,
            normal: -pi2,
            horizontal: 0,
            vertical: -pi2,
        },
        below: {
            parallel: 0,
            normal: pi2,
            horizontal: 0,
            vertical: pi2,
        },
        left: {
            parallel: -pi2,
            normal: 0,
            horizontal: 0,
            vertical: -pi2,
        },
        right: {
            parallel: pi2,
            normal: 0,
            horizontal: 0,
            vertical: pi2,
        },
    };
    const _baseline_lookup = {
        above: {
            justified: TOP,
            parallel: ALPHABETIC,
            normal: MIDDLE,
            horizontal: ALPHABETIC,
            vertical: MIDDLE,
        },
        below: {
            justified: BOTTOM,
            parallel: HANGING,
            normal: MIDDLE,
            horizontal: HANGING,
            vertical: MIDDLE,
        },
        left: {
            justified: TOP,
            parallel: ALPHABETIC,
            normal: MIDDLE,
            horizontal: MIDDLE,
            vertical: ALPHABETIC,
        },
        right: {
            justified: TOP,
            parallel: ALPHABETIC,
            normal: MIDDLE,
            horizontal: MIDDLE,
            vertical: ALPHABETIC,
        },
    };
    const _align_lookup = {
        above: {
            justified: CENTER,
            parallel: CENTER,
            normal: LEFT,
            horizontal: CENTER,
            vertical: LEFT,
        },
        below: {
            justified: CENTER,
            parallel: CENTER,
            normal: LEFT,
            horizontal: CENTER,
            vertical: LEFT,
        },
        left: {
            justified: CENTER,
            parallel: CENTER,
            normal: RIGHT,
            horizontal: RIGHT,
            vertical: CENTER,
        },
        right: {
            justified: CENTER,
            parallel: CENTER,
            normal: LEFT,
            horizontal: LEFT,
            vertical: CENTER,
        },
    };
    const _align_lookup_negative = {
        above: RIGHT,
        below: LEFT,
        left: RIGHT,
        right: LEFT,
    };
    const _align_lookup_positive = {
        above: LEFT,
        below: RIGHT,
        left: RIGHT,
        right: LEFT,
    };
    class SidePanel extends layoutable_1.ContentLayoutable {
        constructor(side, obj) {
            super();
            this.side = side;
            this.obj = obj;
            switch (this.side) {
                case "above":
                    this._dim = 0;
                    this._normals = [0, -1];
                    break;
                case "below":
                    this._dim = 0;
                    this._normals = [0, 1];
                    break;
                case "left":
                    this._dim = 1;
                    this._normals = [-1, 0];
                    break;
                case "right":
                    this._dim = 1;
                    this._normals = [1, 0];
                    break;
                default:
                    throw new Error("unreachable");
            }
            if (this.is_horizontal)
                this.set_sizing({ width_policy: "max", height_policy: "fixed" });
            else
                this.set_sizing({ width_policy: "fixed", height_policy: "max" });
        }
        _content_size() {
            return new types_1.Sizeable(this.get_oriented_size());
        }
        get_oriented_size() {
            const { width, height } = this.obj.get_size();
            if (!this.obj.rotate || this.is_horizontal)
                return { width, height };
            else
                return { width: height, height: width };
        }
        has_size_changed() {
            const { width, height } = this.get_oriented_size();
            if (this.is_horizontal)
                return this.bbox.height != height;
            else
                return this.bbox.width != width;
        }
        get dimension() {
            return this._dim;
        }
        get normals() {
            return this._normals;
        }
        get is_horizontal() {
            return this._dim == 0;
        }
        get is_vertical() {
            return this._dim == 1;
        }
        apply_label_text_heuristics(ctx, orient) {
            const side = this.side;
            let baseline;
            let align;
            if (types_2.isString(orient)) {
                baseline = _baseline_lookup[side][orient];
                align = _align_lookup[side][orient];
            }
            else {
                if (orient === 0) {
                    baseline = "whatever"; // XXX: _baseline_lookup[side][orient]
                    align = "whatever"; // XXX: _align_lookup[side][orient]
                }
                else if (orient < 0) {
                    baseline = 'middle';
                    align = _align_lookup_negative[side];
                }
                else {
                    baseline = 'middle';
                    align = _align_lookup_positive[side];
                }
            }
            ctx.textBaseline = baseline;
            ctx.textAlign = align;
        }
        get_label_angle_heuristic(orient) {
            return _angle_lookup[this.side][orient];
        }
    }
    exports.SidePanel = SidePanel;
    SidePanel.__name__ = "SidePanel";
},
/* core/ui_events.js */ function _(require, module, exports) {
    const Hammer = require(278) /* hammerjs */;
    const signaling_1 = require(13) /* ./signaling */;
    const logging_1 = require(65) /* ./logging */;
    const dom_1 = require(61) /* ./dom */;
    const wheel_1 = require(279) /* ./util/wheel */;
    const array_1 = require(8) /* ./util/array */;
    const object_1 = require(22) /* ./util/object */;
    const types_1 = require(7) /* ./util/types */;
    const compat_1 = require(95) /* ./util/compat */;
    const events = require(274) /* ./bokeh_events */;
    class UIEvents {
        constructor(plot_view, toolbar, hit_area) {
            this.plot_view = plot_view;
            this.toolbar = toolbar;
            this.hit_area = hit_area;
            this.pan_start = new signaling_1.Signal(this, 'pan:start');
            this.pan = new signaling_1.Signal(this, 'pan');
            this.pan_end = new signaling_1.Signal(this, 'pan:end');
            this.pinch_start = new signaling_1.Signal(this, 'pinch:start');
            this.pinch = new signaling_1.Signal(this, 'pinch');
            this.pinch_end = new signaling_1.Signal(this, 'pinch:end');
            this.rotate_start = new signaling_1.Signal(this, 'rotate:start');
            this.rotate = new signaling_1.Signal(this, 'rotate');
            this.rotate_end = new signaling_1.Signal(this, 'rotate:end');
            this.tap = new signaling_1.Signal(this, 'tap');
            this.doubletap = new signaling_1.Signal(this, 'doubletap');
            this.press = new signaling_1.Signal(this, 'press');
            this.pressup = new signaling_1.Signal(this, 'pressup');
            this.move_enter = new signaling_1.Signal(this, 'move:enter');
            this.move = new signaling_1.Signal(this, 'move');
            this.move_exit = new signaling_1.Signal(this, 'move:exit');
            this.scroll = new signaling_1.Signal(this, 'scroll');
            this.keydown = new signaling_1.Signal(this, 'keydown');
            this.keyup = new signaling_1.Signal(this, 'keyup');
            this.hammer = new Hammer(this.hit_area, { touchAction: 'auto' });
            this._configure_hammerjs();
            // Mouse & keyboard events not handled through hammerjs
            // We can 'add and forget' these event listeners because this.hit_area is a DOM element
            // that will be thrown away when the view is removed
            this.hit_area.addEventListener("mousemove", (e) => this._mouse_move(e));
            this.hit_area.addEventListener("mouseenter", (e) => this._mouse_enter(e));
            this.hit_area.addEventListener("mouseleave", (e) => this._mouse_exit(e));
            this.hit_area.addEventListener("wheel", (e) => this._mouse_wheel(e));
            // But we MUST remove listeners registered on document or we'll leak memory: register
            // 'this' as the listener (it implements the event listener interface, i.e. handleEvent)
            // instead of an anonymous function so we can easily refer back to it for removing
            document.addEventListener("keydown", this);
            document.addEventListener("keyup", this);
        }
        destroy() {
            this.hammer.destroy();
            document.removeEventListener("keydown", this);
            document.removeEventListener("keyup", this);
        }
        handleEvent(e) {
            if (e.type == "keydown")
                this._key_down(e);
            else if (e.type == "keyup")
                this._key_up(e);
        }
        _configure_hammerjs() {
            // This is to be able to distinguish double taps from single taps
            this.hammer.get('doubletap').recognizeWith('tap');
            this.hammer.get('tap').requireFailure('doubletap');
            this.hammer.get('doubletap').dropRequireFailure('tap');
            this.hammer.on('doubletap', (e) => this._doubletap(e));
            this.hammer.on('tap', (e) => this._tap(e));
            this.hammer.on('press', (e) => this._press(e));
            this.hammer.on('pressup', (e) => this._pressup(e));
            this.hammer.get('pan').set({ direction: Hammer.DIRECTION_ALL });
            this.hammer.on('panstart', (e) => this._pan_start(e));
            this.hammer.on('pan', (e) => this._pan(e));
            this.hammer.on('panend', (e) => this._pan_end(e));
            this.hammer.get('pinch').set({ enable: true });
            this.hammer.on('pinchstart', (e) => this._pinch_start(e));
            this.hammer.on('pinch', (e) => this._pinch(e));
            this.hammer.on('pinchend', (e) => this._pinch_end(e));
            this.hammer.get('rotate').set({ enable: true });
            this.hammer.on('rotatestart', (e) => this._rotate_start(e));
            this.hammer.on('rotate', (e) => this._rotate(e));
            this.hammer.on('rotateend', (e) => this._rotate_end(e));
        }
        register_tool(tool_view) {
            const et = tool_view.model.event_type;
            if (et != null) {
                if (types_1.isString(et))
                    this._register_tool(tool_view, et);
                else {
                    // Multi-tools should only registered shared events once
                    et.forEach((e, index) => this._register_tool(tool_view, e, index < 1));
                }
            }
        }
        _register_tool(tool_view, et, shared = true) {
            const v = tool_view;
            const { id } = v.model;
            const conditionally = (fn) => (arg) => {
                if (arg.id == id)
                    fn(arg.e);
            };
            const unconditionally = (fn) => (arg) => {
                fn(arg.e);
            };
            switch (et) {
                case "pan": {
                    if (v._pan_start != null)
                        v.connect(this.pan_start, conditionally(v._pan_start.bind(v)));
                    if (v._pan != null)
                        v.connect(this.pan, conditionally(v._pan.bind(v)));
                    if (v._pan_end != null)
                        v.connect(this.pan_end, conditionally(v._pan_end.bind(v)));
                    break;
                }
                case "pinch": {
                    if (v._pinch_start != null)
                        v.connect(this.pinch_start, conditionally(v._pinch_start.bind(v)));
                    if (v._pinch != null)
                        v.connect(this.pinch, conditionally(v._pinch.bind(v)));
                    if (v._pinch_end != null)
                        v.connect(this.pinch_end, conditionally(v._pinch_end.bind(v)));
                    break;
                }
                case "rotate": {
                    if (v._rotate_start != null)
                        v.connect(this.rotate_start, conditionally(v._rotate_start.bind(v)));
                    if (v._rotate != null)
                        v.connect(this.rotate, conditionally(v._rotate.bind(v)));
                    if (v._rotate_end != null)
                        v.connect(this.rotate_end, conditionally(v._rotate_end.bind(v)));
                    break;
                }
                case "move": {
                    if (v._move_enter != null)
                        v.connect(this.move_enter, conditionally(v._move_enter.bind(v)));
                    if (v._move != null)
                        v.connect(this.move, conditionally(v._move.bind(v)));
                    if (v._move_exit != null)
                        v.connect(this.move_exit, conditionally(v._move_exit.bind(v)));
                    break;
                }
                case "tap": {
                    if (v._tap != null)
                        v.connect(this.tap, conditionally(v._tap.bind(v)));
                    break;
                }
                case "press": {
                    if (v._press != null)
                        v.connect(this.press, conditionally(v._press.bind(v)));
                    if (v._pressup != null)
                        v.connect(this.pressup, conditionally(v._pressup.bind(v)));
                    break;
                }
                case "scroll": {
                    if (v._scroll != null)
                        v.connect(this.scroll, conditionally(v._scroll.bind(v)));
                    break;
                }
                default:
                    throw new Error(`unsupported event_type: ${et}`);
            }
            // Skip shared events if registering multi-tool
            if (!shared)
                return;
            if (v._doubletap != null)
                v.connect(this.doubletap, unconditionally(v._doubletap.bind(v)));
            if (v._keydown != null)
                v.connect(this.keydown, unconditionally(v._keydown.bind(v)));
            if (v._keyup != null)
                v.connect(this.keyup, unconditionally(v._keyup.bind(v)));
            // Dual touch hack part 1/2
            // This is a hack for laptops with touch screen who may be pinching or scrolling
            // in order to use the wheel zoom tool. If it's a touch screen the WheelZoomTool event
            // will be linked to pinch. But we also want to trigger in the case of a scroll.
            if (compat_1.is_mobile && v._scroll != null && et == 'pinch') {
                logging_1.logger.debug("Registering scroll on touch screen");
                v.connect(this.scroll, conditionally(v._scroll.bind(v)));
            }
        }
        _hit_test_renderers(sx, sy) {
            const views = this.plot_view.get_renderer_views();
            for (const view of array_1.reversed(views)) {
                const { level } = view.model;
                if ((level == 'annotation' || level == 'overlay') && view.interactive_hit != null) {
                    if (view.interactive_hit(sx, sy))
                        return view;
                }
            }
            return null;
        }
        _hit_test_frame(sx, sy) {
            return this.plot_view.frame.bbox.contains(sx, sy);
        }
        _hit_test_canvas(sx, sy) {
            return this.plot_view.layout.bbox.contains(sx, sy);
        }
        _trigger(signal, e, srcEvent) {
            const gestures = this.toolbar.gestures;
            let event_type = signal.name;
            const base_type = event_type.split(":")[0];
            const view = this._hit_test_renderers(e.sx, e.sy);
            const on_canvas = this._hit_test_canvas(e.sx, e.sy);
            switch (base_type) {
                case "move": {
                    const active_gesture = gestures[base_type].active;
                    if (active_gesture != null)
                        this.trigger(signal, e, active_gesture.id);
                    const active_inspectors = this.toolbar.inspectors.filter(t => t.active);
                    let cursor = "default";
                    // the event happened on a renderer
                    if (view != null) {
                        cursor = view.cursor(e.sx, e.sy) || cursor;
                        if (!object_1.isEmpty(active_inspectors)) {
                            // override event_type to cause inspectors to clear overlays
                            signal = this.move_exit; // XXX
                            event_type = signal.name;
                        }
                        // the event happened on the plot frame but off a renderer
                    }
                    else if (this._hit_test_frame(e.sx, e.sy)) {
                        if (!object_1.isEmpty(active_inspectors)) {
                            cursor = "crosshair";
                        }
                    }
                    this.plot_view.set_cursor(cursor);
                    this.plot_view.set_toolbar_visibility(on_canvas);
                    active_inspectors.map((inspector) => this.trigger(signal, e, inspector.id));
                    break;
                }
                case "tap": {
                    const { target } = srcEvent;
                    if (target != null && target != this.hit_area)
                        return; // don't trigger bokeh events
                    if (view != null && view.on_hit != null)
                        view.on_hit(e.sx, e.sy);
                    const active_gesture = gestures[base_type].active;
                    if (active_gesture != null)
                        this.trigger(signal, e, active_gesture.id);
                    break;
                }
                case "scroll": {
                    // Dual touch hack part 2/2
                    // This is a hack for laptops with touch screen who may be pinching or scrolling
                    // in order to use the wheel zoom tool. If it's a touch screen the WheelZoomTool event
                    // will be linked to pinch. But we also want to trigger in the case of a scroll.
                    const base = compat_1.is_mobile ? "pinch" : "scroll";
                    const active_gesture = gestures[base].active;
                    if (active_gesture != null) {
                        srcEvent.preventDefault();
                        srcEvent.stopPropagation();
                        this.trigger(signal, e, active_gesture.id);
                    }
                    break;
                }
                case "pan": {
                    const active_gesture = gestures[base_type].active;
                    if (active_gesture != null) {
                        srcEvent.preventDefault();
                        this.trigger(signal, e, active_gesture.id);
                    }
                    break;
                }
                default: {
                    const active_gesture = gestures[base_type].active;
                    if (active_gesture != null)
                        this.trigger(signal, e, active_gesture.id);
                }
            }
            this._trigger_bokeh_event(e);
        }
        trigger(signal, e, id = null) {
            signal.emit({ id, e });
        }
        _trigger_bokeh_event(e) {
            const ev = (() => {
                const xscale = this.plot_view.frame.xscales.default;
                const yscale = this.plot_view.frame.yscales.default;
                const { sx, sy } = e;
                const x = xscale.invert(sx);
                const y = yscale.invert(sy);
                switch (e.type) {
                    case "wheel":
                        return new events.MouseWheel(sx, sy, x, y, e.delta);
                    case "mousemove":
                        return new events.MouseMove(sx, sy, x, y);
                    case "mouseenter":
                        return new events.MouseEnter(sx, sy, x, y);
                    case "mouseleave":
                        return new events.MouseLeave(sx, sy, x, y);
                    case "tap":
                        return new events.Tap(sx, sy, x, y);
                    case "doubletap":
                        return new events.DoubleTap(sx, sy, x, y);
                    case "press":
                        return new events.Press(sx, sy, x, y);
                    case "pressup":
                        return new events.PressUp(sx, sy, x, y);
                    case "pan":
                        return new events.Pan(sx, sy, x, y, e.deltaX, e.deltaY);
                    case "panstart":
                        return new events.PanStart(sx, sy, x, y);
                    case "panend":
                        return new events.PanEnd(sx, sy, x, y);
                    case "pinch":
                        return new events.Pinch(sx, sy, x, y, e.scale);
                    case "pinchstart":
                        return new events.PinchStart(sx, sy, x, y);
                    case "pinchend":
                        return new events.PinchEnd(sx, sy, x, y);
                    case "rotate":
                        return new events.Rotate(sx, sy, x, y, e.rotation);
                    case "rotatestart":
                        return new events.RotateStart(sx, sy, x, y);
                    case "rotateend":
                        return new events.RotateEnd(sx, sy, x, y);
                    default:
                        return undefined;
                }
            })();
            if (ev != null)
                this.plot_view.model.trigger_event(ev);
        }
        _get_sxy(event) {
            // XXX: jsdom doesn't support TouchEvent constructor
            function is_touch(event) {
                return typeof TouchEvent !== "undefined" && event instanceof TouchEvent;
            }
            const { pageX, pageY } = is_touch(event) ? (event.touches.length != 0 ? event.touches : event.changedTouches)[0] : event;
            const { left, top } = dom_1.offset(this.hit_area);
            return {
                sx: pageX - left,
                sy: pageY - top,
            };
        }
        _pan_event(e) {
            return Object.assign(Object.assign({ type: e.type }, this._get_sxy(e.srcEvent)), { deltaX: e.deltaX, deltaY: e.deltaY, shiftKey: e.srcEvent.shiftKey });
        }
        _pinch_event(e) {
            return Object.assign(Object.assign({ type: e.type }, this._get_sxy(e.srcEvent)), { scale: e.scale, shiftKey: e.srcEvent.shiftKey });
        }
        _rotate_event(e) {
            return Object.assign(Object.assign({ type: e.type }, this._get_sxy(e.srcEvent)), { rotation: e.rotation, shiftKey: e.srcEvent.shiftKey });
        }
        _tap_event(e) {
            return Object.assign(Object.assign({ type: e.type }, this._get_sxy(e.srcEvent)), { shiftKey: e.srcEvent.shiftKey });
        }
        _move_event(e) {
            return Object.assign({ type: e.type }, this._get_sxy(e));
        }
        _scroll_event(e) {
            return Object.assign(Object.assign({ type: e.type }, this._get_sxy(e)), { delta: wheel_1.getDeltaY(e) });
        }
        _key_event(e) {
            return {
                type: e.type,
                keyCode: e.keyCode,
            };
        }
        _pan_start(e) {
            const ev = this._pan_event(e);
            // back out delta to get original center point
            ev.sx -= e.deltaX;
            ev.sy -= e.deltaY;
            this._trigger(this.pan_start, ev, e.srcEvent);
        }
        _pan(e) {
            this._trigger(this.pan, this._pan_event(e), e.srcEvent);
        }
        _pan_end(e) {
            this._trigger(this.pan_end, this._pan_event(e), e.srcEvent);
        }
        _pinch_start(e) {
            this._trigger(this.pinch_start, this._pinch_event(e), e.srcEvent);
        }
        _pinch(e) {
            this._trigger(this.pinch, this._pinch_event(e), e.srcEvent);
        }
        _pinch_end(e) {
            this._trigger(this.pinch_end, this._pinch_event(e), e.srcEvent);
        }
        _rotate_start(e) {
            this._trigger(this.rotate_start, this._rotate_event(e), e.srcEvent);
        }
        _rotate(e) {
            this._trigger(this.rotate, this._rotate_event(e), e.srcEvent);
        }
        _rotate_end(e) {
            this._trigger(this.rotate_end, this._rotate_event(e), e.srcEvent);
        }
        _tap(e) {
            this._trigger(this.tap, this._tap_event(e), e.srcEvent);
        }
        _doubletap(e) {
            // NOTE: doubletap event triggered unconditionally
            const ev = this._tap_event(e);
            this._trigger_bokeh_event(ev);
            this.trigger(this.doubletap, ev);
        }
        _press(e) {
            this._trigger(this.press, this._tap_event(e), e.srcEvent);
        }
        _pressup(e) {
            this._trigger(this.pressup, this._tap_event(e), e.srcEvent);
        }
        _mouse_enter(e) {
            this._trigger(this.move_enter, this._move_event(e), e);
        }
        _mouse_move(e) {
            this._trigger(this.move, this._move_event(e), e);
        }
        _mouse_exit(e) {
            this._trigger(this.move_exit, this._move_event(e), e);
        }
        _mouse_wheel(e) {
            this._trigger(this.scroll, this._scroll_event(e), e);
        }
        _key_down(e) {
            // NOTE: keyup event triggered unconditionally
            this.trigger(this.keydown, this._key_event(e));
        }
        _key_up(e) {
            // NOTE: keyup event triggered unconditionally
            this.trigger(this.keyup, this._key_event(e));
        }
    }
    exports.UIEvents = UIEvents;
    UIEvents.__name__ = "UIEvents";
},
/* hammerjs/hammer.js */ function _(require, module, exports) {
    /*! Hammer.JS - v2.0.7 - 2016-04-22
     * http://hammerjs.github.io/
     *
     * Copyright (c) 2016 Jorik Tangelder;
     * Licensed under the MIT license */
    (function (window, document, exportName, undefined) {
        'use strict';
        var VENDOR_PREFIXES = ['', 'webkit', 'Moz', 'MS', 'ms', 'o'];
        var TEST_ELEMENT = document.createElement('div');
        var TYPE_FUNCTION = 'function';
        var round = Math.round;
        var abs = Math.abs;
        var now = Date.now;
        /**
         * set a timeout with a given scope
         * @param {Function} fn
         * @param {Number} timeout
         * @param {Object} context
         * @returns {number}
         */
        function setTimeoutContext(fn, timeout, context) {
            return setTimeout(bindFn(fn, context), timeout);
        }
        /**
         * if the argument is an array, we want to execute the fn on each entry
         * if it aint an array we don't want to do a thing.
         * this is used by all the methods that accept a single and array argument.
         * @param {*|Array} arg
         * @param {String} fn
         * @param {Object} [context]
         * @returns {Boolean}
         */
        function invokeArrayArg(arg, fn, context) {
            if (Array.isArray(arg)) {
                each(arg, context[fn], context);
                return true;
            }
            return false;
        }
        /**
         * walk objects and arrays
         * @param {Object} obj
         * @param {Function} iterator
         * @param {Object} context
         */
        function each(obj, iterator, context) {
            var i;
            if (!obj) {
                return;
            }
            if (obj.forEach) {
                obj.forEach(iterator, context);
            }
            else if (obj.length !== undefined) {
                i = 0;
                while (i < obj.length) {
                    iterator.call(context, obj[i], i, obj);
                    i++;
                }
            }
            else {
                for (i in obj) {
                    obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj);
                }
            }
        }
        /**
         * wrap a method with a deprecation warning and stack trace
         * @param {Function} method
         * @param {String} name
         * @param {String} message
         * @returns {Function} A new function wrapping the supplied method.
         */
        function deprecate(method, name, message) {
            var deprecationMessage = 'DEPRECATED METHOD: ' + name + '\n' + message + ' AT \n';
            return function () {
                var e = new Error('get-stack-trace');
                var stack = e && e.stack ? e.stack.replace(/^[^\(]+?[\n$]/gm, '')
                    .replace(/^\s+at\s+/gm, '')
                    .replace(/^Object.<anonymous>\s*\(/gm, '{anonymous}()@') : 'Unknown Stack Trace';
                var log = window.console && (window.console.warn || window.console.log);
                if (log) {
                    log.call(window.console, deprecationMessage, stack);
                }
                return method.apply(this, arguments);
            };
        }
        /**
         * extend object.
         * means that properties in dest will be overwritten by the ones in src.
         * @param {Object} target
         * @param {...Object} objects_to_assign
         * @returns {Object} target
         */
        var assign;
        if (typeof Object.assign !== 'function') {
            assign = function assign(target) {
                if (target === undefined || target === null) {
                    throw new TypeError('Cannot convert undefined or null to object');
                }
                var output = Object(target);
                for (var index = 1; index < arguments.length; index++) {
                    var source = arguments[index];
                    if (source !== undefined && source !== null) {
                        for (var nextKey in source) {
                            if (source.hasOwnProperty(nextKey)) {
                                output[nextKey] = source[nextKey];
                            }
                        }
                    }
                }
                return output;
            };
        }
        else {
            assign = Object.assign;
        }
        /**
         * extend object.
         * means that properties in dest will be overwritten by the ones in src.
         * @param {Object} dest
         * @param {Object} src
         * @param {Boolean} [merge=false]
         * @returns {Object} dest
         */
        var extend = deprecate(function extend(dest, src, merge) {
            var keys = Object.keys(src);
            var i = 0;
            while (i < keys.length) {
                if (!merge || (merge && dest[keys[i]] === undefined)) {
                    dest[keys[i]] = src[keys[i]];
                }
                i++;
            }
            return dest;
        }, 'extend', 'Use `assign`.');
        /**
         * merge the values from src in the dest.
         * means that properties that exist in dest will not be overwritten by src
         * @param {Object} dest
         * @param {Object} src
         * @returns {Object} dest
         */
        var merge = deprecate(function merge(dest, src) {
            return extend(dest, src, true);
        }, 'merge', 'Use `assign`.');
        /**
         * simple class inheritance
         * @param {Function} child
         * @param {Function} base
         * @param {Object} [properties]
         */
        function inherit(child, base, properties) {
            var baseP = base.prototype, childP;
            childP = child.prototype = Object.create(baseP);
            childP.constructor = child;
            childP._super = baseP;
            if (properties) {
                assign(childP, properties);
            }
        }
        /**
         * simple function bind
         * @param {Function} fn
         * @param {Object} context
         * @returns {Function}
         */
        function bindFn(fn, context) {
            return function boundFn() {
                return fn.apply(context, arguments);
            };
        }
        /**
         * let a boolean value also be a function that must return a boolean
         * this first item in args will be used as the context
         * @param {Boolean|Function} val
         * @param {Array} [args]
         * @returns {Boolean}
         */
        function boolOrFn(val, args) {
            if (typeof val == TYPE_FUNCTION) {
                return val.apply(args ? args[0] || undefined : undefined, args);
            }
            return val;
        }
        /**
         * use the val2 when val1 is undefined
         * @param {*} val1
         * @param {*} val2
         * @returns {*}
         */
        function ifUndefined(val1, val2) {
            return (val1 === undefined) ? val2 : val1;
        }
        /**
         * addEventListener with multiple events at once
         * @param {EventTarget} target
         * @param {String} types
         * @param {Function} handler
         */
        function addEventListeners(target, types, handler) {
            each(splitStr(types), function (type) {
                target.addEventListener(type, handler, false);
            });
        }
        /**
         * removeEventListener with multiple events at once
         * @param {EventTarget} target
         * @param {String} types
         * @param {Function} handler
         */
        function removeEventListeners(target, types, handler) {
            each(splitStr(types), function (type) {
                target.removeEventListener(type, handler, false);
            });
        }
        /**
         * find if a node is in the given parent
         * @method hasParent
         * @param {HTMLElement} node
         * @param {HTMLElement} parent
         * @return {Boolean} found
         */
        function hasParent(node, parent) {
            while (node) {
                if (node == parent) {
                    return true;
                }
                node = node.parentNode;
            }
            return false;
        }
        /**
         * small indexOf wrapper
         * @param {String} str
         * @param {String} find
         * @returns {Boolean} found
         */
        function inStr(str, find) {
            return str.indexOf(find) > -1;
        }
        /**
         * split string on whitespace
         * @param {String} str
         * @returns {Array} words
         */
        function splitStr(str) {
            return str.trim().split(/\s+/g);
        }
        /**
         * find if a array contains the object using indexOf or a simple polyFill
         * @param {Array} src
         * @param {String} find
         * @param {String} [findByKey]
         * @return {Boolean|Number} false when not found, or the index
         */
        function inArray(src, find, findByKey) {
            if (src.indexOf && !findByKey) {
                return src.indexOf(find);
            }
            else {
                var i = 0;
                while (i < src.length) {
                    if ((findByKey && src[i][findByKey] == find) || (!findByKey && src[i] === find)) {
                        return i;
                    }
                    i++;
                }
                return -1;
            }
        }
        /**
         * convert array-like objects to real arrays
         * @param {Object} obj
         * @returns {Array}
         */
        function toArray(obj) {
            return Array.prototype.slice.call(obj, 0);
        }
        /**
         * unique array with objects based on a key (like 'id') or just by the array's value
         * @param {Array} src [{id:1},{id:2},{id:1}]
         * @param {String} [key]
         * @param {Boolean} [sort=False]
         * @returns {Array} [{id:1},{id:2}]
         */
        function uniqueArray(src, key, sort) {
            var results = [];
            var values = [];
            var i = 0;
            while (i < src.length) {
                var val = key ? src[i][key] : src[i];
                if (inArray(values, val) < 0) {
                    results.push(src[i]);
                }
                values[i] = val;
                i++;
            }
            if (sort) {
                if (!key) {
                    results = results.sort();
                }
                else {
                    results = results.sort(function sortUniqueArray(a, b) {
                        return a[key] > b[key];
                    });
                }
            }
            return results;
        }
        /**
         * get the prefixed property
         * @param {Object} obj
         * @param {String} property
         * @returns {String|Undefined} prefixed
         */
        function prefixed(obj, property) {
            var prefix, prop;
            var camelProp = property[0].toUpperCase() + property.slice(1);
            var i = 0;
            while (i < VENDOR_PREFIXES.length) {
                prefix = VENDOR_PREFIXES[i];
                prop = (prefix) ? prefix + camelProp : property;
                if (prop in obj) {
                    return prop;
                }
                i++;
            }
            return undefined;
        }
        /**
         * get a unique id
         * @returns {number} uniqueId
         */
        var _uniqueId = 1;
        function uniqueId() {
            return _uniqueId++;
        }
        /**
         * get the window object of an element
         * @param {HTMLElement} element
         * @returns {DocumentView|Window}
         */
        function getWindowForElement(element) {
            var doc = element.ownerDocument || element;
            return (doc.defaultView || doc.parentWindow || window);
        }
        var MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i;
        var SUPPORT_TOUCH = ('ontouchstart' in window);
        var SUPPORT_POINTER_EVENTS = prefixed(window, 'PointerEvent') !== undefined;
        var SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH && MOBILE_REGEX.test(navigator.userAgent);
        var INPUT_TYPE_TOUCH = 'touch';
        var INPUT_TYPE_PEN = 'pen';
        var INPUT_TYPE_MOUSE = 'mouse';
        var INPUT_TYPE_KINECT = 'kinect';
        var COMPUTE_INTERVAL = 25;
        var INPUT_START = 1;
        var INPUT_MOVE = 2;
        var INPUT_END = 4;
        var INPUT_CANCEL = 8;
        var DIRECTION_NONE = 1;
        var DIRECTION_LEFT = 2;
        var DIRECTION_RIGHT = 4;
        var DIRECTION_UP = 8;
        var DIRECTION_DOWN = 16;
        var DIRECTION_HORIZONTAL = DIRECTION_LEFT | DIRECTION_RIGHT;
        var DIRECTION_VERTICAL = DIRECTION_UP | DIRECTION_DOWN;
        var DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL;
        var PROPS_XY = ['x', 'y'];
        var PROPS_CLIENT_XY = ['clientX', 'clientY'];
        /**
         * create new input type manager
         * @param {Manager} manager
         * @param {Function} callback
         * @returns {Input}
         * @constructor
         */
        function Input(manager, callback) {
            var self = this;
            this.manager = manager;
            this.callback = callback;
            this.element = manager.element;
            this.target = manager.options.inputTarget;
            // smaller wrapper around the handler, for the scope and the enabled state of the manager,
            // so when disabled the input events are completely bypassed.
            this.domHandler = function (ev) {
                if (boolOrFn(manager.options.enable, [manager])) {
                    self.handler(ev);
                }
            };
            this.init();
        }
        Input.prototype = {
            /**
             * should handle the inputEvent data and trigger the callback
             * @virtual
             */
            handler: function () { },
            /**
             * bind the events
             */
            init: function () {
                this.evEl && addEventListeners(this.element, this.evEl, this.domHandler);
                this.evTarget && addEventListeners(this.target, this.evTarget, this.domHandler);
                this.evWin && addEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
            },
            /**
             * unbind the events
             */
            destroy: function () {
                this.evEl && removeEventListeners(this.element, this.evEl, this.domHandler);
                this.evTarget && removeEventListeners(this.target, this.evTarget, this.domHandler);
                this.evWin && removeEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
            }
        };
        /**
         * create new input type manager
         * called by the Manager constructor
         * @param {Hammer} manager
         * @returns {Input}
         */
        function createInputInstance(manager) {
            var Type;
            var inputClass = manager.options.inputClass;
            if (inputClass) {
                Type = inputClass;
            }
            else if (SUPPORT_POINTER_EVENTS) {
                Type = PointerEventInput;
            }
            else if (SUPPORT_ONLY_TOUCH) {
                Type = TouchInput;
            }
            else if (!SUPPORT_TOUCH) {
                Type = MouseInput;
            }
            else {
                Type = TouchMouseInput;
            }
            return new (Type)(manager, inputHandler);
        }
        /**
         * handle input events
         * @param {Manager} manager
         * @param {String} eventType
         * @param {Object} input
         */
        function inputHandler(manager, eventType, input) {
            var pointersLen = input.pointers.length;
            var changedPointersLen = input.changedPointers.length;
            var isFirst = (eventType & INPUT_START && (pointersLen - changedPointersLen === 0));
            var isFinal = (eventType & (INPUT_END | INPUT_CANCEL) && (pointersLen - changedPointersLen === 0));
            input.isFirst = !!isFirst;
            input.isFinal = !!isFinal;
            if (isFirst) {
                manager.session = {};
            }
            // source event is the normalized value of the domEvents
            // like 'touchstart, mouseup, pointerdown'
            input.eventType = eventType;
            // compute scale, rotation etc
            computeInputData(manager, input);
            // emit secret event
            manager.emit('hammer.input', input);
            manager.recognize(input);
            manager.session.prevInput = input;
        }
        /**
         * extend the data with some usable properties like scale, rotate, velocity etc
         * @param {Object} manager
         * @param {Object} input
         */
        function computeInputData(manager, input) {
            var session = manager.session;
            var pointers = input.pointers;
            var pointersLength = pointers.length;
            // store the first input to calculate the distance and direction
            if (!session.firstInput) {
                session.firstInput = simpleCloneInputData(input);
            }
            // to compute scale and rotation we need to store the multiple touches
            if (pointersLength > 1 && !session.firstMultiple) {
                session.firstMultiple = simpleCloneInputData(input);
            }
            else if (pointersLength === 1) {
                session.firstMultiple = false;
            }
            var firstInput = session.firstInput;
            var firstMultiple = session.firstMultiple;
            var offsetCenter = firstMultiple ? firstMultiple.center : firstInput.center;
            var center = input.center = getCenter(pointers);
            input.timeStamp = now();
            input.deltaTime = input.timeStamp - firstInput.timeStamp;
            input.angle = getAngle(offsetCenter, center);
            input.distance = getDistance(offsetCenter, center);
            computeDeltaXY(session, input);
            input.offsetDirection = getDirection(input.deltaX, input.deltaY);
            var overallVelocity = getVelocity(input.deltaTime, input.deltaX, input.deltaY);
            input.overallVelocityX = overallVelocity.x;
            input.overallVelocityY = overallVelocity.y;
            input.overallVelocity = (abs(overallVelocity.x) > abs(overallVelocity.y)) ? overallVelocity.x : overallVelocity.y;
            input.scale = firstMultiple ? getScale(firstMultiple.pointers, pointers) : 1;
            input.rotation = firstMultiple ? getRotation(firstMultiple.pointers, pointers) : 0;
            input.maxPointers = !session.prevInput ? input.pointers.length : ((input.pointers.length >
                session.prevInput.maxPointers) ? input.pointers.length : session.prevInput.maxPointers);
            computeIntervalInputData(session, input);
            // find the correct target
            var target = manager.element;
            if (hasParent(input.srcEvent.target, target)) {
                target = input.srcEvent.target;
            }
            input.target = target;
        }
        function computeDeltaXY(session, input) {
            var center = input.center;
            var offset = session.offsetDelta || {};
            var prevDelta = session.prevDelta || {};
            var prevInput = session.prevInput || {};
            if (input.eventType === INPUT_START || prevInput.eventType === INPUT_END) {
                prevDelta = session.prevDelta = {
                    x: prevInput.deltaX || 0,
                    y: prevInput.deltaY || 0
                };
                offset = session.offsetDelta = {
                    x: center.x,
                    y: center.y
                };
            }
            input.deltaX = prevDelta.x + (center.x - offset.x);
            input.deltaY = prevDelta.y + (center.y - offset.y);
        }
        /**
         * velocity is calculated every x ms
         * @param {Object} session
         * @param {Object} input
         */
        function computeIntervalInputData(session, input) {
            var last = session.lastInterval || input, deltaTime = input.timeStamp - last.timeStamp, velocity, velocityX, velocityY, direction;
            if (input.eventType != INPUT_CANCEL && (deltaTime > COMPUTE_INTERVAL || last.velocity === undefined)) {
                var deltaX = input.deltaX - last.deltaX;
                var deltaY = input.deltaY - last.deltaY;
                var v = getVelocity(deltaTime, deltaX, deltaY);
                velocityX = v.x;
                velocityY = v.y;
                velocity = (abs(v.x) > abs(v.y)) ? v.x : v.y;
                direction = getDirection(deltaX, deltaY);
                session.lastInterval = input;
            }
            else {
                // use latest velocity info if it doesn't overtake a minimum period
                velocity = last.velocity;
                velocityX = last.velocityX;
                velocityY = last.velocityY;
                direction = last.direction;
            }
            input.velocity = velocity;
            input.velocityX = velocityX;
            input.velocityY = velocityY;
            input.direction = direction;
        }
        /**
         * create a simple clone from the input used for storage of firstInput and firstMultiple
         * @param {Object} input
         * @returns {Object} clonedInputData
         */
        function simpleCloneInputData(input) {
            // make a simple copy of the pointers because we will get a reference if we don't
            // we only need clientXY for the calculations
            var pointers = [];
            var i = 0;
            while (i < input.pointers.length) {
                pointers[i] = {
                    clientX: round(input.pointers[i].clientX),
                    clientY: round(input.pointers[i].clientY)
                };
                i++;
            }
            return {
                timeStamp: now(),
                pointers: pointers,
                center: getCenter(pointers),
                deltaX: input.deltaX,
                deltaY: input.deltaY
            };
        }
        /**
         * get the center of all the pointers
         * @param {Array} pointers
         * @return {Object} center contains `x` and `y` properties
         */
        function getCenter(pointers) {
            var pointersLength = pointers.length;
            // no need to loop when only one touch
            if (pointersLength === 1) {
                return {
                    x: round(pointers[0].clientX),
                    y: round(pointers[0].clientY)
                };
            }
            var x = 0, y = 0, i = 0;
            while (i < pointersLength) {
                x += pointers[i].clientX;
                y += pointers[i].clientY;
                i++;
            }
            return {
                x: round(x / pointersLength),
                y: round(y / pointersLength)
            };
        }
        /**
         * calculate the velocity between two points. unit is in px per ms.
         * @param {Number} deltaTime
         * @param {Number} x
         * @param {Number} y
         * @return {Object} velocity `x` and `y`
         */
        function getVelocity(deltaTime, x, y) {
            return {
                x: x / deltaTime || 0,
                y: y / deltaTime || 0
            };
        }
        /**
         * get the direction between two points
         * @param {Number} x
         * @param {Number} y
         * @return {Number} direction
         */
        function getDirection(x, y) {
            if (x === y) {
                return DIRECTION_NONE;
            }
            if (abs(x) >= abs(y)) {
                return x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
            }
            return y < 0 ? DIRECTION_UP : DIRECTION_DOWN;
        }
        /**
         * calculate the absolute distance between two points
         * @param {Object} p1 {x, y}
         * @param {Object} p2 {x, y}
         * @param {Array} [props] containing x and y keys
         * @return {Number} distance
         */
        function getDistance(p1, p2, props) {
            if (!props) {
                props = PROPS_XY;
            }
            var x = p2[props[0]] - p1[props[0]], y = p2[props[1]] - p1[props[1]];
            return Math.sqrt((x * x) + (y * y));
        }
        /**
         * calculate the angle between two coordinates
         * @param {Object} p1
         * @param {Object} p2
         * @param {Array} [props] containing x and y keys
         * @return {Number} angle
         */
        function getAngle(p1, p2, props) {
            if (!props) {
                props = PROPS_XY;
            }
            var x = p2[props[0]] - p1[props[0]], y = p2[props[1]] - p1[props[1]];
            return Math.atan2(y, x) * 180 / Math.PI;
        }
        /**
         * calculate the rotation degrees between two pointersets
         * @param {Array} start array of pointers
         * @param {Array} end array of pointers
         * @return {Number} rotation
         */
        function getRotation(start, end) {
            return getAngle(end[1], end[0], PROPS_CLIENT_XY) + getAngle(start[1], start[0], PROPS_CLIENT_XY);
        }
        /**
         * calculate the scale factor between two pointersets
         * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out
         * @param {Array} start array of pointers
         * @param {Array} end array of pointers
         * @return {Number} scale
         */
        function getScale(start, end) {
            return getDistance(end[0], end[1], PROPS_CLIENT_XY) / getDistance(start[0], start[1], PROPS_CLIENT_XY);
        }
        var MOUSE_INPUT_MAP = {
            mousedown: INPUT_START,
            mousemove: INPUT_MOVE,
            mouseup: INPUT_END
        };
        var MOUSE_ELEMENT_EVENTS = 'mousedown';
        var MOUSE_WINDOW_EVENTS = 'mousemove mouseup';
        /**
         * Mouse events input
         * @constructor
         * @extends Input
         */
        function MouseInput() {
            this.evEl = MOUSE_ELEMENT_EVENTS;
            this.evWin = MOUSE_WINDOW_EVENTS;
            this.pressed = false; // mousedown state
            Input.apply(this, arguments);
        }
        inherit(MouseInput, Input, {
            /**
             * handle mouse events
             * @param {Object} ev
             */
            handler: function MEhandler(ev) {
                var eventType = MOUSE_INPUT_MAP[ev.type];
                // on start we want to have the left mouse button down
                if (eventType & INPUT_START && ev.button === 0) {
                    this.pressed = true;
                }
                if (eventType & INPUT_MOVE && ev.which !== 1) {
                    eventType = INPUT_END;
                }
                // mouse must be down
                if (!this.pressed) {
                    return;
                }
                if (eventType & INPUT_END) {
                    this.pressed = false;
                }
                this.callback(this.manager, eventType, {
                    pointers: [ev],
                    changedPointers: [ev],
                    pointerType: INPUT_TYPE_MOUSE,
                    srcEvent: ev
                });
            }
        });
        var POINTER_INPUT_MAP = {
            pointerdown: INPUT_START,
            pointermove: INPUT_MOVE,
            pointerup: INPUT_END,
            pointercancel: INPUT_CANCEL,
            pointerout: INPUT_CANCEL
        };
        // in IE10 the pointer types is defined as an enum
        var IE10_POINTER_TYPE_ENUM = {
            2: INPUT_TYPE_TOUCH,
            3: INPUT_TYPE_PEN,
            4: INPUT_TYPE_MOUSE,
            5: INPUT_TYPE_KINECT // see https://twitter.com/jacobrossi/status/480596438489890816
        };
        var POINTER_ELEMENT_EVENTS = 'pointerdown';
        var POINTER_WINDOW_EVENTS = 'pointermove pointerup pointercancel';
        // IE10 has prefixed support, and case-sensitive
        if (window.MSPointerEvent && !window.PointerEvent) {
            POINTER_ELEMENT_EVENTS = 'MSPointerDown';
            POINTER_WINDOW_EVENTS = 'MSPointerMove MSPointerUp MSPointerCancel';
        }
        /**
         * Pointer events input
         * @constructor
         * @extends Input
         */
        function PointerEventInput() {
            this.evEl = POINTER_ELEMENT_EVENTS;
            this.evWin = POINTER_WINDOW_EVENTS;
            Input.apply(this, arguments);
            this.store = (this.manager.session.pointerEvents = []);
        }
        inherit(PointerEventInput, Input, {
            /**
             * handle mouse events
             * @param {Object} ev
             */
            handler: function PEhandler(ev) {
                var store = this.store;
                var removePointer = false;
                var eventTypeNormalized = ev.type.toLowerCase().replace('ms', '');
                var eventType = POINTER_INPUT_MAP[eventTypeNormalized];
                var pointerType = IE10_POINTER_TYPE_ENUM[ev.pointerType] || ev.pointerType;
                var isTouch = (pointerType == INPUT_TYPE_TOUCH);
                // get index of the event in the store
                var storeIndex = inArray(store, ev.pointerId, 'pointerId');
                // start and mouse must be down
                if (eventType & INPUT_START && (ev.button === 0 || isTouch)) {
                    if (storeIndex < 0) {
                        store.push(ev);
                        storeIndex = store.length - 1;
                    }
                }
                else if (eventType & (INPUT_END | INPUT_CANCEL)) {
                    removePointer = true;
                }
                // it not found, so the pointer hasn't been down (so it's probably a hover)
                if (storeIndex < 0) {
                    return;
                }
                // update the event in the store
                store[storeIndex] = ev;
                this.callback(this.manager, eventType, {
                    pointers: store,
                    changedPointers: [ev],
                    pointerType: pointerType,
                    srcEvent: ev
                });
                if (removePointer) {
                    // remove from the store
                    store.splice(storeIndex, 1);
                }
            }
        });
        var SINGLE_TOUCH_INPUT_MAP = {
            touchstart: INPUT_START,
            touchmove: INPUT_MOVE,
            touchend: INPUT_END,
            touchcancel: INPUT_CANCEL
        };
        var SINGLE_TOUCH_TARGET_EVENTS = 'touchstart';
        var SINGLE_TOUCH_WINDOW_EVENTS = 'touchstart touchmove touchend touchcancel';
        /**
         * Touch events input
         * @constructor
         * @extends Input
         */
        function SingleTouchInput() {
            this.evTarget = SINGLE_TOUCH_TARGET_EVENTS;
            this.evWin = SINGLE_TOUCH_WINDOW_EVENTS;
            this.started = false;
            Input.apply(this, arguments);
        }
        inherit(SingleTouchInput, Input, {
            handler: function TEhandler(ev) {
                var type = SINGLE_TOUCH_INPUT_MAP[ev.type];
                // should we handle the touch events?
                if (type === INPUT_START) {
                    this.started = true;
                }
                if (!this.started) {
                    return;
                }
                var touches = normalizeSingleTouches.call(this, ev, type);
                // when done, reset the started state
                if (type & (INPUT_END | INPUT_CANCEL) && touches[0].length - touches[1].length === 0) {
                    this.started = false;
                }
                this.callback(this.manager, type, {
                    pointers: touches[0],
                    changedPointers: touches[1],
                    pointerType: INPUT_TYPE_TOUCH,
                    srcEvent: ev
                });
            }
        });
        /**
         * @this {TouchInput}
         * @param {Object} ev
         * @param {Number} type flag
         * @returns {undefined|Array} [all, changed]
         */
        function normalizeSingleTouches(ev, type) {
            var all = toArray(ev.touches);
            var changed = toArray(ev.changedTouches);
            if (type & (INPUT_END | INPUT_CANCEL)) {
                all = uniqueArray(all.concat(changed), 'identifier', true);
            }
            return [all, changed];
        }
        var TOUCH_INPUT_MAP = {
            touchstart: INPUT_START,
            touchmove: INPUT_MOVE,
            touchend: INPUT_END,
            touchcancel: INPUT_CANCEL
        };
        var TOUCH_TARGET_EVENTS = 'touchstart touchmove touchend touchcancel';
        /**
         * Multi-user touch events input
         * @constructor
         * @extends Input
         */
        function TouchInput() {
            this.evTarget = TOUCH_TARGET_EVENTS;
            this.targetIds = {};
            Input.apply(this, arguments);
        }
        inherit(TouchInput, Input, {
            handler: function MTEhandler(ev) {
                var type = TOUCH_INPUT_MAP[ev.type];
                var touches = getTouches.call(this, ev, type);
                if (!touches) {
                    return;
                }
                this.callback(this.manager, type, {
                    pointers: touches[0],
                    changedPointers: touches[1],
                    pointerType: INPUT_TYPE_TOUCH,
                    srcEvent: ev
                });
            }
        });
        /**
         * @this {TouchInput}
         * @param {Object} ev
         * @param {Number} type flag
         * @returns {undefined|Array} [all, changed]
         */
        function getTouches(ev, type) {
            var allTouches = toArray(ev.touches);
            var targetIds = this.targetIds;
            // when there is only one touch, the process can be simplified
            if (type & (INPUT_START | INPUT_MOVE) && allTouches.length === 1) {
                targetIds[allTouches[0].identifier] = true;
                return [allTouches, allTouches];
            }
            var i, targetTouches, changedTouches = toArray(ev.changedTouches), changedTargetTouches = [], target = this.target;
            // get target touches from touches
            targetTouches = allTouches.filter(function (touch) {
                return hasParent(touch.target, target);
            });
            // collect touches
            if (type === INPUT_START) {
                i = 0;
                while (i < targetTouches.length) {
                    targetIds[targetTouches[i].identifier] = true;
                    i++;
                }
            }
            // filter changed touches to only contain touches that exist in the collected target ids
            i = 0;
            while (i < changedTouches.length) {
                if (targetIds[changedTouches[i].identifier]) {
                    changedTargetTouches.push(changedTouches[i]);
                }
                // cleanup removed touches
                if (type & (INPUT_END | INPUT_CANCEL)) {
                    delete targetIds[changedTouches[i].identifier];
                }
                i++;
            }
            if (!changedTargetTouches.length) {
                return;
            }
            return [
                // merge targetTouches with changedTargetTouches so it contains ALL touches, including 'end' and 'cancel'
                uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true),
                changedTargetTouches
            ];
        }
        /**
         * Combined touch and mouse input
         *
         * Touch has a higher priority then mouse, and while touching no mouse events are allowed.
         * This because touch devices also emit mouse events while doing a touch.
         *
         * @constructor
         * @extends Input
         */
        var DEDUP_TIMEOUT = 2500;
        var DEDUP_DISTANCE = 25;
        function TouchMouseInput() {
            Input.apply(this, arguments);
            var handler = bindFn(this.handler, this);
            this.touch = new TouchInput(this.manager, handler);
            this.mouse = new MouseInput(this.manager, handler);
            this.primaryTouch = null;
            this.lastTouches = [];
        }
        inherit(TouchMouseInput, Input, {
            /**
             * handle mouse and touch events
             * @param {Hammer} manager
             * @param {String} inputEvent
             * @param {Object} inputData
             */
            handler: function TMEhandler(manager, inputEvent, inputData) {
                var isTouch = (inputData.pointerType == INPUT_TYPE_TOUCH), isMouse = (inputData.pointerType == INPUT_TYPE_MOUSE);
                if (isMouse && inputData.sourceCapabilities && inputData.sourceCapabilities.firesTouchEvents) {
                    return;
                }
                // when we're in a touch event, record touches to  de-dupe synthetic mouse event
                if (isTouch) {
                    recordTouches.call(this, inputEvent, inputData);
                }
                else if (isMouse && isSyntheticEvent.call(this, inputData)) {
                    return;
                }
                this.callback(manager, inputEvent, inputData);
            },
            /**
             * remove the event listeners
             */
            destroy: function destroy() {
                this.touch.destroy();
                this.mouse.destroy();
            }
        });
        function recordTouches(eventType, eventData) {
            if (eventType & INPUT_START) {
                this.primaryTouch = eventData.changedPointers[0].identifier;
                setLastTouch.call(this, eventData);
            }
            else if (eventType & (INPUT_END | INPUT_CANCEL)) {
                setLastTouch.call(this, eventData);
            }
        }
        function setLastTouch(eventData) {
            var touch = eventData.changedPointers[0];
            if (touch.identifier === this.primaryTouch) {
                var lastTouch = { x: touch.clientX, y: touch.clientY };
                this.lastTouches.push(lastTouch);
                var lts = this.lastTouches;
                var removeLastTouch = function () {
                    var i = lts.indexOf(lastTouch);
                    if (i > -1) {
                        lts.splice(i, 1);
                    }
                };
                setTimeout(removeLastTouch, DEDUP_TIMEOUT);
            }
        }
        function isSyntheticEvent(eventData) {
            var x = eventData.srcEvent.clientX, y = eventData.srcEvent.clientY;
            for (var i = 0; i < this.lastTouches.length; i++) {
                var t = this.lastTouches[i];
                var dx = Math.abs(x - t.x), dy = Math.abs(y - t.y);
                if (dx <= DEDUP_DISTANCE && dy <= DEDUP_DISTANCE) {
                    return true;
                }
            }
            return false;
        }
        var PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction');
        var NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined;
        // magical touchAction value
        var TOUCH_ACTION_COMPUTE = 'compute';
        var TOUCH_ACTION_AUTO = 'auto';
        var TOUCH_ACTION_MANIPULATION = 'manipulation'; // not implemented
        var TOUCH_ACTION_NONE = 'none';
        var TOUCH_ACTION_PAN_X = 'pan-x';
        var TOUCH_ACTION_PAN_Y = 'pan-y';
        var TOUCH_ACTION_MAP = getTouchActionProps();
        /**
         * Touch Action
         * sets the touchAction property or uses the js alternative
         * @param {Manager} manager
         * @param {String} value
         * @constructor
         */
        function TouchAction(manager, value) {
            this.manager = manager;
            this.set(value);
        }
        TouchAction.prototype = {
            /**
             * set the touchAction value on the element or enable the polyfill
             * @param {String} value
             */
            set: function (value) {
                // find out the touch-action by the event handlers
                if (value == TOUCH_ACTION_COMPUTE) {
                    value = this.compute();
                }
                if (NATIVE_TOUCH_ACTION && this.manager.element.style && TOUCH_ACTION_MAP[value]) {
                    this.manager.element.style[PREFIXED_TOUCH_ACTION] = value;
                }
                this.actions = value.toLowerCase().trim();
            },
            /**
             * just re-set the touchAction value
             */
            update: function () {
                this.set(this.manager.options.touchAction);
            },
            /**
             * compute the value for the touchAction property based on the recognizer's settings
             * @returns {String} value
             */
            compute: function () {
                var actions = [];
                each(this.manager.recognizers, function (recognizer) {
                    if (boolOrFn(recognizer.options.enable, [recognizer])) {
                        actions = actions.concat(recognizer.getTouchAction());
                    }
                });
                return cleanTouchActions(actions.join(' '));
            },
            /**
             * this method is called on each input cycle and provides the preventing of the browser behavior
             * @param {Object} input
             */
            preventDefaults: function (input) {
                var srcEvent = input.srcEvent;
                var direction = input.offsetDirection;
                // if the touch action did prevented once this session
                if (this.manager.session.prevented) {
                    srcEvent.preventDefault();
                    return;
                }
                var actions = this.actions;
                var hasNone = inStr(actions, TOUCH_ACTION_NONE) && !TOUCH_ACTION_MAP[TOUCH_ACTION_NONE];
                var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_Y];
                var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_X];
                if (hasNone) {
                    //do not prevent defaults if this is a tap gesture
                    var isTapPointer = input.pointers.length === 1;
                    var isTapMovement = input.distance < 2;
                    var isTapTouchTime = input.deltaTime < 250;
                    if (isTapPointer && isTapMovement && isTapTouchTime) {
                        return;
                    }
                }
                if (hasPanX && hasPanY) {
                    // `pan-x pan-y` means browser handles all scrolling/panning, do not prevent
                    return;
                }
                if (hasNone ||
                    (hasPanY && direction & DIRECTION_HORIZONTAL) ||
                    (hasPanX && direction & DIRECTION_VERTICAL)) {
                    return this.preventSrc(srcEvent);
                }
            },
            /**
             * call preventDefault to prevent the browser's default behavior (scrolling in most cases)
             * @param {Object} srcEvent
             */
            preventSrc: function (srcEvent) {
                this.manager.session.prevented = true;
                srcEvent.preventDefault();
            }
        };
        /**
         * when the touchActions are collected they are not a valid value, so we need to clean things up. *
         * @param {String} actions
         * @returns {*}
         */
        function cleanTouchActions(actions) {
            // none
            if (inStr(actions, TOUCH_ACTION_NONE)) {
                return TOUCH_ACTION_NONE;
            }
            var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X);
            var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y);
            // if both pan-x and pan-y are set (different recognizers
            // for different directions, e.g. horizontal pan but vertical swipe?)
            // we need none (as otherwise with pan-x pan-y combined none of these
            // recognizers will work, since the browser would handle all panning
            if (hasPanX && hasPanY) {
                return TOUCH_ACTION_NONE;
            }
            // pan-x OR pan-y
            if (hasPanX || hasPanY) {
                return hasPanX ? TOUCH_ACTION_PAN_X : TOUCH_ACTION_PAN_Y;
            }
            // manipulation
            if (inStr(actions, TOUCH_ACTION_MANIPULATION)) {
                return TOUCH_ACTION_MANIPULATION;
            }
            return TOUCH_ACTION_AUTO;
        }
        function getTouchActionProps() {
            if (!NATIVE_TOUCH_ACTION) {
                return false;
            }
            var touchMap = {};
            var cssSupports = window.CSS && window.CSS.supports;
            ['auto', 'manipulation', 'pan-y', 'pan-x', 'pan-x pan-y', 'none'].forEach(function (val) {
                // If css.supports is not supported but there is native touch-action assume it supports
                // all values. This is the case for IE 10 and 11.
                touchMap[val] = cssSupports ? window.CSS.supports('touch-action', val) : true;
            });
            return touchMap;
        }
        /**
         * Recognizer flow explained; *
         * All recognizers have the initial state of POSSIBLE when a input session starts.
         * The definition of a input session is from the first input until the last input, with all it's movement in it. *
         * Example session for mouse-input: mousedown -> mousemove -> mouseup
         *
         * On each recognizing cycle (see Manager.recognize) the .recognize() method is executed
         * which determines with state it should be.
         *
         * If the recognizer has the state FAILED, CANCELLED or RECOGNIZED (equals ENDED), it is reset to
         * POSSIBLE to give it another change on the next cycle.
         *
         *               Possible
         *                  |
         *            +-----+---------------+
         *            |                     |
         *      +-----+-----+               |
         *      |           |               |
         *   Failed      Cancelled          |
         *                          +-------+------+
         *                          |              |
         *                      Recognized       Began
         *                                         |
         *                                      Changed
         *                                         |
         *                                  Ended/Recognized
         */
        var STATE_POSSIBLE = 1;
        var STATE_BEGAN = 2;
        var STATE_CHANGED = 4;
        var STATE_ENDED = 8;
        var STATE_RECOGNIZED = STATE_ENDED;
        var STATE_CANCELLED = 16;
        var STATE_FAILED = 32;
        /**
         * Recognizer
         * Every recognizer needs to extend from this class.
         * @constructor
         * @param {Object} options
         */
        function Recognizer(options) {
            this.options = assign({}, this.defaults, options || {});
            this.id = uniqueId();
            this.manager = null;
            // default is enable true
            this.options.enable = ifUndefined(this.options.enable, true);
            this.state = STATE_POSSIBLE;
            this.simultaneous = {};
            this.requireFail = [];
        }
        Recognizer.prototype = {
            /**
             * @virtual
             * @type {Object}
             */
            defaults: {},
            /**
             * set options
             * @param {Object} options
             * @return {Recognizer}
             */
            set: function (options) {
                assign(this.options, options);
                // also update the touchAction, in case something changed about the directions/enabled state
                this.manager && this.manager.touchAction.update();
                return this;
            },
            /**
             * recognize simultaneous with an other recognizer.
             * @param {Recognizer} otherRecognizer
             * @returns {Recognizer} this
             */
            recognizeWith: function (otherRecognizer) {
                if (invokeArrayArg(otherRecognizer, 'recognizeWith', this)) {
                    return this;
                }
                var simultaneous = this.simultaneous;
                otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
                if (!simultaneous[otherRecognizer.id]) {
                    simultaneous[otherRecognizer.id] = otherRecognizer;
                    otherRecognizer.recognizeWith(this);
                }
                return this;
            },
            /**
             * drop the simultaneous link. it doesnt remove the link on the other recognizer.
             * @param {Recognizer} otherRecognizer
             * @returns {Recognizer} this
             */
            dropRecognizeWith: function (otherRecognizer) {
                if (invokeArrayArg(otherRecognizer, 'dropRecognizeWith', this)) {
                    return this;
                }
                otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
                delete this.simultaneous[otherRecognizer.id];
                return this;
            },
            /**
             * recognizer can only run when an other is failing
             * @param {Recognizer} otherRecognizer
             * @returns {Recognizer} this
             */
            requireFailure: function (otherRecognizer) {
                if (invokeArrayArg(otherRecognizer, 'requireFailure', this)) {
                    return this;
                }
                var requireFail = this.requireFail;
                otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
                if (inArray(requireFail, otherRecognizer) === -1) {
                    requireFail.push(otherRecognizer);
                    otherRecognizer.requireFailure(this);
                }
                return this;
            },
            /**
             * drop the requireFailure link. it does not remove the link on the other recognizer.
             * @param {Recognizer} otherRecognizer
             * @returns {Recognizer} this
             */
            dropRequireFailure: function (otherRecognizer) {
                if (invokeArrayArg(otherRecognizer, 'dropRequireFailure', this)) {
                    return this;
                }
                otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
                var index = inArray(this.requireFail, otherRecognizer);
                if (index > -1) {
                    this.requireFail.splice(index, 1);
                }
                return this;
            },
            /**
             * has require failures boolean
             * @returns {boolean}
             */
            hasRequireFailures: function () {
                return this.requireFail.length > 0;
            },
            /**
             * if the recognizer can recognize simultaneous with an other recognizer
             * @param {Recognizer} otherRecognizer
             * @returns {Boolean}
             */
            canRecognizeWith: function (otherRecognizer) {
                return !!this.simultaneous[otherRecognizer.id];
            },
            /**
             * You should use `tryEmit` instead of `emit` directly to check
             * that all the needed recognizers has failed before emitting.
             * @param {Object} input
             */
            emit: function (input) {
                var self = this;
                var state = this.state;
                function emit(event) {
                    self.manager.emit(event, input);
                }
                // 'panstart' and 'panmove'
                if (state < STATE_ENDED) {
                    emit(self.options.event + stateStr(state));
                }
                emit(self.options.event); // simple 'eventName' events
                if (input.additionalEvent) { // additional event(panleft, panright, pinchin, pinchout...)
                    emit(input.additionalEvent);
                }
                // panend and pancancel
                if (state >= STATE_ENDED) {
                    emit(self.options.event + stateStr(state));
                }
            },
            /**
             * Check that all the require failure recognizers has failed,
             * if true, it emits a gesture event,
             * otherwise, setup the state to FAILED.
             * @param {Object} input
             */
            tryEmit: function (input) {
                if (this.canEmit()) {
                    return this.emit(input);
                }
                // it's failing anyway
                this.state = STATE_FAILED;
            },
            /**
             * can we emit?
             * @returns {boolean}
             */
            canEmit: function () {
                var i = 0;
                while (i < this.requireFail.length) {
                    if (!(this.requireFail[i].state & (STATE_FAILED | STATE_POSSIBLE))) {
                        return false;
                    }
                    i++;
                }
                return true;
            },
            /**
             * update the recognizer
             * @param {Object} inputData
             */
            recognize: function (inputData) {
                // make a new copy of the inputData
                // so we can change the inputData without messing up the other recognizers
                var inputDataClone = assign({}, inputData);
                // is is enabled and allow recognizing?
                if (!boolOrFn(this.options.enable, [this, inputDataClone])) {
                    this.reset();
                    this.state = STATE_FAILED;
                    return;
                }
                // reset when we've reached the end
                if (this.state & (STATE_RECOGNIZED | STATE_CANCELLED | STATE_FAILED)) {
                    this.state = STATE_POSSIBLE;
                }
                this.state = this.process(inputDataClone);
                // the recognizer has recognized a gesture
                // so trigger an event
                if (this.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED | STATE_CANCELLED)) {
                    this.tryEmit(inputDataClone);
                }
            },
            /**
             * return the state of the recognizer
             * the actual recognizing happens in this method
             * @virtual
             * @param {Object} inputData
             * @returns {Const} STATE
             */
            process: function (inputData) { },
            /**
             * return the preferred touch-action
             * @virtual
             * @returns {Array}
             */
            getTouchAction: function () { },
            /**
             * called when the gesture isn't allowed to recognize
             * like when another is being recognized or it is disabled
             * @virtual
             */
            reset: function () { }
        };
        /**
         * get a usable string, used as event postfix
         * @param {Const} state
         * @returns {String} state
         */
        function stateStr(state) {
            if (state & STATE_CANCELLED) {
                return 'cancel';
            }
            else if (state & STATE_ENDED) {
                return 'end';
            }
            else if (state & STATE_CHANGED) {
                return 'move';
            }
            else if (state & STATE_BEGAN) {
                return 'start';
            }
            return '';
        }
        /**
         * direction cons to string
         * @param {Const} direction
         * @returns {String}
         */
        function directionStr(direction) {
            if (direction == DIRECTION_DOWN) {
                return 'down';
            }
            else if (direction == DIRECTION_UP) {
                return 'up';
            }
            else if (direction == DIRECTION_LEFT) {
                return 'left';
            }
            else if (direction == DIRECTION_RIGHT) {
                return 'right';
            }
            return '';
        }
        /**
         * get a recognizer by name if it is bound to a manager
         * @param {Recognizer|String} otherRecognizer
         * @param {Recognizer} recognizer
         * @returns {Recognizer}
         */
        function getRecognizerByNameIfManager(otherRecognizer, recognizer) {
            var manager = recognizer.manager;
            if (manager) {
                return manager.get(otherRecognizer);
            }
            return otherRecognizer;
        }
        /**
         * This recognizer is just used as a base for the simple attribute recognizers.
         * @constructor
         * @extends Recognizer
         */
        function AttrRecognizer() {
            Recognizer.apply(this, arguments);
        }
        inherit(AttrRecognizer, Recognizer, {
            /**
             * @namespace
             * @memberof AttrRecognizer
             */
            defaults: {
                /**
                 * @type {Number}
                 * @default 1
                 */
                pointers: 1
            },
            /**
             * Used to check if it the recognizer receives valid input, like input.distance > 10.
             * @memberof AttrRecognizer
             * @param {Object} input
             * @returns {Boolean} recognized
             */
            attrTest: function (input) {
                var optionPointers = this.options.pointers;
                return optionPointers === 0 || input.pointers.length === optionPointers;
            },
            /**
             * Process the input and return the state for the recognizer
             * @memberof AttrRecognizer
             * @param {Object} input
             * @returns {*} State
             */
            process: function (input) {
                var state = this.state;
                var eventType = input.eventType;
                var isRecognized = state & (STATE_BEGAN | STATE_CHANGED);
                var isValid = this.attrTest(input);
                // on cancel input and we've recognized before, return STATE_CANCELLED
                if (isRecognized && (eventType & INPUT_CANCEL || !isValid)) {
                    return state | STATE_CANCELLED;
                }
                else if (isRecognized || isValid) {
                    if (eventType & INPUT_END) {
                        return state | STATE_ENDED;
                    }
                    else if (!(state & STATE_BEGAN)) {
                        return STATE_BEGAN;
                    }
                    return state | STATE_CHANGED;
                }
                return STATE_FAILED;
            }
        });
        /**
         * Pan
         * Recognized when the pointer is down and moved in the allowed direction.
         * @constructor
         * @extends AttrRecognizer
         */
        function PanRecognizer() {
            AttrRecognizer.apply(this, arguments);
            this.pX = null;
            this.pY = null;
        }
        inherit(PanRecognizer, AttrRecognizer, {
            /**
             * @namespace
             * @memberof PanRecognizer
             */
            defaults: {
                event: 'pan',
                threshold: 10,
                pointers: 1,
                direction: DIRECTION_ALL
            },
            getTouchAction: function () {
                var direction = this.options.direction;
                var actions = [];
                if (direction & DIRECTION_HORIZONTAL) {
                    actions.push(TOUCH_ACTION_PAN_Y);
                }
                if (direction & DIRECTION_VERTICAL) {
                    actions.push(TOUCH_ACTION_PAN_X);
                }
                return actions;
            },
            directionTest: function (input) {
                var options = this.options;
                var hasMoved = true;
                var distance = input.distance;
                var direction = input.direction;
                var x = input.deltaX;
                var y = input.deltaY;
                // lock to axis?
                if (!(direction & options.direction)) {
                    if (options.direction & DIRECTION_HORIZONTAL) {
                        direction = (x === 0) ? DIRECTION_NONE : (x < 0) ? DIRECTION_LEFT : DIRECTION_RIGHT;
                        hasMoved = x != this.pX;
                        distance = Math.abs(input.deltaX);
                    }
                    else {
                        direction = (y === 0) ? DIRECTION_NONE : (y < 0) ? DIRECTION_UP : DIRECTION_DOWN;
                        hasMoved = y != this.pY;
                        distance = Math.abs(input.deltaY);
                    }
                }
                input.direction = direction;
                return hasMoved && distance > options.threshold && direction & options.direction;
            },
            attrTest: function (input) {
                return AttrRecognizer.prototype.attrTest.call(this, input) &&
                    (this.state & STATE_BEGAN || (!(this.state & STATE_BEGAN) && this.directionTest(input)));
            },
            emit: function (input) {
                this.pX = input.deltaX;
                this.pY = input.deltaY;
                var direction = directionStr(input.direction);
                if (direction) {
                    input.additionalEvent = this.options.event + direction;
                }
                this._super.emit.call(this, input);
            }
        });
        /**
         * Pinch
         * Recognized when two or more pointers are moving toward (zoom-in) or away from each other (zoom-out).
         * @constructor
         * @extends AttrRecognizer
         */
        function PinchRecognizer() {
            AttrRecognizer.apply(this, arguments);
        }
        inherit(PinchRecognizer, AttrRecognizer, {
            /**
             * @namespace
             * @memberof PinchRecognizer
             */
            defaults: {
                event: 'pinch',
                threshold: 0,
                pointers: 2
            },
            getTouchAction: function () {
                return [TOUCH_ACTION_NONE];
            },
            attrTest: function (input) {
                return this._super.attrTest.call(this, input) &&
                    (Math.abs(input.scale - 1) > this.options.threshold || this.state & STATE_BEGAN);
            },
            emit: function (input) {
                if (input.scale !== 1) {
                    var inOut = input.scale < 1 ? 'in' : 'out';
                    input.additionalEvent = this.options.event + inOut;
                }
                this._super.emit.call(this, input);
            }
        });
        /**
         * Press
         * Recognized when the pointer is down for x ms without any movement.
         * @constructor
         * @extends Recognizer
         */
        function PressRecognizer() {
            Recognizer.apply(this, arguments);
            this._timer = null;
            this._input = null;
        }
        inherit(PressRecognizer, Recognizer, {
            /**
             * @namespace
             * @memberof PressRecognizer
             */
            defaults: {
                event: 'press',
                pointers: 1,
                time: 251,
                threshold: 9 // a minimal movement is ok, but keep it low
            },
            getTouchAction: function () {
                return [TOUCH_ACTION_AUTO];
            },
            process: function (input) {
                var options = this.options;
                var validPointers = input.pointers.length === options.pointers;
                var validMovement = input.distance < options.threshold;
                var validTime = input.deltaTime > options.time;
                this._input = input;
                // we only allow little movement
                // and we've reached an end event, so a tap is possible
                if (!validMovement || !validPointers || (input.eventType & (INPUT_END | INPUT_CANCEL) && !validTime)) {
                    this.reset();
                }
                else if (input.eventType & INPUT_START) {
                    this.reset();
                    this._timer = setTimeoutContext(function () {
                        this.state = STATE_RECOGNIZED;
                        this.tryEmit();
                    }, options.time, this);
                }
                else if (input.eventType & INPUT_END) {
                    return STATE_RECOGNIZED;
                }
                return STATE_FAILED;
            },
            reset: function () {
                clearTimeout(this._timer);
            },
            emit: function (input) {
                if (this.state !== STATE_RECOGNIZED) {
                    return;
                }
                if (input && (input.eventType & INPUT_END)) {
                    this.manager.emit(this.options.event + 'up', input);
                }
                else {
                    this._input.timeStamp = now();
                    this.manager.emit(this.options.event, this._input);
                }
            }
        });
        /**
         * Rotate
         * Recognized when two or more pointer are moving in a circular motion.
         * @constructor
         * @extends AttrRecognizer
         */
        function RotateRecognizer() {
            AttrRecognizer.apply(this, arguments);
        }
        inherit(RotateRecognizer, AttrRecognizer, {
            /**
             * @namespace
             * @memberof RotateRecognizer
             */
            defaults: {
                event: 'rotate',
                threshold: 0,
                pointers: 2
            },
            getTouchAction: function () {
                return [TOUCH_ACTION_NONE];
            },
            attrTest: function (input) {
                return this._super.attrTest.call(this, input) &&
                    (Math.abs(input.rotation) > this.options.threshold || this.state & STATE_BEGAN);
            }
        });
        /**
         * Swipe
         * Recognized when the pointer is moving fast (velocity), with enough distance in the allowed direction.
         * @constructor
         * @extends AttrRecognizer
         */
        function SwipeRecognizer() {
            AttrRecognizer.apply(this, arguments);
        }
        inherit(SwipeRecognizer, AttrRecognizer, {
            /**
             * @namespace
             * @memberof SwipeRecognizer
             */
            defaults: {
                event: 'swipe',
                threshold: 10,
                velocity: 0.3,
                direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL,
                pointers: 1
            },
            getTouchAction: function () {
                return PanRecognizer.prototype.getTouchAction.call(this);
            },
            attrTest: function (input) {
                var direction = this.options.direction;
                var velocity;
                if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) {
                    velocity = input.overallVelocity;
                }
                else if (direction & DIRECTION_HORIZONTAL) {
                    velocity = input.overallVelocityX;
                }
                else if (direction & DIRECTION_VERTICAL) {
                    velocity = input.overallVelocityY;
                }
                return this._super.attrTest.call(this, input) &&
                    direction & input.offsetDirection &&
                    input.distance > this.options.threshold &&
                    input.maxPointers == this.options.pointers &&
                    abs(velocity) > this.options.velocity && input.eventType & INPUT_END;
            },
            emit: function (input) {
                var direction = directionStr(input.offsetDirection);
                if (direction) {
                    this.manager.emit(this.options.event + direction, input);
                }
                this.manager.emit(this.options.event, input);
            }
        });
        /**
         * A tap is ecognized when the pointer is doing a small tap/click. Multiple taps are recognized if they occur
         * between the given interval and position. The delay option can be used to recognize multi-taps without firing
         * a single tap.
         *
         * The eventData from the emitted event contains the property `tapCount`, which contains the amount of
         * multi-taps being recognized.
         * @constructor
         * @extends Recognizer
         */
        function TapRecognizer() {
            Recognizer.apply(this, arguments);
            // previous time and center,
            // used for tap counting
            this.pTime = false;
            this.pCenter = false;
            this._timer = null;
            this._input = null;
            this.count = 0;
        }
        inherit(TapRecognizer, Recognizer, {
            /**
             * @namespace
             * @memberof PinchRecognizer
             */
            defaults: {
                event: 'tap',
                pointers: 1,
                taps: 1,
                interval: 300,
                time: 250,
                threshold: 9,
                posThreshold: 10 // a multi-tap can be a bit off the initial position
            },
            getTouchAction: function () {
                return [TOUCH_ACTION_MANIPULATION];
            },
            process: function (input) {
                var options = this.options;
                var validPointers = input.pointers.length === options.pointers;
                var validMovement = input.distance < options.threshold;
                var validTouchTime = input.deltaTime < options.time;
                this.reset();
                if ((input.eventType & INPUT_START) && (this.count === 0)) {
                    return this.failTimeout();
                }
                // we only allow little movement
                // and we've reached an end event, so a tap is possible
                if (validMovement && validTouchTime && validPointers) {
                    if (input.eventType != INPUT_END) {
                        return this.failTimeout();
                    }
                    var validInterval = this.pTime ? (input.timeStamp - this.pTime < options.interval) : true;
                    var validMultiTap = !this.pCenter || getDistance(this.pCenter, input.center) < options.posThreshold;
                    this.pTime = input.timeStamp;
                    this.pCenter = input.center;
                    if (!validMultiTap || !validInterval) {
                        this.count = 1;
                    }
                    else {
                        this.count += 1;
                    }
                    this._input = input;
                    // if tap count matches we have recognized it,
                    // else it has began recognizing...
                    var tapCount = this.count % options.taps;
                    if (tapCount === 0) {
                        // no failing requirements, immediately trigger the tap event
                        // or wait as long as the multitap interval to trigger
                        if (!this.hasRequireFailures()) {
                            return STATE_RECOGNIZED;
                        }
                        else {
                            this._timer = setTimeoutContext(function () {
                                this.state = STATE_RECOGNIZED;
                                this.tryEmit();
                            }, options.interval, this);
                            return STATE_BEGAN;
                        }
                    }
                }
                return STATE_FAILED;
            },
            failTimeout: function () {
                this._timer = setTimeoutContext(function () {
                    this.state = STATE_FAILED;
                }, this.options.interval, this);
                return STATE_FAILED;
            },
            reset: function () {
                clearTimeout(this._timer);
            },
            emit: function () {
                if (this.state == STATE_RECOGNIZED) {
                    this._input.tapCount = this.count;
                    this.manager.emit(this.options.event, this._input);
                }
            }
        });
        /**
         * Simple way to create a manager with a default set of recognizers.
         * @param {HTMLElement} element
         * @param {Object} [options]
         * @constructor
         */
        function Hammer(element, options) {
            options = options || {};
            options.recognizers = ifUndefined(options.recognizers, Hammer.defaults.preset);
            return new Manager(element, options);
        }
        /**
         * @const {string}
         */
        Hammer.VERSION = '2.0.7';
        /**
         * default settings
         * @namespace
         */
        Hammer.defaults = {
            /**
             * set if DOM events are being triggered.
             * But this is slower and unused by simple implementations, so disabled by default.
             * @type {Boolean}
             * @default false
             */
            domEvents: false,
            /**
             * The value for the touchAction property/fallback.
             * When set to `compute` it will magically set the correct value based on the added recognizers.
             * @type {String}
             * @default compute
             */
            touchAction: TOUCH_ACTION_COMPUTE,
            /**
             * @type {Boolean}
             * @default true
             */
            enable: true,
            /**
             * EXPERIMENTAL FEATURE -- can be removed/changed
             * Change the parent input target element.
             * If Null, then it is being set the to main element.
             * @type {Null|EventTarget}
             * @default null
             */
            inputTarget: null,
            /**
             * force an input class
             * @type {Null|Function}
             * @default null
             */
            inputClass: null,
            /**
             * Default recognizer setup when calling `Hammer()`
             * When creating a new Manager these will be skipped.
             * @type {Array}
             */
            preset: [
                // RecognizerClass, options, [recognizeWith, ...], [requireFailure, ...]
                [RotateRecognizer, { enable: false }],
                [PinchRecognizer, { enable: false }, ['rotate']],
                [SwipeRecognizer, { direction: DIRECTION_HORIZONTAL }],
                [PanRecognizer, { direction: DIRECTION_HORIZONTAL }, ['swipe']],
                [TapRecognizer],
                [TapRecognizer, { event: 'doubletap', taps: 2 }, ['tap']],
                [PressRecognizer]
            ],
            /**
             * Some CSS properties can be used to improve the working of Hammer.
             * Add them to this method and they will be set when creating a new Manager.
             * @namespace
             */
            cssProps: {
                /**
                 * Disables text selection to improve the dragging gesture. Mainly for desktop browsers.
                 * @type {String}
                 * @default 'none'
                 */
                userSelect: 'none',
                /**
                 * Disable the Windows Phone grippers when pressing an element.
                 * @type {String}
                 * @default 'none'
                 */
                touchSelect: 'none',
                /**
                 * Disables the default callout shown when you touch and hold a touch target.
                 * On iOS, when you touch and hold a touch target such as a link, Safari displays
                 * a callout containing information about the link. This property allows you to disable that callout.
                 * @type {String}
                 * @default 'none'
                 */
                touchCallout: 'none',
                /**
                 * Specifies whether zooming is enabled. Used by IE10>
                 * @type {String}
                 * @default 'none'
                 */
                contentZooming: 'none',
                /**
                 * Specifies that an entire element should be draggable instead of its contents. Mainly for desktop browsers.
                 * @type {String}
                 * @default 'none'
                 */
                userDrag: 'none',
                /**
                 * Overrides the highlight color shown when the user taps a link or a JavaScript
                 * clickable element in iOS. This property obeys the alpha value, if specified.
                 * @type {String}
                 * @default 'rgba(0,0,0,0)'
                 */
                tapHighlightColor: 'rgba(0,0,0,0)'
            }
        };
        var STOP = 1;
        var FORCED_STOP = 2;
        /**
         * Manager
         * @param {HTMLElement} element
         * @param {Object} [options]
         * @constructor
         */
        function Manager(element, options) {
            this.options = assign({}, Hammer.defaults, options || {});
            this.options.inputTarget = this.options.inputTarget || element;
            this.handlers = {};
            this.session = {};
            this.recognizers = [];
            this.oldCssProps = {};
            this.element = element;
            this.input = createInputInstance(this);
            this.touchAction = new TouchAction(this, this.options.touchAction);
            toggleCssProps(this, true);
            each(this.options.recognizers, function (item) {
                var recognizer = this.add(new (item[0])(item[1]));
                item[2] && recognizer.recognizeWith(item[2]);
                item[3] && recognizer.requireFailure(item[3]);
            }, this);
        }
        Manager.prototype = {
            /**
             * set options
             * @param {Object} options
             * @returns {Manager}
             */
            set: function (options) {
                assign(this.options, options);
                // Options that need a little more setup
                if (options.touchAction) {
                    this.touchAction.update();
                }
                if (options.inputTarget) {
                    // Clean up existing event listeners and reinitialize
                    this.input.destroy();
                    this.input.target = options.inputTarget;
                    this.input.init();
                }
                return this;
            },
            /**
             * stop recognizing for this session.
             * This session will be discarded, when a new [input]start event is fired.
             * When forced, the recognizer cycle is stopped immediately.
             * @param {Boolean} [force]
             */
            stop: function (force) {
                this.session.stopped = force ? FORCED_STOP : STOP;
            },
            /**
             * run the recognizers!
             * called by the inputHandler function on every movement of the pointers (touches)
             * it walks through all the recognizers and tries to detect the gesture that is being made
             * @param {Object} inputData
             */
            recognize: function (inputData) {
                var session = this.session;
                if (session.stopped) {
                    return;
                }
                // run the touch-action polyfill
                this.touchAction.preventDefaults(inputData);
                var recognizer;
                var recognizers = this.recognizers;
                // this holds the recognizer that is being recognized.
                // so the recognizer's state needs to be BEGAN, CHANGED, ENDED or RECOGNIZED
                // if no recognizer is detecting a thing, it is set to `null`
                var curRecognizer = session.curRecognizer;
                // reset when the last recognizer is recognized
                // or when we're in a new session
                if (!curRecognizer || (curRecognizer && curRecognizer.state & STATE_RECOGNIZED)) {
                    curRecognizer = session.curRecognizer = null;
                }
                var i = 0;
                while (i < recognizers.length) {
                    recognizer = recognizers[i];
                    // find out if we are allowed try to recognize the input for this one.
                    // 1.   allow if the session is NOT forced stopped (see the .stop() method)
                    // 2.   allow if we still haven't recognized a gesture in this session, or the this recognizer is the one
                    //      that is being recognized.
                    // 3.   allow if the recognizer is allowed to run simultaneous with the current recognized recognizer.
                    //      this can be setup with the `recognizeWith()` method on the recognizer.
                    if (session.stopped !== FORCED_STOP && ( // 1
                    !curRecognizer || recognizer == curRecognizer || // 2
                        recognizer.canRecognizeWith(curRecognizer))) { // 3
                        recognizer.recognize(inputData);
                    }
                    else {
                        recognizer.reset();
                    }
                    // if the recognizer has been recognizing the input as a valid gesture, we want to store this one as the
                    // current active recognizer. but only if we don't already have an active recognizer
                    if (!curRecognizer && recognizer.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED)) {
                        curRecognizer = session.curRecognizer = recognizer;
                    }
                    i++;
                }
            },
            /**
             * get a recognizer by its event name.
             * @param {Recognizer|String} recognizer
             * @returns {Recognizer|Null}
             */
            get: function (recognizer) {
                if (recognizer instanceof Recognizer) {
                    return recognizer;
                }
                var recognizers = this.recognizers;
                for (var i = 0; i < recognizers.length; i++) {
                    if (recognizers[i].options.event == recognizer) {
                        return recognizers[i];
                    }
                }
                return null;
            },
            /**
             * add a recognizer to the manager
             * existing recognizers with the same event name will be removed
             * @param {Recognizer} recognizer
             * @returns {Recognizer|Manager}
             */
            add: function (recognizer) {
                if (invokeArrayArg(recognizer, 'add', this)) {
                    return this;
                }
                // remove existing
                var existing = this.get(recognizer.options.event);
                if (existing) {
                    this.remove(existing);
                }
                this.recognizers.push(recognizer);
                recognizer.manager = this;
                this.touchAction.update();
                return recognizer;
            },
            /**
             * remove a recognizer by name or instance
             * @param {Recognizer|String} recognizer
             * @returns {Manager}
             */
            remove: function (recognizer) {
                if (invokeArrayArg(recognizer, 'remove', this)) {
                    return this;
                }
                recognizer = this.get(recognizer);
                // let's make sure this recognizer exists
                if (recognizer) {
                    var recognizers = this.recognizers;
                    var index = inArray(recognizers, recognizer);
                    if (index !== -1) {
                        recognizers.splice(index, 1);
                        this.touchAction.update();
                    }
                }
                return this;
            },
            /**
             * bind event
             * @param {String} events
             * @param {Function} handler
             * @returns {EventEmitter} this
             */
            on: function (events, handler) {
                if (events === undefined) {
                    return;
                }
                if (handler === undefined) {
                    return;
                }
                var handlers = this.handlers;
                each(splitStr(events), function (event) {
                    handlers[event] = handlers[event] || [];
                    handlers[event].push(handler);
                });
                return this;
            },
            /**
             * unbind event, leave emit blank to remove all handlers
             * @param {String} events
             * @param {Function} [handler]
             * @returns {EventEmitter} this
             */
            off: function (events, handler) {
                if (events === undefined) {
                    return;
                }
                var handlers = this.handlers;
                each(splitStr(events), function (event) {
                    if (!handler) {
                        delete handlers[event];
                    }
                    else {
                        handlers[event] && handlers[event].splice(inArray(handlers[event], handler), 1);
                    }
                });
                return this;
            },
            /**
             * emit event to the listeners
             * @param {String} event
             * @param {Object} data
             */
            emit: function (event, data) {
                // we also want to trigger dom events
                if (this.options.domEvents) {
                    triggerDomEvent(event, data);
                }
                // no handlers, so skip it all
                var handlers = this.handlers[event] && this.handlers[event].slice();
                if (!handlers || !handlers.length) {
                    return;
                }
                data.type = event;
                data.preventDefault = function () {
                    data.srcEvent.preventDefault();
                };
                var i = 0;
                while (i < handlers.length) {
                    handlers[i](data);
                    i++;
                }
            },
            /**
             * destroy the manager and unbinds all events
             * it doesn't unbind dom events, that is the user own responsibility
             */
            destroy: function () {
                this.element && toggleCssProps(this, false);
                this.handlers = {};
                this.session = {};
                this.input.destroy();
                this.element = null;
            }
        };
        /**
         * add/remove the css properties as defined in manager.options.cssProps
         * @param {Manager} manager
         * @param {Boolean} add
         */
        function toggleCssProps(manager, add) {
            var element = manager.element;
            if (!element.style) {
                return;
            }
            var prop;
            each(manager.options.cssProps, function (value, name) {
                prop = prefixed(element.style, name);
                if (add) {
                    manager.oldCssProps[prop] = element.style[prop];
                    element.style[prop] = value;
                }
                else {
                    element.style[prop] = manager.oldCssProps[prop] || '';
                }
            });
            if (!add) {
                manager.oldCssProps = {};
            }
        }
        /**
         * trigger dom event
         * @param {String} event
         * @param {Object} data
         */
        function triggerDomEvent(event, data) {
            var gestureEvent = document.createEvent('Event');
            gestureEvent.initEvent(event, true, true);
            gestureEvent.gesture = data;
            data.target.dispatchEvent(gestureEvent);
        }
        assign(Hammer, {
            INPUT_START: INPUT_START,
            INPUT_MOVE: INPUT_MOVE,
            INPUT_END: INPUT_END,
            INPUT_CANCEL: INPUT_CANCEL,
            STATE_POSSIBLE: STATE_POSSIBLE,
            STATE_BEGAN: STATE_BEGAN,
            STATE_CHANGED: STATE_CHANGED,
            STATE_ENDED: STATE_ENDED,
            STATE_RECOGNIZED: STATE_RECOGNIZED,
            STATE_CANCELLED: STATE_CANCELLED,
            STATE_FAILED: STATE_FAILED,
            DIRECTION_NONE: DIRECTION_NONE,
            DIRECTION_LEFT: DIRECTION_LEFT,
            DIRECTION_RIGHT: DIRECTION_RIGHT,
            DIRECTION_UP: DIRECTION_UP,
            DIRECTION_DOWN: DIRECTION_DOWN,
            DIRECTION_HORIZONTAL: DIRECTION_HORIZONTAL,
            DIRECTION_VERTICAL: DIRECTION_VERTICAL,
            DIRECTION_ALL: DIRECTION_ALL,
            Manager: Manager,
            Input: Input,
            TouchAction: TouchAction,
            TouchInput: TouchInput,
            MouseInput: MouseInput,
            PointerEventInput: PointerEventInput,
            TouchMouseInput: TouchMouseInput,
            SingleTouchInput: SingleTouchInput,
            Recognizer: Recognizer,
            AttrRecognizer: AttrRecognizer,
            Tap: TapRecognizer,
            Pan: PanRecognizer,
            Swipe: SwipeRecognizer,
            Pinch: PinchRecognizer,
            Rotate: RotateRecognizer,
            Press: PressRecognizer,
            on: addEventListeners,
            off: removeEventListeners,
            each: each,
            merge: merge,
            extend: extend,
            assign: assign,
            inherit: inherit,
            bindFn: bindFn,
            prefixed: prefixed
        });
        // this prevents errors when Hammer is loaded in the presence of an AMD
        //  style loader but by script tag, not by the loader.
        var freeGlobal = (typeof window !== 'undefined' ? window : (typeof self !== 'undefined' ? self : {})); // jshint ignore:line
        freeGlobal.Hammer = Hammer;
        if (typeof define === 'function' && define.amd) {
            define(function () {
                return Hammer;
            });
        }
        else if (typeof module != 'undefined' && module.exports) {
            module.exports = Hammer;
        }
        else {
            window[exportName] = Hammer;
        }
    })(window, document, 'Hammer');
},
/* core/util/wheel.js */ function _(require, module, exports) {
    function fontSize(element) {
        const value = getComputedStyle(element).fontSize;
        if (value != null)
            return parseInt(value, 10);
        return null;
    }
    function lineHeight(element) {
        const parent = element.offsetParent || document.body;
        return fontSize(parent) || fontSize(element) || 16;
    }
    function pageHeight(element) {
        return element.clientHeight; // XXX: should be content height?
    }
    function getDeltaY(event) {
        let deltaY = -event.deltaY;
        if (event.target instanceof HTMLElement) {
            switch (event.deltaMode) {
                case event.DOM_DELTA_LINE:
                    deltaY *= lineHeight(event.target);
                    break;
                case event.DOM_DELTA_PAGE:
                    deltaY *= pageHeight(event.target);
                    break;
            }
        }
        return deltaY;
    }
    exports.getDeltaY = getDeltaY;
},
/* models/plots/gmap_plot_canvas.js */ function _(require, module, exports) {
    const signaling_1 = require(13) /* ../../core/signaling */;
    const projections_1 = require(30) /* ../../core/util/projections */;
    const plot_canvas_1 = require(273) /* ./plot_canvas */;
    const gmaps_ready = new signaling_1.Signal0({}, "gmaps_ready");
    const load_google_api = function (api_key) {
        window._bokeh_gmaps_callback = () => gmaps_ready.emit();
        const script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = `https://maps.googleapis.com/maps/api/js?v=3.36&key=${api_key}&callback=_bokeh_gmaps_callback`;
        document.body.appendChild(script);
    };
    class GMapPlotView extends plot_canvas_1.PlotView {
        initialize() {
            this.pause();
            super.initialize();
            this._tiles_loaded = false;
            this.zoom_count = 0;
            const { zoom, lat, lng } = this.model.map_options;
            this.initial_zoom = zoom;
            this.initial_lat = lat;
            this.initial_lng = lng;
            this.canvas_view.map_el.style.position = "absolute";
            if (typeof google === "undefined" || google.maps == null) {
                if (typeof window._bokeh_gmaps_callback === "undefined") {
                    load_google_api(this.model.api_key);
                }
                gmaps_ready.connect(() => this.request_render());
            }
            this.unpause();
        }
        update_range(range_info) {
            // RESET -------------------------
            if (range_info == null) {
                this.map.setCenter({ lat: this.initial_lat, lng: this.initial_lng });
                this.map.setOptions({ zoom: this.initial_zoom });
                super.update_range(null);
                // PAN ----------------------------
            }
            else if (range_info.sdx != null || range_info.sdy != null) {
                this.map.panBy(range_info.sdx || 0, range_info.sdy || 0);
                super.update_range(range_info);
                // ZOOM ---------------------------
            }
            else if (range_info.factor != null) {
                // The zoom count decreases the sensitivity of the zoom. (We could make this user configurable)
                let zoom_change;
                if (this.zoom_count !== 10) {
                    this.zoom_count += 1;
                    return;
                }
                this.zoom_count = 0;
                this.pause();
                super.update_range(range_info);
                if (range_info.factor < 0)
                    zoom_change = -1;
                else
                    zoom_change = 1;
                const old_map_zoom = this.map.getZoom();
                const new_map_zoom = old_map_zoom + zoom_change;
                // Zooming out too far causes problems
                if (new_map_zoom >= 2) {
                    this.map.setZoom(new_map_zoom);
                    // Check we haven't gone out of bounds, and if we have undo the zoom
                    const [proj_xstart, proj_xend, ,] = this._get_projected_bounds();
                    if (proj_xend - proj_xstart < 0) {
                        this.map.setZoom(old_map_zoom);
                    }
                }
                this.unpause();
            }
            // Finally re-center
            this._set_bokeh_ranges();
        }
        _build_map() {
            const { maps } = google;
            this.map_types = {
                satellite: maps.MapTypeId.SATELLITE,
                terrain: maps.MapTypeId.TERRAIN,
                roadmap: maps.MapTypeId.ROADMAP,
                hybrid: maps.MapTypeId.HYBRID,
            };
            const mo = this.model.map_options;
            const map_options = {
                center: new maps.LatLng(mo.lat, mo.lng),
                zoom: mo.zoom,
                disableDefaultUI: true,
                mapTypeId: this.map_types[mo.map_type],
                scaleControl: mo.scale_control,
                tilt: mo.tilt,
            };
            if (mo.styles != null)
                map_options.styles = JSON.parse(mo.styles);
            // create the map with above options in div
            this.map = new maps.Map(this.canvas_view.map_el, map_options);
            // update bokeh ranges whenever the map idles, which should be after most UI action
            maps.event.addListener(this.map, 'idle', () => this._set_bokeh_ranges());
            // also need an event when bounds change so that map resizes trigger renders too
            maps.event.addListener(this.map, 'bounds_changed', () => this._set_bokeh_ranges());
            maps.event.addListenerOnce(this.map, 'tilesloaded', () => this._render_finished());
            // wire up listeners so that changes to properties are reflected
            this.connect(this.model.properties.map_options.change, () => this._update_options());
            this.connect(this.model.map_options.properties.styles.change, () => this._update_styles());
            this.connect(this.model.map_options.properties.lat.change, () => this._update_center('lat'));
            this.connect(this.model.map_options.properties.lng.change, () => this._update_center('lng'));
            this.connect(this.model.map_options.properties.zoom.change, () => this._update_zoom());
            this.connect(this.model.map_options.properties.map_type.change, () => this._update_map_type());
            this.connect(this.model.map_options.properties.scale_control.change, () => this._update_scale_control());
            this.connect(this.model.map_options.properties.tilt.change, () => this._update_tilt());
        }
        _render_finished() {
            this._tiles_loaded = true;
            this.notify_finished();
        }
        has_finished() {
            return super.has_finished() && this._tiles_loaded === true;
        }
        _get_latlon_bounds() {
            const bounds = this.map.getBounds();
            const top_right = bounds.getNorthEast();
            const bottom_left = bounds.getSouthWest();
            const xstart = bottom_left.lng();
            const xend = top_right.lng();
            const ystart = bottom_left.lat();
            const yend = top_right.lat();
            return [xstart, xend, ystart, yend];
        }
        _get_projected_bounds() {
            const [xstart, xend, ystart, yend] = this._get_latlon_bounds();
            const [proj_xstart, proj_ystart] = projections_1.wgs84_mercator.forward([xstart, ystart]);
            const [proj_xend, proj_yend] = projections_1.wgs84_mercator.forward([xend, yend]);
            return [proj_xstart, proj_xend, proj_ystart, proj_yend];
        }
        _set_bokeh_ranges() {
            const [proj_xstart, proj_xend, proj_ystart, proj_yend] = this._get_projected_bounds();
            this.frame.x_range.setv({ start: proj_xstart, end: proj_xend });
            this.frame.y_range.setv({ start: proj_ystart, end: proj_yend });
        }
        _update_center(fld) {
            const c = this.map.getCenter().toJSON();
            c[fld] = this.model.map_options[fld];
            this.map.setCenter(c);
            this._set_bokeh_ranges();
        }
        _update_map_type() {
            this.map.setOptions({ mapTypeId: this.map_types[this.model.map_options.map_type] });
        }
        _update_scale_control() {
            this.map.setOptions({ scaleControl: this.model.map_options.scale_control });
        }
        _update_tilt() {
            this.map.setOptions({ tilt: this.model.map_options.tilt });
        }
        _update_options() {
            this._update_styles();
            this._update_center('lat');
            this._update_center('lng');
            this._update_zoom();
            this._update_map_type();
        }
        _update_styles() {
            this.map.setOptions({ styles: JSON.parse(this.model.map_options.styles) });
        }
        _update_zoom() {
            this.map.setOptions({ zoom: this.model.map_options.zoom });
            this._set_bokeh_ranges();
        }
        // this method is expected and called by PlotView.render
        _map_hook(_ctx, frame_box) {
            const [left, top, width, height] = frame_box;
            this.canvas_view.map_el.style.top = `${top}px`;
            this.canvas_view.map_el.style.left = `${left}px`;
            this.canvas_view.map_el.style.width = `${width}px`;
            this.canvas_view.map_el.style.height = `${height}px`;
            if (this.map == null && typeof google !== "undefined" && google.maps != null)
                this._build_map();
        }
        // this overrides the standard _paint_empty to make the inner canvas transparent
        _paint_empty(ctx, frame_box) {
            const ow = this.layout._width.value;
            const oh = this.layout._height.value;
            const [left, top, iw, ih] = frame_box;
            ctx.clearRect(0, 0, ow, oh);
            ctx.beginPath();
            ctx.moveTo(0, 0);
            ctx.lineTo(0, oh);
            ctx.lineTo(ow, oh);
            ctx.lineTo(ow, 0);
            ctx.lineTo(0, 0);
            ctx.moveTo(left, top);
            ctx.lineTo(left + iw, top);
            ctx.lineTo(left + iw, top + ih);
            ctx.lineTo(left, top + ih);
            ctx.lineTo(left, top);
            ctx.closePath();
            if (this.model.border_fill_color != null) {
                ctx.fillStyle = this.model.border_fill_color;
                ctx.fill();
            }
        }
    }
    exports.GMapPlotView = GMapPlotView;
    GMapPlotView.__name__ = "GMapPlotView";
},
/* models/ranges/index.js */ function _(require, module, exports) {
    var data_range_1 = require(179) /* ./data_range */;
    exports.DataRange = data_range_1.DataRange;
    var data_range1d_1 = require(178) /* ./data_range1d */;
    exports.DataRange1d = data_range1d_1.DataRange1d;
    var factor_range_1 = require(82) /* ./factor_range */;
    exports.FactorRange = factor_range_1.FactorRange;
    var range_1 = require(83) /* ./range */;
    exports.Range = range_1.Range;
    var range1d_1 = require(123) /* ./range1d */;
    exports.Range1d = range1d_1.Range1d;
},
/* models/renderers/index.js */ function _(require, module, exports) {
    var glyph_renderer_1 = require(73) /* ./glyph_renderer */;
    exports.GlyphRenderer = glyph_renderer_1.GlyphRenderer;
    var graph_renderer_1 = require(90) /* ./graph_renderer */;
    exports.GraphRenderer = graph_renderer_1.GraphRenderer;
    var guide_renderer_1 = require(142) /* ./guide_renderer */;
    exports.GuideRenderer = guide_renderer_1.GuideRenderer;
    var renderer_1 = require(58) /* ./renderer */;
    exports.Renderer = renderer_1.Renderer;
},
/* models/scales/index.js */ function _(require, module, exports) {
    var categorical_scale_1 = require(177) /* ./categorical_scale */;
    exports.CategoricalScale = categorical_scale_1.CategoricalScale;
    var linear_scale_1 = require(113) /* ./linear_scale */;
    exports.LinearScale = linear_scale_1.LinearScale;
    var log_scale_1 = require(122) /* ./log_scale */;
    exports.LogScale = log_scale_1.LogScale;
    var scale_1 = require(114) /* ./scale */;
    exports.Scale = scale_1.Scale;
},
/* models/selections/index.js */ function _(require, module, exports) {
    function __export(m) {
        for (var p in m)
            if (!exports.hasOwnProperty(p))
                exports[p] = m[p];
    }
    __export(require(93) /* ./interaction_policy */);
    var selection_1 = require(71) /* ./selection */;
    exports.Selection = selection_1.Selection;
},
/* models/sources/index.js */ function _(require, module, exports) {
    var server_sent_data_source_1 = require(286) /* ./server_sent_data_source */;
    exports.ServerSentDataSource = server_sent_data_source_1.ServerSentDataSource;
    var ajax_data_source_1 = require(288) /* ./ajax_data_source */;
    exports.AjaxDataSource = ajax_data_source_1.AjaxDataSource;
    var column_data_source_1 = require(68) /* ./column_data_source */;
    exports.ColumnDataSource = column_data_source_1.ColumnDataSource;
    var columnar_data_source_1 = require(69) /* ./columnar_data_source */;
    exports.ColumnarDataSource = columnar_data_source_1.ColumnarDataSource;
    var cds_view_1 = require(89) /* ./cds_view */;
    exports.CDSView = cds_view_1.CDSView;
    var data_source_1 = require(70) /* ./data_source */;
    exports.DataSource = data_source_1.DataSource;
    var geojson_data_source_1 = require(290) /* ./geojson_data_source */;
    exports.GeoJSONDataSource = geojson_data_source_1.GeoJSONDataSource;
    var remote_data_source_1 = require(289) /* ./remote_data_source */;
    exports.RemoteDataSource = remote_data_source_1.RemoteDataSource;
},
/* models/sources/server_sent_data_source.js */ function _(require, module, exports) {
    const web_data_source_1 = require(287) /* ./web_data_source */;
    class ServerSentDataSource extends web_data_source_1.WebDataSource {
        constructor(attrs) {
            super(attrs);
            this.initialized = false;
        }
        destroy() {
            super.destroy();
        }
        setup() {
            if (!this.initialized) {
                this.initialized = true;
                const source = new EventSource(this.data_url);
                source.onmessage = (event) => {
                    this.load_data(JSON.parse(event.data), this.mode, this.max_size);
                };
            }
        }
    }
    exports.ServerSentDataSource = ServerSentDataSource;
    ServerSentDataSource.__name__ = "ServerSentDataSource";
},
/* models/sources/web_data_source.js */ function _(require, module, exports) {
    const column_data_source_1 = require(68) /* ./column_data_source */;
    const p = require(18) /* ../../core/properties */;
    class WebDataSource extends column_data_source_1.ColumnDataSource {
        constructor(attrs) {
            super(attrs);
        }
        get_column(colname) {
            const column = this.data[colname];
            return column != null ? column : [];
        }
        initialize() {
            super.initialize();
            this.setup();
        }
        load_data(raw_data, mode, max_size) {
            const { adapter } = this;
            let data;
            if (adapter != null)
                data = adapter.execute(this, { response: raw_data });
            else
                data = raw_data;
            switch (mode) {
                case "replace": {
                    this.data = data;
                    break;
                }
                case "append": {
                    const original_data = this.data;
                    for (const column of this.columns()) {
                        // XXX: support typed arrays
                        const old_col = Array.from(original_data[column]);
                        const new_col = Array.from(data[column]);
                        data[column] = old_col.concat(new_col).slice(-max_size);
                    }
                    this.data = data;
                    break;
                }
            }
        }
        static init_WebDataSource() {
            this.define({
                mode: [p.UpdateMode, 'replace'],
                max_size: [p.Number],
                adapter: [p.Any, null],
                data_url: [p.String],
            });
        }
    }
    exports.WebDataSource = WebDataSource;
    WebDataSource.__name__ = "WebDataSource";
    WebDataSource.init_WebDataSource();
},
/* models/sources/ajax_data_source.js */ function _(require, module, exports) {
    const remote_data_source_1 = require(289) /* ./remote_data_source */;
    const logging_1 = require(65) /* ../../core/logging */;
    const p = require(18) /* ../../core/properties */;
    class AjaxDataSource extends remote_data_source_1.RemoteDataSource {
        constructor(attrs) {
            super(attrs);
            this.initialized = false;
        }
        static init_AjaxDataSource() {
            this.define({
                content_type: [p.String, 'application/json'],
                http_headers: [p.Any, {}],
                method: [p.HTTPMethod, 'POST'],
                if_modified: [p.Boolean, false],
            });
        }
        destroy() {
            if (this.interval != null)
                clearInterval(this.interval);
            super.destroy();
        }
        setup() {
            if (!this.initialized) {
                this.initialized = true;
                this.get_data(this.mode);
                if (this.polling_interval) {
                    const callback = () => this.get_data(this.mode, this.max_size, this.if_modified);
                    this.interval = setInterval(callback, this.polling_interval);
                }
            }
        }
        get_data(mode, max_size = 0, _if_modified = false) {
            const xhr = this.prepare_request();
            // TODO: if_modified
            xhr.addEventListener("load", () => this.do_load(xhr, mode, max_size));
            xhr.addEventListener("error", () => this.do_error(xhr));
            xhr.send();
        }
        prepare_request() {
            const xhr = new XMLHttpRequest();
            xhr.open(this.method, this.data_url, true);
            xhr.withCredentials = false;
            xhr.setRequestHeader("Content-Type", this.content_type);
            const http_headers = this.http_headers;
            for (const name in http_headers) {
                const value = http_headers[name];
                xhr.setRequestHeader(name, value);
            }
            return xhr;
        }
        do_load(xhr, mode, max_size) {
            if (xhr.status === 200) {
                const raw_data = JSON.parse(xhr.responseText);
                this.load_data(raw_data, mode, max_size);
            }
        }
        do_error(xhr) {
            logging_1.logger.error(`Failed to fetch JSON from ${this.data_url} with code ${xhr.status}`);
        }
    }
    exports.AjaxDataSource = AjaxDataSource;
    AjaxDataSource.__name__ = "AjaxDataSource";
    AjaxDataSource.init_AjaxDataSource();
},
/* models/sources/remote_data_source.js */ function _(require, module, exports) {
    const web_data_source_1 = require(287) /* ./web_data_source */;
    const p = require(18) /* ../../core/properties */;
    class RemoteDataSource extends web_data_source_1.WebDataSource {
        constructor(attrs) {
            super(attrs);
        }
        get_column(colname) {
            const column = this.data[colname];
            return column != null ? column : [];
        }
        initialize() {
            super.initialize();
            this.setup();
        }
        static init_RemoteDataSource() {
            this.define({
                polling_interval: [p.Number],
            });
        }
    }
    exports.RemoteDataSource = RemoteDataSource;
    RemoteDataSource.__name__ = "RemoteDataSource";
    RemoteDataSource.init_RemoteDataSource();
},
/* models/sources/geojson_data_source.js */ function _(require, module, exports) {
    const columnar_data_source_1 = require(69) /* ./columnar_data_source */;
    const logging_1 = require(65) /* ../../core/logging */;
    const p = require(18) /* ../../core/properties */;
    const array_1 = require(8) /* ../../core/util/array */;
    function orNaN(v) {
        return v != null ? v : NaN;
    }
    class GeoJSONDataSource extends columnar_data_source_1.ColumnarDataSource {
        constructor(attrs) {
            super(attrs);
        }
        static init_GeoJSONDataSource() {
            this.define({
                geojson: [p.Any],
            });
            this.internal({
                data: [p.Any, {}],
            });
        }
        initialize() {
            super.initialize();
            this._update_data();
        }
        connect_signals() {
            super.connect_signals();
            this.connect(this.properties.geojson.change, () => this._update_data());
        }
        _update_data() {
            this.data = this.geojson_to_column_data();
        }
        _get_new_list_array(length) {
            return array_1.range(0, length).map((_i) => []);
        }
        _get_new_nan_array(length) {
            return array_1.range(0, length).map((_i) => NaN);
        }
        _add_properties(item, data, i, item_count) {
            const properties = item.properties || {};
            for (const property in properties) {
                if (!data.hasOwnProperty(property))
                    data[property] = this._get_new_nan_array(item_count);
                // orNaN necessary here to prevent null values from ending up in the column
                data[property][i] = orNaN(properties[property]);
            }
        }
        _add_geometry(geometry, data, i) {
            function flatten(acc, item) {
                return acc.concat([[NaN, NaN, NaN]]).concat(item);
            }
            switch (geometry.type) {
                case "Point": {
                    const [x, y, z] = geometry.coordinates;
                    data.x[i] = x;
                    data.y[i] = y;
                    data.z[i] = orNaN(z);
                    break;
                }
                case "LineString": {
                    const { coordinates } = geometry;
                    for (let j = 0; j < coordinates.length; j++) {
                        const [x, y, z] = coordinates[j];
                        data.xs[i][j] = x;
                        data.ys[i][j] = y;
                        data.zs[i][j] = orNaN(z);
                    }
                    break;
                }
                case "Polygon": {
                    if (geometry.coordinates.length > 1)
                        logging_1.logger.warn('Bokeh does not support Polygons with holes in, only exterior ring used.');
                    const exterior_ring = geometry.coordinates[0];
                    for (let j = 0; j < exterior_ring.length; j++) {
                        const [x, y, z] = exterior_ring[j];
                        data.xs[i][j] = x;
                        data.ys[i][j] = y;
                        data.zs[i][j] = orNaN(z);
                    }
                    break;
                }
                case "MultiPoint": {
                    logging_1.logger.warn('MultiPoint not supported in Bokeh');
                    break;
                }
                case "MultiLineString": {
                    const coordinates = geometry.coordinates.reduce(flatten);
                    for (let j = 0; j < coordinates.length; j++) {
                        const [x, y, z] = coordinates[j];
                        data.xs[i][j] = x;
                        data.ys[i][j] = y;
                        data.zs[i][j] = orNaN(z);
                    }
                    break;
                }
                case "MultiPolygon": {
                    const exterior_rings = [];
                    for (const polygon of geometry.coordinates) {
                        if (polygon.length > 1)
                            logging_1.logger.warn('Bokeh does not support Polygons with holes in, only exterior ring used.');
                        exterior_rings.push(polygon[0]);
                    }
                    const coordinates = exterior_rings.reduce(flatten);
                    for (let j = 0; j < coordinates.length; j++) {
                        const [x, y, z] = coordinates[j];
                        data.xs[i][j] = x;
                        data.ys[i][j] = y;
                        data.zs[i][j] = orNaN(z);
                    }
                    break;
                }
                default:
                    throw new Error(`Invalid GeoJSON geometry type: ${geometry.type}`);
            }
        }
        geojson_to_column_data() {
            const geojson = JSON.parse(this.geojson);
            let items;
            switch (geojson.type) {
                case "GeometryCollection": {
                    if (geojson.geometries == null)
                        throw new Error('No geometries found in GeometryCollection');
                    if (geojson.geometries.length === 0)
                        throw new Error('geojson.geometries must have one or more items');
                    items = geojson.geometries;
                    break;
                }
                case "FeatureCollection": {
                    if (geojson.features == null)
                        throw new Error('No features found in FeaturesCollection');
                    if (geojson.features.length == 0)
                        throw new Error('geojson.features must have one or more items');
                    items = geojson.features;
                    break;
                }
                default:
                    throw new Error('Bokeh only supports type GeometryCollection and FeatureCollection at top level');
            }
            let item_count = 0;
            for (const item of items) {
                const geometry = item.type === 'Feature' ? item.geometry : item;
                if (geometry.type == 'GeometryCollection')
                    item_count += geometry.geometries.length;
                else
                    item_count += 1;
            }
            const data = {
                x: this._get_new_nan_array(item_count),
                y: this._get_new_nan_array(item_count),
                z: this._get_new_nan_array(item_count),
                xs: this._get_new_list_array(item_count),
                ys: this._get_new_list_array(item_count),
                zs: this._get_new_list_array(item_count),
            };
            let arr_index = 0;
            for (const item of items) {
                const geometry = item.type == 'Feature' ? item.geometry : item;
                if (geometry.type == "GeometryCollection") {
                    for (const g of geometry.geometries) {
                        this._add_geometry(g, data, arr_index);
                        if (item.type === 'Feature')
                            this._add_properties(item, data, arr_index, item_count);
                        arr_index += 1;
                    }
                }
                else {
                    this._add_geometry(geometry, data, arr_index);
                    if (item.type === 'Feature')
                        this._add_properties(item, data, arr_index, item_count);
                    arr_index += 1;
                }
            }
            return data;
        }
    }
    exports.GeoJSONDataSource = GeoJSONDataSource;
    GeoJSONDataSource.__name__ = "GeoJSONDataSource";
    GeoJSONDataSource.init_GeoJSONDataSource();
},
/* models/tickers/index.js */ function _(require, module, exports) {
    var adaptive_ticker_1 = require(103) /* ./adaptive_ticker */;
    exports.AdaptiveTicker = adaptive_ticker_1.AdaptiveTicker;
    var basic_ticker_1 = require(102) /* ./basic_ticker */;
    exports.BasicTicker = basic_ticker_1.BasicTicker;
    var categorical_ticker_1 = require(144) /* ./categorical_ticker */;
    exports.CategoricalTicker = categorical_ticker_1.CategoricalTicker;
    var composite_ticker_1 = require(155) /* ./composite_ticker */;
    exports.CompositeTicker = composite_ticker_1.CompositeTicker;
    var continuous_ticker_1 = require(104) /* ./continuous_ticker */;
    exports.ContinuousTicker = continuous_ticker_1.ContinuousTicker;
    var datetime_ticker_1 = require(154) /* ./datetime_ticker */;
    exports.DatetimeTicker = datetime_ticker_1.DatetimeTicker;
    var days_ticker_1 = require(156) /* ./days_ticker */;
    exports.DaysTicker = days_ticker_1.DaysTicker;
    var fixed_ticker_1 = require(292) /* ./fixed_ticker */;
    exports.FixedTicker = fixed_ticker_1.FixedTicker;
    var log_ticker_1 = require(163) /* ./log_ticker */;
    exports.LogTicker = log_ticker_1.LogTicker;
    var mercator_ticker_1 = require(166) /* ./mercator_ticker */;
    exports.MercatorTicker = mercator_ticker_1.MercatorTicker;
    var months_ticker_1 = require(159) /* ./months_ticker */;
    exports.MonthsTicker = months_ticker_1.MonthsTicker;
    var single_interval_ticker_1 = require(157) /* ./single_interval_ticker */;
    exports.SingleIntervalTicker = single_interval_ticker_1.SingleIntervalTicker;
    var ticker_1 = require(105) /* ./ticker */;
    exports.Ticker = ticker_1.Ticker;
    var years_ticker_1 = require(160) /* ./years_ticker */;
    exports.YearsTicker = years_ticker_1.YearsTicker;
},
/* models/tickers/fixed_ticker.js */ function _(require, module, exports) {
    const continuous_ticker_1 = require(104) /* ./continuous_ticker */;
    const p = require(18) /* ../../core/properties */;
    class FixedTicker extends continuous_ticker_1.ContinuousTicker {
        constructor(attrs) {
            super(attrs);
            this.min_interval = 0;
            this.max_interval = 0;
        }
        static init_FixedTicker() {
            this.define({
                ticks: [p.Array, []],
                minor_ticks: [p.Array, []],
            });
        }
        get_ticks_no_defaults(_data_low, _data_high, _cross_loc, _desired_n_ticks) {
            return {
                major: this.ticks,
                minor: this.minor_ticks,
            };
        }
        // XXX: whatever, because FixedTicker needs to fulfill the interface somehow
        get_interval(_data_low, _data_high, _desired_n_ticks) {
            return 0;
        }
    }
    exports.FixedTicker = FixedTicker;
    FixedTicker.__name__ = "FixedTicker";
    FixedTicker.init_FixedTicker();
},
/* models/tiles/index.js */ function _(require, module, exports) {
    var bbox_tile_source_1 = require(294) /* ./bbox_tile_source */;
    exports.BBoxTileSource = bbox_tile_source_1.BBoxTileSource;
    var mercator_tile_source_1 = require(295) /* ./mercator_tile_source */;
    exports.MercatorTileSource = mercator_tile_source_1.MercatorTileSource;
    var quadkey_tile_source_1 = require(298) /* ./quadkey_tile_source */;
    exports.QUADKEYTileSource = quadkey_tile_source_1.QUADKEYTileSource;
    var tile_renderer_1 = require(299) /* ./tile_renderer */;
    exports.TileRenderer = tile_renderer_1.TileRenderer;
    var tile_source_1 = require(296) /* ./tile_source */;
    exports.TileSource = tile_source_1.TileSource;
    var tms_tile_source_1 = require(302) /* ./tms_tile_source */;
    exports.TMSTileSource = tms_tile_source_1.TMSTileSource;
    var wmts_tile_source_1 = require(300) /* ./wmts_tile_source */;
    exports.WMTSTileSource = wmts_tile_source_1.WMTSTileSource;
},
/* models/tiles/bbox_tile_source.js */ function _(require, module, exports) {
    const mercator_tile_source_1 = require(295) /* ./mercator_tile_source */;
    const p = require(18) /* ../../core/properties */;
    class BBoxTileSource extends mercator_tile_source_1.MercatorTileSource {
        constructor(attrs) {
            super(attrs);
        }
        static init_BBoxTileSource() {
            this.define({
                use_latlon: [p.Boolean, false],
            });
        }
        get_image_url(x, y, z) {
            const image_url = this.string_lookup_replace(this.url, this.extra_url_vars);
            let xmax, xmin, ymax, ymin;
            if (this.use_latlon)
                [xmin, ymin, xmax, ymax] = this.get_tile_geographic_bounds(x, y, z);
            else
                [xmin, ymin, xmax, ymax] = this.get_tile_meter_bounds(x, y, z);
            return image_url
                .replace("{XMIN}", xmin.toString())
                .replace("{YMIN}", ymin.toString())
                .replace("{XMAX}", xmax.toString())
                .replace("{YMAX}", ymax.toString());
        }
    }
    exports.BBoxTileSource = BBoxTileSource;
    BBoxTileSource.__name__ = "BBoxTileSource";
    BBoxTileSource.init_BBoxTileSource();
},
/* models/tiles/mercator_tile_source.js */ function _(require, module, exports) {
    const tile_source_1 = require(296) /* ./tile_source */;
    const p = require(18) /* ../../core/properties */;
    const array_1 = require(8) /* ../../core/util/array */;
    const tile_utils_1 = require(297) /* ./tile_utils */;
    class MercatorTileSource extends tile_source_1.TileSource {
        constructor(attrs) {
            super(attrs);
        }
        static init_MercatorTileSource() {
            this.define({
                snap_to_zoom: [p.Boolean, false],
                wrap_around: [p.Boolean, true],
            });
            this.override({
                x_origin_offset: 20037508.34,
                y_origin_offset: 20037508.34,
                initial_resolution: 156543.03392804097,
            });
        }
        initialize() {
            super.initialize();
            this._resolutions = array_1.range(this.min_zoom, this.max_zoom + 1).map((z) => this.get_resolution(z));
        }
        _computed_initial_resolution() {
            if (this.initial_resolution != null)
                return this.initial_resolution;
            else {
                // TODO testing 2015-11-17, if this codepath is used it seems
                // to use 100% cpu and wedge Chrome
                return (2 * Math.PI * 6378137) / this.tile_size;
            }
        }
        is_valid_tile(x, y, z) {
            if (!this.wrap_around) {
                if (x < 0 || x >= Math.pow(2, z))
                    return false;
            }
            if (y < 0 || y >= Math.pow(2, z))
                return false;
            return true;
        }
        parent_by_tile_xyz(x, y, z) {
            const quadkey = this.tile_xyz_to_quadkey(x, y, z);
            const parent_quadkey = quadkey.substring(0, quadkey.length - 1);
            return this.quadkey_to_tile_xyz(parent_quadkey);
        }
        get_resolution(level) {
            return this._computed_initial_resolution() / Math.pow(2, level);
        }
        get_resolution_by_extent(extent, height, width) {
            const x_rs = (extent[2] - extent[0]) / width;
            const y_rs = (extent[3] - extent[1]) / height;
            return [x_rs, y_rs];
        }
        get_level_by_extent(extent, height, width) {
            const x_rs = (extent[2] - extent[0]) / width;
            const y_rs = (extent[3] - extent[1]) / height;
            const resolution = Math.max(x_rs, y_rs);
            let i = 0;
            for (const r of this._resolutions) {
                if (resolution > r) {
                    if (i == 0)
                        return 0;
                    if (i > 0)
                        return i - 1;
                }
                i += 1;
            }
            // otherwise return the highest available resolution
            return (i - 1);
        }
        get_closest_level_by_extent(extent, height, width) {
            const x_rs = (extent[2] - extent[0]) / width;
            const y_rs = (extent[3] - extent[1]) / height;
            const resolution = Math.max(x_rs, y_rs);
            const closest = this._resolutions.reduce(function (previous, current) {
                if (Math.abs(current - resolution) < Math.abs(previous - resolution))
                    return current;
                else
                    return previous;
            });
            return this._resolutions.indexOf(closest);
        }
        snap_to_zoom_level(extent, height, width, level) {
            const [xmin, ymin, xmax, ymax] = extent;
            const desired_res = this._resolutions[level];
            let desired_x_delta = width * desired_res;
            let desired_y_delta = height * desired_res;
            if (!this.snap_to_zoom) {
                const xscale = (xmax - xmin) / desired_x_delta;
                const yscale = (ymax - ymin) / desired_y_delta;
                if (xscale > yscale) {
                    desired_x_delta = (xmax - xmin);
                    desired_y_delta = desired_y_delta * xscale;
                }
                else {
                    desired_x_delta = desired_x_delta * yscale;
                    desired_y_delta = (ymax - ymin);
                }
            }
            const x_adjust = (desired_x_delta - (xmax - xmin)) / 2;
            const y_adjust = (desired_y_delta - (ymax - ymin)) / 2;
            return [xmin - x_adjust, ymin - y_adjust, xmax + x_adjust, ymax + y_adjust];
        }
        tms_to_wmts(x, y, z) {
            'Note this works both ways';
            return [x, Math.pow(2, z) - 1 - y, z];
        }
        wmts_to_tms(x, y, z) {
            'Note this works both ways';
            return [x, Math.pow(2, z) - 1 - y, z];
        }
        pixels_to_meters(px, py, level) {
            const res = this.get_resolution(level);
            const mx = (px * res) - this.x_origin_offset;
            const my = (py * res) - this.y_origin_offset;
            return [mx, my];
        }
        meters_to_pixels(mx, my, level) {
            const res = this.get_resolution(level);
            const px = (mx + this.x_origin_offset) / res;
            const py = (my + this.y_origin_offset) / res;
            return [px, py];
        }
        pixels_to_tile(px, py) {
            let tx = Math.ceil(px / this.tile_size);
            tx = tx === 0 ? tx : tx - 1;
            const ty = Math.max(Math.ceil(py / this.tile_size) - 1, 0);
            return [tx, ty];
        }
        pixels_to_raster(px, py, level) {
            const mapSize = this.tile_size << level;
            return [px, mapSize - py];
        }
        meters_to_tile(mx, my, level) {
            const [px, py] = this.meters_to_pixels(mx, my, level);
            return this.pixels_to_tile(px, py);
        }
        get_tile_meter_bounds(tx, ty, level) {
            // expects tms styles coordinates (bottom-left origin)
            const [xmin, ymin] = this.pixels_to_meters(tx * this.tile_size, ty * this.tile_size, level);
            const [xmax, ymax] = this.pixels_to_meters((tx + 1) * this.tile_size, (ty + 1) * this.tile_size, level);
            return [xmin, ymin, xmax, ymax];
        }
        get_tile_geographic_bounds(tx, ty, level) {
            const bounds = this.get_tile_meter_bounds(tx, ty, level);
            const [minLon, minLat, maxLon, maxLat] = tile_utils_1.meters_extent_to_geographic(bounds);
            return [minLon, minLat, maxLon, maxLat];
        }
        get_tiles_by_extent(extent, level, tile_border = 1) {
            // unpack extent and convert to tile coordinates
            const [xmin, ymin, xmax, ymax] = extent;
            let [txmin, tymin] = this.meters_to_tile(xmin, ymin, level);
            let [txmax, tymax] = this.meters_to_tile(xmax, ymax, level);
            // add tiles which border
            txmin -= tile_border;
            tymin -= tile_border;
            txmax += tile_border;
            tymax += tile_border;
            const tiles = [];
            for (let ty = tymax; ty >= tymin; ty--) {
                for (let tx = txmin; tx <= txmax; tx++) {
                    if (this.is_valid_tile(tx, ty, level))
                        tiles.push([tx, ty, level, this.get_tile_meter_bounds(tx, ty, level)]);
                }
            }
            this.sort_tiles_from_center(tiles, [txmin, tymin, txmax, tymax]);
            return tiles;
        }
        quadkey_to_tile_xyz(quadKey) {
            /**
             * Computes tile x, y and z values based on quadKey.
             */
            let tileX = 0;
            let tileY = 0;
            const tileZ = quadKey.length;
            for (let i = tileZ; i > 0; i--) {
                const value = quadKey.charAt(tileZ - i);
                const mask = 1 << (i - 1);
                switch (value) {
                    case '0':
                        continue;
                    case '1':
                        tileX |= mask;
                        break;
                    case '2':
                        tileY |= mask;
                        break;
                    case '3':
                        tileX |= mask;
                        tileY |= mask;
                        break;
                    default:
                        throw new TypeError(`Invalid Quadkey: ${quadKey}`);
                }
            }
            return [tileX, tileY, tileZ];
        }
        tile_xyz_to_quadkey(x, y, z) {
            /*
             * Computes quadkey value based on tile x, y and z values.
             */
            let quadkey = "";
            for (let i = z; i > 0; i--) {
                const mask = 1 << (i - 1);
                let digit = 0;
                if ((x & mask) !== 0) {
                    digit += 1;
                }
                if ((y & mask) !== 0) {
                    digit += 2;
                }
                quadkey += digit.toString();
            }
            return quadkey;
        }
        children_by_tile_xyz(x, y, z) {
            const quadkey = this.tile_xyz_to_quadkey(x, y, z);
            const child_tile_xyz = [];
            for (let i = 0; i <= 3; i++) {
                const [x, y, z] = this.quadkey_to_tile_xyz(quadkey + i.toString());
                const b = this.get_tile_meter_bounds(x, y, z);
                child_tile_xyz.push([x, y, z, b]);
            }
            return child_tile_xyz;
        }
        get_closest_parent_by_tile_xyz(x, y, z) {
            const world_x = this.calculate_world_x_by_tile_xyz(x, y, z);
            [x, y, z] = this.normalize_xyz(x, y, z);
            let quadkey = this.tile_xyz_to_quadkey(x, y, z);
            while (quadkey.length > 0) {
                quadkey = quadkey.substring(0, quadkey.length - 1);
                [x, y, z] = this.quadkey_to_tile_xyz(quadkey);
                [x, y, z] = this.denormalize_xyz(x, y, z, world_x);
                if (this.tiles.has(this.tile_xyz_to_key(x, y, z)))
                    return [x, y, z];
            }
            return [0, 0, 0];
        }
        normalize_xyz(x, y, z) {
            if (this.wrap_around) {
                const tile_count = Math.pow(2, z);
                return [((x % tile_count) + tile_count) % tile_count, y, z];
            }
            else {
                return [x, y, z];
            }
        }
        denormalize_xyz(x, y, z, world_x) {
            return [x + (world_x * Math.pow(2, z)), y, z];
        }
        denormalize_meters(meters_x, meters_y, _level, world_x) {
            return [meters_x + (world_x * 2 * Math.PI * 6378137), meters_y];
        }
        calculate_world_x_by_tile_xyz(x, _y, z) {
            return Math.floor(x / Math.pow(2, z));
        }
    }
    exports.MercatorTileSource = MercatorTileSource;
    MercatorTileSource.__name__ = "MercatorTileSource";
    MercatorTileSource.init_MercatorTileSource();
},
/* models/tiles/tile_source.js */ function _(require, module, exports) {
    const model_1 = require(64) /* ../../model */;
    const p = require(18) /* ../../core/properties */;
    class TileSource extends model_1.Model {
        constructor(attrs) {
            super(attrs);
        }
        static init_TileSource() {
            this.define({
                url: [p.String, ''],
                tile_size: [p.Number, 256],
                max_zoom: [p.Number, 30],
                min_zoom: [p.Number, 0],
                extra_url_vars: [p.Any, {}],
                attribution: [p.String, ''],
                x_origin_offset: [p.Number],
                y_origin_offset: [p.Number],
                initial_resolution: [p.Number],
            });
        }
        initialize() {
            super.initialize();
            this.tiles = new Map();
            this._normalize_case();
        }
        connect_signals() {
            super.connect_signals();
            this.connect(this.change, () => this._clear_cache());
        }
        string_lookup_replace(str, lookup) {
            let result_str = str;
            for (const key in lookup) {
                const value = lookup[key];
                result_str = result_str.replace(`{${key}}`, value);
            }
            return result_str;
        }
        _normalize_case() {
            /*
             * Note: should probably be refactored into subclasses.
             */
            const url = this.url
                .replace('{x}', '{X}')
                .replace('{y}', '{Y}')
                .replace('{z}', '{Z}')
                .replace('{q}', '{Q}')
                .replace('{xmin}', '{XMIN}')
                .replace('{ymin}', '{YMIN}')
                .replace('{xmax}', '{XMAX}')
                .replace('{ymax}', '{YMAX}');
            this.url = url;
        }
        _clear_cache() {
            this.tiles = new Map();
        }
        tile_xyz_to_key(x, y, z) {
            return `${x}:${y}:${z}`;
        }
        key_to_tile_xyz(key) {
            const [x, y, z] = key.split(':').map((c) => parseInt(c));
            return [x, y, z];
        }
        sort_tiles_from_center(tiles, tile_extent) {
            const [txmin, tymin, txmax, tymax] = tile_extent;
            const center_x = ((txmax - txmin) / 2) + txmin;
            const center_y = ((tymax - tymin) / 2) + tymin;
            tiles.sort(function (a, b) {
                const a_distance = Math.sqrt(Math.pow(center_x - a[0], 2) + Math.pow(center_y - a[1], 2));
                const b_distance = Math.sqrt(Math.pow(center_x - b[0], 2) + Math.pow(center_y - b[1], 2));
                return a_distance - b_distance;
            });
        }
        get_image_url(x, y, z) {
            const image_url = this.string_lookup_replace(this.url, this.extra_url_vars);
            return image_url
                .replace("{X}", x.toString())
                .replace('{Y}', y.toString())
                .replace("{Z}", z.toString());
        }
    }
    exports.TileSource = TileSource;
    TileSource.__name__ = "TileSource";
    TileSource.init_TileSource();
},
/* models/tiles/tile_utils.js */ function _(require, module, exports) {
    const projections_1 = require(30) /* ../../core/util/projections */;
    function geographic_to_meters(xLon, yLat) {
        return projections_1.wgs84_mercator.forward([xLon, yLat]);
    }
    exports.geographic_to_meters = geographic_to_meters;
    function meters_to_geographic(mx, my) {
        return projections_1.wgs84_mercator.inverse([mx, my]);
    }
    exports.meters_to_geographic = meters_to_geographic;
    function geographic_extent_to_meters(extent) {
        const [g_xmin, g_ymin, g_xmax, g_ymax] = extent;
        const [m_xmin, m_ymin] = geographic_to_meters(g_xmin, g_ymin);
        const [m_xmax, m_ymax] = geographic_to_meters(g_xmax, g_ymax);
        return [m_xmin, m_ymin, m_xmax, m_ymax];
    }
    exports.geographic_extent_to_meters = geographic_extent_to_meters;
    function meters_extent_to_geographic(extent) {
        const [m_xmin, m_ymin, m_xmax, m_ymax] = extent;
        const [g_xmin, g_ymin] = meters_to_geographic(m_xmin, m_ymin);
        const [g_xmax, g_ymax] = meters_to_geographic(m_xmax, m_ymax);
        return [g_xmin, g_ymin, g_xmax, g_ymax];
    }
    exports.meters_extent_to_geographic = meters_extent_to_geographic;
},
/* models/tiles/quadkey_tile_source.js */ function _(require, module, exports) {
    const mercator_tile_source_1 = require(295) /* ./mercator_tile_source */;
    class QUADKEYTileSource extends mercator_tile_source_1.MercatorTileSource {
        constructor(attrs) {
            super(attrs);
        }
        get_image_url(x, y, z) {
            const image_url = this.string_lookup_replace(this.url, this.extra_url_vars);
            const [wx, wy, wz] = this.tms_to_wmts(x, y, z);
            const quadKey = this.tile_xyz_to_quadkey(wx, wy, wz);
            return image_url.replace("{Q}", quadKey);
        }
    }
    exports.QUADKEYTileSource = QUADKEYTileSource;
    QUADKEYTileSource.__name__ = "QUADKEYTileSource";
},
/* models/tiles/tile_renderer.js */ function _(require, module, exports) {
    const wmts_tile_source_1 = require(300) /* ./wmts_tile_source */;
    const data_renderer_1 = require(74) /* ../renderers/data_renderer */;
    const range1d_1 = require(123) /* ../ranges/range1d */;
    const dom_1 = require(61) /* ../../core/dom */;
    const p = require(18) /* ../../core/properties */;
    const image_1 = require(216) /* ../../core/util/image */;
    const array_1 = require(8) /* ../../core/util/array */;
    const types_1 = require(7) /* ../../core/util/types */;
    const selection_manager_1 = require(72) /* ../../core/selection_manager */;
    const column_data_source_1 = require(68) /* ../sources/column_data_source */;
    const tiles_1 = require(301) /* ../../styles/tiles */;
    class TileRendererView extends data_renderer_1.DataRendererView {
        initialize() {
            this._tiles = [];
            super.initialize();
        }
        connect_signals() {
            super.connect_signals();
            this.connect(this.model.change, () => this.request_render());
            this.connect(this.model.tile_source.change, () => this.request_render());
        }
        get_extent() {
            return [this.x_range.start, this.y_range.start, this.x_range.end, this.y_range.end];
        }
        get map_plot() {
            return this.plot_model;
        }
        get map_canvas() {
            return this.plot_view.canvas_view.ctx;
        }
        get map_frame() {
            return this.plot_view.frame;
        }
        get x_range() {
            return this.map_plot.x_range;
        }
        get y_range() {
            return this.map_plot.y_range;
        }
        _set_data() {
            this.extent = this.get_extent();
            this._last_height = undefined;
            this._last_width = undefined;
        }
        _update_attribution() {
            if (this.attribution_el != null)
                dom_1.removeElement(this.attribution_el);
            const { attribution } = this.model.tile_source;
            if (types_1.isString(attribution) && attribution.length > 0) {
                const { layout, frame } = this.plot_view;
                const offset_right = layout._width.value - frame._right.value;
                const offset_bottom = layout._height.value - frame._bottom.value;
                const max_width = frame._width.value;
                this.attribution_el = dom_1.div({
                    class: tiles_1.bk_tile_attribution,
                    style: {
                        position: "absolute",
                        right: `${offset_right}px`,
                        bottom: `${offset_bottom}px`,
                        'max-width': `${max_width - 4 /*padding*/}px`,
                        padding: "2px",
                        'background-color': 'rgba(255,255,255,0.5)',
                        'font-size': '7pt',
                        'line-height': '1.05',
                        'white-space': 'nowrap',
                        overflow: 'hidden',
                        'text-overflow': 'ellipsis',
                    },
                });
                const overlays = this.plot_view.canvas_view.events_el;
                overlays.appendChild(this.attribution_el);
                this.attribution_el.innerHTML = attribution;
                this.attribution_el.title = this.attribution_el.textContent.replace(/\s*\n\s*/g, " ");
            }
        }
        _map_data() {
            this.initial_extent = this.get_extent();
            const zoom_level = this.model.tile_source.get_level_by_extent(this.initial_extent, this.map_frame._height.value, this.map_frame._width.value);
            const new_extent = this.model.tile_source.snap_to_zoom_level(this.initial_extent, this.map_frame._height.value, this.map_frame._width.value, zoom_level);
            this.x_range.start = new_extent[0];
            this.y_range.start = new_extent[1];
            this.x_range.end = new_extent[2];
            this.y_range.end = new_extent[3];
            if (this.x_range instanceof range1d_1.Range1d) {
                this.x_range.reset_start = new_extent[0];
                this.x_range.reset_end = new_extent[2];
            }
            if (this.y_range instanceof range1d_1.Range1d) {
                this.y_range.reset_start = new_extent[1];
                this.y_range.reset_end = new_extent[3];
            }
            this._update_attribution();
        }
        _create_tile(x, y, z, bounds, cache_only = false) {
            const [nx, ny, nz] = this.model.tile_source.normalize_xyz(x, y, z);
            const tile = {
                img: undefined,
                tile_coords: [x, y, z],
                normalized_coords: [nx, ny, nz],
                quadkey: this.model.tile_source.tile_xyz_to_quadkey(x, y, z),
                cache_key: this.model.tile_source.tile_xyz_to_key(x, y, z),
                bounds,
                loaded: false,
                finished: false,
                x_coord: bounds[0],
                y_coord: bounds[3],
            };
            const src = this.model.tile_source.get_image_url(nx, ny, nz);
            new image_1.ImageLoader(src, {
                loaded: (img) => {
                    Object.assign(tile, { img, loaded: true });
                    if (cache_only) {
                        tile.finished = true;
                        this.notify_finished();
                    }
                    else
                        this.request_render();
                },
                failed() {
                    tile.finished = true;
                },
            });
            this.model.tile_source.tiles.set(tile.cache_key, tile);
            this._tiles.push(tile);
        }
        _enforce_aspect_ratio() {
            // brute force way of handling resize or sizing_mode event -------------------------------------------------------------
            if ((this._last_height !== this.map_frame._height.value) || (this._last_width !== this.map_frame._width.value)) {
                const extent = this.get_extent();
                const zoom_level = this.model.tile_source.get_level_by_extent(extent, this.map_frame._height.value, this.map_frame._width.value);
                const new_extent = this.model.tile_source.snap_to_zoom_level(extent, this.map_frame._height.value, this.map_frame._width.value, zoom_level);
                this.x_range.setv({ start: new_extent[0], end: new_extent[2] });
                this.y_range.setv({ start: new_extent[1], end: new_extent[3] });
                this.extent = new_extent;
                this._last_height = this.map_frame._height.value;
                this._last_width = this.map_frame._width.value;
            }
        }
        has_finished() {
            if (!super.has_finished()) {
                return false;
            }
            if (this._tiles.length === 0) {
                return false;
            }
            for (const tile of this._tiles) {
                if (!tile.finished) {
                    return false;
                }
            }
            return true;
        }
        render() {
            if (this.map_initialized == null) {
                this._set_data();
                this._map_data();
                this.map_initialized = true;
            }
            this._enforce_aspect_ratio();
            this._update();
            if (this.prefetch_timer != null) {
                clearTimeout(this.prefetch_timer);
            }
            this.prefetch_timer = setTimeout(this._prefetch_tiles.bind(this), 500);
            if (this.has_finished()) {
                this.notify_finished();
            }
        }
        _draw_tile(tile_key) {
            const tile_data = this.model.tile_source.tiles.get(tile_key);
            if (tile_data != null && tile_data.loaded) {
                const [[sxmin], [symin]] = this.plot_view.map_to_screen([tile_data.bounds[0]], [tile_data.bounds[3]]);
                const [[sxmax], [symax]] = this.plot_view.map_to_screen([tile_data.bounds[2]], [tile_data.bounds[1]]);
                const sw = sxmax - sxmin;
                const sh = symax - symin;
                const sx = sxmin;
                const sy = symin;
                const old_smoothing = this.map_canvas.getImageSmoothingEnabled();
                this.map_canvas.setImageSmoothingEnabled(this.model.smoothing);
                this.map_canvas.drawImage(tile_data.img, sx, sy, sw, sh);
                this.map_canvas.setImageSmoothingEnabled(old_smoothing);
                tile_data.finished = true;
            }
        }
        _set_rect() {
            const outline_width = this.plot_model.properties.outline_line_width.value();
            const l = this.map_frame._left.value + (outline_width / 2);
            const t = this.map_frame._top.value + (outline_width / 2);
            const w = this.map_frame._width.value - outline_width;
            const h = this.map_frame._height.value - outline_width;
            this.map_canvas.rect(l, t, w, h);
            this.map_canvas.clip();
        }
        _render_tiles(tile_keys) {
            this.map_canvas.save();
            this._set_rect();
            this.map_canvas.globalAlpha = this.model.alpha;
            for (const tile_key of tile_keys) {
                this._draw_tile(tile_key);
            }
            this.map_canvas.restore();
        }
        _prefetch_tiles() {
            const { tile_source } = this.model;
            const extent = this.get_extent();
            const h = this.map_frame._height.value;
            const w = this.map_frame._width.value;
            const zoom_level = this.model.tile_source.get_level_by_extent(extent, h, w);
            const tiles = this.model.tile_source.get_tiles_by_extent(extent, zoom_level);
            for (let t = 0, end = Math.min(10, tiles.length); t < end; t++) {
                const [x, y, z] = tiles[t];
                const children = this.model.tile_source.children_by_tile_xyz(x, y, z);
                for (const c of children) {
                    const [cx, cy, cz, cbounds] = c;
                    if (tile_source.tiles.has(tile_source.tile_xyz_to_key(cx, cy, cz))) {
                        continue;
                    }
                    else {
                        this._create_tile(cx, cy, cz, cbounds, true);
                    }
                }
            }
        }
        _fetch_tiles(tiles) {
            for (const tile of tiles) {
                const [x, y, z, bounds] = tile;
                this._create_tile(x, y, z, bounds);
            }
        }
        _update() {
            const { tile_source } = this.model;
            const { min_zoom } = tile_source;
            const { max_zoom } = tile_source;
            let extent = this.get_extent();
            const zooming_out = (this.extent[2] - this.extent[0]) < (extent[2] - extent[0]);
            const h = this.map_frame._height.value;
            const w = this.map_frame._width.value;
            let zoom_level = tile_source.get_level_by_extent(extent, h, w);
            let snap_back = false;
            if (zoom_level < min_zoom) {
                extent = this.extent;
                zoom_level = min_zoom;
                snap_back = true;
            }
            else if (zoom_level > max_zoom) {
                extent = this.extent;
                zoom_level = max_zoom;
                snap_back = true;
            }
            if (snap_back) {
                this.x_range.setv({ x_range: { start: extent[0], end: extent[2] } });
                this.y_range.setv({ start: extent[1], end: extent[3] });
                this.extent = extent;
            }
            this.extent = extent;
            const tiles = tile_source.get_tiles_by_extent(extent, zoom_level);
            const need_load = [];
            const cached = [];
            const parents = [];
            const children = [];
            for (const t of tiles) {
                const [x, y, z] = t;
                const key = tile_source.tile_xyz_to_key(x, y, z);
                const tile = tile_source.tiles.get(key);
                if (tile != null && tile.loaded) {
                    cached.push(key);
                }
                else {
                    if (this.model.render_parents) {
                        const [px, py, pz] = tile_source.get_closest_parent_by_tile_xyz(x, y, z);
                        const parent_key = tile_source.tile_xyz_to_key(px, py, pz);
                        const parent_tile = tile_source.tiles.get(parent_key);
                        if ((parent_tile != null) && parent_tile.loaded && !array_1.includes(parents, parent_key)) {
                            parents.push(parent_key);
                        }
                        if (zooming_out) {
                            const child_tiles = tile_source.children_by_tile_xyz(x, y, z);
                            for (const [cx, cy, cz] of child_tiles) {
                                const child_key = tile_source.tile_xyz_to_key(cx, cy, cz);
                                if (tile_source.tiles.has(child_key))
                                    children.push(child_key);
                            }
                        }
                    }
                }
                if (tile == null)
                    need_load.push(t);
            }
            // draw stand-in parents ----------
            this._render_tiles(parents);
            this._render_tiles(children);
            // draw cached ----------
            this._render_tiles(cached);
            // fetch missing -------
            if (this.render_timer != null) {
                clearTimeout(this.render_timer);
            }
            this.render_timer = setTimeout((() => this._fetch_tiles(need_load)), 65);
        }
    }
    exports.TileRendererView = TileRendererView;
    TileRendererView.__name__ = "TileRendererView";
    class TileRenderer extends data_renderer_1.DataRenderer {
        constructor(attrs) {
            super(attrs);
            // XXX: tile renderer doesn't allow selection, but needs to fulfil the APIs
            this._selection_manager = new selection_manager_1.SelectionManager({
                source: new column_data_source_1.ColumnDataSource(),
            });
        }
        static init_TileRenderer() {
            this.prototype.default_view = TileRendererView;
            this.define({
                alpha: [p.Number, 1.0],
                smoothing: [p.Boolean, true],
                tile_source: [p.Instance, () => new wmts_tile_source_1.WMTSTileSource()],
                render_parents: [p.Boolean, true],
            });
        }
        get_selection_manager() {
            return this._selection_manager;
        }
    }
    exports.TileRenderer = TileRenderer;
    TileRenderer.__name__ = "TileRenderer";
    TileRenderer.init_TileRenderer();
},
/* models/tiles/wmts_tile_source.js */ function _(require, module, exports) {
    const mercator_tile_source_1 = require(295) /* ./mercator_tile_source */;
    class WMTSTileSource extends mercator_tile_source_1.MercatorTileSource {
        constructor(attrs) {
            super(attrs);
        }
        get_image_url(x, y, z) {
            const image_url = this.string_lookup_replace(this.url, this.extra_url_vars);
            const [wx, wy, wz] = this.tms_to_wmts(x, y, z);
            return image_url
                .replace("{X}", wx.toString())
                .replace("{Y}", wy.toString())
                .replace("{Z}", wz.toString());
        }
    }
    exports.WMTSTileSource = WMTSTileSource;
    WMTSTileSource.__name__ = "WMTSTileSource";
},
/* styles/tiles.js */ function _(require, module, exports) {
    require(62) /* ./root */;
    const _a = require(61) /* ../core/dom */;
    _a.styles.append(".bk-root .bk-tile-attribution a {\n  color: black;\n}\n");
    exports.bk_tile_attribution = "bk-tile-attribution";
},
/* models/tiles/tms_tile_source.js */ function _(require, module, exports) {
    const mercator_tile_source_1 = require(295) /* ./mercator_tile_source */;
    class TMSTileSource extends mercator_tile_source_1.MercatorTileSource {
        constructor(attrs) {
            super(attrs);
        }
        get_image_url(x, y, z) {
            const image_url = this.string_lookup_replace(this.url, this.extra_url_vars);
            return image_url
                .replace("{X}", x.toString())
                .replace('{Y}', y.toString())
                .replace("{Z}", z.toString());
        }
    }
    exports.TMSTileSource = TMSTileSource;
    TMSTileSource.__name__ = "TMSTileSource";
},
/* models/textures/index.js */ function _(require, module, exports) {
    var canvas_texture_1 = require(304) /* ./canvas_texture */;
    exports.CanvasTexture = canvas_texture_1.CanvasTexture;
    var image_url_texture_1 = require(306) /* ./image_url_texture */;
    exports.ImageURLTexture = image_url_texture_1.ImageURLTexture;
    var texture_1 = require(305) /* ./texture */;
    exports.Texture = texture_1.Texture;
},
/* models/textures/canvas_texture.js */ function _(require, module, exports) {
    const texture_1 = require(305) /* ./texture */;
    const p = require(18) /* ../../core/properties */;
    const string_1 = require(25) /* ../../core/util/string */;
    class CanvasTexture extends texture_1.Texture {
        constructor(attrs) {
            super(attrs);
        }
        static init_CanvasTexture() {
            this.define({
                code: [p.String],
            });
        }
        get func() {
            const code = string_1.use_strict(this.code);
            return new Function("ctx", "color", "scale", "weight", "require", "exports", code);
        }
        get_pattern(color, scale, weight) {
            return (ctx) => {
                const canvas = document.createElement('canvas');
                canvas.width = scale;
                canvas.height = scale;
                const pattern_ctx = canvas.getContext('2d');
                this.func.call(this, pattern_ctx, color, scale, weight, require, {});
                return ctx.createPattern(canvas, this.repetition);
            };
        }
    }
    exports.CanvasTexture = CanvasTexture;
    CanvasTexture.__name__ = "CanvasTexture";
    CanvasTexture.init_CanvasTexture();
},
/* models/textures/texture.js */ function _(require, module, exports) {
    const model_1 = require(64) /* ../../model */;
    const p = require(18) /* ../../core/properties */;
    class Texture extends model_1.Model {
        constructor(attrs) {
            super(attrs);
        }
        static init_Texture() {
            this.define({
                repetition: [p.TextureRepetition, "repeat"],
            });
        }
        onload(defer_func) {
            defer_func();
        }
    }
    exports.Texture = Texture;
    Texture.__name__ = "Texture";
    Texture.init_Texture();
},
/* models/textures/image_url_texture.js */ function _(require, module, exports) {
    const texture_1 = require(305) /* ./texture */;
    const p = require(18) /* ../../core/properties */;
    const image_1 = require(216) /* ../../core/util/image */;
    class ImageURLTexture extends texture_1.Texture {
        constructor(attrs) {
            super(attrs);
        }
        static init_ImageURLTexture() {
            this.define({
                url: [p.String],
            });
        }
        initialize() {
            super.initialize();
            this._loader = new image_1.ImageLoader(this.url);
        }
        get_pattern(_color, _scale, _weight) {
            return (ctx) => {
                if (!this._loader.finished) {
                    return null;
                }
                return ctx.createPattern(this._loader.image, this.repetition);
            };
        }
        onload(defer_func) {
            this._loader.promise.then(() => defer_func());
        }
    }
    exports.ImageURLTexture = ImageURLTexture;
    ImageURLTexture.__name__ = "ImageURLTexture";
    ImageURLTexture.init_ImageURLTexture();
},
/* models/tools/index.js */ function _(require, module, exports) {
    var action_tool_1 = require(269) /* ./actions/action_tool */;
    exports.ActionTool = action_tool_1.ActionTool;
    var custom_action_1 = require(308) /* ./actions/custom_action */;
    exports.CustomAction = custom_action_1.CustomAction;
    var help_tool_1 = require(270) /* ./actions/help_tool */;
    exports.HelpTool = help_tool_1.HelpTool;
    var redo_tool_1 = require(309) /* ./actions/redo_tool */;
    exports.RedoTool = redo_tool_1.RedoTool;
    var reset_tool_1 = require(310) /* ./actions/reset_tool */;
    exports.ResetTool = reset_tool_1.ResetTool;
    var save_tool_1 = require(311) /* ./actions/save_tool */;
    exports.SaveTool = save_tool_1.SaveTool;
    var undo_tool_1 = require(312) /* ./actions/undo_tool */;
    exports.UndoTool = undo_tool_1.UndoTool;
    var zoom_in_tool_1 = require(313) /* ./actions/zoom_in_tool */;
    exports.ZoomInTool = zoom_in_tool_1.ZoomInTool;
    var zoom_out_tool_1 = require(315) /* ./actions/zoom_out_tool */;
    exports.ZoomOutTool = zoom_out_tool_1.ZoomOutTool;
    var button_tool_1 = require(263) /* ./button_tool */;
    exports.ButtonTool = button_tool_1.ButtonTool;
    var edit_tool_1 = require(316) /* ./edit/edit_tool */;
    exports.EditTool = edit_tool_1.EditTool;
    var box_edit_tool_1 = require(317) /* ./edit/box_edit_tool */;
    exports.BoxEditTool = box_edit_tool_1.BoxEditTool;
    var freehand_draw_tool_1 = require(318) /* ./edit/freehand_draw_tool */;
    exports.FreehandDrawTool = freehand_draw_tool_1.FreehandDrawTool;
    var point_draw_tool_1 = require(319) /* ./edit/point_draw_tool */;
    exports.PointDrawTool = point_draw_tool_1.PointDrawTool;
    var poly_draw_tool_1 = require(320) /* ./edit/poly_draw_tool */;
    exports.PolyDrawTool = poly_draw_tool_1.PolyDrawTool;
    var poly_tool_1 = require(321) /* ./edit/poly_tool */;
    exports.PolyTool = poly_tool_1.PolyTool;
    var poly_edit_tool_1 = require(322) /* ./edit/poly_edit_tool */;
    exports.PolyEditTool = poly_edit_tool_1.PolyEditTool;
    var box_select_tool_1 = require(323) /* ./gestures/box_select_tool */;
    exports.BoxSelectTool = box_select_tool_1.BoxSelectTool;
    var box_zoom_tool_1 = require(326) /* ./gestures/box_zoom_tool */;
    exports.BoxZoomTool = box_zoom_tool_1.BoxZoomTool;
    var gesture_tool_1 = require(268) /* ./gestures/gesture_tool */;
    exports.GestureTool = gesture_tool_1.GestureTool;
    var lasso_select_tool_1 = require(327) /* ./gestures/lasso_select_tool */;
    exports.LassoSelectTool = lasso_select_tool_1.LassoSelectTool;
    var pan_tool_1 = require(328) /* ./gestures/pan_tool */;
    exports.PanTool = pan_tool_1.PanTool;
    var poly_select_tool_1 = require(329) /* ./gestures/poly_select_tool */;
    exports.PolySelectTool = poly_select_tool_1.PolySelectTool;
    var range_tool_1 = require(330) /* ./gestures/range_tool */;
    exports.RangeTool = range_tool_1.RangeTool;
    var select_tool_1 = require(324) /* ./gestures/select_tool */;
    exports.SelectTool = select_tool_1.SelectTool;
    var tap_tool_1 = require(331) /* ./gestures/tap_tool */;
    exports.TapTool = tap_tool_1.TapTool;
    var wheel_pan_tool_1 = require(332) /* ./gestures/wheel_pan_tool */;
    exports.WheelPanTool = wheel_pan_tool_1.WheelPanTool;
    var wheel_zoom_tool_1 = require(333) /* ./gestures/wheel_zoom_tool */;
    exports.WheelZoomTool = wheel_zoom_tool_1.WheelZoomTool;
    var crosshair_tool_1 = require(334) /* ./inspectors/crosshair_tool */;
    exports.CrosshairTool = crosshair_tool_1.CrosshairTool;
    var customjs_hover_1 = require(335) /* ./inspectors/customjs_hover */;
    exports.CustomJSHover = customjs_hover_1.CustomJSHover;
    var hover_tool_1 = require(336) /* ./inspectors/hover_tool */;
    exports.HoverTool = hover_tool_1.HoverTool;
    var inspect_tool_1 = require(262) /* ./inspectors/inspect_tool */;
    exports.InspectTool = inspect_tool_1.InspectTool;
    var tool_1 = require(264) /* ./tool */;
    exports.Tool = tool_1.Tool;
    var tool_proxy_1 = require(337) /* ./tool_proxy */;
    exports.ToolProxy = tool_proxy_1.ToolProxy;
    var toolbar_1 = require(261) /* ./toolbar */;
    exports.Toolbar = toolbar_1.Toolbar;
    var toolbar_base_1 = require(267) /* ./toolbar_base */;
    exports.ToolbarBase = toolbar_base_1.ToolbarBase;
    var toolbar_box_1 = require(338) /* ./toolbar_box */;
    exports.ProxyToolbar = toolbar_box_1.ProxyToolbar;
    var toolbar_box_2 = require(338) /* ./toolbar_box */;
    exports.ToolbarBox = toolbar_box_2.ToolbarBox;
},
/* models/tools/actions/custom_action.js */ function _(require, module, exports) {
    const action_tool_1 = require(269) /* ./action_tool */;
    const p = require(18) /* ../../../core/properties */;
    const toolbar_1 = require(265) /* ../../../styles/toolbar */;
    class CustomActionButtonView extends action_tool_1.ActionToolButtonView {
        css_classes() {
            return super.css_classes().concat(toolbar_1.bk_toolbar_button_custom_action);
        }
    }
    exports.CustomActionButtonView = CustomActionButtonView;
    CustomActionButtonView.__name__ = "CustomActionButtonView";
    class CustomActionView extends action_tool_1.ActionToolView {
        doit() {
            if (this.model.callback != null)
                this.model.callback.execute(this.model);
        }
    }
    exports.CustomActionView = CustomActionView;
    CustomActionView.__name__ = "CustomActionView";
    class CustomAction extends action_tool_1.ActionTool {
        constructor(attrs) {
            super(attrs);
            this.tool_name = "Custom Action";
            this.button_view = CustomActionButtonView;
        }
        static init_CustomAction() {
            this.prototype.default_view = CustomActionView;
            this.define({
                action_tooltip: [p.String, 'Perform a Custom Action'],
                callback: [p.Any],
                icon: [p.String],
            });
        }
        get tooltip() {
            return this.action_tooltip;
        }
    }
    exports.CustomAction = CustomAction;
    CustomAction.__name__ = "CustomAction";
    CustomAction.init_CustomAction();
},
/* models/tools/actions/redo_tool.js */ function _(require, module, exports) {
    const action_tool_1 = require(269) /* ./action_tool */;
    const icons_1 = require(271) /* ../../../styles/icons */;
    class RedoToolView extends action_tool_1.ActionToolView {
        connect_signals() {
            super.connect_signals();
            this.connect(this.plot_view.state_changed, () => this.model.disabled = !this.plot_view.can_redo());
        }
        doit() {
            this.plot_view.redo();
        }
    }
    exports.RedoToolView = RedoToolView;
    RedoToolView.__name__ = "RedoToolView";
    class RedoTool extends action_tool_1.ActionTool {
        constructor(attrs) {
            super(attrs);
            this.tool_name = "Redo";
            this.icon = icons_1.bk_tool_icon_redo;
        }
        static init_RedoTool() {
            this.prototype.default_view = RedoToolView;
            this.override({
                disabled: true,
            });
        }
    }
    exports.RedoTool = RedoTool;
    RedoTool.__name__ = "RedoTool";
    RedoTool.init_RedoTool();
},
/* models/tools/actions/reset_tool.js */ function _(require, module, exports) {
    const action_tool_1 = require(269) /* ./action_tool */;
    const icons_1 = require(271) /* ../../../styles/icons */;
    class ResetToolView extends action_tool_1.ActionToolView {
        doit() {
            this.plot_view.reset();
        }
    }
    exports.ResetToolView = ResetToolView;
    ResetToolView.__name__ = "ResetToolView";
    class ResetTool extends action_tool_1.ActionTool {
        constructor(attrs) {
            super(attrs);
            this.tool_name = "Reset";
            this.icon = icons_1.bk_tool_icon_reset;
        }
        static init_ResetTool() {
            this.prototype.default_view = ResetToolView;
        }
    }
    exports.ResetTool = ResetTool;
    ResetTool.__name__ = "ResetTool";
    ResetTool.init_ResetTool();
},
/* models/tools/actions/save_tool.js */ function _(require, module, exports) {
    const action_tool_1 = require(269) /* ./action_tool */;
    const icons_1 = require(271) /* ../../../styles/icons */;
    class SaveToolView extends action_tool_1.ActionToolView {
        doit() {
            this.plot_view.save("bokeh_plot");
        }
    }
    exports.SaveToolView = SaveToolView;
    SaveToolView.__name__ = "SaveToolView";
    class SaveTool extends action_tool_1.ActionTool {
        constructor(attrs) {
            super(attrs);
            this.tool_name = "Save";
            this.icon = icons_1.bk_tool_icon_save;
        }
        static init_SaveTool() {
            this.prototype.default_view = SaveToolView;
        }
    }
    exports.SaveTool = SaveTool;
    SaveTool.__name__ = "SaveTool";
    SaveTool.init_SaveTool();
},
/* models/tools/actions/undo_tool.js */ function _(require, module, exports) {
    const action_tool_1 = require(269) /* ./action_tool */;
    const icons_1 = require(271) /* ../../../styles/icons */;
    class UndoToolView extends action_tool_1.ActionToolView {
        connect_signals() {
            super.connect_signals();
            this.connect(this.plot_view.state_changed, () => this.model.disabled = !this.plot_view.can_undo());
        }
        doit() {
            this.plot_view.undo();
        }
    }
    exports.UndoToolView = UndoToolView;
    UndoToolView.__name__ = "UndoToolView";
    class UndoTool extends action_tool_1.ActionTool {
        constructor(attrs) {
            super(attrs);
            this.tool_name = "Undo";
            this.icon = icons_1.bk_tool_icon_undo;
        }
        static init_UndoTool() {
            this.prototype.default_view = UndoToolView;
            this.override({
                disabled: true,
            });
        }
    }
    exports.UndoTool = UndoTool;
    UndoTool.__name__ = "UndoTool";
    UndoTool.init_UndoTool();
},
/* models/tools/actions/zoom_in_tool.js */ function _(require, module, exports) {
    const action_tool_1 = require(269) /* ./action_tool */;
    const zoom_1 = require(314) /* ../../../core/util/zoom */;
    const p = require(18) /* ../../../core/properties */;
    const icons_1 = require(271) /* ../../../styles/icons */;
    class ZoomInToolView extends action_tool_1.ActionToolView {
        doit() {
            const frame = this.plot_view.frame;
            const dims = this.model.dimensions;
            // restrict to axis configured in tool's dimensions property
            const h_axis = dims == 'width' || dims == 'both';
            const v_axis = dims == 'height' || dims == 'both';
            const zoom_info = zoom_1.scale_range(frame, this.model.factor, h_axis, v_axis);
            this.plot_view.push_state('zoom_out', { range: zoom_info });
            this.plot_view.update_range(zoom_info, false, true);
            if (this.model.document)
                this.model.document.interactive_start(this.plot_model);
        }
    }
    exports.ZoomInToolView = ZoomInToolView;
    ZoomInToolView.__name__ = "ZoomInToolView";
    class ZoomInTool extends action_tool_1.ActionTool {
        constructor(attrs) {
            super(attrs);
            this.tool_name = "Zoom In";
            this.icon = icons_1.bk_tool_icon_zoom_in;
        }
        static init_ZoomInTool() {
            this.prototype.default_view = ZoomInToolView;
            this.define({
                factor: [p.Percent, 0.1],
                dimensions: [p.Dimensions, "both"],
            });
        }
        get tooltip() {
            return this._get_dim_tooltip(this.tool_name, this.dimensions);
        }
    }
    exports.ZoomInTool = ZoomInTool;
    ZoomInTool.__name__ = "ZoomInTool";
    ZoomInTool.init_ZoomInTool();
},
/* core/util/zoom.js */ function _(require, module, exports) {
    const math_1 = require(9) /* ./math */;
    // Module for zoom-related functions
    function scale_highlow(range, factor, center) {
        const [low, high] = [range.start, range.end];
        const x = center != null ? center : (high + low) / 2.0;
        const x0 = low - (low - x) * factor;
        const x1 = high - (high - x) * factor;
        return [x0, x1];
    }
    exports.scale_highlow = scale_highlow;
    function get_info(scales, [sxy0, sxy1]) {
        const info = {};
        for (const name in scales) {
            const scale = scales[name];
            const [start, end] = scale.r_invert(sxy0, sxy1);
            info[name] = { start, end };
        }
        return info;
    }
    exports.get_info = get_info;
    function scale_range(frame, factor, h_axis = true, v_axis = true, center) {
        /*
         * Utility function for zoom tools to calculate/create the zoom_info object
         * of the form required by ``PlotView.update_range``
         *
         * Parameters:
         *   frame : CartesianFrame
         *   factor : Number
         *   h_axis : Boolean, optional
         *     whether to zoom the horizontal axis (default = true)
         *   v_axis : Boolean, optional
         *     whether to zoom the horizontal axis (default = true)
         *   center : object, optional
         *     of form {'x': Number, 'y', Number}
         *
         * Returns:
         *   object:
         */
        // clamp the  magnitude of factor, if it is > 1 bad things happen
        factor = math_1.clamp(factor, -0.9, 0.9);
        const hfactor = h_axis ? factor : 0;
        const [sx0, sx1] = scale_highlow(frame.bbox.h_range, hfactor, center != null ? center.x : undefined);
        const xrs = get_info(frame.xscales, [sx0, sx1]);
        const vfactor = v_axis ? factor : 0;
        const [sy0, sy1] = scale_highlow(frame.bbox.v_range, vfactor, center != null ? center.y : undefined);
        const yrs = get_info(frame.yscales, [sy0, sy1]);
        // OK this sucks we can't set factor independently in each direction. It is used
        // for GMap plots, and GMap plots always preserve aspect, so effective the value
        // of 'dimensions' is ignored.
        return { xrs, yrs, factor };
    }
    exports.scale_range = scale_range;
},
/* models/tools/actions/zoom_out_tool.js */ function _(require, module, exports) {
    const action_tool_1 = require(269) /* ./action_tool */;
    const zoom_1 = require(314) /* ../../../core/util/zoom */;
    const p = require(18) /* ../../../core/properties */;
    const icons_1 = require(271) /* ../../../styles/icons */;
    class ZoomOutToolView extends action_tool_1.ActionToolView {
        doit() {
            const frame = this.plot_view.frame;
            const dims = this.model.dimensions;
            // restrict to axis configured in tool's dimensions property
            const h_axis = dims == 'width' || dims == 'both';
            const v_axis = dims == 'height' || dims == 'both';
            // zooming out requires a negative factor to scale_range
            const zoom_info = zoom_1.scale_range(frame, -this.model.factor, h_axis, v_axis);
            this.plot_view.push_state('zoom_out', { range: zoom_info });
            this.plot_view.update_range(zoom_info, false, true);
            if (this.model.document)
                this.model.document.interactive_start(this.plot_model);
        }
    }
    exports.ZoomOutToolView = ZoomOutToolView;
    ZoomOutToolView.__name__ = "ZoomOutToolView";
    class ZoomOutTool extends action_tool_1.ActionTool {
        constructor(attrs) {
            super(attrs);
            this.tool_name = "Zoom Out";
            this.icon = icons_1.bk_tool_icon_zoom_out;
        }
        static init_ZoomOutTool() {
            this.prototype.default_view = ZoomOutToolView;
            this.define({
                factor: [p.Percent, 0.1],
                dimensions: [p.Dimensions, "both"],
            });
        }
        get tooltip() {
            return this._get_dim_tooltip(this.tool_name, this.dimensions);
        }
    }
    exports.ZoomOutTool = ZoomOutTool;
    ZoomOutTool.__name__ = "ZoomOutTool";
    ZoomOutTool.init_ZoomOutTool();
},
/* models/tools/edit/edit_tool.js */ function _(require, module, exports) {
    const p = require(18) /* ../../../core/properties */;
    const array_1 = require(8) /* ../../../core/util/array */;
    const types_1 = require(7) /* ../../../core/util/types */;
    const gesture_tool_1 = require(268) /* ../gestures/gesture_tool */;
    class EditToolView extends gesture_tool_1.GestureToolView {
        constructor() {
            super(...arguments);
            this._mouse_in_frame = true;
        }
        _move_enter(_e) {
            this._mouse_in_frame = true;
        }
        _move_exit(_e) {
            this._mouse_in_frame = false;
        }
        _map_drag(sx, sy, renderer) {
            // Maps screen to data coordinates
            const frame = this.plot_view.frame;
            if (!frame.bbox.contains(sx, sy)) {
                return null;
            }
            const x = frame.xscales[renderer.x_range_name].invert(sx);
            const y = frame.yscales[renderer.y_range_name].invert(sy);
            return [x, y];
        }
        _delete_selected(renderer) {
            // Deletes all selected rows in the ColumnDataSource
            const cds = renderer.data_source;
            const indices = cds.selected.indices;
            indices.sort();
            for (const column of cds.columns()) {
                const values = cds.get_array(column);
                for (let index = 0; index < indices.length; index++) {
                    const ind = indices[index];
                    values.splice(ind - index, 1);
                }
            }
            this._emit_cds_changes(cds);
        }
        _pop_glyphs(cds, num_objects) {
            // Pops rows in the CDS until only num_objects are left
            const columns = cds.columns();
            if (!num_objects || !columns.length)
                return;
            for (const column of columns) {
                let array = cds.get_array(column);
                const drop = array.length - num_objects + 1;
                if (drop < 1)
                    continue;
                if (!types_1.isArray(array)) {
                    array = Array.from(array);
                    cds.data[column] = array;
                }
                array.splice(0, drop);
            }
        }
        _emit_cds_changes(cds, redraw = true, clear = true, emit = true) {
            if (clear)
                cds.selection_manager.clear();
            if (redraw)
                cds.change.emit();
            if (emit) {
                cds.data = cds.data;
                cds.properties.data.change.emit();
            }
        }
        _drag_points(ev, renderers) {
            if (this._basepoint == null)
                return;
            const [bx, by] = this._basepoint;
            for (const renderer of renderers) {
                const basepoint = this._map_drag(bx, by, renderer);
                const point = this._map_drag(ev.sx, ev.sy, renderer);
                if (point == null || basepoint == null) {
                    continue;
                }
                const [x, y] = point;
                const [px, py] = basepoint;
                const [dx, dy] = [x - px, y - py];
                // Type once dataspecs are typed
                const glyph = renderer.glyph;
                const cds = renderer.data_source;
                const [xkey, ykey] = [glyph.x.field, glyph.y.field];
                for (const index of cds.selected.indices) {
                    if (xkey)
                        cds.data[xkey][index] += dx;
                    if (ykey)
                        cds.data[ykey][index] += dy;
                }
                cds.change.emit();
            }
            this._basepoint = [ev.sx, ev.sy];
        }
        _pad_empty_columns(cds, coord_columns) {
            // Pad ColumnDataSource non-coordinate columns with empty_value
            for (const column of cds.columns()) {
                if (!array_1.includes(coord_columns, column))
                    cds.get_array(column).push(this.model.empty_value);
            }
        }
        _select_event(ev, append, renderers) {
            // Process selection event on the supplied renderers and return selected renderers
            const frame = this.plot_view.frame;
            const { sx, sy } = ev;
            if (!frame.bbox.contains(sx, sy)) {
                return [];
            }
            const geometry = { type: 'point', sx, sy };
            const selected = [];
            for (const renderer of renderers) {
                const sm = renderer.get_selection_manager();
                const cds = renderer.data_source;
                const views = [this.plot_view.renderer_views[renderer.id]];
                const did_hit = sm.select(views, geometry, true, append);
                if (did_hit) {
                    selected.push(renderer);
                }
                cds.properties.selected.change.emit();
            }
            return selected;
        }
    }
    exports.EditToolView = EditToolView;
    EditToolView.__name__ = "EditToolView";
    class EditTool extends gesture_tool_1.GestureTool {
        constructor(attrs) {
            super(attrs);
        }
        static init_EditTool() {
            this.define({
                custom_icon: [p.String],
                custom_tooltip: [p.String],
                empty_value: [p.Any],
                renderers: [p.Array, []],
            });
        }
        get tooltip() {
            return this.custom_tooltip || this.tool_name;
        }
        get computed_icon() {
            return this.custom_icon || this.icon;
        }
    }
    exports.EditTool = EditTool;
    EditTool.__name__ = "EditTool";
    EditTool.init_EditTool();
},
/* models/tools/edit/box_edit_tool.js */ function _(require, module, exports) {
    const dom_1 = require(61) /* ../../../core/dom */;
    const p = require(18) /* ../../../core/properties */;
    const edit_tool_1 = require(316) /* ./edit_tool */;
    const icons_1 = require(271) /* ../../../styles/icons */;
    class BoxEditToolView extends edit_tool_1.EditToolView {
        _tap(ev) {
            if ((this._draw_basepoint != null) || (this._basepoint != null))
                return;
            const append = ev.shiftKey;
            this._select_event(ev, append, this.model.renderers);
        }
        _keyup(ev) {
            if (!this.model.active || !this._mouse_in_frame)
                return;
            for (const renderer of this.model.renderers) {
                if (ev.keyCode === dom_1.Keys.Backspace) {
                    this._delete_selected(renderer);
                }
                else if (ev.keyCode == dom_1.Keys.Esc) {
                    // Type properly once selection_manager is typed
                    const cds = renderer.data_source;
                    cds.selection_manager.clear();
                }
            }
        }
        _set_extent([sx0, sx1], [sy0, sy1], append, emit = false) {
            const renderer = this.model.renderers[0];
            const frame = this.plot_view.frame;
            // Type once dataspecs are typed
            const glyph = renderer.glyph;
            const cds = renderer.data_source;
            const xscale = frame.xscales[renderer.x_range_name];
            const yscale = frame.yscales[renderer.y_range_name];
            const [x0, x1] = xscale.r_invert(sx0, sx1);
            const [y0, y1] = yscale.r_invert(sy0, sy1);
            const [x, y] = [(x0 + x1) / 2, (y0 + y1) / 2];
            const [w, h] = [x1 - x0, y1 - y0];
            const [xkey, ykey] = [glyph.x.field, glyph.y.field];
            const [wkey, hkey] = [glyph.width.field, glyph.height.field];
            if (append) {
                this._pop_glyphs(cds, this.model.num_objects);
                if (xkey)
                    cds.get_array(xkey).push(x);
                if (ykey)
                    cds.get_array(ykey).push(y);
                if (wkey)
                    cds.get_array(wkey).push(w);
                if (hkey)
                    cds.get_array(hkey).push(h);
                this._pad_empty_columns(cds, [xkey, ykey, wkey, hkey]);
            }
            else {
                const index = cds.data[xkey].length - 1;
                if (xkey)
                    cds.data[xkey][index] = x;
                if (ykey)
                    cds.data[ykey][index] = y;
                if (wkey)
                    cds.data[wkey][index] = w;
                if (hkey)
                    cds.data[hkey][index] = h;
            }
            this._emit_cds_changes(cds, true, false, emit);
        }
        _update_box(ev, append = false, emit = false) {
            if (this._draw_basepoint == null)
                return;
            const curpoint = [ev.sx, ev.sy];
            const frame = this.plot_view.frame;
            const dims = this.model.dimensions;
            const limits = this.model._get_dim_limits(this._draw_basepoint, curpoint, frame, dims);
            if (limits != null) {
                const [sxlim, sylim] = limits;
                this._set_extent(sxlim, sylim, append, emit);
            }
        }
        _doubletap(ev) {
            if (!this.model.active)
                return;
            if (this._draw_basepoint != null) {
                this._update_box(ev, false, true);
                this._draw_basepoint = null;
            }
            else {
                this._draw_basepoint = [ev.sx, ev.sy];
                this._select_event(ev, true, this.model.renderers);
                this._update_box(ev, true, false);
            }
        }
        _move(ev) {
            this._update_box(ev, false, false);
        }
        _pan_start(ev) {
            if (ev.shiftKey) {
                if (this._draw_basepoint != null)
                    return;
                this._draw_basepoint = [ev.sx, ev.sy];
                this._update_box(ev, true, false);
            }
            else {
                if (this._basepoint != null)
                    return;
                this._select_event(ev, true, this.model.renderers);
                this._basepoint = [ev.sx, ev.sy];
            }
        }
        _pan(ev, append = false, emit = false) {
            if (ev.shiftKey) {
                if (this._draw_basepoint == null)
                    return;
                this._update_box(ev, append, emit);
            }
            else {
                if (this._basepoint == null)
                    return;
                this._drag_points(ev, this.model.renderers);
            }
        }
        _pan_end(ev) {
            this._pan(ev, false, true);
            if (ev.shiftKey) {
                this._draw_basepoint = null;
            }
            else {
                this._basepoint = null;
                for (const renderer of this.model.renderers)
                    this._emit_cds_changes(renderer.data_source, false, true, true);
            }
        }
    }
    exports.BoxEditToolView = BoxEditToolView;
    BoxEditToolView.__name__ = "BoxEditToolView";
    class BoxEditTool extends edit_tool_1.EditTool {
        constructor(attrs) {
            super(attrs);
            this.tool_name = "Box Edit Tool";
            this.icon = icons_1.bk_tool_icon_box_edit;
            this.event_type = ["tap", "pan", "move"];
            this.default_order = 1;
        }
        static init_BoxEditTool() {
            this.prototype.default_view = BoxEditToolView;
            this.define({
                dimensions: [p.Dimensions, "both"],
                num_objects: [p.Int, 0],
            });
        }
    }
    exports.BoxEditTool = BoxEditTool;
    BoxEditTool.__name__ = "BoxEditTool";
    BoxEditTool.init_BoxEditTool();
},
/* models/tools/edit/freehand_draw_tool.js */ function _(require, module, exports) {
    const dom_1 = require(61) /* ../../../core/dom */;
    const p = require(18) /* ../../../core/properties */;
    const types_1 = require(7) /* ../../../core/util/types */;
    const edit_tool_1 = require(316) /* ./edit_tool */;
    const icons_1 = require(271) /* ../../../styles/icons */;
    class FreehandDrawToolView extends edit_tool_1.EditToolView {
        _draw(ev, mode, emit = false) {
            if (!this.model.active)
                return;
            const renderer = this.model.renderers[0];
            const point = this._map_drag(ev.sx, ev.sy, renderer);
            if (point == null)
                return;
            const [x, y] = point;
            const cds = renderer.data_source;
            const glyph = renderer.glyph;
            const [xkey, ykey] = [glyph.xs.field, glyph.ys.field];
            if (mode == 'new') {
                this._pop_glyphs(cds, this.model.num_objects);
                if (xkey)
                    cds.get_array(xkey).push([x]);
                if (ykey)
                    cds.get_array(ykey).push([y]);
                this._pad_empty_columns(cds, [xkey, ykey]);
            }
            else if (mode == 'add') {
                if (xkey) {
                    const xidx = cds.data[xkey].length - 1;
                    let xs = cds.get_array(xkey)[xidx];
                    if (!types_1.isArray(xs)) {
                        xs = Array.from(xs);
                        cds.data[xkey][xidx] = xs;
                    }
                    xs.push(x);
                }
                if (ykey) {
                    const yidx = cds.data[ykey].length - 1;
                    let ys = cds.get_array(ykey)[yidx];
                    if (!types_1.isArray(ys)) {
                        ys = Array.from(ys);
                        cds.data[ykey][yidx] = ys;
                    }
                    ys.push(y);
                }
            }
            this._emit_cds_changes(cds, true, true, emit);
        }
        _pan_start(ev) {
            this._draw(ev, 'new');
        }
        _pan(ev) {
            this._draw(ev, 'add');
        }
        _pan_end(ev) {
            this._draw(ev, 'add', true);
        }
        _tap(ev) {
            this._select_event(ev, ev.shiftKey, this.model.renderers);
        }
        _keyup(ev) {
            if (!this.model.active || !this._mouse_in_frame)
                return;
            for (const renderer of this.model.renderers) {
                if (ev.keyCode === dom_1.Keys.Esc) {
                    renderer.data_source.selection_manager.clear();
                }
                else if (ev.keyCode === dom_1.Keys.Backspace) {
                    this._delete_selected(renderer);
                }
            }
        }
    }
    exports.FreehandDrawToolView = FreehandDrawToolView;
    FreehandDrawToolView.__name__ = "FreehandDrawToolView";
    class FreehandDrawTool extends edit_tool_1.EditTool {
        constructor(attrs) {
            super(attrs);
            this.tool_name = "Freehand Draw Tool";
            this.icon = icons_1.bk_tool_icon_freehand_draw;
            this.event_type = ["pan", "tap"];
            this.default_order = 3;
        }
        static init_FreehandDrawTool() {
            this.prototype.default_view = FreehandDrawToolView;
            this.define({
                num_objects: [p.Int, 0],
            });
        }
    }
    exports.FreehandDrawTool = FreehandDrawTool;
    FreehandDrawTool.__name__ = "FreehandDrawTool";
    FreehandDrawTool.init_FreehandDrawTool();
},
/* models/tools/edit/point_draw_tool.js */ function _(require, module, exports) {
    const dom_1 = require(61) /* ../../../core/dom */;
    const p = require(18) /* ../../../core/properties */;
    const edit_tool_1 = require(316) /* ./edit_tool */;
    const icons_1 = require(271) /* ../../../styles/icons */;
    class PointDrawToolView extends edit_tool_1.EditToolView {
        _tap(ev) {
            const append = ev.shiftKey;
            const renderers = this._select_event(ev, append, this.model.renderers);
            if (renderers.length || !this.model.add) {
                return;
            }
            const renderer = this.model.renderers[0];
            const point = this._map_drag(ev.sx, ev.sy, renderer);
            if (point == null)
                return;
            // Type once dataspecs are typed
            const glyph = renderer.glyph;
            const cds = renderer.data_source;
            const [xkey, ykey] = [glyph.x.field, glyph.y.field];
            const [x, y] = point;
            this._pop_glyphs(cds, this.model.num_objects);
            if (xkey)
                cds.get_array(xkey).push(x);
            if (ykey)
                cds.get_array(ykey).push(y);
            this._pad_empty_columns(cds, [xkey, ykey]);
            cds.change.emit();
            cds.data = cds.data;
            cds.properties.data.change.emit();
        }
        _keyup(ev) {
            if (!this.model.active || !this._mouse_in_frame)
                return;
            for (const renderer of this.model.renderers) {
                if (ev.keyCode === dom_1.Keys.Backspace) {
                    this._delete_selected(renderer);
                }
                else if (ev.keyCode == dom_1.Keys.Esc) {
                    renderer.data_source.selection_manager.clear();
                }
            }
        }
        _pan_start(ev) {
            if (!this.model.drag)
                return;
            this._select_event(ev, true, this.model.renderers);
            this._basepoint = [ev.sx, ev.sy];
        }
        _pan(ev) {
            if (!this.model.drag || this._basepoint == null)
                return;
            this._drag_points(ev, this.model.renderers);
        }
        _pan_end(ev) {
            if (!this.model.drag)
                return;
            this._pan(ev);
            for (const renderer of this.model.renderers)
                this._emit_cds_changes(renderer.data_source, false, true, true);
            this._basepoint = null;
        }
    }
    exports.PointDrawToolView = PointDrawToolView;
    PointDrawToolView.__name__ = "PointDrawToolView";
    class PointDrawTool extends edit_tool_1.EditTool {
        constructor(attrs) {
            super(attrs);
            this.tool_name = "Point Draw Tool";
            this.icon = icons_1.bk_tool_icon_point_draw;
            this.event_type = ["tap", "pan", "move"];
            this.default_order = 2;
        }
        static init_PointDrawTool() {
            this.prototype.default_view = PointDrawToolView;
            this.define({
                add: [p.Boolean, true],
                drag: [p.Boolean, true],
                num_objects: [p.Int, 0],
            });
        }
    }
    exports.PointDrawTool = PointDrawTool;
    PointDrawTool.__name__ = "PointDrawTool";
    PointDrawTool.init_PointDrawTool();
},
/* models/tools/edit/poly_draw_tool.js */ function _(require, module, exports) {
    const dom_1 = require(61) /* ../../../core/dom */;
    const p = require(18) /* ../../../core/properties */;
    const types_1 = require(7) /* ../../../core/util/types */;
    const poly_tool_1 = require(321) /* ./poly_tool */;
    const icons_1 = require(271) /* ../../../styles/icons */;
    class PolyDrawToolView extends poly_tool_1.PolyToolView {
        constructor() {
            super(...arguments);
            this._drawing = false;
            this._initialized = false;
        }
        _tap(ev) {
            if (this._drawing)
                this._draw(ev, 'add', true);
            else
                this._select_event(ev, ev.shiftKey, this.model.renderers);
        }
        _draw(ev, mode, emit = false) {
            const renderer = this.model.renderers[0];
            const point = this._map_drag(ev.sx, ev.sy, renderer);
            if (!this._initialized)
                this.activate(); // Ensure that activate has been called
            if (point == null)
                return;
            const [x, y] = this._snap_to_vertex(ev, ...point);
            const cds = renderer.data_source;
            const glyph = renderer.glyph;
            const [xkey, ykey] = [glyph.xs.field, glyph.ys.field];
            if (mode == 'new') {
                this._pop_glyphs(cds, this.model.num_objects);
                if (xkey)
                    cds.get_array(xkey).push([x, x]);
                if (ykey)
                    cds.get_array(ykey).push([y, y]);
                this._pad_empty_columns(cds, [xkey, ykey]);
            }
            else if (mode == 'edit') {
                if (xkey) {
                    const xs = cds.data[xkey][cds.data[xkey].length - 1];
                    xs[xs.length - 1] = x;
                }
                if (ykey) {
                    const ys = cds.data[ykey][cds.data[ykey].length - 1];
                    ys[ys.length - 1] = y;
                }
            }
            else if (mode == 'add') {
                if (xkey) {
                    const xidx = cds.data[xkey].length - 1;
                    let xs = cds.get_array(xkey)[xidx];
                    const nx = xs[xs.length - 1];
                    xs[xs.length - 1] = x;
                    if (!types_1.isArray(xs)) {
                        xs = Array.from(xs);
                        cds.data[xkey][xidx] = xs;
                    }
                    xs.push(nx);
                }
                if (ykey) {
                    const yidx = cds.data[ykey].length - 1;
                    let ys = cds.get_array(ykey)[yidx];
                    const ny = ys[ys.length - 1];
                    ys[ys.length - 1] = y;
                    if (!types_1.isArray(ys)) {
                        ys = Array.from(ys);
                        cds.data[ykey][yidx] = ys;
                    }
                    ys.push(ny);
                }
            }
            this._emit_cds_changes(cds, true, false, emit);
        }
        _show_vertices() {
            if (!this.model.active) {
                return;
            }
            const xs = [];
            const ys = [];
            for (let i = 0; i < this.model.renderers.length; i++) {
                const renderer = this.model.renderers[i];
                const cds = renderer.data_source;
                const glyph = renderer.glyph;
                const [xkey, ykey] = [glyph.xs.field, glyph.ys.field];
                if (xkey) {
                    for (const array of cds.get_array(xkey))
                        Array.prototype.push.apply(xs, array);
                }
                if (ykey) {
                    for (const array of cds.get_array(ykey))
                        Array.prototype.push.apply(ys, array);
                }
                if (this._drawing && (i == (this.model.renderers.length - 1))) {
                    // Skip currently drawn vertex
                    xs.splice(xs.length - 1, 1);
                    ys.splice(ys.length - 1, 1);
                }
            }
            this._set_vertices(xs, ys);
        }
        _doubletap(ev) {
            if (!this.model.active)
                return;
            if (this._drawing) {
                this._drawing = false;
                this._draw(ev, 'edit', true);
            }
            else {
                this._drawing = true;
                this._draw(ev, 'new', true);
            }
        }
        _move(ev) {
            if (this._drawing) {
                this._draw(ev, 'edit');
            }
        }
        _remove() {
            const renderer = this.model.renderers[0];
            const cds = renderer.data_source;
            const glyph = renderer.glyph;
            const [xkey, ykey] = [glyph.xs.field, glyph.ys.field];
            if (xkey) {
                const xidx = cds.data[xkey].length - 1;
                const xs = cds.get_array(xkey)[xidx];
                xs.splice(xs.length - 1, 1);
            }
            if (ykey) {
                const yidx = cds.data[ykey].length - 1;
                const ys = cds.get_array(ykey)[yidx];
                ys.splice(ys.length - 1, 1);
            }
            this._emit_cds_changes(cds);
        }
        _keyup(ev) {
            if (!this.model.active || !this._mouse_in_frame)
                return;
            for (const renderer of this.model.renderers) {
                if (ev.keyCode === dom_1.Keys.Backspace) {
                    this._delete_selected(renderer);
                }
                else if (ev.keyCode == dom_1.Keys.Esc) {
                    if (this._drawing) {
                        this._remove();
                        this._drawing = false;
                    }
                    renderer.data_source.selection_manager.clear();
                }
            }
        }
        _pan_start(ev) {
            if (!this.model.drag)
                return;
            this._select_event(ev, true, this.model.renderers);
            this._basepoint = [ev.sx, ev.sy];
        }
        _pan(ev) {
            if (this._basepoint == null || !this.model.drag)
                return;
            const [bx, by] = this._basepoint;
            // Process polygon/line dragging
            for (const renderer of this.model.renderers) {
                const basepoint = this._map_drag(bx, by, renderer);
                const point = this._map_drag(ev.sx, ev.sy, renderer);
                if (point == null || basepoint == null)
                    continue;
                const cds = renderer.data_source;
                // Type once dataspecs are typed
                const glyph = renderer.glyph;
                const [xkey, ykey] = [glyph.xs.field, glyph.ys.field];
                if (!xkey && !ykey)
                    continue;
                const [x, y] = point;
                const [px, py] = basepoint;
                const [dx, dy] = [x - px, y - py];
                for (const index of cds.selected.indices) {
                    let length, xs, ys;
                    if (xkey)
                        xs = cds.data[xkey][index];
                    if (ykey) {
                        ys = cds.data[ykey][index];
                        length = ys.length;
                    }
                    else {
                        length = xs.length;
                    }
                    for (let i = 0; i < length; i++) {
                        if (xs)
                            xs[i] += dx;
                        if (ys)
                            ys[i] += dy;
                    }
                }
                cds.change.emit();
            }
            this._basepoint = [ev.sx, ev.sy];
        }
        _pan_end(ev) {
            if (!this.model.drag)
                return;
            this._pan(ev);
            for (const renderer of this.model.renderers)
                this._emit_cds_changes(renderer.data_source);
            this._basepoint = null;
        }
        activate() {
            if (!this.model.vertex_renderer || !this.model.active)
                return;
            this._show_vertices();
            if (!this._initialized) {
                for (const renderer of this.model.renderers) {
                    const cds = renderer.data_source;
                    cds.connect(cds.properties.data.change, () => this._show_vertices());
                }
            }
            this._initialized = true;
        }
        deactivate() {
            if (this._drawing) {
                this._remove();
                this._drawing = false;
            }
            if (this.model.vertex_renderer)
                this._hide_vertices();
        }
    }
    exports.PolyDrawToolView = PolyDrawToolView;
    PolyDrawToolView.__name__ = "PolyDrawToolView";
    class PolyDrawTool extends poly_tool_1.PolyTool {
        constructor(attrs) {
            super(attrs);
            this.tool_name = "Polygon Draw Tool";
            this.icon = icons_1.bk_tool_icon_poly_draw;
            this.event_type = ["pan", "tap", "move"];
            this.default_order = 3;
        }
        static init_PolyDrawTool() {
            this.prototype.default_view = PolyDrawToolView;
            this.define({
                drag: [p.Boolean, true],
                num_objects: [p.Int, 0],
            });
        }
    }
    exports.PolyDrawTool = PolyDrawTool;
    PolyDrawTool.__name__ = "PolyDrawTool";
    PolyDrawTool.init_PolyDrawTool();
},
/* models/tools/edit/poly_tool.js */ function _(require, module, exports) {
    const p = require(18) /* ../../../core/properties */;
    const types_1 = require(7) /* ../../../core/util/types */;
    const edit_tool_1 = require(316) /* ./edit_tool */;
    class PolyToolView extends edit_tool_1.EditToolView {
        _set_vertices(xs, ys) {
            const point_glyph = this.model.vertex_renderer.glyph;
            const point_cds = this.model.vertex_renderer.data_source;
            const [pxkey, pykey] = [point_glyph.x.field, point_glyph.y.field];
            if (pxkey) {
                if (types_1.isArray(xs))
                    point_cds.data[pxkey] = xs;
                else
                    point_glyph.x = { value: xs };
            }
            if (pykey) {
                if (types_1.isArray(ys))
                    point_cds.data[pykey] = ys;
                else
                    point_glyph.y = { value: ys };
            }
            this._emit_cds_changes(point_cds, true, true, false);
        }
        _hide_vertices() {
            this._set_vertices([], []);
        }
        _snap_to_vertex(ev, x, y) {
            if (this.model.vertex_renderer) {
                // If an existing vertex is hit snap to it
                const vertex_selected = this._select_event(ev, false, [this.model.vertex_renderer]);
                const point_ds = this.model.vertex_renderer.data_source;
                // Type once dataspecs are typed
                const point_glyph = this.model.vertex_renderer.glyph;
                const [pxkey, pykey] = [point_glyph.x.field, point_glyph.y.field];
                if (vertex_selected.length) {
                    const index = point_ds.selected.indices[0];
                    if (pxkey)
                        x = point_ds.data[pxkey][index];
                    if (pykey)
                        y = point_ds.data[pykey][index];
                    point_ds.selection_manager.clear();
                }
            }
            return [x, y];
        }
    }
    exports.PolyToolView = PolyToolView;
    PolyToolView.__name__ = "PolyToolView";
    class PolyTool extends edit_tool_1.EditTool {
        constructor(attrs) {
            super(attrs);
        }
        static init_PolyTool() {
            this.prototype.default_view = PolyToolView;
            this.define({
                vertex_renderer: [p.Instance],
            });
        }
    }
    exports.PolyTool = PolyTool;
    PolyTool.__name__ = "PolyTool";
    PolyTool.init_PolyTool();
},
/* models/tools/edit/poly_edit_tool.js */ function _(require, module, exports) {
    const dom_1 = require(61) /* ../../../core/dom */;
    const types_1 = require(7) /* ../../../core/util/types */;
    const poly_tool_1 = require(321) /* ./poly_tool */;
    const icons_1 = require(271) /* ../../../styles/icons */;
    class PolyEditToolView extends poly_tool_1.PolyToolView {
        constructor() {
            super(...arguments);
            this._drawing = false;
        }
        _doubletap(ev) {
            if (!this.model.active)
                return;
            const point = this._map_drag(ev.sx, ev.sy, this.model.vertex_renderer);
            if (point == null)
                return;
            const [x, y] = point;
            // Perform hit testing
            const vertex_selected = this._select_event(ev, false, [this.model.vertex_renderer]);
            const point_cds = this.model.vertex_renderer.data_source;
            // Type once dataspecs are typed
            const point_glyph = this.model.vertex_renderer.glyph;
            const [pxkey, pykey] = [point_glyph.x.field, point_glyph.y.field];
            if (vertex_selected.length && this._selected_renderer != null) {
                // Insert a new point after the selected vertex and enter draw mode
                const index = point_cds.selected.indices[0];
                if (this._drawing) {
                    this._drawing = false;
                    point_cds.selection_manager.clear();
                }
                else {
                    point_cds.selected.indices = [index + 1];
                    if (pxkey)
                        point_cds.get_array(pxkey).splice(index + 1, 0, x);
                    if (pykey)
                        point_cds.get_array(pykey).splice(index + 1, 0, y);
                    this._drawing = true;
                }
                point_cds.change.emit();
                this._emit_cds_changes(this._selected_renderer.data_source);
            }
            else {
                this._show_vertices(ev);
            }
        }
        _show_vertices(ev) {
            if (!this.model.active)
                return;
            const renderers = this._select_event(ev, false, this.model.renderers);
            if (!renderers.length) {
                this._set_vertices([], []);
                this._selected_renderer = null;
                this._drawing = false;
                return;
            }
            const renderer = renderers[0];
            const glyph = renderer.glyph;
            const cds = renderer.data_source;
            const index = cds.selected.indices[0];
            const [xkey, ykey] = [glyph.xs.field, glyph.ys.field];
            let xs;
            let ys;
            if (xkey) {
                xs = cds.data[xkey][index];
                if (!types_1.isArray(xs))
                    cds.data[xkey][index] = xs = Array.from(xs);
            }
            else {
                xs = glyph.xs.value;
            }
            if (ykey) {
                ys = cds.data[ykey][index];
                if (!types_1.isArray(ys))
                    cds.data[ykey][index] = ys = Array.from(ys);
            }
            else {
                ys = glyph.ys.value;
            }
            this._selected_renderer = renderer;
            this._set_vertices(xs, ys);
        }
        _move(ev) {
            if (this._drawing && this._selected_renderer != null) {
                const renderer = this.model.vertex_renderer;
                const cds = renderer.data_source;
                const glyph = renderer.glyph;
                const point = this._map_drag(ev.sx, ev.sy, renderer);
                if (point == null)
                    return;
                let [x, y] = point;
                const indices = cds.selected.indices;
                [x, y] = this._snap_to_vertex(ev, x, y);
                cds.selected.indices = indices;
                const [xkey, ykey] = [glyph.x.field, glyph.y.field];
                const index = indices[0];
                if (xkey)
                    cds.data[xkey][index] = x;
                if (ykey)
                    cds.data[ykey][index] = y;
                cds.change.emit();
                this._selected_renderer.data_source.change.emit();
            }
        }
        _tap(ev) {
            const renderer = this.model.vertex_renderer;
            const point = this._map_drag(ev.sx, ev.sy, renderer);
            if (point == null)
                return;
            else if (this._drawing && this._selected_renderer) {
                let [x, y] = point;
                const cds = renderer.data_source;
                // Type once dataspecs are typed
                const glyph = renderer.glyph;
                const [xkey, ykey] = [glyph.x.field, glyph.y.field];
                const indices = cds.selected.indices;
                [x, y] = this._snap_to_vertex(ev, x, y);
                const index = indices[0];
                cds.selected.indices = [index + 1];
                if (xkey) {
                    const xs = cds.get_array(xkey);
                    const nx = xs[index];
                    xs[index] = x;
                    xs.splice(index + 1, 0, nx);
                }
                if (ykey) {
                    const ys = cds.get_array(ykey);
                    const ny = ys[index];
                    ys[index] = y;
                    ys.splice(index + 1, 0, ny);
                }
                cds.change.emit();
                this._emit_cds_changes(this._selected_renderer.data_source, true, false, true);
                return;
            }
            const append = ev.shiftKey;
            this._select_event(ev, append, [renderer]);
            this._select_event(ev, append, this.model.renderers);
        }
        _remove_vertex() {
            if (!this._drawing || !this._selected_renderer)
                return;
            const renderer = this.model.vertex_renderer;
            const cds = renderer.data_source;
            // Type once dataspecs are typed
            const glyph = renderer.glyph;
            const index = cds.selected.indices[0];
            const [xkey, ykey] = [glyph.x.field, glyph.y.field];
            if (xkey)
                cds.get_array(xkey).splice(index, 1);
            if (ykey)
                cds.get_array(ykey).splice(index, 1);
            cds.change.emit();
            this._emit_cds_changes(this._selected_renderer.data_source);
        }
        _pan_start(ev) {
            this._select_event(ev, true, [this.model.vertex_renderer]);
            this._basepoint = [ev.sx, ev.sy];
        }
        _pan(ev) {
            if (this._basepoint == null)
                return;
            this._drag_points(ev, [this.model.vertex_renderer]);
            if (this._selected_renderer)
                this._selected_renderer.data_source.change.emit();
        }
        _pan_end(ev) {
            if (this._basepoint == null)
                return;
            this._drag_points(ev, [this.model.vertex_renderer]);
            this._emit_cds_changes(this.model.vertex_renderer.data_source, false, true, true);
            if (this._selected_renderer) {
                this._emit_cds_changes(this._selected_renderer.data_source);
            }
            this._basepoint = null;
        }
        _keyup(ev) {
            if (!this.model.active || !this._mouse_in_frame)
                return;
            let renderers;
            if (this._selected_renderer) {
                renderers = [this.model.vertex_renderer];
            }
            else {
                renderers = this.model.renderers;
            }
            for (const renderer of renderers) {
                if (ev.keyCode === dom_1.Keys.Backspace) {
                    this._delete_selected(renderer);
                    if (this._selected_renderer) {
                        this._emit_cds_changes(this._selected_renderer.data_source);
                    }
                }
                else if (ev.keyCode == dom_1.Keys.Esc) {
                    if (this._drawing) {
                        this._remove_vertex();
                        this._drawing = false;
                    }
                    else if (this._selected_renderer) {
                        this._hide_vertices();
                    }
                    renderer.data_source.selection_manager.clear();
                }
            }
        }
        deactivate() {
            if (!this._selected_renderer) {
                return;
            }
            else if (this._drawing) {
                this._remove_vertex();
                this._drawing = false;
            }
            this._hide_vertices();
        }
    }
    exports.PolyEditToolView = PolyEditToolView;
    PolyEditToolView.__name__ = "PolyEditToolView";
    class PolyEditTool extends poly_tool_1.PolyTool {
        constructor(attrs) {
            super(attrs);
            this.tool_name = "Poly Edit Tool";
            this.icon = icons_1.bk_tool_icon_poly_edit;
            this.event_type = ["tap", "pan", "move"];
            this.default_order = 4;
        }
        static init_PolyEditTool() {
            this.prototype.default_view = PolyEditToolView;
        }
    }
    exports.PolyEditTool = PolyEditTool;
    PolyEditTool.__name__ = "PolyEditTool";
    PolyEditTool.init_PolyEditTool();
},
/* models/tools/gestures/box_select_tool.js */ function _(require, module, exports) {
    const select_tool_1 = require(324) /* ./select_tool */;
    const box_annotation_1 = require(99) /* ../../annotations/box_annotation */;
    const p = require(18) /* ../../../core/properties */;
    const icons_1 = require(271) /* ../../../styles/icons */;
    class BoxSelectToolView extends select_tool_1.SelectToolView {
        _compute_limits(curpoint) {
            const frame = this.plot_view.frame;
            const dims = this.model.dimensions;
            let base_point = this._base_point;
            if (this.model.origin == "center") {
                const [cx, cy] = base_point;
                const [dx, dy] = curpoint;
                base_point = [cx - (dx - cx), cy - (dy - cy)];
            }
            return this.model._get_dim_limits(base_point, curpoint, frame, dims);
        }
        _pan_start(ev) {
            const { sx, sy } = ev;
            this._base_point = [sx, sy];
        }
        _pan(ev) {
            const { sx, sy } = ev;
            const curpoint = [sx, sy];
            const [sxlim, sylim] = this._compute_limits(curpoint);
            this.model.overlay.update({ left: sxlim[0], right: sxlim[1], top: sylim[0], bottom: sylim[1] });
            if (this.model.select_every_mousemove) {
                const append = ev.shiftKey;
                this._do_select(sxlim, sylim, false, append);
            }
        }
        _pan_end(ev) {
            const { sx, sy } = ev;
            const curpoint = [sx, sy];
            const [sxlim, sylim] = this._compute_limits(curpoint);
            const append = ev.shiftKey;
            this._do_select(sxlim, sylim, true, append);
            this.model.overlay.update({ left: null, right: null, top: null, bottom: null });
            this._base_point = null;
            this.plot_view.push_state('box_select', { selection: this.plot_view.get_selection() });
        }
        _do_select([sx0, sx1], [sy0, sy1], final, append = false) {
            const geometry = { type: 'rect', sx0, sx1, sy0, sy1 };
            this._select(geometry, final, append);
        }
        _emit_callback(geometry) {
            const r = this.computed_renderers[0];
            const frame = this.plot_view.frame;
            const xscale = frame.xscales[r.x_range_name];
            const yscale = frame.yscales[r.y_range_name];
            const { sx0, sx1, sy0, sy1 } = geometry;
            const [x0, x1] = xscale.r_invert(sx0, sx1);
            const [y0, y1] = yscale.r_invert(sy0, sy1);
            const g = Object.assign({ x0, y0, x1, y1 }, geometry);
            if (this.model.callback != null)
                this.model.callback.execute(this.model, { geometry: g });
        }
    }
    exports.BoxSelectToolView = BoxSelectToolView;
    BoxSelectToolView.__name__ = "BoxSelectToolView";
    const DEFAULT_BOX_OVERLAY = () => {
        return new box_annotation_1.BoxAnnotation({
            level: "overlay",
            render_mode: "css",
            top_units: "screen",
            left_units: "screen",
            bottom_units: "screen",
            right_units: "screen",
            fill_color: { value: "lightgrey" },
            fill_alpha: { value: 0.5 },
            line_color: { value: "black" },
            line_alpha: { value: 1.0 },
            line_width: { value: 2 },
            line_dash: { value: [4, 4] },
        });
    };
    class BoxSelectTool extends select_tool_1.SelectTool {
        constructor(attrs) {
            super(attrs);
            this.tool_name = "Box Select";
            this.icon = icons_1.bk_tool_icon_box_select;
            this.event_type = "pan";
            this.default_order = 30;
        }
        static init_BoxSelectTool() {
            this.prototype.default_view = BoxSelectToolView;
            this.define({
                dimensions: [p.Dimensions, "both"],
                select_every_mousemove: [p.Boolean, false],
                callback: [p.Any],
                overlay: [p.Instance, DEFAULT_BOX_OVERLAY],
                origin: [p.BoxOrigin, "corner"],
            });
        }
        get tooltip() {
            return this._get_dim_tooltip(this.tool_name, this.dimensions);
        }
    }
    exports.BoxSelectTool = BoxSelectTool;
    BoxSelectTool.__name__ = "BoxSelectTool";
    BoxSelectTool.init_BoxSelectTool();
},
/* models/tools/gestures/select_tool.js */ function _(require, module, exports) {
    const gesture_tool_1 = require(268) /* ./gesture_tool */;
    const glyph_renderer_1 = require(73) /* ../../renderers/glyph_renderer */;
    const graph_renderer_1 = require(90) /* ../../renderers/graph_renderer */;
    const util_1 = require(325) /* ../util */;
    const p = require(18) /* ../../../core/properties */;
    const dom_1 = require(61) /* ../../../core/dom */;
    const bokeh_events_1 = require(274) /* ../../../core/bokeh_events */;
    class SelectToolView extends gesture_tool_1.GestureToolView {
        get computed_renderers() {
            const renderers = this.model.renderers;
            const all_renderers = this.plot_model.renderers;
            const names = this.model.names;
            return util_1.compute_renderers(renderers, all_renderers, names);
        }
        _computed_renderers_by_data_source() {
            const renderers_by_source = {};
            for (const r of this.computed_renderers) {
                let source_id;
                if (r instanceof glyph_renderer_1.GlyphRenderer)
                    source_id = r.data_source.id;
                else if (r instanceof graph_renderer_1.GraphRenderer)
                    source_id = r.node_renderer.data_source.id;
                else
                    continue;
                if (!(source_id in renderers_by_source))
                    renderers_by_source[source_id] = [];
                renderers_by_source[source_id].push(r);
            }
            return renderers_by_source;
        }
        _keyup(ev) {
            if (ev.keyCode == dom_1.Keys.Esc) {
                for (const r of this.computed_renderers) {
                    r.get_selection_manager().clear();
                }
                this.plot_view.request_render();
            }
        }
        _select(geometry, final, append) {
            const renderers_by_source = this._computed_renderers_by_data_source();
            for (const id in renderers_by_source) {
                const renderers = renderers_by_source[id];
                const sm = renderers[0].get_selection_manager();
                const r_views = [];
                for (const r of renderers) {
                    if (r.id in this.plot_view.renderer_views)
                        r_views.push(this.plot_view.renderer_views[r.id]);
                }
                sm.select(r_views, geometry, final, append);
            }
            // XXX: messed up class structure
            if (this.model.callback != null)
                this._emit_callback(geometry);
            this._emit_selection_event(geometry, final);
        }
        _emit_selection_event(geometry, final = true) {
            const { frame } = this.plot_view;
            const xm = frame.xscales.default;
            const ym = frame.yscales.default;
            let g; // XXX: Geometry & something
            switch (geometry.type) {
                case 'point': {
                    const { sx, sy } = geometry;
                    const x = xm.invert(sx);
                    const y = ym.invert(sy);
                    g = Object.assign(Object.assign({}, geometry), { x, y });
                    break;
                }
                case 'rect': {
                    const { sx0, sx1, sy0, sy1 } = geometry;
                    const [x0, x1] = xm.r_invert(sx0, sx1);
                    const [y0, y1] = ym.r_invert(sy0, sy1);
                    g = Object.assign(Object.assign({}, geometry), { x0, y0, x1, y1 });
                    break;
                }
                case 'poly': {
                    const { sx, sy } = geometry;
                    const x = xm.v_invert(sx);
                    const y = ym.v_invert(sy);
                    g = Object.assign(Object.assign({}, geometry), { x, y });
                    break;
                }
                default:
                    throw new Error(`Unrecognized selection geometry type: '${geometry.type}'`);
            }
            this.plot_model.trigger_event(new bokeh_events_1.SelectionGeometry(g, final));
        }
    }
    exports.SelectToolView = SelectToolView;
    SelectToolView.__name__ = "SelectToolView";
    class SelectTool extends gesture_tool_1.GestureTool {
        constructor(attrs) {
            super(attrs);
        }
        static init_SelectTool() {
            this.define({
                renderers: [p.Any, 'auto'],
                names: [p.Array, []],
            });
        }
    }
    exports.SelectTool = SelectTool;
    SelectTool.__name__ = "SelectTool";
    SelectTool.init_SelectTool();
},
/* models/tools/util.js */ function _(require, module, exports) {
    const array_1 = require(8) /* ../../core/util/array */;
    function compute_renderers(renderers, all_renderers, names) {
        if (renderers == null)
            return [];
        let result = renderers == 'auto' ? all_renderers : renderers;
        if (names.length > 0)
            result = result.filter((r) => array_1.includes(names, r.name));
        return result;
    }
    exports.compute_renderers = compute_renderers;
},
/* models/tools/gestures/box_zoom_tool.js */ function _(require, module, exports) {
    const gesture_tool_1 = require(268) /* ./gesture_tool */;
    const box_annotation_1 = require(99) /* ../../annotations/box_annotation */;
    const p = require(18) /* ../../../core/properties */;
    const icons_1 = require(271) /* ../../../styles/icons */;
    class BoxZoomToolView extends gesture_tool_1.GestureToolView {
        _match_aspect(base_point, curpoint, frame) {
            // aspect ratio of plot frame
            const a = frame.bbox.aspect;
            const hend = frame.bbox.h_range.end;
            const hstart = frame.bbox.h_range.start;
            const vend = frame.bbox.v_range.end;
            const vstart = frame.bbox.v_range.start;
            // current aspect of cursor-defined box
            let vw = Math.abs(base_point[0] - curpoint[0]);
            let vh = Math.abs(base_point[1] - curpoint[1]);
            const va = vh == 0 ? 0 : vw / vh;
            const [xmod] = va >= a ? [1, va / a] : [a / va, 1];
            // OK the code blocks below merit some explanation. They do:
            //
            // compute left/right, pin to frame if necessary
            // compute top/bottom (based on new left/right), pin to frame if necessary
            // recompute left/right (based on top/bottom), in case top/bottom were pinned
            // base_point[0] is left
            let left;
            let right;
            if (base_point[0] <= curpoint[0]) {
                left = base_point[0];
                right = base_point[0] + vw * xmod;
                if (right > hend)
                    right = hend;
                // base_point[0] is right
            }
            else {
                right = base_point[0];
                left = base_point[0] - vw * xmod;
                if (left < hstart)
                    left = hstart;
            }
            vw = Math.abs(right - left);
            // base_point[1] is bottom
            let top;
            let bottom;
            if (base_point[1] <= curpoint[1]) {
                bottom = base_point[1];
                top = base_point[1] + vw / a;
                if (top > vend)
                    top = vend;
                // base_point[1] is top
            }
            else {
                top = base_point[1];
                bottom = base_point[1] - vw / a;
                if (bottom < vstart)
                    bottom = vstart;
            }
            vh = Math.abs(top - bottom);
            // base_point[0] is left
            if (base_point[0] <= curpoint[0])
                right = base_point[0] + a * vh;
            // base_point[0] is right
            else
                left = base_point[0] - a * vh;
            return [[left, right], [bottom, top]];
        }
        _compute_limits(curpoint) {
            const frame = this.plot_view.frame;
            const dims = this.model.dimensions;
            let base_point = this._base_point;
            if (this.model.origin == "center") {
                const [cx, cy] = base_point;
                const [dx, dy] = curpoint;
                base_point = [cx - (dx - cx), cy - (dy - cy)];
            }
            let sx;
            let sy;
            if (this.model.match_aspect && dims == 'both')
                [sx, sy] = this._match_aspect(base_point, curpoint, frame);
            else
                [sx, sy] = this.model._get_dim_limits(base_point, curpoint, frame, dims);
            return [sx, sy];
        }
        _pan_start(ev) {
            this._base_point = [ev.sx, ev.sy];
        }
        _pan(ev) {
            const curpoint = [ev.sx, ev.sy];
            const [sx, sy] = this._compute_limits(curpoint);
            this.model.overlay.update({ left: sx[0], right: sx[1], top: sy[0], bottom: sy[1] });
        }
        _pan_end(ev) {
            const curpoint = [ev.sx, ev.sy];
            const [sx, sy] = this._compute_limits(curpoint);
            this._update(sx, sy);
            this.model.overlay.update({ left: null, right: null, top: null, bottom: null });
            this._base_point = null;
        }
        _update([sx0, sx1], [sy0, sy1]) {
            // If the viewing window is too small, no-op: it is likely that the user did
            // not intend to make this box zoom and instead was trying to cancel out of the
            // zoom, a la matplotlib's ToolZoom. Like matplotlib, set the threshold at 5 pixels.
            if (Math.abs(sx1 - sx0) <= 5 || Math.abs(sy1 - sy0) <= 5)
                return;
            const { xscales, yscales } = this.plot_view.frame;
            const xrs = {};
            for (const name in xscales) {
                const scale = xscales[name];
                const [start, end] = scale.r_invert(sx0, sx1);
                xrs[name] = { start, end };
            }
            const yrs = {};
            for (const name in yscales) {
                const scale = yscales[name];
                const [start, end] = scale.r_invert(sy0, sy1);
                yrs[name] = { start, end };
            }
            const zoom_info = { xrs, yrs };
            this.plot_view.push_state('box_zoom', { range: zoom_info });
            this.plot_view.update_range(zoom_info);
        }
    }
    exports.BoxZoomToolView = BoxZoomToolView;
    BoxZoomToolView.__name__ = "BoxZoomToolView";
    const DEFAULT_BOX_OVERLAY = () => {
        return new box_annotation_1.BoxAnnotation({
            level: "overlay",
            render_mode: "css",
            top_units: "screen",
            left_units: "screen",
            bottom_units: "screen",
            right_units: "screen",
            fill_color: { value: "lightgrey" },
            fill_alpha: { value: 0.5 },
            line_color: { value: "black" },
            line_alpha: { value: 1.0 },
            line_width: { value: 2 },
            line_dash: { value: [4, 4] },
        });
    };
    class BoxZoomTool extends gesture_tool_1.GestureTool {
        constructor(attrs) {
            super(attrs);
            this.tool_name = "Box Zoom";
            this.icon = icons_1.bk_tool_icon_box_zoom;
            this.event_type = "pan";
            this.default_order = 20;
        }
        static init_BoxZoomTool() {
            this.prototype.default_view = BoxZoomToolView;
            this.define({
                dimensions: [p.Dimensions, "both"],
                overlay: [p.Instance, DEFAULT_BOX_OVERLAY],
                match_aspect: [p.Boolean, false],
                origin: [p.BoxOrigin, "corner"],
            });
        }
        get tooltip() {
            return this._get_dim_tooltip(this.tool_name, this.dimensions);
        }
    }
    exports.BoxZoomTool = BoxZoomTool;
    BoxZoomTool.__name__ = "BoxZoomTool";
    BoxZoomTool.init_BoxZoomTool();
},
/* models/tools/gestures/lasso_select_tool.js */ function _(require, module, exports) {
    const select_tool_1 = require(324) /* ./select_tool */;
    const poly_annotation_1 = require(131) /* ../../annotations/poly_annotation */;
    const dom_1 = require(61) /* ../../../core/dom */;
    const p = require(18) /* ../../../core/properties */;
    const icons_1 = require(271) /* ../../../styles/icons */;
    class LassoSelectToolView extends select_tool_1.SelectToolView {
        initialize() {
            super.initialize();
            this.data = null;
        }
        connect_signals() {
            super.connect_signals();
            this.connect(this.model.properties.active.change, () => this._active_change());
        }
        _active_change() {
            if (!this.model.active)
                this._clear_overlay();
        }
        _keyup(ev) {
            if (ev.keyCode == dom_1.Keys.Enter)
                this._clear_overlay();
        }
        _pan_start(ev) {
            const { sx, sy } = ev;
            this.data = { sx: [sx], sy: [sy] };
        }
        _pan(ev) {
            const { sx: _sx, sy: _sy } = ev;
            const [sx, sy] = this.plot_view.frame.bbox.clip(_sx, _sy);
            this.data.sx.push(sx);
            this.data.sy.push(sy);
            const overlay = this.model.overlay;
            overlay.update({ xs: this.data.sx, ys: this.data.sy });
            if (this.model.select_every_mousemove) {
                const append = ev.shiftKey;
                this._do_select(this.data.sx, this.data.sy, false, append);
            }
        }
        _pan_end(ev) {
            this._clear_overlay();
            const append = ev.shiftKey;
            this._do_select(this.data.sx, this.data.sy, true, append);
            this.plot_view.push_state('lasso_select', { selection: this.plot_view.get_selection() });
        }
        _clear_overlay() {
            this.model.overlay.update({ xs: [], ys: [] });
        }
        _do_select(sx, sy, final, append) {
            const geometry = { type: 'poly', sx, sy };
            this._select(geometry, final, append);
        }
        _emit_callback(geometry) {
            const r = this.computed_renderers[0];
            const frame = this.plot_view.frame;
            const xscale = frame.xscales[r.x_range_name];
            const yscale = frame.yscales[r.y_range_name];
            const x = xscale.v_invert(geometry.sx);
            const y = yscale.v_invert(geometry.sy);
            const g = Object.assign({ x, y }, geometry);
            if (this.model.callback != null)
                this.model.callback.execute(this.model, { geometry: g });
        }
    }
    exports.LassoSelectToolView = LassoSelectToolView;
    LassoSelectToolView.__name__ = "LassoSelectToolView";
    const DEFAULT_POLY_OVERLAY = () => {
        return new poly_annotation_1.PolyAnnotation({
            level: "overlay",
            xs_units: "screen",
            ys_units: "screen",
            fill_color: { value: "lightgrey" },
            fill_alpha: { value: 0.5 },
            line_color: { value: "black" },
            line_alpha: { value: 1.0 },
            line_width: { value: 2 },
            line_dash: { value: [4, 4] },
        });
    };
    class LassoSelectTool extends select_tool_1.SelectTool {
        constructor(attrs) {
            super(attrs);
            this.tool_name = "Lasso Select";
            this.icon = icons_1.bk_tool_icon_lasso_select;
            this.event_type = "pan";
            this.default_order = 12;
        }
        static init_LassoSelectTool() {
            this.prototype.default_view = LassoSelectToolView;
            this.define({
                select_every_mousemove: [p.Boolean, true],
                callback: [p.Any],
                overlay: [p.Instance, DEFAULT_POLY_OVERLAY],
            });
        }
    }
    exports.LassoSelectTool = LassoSelectTool;
    LassoSelectTool.__name__ = "LassoSelectTool";
    LassoSelectTool.init_LassoSelectTool();
},
/* models/tools/gestures/pan_tool.js */ function _(require, module, exports) {
    const gesture_tool_1 = require(268) /* ./gesture_tool */;
    const p = require(18) /* ../../../core/properties */;
    const icons_1 = require(271) /* ../../../styles/icons */;
    class PanToolView extends gesture_tool_1.GestureToolView {
        _pan_start(ev) {
            this.last_dx = 0;
            this.last_dy = 0;
            const { sx, sy } = ev;
            const bbox = this.plot_view.frame.bbox;
            if (!bbox.contains(sx, sy)) {
                const hr = bbox.h_range;
                const vr = bbox.v_range;
                if (sx < hr.start || sx > hr.end)
                    this.v_axis_only = true;
                if (sy < vr.start || sy > vr.end)
                    this.h_axis_only = true;
            }
            if (this.model.document != null)
                this.model.document.interactive_start(this.plot_model);
        }
        _pan(ev) {
            this._update(ev.deltaX, ev.deltaY);
            if (this.model.document != null)
                this.model.document.interactive_start(this.plot_model);
        }
        _pan_end(_e) {
            this.h_axis_only = false;
            this.v_axis_only = false;
            if (this.pan_info != null)
                this.plot_view.push_state('pan', { range: this.pan_info });
        }
        _update(dx, dy) {
            const frame = this.plot_view.frame;
            const new_dx = dx - this.last_dx;
            const new_dy = dy - this.last_dy;
            const hr = frame.bbox.h_range;
            const sx_low = hr.start - new_dx;
            const sx_high = hr.end - new_dx;
            const vr = frame.bbox.v_range;
            const sy_low = vr.start - new_dy;
            const sy_high = vr.end - new_dy;
            const dims = this.model.dimensions;
            let sx0;
            let sx1;
            let sdx;
            if ((dims == 'width' || dims == 'both') && !this.v_axis_only) {
                sx0 = sx_low;
                sx1 = sx_high;
                sdx = -new_dx;
            }
            else {
                sx0 = hr.start;
                sx1 = hr.end;
                sdx = 0;
            }
            let sy0;
            let sy1;
            let sdy;
            if ((dims == 'height' || dims == 'both') && !this.h_axis_only) {
                sy0 = sy_low;
                sy1 = sy_high;
                sdy = -new_dy;
            }
            else {
                sy0 = vr.start;
                sy1 = vr.end;
                sdy = 0;
            }
            this.last_dx = dx;
            this.last_dy = dy;
            const { xscales, yscales } = frame;
            const xrs = {};
            for (const name in xscales) {
                const scale = xscales[name];
                const [start, end] = scale.r_invert(sx0, sx1);
                xrs[name] = { start, end };
            }
            const yrs = {};
            for (const name in yscales) {
                const scale = yscales[name];
                const [start, end] = scale.r_invert(sy0, sy1);
                yrs[name] = { start, end };
            }
            this.pan_info = { xrs, yrs, sdx, sdy };
            this.plot_view.update_range(this.pan_info, true);
        }
    }
    exports.PanToolView = PanToolView;
    PanToolView.__name__ = "PanToolView";
    class PanTool extends gesture_tool_1.GestureTool {
        constructor(attrs) {
            super(attrs);
            this.tool_name = "Pan";
            this.event_type = "pan";
            this.default_order = 10;
        }
        static init_PanTool() {
            this.prototype.default_view = PanToolView;
            this.define({
                dimensions: [p.Dimensions, "both"],
            });
        }
        get tooltip() {
            return this._get_dim_tooltip("Pan", this.dimensions);
        }
        get icon() {
            switch (this.dimensions) {
                case "both": return icons_1.bk_tool_icon_pan;
                case "width": return icons_1.bk_tool_icon_xpan;
                case "height": return icons_1.bk_tool_icon_ypan;
            }
        }
    }
    exports.PanTool = PanTool;
    PanTool.__name__ = "PanTool";
    PanTool.init_PanTool();
},
/* models/tools/gestures/poly_select_tool.js */ function _(require, module, exports) {
    const select_tool_1 = require(324) /* ./select_tool */;
    const poly_annotation_1 = require(131) /* ../../annotations/poly_annotation */;
    const dom_1 = require(61) /* ../../../core/dom */;
    const p = require(18) /* ../../../core/properties */;
    const array_1 = require(8) /* ../../../core/util/array */;
    const icons_1 = require(271) /* ../../../styles/icons */;
    class PolySelectToolView extends select_tool_1.SelectToolView {
        initialize() {
            super.initialize();
            this.data = { sx: [], sy: [] };
        }
        connect_signals() {
            super.connect_signals();
            this.connect(this.model.properties.active.change, () => this._active_change());
        }
        _active_change() {
            if (!this.model.active)
                this._clear_data();
        }
        _keyup(ev) {
            if (ev.keyCode == dom_1.Keys.Enter)
                this._clear_data();
        }
        _doubletap(ev) {
            const append = ev.shiftKey;
            this._do_select(this.data.sx, this.data.sy, true, append);
            this.plot_view.push_state('poly_select', { selection: this.plot_view.get_selection() });
            this._clear_data();
        }
        _clear_data() {
            this.data = { sx: [], sy: [] };
            this.model.overlay.update({ xs: [], ys: [] });
        }
        _tap(ev) {
            const { sx, sy } = ev;
            const frame = this.plot_view.frame;
            if (!frame.bbox.contains(sx, sy))
                return;
            this.data.sx.push(sx);
            this.data.sy.push(sy);
            this.model.overlay.update({ xs: array_1.copy(this.data.sx), ys: array_1.copy(this.data.sy) });
        }
        _do_select(sx, sy, final, append) {
            const geometry = { type: 'poly', sx, sy };
            this._select(geometry, final, append);
        }
        _emit_callback(geometry) {
            const r = this.computed_renderers[0];
            const frame = this.plot_view.frame;
            const xscale = frame.xscales[r.x_range_name];
            const yscale = frame.yscales[r.y_range_name];
            const x = xscale.v_invert(geometry.sx);
            const y = yscale.v_invert(geometry.sy);
            const g = Object.assign({ x, y }, geometry);
            if (this.model.callback != null)
                this.model.callback.execute(this.model, { geometry: g });
        }
    }
    exports.PolySelectToolView = PolySelectToolView;
    PolySelectToolView.__name__ = "PolySelectToolView";
    const DEFAULT_POLY_OVERLAY = () => {
        return new poly_annotation_1.PolyAnnotation({
            level: "overlay",
            xs_units: "screen",
            ys_units: "screen",
            fill_color: { value: "lightgrey" },
            fill_alpha: { value: 0.5 },
            line_color: { value: "black" },
            line_alpha: { value: 1.0 },
            line_width: { value: 2 },
            line_dash: { value: [4, 4] },
        });
    };
    class PolySelectTool extends select_tool_1.SelectTool {
        constructor(attrs) {
            super(attrs);
            this.tool_name = "Poly Select";
            this.icon = icons_1.bk_tool_icon_polygon_select;
            this.event_type = "tap";
            this.default_order = 11;
        }
        static init_PolySelectTool() {
            this.prototype.default_view = PolySelectToolView;
            this.define({
                callback: [p.Any],
                overlay: [p.Instance, DEFAULT_POLY_OVERLAY],
            });
        }
    }
    exports.PolySelectTool = PolySelectTool;
    PolySelectTool.__name__ = "PolySelectTool";
    PolySelectTool.init_PolySelectTool();
},
/* models/tools/gestures/range_tool.js */ function _(require, module, exports) {
    const box_annotation_1 = require(99) /* ../../annotations/box_annotation */;
    const logging_1 = require(65) /* ../../../core/logging */;
    const p = require(18) /* ../../../core/properties */;
    const gesture_tool_1 = require(268) /* ./gesture_tool */;
    const icons_1 = require(271) /* ../../../styles/icons */;
    function flip_side(side) {
        switch (side) {
            case 1 /* Left */: return 2 /* Right */;
            case 2 /* Right */: return 1 /* Left */;
            case 4 /* Bottom */: return 5 /* Top */;
            case 5 /* Top */: return 4 /* Bottom */;
            default: return side;
        }
    }
    exports.flip_side = flip_side;
    // TODO (bev) This would be better directly with BoxAnnotation, but hard
    // to test on a view. Move when "View Models" are implemented
    function is_near(pos, value, scale, tolerance) {
        if (value == null)
            return false;
        const svalue = scale.compute(value);
        return Math.abs(pos - svalue) < tolerance;
    }
    exports.is_near = is_near;
    // TODO (bev) This would be better directly with BoxAnnotation, but hard
    // to test on a view. Move when "View Models" are implemented
    function is_inside(sx, sy, xscale, yscale, overlay) {
        let result = true;
        if (overlay.left != null && overlay.right != null) {
            const x = xscale.invert(sx);
            if (x < overlay.left || x > overlay.right)
                result = false;
        }
        if (overlay.bottom != null && overlay.top != null) {
            const y = yscale.invert(sy);
            if (y < overlay.bottom || y > overlay.top)
                result = false;
        }
        return result;
    }
    exports.is_inside = is_inside;
    function sides_inside(start, end, range) {
        let result = 0;
        if (start >= range.start && start <= range.end)
            result += 1;
        if (end >= range.start && end <= range.end)
            result += 1;
        return result;
    }
    exports.sides_inside = sides_inside;
    function compute_value(value, scale, sdelta, range) {
        const svalue = scale.compute(value);
        const new_value = scale.invert(svalue + sdelta);
        if (new_value >= range.start && new_value <= range.end)
            return new_value;
        return value;
    }
    exports.compute_value = compute_value;
    function update_range_end_side(end, range, side) {
        if (end > range.start) {
            range.end = end;
            return side;
        }
        else {
            range.end = range.start;
            range.start = end;
            return flip_side(side);
        }
    }
    exports.update_range_end_side = update_range_end_side;
    function update_range_start_side(start, range, side) {
        if (start < range.end) {
            range.start = start;
            return side;
        }
        else {
            range.start = range.end;
            range.end = start;
            return flip_side(side);
        }
    }
    exports.update_range_start_side = update_range_start_side;
    function update_range(range, scale, delta, plot_range) {
        const [sstart, send] = scale.r_compute(range.start, range.end);
        const [start, end] = scale.r_invert(sstart + delta, send + delta);
        const initial_sides_inside = sides_inside(range.start, range.end, plot_range);
        const final_sides_inside = sides_inside(start, end, plot_range);
        // Allow the update as long as the number of sides in-bounds does not decrease
        if (final_sides_inside >= initial_sides_inside) {
            range.start = start;
            range.end = end;
        }
    }
    exports.update_range = update_range;
    class RangeToolView extends gesture_tool_1.GestureToolView {
        initialize() {
            super.initialize();
            this.side = 0 /* None */;
            this.model.update_overlay_from_ranges();
        }
        connect_signals() {
            super.connect_signals();
            if (this.model.x_range != null)
                this.connect(this.model.x_range.change, () => this.model.update_overlay_from_ranges());
            if (this.model.y_range != null)
                this.connect(this.model.y_range.change, () => this.model.update_overlay_from_ranges());
        }
        _pan_start(ev) {
            this.last_dx = 0;
            this.last_dy = 0;
            const xr = this.model.x_range;
            const yr = this.model.y_range;
            const frame = this.plot_view.frame;
            const xscale = frame.xscales.default;
            const yscale = frame.yscales.default;
            const overlay = this.model.overlay;
            const { left, right, top, bottom } = overlay;
            const tolerance = this.model.overlay.properties.line_width.value() + box_annotation_1.EDGE_TOLERANCE;
            if (xr != null && this.model.x_interaction) {
                if (is_near(ev.sx, left, xscale, tolerance))
                    this.side = 1 /* Left */;
                else if (is_near(ev.sx, right, xscale, tolerance))
                    this.side = 2 /* Right */;
                else if (is_inside(ev.sx, ev.sy, xscale, yscale, overlay)) {
                    this.side = 3 /* LeftRight */;
                }
            }
            if (yr != null && this.model.y_interaction) {
                if (this.side == 0 /* None */ && is_near(ev.sy, bottom, yscale, tolerance))
                    this.side = 4 /* Bottom */;
                if (this.side == 0 /* None */ && is_near(ev.sy, top, yscale, tolerance))
                    this.side = 5 /* Top */;
                else if (is_inside(ev.sx, ev.sy, xscale, yscale, this.model.overlay)) {
                    if (this.side == 3 /* LeftRight */)
                        this.side = 7 /* LeftRightBottomTop */;
                    else
                        this.side = 6 /* BottomTop */;
                }
            }
        }
        _pan(ev) {
            const frame = this.plot_view.frame;
            const new_dx = ev.deltaX - this.last_dx;
            const new_dy = ev.deltaY - this.last_dy;
            const xr = this.model.x_range;
            const yr = this.model.y_range;
            const xscale = frame.xscales.default;
            const yscale = frame.yscales.default;
            if (xr != null) {
                if (this.side == 3 /* LeftRight */ || this.side == 7 /* LeftRightBottomTop */)
                    update_range(xr, xscale, new_dx, frame.x_range);
                else if (this.side == 1 /* Left */) {
                    const start = compute_value(xr.start, xscale, new_dx, frame.x_range);
                    this.side = update_range_start_side(start, xr, this.side);
                }
                else if (this.side == 2 /* Right */) {
                    const end = compute_value(xr.end, xscale, new_dx, frame.x_range);
                    this.side = update_range_end_side(end, xr, this.side);
                }
            }
            if (yr != null) {
                if (this.side == 6 /* BottomTop */ || this.side == 7 /* LeftRightBottomTop */)
                    update_range(yr, yscale, new_dy, frame.y_range);
                else if (this.side == 4 /* Bottom */) {
                    const start = compute_value(yr.start, yscale, new_dy, frame.y_range);
                    this.side = update_range_start_side(start, yr, this.side);
                }
                else if (this.side == 5 /* Top */) {
                    const end = compute_value(yr.end, yscale, new_dy, frame.y_range);
                    this.side = update_range_end_side(end, yr, this.side);
                }
            }
            this.last_dx = ev.deltaX;
            this.last_dy = ev.deltaY;
        }
        _pan_end(_ev) {
            this.side = 0 /* None */;
        }
    }
    exports.RangeToolView = RangeToolView;
    RangeToolView.__name__ = "RangeToolView";
    const DEFAULT_RANGE_OVERLAY = () => {
        return new box_annotation_1.BoxAnnotation({
            level: "overlay",
            render_mode: "canvas",
            fill_color: "lightgrey",
            fill_alpha: { value: 0.5 },
            line_color: { value: "black" },
            line_alpha: { value: 1.0 },
            line_width: { value: 0.5 },
            line_dash: [2, 2],
        });
    };
    class RangeTool extends gesture_tool_1.GestureTool {
        constructor(attrs) {
            super(attrs);
            this.tool_name = "Range Tool";
            this.icon = icons_1.bk_tool_icon_range;
            this.event_type = "pan";
            this.default_order = 1;
        }
        static init_RangeTool() {
            this.prototype.default_view = RangeToolView;
            this.define({
                x_range: [p.Instance, null],
                x_interaction: [p.Boolean, true],
                y_range: [p.Instance, null],
                y_interaction: [p.Boolean, true],
                overlay: [p.Instance, DEFAULT_RANGE_OVERLAY],
            });
        }
        initialize() {
            super.initialize();
            this.overlay.in_cursor = "grab";
            this.overlay.ew_cursor = this.x_range != null && this.x_interaction ? "ew-resize" : null;
            this.overlay.ns_cursor = this.y_range != null && this.y_interaction ? "ns-resize" : null;
        }
        update_overlay_from_ranges() {
            if (this.x_range == null && this.y_range == null) {
                this.overlay.left = null;
                this.overlay.right = null;
                this.overlay.bottom = null;
                this.overlay.top = null;
                logging_1.logger.warn('RangeTool not configured with any Ranges.');
            }
            if (this.x_range == null) {
                this.overlay.left = null;
                this.overlay.right = null;
            }
            else {
                this.overlay.left = this.x_range.start;
                this.overlay.right = this.x_range.end;
            }
            if (this.y_range == null) {
                this.overlay.bottom = null;
                this.overlay.top = null;
            }
            else {
                this.overlay.bottom = this.y_range.start;
                this.overlay.top = this.y_range.end;
            }
        }
    }
    exports.RangeTool = RangeTool;
    RangeTool.__name__ = "RangeTool";
    RangeTool.init_RangeTool();
},
/* models/tools/gestures/tap_tool.js */ function _(require, module, exports) {
    const select_tool_1 = require(324) /* ./select_tool */;
    const p = require(18) /* ../../../core/properties */;
    const icons_1 = require(271) /* ../../../styles/icons */;
    class TapToolView extends select_tool_1.SelectToolView {
        _tap(ev) {
            const { sx, sy } = ev;
            const geometry = { type: 'point', sx, sy };
            const append = ev.shiftKey;
            this._select(geometry, true, append);
        }
        _select(geometry, final, append) {
            const callback = this.model.callback;
            if (this.model.behavior == "select") {
                const renderers_by_source = this._computed_renderers_by_data_source();
                for (const id in renderers_by_source) {
                    const renderers = renderers_by_source[id];
                    const sm = renderers[0].get_selection_manager();
                    const r_views = renderers.map((r) => this.plot_view.renderer_views[r.id]);
                    const did_hit = sm.select(r_views, geometry, final, append);
                    if (did_hit && callback != null) {
                        const { frame } = this.plot_view;
                        const xscale = frame.xscales[renderers[0].x_range_name];
                        const yscale = frame.yscales[renderers[0].y_range_name];
                        const x = xscale.invert(geometry.sx);
                        const y = yscale.invert(geometry.sy);
                        const data = { geometries: Object.assign(Object.assign({}, geometry), { x, y }), source: sm.source };
                        callback.execute(this.model, data);
                    }
                }
                this._emit_selection_event(geometry);
                this.plot_view.push_state('tap', { selection: this.plot_view.get_selection() });
            }
            else {
                for (const r of this.computed_renderers) {
                    const sm = r.get_selection_manager();
                    const did_hit = sm.inspect(this.plot_view.renderer_views[r.id], geometry);
                    if (did_hit && callback != null) {
                        const { frame } = this.plot_view;
                        const xscale = frame.xscales[r.x_range_name];
                        const yscale = frame.yscales[r.y_range_name];
                        const x = xscale.invert(geometry.sx);
                        const y = yscale.invert(geometry.sy);
                        const data = { geometries: Object.assign(Object.assign({}, geometry), { x, y }), source: sm.source };
                        callback.execute(this.model, data);
                    }
                }
            }
        }
    }
    exports.TapToolView = TapToolView;
    TapToolView.__name__ = "TapToolView";
    class TapTool extends select_tool_1.SelectTool {
        constructor(attrs) {
            super(attrs);
            this.tool_name = "Tap";
            this.icon = icons_1.bk_tool_icon_tap_select;
            this.event_type = "tap";
            this.default_order = 10;
        }
        static init_TapTool() {
            this.prototype.default_view = TapToolView;
            this.define({
                behavior: [p.TapBehavior, "select"],
                callback: [p.Any],
            });
        }
    }
    exports.TapTool = TapTool;
    TapTool.__name__ = "TapTool";
    TapTool.init_TapTool();
},
/* models/tools/gestures/wheel_pan_tool.js */ function _(require, module, exports) {
    const gesture_tool_1 = require(268) /* ./gesture_tool */;
    const p = require(18) /* ../../../core/properties */;
    const icons_1 = require(271) /* ../../../styles/icons */;
    class WheelPanToolView extends gesture_tool_1.GestureToolView {
        _scroll(ev) {
            let factor = this.model.speed * ev.delta;
            // clamp the magnitude of factor, if it is > 1 bad things happen
            if (factor > 0.9)
                factor = 0.9;
            else if (factor < -0.9)
                factor = -0.9;
            this._update_ranges(factor);
        }
        _update_ranges(factor) {
            const { frame } = this.plot_view;
            const hr = frame.bbox.h_range;
            const vr = frame.bbox.v_range;
            const [sx_low, sx_high] = [hr.start, hr.end];
            const [sy_low, sy_high] = [vr.start, vr.end];
            let sx0;
            let sx1;
            let sy0;
            let sy1;
            switch (this.model.dimension) {
                case "height": {
                    const sy_range = Math.abs(sy_high - sy_low);
                    sx0 = sx_low;
                    sx1 = sx_high;
                    sy0 = sy_low - sy_range * factor;
                    sy1 = sy_high - sy_range * factor;
                    break;
                }
                case "width": {
                    const sx_range = Math.abs(sx_high - sx_low);
                    sx0 = sx_low - sx_range * factor;
                    sx1 = sx_high - sx_range * factor;
                    sy0 = sy_low;
                    sy1 = sy_high;
                    break;
                }
                default:
                    throw new Error("this shouldn't have happened");
            }
            const { xscales, yscales } = frame;
            const xrs = {};
            for (const name in xscales) {
                const scale = xscales[name];
                const [start, end] = scale.r_invert(sx0, sx1);
                xrs[name] = { start, end };
            }
            const yrs = {};
            for (const name in yscales) {
                const scale = yscales[name];
                const [start, end] = scale.r_invert(sy0, sy1);
                yrs[name] = { start, end };
            }
            // OK this sucks we can't set factor independently in each direction. It is used
            // for GMap plots, and GMap plots always preserve aspect, so effective the value
            // of 'dimensions' is ignored.
            const pan_info = { xrs, yrs, factor };
            this.plot_view.push_state('wheel_pan', { range: pan_info });
            this.plot_view.update_range(pan_info, false, true);
            if (this.model.document != null)
                this.model.document.interactive_start(this.plot_model);
        }
    }
    exports.WheelPanToolView = WheelPanToolView;
    WheelPanToolView.__name__ = "WheelPanToolView";
    class WheelPanTool extends gesture_tool_1.GestureTool {
        constructor(attrs) {
            super(attrs);
            this.tool_name = "Wheel Pan";
            this.icon = icons_1.bk_tool_icon_wheel_pan;
            this.event_type = "scroll";
            this.default_order = 12;
        }
        static init_WheelPanTool() {
            this.prototype.default_view = WheelPanToolView;
            this.define({
                dimension: [p.Dimension, "width"],
            });
            this.internal({
                speed: [p.Number, 1 / 1000],
            });
        }
        get tooltip() {
            return this._get_dim_tooltip(this.tool_name, this.dimension);
        }
    }
    exports.WheelPanTool = WheelPanTool;
    WheelPanTool.__name__ = "WheelPanTool";
    WheelPanTool.init_WheelPanTool();
},
/* models/tools/gestures/wheel_zoom_tool.js */ function _(require, module, exports) {
    const gesture_tool_1 = require(268) /* ./gesture_tool */;
    const zoom_1 = require(314) /* ../../../core/util/zoom */;
    const p = require(18) /* ../../../core/properties */;
    const compat_1 = require(95) /* ../../../core/util/compat */;
    const icons_1 = require(271) /* ../../../styles/icons */;
    class WheelZoomToolView extends gesture_tool_1.GestureToolView {
        _pinch(ev) {
            // TODO (bev) this can probably be done much better
            const { sx, sy, scale } = ev;
            let delta;
            if (scale >= 1)
                delta = (scale - 1) * 20.0;
            else
                delta = -20.0 / scale;
            this._scroll({ type: "wheel", sx, sy, delta });
        }
        _scroll(ev) {
            const { frame } = this.plot_view;
            const hr = frame.bbox.h_range;
            const vr = frame.bbox.v_range;
            const { sx, sy } = ev;
            const dims = this.model.dimensions;
            // restrict to axis configured in tool's dimensions property and if
            // zoom origin is inside of frame range/domain
            const h_axis = (dims == 'width' || dims == 'both') && hr.start < sx && sx < hr.end;
            const v_axis = (dims == 'height' || dims == 'both') && vr.start < sy && sy < vr.end;
            if ((!h_axis || !v_axis) && !this.model.zoom_on_axis) {
                return;
            }
            const factor = this.model.speed * ev.delta;
            const zoom_info = zoom_1.scale_range(frame, factor, h_axis, v_axis, { x: sx, y: sy });
            this.plot_view.push_state('wheel_zoom', { range: zoom_info });
            this.plot_view.update_range(zoom_info, false, true, this.model.maintain_focus);
            if (this.model.document != null)
                this.model.document.interactive_start(this.plot_model);
        }
    }
    exports.WheelZoomToolView = WheelZoomToolView;
    WheelZoomToolView.__name__ = "WheelZoomToolView";
    class WheelZoomTool extends gesture_tool_1.GestureTool {
        constructor(attrs) {
            super(attrs);
            this.tool_name = "Wheel Zoom";
            this.icon = icons_1.bk_tool_icon_wheel_zoom;
            this.event_type = compat_1.is_mobile ? "pinch" : "scroll";
            this.default_order = 10;
        }
        static init_WheelZoomTool() {
            this.prototype.default_view = WheelZoomToolView;
            this.define({
                dimensions: [p.Dimensions, "both"],
                maintain_focus: [p.Boolean, true],
                zoom_on_axis: [p.Boolean, true],
                speed: [p.Number, 1 / 600],
            });
        }
        get tooltip() {
            return this._get_dim_tooltip(this.tool_name, this.dimensions);
        }
    }
    exports.WheelZoomTool = WheelZoomTool;
    WheelZoomTool.__name__ = "WheelZoomTool";
    WheelZoomTool.init_WheelZoomTool();
},
/* models/tools/inspectors/crosshair_tool.js */ function _(require, module, exports) {
    const inspect_tool_1 = require(262) /* ./inspect_tool */;
    const span_1 = require(133) /* ../../annotations/span */;
    const p = require(18) /* ../../../core/properties */;
    const object_1 = require(22) /* ../../../core/util/object */;
    const icons_1 = require(271) /* ../../../styles/icons */;
    class CrosshairToolView extends inspect_tool_1.InspectToolView {
        _move(ev) {
            if (!this.model.active)
                return;
            const { sx, sy } = ev;
            if (!this.plot_view.frame.bbox.contains(sx, sy))
                this._update_spans(null, null);
            else
                this._update_spans(sx, sy);
        }
        _move_exit(_e) {
            this._update_spans(null, null);
        }
        _update_spans(x, y) {
            const dims = this.model.dimensions;
            if (dims == "width" || dims == "both")
                this.model.spans.width.computed_location = y;
            if (dims == "height" || dims == "both")
                this.model.spans.height.computed_location = x;
        }
    }
    exports.CrosshairToolView = CrosshairToolView;
    CrosshairToolView.__name__ = "CrosshairToolView";
    class CrosshairTool extends inspect_tool_1.InspectTool {
        constructor(attrs) {
            super(attrs);
            this.tool_name = "Crosshair";
            this.icon = icons_1.bk_tool_icon_crosshair;
        }
        static init_CrosshairTool() {
            this.prototype.default_view = CrosshairToolView;
            this.define({
                dimensions: [p.Dimensions, "both"],
                line_color: [p.Color, 'black'],
                line_width: [p.Number, 1],
                line_alpha: [p.Number, 1.0],
            });
            this.internal({
                location_units: [p.SpatialUnits, "screen"],
                render_mode: [p.RenderMode, "css"],
                spans: [p.Any],
            });
        }
        get tooltip() {
            return this._get_dim_tooltip("Crosshair", this.dimensions);
        }
        get synthetic_renderers() {
            return object_1.values(this.spans);
        }
        initialize() {
            super.initialize();
            this.spans = {
                width: new span_1.Span({
                    for_hover: true,
                    dimension: "width",
                    render_mode: this.render_mode,
                    location_units: this.location_units,
                    line_color: this.line_color,
                    line_width: this.line_width,
                    line_alpha: this.line_alpha,
                }),
                height: new span_1.Span({
                    for_hover: true,
                    dimension: "height",
                    render_mode: this.render_mode,
                    location_units: this.location_units,
                    line_color: this.line_color,
                    line_width: this.line_width,
                    line_alpha: this.line_alpha,
                }),
            };
        }
    }
    exports.CrosshairTool = CrosshairTool;
    CrosshairTool.__name__ = "CrosshairTool";
    CrosshairTool.init_CrosshairTool();
},
/* models/tools/inspectors/customjs_hover.js */ function _(require, module, exports) {
    const model_1 = require(64) /* ../../../model */;
    const p = require(18) /* ../../../core/properties */;
    const object_1 = require(22) /* ../../../core/util/object */;
    const string_1 = require(25) /* ../../../core/util/string */;
    class CustomJSHover extends model_1.Model {
        constructor(attrs) {
            super(attrs);
        }
        static init_CustomJSHover() {
            this.define({
                args: [p.Any, {}],
                code: [p.String, ""],
            });
        }
        get values() {
            return object_1.values(this.args);
        }
        /*protected*/ _make_code(valname, formatname, varsname, fn) {
            // this relies on keys(args) and values(args) returning keys and values
            // in the same order
            return new Function(...object_1.keys(this.args), valname, formatname, varsname, "require", "exports", string_1.use_strict(fn));
        }
        format(value, format, special_vars) {
            const formatter = this._make_code("value", "format", "special_vars", this.code);
            return formatter(...this.values, value, format, special_vars, require, exports);
        }
    }
    exports.CustomJSHover = CustomJSHover;
    CustomJSHover.__name__ = "CustomJSHover";
    CustomJSHover.init_CustomJSHover();
},
/* models/tools/inspectors/hover_tool.js */ function _(require, module, exports) {
    const inspect_tool_1 = require(262) /* ./inspect_tool */;
    const tooltip_1 = require(136) /* ../../annotations/tooltip */;
    const glyph_renderer_1 = require(73) /* ../../renderers/glyph_renderer */;
    const graph_renderer_1 = require(90) /* ../../renderers/graph_renderer */;
    const util_1 = require(325) /* ../util */;
    const hittest = require(81) /* ../../../core/hittest */;
    const templating_1 = require(151) /* ../../../core/util/templating */;
    const dom_1 = require(61) /* ../../../core/dom */;
    const p = require(18) /* ../../../core/properties */;
    const color_1 = require(20) /* ../../../core/util/color */;
    const object_1 = require(22) /* ../../../core/util/object */;
    const types_1 = require(7) /* ../../../core/util/types */;
    const build_views_1 = require(92) /* ../../../core/build_views */;
    const icons_1 = require(271) /* ../../../styles/icons */;
    const tooltips_1 = require(137) /* ../../../styles/tooltips */;
    function _nearest_line_hit(i, geometry, sx, sy, dx, dy) {
        const d1 = { x: dx[i], y: dy[i] };
        const d2 = { x: dx[i + 1], y: dy[i + 1] };
        let dist1;
        let dist2;
        if (geometry.type == "span") {
            if (geometry.direction == "h") {
                dist1 = Math.abs(d1.x - sx);
                dist2 = Math.abs(d2.x - sx);
            }
            else {
                dist1 = Math.abs(d1.y - sy);
                dist2 = Math.abs(d2.y - sy);
            }
        }
        else {
            const s = { x: sx, y: sy };
            dist1 = hittest.dist_2_pts(d1, s);
            dist2 = hittest.dist_2_pts(d2, s);
        }
        if (dist1 < dist2)
            return [[d1.x, d1.y], i];
        else
            return [[d2.x, d2.y], i + 1];
    }
    exports._nearest_line_hit = _nearest_line_hit;
    function _line_hit(xs, ys, ind) {
        return [[xs[ind], ys[ind]], ind];
    }
    exports._line_hit = _line_hit;
    class HoverToolView extends inspect_tool_1.InspectToolView {
        initialize() {
            super.initialize();
            this.ttviews = {};
        }
        remove() {
            build_views_1.remove_views(this.ttviews);
            super.remove();
        }
        connect_signals() {
            super.connect_signals();
            for (const r of this.computed_renderers) {
                if (r instanceof glyph_renderer_1.GlyphRenderer)
                    this.connect(r.data_source.inspect, this._update);
                else if (r instanceof graph_renderer_1.GraphRenderer) {
                    this.connect(r.node_renderer.data_source.inspect, this._update);
                    this.connect(r.edge_renderer.data_source.inspect, this._update);
                }
            }
            // TODO: this.connect(this.plot_model.properties.renderers.change, () => this._computed_renderers = this._ttmodels = null)
            this.connect(this.model.properties.renderers.change, () => this._computed_renderers = this._ttmodels = null);
            this.connect(this.model.properties.names.change, () => this._computed_renderers = this._ttmodels = null);
            this.connect(this.model.properties.tooltips.change, () => this._ttmodels = null);
        }
        _compute_ttmodels() {
            const ttmodels = {};
            const tooltips = this.model.tooltips;
            if (tooltips != null) {
                for (const r of this.computed_renderers) {
                    if (r instanceof glyph_renderer_1.GlyphRenderer) {
                        const tooltip = new tooltip_1.Tooltip({
                            custom: types_1.isString(tooltips) || types_1.isFunction(tooltips),
                            attachment: this.model.attachment,
                            show_arrow: this.model.show_arrow,
                        });
                        ttmodels[r.id] = tooltip;
                    }
                    else if (r instanceof graph_renderer_1.GraphRenderer) {
                        const tooltip = new tooltip_1.Tooltip({
                            custom: types_1.isString(tooltips) || types_1.isFunction(tooltips),
                            attachment: this.model.attachment,
                            show_arrow: this.model.show_arrow,
                        });
                        ttmodels[r.node_renderer.id] = tooltip;
                        ttmodels[r.edge_renderer.id] = tooltip;
                    }
                }
            }
            build_views_1.build_views(this.ttviews, object_1.values(ttmodels), { parent: this.plot_view });
            return ttmodels;
        }
        get computed_renderers() {
            if (this._computed_renderers == null) {
                const renderers = this.model.renderers;
                const all_renderers = this.plot_model.renderers;
                const names = this.model.names;
                this._computed_renderers = util_1.compute_renderers(renderers, all_renderers, names);
            }
            return this._computed_renderers;
        }
        get ttmodels() {
            if (this._ttmodels == null)
                this._ttmodels = this._compute_ttmodels();
            return this._ttmodels;
        }
        _clear() {
            this._inspect(Infinity, Infinity);
            for (const rid in this.ttmodels) {
                const tt = this.ttmodels[rid];
                tt.clear();
            }
        }
        _move(ev) {
            if (!this.model.active)
                return;
            const { sx, sy } = ev;
            if (!this.plot_view.frame.bbox.contains(sx, sy))
                this._clear();
            else
                this._inspect(sx, sy);
        }
        _move_exit() {
            this._clear();
        }
        _inspect(sx, sy) {
            let geometry;
            if (this.model.mode == 'mouse')
                geometry = { type: 'point', sx, sy };
            else {
                const direction = this.model.mode == 'vline' ? 'h' : 'v';
                geometry = { type: 'span', direction, sx, sy };
            }
            for (const r of this.computed_renderers) {
                const sm = r.get_selection_manager();
                sm.inspect(this.plot_view.renderer_views[r.id], geometry);
            }
            if (this.model.callback != null)
                this._emit_callback(geometry);
        }
        _update([renderer_view, { geometry }]) {
            if (!this.model.active)
                return;
            if (!(renderer_view instanceof glyph_renderer_1.GlyphRendererView || renderer_view instanceof graph_renderer_1.GraphRendererView))
                return;
            const { model: renderer } = renderer_view;
            const tooltip = this.ttmodels[renderer.id];
            if (tooltip == null)
                return;
            tooltip.clear();
            const selection_manager = renderer.get_selection_manager();
            let indices = selection_manager.inspectors[renderer.id];
            if (renderer instanceof glyph_renderer_1.GlyphRenderer)
                indices = renderer.view.convert_selection_to_subset(indices);
            if (indices.is_empty())
                return;
            const ds = selection_manager.source;
            const { frame } = this.plot_view;
            const { sx, sy } = geometry;
            const xscale = frame.xscales[renderer.x_range_name];
            const yscale = frame.yscales[renderer.y_range_name];
            const x = xscale.invert(sx);
            const y = yscale.invert(sy);
            const glyph = renderer_view.glyph; // XXX
            for (const i of indices.line_indices) {
                let data_x = glyph._x[i + 1];
                let data_y = glyph._y[i + 1];
                let ii = i;
                let rx;
                let ry;
                switch (this.model.line_policy) {
                    case "interp": { // and renderer.get_interpolation_hit?
                        [data_x, data_y] = glyph.get_interpolation_hit(i, geometry);
                        rx = xscale.compute(data_x);
                        ry = yscale.compute(data_y);
                        break;
                    }
                    case "prev": {
                        [[rx, ry], ii] = _line_hit(glyph.sx, glyph.sy, i);
                        break;
                    }
                    case "next": {
                        [[rx, ry], ii] = _line_hit(glyph.sx, glyph.sy, i + 1);
                        break;
                    }
                    case "nearest": {
                        [[rx, ry], ii] = _nearest_line_hit(i, geometry, sx, sy, glyph.sx, glyph.sy);
                        data_x = glyph._x[ii];
                        data_y = glyph._y[ii];
                        break;
                    }
                    default: {
                        [rx, ry] = [sx, sy];
                    }
                }
                const vars = {
                    index: ii,
                    x, y, sx, sy, data_x, data_y, rx, ry,
                    indices: indices.line_indices,
                    name: renderer_view.model.name,
                };
                tooltip.add(rx, ry, this._render_tooltips(ds, ii, vars));
            }
            for (const struct of indices.image_indices) {
                const vars = { index: struct.index, x, y, sx, sy };
                const rendered = this._render_tooltips(ds, struct, vars);
                tooltip.add(sx, sy, rendered);
            }
            for (const i of indices.indices) {
                // multiglyphs set additional indices, e.g. multiline_indices for different tooltips
                if (!object_1.isEmpty(indices.multiline_indices)) {
                    for (const j of indices.multiline_indices[i.toString()]) {
                        let data_x = glyph._xs[i][j];
                        let data_y = glyph._ys[i][j];
                        let jj = j;
                        let rx;
                        let ry;
                        switch (this.model.line_policy) {
                            case "interp": { // and renderer.get_interpolation_hit?
                                [data_x, data_y] = glyph.get_interpolation_hit(i, j, geometry);
                                rx = xscale.compute(data_x);
                                ry = yscale.compute(data_y);
                                break;
                            }
                            case "prev": {
                                [[rx, ry], jj] = _line_hit(glyph.sxs[i], glyph.sys[i], j);
                                break;
                            }
                            case "next": {
                                [[rx, ry], jj] = _line_hit(glyph.sxs[i], glyph.sys[i], j + 1);
                                break;
                            }
                            case "nearest": {
                                [[rx, ry], jj] = _nearest_line_hit(j, geometry, sx, sy, glyph.sxs[i], glyph.sys[i]);
                                data_x = glyph._xs[i][jj];
                                data_y = glyph._ys[i][jj];
                                break;
                            }
                            default:
                                throw new Error("should't have happened");
                        }
                        let index;
                        if (renderer instanceof glyph_renderer_1.GlyphRenderer)
                            index = renderer.view.convert_indices_from_subset([i])[0];
                        else
                            index = i;
                        const vars = {
                            index, x, y, sx, sy, data_x, data_y,
                            segment_index: jj,
                            indices: indices.multiline_indices,
                            name: renderer_view.model.name,
                        };
                        tooltip.add(rx, ry, this._render_tooltips(ds, index, vars));
                    }
                }
                else {
                    // handle non-multiglyphs
                    const data_x = glyph._x != null ? glyph._x[i] : undefined;
                    const data_y = glyph._y != null ? glyph._y[i] : undefined;
                    let rx;
                    let ry;
                    if (this.model.point_policy == 'snap_to_data') { // and renderer.glyph.sx? and renderer.glyph.sy?
                        // Pass in our screen position so we can determine which patch we're
                        // over if there are discontinuous patches.
                        let pt = glyph.get_anchor_point(this.model.anchor, i, [sx, sy]);
                        if (pt == null)
                            pt = glyph.get_anchor_point("center", i, [sx, sy]);
                        rx = pt.x;
                        ry = pt.y;
                    }
                    else
                        [rx, ry] = [sx, sy];
                    let index;
                    if (renderer instanceof glyph_renderer_1.GlyphRenderer)
                        index = renderer.view.convert_indices_from_subset([i])[0];
                    else
                        index = i;
                    const vars = {
                        index, x, y, sx, sy, data_x, data_y,
                        indices: indices.indices,
                        name: renderer_view.model.name,
                    };
                    tooltip.add(rx, ry, this._render_tooltips(ds, index, vars));
                }
            }
        }
        _emit_callback(geometry) {
            for (const r of this.computed_renderers) {
                const index = r.data_source.inspected;
                const { frame } = this.plot_view;
                const xscale = frame.xscales[r.x_range_name];
                const yscale = frame.yscales[r.y_range_name];
                const x = xscale.invert(geometry.sx);
                const y = yscale.invert(geometry.sy);
                const g = Object.assign({ x, y }, geometry);
                this.model.callback.execute(this.model, { index, geometry: g, renderer: r });
            }
        }
        _render_tooltips(ds, i, vars) {
            const tooltips = this.model.tooltips;
            if (types_1.isString(tooltips)) {
                const el = dom_1.div();
                el.innerHTML = templating_1.replace_placeholders(tooltips, ds, i, this.model.formatters, vars);
                return el;
            }
            else if (types_1.isFunction(tooltips)) {
                return tooltips(ds, vars);
            }
            else {
                const rows = dom_1.div({ style: { display: "table", borderSpacing: "2px" } });
                for (const [label, value] of tooltips) {
                    const row = dom_1.div({ style: { display: "table-row" } });
                    rows.appendChild(row);
                    let cell;
                    cell = dom_1.div({ style: { display: "table-cell" }, class: tooltips_1.bk_tooltip_row_label }, label.length != 0 ? `${label}: ` : "");
                    row.appendChild(cell);
                    cell = dom_1.div({ style: { display: "table-cell" }, class: tooltips_1.bk_tooltip_row_value });
                    row.appendChild(cell);
                    if (value.indexOf("$color") >= 0) {
                        const [, opts = "", colname] = value.match(/\$color(\[.*\])?:(\w*)/); // XXX!
                        const column = ds.get_column(colname); // XXX: change to columnar ds
                        if (column == null) {
                            const el = dom_1.span({}, `${colname} unknown`);
                            cell.appendChild(el);
                            continue;
                        }
                        const hex = opts.indexOf("hex") >= 0;
                        const swatch = opts.indexOf("swatch") >= 0;
                        let color = types_1.isNumber(i) ? column[i] : null;
                        if (color == null) {
                            const el = dom_1.span({}, "(null)");
                            cell.appendChild(el);
                            continue;
                        }
                        if (hex)
                            color = color_1.color2hex(color);
                        let el = dom_1.span({}, color);
                        cell.appendChild(el);
                        if (swatch) {
                            el = dom_1.span({ class: tooltips_1.bk_tooltip_color_block, style: { backgroundColor: color } }, " ");
                            cell.appendChild(el);
                        }
                    }
                    else {
                        const el = dom_1.span();
                        el.innerHTML = templating_1.replace_placeholders(value.replace("$~", "$data_"), ds, i, this.model.formatters, vars);
                        cell.appendChild(el);
                    }
                }
                return rows;
            }
        }
    }
    exports.HoverToolView = HoverToolView;
    HoverToolView.__name__ = "HoverToolView";
    class HoverTool extends inspect_tool_1.InspectTool {
        constructor(attrs) {
            super(attrs);
            this.tool_name = "Hover";
            this.icon = icons_1.bk_tool_icon_hover;
        }
        static init_HoverTool() {
            this.prototype.default_view = HoverToolView;
            this.define({
                tooltips: [p.Any, [
                        ["index", "$index"],
                        ["data (x, y)", "($x, $y)"],
                        ["screen (x, y)", "($sx, $sy)"],
                    ]],
                formatters: [p.Any, {}],
                renderers: [p.Any, 'auto'],
                names: [p.Array, []],
                mode: [p.HoverMode, 'mouse'],
                point_policy: [p.PointPolicy, 'snap_to_data'],
                line_policy: [p.LinePolicy, 'nearest'],
                show_arrow: [p.Boolean, true],
                anchor: [p.Anchor, 'center'],
                attachment: [p.TooltipAttachment, 'horizontal'],
                callback: [p.Any],
            });
        }
    }
    exports.HoverTool = HoverTool;
    HoverTool.__name__ = "HoverTool";
    HoverTool.init_HoverTool();
},
/* models/tools/tool_proxy.js */ function _(require, module, exports) {
    const p = require(18) /* ../../core/properties */;
    const signaling_1 = require(13) /* ../../core/signaling */;
    const model_1 = require(64) /* ../../model */;
    const inspect_tool_1 = require(262) /* ./inspectors/inspect_tool */;
    class ToolProxy extends model_1.Model {
        constructor(attrs) {
            super(attrs);
        }
        static init_ToolProxy() {
            this.define({
                tools: [p.Array, []],
                active: [p.Boolean, false],
                disabled: [p.Boolean, false],
            });
        }
        // Operates all the tools given only one button
        get button_view() {
            return this.tools[0].button_view;
        }
        get event_type() {
            return this.tools[0].event_type;
        }
        get tooltip() {
            return this.tools[0].tooltip;
        }
        get tool_name() {
            return this.tools[0].tool_name;
        }
        get icon() {
            return this.tools[0].computed_icon;
        }
        get computed_icon() {
            return this.icon;
        }
        get toggleable() {
            const tool = this.tools[0];
            return tool instanceof inspect_tool_1.InspectTool && tool.toggleable;
        }
        initialize() {
            super.initialize();
            this.do = new signaling_1.Signal0(this, "do");
        }
        connect_signals() {
            super.connect_signals();
            this.connect(this.do, () => this.doit());
            this.connect(this.properties.active.change, () => this.set_active());
        }
        doit() {
            for (const tool of this.tools) {
                tool.do.emit();
            }
        }
        set_active() {
            for (const tool of this.tools) {
                tool.active = this.active;
            }
        }
    }
    exports.ToolProxy = ToolProxy;
    ToolProxy.__name__ = "ToolProxy";
    ToolProxy.init_ToolProxy();
},
/* models/tools/toolbar_box.js */ function _(require, module, exports) {
    const p = require(18) /* ../../core/properties */;
    const array_1 = require(8) /* ../../core/util/array */;
    const toolbar_base_1 = require(267) /* ./toolbar_base */;
    const tool_proxy_1 = require(337) /* ./tool_proxy */;
    const layout_dom_1 = require(237) /* ../layouts/layout_dom */;
    const layout_1 = require(180) /* ../../core/layout */;
    class ProxyToolbar extends toolbar_base_1.ToolbarBase {
        constructor(attrs) {
            super(attrs);
        }
        initialize() {
            super.initialize();
            this._merge_tools();
        }
        _merge_tools() {
            // Go through all the tools on the toolbar and replace them with
            // a proxy e.g. PanTool, BoxSelectTool, etc.
            this._proxied_tools = [];
            const inspectors = {};
            const actions = {};
            const gestures = {};
            const new_help_tools = [];
            const new_help_urls = [];
            for (const helptool of this.help) {
                if (!array_1.includes(new_help_urls, helptool.redirect)) {
                    new_help_tools.push(helptool);
                    new_help_urls.push(helptool.redirect);
                }
            }
            this._proxied_tools.push(...new_help_tools);
            this.help = new_help_tools;
            for (const event_type in this.gestures) {
                const gesture = this.gestures[event_type];
                if (!(event_type in gestures)) {
                    gestures[event_type] = {};
                }
                for (const tool of gesture.tools) {
                    if (!(tool.type in gestures[event_type])) {
                        gestures[event_type][tool.type] = [];
                    }
                    gestures[event_type][tool.type].push(tool);
                }
            }
            for (const tool of this.inspectors) {
                if (!(tool.type in inspectors)) {
                    inspectors[tool.type] = [];
                }
                inspectors[tool.type].push(tool);
            }
            for (const tool of this.actions) {
                if (!(tool.type in actions)) {
                    actions[tool.type] = [];
                }
                actions[tool.type].push(tool);
            }
            // Add a proxy for each of the groups of tools.
            const make_proxy = (tools, active = false) => {
                const proxy = new tool_proxy_1.ToolProxy({ tools, active });
                this._proxied_tools.push(proxy);
                return proxy;
            };
            for (const event_type in gestures) {
                const gesture = this.gestures[event_type];
                gesture.tools = [];
                for (const tool_type in gestures[event_type]) {
                    const tools = gestures[event_type][tool_type];
                    if (tools.length > 0) {
                        if (event_type == 'multi') {
                            for (const tool of tools) {
                                const proxy = make_proxy([tool]);
                                gesture.tools.push(proxy);
                                this.connect(proxy.properties.active.change, this._active_change.bind(this, proxy));
                            }
                        }
                        else {
                            const proxy = make_proxy(tools);
                            gesture.tools.push(proxy);
                            this.connect(proxy.properties.active.change, this._active_change.bind(this, proxy));
                        }
                    }
                }
            }
            this.actions = [];
            for (const tool_type in actions) {
                const tools = actions[tool_type];
                if (tool_type == 'CustomAction') {
                    for (const tool of tools)
                        this.actions.push(make_proxy([tool]));
                }
                else if (tools.length > 0) {
                    this.actions.push(make_proxy(tools)); // XXX
                }
            }
            this.inspectors = [];
            for (const tool_type in inspectors) {
                const tools = inspectors[tool_type];
                if (tools.length > 0)
                    this.inspectors.push(make_proxy(tools, true)); // XXX
            }
            for (const et in this.gestures) {
                const gesture = this.gestures[et];
                if (gesture.tools.length == 0)
                    continue;
                gesture.tools = array_1.sort_by(gesture.tools, (tool) => tool.default_order);
                if (!(et == 'pinch' || et == 'scroll' || et == 'multi'))
                    gesture.tools[0].active = true;
            }
        }
    }
    exports.ProxyToolbar = ProxyToolbar;
    ProxyToolbar.__name__ = "ProxyToolbar";
    class ToolbarBoxView extends layout_dom_1.LayoutDOMView {
        initialize() {
            this.model.toolbar.toolbar_location = this.model.toolbar_location;
            super.initialize();
        }
        get child_models() {
            return [this.model.toolbar]; // XXX
        }
        _update_layout() {
            this.layout = new layout_1.ContentBox(this.child_views[0].el);
            const { toolbar } = this.model;
            if (toolbar.horizontal) {
                this.layout.set_sizing({
                    width_policy: "fit", min_width: 100, height_policy: "fixed",
                });
            }
            else {
                this.layout.set_sizing({
                    width_policy: "fixed", height_policy: "fit", min_height: 100,
                });
            }
        }
    }
    exports.ToolbarBoxView = ToolbarBoxView;
    ToolbarBoxView.__name__ = "ToolbarBoxView";
    class ToolbarBox extends layout_dom_1.LayoutDOM {
        constructor(attrs) {
            super(attrs);
        }
        static init_ToolbarBox() {
            this.prototype.default_view = ToolbarBoxView;
            this.define({
                toolbar: [p.Instance],
                toolbar_location: [p.Location, "right"],
            });
        }
    }
    exports.ToolbarBox = ToolbarBox;
    ToolbarBox.__name__ = "ToolbarBox";
    ToolbarBox.init_ToolbarBox();
},
/* embed/standalone.js */ function _(require, module, exports) {
    const document_1 = require(4) /* ../document */;
    const dom_1 = require(61) /* ../core/dom */;
    const dom_2 = require(340) /* ./dom */;
    // A map from the root model IDs to their views.
    exports.index = {};
    function _create_view(model) {
        const view = new model.default_view({ model, parent: null });
        exports.index[model.id] = view;
        return view;
    }
    function add_document_standalone(document, element, roots = {}, use_for_title = false) {
        // this is a LOCAL index of views used only by this particular rendering
        // call, so we can remove the views we create.
        const views = {};
        function render_model(model) {
            let root_el;
            if (model.id in roots)
                root_el = roots[model.id];
            else if (element.classList.contains(dom_2.BOKEH_ROOT))
                root_el = element;
            else {
                root_el = dom_1.div({ class: dom_2.BOKEH_ROOT });
                element.appendChild(root_el);
            }
            const view = _create_view(model);
            view.renderTo(root_el);
            views[model.id] = view;
        }
        function unrender_model(model) {
            const { id } = model;
            if (id in views) {
                const view = views[id];
                view.remove();
                delete views[id];
                delete exports.index[id];
            }
        }
        for (const model of document.roots())
            render_model(model);
        if (use_for_title)
            window.document.title = document.title();
        document.on_change((event) => {
            if (event instanceof document_1.RootAddedEvent)
                render_model(event.model);
            else if (event instanceof document_1.RootRemovedEvent)
                unrender_model(event.model);
            else if (use_for_title && event instanceof document_1.TitleChangedEvent)
                window.document.title = event.title;
        });
        return views;
    }
    exports.add_document_standalone = add_document_standalone;
},
/* embed/dom.js */ function _(require, module, exports) {
    const dom_1 = require(61) /* ../core/dom */;
    const root_1 = require(62) /* ../styles/root */;
    // Matches Bokeh CSS class selector. Setting all Bokeh parent element class names
    // with this var prevents user configurations where css styling is unset.
    exports.BOKEH_ROOT = root_1.bk_root;
    function _get_element(elementid) {
        let element = document.getElementById(elementid);
        if (element == null)
            throw new Error(`Error rendering Bokeh model: could not find #${elementid} HTML tag`);
        if (!document.body.contains(element))
            throw new Error(`Error rendering Bokeh model: element #${elementid} must be under <body>`);
        // If autoload script, replace script tag with div for embedding.
        if (element.tagName == "SCRIPT") {
            const root_el = dom_1.div({ class: exports.BOKEH_ROOT });
            dom_1.replaceWith(element, root_el);
            element = root_el;
        }
        return element;
    }
    function _resolve_element(item) {
        const { elementid } = item;
        if (elementid != null)
            return _get_element(elementid);
        else
            return document.body;
    }
    exports._resolve_element = _resolve_element;
    function _resolve_root_elements(item) {
        const roots = {};
        if (item.roots != null) {
            for (const root_id in item.roots)
                roots[root_id] = _get_element(item.roots[root_id]);
        }
        return roots;
    }
    exports._resolve_root_elements = _resolve_root_elements;
},
/* embed/server.js */ function _(require, module, exports) {
    const connection_1 = require(342) /* ../client/connection */;
    const logging_1 = require(65) /* ../core/logging */;
    const standalone_1 = require(339) /* ./standalone */;
    // @internal
    function _get_ws_url(app_path, absolute_url) {
        let protocol = 'ws:';
        if (window.location.protocol == 'https:')
            protocol = 'wss:';
        let loc;
        if (absolute_url != null) {
            loc = document.createElement('a');
            loc.href = absolute_url;
        }
        else
            loc = window.location;
        if (app_path != null) {
            if (app_path == "/")
                app_path = "";
        }
        else
            app_path = loc.pathname.replace(/\/+$/, '');
        return protocol + '//' + loc.host + app_path + '/ws';
    }
    exports._get_ws_url = _get_ws_url;
    // map { websocket url to map { session id to promise of ClientSession } }
    const _sessions = {};
    function _get_session(websocket_url, session_id, args_string) {
        if (!(websocket_url in _sessions))
            _sessions[websocket_url] = {};
        const subsessions = _sessions[websocket_url];
        if (!(session_id in subsessions))
            subsessions[session_id] = connection_1.pull_session(websocket_url, session_id, args_string);
        return subsessions[session_id];
    }
    // Fill element with the roots from session_id
    function add_document_from_session(websocket_url, session_id, element, roots = {}, use_for_title = false) {
        const args_string = window.location.search.substr(1);
        const promise = _get_session(websocket_url, session_id, args_string);
        return promise.then((session) => {
            return standalone_1.add_document_standalone(session.document, element, roots, use_for_title);
        }, (error) => {
            logging_1.logger.error(`Failed to load Bokeh session ${session_id}: ${error}`);
            throw error;
        });
    }
    exports.add_document_from_session = add_document_from_session;
},
/* client/connection.js */ function _(require, module, exports) {
    const logging_1 = require(65) /* ../core/logging */;
    const document_1 = require(4) /* ../document */;
    const message_1 = require(343) /* ../protocol/message */;
    const receiver_1 = require(344) /* ../protocol/receiver */;
    const session_1 = require(345) /* ./session */;
    exports.DEFAULT_SERVER_WEBSOCKET_URL = "ws://localhost:5006/ws";
    exports.DEFAULT_SESSION_ID = "default";
    let _connection_count = 0;
    class ClientConnection {
        constructor(url = exports.DEFAULT_SERVER_WEBSOCKET_URL, id = exports.DEFAULT_SESSION_ID, args_string = null, _on_have_session_hook = null, _on_closed_permanently_hook = null) {
            this.url = url;
            this.id = id;
            this.args_string = args_string;
            this._on_have_session_hook = _on_have_session_hook;
            this._on_closed_permanently_hook = _on_closed_permanently_hook;
            this._number = _connection_count++;
            this.socket = null;
            this.session = null;
            this.closed_permanently = false;
            this._current_handler = null;
            this._pending_ack = null; // null or [resolve,reject]
            this._pending_replies = {}; // map reqid to [resolve,reject]
            this._pending_messages = [];
            this._receiver = new receiver_1.Receiver();
            logging_1.logger.debug(`Creating websocket ${this._number} to '${this.url}' session '${this.id}'`);
        }
        connect() {
            if (this.closed_permanently)
                return Promise.reject(new Error("Cannot connect() a closed ClientConnection"));
            if (this.socket != null)
                return Promise.reject(new Error("Already connected"));
            this._pending_replies = {};
            this._current_handler = null;
            try {
                let versioned_url = `${this.url}?bokeh-protocol-version=1.0&bokeh-session-id=${this.id}`;
                if (this.args_string != null && this.args_string.length > 0)
                    versioned_url += `&${this.args_string}`;
                this.socket = new WebSocket(versioned_url);
                return new Promise((resolve, reject) => {
                    // "arraybuffer" gives us binary data we can look at;
                    // if we just needed an opaque blob we could use "blob"
                    this.socket.binaryType = "arraybuffer";
                    this.socket.onopen = () => this._on_open(resolve, reject);
                    this.socket.onmessage = (event) => this._on_message(event);
                    this.socket.onclose = (event) => this._on_close(event);
                    this.socket.onerror = () => this._on_error(reject);
                });
            }
            catch (error) {
                logging_1.logger.error(`websocket creation failed to url: ${this.url}`);
                logging_1.logger.error(` - ${error}`);
                return Promise.reject(error);
            }
        }
        close() {
            if (!this.closed_permanently) {
                logging_1.logger.debug(`Permanently closing websocket connection ${this._number}`);
                this.closed_permanently = true;
                if (this.socket != null)
                    this.socket.close(1000, `close method called on ClientConnection ${this._number}`);
                this.session._connection_closed();
                if (this._on_closed_permanently_hook != null) {
                    this._on_closed_permanently_hook();
                    this._on_closed_permanently_hook = null;
                }
            }
        }
        _schedule_reconnect(milliseconds) {
            const retry = () => {
                // TODO commented code below until we fix reconnection to repull
                // the document when required. Otherwise, we get a lot of
                // confusing errors that are causing trouble when debugging.
                /*
                if (this.closed_permanently) {
                */
                if (!this.closed_permanently)
                    logging_1.logger.info(`Websocket connection ${this._number} disconnected, will not attempt to reconnect`);
                return;
                /*
                } else {
                  logger.debug(`Attempting to reconnect websocket ${this._number}`)
                  this.connect()
                }
                */
            };
            setTimeout(retry, milliseconds);
        }
        send(message) {
            if (this.socket == null)
                throw new Error(`not connected so cannot send ${message}`);
            message.send(this.socket);
        }
        send_with_reply(message) {
            const promise = new Promise((resolve, reject) => {
                this._pending_replies[message.msgid()] = [resolve, reject];
                this.send(message);
            });
            return promise.then((message) => {
                if (message.msgtype() === "ERROR")
                    throw new Error(`Error reply ${message.content.text}`);
                else
                    return message;
            }, (error) => {
                throw error;
            });
        }
        _pull_doc_json() {
            const message = message_1.Message.create("PULL-DOC-REQ", {});
            const promise = this.send_with_reply(message);
            return promise.then((reply) => {
                if (!('doc' in reply.content))
                    throw new Error("No 'doc' field in PULL-DOC-REPLY");
                return reply.content.doc;
            }, (error) => {
                throw error;
            });
        }
        _repull_session_doc() {
            if (this.session == null)
                logging_1.logger.debug("Pulling session for first time");
            else
                logging_1.logger.debug("Repulling session");
            this._pull_doc_json().then((doc_json) => {
                if (this.session == null) {
                    if (this.closed_permanently)
                        logging_1.logger.debug("Got new document after connection was already closed");
                    else {
                        const document = document_1.Document.from_json(doc_json);
                        // Constructing models changes some of their attributes, we deal with that
                        // here. This happens when models set attributes during construction
                        // or initialization.
                        const patch = document_1.Document._compute_patch_since_json(doc_json, document);
                        if (patch.events.length > 0) {
                            logging_1.logger.debug(`Sending ${patch.events.length} changes from model construction back to server`);
                            const patch_message = message_1.Message.create('PATCH-DOC', {}, patch);
                            this.send(patch_message);
                        }
                        this.session = new session_1.ClientSession(this, document, this.id);
                        for (const msg of this._pending_messages) {
                            this.session.handle(msg);
                        }
                        this._pending_messages = [];
                        logging_1.logger.debug("Created a new session from new pulled doc");
                        if (this._on_have_session_hook != null) {
                            this._on_have_session_hook(this.session);
                            this._on_have_session_hook = null;
                        }
                    }
                }
                else {
                    this.session.document.replace_with_json(doc_json);
                    logging_1.logger.debug("Updated existing session with new pulled doc");
                }
            }, (error) => {
                // handling the error here is useless because we wouldn't
                // get errors from the resolve handler above, so see
                // the catch below instead
                throw error;
            }).catch((error) => {
                if (console.trace != null)
                    console.trace(error);
                logging_1.logger.error(`Failed to repull session ${error}`);
            });
        }
        _on_open(resolve, reject) {
            logging_1.logger.info(`Websocket connection ${this._number} is now open`);
            this._pending_ack = [resolve, reject];
            this._current_handler = (message) => {
                this._awaiting_ack_handler(message);
            };
        }
        _on_message(event) {
            if (this._current_handler == null)
                logging_1.logger.error("Got a message with no current handler set");
            try {
                this._receiver.consume(event.data);
            }
            catch (e) {
                this._close_bad_protocol(e.toString());
            }
            if (this._receiver.message == null)
                return;
            const msg = this._receiver.message;
            const problem = msg.problem();
            if (problem != null)
                this._close_bad_protocol(problem);
            this._current_handler(msg);
        }
        _on_close(event) {
            logging_1.logger.info(`Lost websocket ${this._number} connection, ${event.code} (${event.reason})`);
            this.socket = null;
            if (this._pending_ack != null) {
                this._pending_ack[1](new Error(`Lost websocket connection, ${event.code} (${event.reason})`));
                this._pending_ack = null;
            }
            const pop_pending = () => {
                for (const reqid in this._pending_replies) {
                    const promise_funcs = this._pending_replies[reqid];
                    delete this._pending_replies[reqid];
                    return promise_funcs;
                }
                return null;
            };
            let promise_funcs = pop_pending();
            while (promise_funcs != null) {
                promise_funcs[1]("Disconnected");
                promise_funcs = pop_pending();
            }
            if (!this.closed_permanently)
                this._schedule_reconnect(2000);
        }
        _on_error(reject) {
            logging_1.logger.debug(`Websocket error on socket ${this._number}`);
            reject(new Error("Could not open websocket"));
        }
        _close_bad_protocol(detail) {
            logging_1.logger.error(`Closing connection: ${detail}`);
            if (this.socket != null)
                this.socket.close(1002, detail); // 1002 = protocol error
        }
        _awaiting_ack_handler(message) {
            if (message.msgtype() === "ACK") {
                this._current_handler = (message) => this._steady_state_handler(message);
                // Reload any sessions
                this._repull_session_doc();
                if (this._pending_ack != null) {
                    this._pending_ack[0](this);
                    this._pending_ack = null;
                }
            }
            else
                this._close_bad_protocol("First message was not an ACK");
        }
        _steady_state_handler(message) {
            if (message.reqid() in this._pending_replies) {
                const promise_funcs = this._pending_replies[message.reqid()];
                delete this._pending_replies[message.reqid()];
                promise_funcs[0](message);
            }
            else if (this.session) {
                this.session.handle(message);
            }
            else {
                this._pending_messages.push(message);
            }
        }
    }
    exports.ClientConnection = ClientConnection;
    ClientConnection.__name__ = "ClientConnection";
    // Returns a promise of a ClientSession
    // The returned promise has a close() method in case you want to close before
    // getting a session; session.close() works too once you have a session.
    function pull_session(url, session_id, args_string) {
        const promise = new Promise((resolve, reject) => {
            const connection = new ClientConnection(url, session_id, args_string, (session) => {
                try {
                    resolve(session);
                }
                catch (error) {
                    logging_1.logger.error(`Promise handler threw an error, closing session ${error}`);
                    session.close();
                    throw error;
                }
            }, () => {
                // we rely on reject() as a no-op if we already resolved
                reject(new Error("Connection was closed before we successfully pulled a session"));
            });
            connection.connect().then((_) => undefined, (error) => {
                logging_1.logger.error(`Failed to connect to Bokeh server ${error}`);
                throw error;
            });
        });
        return promise;
    }
    exports.pull_session = pull_session;
},
/* protocol/message.js */ function _(require, module, exports) {
    const string_1 = require(25) /* ../core/util/string */;
    class Message {
        constructor(header, metadata, content) {
            this.header = header;
            this.metadata = metadata;
            this.content = content;
            this.buffers = [];
        }
        static assemble(header_json, metadata_json, content_json) {
            const header = JSON.parse(header_json);
            const metadata = JSON.parse(metadata_json);
            const content = JSON.parse(content_json);
            return new Message(header, metadata, content);
        }
        assemble_buffer(buf_header, buf_payload) {
            const nb = this.header.num_buffers != null ? this.header.num_buffers : 0;
            if (nb <= this.buffers.length)
                throw new Error("too many buffers received, expecting #{nb}");
            this.buffers.push([buf_header, buf_payload]);
        }
        // not defined for BokehJS, only *receiving* buffers is supported
        // add_buffer: (buf_header, buf_payload) ->
        // write_buffers: (socket)
        static create(msgtype, metadata, content = {}) {
            const header = Message.create_header(msgtype);
            return new Message(header, metadata, content);
        }
        static create_header(msgtype) {
            return {
                msgid: string_1.uniqueId(),
                msgtype,
            };
        }
        complete() {
            if (this.header != null && this.metadata != null && this.content != null) {
                if ('num_buffers' in this.header)
                    return this.buffers.length === this.header.num_buffers;
                else
                    return true;
            }
            else
                return false;
        }
        send(socket) {
            const nb = this.header.num_buffers != null ? this.header.num_buffers : 0;
            if (nb > 0)
                throw new Error("BokehJS only supports receiving buffers, not sending");
            const header_json = JSON.stringify(this.header);
            const metadata_json = JSON.stringify(this.metadata);
            const content_json = JSON.stringify(this.content);
            socket.send(header_json);
            socket.send(metadata_json);
            socket.send(content_json);
        }
        msgid() {
            return this.header.msgid;
        }
        msgtype() {
            return this.header.msgtype;
        }
        reqid() {
            return this.header.reqid;
        }
        // return the reason we should close on bad protocol, if there is one
        problem() {
            if (!('msgid' in this.header))
                return "No msgid in header";
            else if (!('msgtype' in this.header))
                return "No msgtype in header";
            else
                return null;
        }
    }
    exports.Message = Message;
    Message.__name__ = "Message";
},
/* protocol/receiver.js */ function _(require, module, exports) {
    const message_1 = require(343) /* ./message */;
    class Receiver {
        constructor() {
            this.message = null;
            this._partial = null;
            this._fragments = [];
            this._buf_header = null;
            this._current_consumer = this._HEADER;
        }
        consume(fragment) {
            this._current_consumer(fragment);
        }
        _HEADER(fragment) {
            this._assume_text(fragment);
            this.message = null;
            this._partial = null;
            this._fragments = [fragment];
            this._buf_header = null;
            this._current_consumer = this._METADATA;
        }
        _METADATA(fragment) {
            this._assume_text(fragment);
            this._fragments.push(fragment);
            this._current_consumer = this._CONTENT;
        }
        _CONTENT(fragment) {
            this._assume_text(fragment);
            this._fragments.push(fragment);
            const [header_json, metadata_json, content_json] = this._fragments.slice(0, 3);
            this._partial = message_1.Message.assemble(header_json, metadata_json, content_json);
            this._check_complete();
        }
        _BUFFER_HEADER(fragment) {
            this._assume_text(fragment);
            this._buf_header = fragment; // XXX: assume text but Header is expected
            this._current_consumer = this._BUFFER_PAYLOAD;
        }
        _BUFFER_PAYLOAD(fragment) {
            this._assume_binary(fragment);
            this._partial.assemble_buffer(this._buf_header, fragment);
            this._check_complete();
        }
        _assume_text(fragment) {
            if (fragment instanceof ArrayBuffer)
                throw new Error("Expected text fragment but received binary fragment");
        }
        _assume_binary(fragment) {
            if (!(fragment instanceof ArrayBuffer))
                throw new Error("Expected binary fragment but received text fragment");
        }
        _check_complete() {
            if (this._partial.complete()) {
                this.message = this._partial;
                this._current_consumer = this._HEADER;
            }
            else
                this._current_consumer = this._BUFFER_HEADER;
        }
    }
    exports.Receiver = Receiver;
    Receiver.__name__ = "Receiver";
},
/* client/session.js */ function _(require, module, exports) {
    const document_1 = require(4) /* ../document */;
    const message_1 = require(343) /* ../protocol/message */;
    const logging_1 = require(65) /* ../core/logging */;
    class ClientSession {
        constructor(_connection, document, id) {
            this._connection = _connection;
            this.document = document;
            this.id = id;
            this._document_listener = (event) => this._document_changed(event);
            this.document.on_change(this._document_listener);
            this.event_manager = this.document.event_manager;
            this.event_manager.session = this;
        }
        handle(message) {
            const msgtype = message.msgtype();
            if (msgtype === 'PATCH-DOC')
                this._handle_patch(message);
            else if (msgtype === 'OK')
                this._handle_ok(message);
            else if (msgtype === 'ERROR')
                this._handle_error(message);
            else
                logging_1.logger.debug(`Doing nothing with message ${message.msgtype()}`);
        }
        close() {
            this._connection.close();
        }
        send_event(event) {
            const message = message_1.Message.create('EVENT', {}, JSON.stringify(event.to_json()));
            this._connection.send(message);
        }
        /*protected*/ _connection_closed() {
            this.document.remove_on_change(this._document_listener);
        }
        // Sends a request to the server for info about the server, such as its Bokeh
        // version. Returns a promise, the value of the promise is a free-form dictionary
        // of server details.
        request_server_info() {
            const message = message_1.Message.create('SERVER-INFO-REQ', {});
            const promise = this._connection.send_with_reply(message);
            return promise.then((reply) => reply.content);
        }
        // Sends some request to the server (no guarantee about which one) and returns
        // a promise which is completed when the server replies. The purpose of this
        // is that if you wait for the promise to be completed, you know the server
        // has processed the request. This is useful when writing tests because once
        // the server has processed this request it should also have processed any
        // events or requests you sent previously, which means you can check for the
        // results of that processing without a race condition. (This assumes the
        // server processes events in sequence, which it mostly has to semantically,
        // since reordering events might change the final state.)
        force_roundtrip() {
            return this.request_server_info().then((_) => undefined);
        }
        _document_changed(event) {
            // Filter out events that were initiated by the ClientSession itself
            if (event.setter_id === this.id) // XXX: not all document events define this
                return;
            // Filter out changes to attributes that aren't server-visible
            if (event instanceof document_1.ModelChangedEvent && !(event.attr in event.model.serializable_attributes()))
                return;
            // TODO (havocp) the connection may be closed here, which will
            // cause this send to throw an error - need to deal with it more cleanly.
            const message = message_1.Message.create('PATCH-DOC', {}, this.document.create_json_patch([event]));
            this._connection.send(message);
        }
        _handle_patch(message) {
            this.document.apply_json_patch(message.content, message.buffers, this.id);
        }
        _handle_ok(message) {
            logging_1.logger.trace(`Unhandled OK reply to ${message.reqid()}`);
        }
        _handle_error(message) {
            logging_1.logger.error(`Unhandled ERROR reply to ${message.reqid()}: ${message.content.text}`);
        }
    }
    exports.ClientSession = ClientSession;
    ClientSession.__name__ = "ClientSession";
},
/* embed/notebook.js */ function _(require, module, exports) {
    const document_1 = require(4) /* ../document */;
    const receiver_1 = require(344) /* ../protocol/receiver */;
    const logging_1 = require(65) /* ../core/logging */;
    const object_1 = require(22) /* ../core/util/object */;
    const standalone_1 = require(339) /* ./standalone */;
    const dom_1 = require(340) /* ./dom */;
    require(272) /* ../styles/logo */;
    require(347) /* ../styles/notebook */;
    // This exists to allow the @bokeh/jupyter_bokeh extension to store the
    // notebook kernel so that _init_comms can register the comms target.
    // This has to be available at window.Bokeh.embed.kernels in JupyterLab.
    exports.kernels = {};
    function _handle_notebook_comms(receiver, comm_msg) {
        if (comm_msg.buffers.length > 0)
            receiver.consume(comm_msg.buffers[0].buffer);
        else
            receiver.consume(comm_msg.content.data);
        const msg = receiver.message;
        if (msg != null)
            this.apply_json_patch(msg.content, msg.buffers);
    }
    function _init_comms(target, doc) {
        if (typeof Jupyter !== 'undefined' && Jupyter.notebook.kernel != null) {
            logging_1.logger.info(`Registering Jupyter comms for target ${target}`);
            const comm_manager = Jupyter.notebook.kernel.comm_manager;
            try {
                comm_manager.register_target(target, (comm) => {
                    logging_1.logger.info(`Registering Jupyter comms for target ${target}`);
                    const r = new receiver_1.Receiver();
                    comm.on_msg(_handle_notebook_comms.bind(doc, r));
                });
            }
            catch (e) {
                logging_1.logger.warn(`Jupyter comms failed to register. push_notebook() will not function. (exception reported: ${e})`);
            }
        }
        else if (doc.roots()[0].id in exports.kernels) {
            logging_1.logger.info(`Registering JupyterLab comms for target ${target}`);
            const kernel = exports.kernels[doc.roots()[0].id];
            try {
                kernel.registerCommTarget(target, (comm) => {
                    logging_1.logger.info(`Registering JupyterLab comms for target ${target}`);
                    const r = new receiver_1.Receiver();
                    comm.onMsg = _handle_notebook_comms.bind(doc, r);
                });
            }
            catch (e) {
                logging_1.logger.warn(`Jupyter comms failed to register. push_notebook() will not function. (exception reported: ${e})`);
            }
        }
        else {
            console.warn(`Jupyter notebooks comms not available. push_notebook() will not function. If running JupyterLab ensure the latest @bokeh/jupyter_bokeh extension is installed. In an exported notebook this warning is expected.`);
        }
    }
    function embed_items_notebook(docs_json, render_items) {
        if (object_1.size(docs_json) != 1)
            throw new Error("embed_items_notebook expects exactly one document in docs_json");
        const document = document_1.Document.from_json(object_1.values(docs_json)[0]);
        for (const item of render_items) {
            if (item.notebook_comms_target != null)
                _init_comms(item.notebook_comms_target, document);
            const element = dom_1._resolve_element(item);
            const roots = dom_1._resolve_root_elements(item);
            standalone_1.add_document_standalone(document, element, roots);
        }
    }
    exports.embed_items_notebook = embed_items_notebook;
},
/* styles/notebook.js */ function _(require, module, exports) {
    require(62) /* ./root */;
    const _a = require(61) /* ../core/dom */;
    _a.styles.append("/* notebook specific tweaks so no black outline and matching padding\n/* can't be wrapped inside bk-root. here are the offending jupyter lines:\n/* https://github.com/jupyter/notebook/blob/master/notebook/static/notebook/less/renderedhtml.less#L59-L76 */\n.rendered_html .bk-root .bk-tooltip table,\n.rendered_html .bk-root .bk-tooltip tr,\n.rendered_html .bk-root .bk-tooltip th,\n.rendered_html .bk-root .bk-tooltip td {\n  border: none;\n  padding: 1px;\n}\n");
},
/* protocol/index.js */ function _(require, module, exports) {
    function __export(m) {
        for (var p in m)
            if (!exports.hasOwnProperty(p))
                exports[p] = m[p];
    }
    __export(require(343) /* ./message */);
    __export(require(344) /* ./receiver */);
},
/* testing.js */ function _(require, module, exports) {
    // Just a dumb key/value record for collecting arbitrary info for tests
    exports.results = {};
    // Selenium has race conditions that make it difficult to read out the
    // results structure. This function deletes/creates a div that can act as
    // a semaphore. Tests should wait for the previous div to be stale, then
    // find the new div. At that point the results should be available
    function _update_test_div() {
        const body = document.getElementsByTagName("body")[0];
        const col = document.getElementsByClassName("bokeh-test-div");
        if (col.length == 1) {
            body.removeChild(col[0]);
            delete col[0];
        }
        const box = document.createElement("div");
        box.classList.add("bokeh-test-div");
        box.style.display = "none";
        body.insertBefore(box, body.firstChild);
    }
    function init() {
        _update_test_div();
    }
    exports.init = init;
    function record(key, value) {
        exports.results[key] = value;
        _update_test_div();
    }
    exports.record = record;
    function count(key) {
        if (exports.results[key] == undefined)
            exports.results[key] = 0;
        exports.results[key] += 1;
        _update_test_div();
    }
    exports.count = count;
    function clear() {
        for (const prop of Object.keys(exports.results))
            delete exports.results[prop];
        _update_test_div();
    }
    exports.clear = clear;
},
/* safely.js */ function _(require, module, exports) {
    function _burst_into_flames(error) {
        // Make box
        const box = document.createElement("div");
        box.style.backgroundColor = "#f2dede";
        box.style.border = "1px solid #a94442";
        box.style.borderRadius = "4px";
        box.style.display = "inline-block";
        box.style.fontFamily = "sans-serif";
        box.style.marginTop = "5px";
        box.style.minWidth = "200px";
        box.style.padding = "5px 5px 5px 10px";
        box.classList.add("bokeh-error-box-into-flames");
        // Make button
        const button = document.createElement("span");
        button.style.backgroundColor = "#a94442";
        button.style.borderRadius = "0px 4px 0px 0px";
        button.style.color = "white";
        button.style.cursor = "pointer";
        button.style.cssFloat = "right";
        button.style.fontSize = "0.8em";
        button.style.margin = "-6px -6px 0px 0px";
        button.style.padding = "2px 5px 4px 5px";
        button.title = "close";
        button.setAttribute("aria-label", "close");
        button.appendChild(document.createTextNode("x"));
        button.addEventListener("click", () => body.removeChild(box));
        // Make title
        const title = document.createElement("h3");
        title.style.color = "#a94442";
        title.style.margin = "8px 0px 0px 0px";
        title.style.padding = "0px";
        title.appendChild(document.createTextNode("Bokeh Error"));
        // Make message
        const message = document.createElement("pre");
        message.style.whiteSpace = "unset";
        message.style.overflowX = "auto";
        const text = error instanceof Error ? error.message : error;
        message.appendChild(document.createTextNode(text));
        // Add pieces to box
        box.appendChild(button);
        box.appendChild(title);
        box.appendChild(message);
        // Put box in doc
        const body = document.getElementsByTagName("body")[0];
        body.insertBefore(box, body.firstChild);
    }
    function safely(fn, silent = false) {
        try {
            return fn();
        }
        catch (error) {
            _burst_into_flames(error);
            if (!silent)
                throw error;
            else
                return;
        }
    }
    exports.safely = safely;
},
], 0, {"main":0,"index":1,"version":2,"embed/index":3,"document/index":4,"document/document":5,"base":6,"core/util/types":7,"core/util/array":8,"core/util/math":9,"core/util/assert":10,"core/util/arrayable":11,"core/has_props":12,"core/signaling":13,"core/util/data_structures":14,"core/util/eq":15,"core/util/callback":16,"core/property_mixins":17,"core/properties":18,"core/enums":19,"core/util/color":20,"core/util/svg_colors":21,"core/util/object":22,"core/util/refs":24,"core/util/string":25,"core/settings":26,"models/index":27,"models/annotations/index":28,"models/annotations/annotation":29,"core/util/projections":30,"models/renderers/renderer":58,"core/dom_view":59,"core/view":60,"core/dom":61,"styles/root":62,"core/visuals":63,"model":64,"core/logging":65,"models/annotations/arrow":66,"models/annotations/arrow_head":67,"models/sources/column_data_source":68,"models/sources/columnar_data_source":69,"models/sources/data_source":70,"models/selections/selection":71,"core/selection_manager":72,"models/renderers/glyph_renderer":73,"models/renderers/data_renderer":74,"models/glyphs/line":75,"models/glyphs/xy_glyph":76,"core/util/spatial":77,"core/util/bbox":79,"models/glyphs/glyph":80,"core/hittest":81,"models/ranges/factor_range":82,"models/ranges/range":83,"models/glyphs/utils":84,"models/glyphs/patch":85,"models/glyphs/harea":86,"models/glyphs/area":87,"models/glyphs/varea":88,"models/sources/cds_view":89,"models/renderers/graph_renderer":90,"models/graphs/graph_hit_test_policy":91,"core/build_views":92,"models/selections/interaction_policy":93,"core/util/serialization":94,"core/util/compat":95,"core/util/typed_array":96,"document/events":97,"models/annotations/band":98,"models/annotations/box_annotation":99,"styles/annotations":100,"models/annotations/color_bar":101,"models/tickers/basic_ticker":102,"models/tickers/adaptive_ticker":103,"models/tickers/continuous_ticker":104,"models/tickers/ticker":105,"models/formatters/basic_tick_formatter":106,"models/formatters/tick_formatter":107,"models/mappers/linear_color_mapper":108,"models/mappers/continuous_color_mapper":109,"models/mappers/color_mapper":110,"models/mappers/mapper":111,"models/transforms/transform":112,"models/scales/linear_scale":113,"models/scales/scale":114,"models/transforms/index":115,"models/transforms/customjs_transform":116,"models/transforms/dodge":117,"models/transforms/interpolator":118,"models/transforms/jitter":119,"models/transforms/linear_interpolator":120,"models/transforms/step_interpolator":121,"models/scales/log_scale":122,"models/ranges/range1d":123,"core/util/text":124,"models/annotations/label":125,"models/annotations/text_annotation":126,"models/annotations/label_set":127,"models/annotations/legend":128,"models/annotations/legend_item":129,"core/vectorization":130,"models/annotations/poly_annotation":131,"models/annotations/slope":132,"models/annotations/span":133,"models/annotations/title":134,"models/annotations/toolbar_panel":135,"models/annotations/tooltip":136,"styles/tooltips":137,"styles/mixins":138,"models/annotations/whisker":139,"models/axes/index":140,"models/axes/axis":141,"models/renderers/guide_renderer":142,"models/axes/categorical_axis":143,"models/tickers/categorical_ticker":144,"models/formatters/categorical_tick_formatter":145,"models/axes/continuous_axis":146,"models/axes/datetime_axis":147,"models/axes/linear_axis":148,"models/formatters/datetime_tick_formatter":149,"core/util/templating":151,"models/tickers/datetime_ticker":154,"models/tickers/composite_ticker":155,"models/tickers/days_ticker":156,"models/tickers/single_interval_ticker":157,"models/tickers/util":158,"models/tickers/months_ticker":159,"models/tickers/years_ticker":160,"models/axes/log_axis":161,"models/formatters/log_tick_formatter":162,"models/tickers/log_ticker":163,"models/axes/mercator_axis":164,"models/formatters/mercator_tick_formatter":165,"models/tickers/mercator_ticker":166,"models/callbacks/index":167,"models/callbacks/customjs":168,"models/callbacks/callback":169,"models/callbacks/open_url":170,"models/canvas/index":171,"models/canvas/canvas":172,"core/util/canvas":173,"styles/canvas":174,"models/canvas/cartesian_frame":176,"models/scales/categorical_scale":177,"models/ranges/data_range1d":178,"models/ranges/data_range":179,"core/layout/index":180,"core/layout/types":181,"core/layout/layoutable":182,"core/layout/alignments":183,"core/layout/grid":184,"core/layout/html":185,"models/expressions/index":186,"models/expressions/expression":187,"models/expressions/stack":188,"models/expressions/cumsum":189,"models/filters/index":190,"models/filters/boolean_filter":191,"models/filters/filter":192,"models/filters/customjs_filter":193,"models/filters/group_filter":194,"models/filters/index_filter":195,"models/formatters/index":196,"models/formatters/func_tick_formatter":197,"models/formatters/numeral_tick_formatter":198,"models/formatters/printf_tick_formatter":199,"models/glyphs/index":200,"models/glyphs/annular_wedge":201,"models/glyphs/annulus":202,"models/glyphs/arc":203,"models/glyphs/bezier":204,"models/glyphs/circle":205,"models/glyphs/center_rotatable":206,"models/glyphs/ellipse":207,"models/glyphs/ellipse_oval":208,"models/glyphs/hbar":209,"models/glyphs/box":210,"models/glyphs/hex_tile":211,"models/glyphs/image":212,"models/glyphs/image_base":213,"models/glyphs/image_rgba":214,"models/glyphs/image_url":215,"core/util/image":216,"models/glyphs/multi_line":217,"models/glyphs/multi_polygons":218,"models/glyphs/oval":219,"models/glyphs/patches":220,"models/glyphs/quad":221,"models/glyphs/quadratic":222,"models/glyphs/ray":223,"models/glyphs/rect":224,"models/glyphs/segment":225,"models/glyphs/step":226,"models/glyphs/text":227,"models/glyphs/vbar":228,"models/glyphs/wedge":229,"models/graphs/index":230,"models/graphs/layout_provider":231,"models/graphs/static_layout_provider":232,"models/grids/index":233,"models/grids/grid":234,"models/layouts/index":235,"models/layouts/box":236,"models/layouts/layout_dom":237,"models/layouts/column":238,"models/layouts/grid_box":239,"models/layouts/html_box":240,"models/layouts/row":241,"models/layouts/spacer":242,"models/layouts/tabs":243,"styles/tabs":244,"styles/buttons":245,"styles/menus":246,"models/layouts/widget_box":247,"models/mappers/index":248,"models/mappers/categorical_color_mapper":249,"models/mappers/categorical_mapper":250,"models/mappers/categorical_marker_mapper":251,"models/mappers/categorical_pattern_mapper":252,"models/mappers/log_color_mapper":253,"models/markers/index":254,"models/markers/defs":255,"models/markers/marker":256,"models/markers/scatter":257,"models/plots/index":258,"models/plots/gmap_plot":259,"models/plots/plot":260,"models/tools/toolbar":261,"models/tools/inspectors/inspect_tool":262,"models/tools/button_tool":263,"models/tools/tool":264,"styles/toolbar":265,"models/tools/on_off_button":266,"models/tools/toolbar_base":267,"models/tools/gestures/gesture_tool":268,"models/tools/actions/action_tool":269,"models/tools/actions/help_tool":270,"styles/icons":271,"styles/logo":272,"models/plots/plot_canvas":273,"core/bokeh_events":274,"core/util/throttle":275,"core/layout/side_panel":276,"core/ui_events":277,"core/util/wheel":279,"models/plots/gmap_plot_canvas":280,"models/ranges/index":281,"models/renderers/index":282,"models/scales/index":283,"models/selections/index":284,"models/sources/index":285,"models/sources/server_sent_data_source":286,"models/sources/web_data_source":287,"models/sources/ajax_data_source":288,"models/sources/remote_data_source":289,"models/sources/geojson_data_source":290,"models/tickers/index":291,"models/tickers/fixed_ticker":292,"models/tiles/index":293,"models/tiles/bbox_tile_source":294,"models/tiles/mercator_tile_source":295,"models/tiles/tile_source":296,"models/tiles/tile_utils":297,"models/tiles/quadkey_tile_source":298,"models/tiles/tile_renderer":299,"models/tiles/wmts_tile_source":300,"styles/tiles":301,"models/tiles/tms_tile_source":302,"models/textures/index":303,"models/textures/canvas_texture":304,"models/textures/texture":305,"models/textures/image_url_texture":306,"models/tools/index":307,"models/tools/actions/custom_action":308,"models/tools/actions/redo_tool":309,"models/tools/actions/reset_tool":310,"models/tools/actions/save_tool":311,"models/tools/actions/undo_tool":312,"models/tools/actions/zoom_in_tool":313,"core/util/zoom":314,"models/tools/actions/zoom_out_tool":315,"models/tools/edit/edit_tool":316,"models/tools/edit/box_edit_tool":317,"models/tools/edit/freehand_draw_tool":318,"models/tools/edit/point_draw_tool":319,"models/tools/edit/poly_draw_tool":320,"models/tools/edit/poly_tool":321,"models/tools/edit/poly_edit_tool":322,"models/tools/gestures/box_select_tool":323,"models/tools/gestures/select_tool":324,"models/tools/util":325,"models/tools/gestures/box_zoom_tool":326,"models/tools/gestures/lasso_select_tool":327,"models/tools/gestures/pan_tool":328,"models/tools/gestures/poly_select_tool":329,"models/tools/gestures/range_tool":330,"models/tools/gestures/tap_tool":331,"models/tools/gestures/wheel_pan_tool":332,"models/tools/gestures/wheel_zoom_tool":333,"models/tools/inspectors/crosshair_tool":334,"models/tools/inspectors/customjs_hover":335,"models/tools/inspectors/hover_tool":336,"models/tools/tool_proxy":337,"models/tools/toolbar_box":338,"embed/standalone":339,"embed/dom":340,"embed/server":341,"client/connection":342,"protocol/message":343,"protocol/receiver":344,"client/session":345,"embed/notebook":346,"styles/notebook":347,"protocol/index":348,"testing":349,"safely":350}, {});
})

//# sourceMappingURL=bokeh-es6.js.map
